[cfe-commits] r167668 - in /cfe/trunk: include/clang/AST/DeclCXX.h lib/AST/CXXInheritance.cpp lib/Sema/SemaDeclCXX.cpp test/SemaTemplate/dependent-names.cpp
Douglas Gregor
dgregor at apple.com
Fri Nov 9 23:24:10 PST 2012
Author: dgregor
Date: Sat Nov 10 01:24:09 2012
New Revision: 167668
URL: http://llvm.org/viewvc/llvm-project?rev=167668&view=rev
Log:
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.
Modified:
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/lib/AST/CXXInheritance.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/SemaTemplate/dependent-names.cpp
Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=167668&r1=167667&r2=167668&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Sat Nov 10 01:24:09 2012
@@ -1322,12 +1322,8 @@
/// \param AllowShortCircuit if false, forces the callback to be called
/// for every base class, even if a dependent or non-matching base was
/// found.
- ///
- /// \param VisitDependent whether we should also visit dependent bases
- /// that can be resolved to CXXRecordDecls.
bool forallBases(ForallBasesCallback *BaseMatches, void *UserData,
- bool AllowShortCircuit = true,
- bool VisitDependent = false) const;
+ bool AllowShortCircuit = true) const;
/// \brief Function type used by lookupInBases() to determine whether a
/// specific base class subobject matches the lookup criteria.
Modified: cfe/trunk/lib/AST/CXXInheritance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CXXInheritance.cpp?rev=167668&r1=167667&r2=167668&view=diff
==============================================================================
--- cfe/trunk/lib/AST/CXXInheritance.cpp (original)
+++ cfe/trunk/lib/AST/CXXInheritance.cpp Sat Nov 10 01:24:09 2012
@@ -123,8 +123,7 @@
bool CXXRecordDecl::forallBases(ForallBasesCallback *BaseMatches,
void *OpaqueData,
- bool AllowShortCircuit,
- bool VisitDependent) const {
+ bool AllowShortCircuit) const {
SmallVector<const CXXRecordDecl*, 8> Queue;
const CXXRecordDecl *Record = this;
@@ -132,14 +131,15 @@
while (true) {
for (CXXRecordDecl::base_class_const_iterator
I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) {
- CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
- if (!Base || (!VisitDependent && I->getType()->isDependentType())) {
+ const RecordType *Ty = I->getType()->getAs<RecordType>();
+ if (!Ty) {
if (AllowShortCircuit) return false;
AllMatches = false;
continue;
}
- Base = Base->getDefinition();
+ CXXRecordDecl *Base =
+ cast_or_null<CXXRecordDecl>(Ty->getDecl()->getDefinition());
if (!Base) {
if (AllowShortCircuit) return false;
AllMatches = false;
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=167668&r1=167667&r2=167668&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Sat Nov 10 01:24:09 2012
@@ -1018,12 +1018,39 @@
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 @@
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);
Modified: cfe/trunk/test/SemaTemplate/dependent-names.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/dependent-names.cpp?rev=167668&r1=167667&r2=167668&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/dependent-names.cpp (original)
+++ cfe/trunk/test/SemaTemplate/dependent-names.cpp Sat Nov 10 01:24:09 2012
@@ -336,6 +336,9 @@
virtual void foo() { }
};
struct B;
+
+ struct D : T::foo { };
+ struct E : D { };
};
template<class T>
More information about the cfe-commits
mailing list