summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/CXXInheritance.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2009-12-08 07:42:38 +0000
committerJohn McCall <rjmccall@apple.com>2009-12-08 07:42:38 +0000
commitddabf1a94614f895d0de595e6145bda07d30a2ef (patch)
tree6cc8193eb34d35a2144d0c9cfbe0606464461c35 /clang/lib/AST/CXXInheritance.cpp
parent80888c7b38bdfc0925893ba74c06c10606a1a535 (diff)
downloadbcm5719-llvm-ddabf1a94614f895d0de595e6145bda07d30a2ef.tar.gz
bcm5719-llvm-ddabf1a94614f895d0de595e6145bda07d30a2ef.zip
Add CXXRecordDecl::forallBases to walk an inheritance hierarchy with non-lookup
semantics and CXXRecordDecl::isProvablyNotDerivedFrom to assist with pre-instantiation diagnostics. llvm-svn: 90842
Diffstat (limited to 'clang/lib/AST/CXXInheritance.cpp')
-rw-r--r--clang/lib/AST/CXXInheritance.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/clang/lib/AST/CXXInheritance.cpp b/clang/lib/AST/CXXInheritance.cpp
index 023bca43633..e5300f82847 100644
--- a/clang/lib/AST/CXXInheritance.cpp
+++ b/clang/lib/AST/CXXInheritance.cpp
@@ -90,6 +90,55 @@ bool CXXRecordDecl::isDerivedFrom(CXXRecordDecl *Base, CXXBasePaths &Paths) cons
return lookupInBases(&FindBaseClass, Base->getCanonicalDecl(), Paths);
}
+static bool BaseIsNot(const CXXRecordDecl *Base, void *OpaqueTarget) {
+ // OpaqueTarget is a CXXRecordDecl*.
+ return Base->getCanonicalDecl() != (const CXXRecordDecl*) OpaqueTarget;
+}
+
+bool CXXRecordDecl::isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const {
+ return forallBases(BaseIsNot, (void*) Base->getCanonicalDecl());
+}
+
+bool CXXRecordDecl::forallBases(ForallBasesCallback *BaseMatches,
+ void *OpaqueData,
+ bool AllowShortCircuit) const {
+ ASTContext &Context = getASTContext();
+ llvm::SmallVector<const CXXRecordDecl*, 8> Queue;
+
+ const CXXRecordDecl *Record = this;
+ bool AllMatches = true;
+ while (true) {
+ for (CXXRecordDecl::base_class_const_iterator
+ I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) {
+ const RecordType *Ty = I->getType()->getAs<RecordType>();
+ if (!Ty) {
+ if (AllowShortCircuit) return false;
+ AllMatches = false;
+ continue;
+ }
+
+ RecordDecl *Base = Ty->getDecl()->getDefinition(Context);
+ if (!Base) {
+ if (AllowShortCircuit) return false;
+ AllMatches = false;
+ continue;
+ }
+
+ if (!BaseMatches(cast<CXXRecordDecl>(Base), OpaqueData)) {
+ if (AllowShortCircuit) return false;
+ AllMatches = false;
+ continue;
+ }
+ }
+
+ if (Queue.empty()) break;
+ Record = Queue.back(); // not actually a queue.
+ Queue.pop_back();
+ }
+
+ return AllMatches;
+}
+
bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches,
void *UserData,
CXXBasePaths &Paths) const {
OpenPOWER on IntegriCloud