summaryrefslogtreecommitdiffstats
path: root/clang/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
commit36d1b14ddedb32dfc628ec7ee4259ea8aa9268b6 (patch)
treea38572ad79629e315019c0f47420065e824dc640 /clang/lib/Sema/SemaLookup.cpp
parent80ef6f1a46663d33dfaffb5170014e047890727f (diff)
downloadbcm5719-llvm-36d1b14ddedb32dfc628ec7ee4259ea8aa9268b6.tar.gz
bcm5719-llvm-36d1b14ddedb32dfc628ec7ee4259ea8aa9268b6.zip
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. llvm-svn: 83396
Diffstat (limited to 'clang/lib/Sema/SemaLookup.cpp')
-rw-r--r--clang/lib/Sema/SemaLookup.cpp53
1 files changed, 39 insertions, 14 deletions
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 44641b72e4a..b55a5333e12 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/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)
OpenPOWER on IntegriCloud