forked from OSchip/llvm-project
A using declaration can redeclare a typedef to the same type. These
typedefs won't have the same canonical declaration (since they are distinct), so we need to check for this case specifically. Fixes <rdar://problem/8018262>. llvm-svn: 107833
This commit is contained in:
parent
6213ab789f
commit
1d9ef840fa
|
@ -3496,6 +3496,28 @@ Sema::DeclPtrTy Sema::ActOnUsingDeclaration(Scope *S,
|
||||||
return DeclPtrTy::make(UD);
|
return DeclPtrTy::make(UD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Determine whether a using declaration considers the given
|
||||||
|
/// declarations as "equivalent", e.g., if they are redeclarations of
|
||||||
|
/// the same entity or are both typedefs of the same type.
|
||||||
|
static bool
|
||||||
|
IsEquivalentForUsingDecl(ASTContext &Context, NamedDecl *D1, NamedDecl *D2,
|
||||||
|
bool &SuppressRedeclaration) {
|
||||||
|
if (D1->getCanonicalDecl() == D2->getCanonicalDecl()) {
|
||||||
|
SuppressRedeclaration = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TypedefDecl *TD1 = dyn_cast<TypedefDecl>(D1))
|
||||||
|
if (TypedefDecl *TD2 = dyn_cast<TypedefDecl>(D2)) {
|
||||||
|
SuppressRedeclaration = true;
|
||||||
|
return Context.hasSameType(TD1->getUnderlyingType(),
|
||||||
|
TD2->getUnderlyingType());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Determines whether to create a using shadow decl for a particular
|
/// Determines whether to create a using shadow decl for a particular
|
||||||
/// decl, given the set of decls existing prior to this using lookup.
|
/// decl, given the set of decls existing prior to this using lookup.
|
||||||
bool Sema::CheckUsingShadowDecl(UsingDecl *Using, NamedDecl *Orig,
|
bool Sema::CheckUsingShadowDecl(UsingDecl *Using, NamedDecl *Orig,
|
||||||
|
@ -3562,8 +3584,9 @@ bool Sema::CheckUsingShadowDecl(UsingDecl *Using, NamedDecl *Orig,
|
||||||
for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
|
for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
NamedDecl *D = (*I)->getUnderlyingDecl();
|
NamedDecl *D = (*I)->getUnderlyingDecl();
|
||||||
if (D->getCanonicalDecl() == Target->getCanonicalDecl())
|
bool Result;
|
||||||
return false;
|
if (IsEquivalentForUsingDecl(Context, D, Target, Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
(isa<TagDecl>(D) ? Tag : NonTag) = D;
|
(isa<TagDecl>(D) ? Tag : NonTag) = D;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,19 @@ namespace test0 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Typedef redeclaration.
|
||||||
|
namespace rdar8018262 {
|
||||||
|
typedef void (*fp)();
|
||||||
|
|
||||||
|
namespace N {
|
||||||
|
typedef void (*fp)();
|
||||||
|
}
|
||||||
|
|
||||||
|
using N::fp;
|
||||||
|
|
||||||
|
fp fp_1;
|
||||||
|
}
|
||||||
|
|
||||||
// Things to test:
|
// Things to test:
|
||||||
// member operators
|
// member operators
|
||||||
// conversion operators
|
// conversion operators
|
||||||
|
|
Loading…
Reference in New Issue