diff options
author | John McCall <rjmccall@apple.com> | 2009-10-10 05:48:19 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2009-10-10 05:48:19 +0000 |
commit | 6e24726524c2b51b31bb4b622aa678a46b024f42 (patch) | |
tree | 18635fadba59cf37262ebf36c8ad806ad0eb8bd2 /lib/Sema/SemaDecl.cpp | |
parent | eed3e699b581ad9e17f8147f26b882d20d65a317 (diff) |
Qualified lookup through using declarations. Diagnose a new type of ambiguity.
Split the various ambiguous result enumerators into their own enum. Tests
for most of C++ [namespace.qual].
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83700 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 7982387281..f12f2b9985 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -94,9 +94,15 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc, case LookupResult::FoundOverloaded: return 0; - case LookupResult::AmbiguousBaseSubobjectTypes: - case LookupResult::AmbiguousBaseSubobjects: - case LookupResult::AmbiguousReference: { + case LookupResult::Ambiguous: { + // Recover from type-hiding ambiguities by hiding the type. We'll + // do the lookup again when looking for an object, and we can + // diagnose the error then. If we don't do this, then the error + // about hiding the type will be immediately followed by an error + // that only makes sense if the identifier was treated like a type. + if (Result.getAmbiguityKind() == LookupResult::AmbiguousTagHiding) + return 0; + // Look to see if we have a type anywhere in the list of results. for (LookupResult::iterator Res = Result.begin(), ResEnd = Result.end(); Res != ResEnd; ++Res) { @@ -4129,6 +4135,8 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, bool isStdBadAlloc = false; bool Invalid = false; + bool RedeclarationOnly = (TUK != TUK_Reference); + if (Name && SS.isNotEmpty()) { // We have a nested-name tag ('struct foo::bar'). @@ -4155,11 +4163,18 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SearchDC = DC; // Look-up name inside 'foo::'. LookupResult R; - LookupQualifiedName(R, DC, Name, LookupTagName, true); - PrevDecl = dyn_cast_or_null<TagDecl>(R.getAsSingleDecl(Context)); + LookupQualifiedName(R, DC, Name, LookupTagName, RedeclarationOnly); + + if (R.isAmbiguous()) { + DiagnoseAmbiguousLookup(R, Name, NameLoc, SS.getRange()); + return DeclPtrTy(); + } + + if (R.getKind() == LookupResult::Found) + PrevDecl = dyn_cast<TagDecl>(R.getFoundDecl()); // A tag 'foo::bar' must already exist. - if (PrevDecl == 0) { + if (!PrevDecl) { Diag(NameLoc, diag::err_not_tag_in_scope) << Name << SS.getRange(); Name = 0; Invalid = true; @@ -4172,8 +4187,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // shouldn't be. Doing so can result in ambiguities that we // shouldn't be diagnosing. LookupResult R; - LookupName(R, S, Name, LookupTagName, - /*RedeclarationOnly=*/(TUK != TUK_Reference)); + LookupName(R, S, Name, LookupTagName, RedeclarationOnly); if (R.isAmbiguous()) { DiagnoseAmbiguousLookup(R, Name, NameLoc); // FIXME: This is not best way to recover from case like: |