1 //===- CXXInheritance.cpp - C++ Inheritance -------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file provides routines that help analyzing C++ inheritance hierarchies.
11 //===----------------------------------------------------------------------===//
13 #include "clang/AST/CXXInheritance.h"
14 #include "clang/AST/ASTContext.h"
15 #include "clang/AST/Decl.h"
16 #include "clang/AST/DeclBase.h"
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/DeclTemplate.h"
19 #include "clang/AST/RecordLayout.h"
20 #include "clang/AST/TemplateName.h"
21 #include "clang/AST/Type.h"
22 #include "clang/Basic/LLVM.h"
23 #include "llvm/ADT/DenseMap.h"
24 #include "llvm/ADT/STLExtras.h"
25 #include "llvm/ADT/SmallVector.h"
26 #include "llvm/ADT/iterator_range.h"
32 using namespace clang
;
34 /// isAmbiguous - Determines whether the set of paths provided is
35 /// ambiguous, i.e., there are two or more paths that refer to
36 /// different base class subobjects of the same type. BaseType must be
37 /// an unqualified, canonical class type.
38 bool CXXBasePaths::isAmbiguous(CanQualType BaseType
) {
39 BaseType
= BaseType
.getUnqualifiedType();
40 IsVirtBaseAndNumberNonVirtBases Subobjects
= ClassSubobjects
[BaseType
];
41 return Subobjects
.NumberOfNonVirtBases
+ (Subobjects
.IsVirtBase
? 1 : 0) > 1;
44 /// clear - Clear out all prior path information.
45 void CXXBasePaths::clear() {
47 ClassSubobjects
.clear();
48 VisitedDependentRecords
.clear();
50 DetectedVirtual
= nullptr;
53 /// Swaps the contents of this CXXBasePaths structure with the
54 /// contents of Other.
55 void CXXBasePaths::swap(CXXBasePaths
&Other
) {
56 std::swap(Origin
, Other
.Origin
);
57 Paths
.swap(Other
.Paths
);
58 ClassSubobjects
.swap(Other
.ClassSubobjects
);
59 VisitedDependentRecords
.swap(Other
.VisitedDependentRecords
);
60 std::swap(FindAmbiguities
, Other
.FindAmbiguities
);
61 std::swap(RecordPaths
, Other
.RecordPaths
);
62 std::swap(DetectVirtual
, Other
.DetectVirtual
);
63 std::swap(DetectedVirtual
, Other
.DetectedVirtual
);
66 bool CXXRecordDecl::isDerivedFrom(const CXXRecordDecl
*Base
) const {
67 CXXBasePaths
Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false,
68 /*DetectVirtual=*/false);
69 return isDerivedFrom(Base
, Paths
);
72 bool CXXRecordDecl::isDerivedFrom(const CXXRecordDecl
*Base
,
73 CXXBasePaths
&Paths
) const {
74 if (getCanonicalDecl() == Base
->getCanonicalDecl())
77 Paths
.setOrigin(const_cast<CXXRecordDecl
*>(this));
79 const CXXRecordDecl
*BaseDecl
= Base
->getCanonicalDecl();
81 [BaseDecl
](const CXXBaseSpecifier
*Specifier
, CXXBasePath
&Path
) {
82 return Specifier
->getType()->getAsRecordDecl() &&
83 FindBaseClass(Specifier
, Path
, BaseDecl
);
88 bool CXXRecordDecl::isVirtuallyDerivedFrom(const CXXRecordDecl
*Base
) const {
92 CXXBasePaths
Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false,
93 /*DetectVirtual=*/false);
95 if (getCanonicalDecl() == Base
->getCanonicalDecl())
98 Paths
.setOrigin(const_cast<CXXRecordDecl
*>(this));
100 const CXXRecordDecl
*BaseDecl
= Base
->getCanonicalDecl();
101 return lookupInBases(
102 [BaseDecl
](const CXXBaseSpecifier
*Specifier
, CXXBasePath
&Path
) {
103 return FindVirtualBaseClass(Specifier
, Path
, BaseDecl
);
108 bool CXXRecordDecl::isProvablyNotDerivedFrom(const CXXRecordDecl
*Base
) const {
109 const CXXRecordDecl
*TargetDecl
= Base
->getCanonicalDecl();
110 return forallBases([TargetDecl
](const CXXRecordDecl
*Base
) {
111 return Base
->getCanonicalDecl() != TargetDecl
;
116 CXXRecordDecl::isCurrentInstantiation(const DeclContext
*CurContext
) const {
117 assert(isDependentContext());
119 for (; !CurContext
->isFileContext(); CurContext
= CurContext
->getParent())
120 if (CurContext
->Equals(this))
126 bool CXXRecordDecl::forallBases(ForallBasesCallback BaseMatches
) const {
127 SmallVector
<const CXXRecordDecl
*, 8> Queue
;
129 const CXXRecordDecl
*Record
= this;
131 for (const auto &I
: Record
->bases()) {
132 const RecordType
*Ty
= I
.getType()->getAs
<RecordType
>();
136 CXXRecordDecl
*Base
=
137 cast_or_null
<CXXRecordDecl
>(Ty
->getDecl()->getDefinition());
139 (Base
->isDependentContext() &&
140 !Base
->isCurrentInstantiation(Record
))) {
144 Queue
.push_back(Base
);
145 if (!BaseMatches(Base
))
151 Record
= Queue
.pop_back_val(); // not actually a queue.
157 bool CXXBasePaths::lookupInBases(ASTContext
&Context
,
158 const CXXRecordDecl
*Record
,
159 CXXRecordDecl::BaseMatchesCallback BaseMatches
,
160 bool LookupInDependent
) {
161 bool FoundPath
= false;
163 // The access of the path down to this record.
164 AccessSpecifier AccessToHere
= ScratchPath
.Access
;
165 bool IsFirstStep
= ScratchPath
.empty();
167 for (const auto &BaseSpec
: Record
->bases()) {
168 // Find the record of the base class subobjects for this type.
170 Context
.getCanonicalType(BaseSpec
.getType()).getUnqualifiedType();
173 // In the definition of a class template or a member of a class template,
174 // if a base class of the class template depends on a template-parameter,
175 // the base class scope is not examined during unqualified name lookup
176 // either at the point of definition of the class template or member or
177 // during an instantiation of the class tem- plate or member.
178 if (!LookupInDependent
&& BaseType
->isDependentType())
181 // Determine whether we need to visit this base class at all,
182 // updating the count of subobjects appropriately.
183 IsVirtBaseAndNumberNonVirtBases
&Subobjects
= ClassSubobjects
[BaseType
];
184 bool VisitBase
= true;
185 bool SetVirtual
= false;
186 if (BaseSpec
.isVirtual()) {
187 VisitBase
= !Subobjects
.IsVirtBase
;
188 Subobjects
.IsVirtBase
= true;
189 if (isDetectingVirtual() && DetectedVirtual
== nullptr) {
190 // If this is the first virtual we find, remember it. If it turns out
191 // there is no base path here, we'll reset it later.
192 DetectedVirtual
= BaseType
->getAs
<RecordType
>();
196 ++Subobjects
.NumberOfNonVirtBases
;
198 if (isRecordingPaths()) {
199 // Add this base specifier to the current path.
200 CXXBasePathElement Element
;
201 Element
.Base
= &BaseSpec
;
202 Element
.Class
= Record
;
203 if (BaseSpec
.isVirtual())
204 Element
.SubobjectNumber
= 0;
206 Element
.SubobjectNumber
= Subobjects
.NumberOfNonVirtBases
;
207 ScratchPath
.push_back(Element
);
209 // Calculate the "top-down" access to this base class.
210 // The spec actually describes this bottom-up, but top-down is
211 // equivalent because the definition works out as follows:
212 // 1. Write down the access along each step in the inheritance
213 // chain, followed by the access of the decl itself.
215 // class A { public: int foo; };
216 // class B : protected A {};
217 // class C : public B {};
218 // class D : private C {};
220 // private public protected public
221 // 2. If 'private' appears anywhere except far-left, access is denied.
222 // 3. Otherwise, overall access is determined by the most restrictive
223 // access in the sequence.
225 ScratchPath
.Access
= BaseSpec
.getAccessSpecifier();
227 ScratchPath
.Access
= CXXRecordDecl::MergeAccess(AccessToHere
,
228 BaseSpec
.getAccessSpecifier());
231 // Track whether there's a path involving this specific base.
232 bool FoundPathThroughBase
= false;
234 if (BaseMatches(&BaseSpec
, ScratchPath
)) {
235 // We've found a path that terminates at this base.
236 FoundPath
= FoundPathThroughBase
= true;
237 if (isRecordingPaths()) {
238 // We have a path. Make a copy of it before moving on.
239 Paths
.push_back(ScratchPath
);
240 } else if (!isFindingAmbiguities()) {
241 // We found a path and we don't care about ambiguities;
242 // return immediately.
245 } else if (VisitBase
) {
246 CXXRecordDecl
*BaseRecord
;
247 if (LookupInDependent
) {
248 BaseRecord
= nullptr;
249 const TemplateSpecializationType
*TST
=
250 BaseSpec
.getType()->getAs
<TemplateSpecializationType
>();
252 if (auto *RT
= BaseSpec
.getType()->getAs
<RecordType
>())
253 BaseRecord
= cast
<CXXRecordDecl
>(RT
->getDecl());
255 TemplateName TN
= TST
->getTemplateName();
257 dyn_cast_or_null
<ClassTemplateDecl
>(TN
.getAsTemplateDecl()))
258 BaseRecord
= TD
->getTemplatedDecl();
261 if (!BaseRecord
->hasDefinition())
262 BaseRecord
= nullptr;
263 else if (!VisitedDependentRecords
.insert(BaseRecord
).second
)
264 BaseRecord
= nullptr;
267 BaseRecord
= cast
<CXXRecordDecl
>(
268 BaseSpec
.getType()->castAs
<RecordType
>()->getDecl());
271 lookupInBases(Context
, BaseRecord
, BaseMatches
, LookupInDependent
)) {
272 // C++ [class.member.lookup]p2:
273 // A member name f in one sub-object B hides a member name f in
274 // a sub-object A if A is a base class sub-object of B. Any
275 // declarations that are so hidden are eliminated from
278 // There is a path to a base class that meets the criteria. If we're
279 // not collecting paths or finding ambiguities, we're done.
280 FoundPath
= FoundPathThroughBase
= true;
281 if (!isFindingAmbiguities())
286 // Pop this base specifier off the current path (if we're
287 // collecting paths).
288 if (isRecordingPaths()) {
289 ScratchPath
.pop_back();
292 // If we set a virtual earlier, and this isn't a path, forget it again.
293 if (SetVirtual
&& !FoundPathThroughBase
) {
294 DetectedVirtual
= nullptr;
298 // Reset the scratch path access.
299 ScratchPath
.Access
= AccessToHere
;
304 bool CXXRecordDecl::lookupInBases(BaseMatchesCallback BaseMatches
,
306 bool LookupInDependent
) const {
307 // If we didn't find anything, report that.
308 if (!Paths
.lookupInBases(getASTContext(), this, BaseMatches
,
312 // If we're not recording paths or we won't ever find ambiguities,
314 if (!Paths
.isRecordingPaths() || !Paths
.isFindingAmbiguities())
317 // C++ [class.member.lookup]p6:
318 // When virtual base classes are used, a hidden declaration can be
319 // reached along a path through the sub-object lattice that does
320 // not pass through the hiding declaration. This is not an
321 // ambiguity. The identical use with nonvirtual base classes is an
322 // ambiguity; in that case there is no unique instance of the name
323 // that hides all the others.
325 // FIXME: This is an O(N^2) algorithm, but DPG doesn't see an easy
326 // way to make it any faster.
327 Paths
.Paths
.remove_if([&Paths
](const CXXBasePath
&Path
) {
328 for (const CXXBasePathElement
&PE
: Path
) {
329 if (!PE
.Base
->isVirtual())
332 CXXRecordDecl
*VBase
= nullptr;
333 if (const RecordType
*Record
= PE
.Base
->getType()->getAs
<RecordType
>())
334 VBase
= cast
<CXXRecordDecl
>(Record
->getDecl());
338 // The declaration(s) we found along this path were found in a
339 // subobject of a virtual base. Check whether this virtual
340 // base is a subobject of any other path; if so, then the
341 // declaration in this path are hidden by that patch.
342 for (const CXXBasePath
&HidingP
: Paths
) {
343 CXXRecordDecl
*HidingClass
= nullptr;
344 if (const RecordType
*Record
=
345 HidingP
.back().Base
->getType()->getAs
<RecordType
>())
346 HidingClass
= cast
<CXXRecordDecl
>(Record
->getDecl());
350 if (HidingClass
->isVirtuallyDerivedFrom(VBase
))
360 bool CXXRecordDecl::FindBaseClass(const CXXBaseSpecifier
*Specifier
,
362 const CXXRecordDecl
*BaseRecord
) {
363 assert(BaseRecord
->getCanonicalDecl() == BaseRecord
&&
364 "User data for FindBaseClass is not canonical!");
365 return Specifier
->getType()->castAs
<RecordType
>()->getDecl()
366 ->getCanonicalDecl() == BaseRecord
;
369 bool CXXRecordDecl::FindVirtualBaseClass(const CXXBaseSpecifier
*Specifier
,
371 const CXXRecordDecl
*BaseRecord
) {
372 assert(BaseRecord
->getCanonicalDecl() == BaseRecord
&&
373 "User data for FindBaseClass is not canonical!");
374 return Specifier
->isVirtual() &&
375 Specifier
->getType()->castAs
<RecordType
>()->getDecl()
376 ->getCanonicalDecl() == BaseRecord
;
379 static bool isOrdinaryMember(const NamedDecl
*ND
) {
380 return ND
->isInIdentifierNamespace(Decl::IDNS_Ordinary
| Decl::IDNS_Tag
|
384 static bool findOrdinaryMember(const CXXRecordDecl
*RD
, CXXBasePath
&Path
,
385 DeclarationName Name
) {
386 Path
.Decls
= RD
->lookup(Name
).begin();
387 for (DeclContext::lookup_iterator I
= Path
.Decls
, E
= I
.end(); I
!= E
; ++I
)
388 if (isOrdinaryMember(*I
))
394 bool CXXRecordDecl::hasMemberName(DeclarationName Name
) const {
396 if (findOrdinaryMember(this, P
, Name
))
399 CXXBasePaths
Paths(false, false, false);
400 return lookupInBases(
401 [Name
](const CXXBaseSpecifier
*Specifier
, CXXBasePath
&Path
) {
402 return findOrdinaryMember(Specifier
->getType()->getAsCXXRecordDecl(),
409 findOrdinaryMemberInDependentClasses(const CXXBaseSpecifier
*Specifier
,
410 CXXBasePath
&Path
, DeclarationName Name
) {
411 const TemplateSpecializationType
*TST
=
412 Specifier
->getType()->getAs
<TemplateSpecializationType
>();
414 auto *RT
= Specifier
->getType()->getAs
<RecordType
>();
417 return findOrdinaryMember(cast
<CXXRecordDecl
>(RT
->getDecl()), Path
, Name
);
419 TemplateName TN
= TST
->getTemplateName();
420 const auto *TD
= dyn_cast_or_null
<ClassTemplateDecl
>(TN
.getAsTemplateDecl());
423 CXXRecordDecl
*RD
= TD
->getTemplatedDecl();
426 return findOrdinaryMember(RD
, Path
, Name
);
429 std::vector
<const NamedDecl
*> CXXRecordDecl::lookupDependentName(
430 DeclarationName Name
,
431 llvm::function_ref
<bool(const NamedDecl
*ND
)> Filter
) {
432 std::vector
<const NamedDecl
*> Results
;
433 // Lookup in the class.
434 bool AnyOrdinaryMembers
= false;
435 for (const NamedDecl
*ND
: lookup(Name
)) {
436 if (isOrdinaryMember(ND
))
437 AnyOrdinaryMembers
= true;
439 Results
.push_back(ND
);
441 if (AnyOrdinaryMembers
)
444 // Perform lookup into our base classes.
446 Paths
.setOrigin(this);
448 [&](const CXXBaseSpecifier
*Specifier
, CXXBasePath
&Path
) {
449 return findOrdinaryMemberInDependentClasses(Specifier
, Path
, Name
);
451 Paths
, /*LookupInDependent=*/true))
453 for (DeclContext::lookup_iterator I
= Paths
.front().Decls
, E
= I
.end();
455 if (isOrdinaryMember(*I
) && Filter(*I
))
456 Results
.push_back(*I
);
461 void OverridingMethods::add(unsigned OverriddenSubobject
,
462 UniqueVirtualMethod Overriding
) {
463 SmallVectorImpl
<UniqueVirtualMethod
> &SubobjectOverrides
464 = Overrides
[OverriddenSubobject
];
465 if (!llvm::is_contained(SubobjectOverrides
, Overriding
))
466 SubobjectOverrides
.push_back(Overriding
);
469 void OverridingMethods::add(const OverridingMethods
&Other
) {
470 for (const_iterator I
= Other
.begin(), IE
= Other
.end(); I
!= IE
; ++I
) {
471 for (overriding_const_iterator M
= I
->second
.begin(),
472 MEnd
= I
->second
.end();
479 void OverridingMethods::replaceAll(UniqueVirtualMethod Overriding
) {
480 for (iterator I
= begin(), IEnd
= end(); I
!= IEnd
; ++I
) {
482 I
->second
.push_back(Overriding
);
488 class FinalOverriderCollector
{
489 /// The number of subobjects of a given class type that
490 /// occur within the class hierarchy.
491 llvm::DenseMap
<const CXXRecordDecl
*, unsigned> SubobjectCount
;
493 /// Overriders for each virtual base subobject.
494 llvm::DenseMap
<const CXXRecordDecl
*, CXXFinalOverriderMap
*> VirtualOverriders
;
496 CXXFinalOverriderMap FinalOverriders
;
499 ~FinalOverriderCollector();
501 void Collect(const CXXRecordDecl
*RD
, bool VirtualBase
,
502 const CXXRecordDecl
*InVirtualSubobject
,
503 CXXFinalOverriderMap
&Overriders
);
508 void FinalOverriderCollector::Collect(const CXXRecordDecl
*RD
,
510 const CXXRecordDecl
*InVirtualSubobject
,
511 CXXFinalOverriderMap
&Overriders
) {
512 unsigned SubobjectNumber
= 0;
515 = ++SubobjectCount
[cast
<CXXRecordDecl
>(RD
->getCanonicalDecl())];
517 for (const auto &Base
: RD
->bases()) {
518 if (const RecordType
*RT
= Base
.getType()->getAs
<RecordType
>()) {
519 const CXXRecordDecl
*BaseDecl
= cast
<CXXRecordDecl
>(RT
->getDecl());
520 if (!BaseDecl
->isPolymorphic())
523 if (Overriders
.empty() && !Base
.isVirtual()) {
524 // There are no other overriders of virtual member functions,
525 // so let the base class fill in our overriders for us.
526 Collect(BaseDecl
, false, InVirtualSubobject
, Overriders
);
530 // Collect all of the overridders from the base class subobject
531 // and merge them into the set of overridders for this class.
532 // For virtual base classes, populate or use the cached virtual
533 // overrides so that we do not walk the virtual base class (and
534 // its base classes) more than once.
535 CXXFinalOverriderMap ComputedBaseOverriders
;
536 CXXFinalOverriderMap
*BaseOverriders
= &ComputedBaseOverriders
;
537 if (Base
.isVirtual()) {
538 CXXFinalOverriderMap
*&MyVirtualOverriders
= VirtualOverriders
[BaseDecl
];
539 BaseOverriders
= MyVirtualOverriders
;
540 if (!MyVirtualOverriders
) {
541 MyVirtualOverriders
= new CXXFinalOverriderMap
;
543 // Collect may cause VirtualOverriders to reallocate, invalidating the
544 // MyVirtualOverriders reference. Set BaseOverriders to the right
546 BaseOverriders
= MyVirtualOverriders
;
548 Collect(BaseDecl
, true, BaseDecl
, *MyVirtualOverriders
);
551 Collect(BaseDecl
, false, InVirtualSubobject
, ComputedBaseOverriders
);
553 // Merge the overriders from this base class into our own set of
555 for (CXXFinalOverriderMap::iterator OM
= BaseOverriders
->begin(),
556 OMEnd
= BaseOverriders
->end();
559 const CXXMethodDecl
*CanonOM
= OM
->first
->getCanonicalDecl();
560 Overriders
[CanonOM
].add(OM
->second
);
565 for (auto *M
: RD
->methods()) {
566 // We only care about virtual methods.
570 CXXMethodDecl
*CanonM
= M
->getCanonicalDecl();
571 using OverriddenMethodsRange
=
572 llvm::iterator_range
<CXXMethodDecl::method_iterator
>;
573 OverriddenMethodsRange OverriddenMethods
= CanonM
->overridden_methods();
575 if (OverriddenMethods
.begin() == OverriddenMethods
.end()) {
576 // This is a new virtual function that does not override any
577 // other virtual function. Add it to the map of virtual
578 // functions for which we are tracking overridders.
580 // C++ [class.virtual]p2:
581 // For convenience we say that any virtual function overrides itself.
582 Overriders
[CanonM
].add(SubobjectNumber
,
583 UniqueVirtualMethod(CanonM
, SubobjectNumber
,
584 InVirtualSubobject
));
588 // This virtual method overrides other virtual methods, so it does
589 // not add any new slots into the set of overriders. Instead, we
590 // replace entries in the set of overriders with the new
591 // overrider. To do so, we dig down to the original virtual
592 // functions using data recursion and update all of the methods it
594 SmallVector
<OverriddenMethodsRange
, 4> Stack(1, OverriddenMethods
);
595 while (!Stack
.empty()) {
596 for (const CXXMethodDecl
*OM
: Stack
.pop_back_val()) {
597 const CXXMethodDecl
*CanonOM
= OM
->getCanonicalDecl();
599 // C++ [class.virtual]p2:
600 // A virtual member function C::vf of a class object S is
601 // a final overrider unless the most derived class (1.8)
602 // of which S is a base class subobject (if any) declares
603 // or inherits another member function that overrides vf.
605 // Treating this object like the most derived class, we
606 // replace any overrides from base classes with this
607 // overriding virtual function.
608 Overriders
[CanonOM
].replaceAll(
609 UniqueVirtualMethod(CanonM
, SubobjectNumber
,
610 InVirtualSubobject
));
612 auto OverriddenMethods
= CanonOM
->overridden_methods();
613 if (OverriddenMethods
.begin() == OverriddenMethods
.end())
616 // Continue recursion to the methods that this virtual method
618 Stack
.push_back(OverriddenMethods
);
622 // C++ [class.virtual]p2:
623 // For convenience we say that any virtual function overrides itself.
624 Overriders
[CanonM
].add(SubobjectNumber
,
625 UniqueVirtualMethod(CanonM
, SubobjectNumber
,
626 InVirtualSubobject
));
630 FinalOverriderCollector::~FinalOverriderCollector() {
631 for (llvm::DenseMap
<const CXXRecordDecl
*, CXXFinalOverriderMap
*>::iterator
632 VO
= VirtualOverriders
.begin(), VOEnd
= VirtualOverriders
.end();
639 CXXRecordDecl::getFinalOverriders(CXXFinalOverriderMap
&FinalOverriders
) const {
640 FinalOverriderCollector Collector
;
641 Collector
.Collect(this, false, nullptr, FinalOverriders
);
643 // Weed out any final overriders that come from virtual base class
644 // subobjects that were hidden by other subobjects along any path.
645 // This is the final-overrider variant of C++ [class.member.lookup]p10.
646 for (auto &OM
: FinalOverriders
) {
647 for (auto &SO
: OM
.second
) {
648 SmallVectorImpl
<UniqueVirtualMethod
> &Overriding
= SO
.second
;
649 if (Overriding
.size() < 2)
652 auto IsHidden
= [&Overriding
](const UniqueVirtualMethod
&M
) {
653 if (!M
.InVirtualSubobject
)
656 // We have an overriding method in a virtual base class
657 // subobject (or non-virtual base class subobject thereof);
658 // determine whether there exists an other overriding method
659 // in a base class subobject that hides the virtual base class
661 for (const UniqueVirtualMethod
&OP
: Overriding
)
663 OP
.Method
->getParent()->isVirtuallyDerivedFrom(
664 M
.InVirtualSubobject
))
669 // FIXME: IsHidden reads from Overriding from the middle of a remove_if
670 // over the same sequence! Is this guaranteed to work?
671 llvm::erase_if(Overriding
, IsHidden
);
677 AddIndirectPrimaryBases(const CXXRecordDecl
*RD
, ASTContext
&Context
,
678 CXXIndirectPrimaryBaseSet
& Bases
) {
679 // If the record has a virtual primary base class, add it to our set.
680 const ASTRecordLayout
&Layout
= Context
.getASTRecordLayout(RD
);
681 if (Layout
.isPrimaryBaseVirtual())
682 Bases
.insert(Layout
.getPrimaryBase());
684 for (const auto &I
: RD
->bases()) {
685 assert(!I
.getType()->isDependentType() &&
686 "Cannot get indirect primary bases for class with dependent bases.");
688 const CXXRecordDecl
*BaseDecl
=
689 cast
<CXXRecordDecl
>(I
.getType()->castAs
<RecordType
>()->getDecl());
691 // Only bases with virtual bases participate in computing the
692 // indirect primary virtual base classes.
693 if (BaseDecl
->getNumVBases())
694 AddIndirectPrimaryBases(BaseDecl
, Context
, Bases
);
700 CXXRecordDecl::getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet
& Bases
) const {
701 ASTContext
&Context
= getASTContext();
706 for (const auto &I
: bases()) {
707 assert(!I
.getType()->isDependentType() &&
708 "Cannot get indirect primary bases for class with dependent bases.");
710 const CXXRecordDecl
*BaseDecl
=
711 cast
<CXXRecordDecl
>(I
.getType()->castAs
<RecordType
>()->getDecl());
713 // Only bases with virtual bases participate in computing the
714 // indirect primary virtual base classes.
715 if (BaseDecl
->getNumVBases())
716 AddIndirectPrimaryBases(BaseDecl
, Context
, Bases
);