зеркало из https://github.com/microsoft/clang-1.git
If name lookup finds different type declarations in different scopes
that actually refer to the same underlying type, it is not an ambiguity; add uniquing support based on the canonical type of type declarations. Fixes <rdar://problem/8296180>. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110806 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
6bf1830875
Коммит
7f1c547ee6
|
@ -311,7 +311,8 @@ void LookupResult::resolveKind() {
|
|||
if (ResultKind == Ambiguous) return;
|
||||
|
||||
llvm::SmallPtrSet<NamedDecl*, 16> Unique;
|
||||
|
||||
llvm::SmallPtrSet<QualType, 16> UniqueTypes;
|
||||
|
||||
bool Ambiguous = false;
|
||||
bool HasTag = false, HasFunction = false, HasNonFunction = false;
|
||||
bool HasFunctionTemplate = false, HasUnresolved = false;
|
||||
|
@ -323,32 +324,49 @@ void LookupResult::resolveKind() {
|
|||
NamedDecl *D = Decls[I]->getUnderlyingDecl();
|
||||
D = cast<NamedDecl>(D->getCanonicalDecl());
|
||||
|
||||
// Redeclarations of types via typedef can occur both within a scope
|
||||
// and, through using declarations and directives, across scopes. There is
|
||||
// no ambiguity if they all refer to the same type, so unique based on the
|
||||
// canonical type.
|
||||
if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) {
|
||||
if (!TD->getDeclContext()->isRecord()) {
|
||||
QualType T = SemaRef.Context.getTypeDeclType(TD);
|
||||
if (!UniqueTypes.insert(SemaRef.Context.getCanonicalType(T))) {
|
||||
// The type is not unique; pull something off the back and continue
|
||||
// at this index.
|
||||
Decls[I] = Decls[--N];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!Unique.insert(D)) {
|
||||
// If it's not unique, pull something off the back (and
|
||||
// continue at this index).
|
||||
Decls[I] = Decls[--N];
|
||||
} else {
|
||||
// Otherwise, do some decl type analysis and then continue.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Otherwise, do some decl type analysis and then continue.
|
||||
|
||||
if (isa<UnresolvedUsingValueDecl>(D)) {
|
||||
HasUnresolved = true;
|
||||
} else if (isa<TagDecl>(D)) {
|
||||
if (HasTag)
|
||||
Ambiguous = true;
|
||||
UniqueTagIndex = I;
|
||||
HasTag = true;
|
||||
} else if (isa<FunctionTemplateDecl>(D)) {
|
||||
HasFunction = true;
|
||||
HasFunctionTemplate = true;
|
||||
} else if (isa<FunctionDecl>(D)) {
|
||||
HasFunction = true;
|
||||
} else {
|
||||
if (HasNonFunction)
|
||||
Ambiguous = true;
|
||||
HasNonFunction = true;
|
||||
}
|
||||
I++;
|
||||
if (isa<UnresolvedUsingValueDecl>(D)) {
|
||||
HasUnresolved = true;
|
||||
} else if (isa<TagDecl>(D)) {
|
||||
if (HasTag)
|
||||
Ambiguous = true;
|
||||
UniqueTagIndex = I;
|
||||
HasTag = true;
|
||||
} else if (isa<FunctionTemplateDecl>(D)) {
|
||||
HasFunction = true;
|
||||
HasFunctionTemplate = true;
|
||||
} else if (isa<FunctionDecl>(D)) {
|
||||
HasFunction = true;
|
||||
} else {
|
||||
if (HasNonFunction)
|
||||
Ambiguous = true;
|
||||
HasNonFunction = true;
|
||||
}
|
||||
I++;
|
||||
}
|
||||
|
||||
// C++ [basic.scope.hiding]p2:
|
||||
|
|
|
@ -31,3 +31,4 @@ namespace test1 {
|
|||
using test1::foo;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
|
||||
// <rdar://problem/8296180>
|
||||
typedef int pid_t;
|
||||
namespace ns {
|
||||
typedef int pid_t;
|
||||
}
|
||||
using namespace ns;
|
||||
pid_t x;
|
||||
|
||||
struct A { };
|
||||
namespace ns {
|
||||
typedef ::A A;
|
||||
}
|
||||
A a;
|
Загрузка…
Ссылка в новой задаче