diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-11-10 07:24:09 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-11-10 07:24:09 +0000 |
commit | dc97457178d08a2e5e74dac716ae20018ee68367 (patch) | |
tree | 63f769d309785efbe6d241fe0ec842c8c5bf3e99 /clang/lib/Sema | |
parent | e424a9b5ca05763480068f93afecca3ee9c4fe75 (diff) | |
download | bcm5719-llvm-dc97457178d08a2e5e74dac716ae20018ee68367.tar.gz bcm5719-llvm-dc97457178d08a2e5e74dac716ae20018ee68367.zip |
Rework my implementation of circular-reference finding to not use
CXXRecordDecl::forallBases, which does *not* do what I need. Fixes the
failure introduced in r167651.
llvm-svn: 167668
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 1c3d4f2052c..16eddf80ae5 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1018,12 +1018,39 @@ bool Sema::isCurrentClassName(const IdentifierInfo &II, Scope *, return false; } -/// \brief Determine whether we have the same C++ record definition. -/// -/// Used as a helper function in Sema::CheckBaseSpecifier, below. -static bool sameCXXRecordDef(const CXXRecordDecl *BaseDefinition, - void *UserData) { - return (CXXRecordDecl *)UserData != BaseDefinition; +/// \brief Determine whether the given class is a base class of the given +/// class, including looking at dependent bases. +static bool findCircularInheritance(const CXXRecordDecl *Class, + const CXXRecordDecl *Current) { + SmallVector<const CXXRecordDecl*, 8> Queue; + + Class = Class->getCanonicalDecl(); + while (true) { + for (CXXRecordDecl::base_class_const_iterator I = Current->bases_begin(), + E = Current->bases_end(); + I != E; ++I) { + CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl(); + if (!Base) + continue; + + Base = Base->getDefinition(); + if (!Base) + continue; + + if (Base->getCanonicalDecl() == Class) + return true; + + Queue.push_back(Base); + } + + if (Queue.empty()) + return false; + + Current = Queue.back(); + Queue.pop_back(); + } + + return false; } /// \brief Check the validity of a C++ base class specifier. @@ -1062,7 +1089,7 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class, if (CXXRecordDecl *BaseDecl = BaseType->getAsCXXRecordDecl()) { if (BaseDecl->getCanonicalDecl() == Class->getCanonicalDecl() || ((BaseDecl = BaseDecl->getDefinition()) && - !BaseDecl->forallBases(&sameCXXRecordDef, Class))) { + findCircularInheritance(Class, BaseDecl))) { Diag(BaseLoc, diag::err_circular_inheritance) << BaseType << Context.getTypeDeclType(Class); |