diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-10-06 17:59:45 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-10-06 17:59:45 +0000 |
commit | a8f32e0965ee19ecc53cd796e34268377a20357c (patch) | |
tree | 5fcfab02b127c4a6f93721a0260612245f443f0c /lib/Sema/SemaLookup.cpp | |
parent | b299d3516d4722ef527b1070bb87133427e621a3 (diff) |
Refactor the code that walks a C++ inheritance hierarchy, searching
for bases, members, overridden virtual methods, etc. The operations
isDerivedFrom and lookupInBases are now provided by CXXRecordDecl,
rather than by Sema, so that CodeGen and other clients can use them
directly.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83396 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaLookup.cpp')
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 53 |
1 files changed, 39 insertions, 14 deletions
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 44641b72e4..b55a5333e1 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// #include "Sema.h" -#include "SemaInherit.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/CXXInheritance.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" @@ -460,9 +460,9 @@ NamedDecl *Sema::LookupResult::getAsDecl() const { /// @brief Retrieves the BasePaths structure describing an ambiguous /// name lookup, or null. -BasePaths *Sema::LookupResult::getBasePaths() const { +CXXBasePaths *Sema::LookupResult::getBasePaths() const { if (StoredKind == AmbiguousLookupStoresBasePaths) - return reinterpret_cast<BasePaths *>(First); + return reinterpret_cast<CXXBasePaths *>(First); return 0; } @@ -594,7 +594,7 @@ Sema::LookupResult::iterator Sema::LookupResult::end() { } void Sema::LookupResult::Destroy() { - if (BasePaths *Paths = getBasePaths()) + if (CXXBasePaths *Paths = getBasePaths()) delete Paths; else if (getKind() == AmbiguousReference) delete[] reinterpret_cast<NamedDecl **>(First); @@ -1037,12 +1037,37 @@ Sema::LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name, return LookupResult::CreateLookupResult(Context, 0); // Perform lookup into our base classes. - BasePaths Paths; - Paths.setOrigin(Context.getTypeDeclType(cast<RecordDecl>(LookupCtx))); + CXXRecordDecl *LookupRec = cast<CXXRecordDecl>(LookupCtx); + CXXBasePaths Paths; + Paths.setOrigin(LookupRec); // Look for this member in our base classes - if (!LookupInBases(cast<CXXRecordDecl>(LookupCtx), - MemberLookupCriteria(Name, NameKind, IDNS), Paths)) + CXXRecordDecl::BaseMatchesCallback *BaseCallback = 0; + switch (NameKind) { + case LookupOrdinaryName: + case LookupMemberName: + case LookupRedeclarationWithLinkage: + BaseCallback = &CXXRecordDecl::FindOrdinaryMember; + break; + + case LookupTagName: + BaseCallback = &CXXRecordDecl::FindTagMember; + break; + + case LookupOperatorName: + case LookupNamespaceName: + case LookupObjCProtocolName: + case LookupObjCImplementationName: + case LookupObjCCategoryImplName: + // These lookups will never find a member in a C++ class (or base class). + return LookupResult::CreateLookupResult(Context, 0); + + case LookupNestedNameSpecifierName: + BaseCallback = &CXXRecordDecl::FindNestedNameSpecifierMember; + break; + } + + if (!LookupRec->lookupInBases(BaseCallback, Name.getAsOpaquePtr(), Paths)) return LookupResult::CreateLookupResult(Context, 0); // C++ [class.member.lookup]p2: @@ -1054,9 +1079,9 @@ Sema::LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name, // FIXME: support using declarations! QualType SubobjectType; int SubobjectNumber = 0; - for (BasePaths::paths_iterator Path = Paths.begin(), PathEnd = Paths.end(); + for (CXXBasePaths::paths_iterator Path = Paths.begin(), PathEnd = Paths.end(); Path != PathEnd; ++Path) { - const BasePathElement &PathElement = Path->back(); + const CXXBasePathElement &PathElement = Path->back(); // Determine whether we're looking at a distinct sub-object or not. if (SubobjectType.isNull()) { @@ -1067,7 +1092,7 @@ Sema::LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name, != Context.getCanonicalType(PathElement.Base->getType())) { // We found members of the given name in two subobjects of // different types. This lookup is ambiguous. - BasePaths *PathsOnHeap = new BasePaths; + CXXBasePaths *PathsOnHeap = new CXXBasePaths; PathsOnHeap->swap(Paths); return LookupResult::CreateLookupResult(Context, PathsOnHeap, true); } else if (SubobjectNumber != PathElement.SubobjectNumber) { @@ -1105,7 +1130,7 @@ Sema::LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name, // We have found a nonstatic member name in multiple, distinct // subobjects. Name lookup is ambiguous. - BasePaths *PathsOnHeap = new BasePaths; + CXXBasePaths *PathsOnHeap = new CXXBasePaths; PathsOnHeap->swap(Paths); return LookupResult::CreateLookupResult(Context, PathsOnHeap, false); } @@ -1202,7 +1227,7 @@ bool Sema::DiagnoseAmbiguousLookup(LookupResult &Result, DeclarationName Name, SourceRange LookupRange) { assert(Result.isAmbiguous() && "Lookup result must be ambiguous"); - if (BasePaths *Paths = Result.getBasePaths()) { + if (CXXBasePaths *Paths = Result.getBasePaths()) { if (Result.getKind() == LookupResult::AmbiguousBaseSubobjects) { QualType SubobjectType = Paths->front().back().Base->getType(); Diag(NameLoc, diag::err_ambiguous_member_multiple_subobjects) @@ -1227,7 +1252,7 @@ bool Sema::DiagnoseAmbiguousLookup(LookupResult &Result, DeclarationName Name, << Name << LookupRange; std::set<Decl *> DeclsPrinted; - for (BasePaths::paths_iterator Path = Paths->begin(), PathEnd = Paths->end(); + for (CXXBasePaths::paths_iterator Path = Paths->begin(), PathEnd = Paths->end(); Path != PathEnd; ++Path) { Decl *D = *Path->Decls.first; if (DeclsPrinted.insert(D).second) |