aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/CXXInheritance.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/CXXInheritance.cpp')
-rw-r--r--lib/AST/CXXInheritance.cpp85
1 files changed, 42 insertions, 43 deletions
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index 800c8f83b880..6785a0c2935a 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -31,16 +31,16 @@ void CXXBasePaths::ComputeDeclsFound() {
Decls.insert(Path->Decls.front());
NumDeclsFound = Decls.size();
- DeclsFound = new NamedDecl * [NumDeclsFound];
- std::copy(Decls.begin(), Decls.end(), DeclsFound);
+ DeclsFound = llvm::make_unique<NamedDecl *[]>(NumDeclsFound);
+ std::copy(Decls.begin(), Decls.end(), DeclsFound.get());
}
CXXBasePaths::decl_range CXXBasePaths::found_decls() {
if (NumDeclsFound == 0)
ComputeDeclsFound();
- return decl_range(decl_iterator(DeclsFound),
- decl_iterator(DeclsFound + NumDeclsFound));
+ return decl_range(decl_iterator(DeclsFound.get()),
+ decl_iterator(DeclsFound.get() + NumDeclsFound));
}
/// isAmbiguous - Determines whether the set of paths provided is
@@ -85,9 +85,14 @@ bool CXXRecordDecl::isDerivedFrom(const CXXRecordDecl *Base,
return false;
Paths.setOrigin(const_cast<CXXRecordDecl*>(this));
- return lookupInBases(&FindBaseClass,
- const_cast<CXXRecordDecl*>(Base->getCanonicalDecl()),
- Paths);
+
+ const CXXRecordDecl *BaseDecl = Base->getCanonicalDecl();
+ // FIXME: Capturing 'this' is a workaround for name lookup bugs in GCC 4.7.
+ return lookupInBases(
+ [this, BaseDecl](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
+ return FindBaseClass(Specifier, Path, BaseDecl);
+ },
+ Paths);
}
bool CXXRecordDecl::isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const {
@@ -102,20 +107,20 @@ bool CXXRecordDecl::isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const {
Paths.setOrigin(const_cast<CXXRecordDecl*>(this));
- const void *BasePtr = static_cast<const void*>(Base->getCanonicalDecl());
- return lookupInBases(&FindVirtualBaseClass,
- const_cast<void *>(BasePtr),
- Paths);
-}
-
-static bool BaseIsNot(const CXXRecordDecl *Base, void *OpaqueTarget) {
- // OpaqueTarget is a CXXRecordDecl*.
- return Base->getCanonicalDecl() != (const CXXRecordDecl*) OpaqueTarget;
+ const CXXRecordDecl *BaseDecl = Base->getCanonicalDecl();
+ // FIXME: Capturing 'this' is a workaround for name lookup bugs in GCC 4.7.
+ return lookupInBases(
+ [this, BaseDecl](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
+ return FindVirtualBaseClass(Specifier, Path, BaseDecl);
+ },
+ Paths);
}
bool CXXRecordDecl::isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const {
- return forallBases(BaseIsNot,
- const_cast<CXXRecordDecl *>(Base->getCanonicalDecl()));
+ const CXXRecordDecl *TargetDecl = Base->getCanonicalDecl();
+ return forallBases([TargetDecl](const CXXRecordDecl *Base) {
+ return Base->getCanonicalDecl() != TargetDecl;
+ });
}
bool
@@ -129,8 +134,7 @@ CXXRecordDecl::isCurrentInstantiation(const DeclContext *CurContext) const {
return false;
}
-bool CXXRecordDecl::forallBases(ForallBasesCallback *BaseMatches,
- void *OpaqueData,
+bool CXXRecordDecl::forallBases(ForallBasesCallback BaseMatches,
bool AllowShortCircuit) const {
SmallVector<const CXXRecordDecl*, 8> Queue;
@@ -156,7 +160,7 @@ bool CXXRecordDecl::forallBases(ForallBasesCallback *BaseMatches,
}
Queue.push_back(Base);
- if (!BaseMatches(Base, OpaqueData)) {
+ if (!BaseMatches(Base)) {
if (AllowShortCircuit) return false;
AllMatches = false;
continue;
@@ -171,10 +175,9 @@ bool CXXRecordDecl::forallBases(ForallBasesCallback *BaseMatches,
return AllMatches;
}
-bool CXXBasePaths::lookupInBases(ASTContext &Context,
- const CXXRecordDecl *Record,
- CXXRecordDecl::BaseMatchesCallback *BaseMatches,
- void *UserData) {
+bool CXXBasePaths::lookupInBases(
+ ASTContext &Context, const CXXRecordDecl *Record,
+ CXXRecordDecl::BaseMatchesCallback BaseMatches) {
bool FoundPath = false;
// The access of the path down to this record.
@@ -248,7 +251,7 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
// Track whether there's a path involving this specific base.
bool FoundPathThroughBase = false;
- if (BaseMatches(&BaseSpec, ScratchPath, UserData)) {
+ if (BaseMatches(&BaseSpec, ScratchPath)) {
// We've found a path that terminates at this base.
FoundPath = FoundPathThroughBase = true;
if (isRecordingPaths()) {
@@ -263,7 +266,7 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
CXXRecordDecl *BaseRecord
= cast<CXXRecordDecl>(BaseSpec.getType()->castAs<RecordType>()
->getDecl());
- if (lookupInBases(Context, BaseRecord, BaseMatches, UserData)) {
+ if (lookupInBases(Context, BaseRecord, BaseMatches)) {
// C++ [class.member.lookup]p2:
// A member name f in one sub-object B hides a member name f in
// a sub-object A if A is a base class sub-object of B. Any
@@ -296,11 +299,10 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
return FoundPath;
}
-bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches,
- void *UserData,
+bool CXXRecordDecl::lookupInBases(BaseMatchesCallback BaseMatches,
CXXBasePaths &Paths) const {
// If we didn't find anything, report that.
- if (!Paths.lookupInBases(getASTContext(), this, BaseMatches, UserData))
+ if (!Paths.lookupInBases(getASTContext(), this, BaseMatches))
return false;
// If we're not recording paths or we won't ever find ambiguities,
@@ -353,8 +355,8 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches,
bool CXXRecordDecl::FindBaseClass(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
- void *BaseRecord) {
- assert(((Decl *)BaseRecord)->getCanonicalDecl() == BaseRecord &&
+ const CXXRecordDecl *BaseRecord) {
+ assert(BaseRecord->getCanonicalDecl() == BaseRecord &&
"User data for FindBaseClass is not canonical!");
return Specifier->getType()->castAs<RecordType>()->getDecl()
->getCanonicalDecl() == BaseRecord;
@@ -362,8 +364,8 @@ bool CXXRecordDecl::FindBaseClass(const CXXBaseSpecifier *Specifier,
bool CXXRecordDecl::FindVirtualBaseClass(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
- void *BaseRecord) {
- assert(((Decl *)BaseRecord)->getCanonicalDecl() == BaseRecord &&
+ const CXXRecordDecl *BaseRecord) {
+ assert(BaseRecord->getCanonicalDecl() == BaseRecord &&
"User data for FindBaseClass is not canonical!");
return Specifier->isVirtual() &&
Specifier->getType()->castAs<RecordType>()->getDecl()
@@ -372,12 +374,11 @@ bool CXXRecordDecl::FindVirtualBaseClass(const CXXBaseSpecifier *Specifier,
bool CXXRecordDecl::FindTagMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
- void *Name) {
+ DeclarationName Name) {
RecordDecl *BaseRecord =
Specifier->getType()->castAs<RecordType>()->getDecl();
- DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
- for (Path.Decls = BaseRecord->lookup(N);
+ for (Path.Decls = BaseRecord->lookup(Name);
!Path.Decls.empty();
Path.Decls = Path.Decls.slice(1)) {
if (Path.Decls.front()->isInIdentifierNamespace(IDNS_Tag))
@@ -389,13 +390,12 @@ bool CXXRecordDecl::FindTagMember(const CXXBaseSpecifier *Specifier,
bool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
- void *Name) {
+ DeclarationName Name) {
RecordDecl *BaseRecord =
Specifier->getType()->castAs<RecordType>()->getDecl();
const unsigned IDNS = IDNS_Ordinary | IDNS_Tag | IDNS_Member;
- DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
- for (Path.Decls = BaseRecord->lookup(N);
+ for (Path.Decls = BaseRecord->lookup(Name);
!Path.Decls.empty();
Path.Decls = Path.Decls.slice(1)) {
if (Path.Decls.front()->isInIdentifierNamespace(IDNS))
@@ -408,12 +408,11 @@ bool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
bool CXXRecordDecl::
FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
- void *Name) {
+ DeclarationName Name) {
RecordDecl *BaseRecord =
Specifier->getType()->castAs<RecordType>()->getDecl();
- DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
- for (Path.Decls = BaseRecord->lookup(N);
+ for (Path.Decls = BaseRecord->lookup(Name);
!Path.Decls.empty();
Path.Decls = Path.Decls.slice(1)) {
// FIXME: Refactor the "is it a nested-name-specifier?" check