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(); 34a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor DeclsFound = new NamedDecl * [NumDeclsFound]; 35a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor std::copy(Decls.begin(), Decls.end(), DeclsFound); 36a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor} 37a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 38651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesCXXBasePaths::decl_range CXXBasePaths::found_decls() { 39a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor if (NumDeclsFound == 0) 40a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor ComputeDeclsFound(); 41a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 42651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return decl_range(decl_iterator(DeclsFound), 43651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines decl_iterator(DeclsFound + 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)); 88d89d30fdd9e3061fb100fb8f976aab5c6cf2c901John McCall return lookupInBases(&FindBaseClass, 89d89d30fdd9e3061fb100fb8f976aab5c6cf2c901John McCall const_cast<CXXRecordDecl*>(Base->getCanonicalDecl()), 90d89d30fdd9e3061fb100fb8f976aab5c6cf2c901John McCall Paths); 91a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor} 92a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 932aa800a955132d83a666bcd52d3d59d09cffc079Jordan Rosebool CXXRecordDecl::isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const { 941c4c397c581ad7106fc911fc4592c7aca163b5bcAnders Carlsson if (!getNumVBases()) 951c4c397c581ad7106fc911fc4592c7aca163b5bcAnders Carlsson return false; 961c4c397c581ad7106fc911fc4592c7aca163b5bcAnders Carlsson 974e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false, 984e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor /*DetectVirtual=*/false); 994e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor 1004e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor if (getCanonicalDecl() == Base->getCanonicalDecl()) 1014e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor return false; 1024e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor 1032aa800a955132d83a666bcd52d3d59d09cffc079Jordan Rose Paths.setOrigin(const_cast<CXXRecordDecl*>(this)); 1042aa800a955132d83a666bcd52d3d59d09cffc079Jordan Rose 1052aa800a955132d83a666bcd52d3d59d09cffc079Jordan Rose const void *BasePtr = static_cast<const void*>(Base->getCanonicalDecl()); 1062aa800a955132d83a666bcd52d3d59d09cffc079Jordan Rose return lookupInBases(&FindVirtualBaseClass, 1072aa800a955132d83a666bcd52d3d59d09cffc079Jordan Rose const_cast<void *>(BasePtr), 1082aa800a955132d83a666bcd52d3d59d09cffc079Jordan Rose Paths); 1094e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor} 1104e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor 111e8174bc483615e79614d9284a50ac94831e8b7c6John McCallstatic bool BaseIsNot(const CXXRecordDecl *Base, void *OpaqueTarget) { 112e8174bc483615e79614d9284a50ac94831e8b7c6John McCall // OpaqueTarget is a CXXRecordDecl*. 113e8174bc483615e79614d9284a50ac94831e8b7c6John McCall return Base->getCanonicalDecl() != (const CXXRecordDecl*) OpaqueTarget; 114e8174bc483615e79614d9284a50ac94831e8b7c6John McCall} 115e8174bc483615e79614d9284a50ac94831e8b7c6John McCall 116e8174bc483615e79614d9284a50ac94831e8b7c6John McCallbool CXXRecordDecl::isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const { 1173f7b3a754e9698d613672dd1f7af3ccd1b42470aDavid Greene return forallBases(BaseIsNot, 1183f7b3a754e9698d613672dd1f7af3ccd1b42470aDavid Greene const_cast<CXXRecordDecl *>(Base->getCanonicalDecl())); 119e8174bc483615e79614d9284a50ac94831e8b7c6John McCall} 120e8174bc483615e79614d9284a50ac94831e8b7c6John McCall 121f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smithbool 122f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard SmithCXXRecordDecl::isCurrentInstantiation(const DeclContext *CurContext) const { 123f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith assert(isDependentContext()); 124f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith 125f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith for (; !CurContext->isFileContext(); CurContext = CurContext->getParent()) 126f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith if (CurContext->Equals(this)) 127f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith return true; 128f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith 129f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith return false; 130f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith} 131f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith 132e8174bc483615e79614d9284a50ac94831e8b7c6John McCallbool CXXRecordDecl::forallBases(ForallBasesCallback *BaseMatches, 133e8174bc483615e79614d9284a50ac94831e8b7c6John McCall void *OpaqueData, 134229d47aef27e6f65fe4dc3beb22f622dd81104adDouglas Gregor bool AllowShortCircuit) const { 1355f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<const CXXRecordDecl*, 8> Queue; 136e8174bc483615e79614d9284a50ac94831e8b7c6John McCall 137e8174bc483615e79614d9284a50ac94831e8b7c6John McCall const CXXRecordDecl *Record = this; 138e8174bc483615e79614d9284a50ac94831e8b7c6John McCall bool AllMatches = true; 139e8174bc483615e79614d9284a50ac94831e8b7c6John McCall while (true) { 140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &I : Record->bases()) { 141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const RecordType *Ty = I.getType()->getAs<RecordType>(); 142229d47aef27e6f65fe4dc3beb22f622dd81104adDouglas Gregor if (!Ty) { 143e8174bc483615e79614d9284a50ac94831e8b7c6John McCall if (AllowShortCircuit) return false; 144e8174bc483615e79614d9284a50ac94831e8b7c6John McCall AllMatches = false; 145e8174bc483615e79614d9284a50ac94831e8b7c6John McCall continue; 146e8174bc483615e79614d9284a50ac94831e8b7c6John McCall } 147e8174bc483615e79614d9284a50ac94831e8b7c6John McCall 148229d47aef27e6f65fe4dc3beb22f622dd81104adDouglas Gregor CXXRecordDecl *Base = 149229d47aef27e6f65fe4dc3beb22f622dd81104adDouglas Gregor cast_or_null<CXXRecordDecl>(Ty->getDecl()->getDefinition()); 150f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith if (!Base || 151f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith (Base->isDependentContext() && 152f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297Richard Smith !Base->isCurrentInstantiation(Record))) { 153e8174bc483615e79614d9284a50ac94831e8b7c6John McCall if (AllowShortCircuit) return false; 154e8174bc483615e79614d9284a50ac94831e8b7c6John McCall AllMatches = false; 155e8174bc483615e79614d9284a50ac94831e8b7c6John McCall continue; 156e8174bc483615e79614d9284a50ac94831e8b7c6John McCall } 157e8174bc483615e79614d9284a50ac94831e8b7c6John McCall 158ca910e84ea026a898c7184d3f3608403005b9bc0Anders Carlsson Queue.push_back(Base); 159ca910e84ea026a898c7184d3f3608403005b9bc0Anders Carlsson if (!BaseMatches(Base, OpaqueData)) { 160e8174bc483615e79614d9284a50ac94831e8b7c6John McCall if (AllowShortCircuit) return false; 161e8174bc483615e79614d9284a50ac94831e8b7c6John McCall AllMatches = false; 162e8174bc483615e79614d9284a50ac94831e8b7c6John McCall continue; 163e8174bc483615e79614d9284a50ac94831e8b7c6John McCall } 164e8174bc483615e79614d9284a50ac94831e8b7c6John McCall } 165e8174bc483615e79614d9284a50ac94831e8b7c6John McCall 166344472ebeded2fca2ed5013b9e87f81d09bfa908Robert Wilhelm if (Queue.empty()) 167344472ebeded2fca2ed5013b9e87f81d09bfa908Robert Wilhelm break; 168344472ebeded2fca2ed5013b9e87f81d09bfa908Robert Wilhelm Record = Queue.pop_back_val(); // not actually a queue. 169e8174bc483615e79614d9284a50ac94831e8b7c6John McCall } 170e8174bc483615e79614d9284a50ac94831e8b7c6John McCall 171e8174bc483615e79614d9284a50ac94831e8b7c6John McCall return AllMatches; 172e8174bc483615e79614d9284a50ac94831e8b7c6John McCall} 173e8174bc483615e79614d9284a50ac94831e8b7c6John McCall 1742aa800a955132d83a666bcd52d3d59d09cffc079Jordan Rosebool CXXBasePaths::lookupInBases(ASTContext &Context, 17589b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor const CXXRecordDecl *Record, 17689b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor CXXRecordDecl::BaseMatchesCallback *BaseMatches, 17789b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor void *UserData) { 178a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor bool FoundPath = false; 17946460a68f6508775e98c19b4bb8454bb471aac24John McCall 18092f883177b162928a8e632e4e3b93fafd2b26072John McCall // The access of the path down to this record. 18189b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor AccessSpecifier AccessToHere = ScratchPath.Access; 18289b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor bool IsFirstStep = ScratchPath.empty(); 18392f883177b162928a8e632e4e3b93fafd2b26072John McCall 184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &BaseSpec : Record->bases()) { 185a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // Find the record of the base class subobjects for this type. 186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType BaseType = 187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Context.getCanonicalType(BaseSpec.getType()).getUnqualifiedType(); 188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 189a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // C++ [temp.dep]p3: 190a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // In the definition of a class template or a member of a class template, 191a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // if a base class of the class template depends on a template-parameter, 192a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // the base class scope is not examined during unqualified name lookup 193a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // either at the point of definition of the class template or member or 194a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // during an instantiation of the class tem- plate or member. 195a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor if (BaseType->isDependentType()) 196a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor continue; 197a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 198a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // Determine whether we need to visit this base class at all, 199a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // updating the count of subobjects appropriately. 20089b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType]; 201a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor bool VisitBase = true; 202a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor bool SetVirtual = false; 203651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (BaseSpec.isVirtual()) { 204a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor VisitBase = !Subobjects.first; 205a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor Subobjects.first = true; 2066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (isDetectingVirtual() && DetectedVirtual == nullptr) { 207a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // If this is the first virtual we find, remember it. If it turns out 208a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // there is no base path here, we'll reset it later. 20989b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor DetectedVirtual = BaseType->getAs<RecordType>(); 210a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor SetVirtual = true; 211a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor } 212a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor } else 213a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor ++Subobjects.second; 214a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 21589b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor if (isRecordingPaths()) { 216a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // Add this base specifier to the current path. 217a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor CXXBasePathElement Element; 218651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Element.Base = &BaseSpec; 21989b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor Element.Class = Record; 220651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (BaseSpec.isVirtual()) 221a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor Element.SubobjectNumber = 0; 222a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor else 223a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor Element.SubobjectNumber = Subobjects.second; 22489b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor ScratchPath.push_back(Element); 22546460a68f6508775e98c19b4bb8454bb471aac24John McCall 22692f883177b162928a8e632e4e3b93fafd2b26072John McCall // Calculate the "top-down" access to this base class. 22792f883177b162928a8e632e4e3b93fafd2b26072John McCall // The spec actually describes this bottom-up, but top-down is 22892f883177b162928a8e632e4e3b93fafd2b26072John McCall // equivalent because the definition works out as follows: 22992f883177b162928a8e632e4e3b93fafd2b26072John McCall // 1. Write down the access along each step in the inheritance 23092f883177b162928a8e632e4e3b93fafd2b26072John McCall // chain, followed by the access of the decl itself. 23192f883177b162928a8e632e4e3b93fafd2b26072John McCall // For example, in 23292f883177b162928a8e632e4e3b93fafd2b26072John McCall // class A { public: int foo; }; 23392f883177b162928a8e632e4e3b93fafd2b26072John McCall // class B : protected A {}; 23492f883177b162928a8e632e4e3b93fafd2b26072John McCall // class C : public B {}; 23592f883177b162928a8e632e4e3b93fafd2b26072John McCall // class D : private C {}; 23692f883177b162928a8e632e4e3b93fafd2b26072John McCall // we would write: 23792f883177b162928a8e632e4e3b93fafd2b26072John McCall // private public protected public 23892f883177b162928a8e632e4e3b93fafd2b26072John McCall // 2. If 'private' appears anywhere except far-left, access is denied. 23992f883177b162928a8e632e4e3b93fafd2b26072John McCall // 3. Otherwise, overall access is determined by the most restrictive 24092f883177b162928a8e632e4e3b93fafd2b26072John McCall // access in the sequence. 24192f883177b162928a8e632e4e3b93fafd2b26072John McCall if (IsFirstStep) 242651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ScratchPath.Access = BaseSpec.getAccessSpecifier(); 24392f883177b162928a8e632e4e3b93fafd2b26072John McCall else 24489b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor ScratchPath.Access = CXXRecordDecl::MergeAccess(AccessToHere, 245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BaseSpec.getAccessSpecifier()); 246a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor } 247ed814cc4cd2bd4d32cbb4bfde3cc59ccae723a92John McCall 248ed814cc4cd2bd4d32cbb4bfde3cc59ccae723a92John McCall // Track whether there's a path involving this specific base. 249ed814cc4cd2bd4d32cbb4bfde3cc59ccae723a92John McCall bool FoundPathThroughBase = false; 250ed814cc4cd2bd4d32cbb4bfde3cc59ccae723a92John McCall 251651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (BaseMatches(&BaseSpec, ScratchPath, UserData)) { 25292f883177b162928a8e632e4e3b93fafd2b26072John McCall // We've found a path that terminates at this base. 253ed814cc4cd2bd4d32cbb4bfde3cc59ccae723a92John McCall FoundPath = FoundPathThroughBase = true; 25489b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor if (isRecordingPaths()) { 255a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // We have a path. Make a copy of it before moving on. 25689b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor Paths.push_back(ScratchPath); 25789b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor } else if (!isFindingAmbiguities()) { 258a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // We found a path and we don't care about ambiguities; 259a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // return immediately. 260a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor return FoundPath; 261a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor } 262a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor } else if (VisitBase) { 263a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor CXXRecordDecl *BaseRecord 264651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines = cast<CXXRecordDecl>(BaseSpec.getType()->castAs<RecordType>() 265a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor ->getDecl()); 26689b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor if (lookupInBases(Context, BaseRecord, BaseMatches, UserData)) { 267a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // C++ [class.member.lookup]p2: 268a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // A member name f in one sub-object B hides a member name f in 269a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // a sub-object A if A is a base class sub-object of B. Any 270a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // declarations that are so hidden are eliminated from 271a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // consideration. 272a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 273a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // There is a path to a base class that meets the criteria. If we're 274a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // not collecting paths or finding ambiguities, we're done. 275ed814cc4cd2bd4d32cbb4bfde3cc59ccae723a92John McCall FoundPath = FoundPathThroughBase = true; 27689b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor if (!isFindingAmbiguities()) 277a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor return FoundPath; 278a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor } 279a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor } 280a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 281a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // Pop this base specifier off the current path (if we're 282a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // collecting paths). 28389b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor if (isRecordingPaths()) { 28489b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor ScratchPath.pop_back(); 28546460a68f6508775e98c19b4bb8454bb471aac24John McCall } 28646460a68f6508775e98c19b4bb8454bb471aac24John McCall 287a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // If we set a virtual earlier, and this isn't a path, forget it again. 288ed814cc4cd2bd4d32cbb4bfde3cc59ccae723a92John McCall if (SetVirtual && !FoundPathThroughBase) { 2896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines DetectedVirtual = nullptr; 290a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor } 291a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor } 29292f883177b162928a8e632e4e3b93fafd2b26072John McCall 29392f883177b162928a8e632e4e3b93fafd2b26072John McCall // Reset the scratch path access. 29489b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor ScratchPath.Access = AccessToHere; 295a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 296a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor return FoundPath; 297a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor} 298a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 29989b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregorbool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches, 30089b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor void *UserData, 30189b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor CXXBasePaths &Paths) const { 3024e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // If we didn't find anything, report that. 3034e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor if (!Paths.lookupInBases(getASTContext(), this, BaseMatches, UserData)) 3044e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor return false; 3054e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor 3064e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // If we're not recording paths or we won't ever find ambiguities, 3074e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // we're done. 3084e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor if (!Paths.isRecordingPaths() || !Paths.isFindingAmbiguities()) 3094e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor return true; 3104e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor 3114e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // C++ [class.member.lookup]p6: 3124e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // When virtual base classes are used, a hidden declaration can be 3134e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // reached along a path through the sub-object lattice that does 3144e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // not pass through the hiding declaration. This is not an 3154e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // ambiguity. The identical use with nonvirtual base classes is an 3164e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // ambiguity; in that case there is no unique instance of the name 3174e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // that hides all the others. 3184e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // 3194e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // FIXME: This is an O(N^2) algorithm, but DPG doesn't see an easy 3204e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor // way to make it any faster. 3210e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Paths.Paths.remove_if([&Paths](const CXXBasePath &Path) { 3220e2c34f92f00628d48968dfea096d36381f494cbStephen Hines for (const CXXBasePathElement &PE : Path) { 3230e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (!PE.Base->isVirtual()) 3240e2c34f92f00628d48968dfea096d36381f494cbStephen Hines continue; 3250e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 3260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CXXRecordDecl *VBase = nullptr; 3270e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (const RecordType *Record = PE.Base->getType()->getAs<RecordType>()) 3280e2c34f92f00628d48968dfea096d36381f494cbStephen Hines VBase = cast<CXXRecordDecl>(Record->getDecl()); 3290e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (!VBase) 3300e2c34f92f00628d48968dfea096d36381f494cbStephen Hines break; 3310e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 3320e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // The declaration(s) we found along this path were found in a 3330e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // subobject of a virtual base. Check whether this virtual 3340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // base is a subobject of any other path; if so, then the 3350e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // declaration in this path are hidden by that patch. 3360e2c34f92f00628d48968dfea096d36381f494cbStephen Hines for (const CXXBasePath &HidingP : Paths) { 3370e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CXXRecordDecl *HidingClass = nullptr; 3380e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (const RecordType *Record = 3390e2c34f92f00628d48968dfea096d36381f494cbStephen Hines HidingP.back().Base->getType()->getAs<RecordType>()) 3400e2c34f92f00628d48968dfea096d36381f494cbStephen Hines HidingClass = cast<CXXRecordDecl>(Record->getDecl()); 3410e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (!HidingClass) 3424e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor break; 3434e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor 3440e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (HidingClass->isVirtuallyDerivedFrom(VBase)) 3450e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return true; 3464e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor } 3474e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor } 3480e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return false; 3490e2c34f92f00628d48968dfea096d36381f494cbStephen Hines }); 3504e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor 3514e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor return true; 35289b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor} 35389b7702c9a64e12093ed34fc02dc3cfbb6eb133aDouglas Gregor 354af8e6ed61b5e80ab95632b63f583af79dcb62590John McCallbool CXXRecordDecl::FindBaseClass(const CXXBaseSpecifier *Specifier, 355a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor CXXBasePath &Path, 356a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor void *BaseRecord) { 357a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor assert(((Decl *)BaseRecord)->getCanonicalDecl() == BaseRecord && 358a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor "User data for FindBaseClass is not canonical!"); 359890f0f1612b0028b8b16730ae7ed07e295600c76Ted Kremenek return Specifier->getType()->castAs<RecordType>()->getDecl() 360890f0f1612b0028b8b16730ae7ed07e295600c76Ted Kremenek ->getCanonicalDecl() == BaseRecord; 361a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor} 362a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 3634e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregorbool CXXRecordDecl::FindVirtualBaseClass(const CXXBaseSpecifier *Specifier, 3644e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor CXXBasePath &Path, 3654e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor void *BaseRecord) { 3664e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor assert(((Decl *)BaseRecord)->getCanonicalDecl() == BaseRecord && 3674e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor "User data for FindBaseClass is not canonical!"); 3684e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor return Specifier->isVirtual() && 369890f0f1612b0028b8b16730ae7ed07e295600c76Ted Kremenek Specifier->getType()->castAs<RecordType>()->getDecl() 370890f0f1612b0028b8b16730ae7ed07e295600c76Ted Kremenek ->getCanonicalDecl() == BaseRecord; 3714e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor} 3724e6ba4be8ddeca2978da6b9bae02cbe9594f2ef4Douglas Gregor 373af8e6ed61b5e80ab95632b63f583af79dcb62590John McCallbool CXXRecordDecl::FindTagMember(const CXXBaseSpecifier *Specifier, 374a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor CXXBasePath &Path, 375a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor void *Name) { 376890f0f1612b0028b8b16730ae7ed07e295600c76Ted Kremenek RecordDecl *BaseRecord = 377890f0f1612b0028b8b16730ae7ed07e295600c76Ted Kremenek Specifier->getType()->castAs<RecordType>()->getDecl(); 378a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 379a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor DeclarationName N = DeclarationName::getFromOpaquePtr(Name); 380a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor for (Path.Decls = BaseRecord->lookup(N); 3813bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie !Path.Decls.empty(); 3823bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie Path.Decls = Path.Decls.slice(1)) { 3833bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie if (Path.Decls.front()->isInIdentifierNamespace(IDNS_Tag)) 384a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor return true; 385a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor } 386a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 387a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor return false; 388a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor} 389a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 390af8e6ed61b5e80ab95632b63f583af79dcb62590John McCallbool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier, 391a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor CXXBasePath &Path, 392a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor void *Name) { 393890f0f1612b0028b8b16730ae7ed07e295600c76Ted Kremenek RecordDecl *BaseRecord = 394890f0f1612b0028b8b16730ae7ed07e295600c76Ted Kremenek Specifier->getType()->castAs<RecordType>()->getDecl(); 395a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 396a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor const unsigned IDNS = IDNS_Ordinary | IDNS_Tag | IDNS_Member; 397a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor DeclarationName N = DeclarationName::getFromOpaquePtr(Name); 398a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor for (Path.Decls = BaseRecord->lookup(N); 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, 411af8e6ed61b5e80ab95632b63f583af79dcb62590John McCall void *Name) { 412890f0f1612b0028b8b16730ae7ed07e295600c76Ted Kremenek RecordDecl *BaseRecord = 413890f0f1612b0028b8b16730ae7ed07e295600c76Ted Kremenek Specifier->getType()->castAs<RecordType>()->getDecl(); 414a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 415a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor DeclarationName N = DeclarationName::getFromOpaquePtr(Name); 416a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor for (Path.Decls = BaseRecord->lookup(N); 4173bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie !Path.Decls.empty(); 4183bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie Path.Decls = Path.Decls.slice(1)) { 419a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor // FIXME: Refactor the "is it a nested-name-specifier?" check 4203bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie if (isa<TypedefNameDecl>(Path.Decls.front()) || 4213bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie Path.Decls.front()->isInIdentifierNamespace(IDNS_Tag)) 422a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor return true; 423a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor } 424a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor 425a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor return false; 42682109bd64a8494c801263c11f4d2294f47e21807Mike Stump} 4277b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 4287b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregorvoid OverridingMethods::add(unsigned OverriddenSubobject, 4297b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor UniqueVirtualMethod Overriding) { 43009d19efaa147762f84aed55efa7930bb3616a4e5Craig Topper SmallVectorImpl<UniqueVirtualMethod> &SubobjectOverrides 4317b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor = Overrides[OverriddenSubobject]; 4327b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor if (std::find(SubobjectOverrides.begin(), SubobjectOverrides.end(), 4337b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor Overriding) == SubobjectOverrides.end()) 4347b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor SubobjectOverrides.push_back(Overriding); 4357b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor} 4367b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 4377b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregorvoid OverridingMethods::add(const OverridingMethods &Other) { 4387b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor for (const_iterator I = Other.begin(), IE = Other.end(); I != IE; ++I) { 4397b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor for (overriding_const_iterator M = I->second.begin(), 4407b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor MEnd = I->second.end(); 4417b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor M != MEnd; 4427b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor ++M) 4437b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor add(I->first, *M); 4447b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 4457b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor} 4467b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 4477b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregorvoid OverridingMethods::replaceAll(UniqueVirtualMethod Overriding) { 4487b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor for (iterator I = begin(), IEnd = end(); I != IEnd; ++I) { 4497b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor I->second.clear(); 4507b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor I->second.push_back(Overriding); 4517b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 4527b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor} 4537b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 4547b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 4557b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregornamespace { 4567b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor class FinalOverriderCollector { 4577b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor /// \brief The number of subobjects of a given class type that 4587b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor /// occur within the class hierarchy. 4597b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor llvm::DenseMap<const CXXRecordDecl *, unsigned> SubobjectCount; 4607b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 4617b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor /// \brief Overriders for each virtual base subobject. 4627b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor llvm::DenseMap<const CXXRecordDecl *, CXXFinalOverriderMap *> VirtualOverriders; 4637b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 4647b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor CXXFinalOverriderMap FinalOverriders; 4657b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 4667b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor public: 4677b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor ~FinalOverriderCollector(); 4687b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 4697b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor void Collect(const CXXRecordDecl *RD, bool VirtualBase, 4707b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor const CXXRecordDecl *InVirtualSubobject, 4717b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor CXXFinalOverriderMap &Overriders); 4727b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor }; 4737b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor} 4747b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 4757b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregorvoid FinalOverriderCollector::Collect(const CXXRecordDecl *RD, 4767b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor bool VirtualBase, 4777b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor const CXXRecordDecl *InVirtualSubobject, 4787b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor CXXFinalOverriderMap &Overriders) { 4797b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor unsigned SubobjectNumber = 0; 4807b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor if (!VirtualBase) 4817b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor SubobjectNumber 4827b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor = ++SubobjectCount[cast<CXXRecordDecl>(RD->getCanonicalDecl())]; 4837b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 484651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &Base : RD->bases()) { 485651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const RecordType *RT = Base.getType()->getAs<RecordType>()) { 4867b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor const CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(RT->getDecl()); 4877b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor if (!BaseDecl->isPolymorphic()) 4887b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor continue; 4897b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 490651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Overriders.empty() && !Base.isVirtual()) { 4917b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // There are no other overriders of virtual member functions, 4927b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // so let the base class fill in our overriders for us. 4937b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor Collect(BaseDecl, false, InVirtualSubobject, Overriders); 4947b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor continue; 4957b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 4967b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 4977b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // Collect all of the overridders from the base class subobject 4987b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // and merge them into the set of overridders for this class. 4997b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // For virtual base classes, populate or use the cached virtual 5007b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // overrides so that we do not walk the virtual base class (and 5017b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // its base classes) more than once. 5027b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor CXXFinalOverriderMap ComputedBaseOverriders; 5037b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor CXXFinalOverriderMap *BaseOverriders = &ComputedBaseOverriders; 504651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Base.isVirtual()) { 5057b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor CXXFinalOverriderMap *&MyVirtualOverriders = VirtualOverriders[BaseDecl]; 506e0cf31dc263979027f345c00318a704c5f5b1e76Benjamin Kramer BaseOverriders = MyVirtualOverriders; 5077b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor if (!MyVirtualOverriders) { 5087b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor MyVirtualOverriders = new CXXFinalOverriderMap; 509e0cf31dc263979027f345c00318a704c5f5b1e76Benjamin Kramer 510e0cf31dc263979027f345c00318a704c5f5b1e76Benjamin Kramer // Collect may cause VirtualOverriders to reallocate, invalidating the 511e0cf31dc263979027f345c00318a704c5f5b1e76Benjamin Kramer // MyVirtualOverriders reference. Set BaseOverriders to the right 512e0cf31dc263979027f345c00318a704c5f5b1e76Benjamin Kramer // value now. 513e0cf31dc263979027f345c00318a704c5f5b1e76Benjamin Kramer BaseOverriders = MyVirtualOverriders; 514e0cf31dc263979027f345c00318a704c5f5b1e76Benjamin Kramer 5157b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor Collect(BaseDecl, true, BaseDecl, *MyVirtualOverriders); 5167b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 5177b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } else 5187b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor Collect(BaseDecl, false, InVirtualSubobject, ComputedBaseOverriders); 5197b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 5207b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // Merge the overriders from this base class into our own set of 5217b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // overriders. 5227b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor for (CXXFinalOverriderMap::iterator OM = BaseOverriders->begin(), 5237b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor OMEnd = BaseOverriders->end(); 5247b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor OM != OMEnd; 5257b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor ++OM) { 5267b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor const CXXMethodDecl *CanonOM 5277b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor = cast<CXXMethodDecl>(OM->first->getCanonicalDecl()); 5287b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor Overriders[CanonOM].add(OM->second); 5297b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 5307b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 5317b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 5327b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 533651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *M : RD->methods()) { 5347b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // We only care about virtual methods. 5357b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor if (!M->isVirtual()) 5367b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor continue; 5377b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 5387b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor CXXMethodDecl *CanonM = cast<CXXMethodDecl>(M->getCanonicalDecl()); 5397b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 5407b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor if (CanonM->begin_overridden_methods() 5417b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor == CanonM->end_overridden_methods()) { 5427b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // This is a new virtual function that does not override any 5437b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // other virtual function. Add it to the map of virtual 5447b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // functions for which we are tracking overridders. 5457b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 5467b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // C++ [class.virtual]p2: 5477b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // For convenience we say that any virtual function overrides itself. 5487b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor Overriders[CanonM].add(SubobjectNumber, 5497b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor UniqueVirtualMethod(CanonM, SubobjectNumber, 5507b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor InVirtualSubobject)); 5517b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor continue; 5527b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 5537b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 5547b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // This virtual method overrides other virtual methods, so it does 5557b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // not add any new slots into the set of overriders. Instead, we 5567b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // replace entries in the set of overriders with the new 5577b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // overrider. To do so, we dig down to the original virtual 5587b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // functions using data recursion and update all of the methods it 5597b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // overrides. 5600e2c34f92f00628d48968dfea096d36381f494cbStephen Hines typedef llvm::iterator_range<CXXMethodDecl::method_iterator> 5610e2c34f92f00628d48968dfea096d36381f494cbStephen Hines OverriddenMethods; 5625f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<OverriddenMethods, 4> Stack; 5630e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Stack.push_back(llvm::make_range(CanonM->begin_overridden_methods(), 5640e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CanonM->end_overridden_methods())); 5657b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor while (!Stack.empty()) { 5660e2c34f92f00628d48968dfea096d36381f494cbStephen Hines for (const CXXMethodDecl *OM : Stack.pop_back_val()) { 5670e2c34f92f00628d48968dfea096d36381f494cbStephen Hines const CXXMethodDecl *CanonOM = OM->getCanonicalDecl(); 568ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson 569ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson // C++ [class.virtual]p2: 570ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson // A virtual member function C::vf of a class object S is 571ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson // a final overrider unless the most derived class (1.8) 572ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson // of which S is a base class subobject (if any) declares 573ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson // or inherits another member function that overrides vf. 574ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson // 575ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson // Treating this object like the most derived class, we 576ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson // replace any overrides from base classes with this 577ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson // overriding virtual function. 578ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson Overriders[CanonOM].replaceAll( 579ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson UniqueVirtualMethod(CanonM, SubobjectNumber, 580ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson InVirtualSubobject)); 581ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson 5827b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor if (CanonOM->begin_overridden_methods() 583ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson == CanonOM->end_overridden_methods()) 5847b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor continue; 5857b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 5867b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // Continue recursion to the methods that this virtual method 5877b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // overrides. 5880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Stack.push_back(llvm::make_range(CanonOM->begin_overridden_methods(), 5890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CanonOM->end_overridden_methods())); 5907b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 5917b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 592ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson 593ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson // C++ [class.virtual]p2: 594ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson // For convenience we say that any virtual function overrides itself. 595ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson Overriders[CanonM].add(SubobjectNumber, 596ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson UniqueVirtualMethod(CanonM, SubobjectNumber, 597ffdb2d2a8860c601b35575855494f45d85cf14d9Anders Carlsson InVirtualSubobject)); 5987b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 5997b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor} 6007b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 6017b2fc9d3c97f2526528a8b686af1589054025ca0Douglas GregorFinalOverriderCollector::~FinalOverriderCollector() { 6027b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor for (llvm::DenseMap<const CXXRecordDecl *, CXXFinalOverriderMap *>::iterator 6037b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor VO = VirtualOverriders.begin(), VOEnd = VirtualOverriders.end(); 6047b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor VO != VOEnd; 6057b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor ++VO) 6067b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor delete VO->second; 6077b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor} 6087b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 6097b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregorvoid 6107b2fc9d3c97f2526528a8b686af1589054025ca0Douglas GregorCXXRecordDecl::getFinalOverriders(CXXFinalOverriderMap &FinalOverriders) const { 6117b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor FinalOverriderCollector Collector; 6126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Collector.Collect(this, false, nullptr, FinalOverriders); 6137b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 6147b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // Weed out any final overriders that come from virtual base class 6157b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // subobjects that were hidden by other subobjects along any path. 6167b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // This is the final-overrider variant of C++ [class.member.lookup]p10. 6170e2c34f92f00628d48968dfea096d36381f494cbStephen Hines for (auto &OM : FinalOverriders) { 6180e2c34f92f00628d48968dfea096d36381f494cbStephen Hines for (auto &SO : OM.second) { 6190e2c34f92f00628d48968dfea096d36381f494cbStephen Hines SmallVectorImpl<UniqueVirtualMethod> &Overriding = SO.second; 6207b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor if (Overriding.size() < 2) 6217b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor continue; 6227b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 6230e2c34f92f00628d48968dfea096d36381f494cbStephen Hines auto IsHidden = [&Overriding](const UniqueVirtualMethod &M) { 6240e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (!M.InVirtualSubobject) 6250e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return false; 6267b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor 6277b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // We have an overriding method in a virtual base class 6287b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // subobject (or non-virtual base class subobject thereof); 6297b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // determine whether there exists an other overriding method 6307b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // in a base class subobject that hides the virtual base class 6317b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor // subobject. 6320e2c34f92f00628d48968dfea096d36381f494cbStephen Hines for (const UniqueVirtualMethod &OP : Overriding) 6330e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (&M != &OP && 6340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines OP.Method->getParent()->isVirtuallyDerivedFrom( 6350e2c34f92f00628d48968dfea096d36381f494cbStephen Hines M.InVirtualSubobject)) 6360e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return true; 6370e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return false; 6380e2c34f92f00628d48968dfea096d36381f494cbStephen Hines }; 6390e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 6400e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Overriding.erase( 6410e2c34f92f00628d48968dfea096d36381f494cbStephen Hines std::remove_if(Overriding.begin(), Overriding.end(), IsHidden), 6420e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Overriding.end()); 6437b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 6447b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor } 6457b2fc9d3c97f2526528a8b686af1589054025ca0Douglas Gregor} 64646170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson 64746170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlssonstatic void 64846170f9c7d561d0f94af34a4b5da909d2584370aAnders CarlssonAddIndirectPrimaryBases(const CXXRecordDecl *RD, ASTContext &Context, 64946170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson CXXIndirectPrimaryBaseSet& Bases) { 65046170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson // If the record has a virtual primary base class, add it to our set. 65146170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 652c9e814ba193f38a7b08268612248f63beb279bb3Anders Carlsson if (Layout.isPrimaryBaseVirtual()) 65346170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson Bases.insert(Layout.getPrimaryBase()); 65446170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson 655651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &I : RD->bases()) { 656651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(!I.getType()->isDependentType() && 65746170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson "Cannot get indirect primary bases for class with dependent bases."); 65846170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson 65946170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson const CXXRecordDecl *BaseDecl = 660651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl()); 66146170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson 66246170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson // Only bases with virtual bases participate in computing the 66346170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson // indirect primary virtual base classes. 66446170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson if (BaseDecl->getNumVBases()) 66546170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson AddIndirectPrimaryBases(BaseDecl, Context, Bases); 66646170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson } 66746170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson 66846170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson} 66946170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson 67046170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlssonvoid 67146170f9c7d561d0f94af34a4b5da909d2584370aAnders CarlssonCXXRecordDecl::getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const { 67246170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson ASTContext &Context = getASTContext(); 67346170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson 67446170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson if (!getNumVBases()) 67546170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson return; 67646170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson 677651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &I : bases()) { 678651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(!I.getType()->isDependentType() && 67946170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson "Cannot get indirect primary bases for class with dependent bases."); 68046170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson 68146170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson const CXXRecordDecl *BaseDecl = 682651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl()); 68346170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson 68446170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson // Only bases with virtual bases participate in computing the 68546170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson // indirect primary virtual base classes. 68646170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson if (BaseDecl->getNumVBases()) 68746170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson AddIndirectPrimaryBases(BaseDecl, Context, Bases); 68846170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson } 68946170f9c7d561d0f94af34a4b5da909d2584370aAnders Carlsson} 690