aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaLookup.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-04-01 21:51:26 +0000
committerDouglas Gregor <dgregor@apple.com>2009-04-01 21:51:26 +0000
commit31a19b6989bbf326d2de5ae12e712e2a65ca9c34 (patch)
treee79ad32f23a5f590558c274cf11b000f10b04042 /lib/Sema/SemaLookup.cpp
parentfaa435a326a694e0517d035376e616ff82655fe5 (diff)
Make parsing a semantic analysis a little more robust following Sema
failures that involve malformed types, e.g., "typename X::foo" where "foo" isn't a type, or "std::vector<void>" that doens't instantiate properly. Similarly, be a bit smarter in our handling of ambiguities that occur in Sema::getTypeName, to eliminate duplicate error messages about ambiguous name lookup. This eliminates two XFAILs in test/SemaCXX, one of which was crying out to us, trying to tell us that we were producing repeated error messages. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68251 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaLookup.cpp')
-rw-r--r--lib/Sema/SemaLookup.cpp112
1 files changed, 82 insertions, 30 deletions
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 69bd5602d3..d85123c853 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -437,13 +437,16 @@ Sema::LookupResult::iterator::operator*() const {
case OverloadedDeclFromIdResolver:
return *IdentifierResolver::iterator::getFromOpaqueValue(Current);
+ case AmbiguousLookupStoresBasePaths:
+ if (Result->Last)
+ return *reinterpret_cast<NamedDecl**>(Current);
+
+ // Fall through to handle the DeclContext::lookup_iterator we're
+ // storing.
+
case OverloadedDeclFromDeclContext:
- return *reinterpret_cast<DeclContext::lookup_iterator>(Current);
-
case AmbiguousLookupStoresDecls:
- case AmbiguousLookupStoresBasePaths:
- assert(false && "Cannot look into ambiguous lookup results");
- break;
+ return *reinterpret_cast<DeclContext::lookup_iterator>(Current);
}
return 0;
@@ -470,39 +473,90 @@ Sema::LookupResult::iterator& Sema::LookupResult::iterator::operator++() {
break;
}
- case OverloadedDeclFromDeclContext: {
+ case AmbiguousLookupStoresBasePaths:
+ if (Result->Last) {
+ NamedDecl ** I = reinterpret_cast<NamedDecl**>(Current);
+ ++I;
+ Current = reinterpret_cast<uintptr_t>(I);
+ break;
+ }
+ // Fall through to handle the DeclContext::lookup_iterator we're
+ // storing.
+
+ case OverloadedDeclFromDeclContext:
+ case AmbiguousLookupStoresDecls: {
DeclContext::lookup_iterator I
= reinterpret_cast<DeclContext::lookup_iterator>(Current);
++I;
Current = reinterpret_cast<uintptr_t>(I);
break;
}
-
- case AmbiguousLookupStoresDecls:
- case AmbiguousLookupStoresBasePaths:
- assert(false && "Cannot look into ambiguous lookup results");
- break;
}
return *this;
}
Sema::LookupResult::iterator Sema::LookupResult::begin() {
- assert(!isAmbiguous() && "Lookup into an ambiguous result");
- if (StoredKind != OverloadedDeclSingleDecl)
+ switch (StoredKind) {
+ case SingleDecl:
+ case OverloadedDeclFromIdResolver:
+ case OverloadedDeclFromDeclContext:
+ case AmbiguousLookupStoresDecls:
return iterator(this, First);
- OverloadedFunctionDecl * Ovl =
- reinterpret_cast<OverloadedFunctionDecl*>(First);
- return iterator(this, reinterpret_cast<uintptr_t>(&(*Ovl->function_begin())));
+
+ case OverloadedDeclSingleDecl: {
+ OverloadedFunctionDecl * Ovl =
+ reinterpret_cast<OverloadedFunctionDecl*>(First);
+ return iterator(this,
+ reinterpret_cast<uintptr_t>(&(*Ovl->function_begin())));
+ }
+
+ case AmbiguousLookupStoresBasePaths:
+ if (Last)
+ return iterator(this,
+ reinterpret_cast<uintptr_t>(getBasePaths()->found_decls_begin()));
+ else
+ return iterator(this,
+ reinterpret_cast<uintptr_t>(getBasePaths()->front().Decls.first));
+ }
+
+ // Required to suppress GCC warning.
+ return iterator();
}
Sema::LookupResult::iterator Sema::LookupResult::end() {
- assert(!isAmbiguous() && "Lookup into an ambiguous result");
- if (StoredKind != OverloadedDeclSingleDecl)
+ switch (StoredKind) {
+ case SingleDecl:
+ case OverloadedDeclFromIdResolver:
+ case OverloadedDeclFromDeclContext:
+ case AmbiguousLookupStoresDecls:
return iterator(this, Last);
- OverloadedFunctionDecl * Ovl =
- reinterpret_cast<OverloadedFunctionDecl*>(First);
- return iterator(this, reinterpret_cast<uintptr_t>(&(*Ovl->function_end())));
+
+ case OverloadedDeclSingleDecl: {
+ OverloadedFunctionDecl * Ovl =
+ reinterpret_cast<OverloadedFunctionDecl*>(First);
+ return iterator(this,
+ reinterpret_cast<uintptr_t>(&(*Ovl->function_end())));
+ }
+
+ case AmbiguousLookupStoresBasePaths:
+ if (Last)
+ return iterator(this,
+ reinterpret_cast<uintptr_t>(getBasePaths()->found_decls_end()));
+ else
+ return iterator(this, reinterpret_cast<uintptr_t>(
+ getBasePaths()->front().Decls.second));
+ }
+
+ // Required to suppress GCC warning.
+ return iterator();
+}
+
+void Sema::LookupResult::Destroy() {
+ if (BasePaths *Paths = getBasePaths())
+ delete Paths;
+ else if (getKind() == AmbiguousReference)
+ delete[] reinterpret_cast<NamedDecl **>(First);
}
static void
@@ -1071,8 +1125,7 @@ bool Sema::DiagnoseAmbiguousLookup(LookupResult &Result, DeclarationName Name,
SourceRange LookupRange) {
assert(Result.isAmbiguous() && "Lookup result must be ambiguous");
- if (BasePaths *Paths = Result.getBasePaths())
- {
+ if (BasePaths *Paths = Result.getBasePaths()) {
if (Result.getKind() == LookupResult::AmbiguousBaseSubobjects) {
QualType SubobjectType = Paths->front().back().Base->getType();
Diag(NameLoc, diag::err_ambiguous_member_multiple_subobjects)
@@ -1080,11 +1133,13 @@ bool Sema::DiagnoseAmbiguousLookup(LookupResult &Result, DeclarationName Name,
<< LookupRange;
DeclContext::lookup_iterator Found = Paths->front().Decls.first;
- while (isa<CXXMethodDecl>(*Found) && cast<CXXMethodDecl>(*Found)->isStatic())
+ while (isa<CXXMethodDecl>(*Found) &&
+ cast<CXXMethodDecl>(*Found)->isStatic())
++Found;
Diag((*Found)->getLocation(), diag::note_ambiguous_member_found);
+ Result.Destroy();
return true;
}
@@ -1102,20 +1157,18 @@ bool Sema::DiagnoseAmbiguousLookup(LookupResult &Result, DeclarationName Name,
Diag(D->getLocation(), diag::note_ambiguous_member_found);
}
- delete Paths;
+ Result.Destroy();
return true;
} else if (Result.getKind() == LookupResult::AmbiguousReference) {
-
Diag(NameLoc, diag::err_ambiguous_reference) << Name << LookupRange;
NamedDecl **DI = reinterpret_cast<NamedDecl **>(Result.First),
- **DEnd = reinterpret_cast<NamedDecl **>(Result.Last);
+ **DEnd = reinterpret_cast<NamedDecl **>(Result.Last);
for (; DI != DEnd; ++DI)
Diag((*DI)->getLocation(), diag::note_ambiguous_candidate) << *DI;
- delete[] reinterpret_cast<NamedDecl **>(Result.First);
-
+ Result.Destroy();
return true;
}
@@ -1466,7 +1519,6 @@ void Sema::ArgumentDependentLookup(DeclarationName Name,
AssociatedNamespaces, AssociatedClasses);
// C++ [basic.lookup.argdep]p3:
- //
// Let X be the lookup set produced by unqualified lookup (3.4.1)
// and let Y be the lookup set produced by argument dependent
// lookup (defined as follows). If X contains [...] then Y is