aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaLookup.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-10-06 17:59:45 +0000
committerDouglas Gregor <dgregor@apple.com>2009-10-06 17:59:45 +0000
commita8f32e0965ee19ecc53cd796e34268377a20357c (patch)
tree5fcfab02b127c4a6f93721a0260612245f443f0c /lib/Sema/SemaLookup.cpp
parentb299d3516d4722ef527b1070bb87133427e621a3 (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.cpp53
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)