1a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor//===------ CXXInheritance.cpp - C++ Inheritance ----------------*- C++ -*-===// 2a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor// 3a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor// The LLVM Compiler Infrastructure 4a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor// 5a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor// This file is distributed under the University of Illinois Open Source 6a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor// License. See LICENSE.TXT for details. 7a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor// 8a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor//===----------------------------------------------------------------------===// 9a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor// 10a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor// This file provides routines that help analyzing C++ inheritance hierarchies. 11a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor// 12a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor//===----------------------------------------------------------------------===// 13a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor#include "clang/AST/CXXInheritance.h" 14d4f5198ae07d9a4958d8191bac694ded12173ad9Benjamin Kramer#include "clang/AST/ASTContext.h" 15a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor#include "clang/AST/DeclCXX.h" 1655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/RecordLayout.h" 17a13cdf4780a885c0d3726fe8d3562b9bc770b7ecDouglas Gregor#include "llvm/ADT/SetVector.h" 18a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor#include <algorithm> 19a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor#include <set> 20a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 21a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregorusing namespace clang; 22a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 23a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor/// \brief Computes the set of declarations referenced by these base 24a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor/// paths. 25a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregorvoid CXXBasePaths::ComputeDeclsFound() { 26a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor assert(NumDeclsFound == 0 && !DeclsFound && 27a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor "Already computed the set of declarations"); 28d0e49e587afd15ccc6c2f910a979f0d3d602d166Benjamin Kramer 29a13cdf4780a885c0d3726fe8d3562b9bc770b7ecDouglas Gregor llvm::SetVector<NamedDecl *, SmallVector<NamedDecl *, 8> > Decls; 30d0e49e587afd15ccc6c2f910a979f0d3d602d166Benjamin Kramer for (paths_iterator Path = begin(), PathEnd = end(); Path != PathEnd; ++Path) 313bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie Decls.insert(Path->Decls.front()); 32d0e49e587afd15ccc6c2f910a979f0d3d602d166Benjamin Kramer 33a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor NumDeclsFound = Decls.size(); 34a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar DeclsFound = llvm::make_unique<NamedDecl *[]>(NumDeclsFound); 35a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar std::copy(Decls.begin(), Decls.end(), DeclsFound.get()); 36a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor} 37a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 38651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesCXXBasePaths::decl_range CXXBasePaths::found_decls() { 39a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor if (NumDeclsFound == 0) 40a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor ComputeDeclsFound(); 41a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 42a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return decl_range(decl_iterator(DeclsFound.get()), 43a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar decl_iterator(DeclsFound.get() + NumDeclsFound)); 44a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor} 45a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 46a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor/// isAmbiguous - Determines whether the set of paths provided is 47a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor/// ambiguous, i.e., there are two or more paths that refer to 48a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor/// different base class subobjects of the same type. BaseType must be 49a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor/// an unqualified, canonical class type. 50e0d5fe2a417b84ac8b51927ebeb8f1c9ae492760Douglas Gregorbool CXXBasePaths::isAmbiguous(CanQualType BaseType) { 51e0d5fe2a417b84ac8b51927ebeb8f1c9ae492760Douglas Gregor BaseType = BaseType.getUnqualifiedType(); 52a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType]; 53a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor return Subobjects.second + (Subobjects.first? 1 : 0) > 1; 54a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor} 55a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 56a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor/// clear - Clear out all prior path information. 57a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregorvoid CXXBasePaths::clear() { 58a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor Paths.clear(); 59a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor ClassSubobjects.clear(); 60a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor ScratchPath.clear(); 616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines DetectedVirtual = nullptr; 62a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor} 63a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 64a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor/// @brief Swaps the contents of this CXXBasePaths structure with the 65a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor/// contents of Other. 66a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregorvoid CXXBasePaths::swap(CXXBasePaths &Other) { 67a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor std::swap(Origin, Other.Origin); 68a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor Paths.swap(Other.Paths); 69a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor ClassSubobjects.swap(Other.ClassSubobjects); 70a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor std::swap(FindAmbiguities, Other.FindAmbiguities); 71a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor std::swap(RecordPaths, Other.RecordPaths); 72a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor std::swap(DetectVirtual, Other.DetectVirtual); 73a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor std::swap(DetectedVirtual, Other.DetectedVirtual); 74a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor} 75a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 76d89d30fdd9e3061fb100fb8f976aab5c6cf2c901John McCallbool CXXRecordDecl::isDerivedFrom(const CXXRecordDecl *Base) const { 77a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false, 78a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor /*DetectVirtual=*/false); 79a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor return isDerivedFrom(Base, Paths); 80a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor} 81a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 82d89d30fdd9e3061fb100fb8f976aab5c6cf2c901John McCallbool CXXRecordDecl::isDerivedFrom(const CXXRecordDecl *Base, 83d89d30fdd9e3061fb100fb8f976aab5c6cf2c901John McCall CXXBasePaths &Paths) const { 84a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor if (getCanonicalDecl() == Base->getCanonicalDecl()) 85a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor return false; 86a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 87af8e6ed61b5e80ab95632b63f583af79dcb62590John McCall Paths.setOrigin(const_cast<CXXRecordDecl*>(this)); 88a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 89a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const CXXRecordDecl *BaseDecl = Base->getCanonicalDecl(); 90a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // FIXME: Capturing 'this' is a workaround for name lookup bugs in GCC 4.7. 91a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return lookupInBases( 92a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar [this, BaseDecl](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) { 93a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return FindBaseClass(Specifier, Path, BaseDecl); 94a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar }, 95a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Paths); 96a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor} 97a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 982aa800a955132d83a666bcd52d3d59d09cffc079Jordan Rosebool CXXRecordDecl::isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const { 991c4c397c581ad7106fc911fc4592c7aca163b5bcAnders Carlsson if (!getNumVBases()) 1001c4c397c581ad7106fc911fc4592c7aca163b5bcAnders Carlsson return false; 1011c4c397c581ad7106fc911fc4592c7aca163b5bcAnders Carlsson 1024e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false, 1034e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor /*DetectVirtual=*/false); 1044e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor 1054e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor if (getCanonicalDecl() == Base->getCanonicalDecl()) 1064e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor return false; 1074e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor 1082aa800a955132d83a666bcd52d3d59d09cffc079Jordan Rose Paths.setOrigin(const_cast<CXXRecordDecl*>(this)); 1092aa800a955132d83a666bcd52d3d59d09cffc079Jordan Rose 110a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const CXXRecordDecl *BaseDecl = Base->getCanonicalDecl(); 111a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // FIXME: Capturing 'this' is a workaround for name lookup bugs in GCC 4.7. 112a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return lookupInBases( 113a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar [this, BaseDecl](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) { 114a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return FindVirtualBaseClass(Specifier, Path, BaseDecl); 115a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar }, 116a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Paths); 117e8174bc483615e79614d9284a50ac94831e8b7c6John McCall} 118e8174bc483615e79614d9284a50ac94831e8b7c6John McCall 119e8174bc483615e79614d9284a50ac94831e8b7c6John McCallbool CXXRecordDecl::isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const { 120a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const CXXRecordDecl *TargetDecl = Base->getCanonicalDecl(); 121a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return forallBases([TargetDecl](const CXXRecordDecl *Base) { 122a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return Base->getCanonicalDecl() != TargetDecl; 123a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar }); 124e8174bc483615e79614d9284a50ac94831e8b7c6John McCall} 125e8174bc483615e79614d9284a50ac94831e8b7c6John McCall 126f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smithbool 127f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard SmithCXXRecordDecl::isCurrentInstantiation(const DeclContext *CurContext) const { 128f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith assert(isDependentContext()); 129f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith 130f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith for (; !CurContext->isFileContext(); CurContext = CurContext->getParent()) 131f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith if (CurContext->Equals(this)) 132f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith return true; 133f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith 134f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith return false; 135f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith} 136f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith 137a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainarbool CXXRecordDecl::forallBases(ForallBasesCallback BaseMatches, 138229d47aef27e6f65fe4dc3beb22f622dd81104adDouglas Gregor bool AllowShortCircuit) const { 1395f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<const CXXRecordDecl*, 8> Queue; 140e8174bc483615e79614d9284a50ac94831e8b7c6John McCall 141e8174bc483615e79614d9284a50ac94831e8b7c6John McCall const CXXRecordDecl *Record = this; 142e8174bc483615e79614d9284a50ac94831e8b7c6John McCall bool AllMatches = true; 143e8174bc483615e79614d9284a50ac94831e8b7c6John McCall while (true) { 144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &I : Record->bases()) { 145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const RecordType *Ty = I.getType()->getAs<RecordType>(); 146229d47aef27e6f65fe4dc3beb22f622dd81104adDouglas Gregor if (!Ty) { 147e8174bc483615e79614d9284a50ac94831e8b7c6John McCall if (AllowShortCircuit) return false; 148e8174bc483615e79614d9284a50ac94831e8b7c6John McCall AllMatches = false; 149e8174bc483615e79614d9284a50ac94831e8b7c6John McCall continue; 150e8174bc483615e79614d9284a50ac94831e8b7c6John McCall } 151e8174bc483615e79614d9284a50ac94831e8b7c6John McCall 152229d47aef27e6f65fe4dc3beb22f622dd81104adDouglas Gregor CXXRecordDecl *Base = 153229d47aef27e6f65fe4dc3beb22f622dd81104adDouglas Gregor cast_or_null<CXXRecordDecl>(Ty->getDecl()->getDefinition()); 154f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith if (!Base || 155f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith (Base->isDependentContext() && 156f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith !Base->isCurrentInstantiation(Record))) { 157e8174bc483615e79614d9284a50ac94831e8b7c6John McCall if (AllowShortCircuit) return false; 158e8174bc483615e79614d9284a50ac94831e8b7c6John McCall AllMatches = false; 159e8174bc483615e79614d9284a50ac94831e8b7c6John McCall continue; 160e8174bc483615e79614d9284a50ac94831e8b7c6John McCall } 161e8174bc483615e79614d9284a50ac94831e8b7c6John McCall 162ca910e84ea026a898c7184d3f3608403005b9bc0Anders Carlsson Queue.push_back(Base); 163a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (!BaseMatches(Base)) { 164e8174bc483615e79614d9284a50ac94831e8b7c6John McCall if (AllowShortCircuit) return false; 165e8174bc483615e79614d9284a50ac94831e8b7c6John McCall AllMatches = false; 166e8174bc483615e79614d9284a50ac94831e8b7c6John McCall continue; 167e8174bc483615e79614d9284a50ac94831e8b7c6John McCall } 168e8174bc483615e79614d9284a50ac94831e8b7c6John McCall } 169e8174bc483615e79614d9284a50ac94831e8b7c6John McCall 170344472ebeded2fca2ed5013b9e87f81d09bfa908Robert Wilhelm if (Queue.empty()) 171344472ebeded2fca2ed5013b9e87f81d09bfa908Robert Wilhelm break; 172344472ebeded2fca2ed5013b9e87f81d09bfa908Robert Wilhelm Record = Queue.pop_back_val(); // not actually a queue. 173e8174bc483615e79614d9284a50ac94831e8b7c6John McCall } 174e8174bc483615e79614d9284a50ac94831e8b7c6John McCall 175e8174bc483615e79614d9284a50ac94831e8b7c6John McCall return AllMatches; 176e8174bc483615e79614d9284a50ac94831e8b7c6John McCall} 177e8174bc483615e79614d9284a50ac94831e8b7c6John McCall 178a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainarbool CXXBasePaths::lookupInBases( 179a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASTContext &Context, const CXXRecordDecl *Record, 180a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CXXRecordDecl::BaseMatchesCallback BaseMatches) { 181a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor bool FoundPath = false; 18246460a68f6508775e98c19b4bb8454bb471aac24John McCall 18392f883177b162928a8e632e4e3b93fafd2b26072John McCall // The access of the path down to this record. 18489b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor AccessSpecifier AccessToHere = ScratchPath.Access; 18589b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor bool IsFirstStep = ScratchPath.empty(); 18692f883177b162928a8e632e4e3b93fafd2b26072John McCall 187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &BaseSpec : Record->bases()) { 188a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // Find the record of the base class subobjects for this type. 189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType BaseType = 190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Context.getCanonicalType(BaseSpec.getType()).getUnqualifiedType(); 191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 192a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // C++ [temp.dep]p3: 193a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // In the definition of a class template or a member of a class template, 194a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // if a base class of the class template depends on a template-parameter, 195a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // the base class scope is not examined during unqualified name lookup 196a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // either at the point of definition of the class template or member or 197a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // during an instantiation of the class tem- plate or member. 198a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor if (BaseType->isDependentType()) 199a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor continue; 200a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 201a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // Determine whether we need to visit this base class at all, 202a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // updating the count of subobjects appropriately. 20389b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType]; 204a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor bool VisitBase = true; 205a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor bool SetVirtual = false; 206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (BaseSpec.isVirtual()) { 207a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor VisitBase = !Subobjects.first; 208a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor Subobjects.first = true; 2096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (isDetectingVirtual() && DetectedVirtual == nullptr) { 210a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // If this is the first virtual we find, remember it. If it turns out 211a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // there is no base path here, we'll reset it later. 21289b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor DetectedVirtual = BaseType->getAs<RecordType>(); 213a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor SetVirtual = true; 214a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor } 215a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor } else 216a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor ++Subobjects.second; 217a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 21889b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor if (isRecordingPaths()) { 219a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // Add this base specifier to the current path. 220a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor CXXBasePathElement Element; 221651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Element.Base = &BaseSpec; 22289b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor Element.Class = Record; 223651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (BaseSpec.isVirtual()) 224a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor Element.SubobjectNumber = 0; 225a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor else 226a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor Element.SubobjectNumber = Subobjects.second; 22789b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor ScratchPath.push_back(Element); 22846460a68f6508775e98c19b4bb8454bb471aac24John McCall 22992f883177b162928a8e632e4e3b93fafd2b26072John McCall // Calculate the "top-down" access to this base class. 23092f883177b162928a8e632e4e3b93fafd2b26072John McCall // The spec actually describes this bottom-up, but top-down is 23192f883177b162928a8e632e4e3b93fafd2b26072John McCall // equivalent because the definition works out as follows: 23292f883177b162928a8e632e4e3b93fafd2b26072John McCall // 1. Write down the access along each step in the inheritance 23392f883177b162928a8e632e4e3b93fafd2b26072John McCall // chain, followed by the access of the decl itself. 23492f883177b162928a8e632e4e3b93fafd2b26072John McCall // For example, in 23592f883177b162928a8e632e4e3b93fafd2b26072John McCall // class A { public: int foo; }; 23692f883177b162928a8e632e4e3b93fafd2b26072John McCall // class B : protected A {}; 23792f883177b162928a8e632e4e3b93fafd2b26072John McCall // class C : public B {}; 23892f883177b162928a8e632e4e3b93fafd2b26072John McCall // class D : private C {}; 23992f883177b162928a8e632e4e3b93fafd2b26072John McCall // we would write: 24092f883177b162928a8e632e4e3b93fafd2b26072John McCall // private public protected public 24192f883177b162928a8e632e4e3b93fafd2b26072John McCall // 2. If 'private' appears anywhere except far-left, access is denied. 24292f883177b162928a8e632e4e3b93fafd2b26072John McCall // 3. Otherwise, overall access is determined by the most restrictive 24392f883177b162928a8e632e4e3b93fafd2b26072John McCall // access in the sequence. 24492f883177b162928a8e632e4e3b93fafd2b26072John McCall if (IsFirstStep) 245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ScratchPath.Access = BaseSpec.getAccessSpecifier(); 24692f883177b162928a8e632e4e3b93fafd2b26072John McCall else 24789b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor ScratchPath.Access = CXXRecordDecl::MergeAccess(AccessToHere, 248651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BaseSpec.getAccessSpecifier()); 249a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor } 250ed814cc4cd2bd4d32cbb4bfde3cc59ccae723a92John McCall 251ed814cc4cd2bd4d32cbb4bfde3cc59ccae723a92John McCall // Track whether there's a path involving this specific base. 252ed814cc4cd2bd4d32cbb4bfde3cc59ccae723a92John McCall bool FoundPathThroughBase = false; 253ed814cc4cd2bd4d32cbb4bfde3cc59ccae723a92John McCall 254a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (BaseMatches(&BaseSpec, ScratchPath)) { 25592f883177b162928a8e632e4e3b93fafd2b26072John McCall // We've found a path that terminates at this base. 256ed814cc4cd2bd4d32cbb4bfde3cc59ccae723a92John McCall FoundPath = FoundPathThroughBase = true; 25789b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor if (isRecordingPaths()) { 258a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // We have a path. Make a copy of it before moving on. 25989b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor Paths.push_back(ScratchPath); 26089b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor } else if (!isFindingAmbiguities()) { 261a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // We found a path and we don't care about ambiguities; 262a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // return immediately. 263a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor return FoundPath; 264a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor } 265a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor } else if (VisitBase) { 266a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor CXXRecordDecl *BaseRecord 267651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines = cast<CXXRecordDecl>(BaseSpec.getType()->castAs<RecordType>() 268a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor ->getDecl()); 269a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (lookupInBases(Context, BaseRecord, BaseMatches)) { 270a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // C++ [class.member.lookup]p2: 271a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // A member name f in one sub-object B hides a member name f in 272a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // a sub-object A if A is a base class sub-object of B. Any 273a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // declarations that are so hidden are eliminated from 274a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // consideration. 275a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 276a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // There is a path to a base class that meets the criteria. If we're 277a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // not collecting paths or finding ambiguities, we're done. 278ed814cc4cd2bd4d32cbb4bfde3cc59ccae723a92John McCall FoundPath = FoundPathThroughBase = true; 27989b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor if (!isFindingAmbiguities()) 280a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor return FoundPath; 281a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor } 282a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor } 283a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 284a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // Pop this base specifier off the current path (if we're 285a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // collecting paths). 28689b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor if (isRecordingPaths()) { 28789b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor ScratchPath.pop_back(); 28846460a68f6508775e98c19b4bb8454bb471aac24John McCall } 28946460a68f6508775e98c19b4bb8454bb471aac24John McCall 290a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // If we set a virtual earlier, and this isn't a path, forget it again. 291ed814cc4cd2bd4d32cbb4bfde3cc59ccae723a92John McCall if (SetVirtual && !FoundPathThroughBase) { 2926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines DetectedVirtual = nullptr; 293a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor } 294a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor } 29592f883177b162928a8e632e4e3b93fafd2b26072John McCall 29692f883177b162928a8e632e4e3b93fafd2b26072John McCall // Reset the scratch path access. 29789b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor ScratchPath.Access = AccessToHere; 298a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 299a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor return FoundPath; 300a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor} 301a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 302a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainarbool CXXRecordDecl::lookupInBases(BaseMatchesCallback BaseMatches, 30389b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor CXXBasePaths &Paths) const { 3044e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // If we didn't find anything, report that. 305a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (!Paths.lookupInBases(getASTContext(), this, BaseMatches)) 3064e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor return false; 3074e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor 3084e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // If we're not recording paths or we won't ever find ambiguities, 3094e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // we're done. 3104e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor if (!Paths.isRecordingPaths() || !Paths.isFindingAmbiguities()) 3114e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor return true; 3124e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor 3134e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // C++ [class.member.lookup]p6: 3144e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // When virtual base classes are used, a hidden declaration can be 3154e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // reached along a path through the sub-object lattice that does 3164e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // not pass through the hiding declaration. This is not an 3174e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // ambiguity. The identical use with nonvirtual base classes is an 3184e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // ambiguity; in that case there is no unique instance of the name 3194e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // that hides all the others. 3204e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // 3214e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // FIXME: This is an O(N^2) algorithm, but DPG doesn't see an easy 3224e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // way to make it any faster. 3230e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Paths.Paths.remove_if([&Paths](const CXXBasePath &Path) { 3240e2c34f92f00628d48968dfea096d36381f494cbStephen Hines for (const CXXBasePathElement &PE : Path) { 3250e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (!PE.Base->isVirtual()) 3260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines continue; 3270e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 3280e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CXXRecordDecl *VBase = nullptr; 3290e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (const RecordType *Record = PE.Base->getType()->getAs<RecordType>()) 3300e2c34f92f00628d48968dfea096d36381f494cbStephen Hines VBase = cast<CXXRecordDecl>(Record->getDecl()); 3310e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (!VBase) 3320e2c34f92f00628d48968dfea096d36381f494cbStephen Hines break; 3330e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 3340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // The declaration(s) we found along this path were found in a 3350e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // subobject of a virtual base. Check whether this virtual 3360e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // base is a subobject of any other path; if so, then the 3370e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // declaration in this path are hidden by that patch. 3380e2c34f92f00628d48968dfea096d36381f494cbStephen Hines for (const CXXBasePath &HidingP : Paths) { 3390e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CXXRecordDecl *HidingClass = nullptr; 3400e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (const RecordType *Record = 3410e2c34f92f00628d48968dfea096d36381f494cbStephen Hines HidingP.back().Base->getType()->getAs<RecordType>()) 3420e2c34f92f00628d48968dfea096d36381f494cbStephen Hines HidingClass = cast<CXXRecordDecl>(Record->getDecl()); 3430e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (!HidingClass) 3444e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor break; 3454e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor 3460e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (HidingClass->isVirtuallyDerivedFrom(VBase)) 3470e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return true; 3484e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor } 3494e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor } 3500e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return false; 3510e2c34f92f00628d48968dfea096d36381f494cbStephen Hines }); 3524e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor 3534e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor return true; 35489b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor} 35589b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor 356af8e6ed61b5e80ab95632b63f583af79dcb62590John McCallbool CXXRecordDecl::FindBaseClass(const CXXBaseSpecifier *Specifier, 357a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor CXXBasePath &Path, 358a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const CXXRecordDecl *BaseRecord) { 359a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar assert(BaseRecord->getCanonicalDecl() == BaseRecord && 360a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor "User data for FindBaseClass is not canonical!"); 361890f0f1612b0028b8b16730ae7ed07e295600c76Ted Kremenek return Specifier->getType()->castAs<RecordType>()->getDecl() 362890f0f1612b0028b8b16730ae7ed07e295600c76Ted Kremenek ->getCanonicalDecl() == BaseRecord; 363a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor} 364a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 3654e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregorbool CXXRecordDecl::FindVirtualBaseClass(const CXXBaseSpecifier *Specifier, 3664e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor CXXBasePath &Path, 367a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const CXXRecordDecl *BaseRecord) { 368a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar assert(BaseRecord->getCanonicalDecl() == BaseRecord && 3694e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor "User data for FindBaseClass is not canonical!"); 3704e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor return Specifier->isVirtual() && 371890f0f1612b0028b8b16730ae7ed07e295600c76Ted Kremenek Specifier->getType()->castAs<RecordType>()->getDecl() 372890f0f1612b0028b8b16730ae7ed07e295600c76Ted Kremenek ->getCanonicalDecl() == BaseRecord; 3734e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor} 3744e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor 375af8e6ed61b5e80ab95632b63f583af79dcb62590John McCallbool CXXRecordDecl::FindTagMember(const CXXBaseSpecifier *Specifier, 376a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor CXXBasePath &Path, 377a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar DeclarationName Name) { 378890f0f1612b0028b8b16730ae7ed07e295600c76Ted Kremenek RecordDecl *BaseRecord = 379890f0f1612b0028b8b16730ae7ed07e295600c76Ted Kremenek Specifier->getType()->castAs<RecordType>()->getDecl(); 380a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 381a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar for (Path.Decls = BaseRecord->lookup(Name); 3823bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie !Path.Decls.empty(); 3833bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie Path.Decls = Path.Decls.slice(1)) { 3843bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie if (Path.Decls.front()->isInIdentifierNamespace(IDNS_Tag)) 385a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor return true; 386a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor } 387a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 388a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor return false; 389a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor} 390a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 391af8e6ed61b5e80ab95632b63f583af79dcb62590John McCallbool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier, 392a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor CXXBasePath &Path, 393a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar DeclarationName Name) { 394890f0f1612b0028b8b16730ae7ed07e295600c76Ted Kremenek RecordDecl *BaseRecord = 395890f0f1612b0028b8b16730ae7ed07e295600c76Ted Kremenek Specifier->getType()->castAs<RecordType>()->getDecl(); 396a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 397a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor const unsigned IDNS = IDNS_Ordinary | IDNS_Tag | IDNS_Member; 398a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar for (Path.Decls = BaseRecord->lookup(Name); 3993bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie !Path.Decls.empty(); 4003bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie Path.Decls = Path.Decls.slice(1)) { 4013bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie if (Path.Decls.front()->isInIdentifierNamespace(IDNS)) 402a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor return true; 403a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor } 404a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 405a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor return false; 406a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor} 407a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 408af8e6ed61b5e80ab95632b63f583af79dcb62590John McCallbool CXXRecordDecl:: 409af8e6ed61b5e80ab95632b63f583af79dcb62590John McCallFindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier, 410af8e6ed61b5e80ab95632b63f583af79dcb62590John McCall CXXBasePath &Path, 411a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar DeclarationName Name) { 412890f0f1612b0028b8b16730ae7ed07e295600c76Ted Kremenek RecordDecl *BaseRecord = 413890f0f1612b0028b8b16730ae7ed07e295600c76Ted Kremenek Specifier->getType()->castAs<RecordType>()->getDecl(); 414a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 415a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar for (Path.Decls = BaseRecord->lookup(Name); 4163bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie !Path.Decls.empty(); 4173bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie Path.Decls = Path.Decls.slice(1)) { 418a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // FIXME: Refactor the "is it a nested-name-specifier?" check 4193bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie if (isa<TypedefNameDecl>(Path.Decls.front()) || 4203bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie Path.Decls.front()->isInIdentifierNamespace(IDNS_Tag)) 421a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor return true; 422a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor } 423a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 424a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor return false; 42582109bd64a8494c801263c11f4d2294f47e21807Mike Stump} 4267b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 4277b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregorvoid OverridingMethods::add(unsigned OverriddenSubobject, 4287b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor UniqueVirtualMethod Overriding) { 42909d19efaa147762f84aed55efa7930bb3616a4e5Craig Topper SmallVectorImpl<UniqueVirtualMethod> &SubobjectOverrides 4307b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor = Overrides[OverriddenSubobject]; 4317b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor if (std::find(SubobjectOverrides.begin(), SubobjectOverrides.end(), 4327b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor Overriding) == SubobjectOverrides.end()) 4337b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor SubobjectOverrides.push_back(Overriding); 4347b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor} 4357b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 4367b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregorvoid OverridingMethods::add(const OverridingMethods &Other) { 4377b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor for (const_iterator I = Other.begin(), IE = Other.end(); I != IE; ++I) { 4387b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor for (overriding_const_iterator M = I->second.begin(), 4397b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor MEnd = I->second.end(); 4407b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor M != MEnd; 4417b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor ++M) 4427b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor add(I->first, *M); 4437b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 4447b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor} 4457b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 4467b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregorvoid OverridingMethods::replaceAll(UniqueVirtualMethod Overriding) { 4477b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor for (iterator I = begin(), IEnd = end(); I != IEnd; ++I) { 4487b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor I->second.clear(); 4497b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor I->second.push_back(Overriding); 4507b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 4517b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor} 4527b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 4537b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 4547b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregornamespace { 4557b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor class FinalOverriderCollector { 4567b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor /// \brief The number of subobjects of a given class type that 4577b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor /// occur within the class hierarchy. 4587b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor llvm::DenseMap<const CXXRecordDecl *, unsigned> SubobjectCount; 4597b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 4607b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor /// \brief Overriders for each virtual base subobject. 4617b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor llvm::DenseMap<const CXXRecordDecl *, CXXFinalOverriderMap *> VirtualOverriders; 4627b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 4637b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor CXXFinalOverriderMap FinalOverriders; 4647b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 4657b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor public: 4667b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor ~FinalOverriderCollector(); 4677b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 4687b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor void Collect(const CXXRecordDecl *RD, bool VirtualBase, 4697b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor const CXXRecordDecl *InVirtualSubobject, 4707b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor CXXFinalOverriderMap &Overriders); 4717b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor }; 4727b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor} 4737b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 4747b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregorvoid FinalOverriderCollector::Collect(const CXXRecordDecl *RD, 4757b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor bool VirtualBase, 4767b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor const CXXRecordDecl *InVirtualSubobject, 4777b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor CXXFinalOverriderMap &Overriders) { 4787b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor unsigned SubobjectNumber = 0; 4797b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor if (!VirtualBase) 4807b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor SubobjectNumber 4817b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor = ++SubobjectCount[cast<CXXRecordDecl>(RD->getCanonicalDecl())]; 4827b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 483651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &Base : RD->bases()) { 484651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const RecordType *RT = Base.getType()->getAs<RecordType>()) { 4857b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor const CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(RT->getDecl()); 4867b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor if (!BaseDecl->isPolymorphic()) 4877b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor continue; 4887b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 489651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Overriders.empty() && !Base.isVirtual()) { 4907b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // There are no other overriders of virtual member functions, 4917b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // so let the base class fill in our overriders for us. 4927b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor Collect(BaseDecl, false, InVirtualSubobject, Overriders); 4937b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor continue; 4947b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 4957b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 4967b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // Collect all of the overridders from the base class subobject 4977b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // and merge them into the set of overridders for this class. 4987b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // For virtual base classes, populate or use the cached virtual 4997b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // overrides so that we do not walk the virtual base class (and 5007b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // its base classes) more than once. 5017b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor CXXFinalOverriderMap ComputedBaseOverriders; 5027b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor CXXFinalOverriderMap *BaseOverriders = &ComputedBaseOverriders; 503651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Base.isVirtual()) { 5047b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor CXXFinalOverriderMap *&MyVirtualOverriders = VirtualOverriders[BaseDecl]; 505e0cf31dc263979027f345c00318a704c5f5b1e76Benjamin Kramer BaseOverriders = MyVirtualOverriders; 5067b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor if (!MyVirtualOverriders) { 5077b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor MyVirtualOverriders = new CXXFinalOverriderMap; 508e0cf31dc263979027f345c00318a704c5f5b1e76Benjamin Kramer 509e0cf31dc263979027f345c00318a704c5f5b1e76Benjamin Kramer // Collect may cause VirtualOverriders to reallocate, invalidating the 510e0cf31dc263979027f345c00318a704c5f5b1e76Benjamin Kramer // MyVirtualOverriders reference. Set BaseOverriders to the right 511e0cf31dc263979027f345c00318a704c5f5b1e76Benjamin Kramer // value now. 512e0cf31dc263979027f345c00318a704c5f5b1e76Benjamin Kramer BaseOverriders = MyVirtualOverriders; 513e0cf31dc263979027f345c00318a704c5f5b1e76Benjamin Kramer 5147b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor Collect(BaseDecl, true, BaseDecl, *MyVirtualOverriders); 5157b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 5167b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } else 5177b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor Collect(BaseDecl, false, InVirtualSubobject, ComputedBaseOverriders); 5187b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 5197b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // Merge the overriders from this base class into our own set of 5207b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // overriders. 5217b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor for (CXXFinalOverriderMap::iterator OM = BaseOverriders->begin(), 5227b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor OMEnd = BaseOverriders->end(); 5237b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor OM != OMEnd; 5247b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor ++OM) { 5257b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor const CXXMethodDecl *CanonOM 5267b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor = cast<CXXMethodDecl>(OM->first->getCanonicalDecl()); 5277b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor Overriders[CanonOM].add(OM->second); 5287b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 5297b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 5307b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 5317b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 532651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *M : RD->methods()) { 5337b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // We only care about virtual methods. 5347b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor if (!M->isVirtual()) 5357b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor continue; 5367b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 5377b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor CXXMethodDecl *CanonM = cast<CXXMethodDecl>(M->getCanonicalDecl()); 5387b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 5397b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor if (CanonM->begin_overridden_methods() 5407b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor == CanonM->end_overridden_methods()) { 5417b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // This is a new virtual function that does not override any 5427b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // other virtual function. Add it to the map of virtual 5437b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // functions for which we are tracking overridders. 5447b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 5457b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // C++ [class.virtual]p2: 5467b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // For convenience we say that any virtual function overrides itself. 5477b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor Overriders[CanonM].add(SubobjectNumber, 5487b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor UniqueVirtualMethod(CanonM, SubobjectNumber, 5497b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor InVirtualSubobject)); 5507b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor continue; 5517b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 5527b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 5537b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // This virtual method overrides other virtual methods, so it does 5547b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // not add any new slots into the set of overriders. Instead, we 5557b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // replace entries in the set of overriders with the new 5567b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // overrider. To do so, we dig down to the original virtual 5577b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // functions using data recursion and update all of the methods it 5587b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // overrides. 5590e2c34f92f00628d48968dfea096d36381f494cbStephen Hines typedef llvm::iterator_range<CXXMethodDecl::method_iterator> 5600e2c34f92f00628d48968dfea096d36381f494cbStephen Hines OverriddenMethods; 5615f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<OverriddenMethods, 4> Stack; 5620e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Stack.push_back(llvm::make_range(CanonM->begin_overridden_methods(), 5630e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CanonM->end_overridden_methods())); 5647b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor while (!Stack.empty()) { 5650e2c34f92f00628d48968dfea096d36381f494cbStephen Hines for (const CXXMethodDecl *OM : Stack.pop_back_val()) { 5660e2c34f92f00628d48968dfea096d36381f494cbStephen Hines const CXXMethodDecl *CanonOM = OM->getCanonicalDecl(); 567ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson 568ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson // C++ [class.virtual]p2: 569ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson // A virtual member function C::vf of a class object S is 570ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson // a final overrider unless the most derived class (1.8) 571ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson // of which S is a base class subobject (if any) declares 572ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson // or inherits another member function that overrides vf. 573ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson // 574ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson // Treating this object like the most derived class, we 575ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson // replace any overrides from base classes with this 576ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson // overriding virtual function. 577ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson Overriders[CanonOM].replaceAll( 578ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson UniqueVirtualMethod(CanonM, SubobjectNumber, 579ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson InVirtualSubobject)); 580ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson 5817b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor if (CanonOM->begin_overridden_methods() 582ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson == CanonOM->end_overridden_methods()) 5837b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor continue; 5847b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 5857b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // Continue recursion to the methods that this virtual method 5867b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // overrides. 5870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Stack.push_back(llvm::make_range(CanonOM->begin_overridden_methods(), 5880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CanonOM->end_overridden_methods())); 5897b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 5907b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 591ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson 592ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson // C++ [class.virtual]p2: 593ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson // For convenience we say that any virtual function overrides itself. 594ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson Overriders[CanonM].add(SubobjectNumber, 595ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson UniqueVirtualMethod(CanonM, SubobjectNumber, 596ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson InVirtualSubobject)); 5977b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 5987b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor} 5997b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 6007b2fc9d3c97f2526528a8b686af1589054025ca0Douglas GregorFinalOverriderCollector::~FinalOverriderCollector() { 6017b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor for (llvm::DenseMap<const CXXRecordDecl *, CXXFinalOverriderMap *>::iterator 6027b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor VO = VirtualOverriders.begin(), VOEnd = VirtualOverriders.end(); 6037b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor VO != VOEnd; 6047b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor ++VO) 6057b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor delete VO->second; 6067b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor} 6077b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 6087b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregorvoid 6097b2fc9d3c97f2526528a8b686af1589054025ca0Douglas GregorCXXRecordDecl::getFinalOverriders(CXXFinalOverriderMap &FinalOverriders) const { 6107b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor FinalOverriderCollector Collector; 6116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Collector.Collect(this, false, nullptr, FinalOverriders); 6127b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 6137b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // Weed out any final overriders that come from virtual base class 6147b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // subobjects that were hidden by other subobjects along any path. 6157b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // This is the final-overrider variant of C++ [class.member.lookup]p10. 6160e2c34f92f00628d48968dfea096d36381f494cbStephen Hines for (auto &OM : FinalOverriders) { 6170e2c34f92f00628d48968dfea096d36381f494cbStephen Hines for (auto &SO : OM.second) { 6180e2c34f92f00628d48968dfea096d36381f494cbStephen Hines SmallVectorImpl<UniqueVirtualMethod> &Overriding = SO.second; 6197b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor if (Overriding.size() < 2) 6207b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor continue; 6217b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 6220e2c34f92f00628d48968dfea096d36381f494cbStephen Hines auto IsHidden = [&Overriding](const UniqueVirtualMethod &M) { 6230e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (!M.InVirtualSubobject) 6240e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return false; 6257b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 6267b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // We have an overriding method in a virtual base class 6277b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // subobject (or non-virtual base class subobject thereof); 6287b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // determine whether there exists an other overriding method 6297b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // in a base class subobject that hides the virtual base class 6307b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // subobject. 6310e2c34f92f00628d48968dfea096d36381f494cbStephen Hines for (const UniqueVirtualMethod &OP : Overriding) 6320e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (&M != &OP && 6330e2c34f92f00628d48968dfea096d36381f494cbStephen Hines OP.Method->getParent()->isVirtuallyDerivedFrom( 6340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines M.InVirtualSubobject)) 6350e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return true; 6360e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return false; 6370e2c34f92f00628d48968dfea096d36381f494cbStephen Hines }; 6380e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 6390e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Overriding.erase( 6400e2c34f92f00628d48968dfea096d36381f494cbStephen Hines std::remove_if(Overriding.begin(), Overriding.end(), IsHidden), 6410e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Overriding.end()); 6427b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 6437b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 6447b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor} 64546170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson 64646170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlssonstatic void 64746170f9c7d561d0f94af34a4b5da909d2584370aAnders CarlssonAddIndirectPrimaryBases(const CXXRecordDecl *RD, ASTContext &Context, 64846170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson CXXIndirectPrimaryBaseSet& Bases) { 64946170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson // If the record has a virtual primary base class, add it to our set. 65046170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 651c9e814ba193f38a7b08268612248f63beb279bb3Anders Carlsson if (Layout.isPrimaryBaseVirtual()) 65246170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson Bases.insert(Layout.getPrimaryBase()); 65346170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson 654651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &I : RD->bases()) { 655651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(!I.getType()->isDependentType() && 65646170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson "Cannot get indirect primary bases for class with dependent bases."); 65746170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson 65846170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson const CXXRecordDecl *BaseDecl = 659651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl()); 66046170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson 66146170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson // Only bases with virtual bases participate in computing the 66246170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson // indirect primary virtual base classes. 66346170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson if (BaseDecl->getNumVBases()) 66446170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson AddIndirectPrimaryBases(BaseDecl, Context, Bases); 66546170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson } 66646170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson 66746170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson} 66846170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson 66946170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlssonvoid 67046170f9c7d561d0f94af34a4b5da909d2584370aAnders CarlssonCXXRecordDecl::getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const { 67146170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson ASTContext &Context = getASTContext(); 67246170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson 67346170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson if (!getNumVBases()) 67446170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson return; 67546170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson 676651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &I : bases()) { 677651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(!I.getType()->isDependentType() && 67846170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson "Cannot get indirect primary bases for class with dependent bases."); 67946170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson 68046170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson const CXXRecordDecl *BaseDecl = 681651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl()); 68246170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson 68346170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson // Only bases with virtual bases participate in computing the 68446170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson // indirect primary virtual base classes. 68546170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson if (BaseDecl->getNumVBases()) 68646170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson AddIndirectPrimaryBases(BaseDecl, Context, Bases); 68746170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson } 68846170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson} 689