diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-01-14 22:20:51 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-01-14 22:20:51 +0000 |
commit | 34074326449e1e6b7de77a4c9a0d78ea4b54ca64 (patch) | |
tree | 7c12b76899ad12bfb4002dd8b72e5294a8a3f9a3 /clang/lib/Sema/SemaCXXScopeSpec.cpp | |
parent | 8fb9480ed26693dc8f8053b6345bdd188041d41b (diff) | |
download | bcm5719-llvm-34074326449e1e6b7de77a4c9a0d78ea4b54ca64.tar.gz bcm5719-llvm-34074326449e1e6b7de77a4c9a0d78ea4b54ca64.zip |
Refactor name lookup.
This change refactors and cleans up our handling of name lookup with
LookupDecl. There are several aspects to this refactoring:
- The criteria for name lookup is now encapsulated into the class
LookupCriteria, which replaces the hideous set of boolean values
that LookupDecl currently has.
- The results of name lookup are returned in a new class
LookupResult, which can lazily build OverloadedFunctionDecls for
overloaded function sets (and, eventually, eliminate the need to
allocate member for OverloadedFunctionDecls) and contains a
placeholder for handling ambiguous name lookup (for C++).
- The primary entry points for name lookup are now LookupName (for
unqualified name lookup) and LookupQualifiedName (for qualified
name lookup). There is also a convenience function
LookupParsedName that handles qualified/unqualified name lookup
when given a scope specifier. Together, these routines are meant
to gradually replace the kludgy LookupDecl, but this won't happen
until after we have base class lookup (which forces us to cope
with ambiguities).
- Documented the heck out of name lookup. Experimenting a little
with using Doxygen's member groups to make some sense of the Sema
class. Feedback welcome!
- Fixes some lingering issues with name lookup for
nested-name-specifiers, which now goes through
LookupName/LookupQualifiedName.
llvm-svn: 62245
Diffstat (limited to 'clang/lib/Sema/SemaCXXScopeSpec.cpp')
-rw-r--r-- | clang/lib/Sema/SemaCXXScopeSpec.cpp | 78 |
1 files changed, 17 insertions, 61 deletions
diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp index dcb2a5fba55..0c0fa35a5e7 100644 --- a/clang/lib/Sema/SemaCXXScopeSpec.cpp +++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp @@ -19,54 +19,6 @@ using namespace clang;
-namespace {
- Decl *LookupNestedName(DeclContext *LookupCtx, bool LookInParentCtx,
- DeclarationName Name, bool &IdIsUndeclared,
- ASTContext &Context) {
- if (LookupCtx && !LookInParentCtx) {
- IdIsUndeclared = true;
- DeclContext::lookup_const_iterator I, E;
- for (llvm::tie(I, E) = LookupCtx->lookup(Name); I != E; ++I) {
- IdIsUndeclared = false;
- if (((*I)->isInIdentifierNamespace(Decl::IDNS_Tag)) ||
- isa<TypedefDecl>(*I))
- return *I;
- }
-
- return 0;
- }
-
- // FIXME: Decouple this from the IdentifierResolver so that we can
- // deal with lookups into the semantic parent contexts that aren't
- // lexical parent contexts.
-
- IdentifierResolver::iterator
- I = IdentifierResolver::begin(Name, LookupCtx, LookInParentCtx),
- E = IdentifierResolver::end();
-
- if (I == E) {
- IdIsUndeclared = true;
- return 0;
- }
- IdIsUndeclared = false;
-
- // C++ 3.4.3p1 :
- // During the lookup for a name preceding the :: scope resolution operator,
- // object, function, and enumerator names are ignored. If the name found is
- // not a class-name or namespace-name, the program is ill-formed.
-
- for (; I != E; ++I) {
- if (isa<TypedefDecl>(*I)) {
- break;
- }
- if (((*I)->getIdentifierNamespace() & Decl::IDNS_Tag))
- break;
- }
-
- return (I != E ? *I : 0);
- }
-} // anonymous namespace
-
/// ActOnCXXGlobalScopeSpecifier - Return the object that represents the
/// global scope ('::').
Sema::CXXScopeTy *Sema::ActOnCXXGlobalScopeSpecifier(Scope *S,
@@ -85,16 +37,10 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S, SourceLocation IdLoc,
SourceLocation CCLoc,
IdentifierInfo &II) {
- DeclContext *DC = static_cast<DeclContext*>(SS.getScopeRep());
- Decl *SD;
- bool IdIsUndeclared;
-
- if (DC)
- SD = LookupNestedName(DC, false/*LookInParentCtx*/, &II, IdIsUndeclared,
- Context);
- else
- SD = LookupNestedName(CurContext, true/*LookInParent*/, &II,
- IdIsUndeclared, Context);
+ Decl *SD = LookupParsedName(S, SS, &II,
+ LookupCriteria(LookupCriteria::NestedNameSpecifier,
+ /*RedeclarationOnly=*/false,
+ /*CPlusPlus=*/true));
if (SD) {
if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) {
@@ -104,19 +50,29 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S, return cast<DeclContext>(SD);
}
+ // FIXME: C++0x scoped enums
+
// Fall through to produce an error: we found something that isn't
// a class or a namespace.
}
+ // If we didn't find anything during our lookup, try again with
+ // ordinary name lookup, which can help us produce better error
+ // messages.
+ if (!SD)
+ SD = LookupParsedName(S, SS, &II,
+ LookupCriteria(LookupCriteria::Ordinary,
+ /*RedeclarationOnly=*/false,
+ /*CPlusPlus=*/true));
unsigned DiagID;
- if (!IdIsUndeclared)
+ if (SD)
DiagID = diag::err_expected_class_or_namespace;
- else if (DC)
+ else if (SS.isSet())
DiagID = diag::err_typecheck_no_member;
else
DiagID = diag::err_undeclared_var_use;
- if (DC)
+ if (SS.isSet())
Diag(IdLoc, DiagID) << &II << SS.getRange();
else
Diag(IdLoc, DiagID) << &II;
|