clang 22.0.0git
CXXInheritance.cpp
Go to the documentation of this file.
1//===- CXXInheritance.cpp - C++ Inheritance -------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8//
9// This file provides routines that help analyzing C++ inheritance hierarchies.
10//
11//===----------------------------------------------------------------------===//
12
15#include "clang/AST/Decl.h"
16#include "clang/AST/DeclBase.h"
17#include "clang/AST/DeclCXX.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"
27#include <algorithm>
28#include <cassert>
29#include <utility>
30
31using namespace clang;
32
33/// isAmbiguous - Determines whether the set of paths provided is
34/// ambiguous, i.e., there are two or more paths that refer to
35/// different base class subobjects of the same type. BaseType must be
36/// an unqualified, canonical class type.
38 BaseType = BaseType.getUnqualifiedType();
39 IsVirtBaseAndNumberNonVirtBases Subobjects = ClassSubobjects[BaseType];
40 return Subobjects.NumberOfNonVirtBases + (Subobjects.IsVirtBase ? 1 : 0) > 1;
41}
42
43/// clear - Clear out all prior path information.
45 Paths.clear();
46 ClassSubobjects.clear();
47 VisitedDependentRecords.clear();
48 ScratchPath.clear();
49 DetectedVirtual = nullptr;
50}
51
52/// Swaps the contents of this CXXBasePaths structure with the
53/// contents of Other.
55 std::swap(Origin, Other.Origin);
56 Paths.swap(Other.Paths);
57 ClassSubobjects.swap(Other.ClassSubobjects);
58 VisitedDependentRecords.swap(Other.VisitedDependentRecords);
59 std::swap(FindAmbiguities, Other.FindAmbiguities);
60 std::swap(RecordPaths, Other.RecordPaths);
61 std::swap(DetectVirtual, Other.DetectVirtual);
62 std::swap(DetectedVirtual, Other.DetectedVirtual);
63}
64
66 CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false,
67 /*DetectVirtual=*/false);
68 return isDerivedFrom(Base, Paths);
69}
70
72 CXXBasePaths &Paths) const {
73 if (getCanonicalDecl() == Base->getCanonicalDecl())
74 return false;
75
76 Paths.setOrigin(const_cast<CXXRecordDecl*>(this));
77
78 const CXXRecordDecl *BaseDecl = Base->getCanonicalDecl();
79 return lookupInBases(
80 [BaseDecl](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
81 return Specifier->getType()->getAsRecordDecl() &&
82 FindBaseClass(Specifier, Path, BaseDecl);
83 },
84 Paths);
85}
86
88 if (!getNumVBases())
89 return false;
90
91 CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false,
92 /*DetectVirtual=*/false);
93
94 if (getCanonicalDecl() == Base->getCanonicalDecl())
95 return false;
96
97 Paths.setOrigin(const_cast<CXXRecordDecl*>(this));
98
99 const CXXRecordDecl *BaseDecl = Base->getCanonicalDecl();
100 return lookupInBases(
101 [BaseDecl](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
102 return FindVirtualBaseClass(Specifier, Path, BaseDecl);
103 },
104 Paths);
105}
106
108 const CXXRecordDecl *TargetDecl = Base->getCanonicalDecl();
109 return forallBases([TargetDecl](const CXXRecordDecl *Base) {
110 return Base->getCanonicalDecl() != TargetDecl;
111 });
112}
113
114bool
116 assert(isDependentContext());
117
118 for (; !CurContext->isFileContext(); CurContext = CurContext->getParent())
119 if (CurContext->Equals(this))
120 return true;
121
122 return false;
123}
124
127
128 const CXXRecordDecl *Record = this;
129 while (true) {
130 for (const auto &I : Record->bases()) {
131 const auto *Base = I.getType()->getAsCXXRecordDecl();
132 if (!Base || !(Base->isBeingDefined() || Base->isCompleteDefinition()))
133 return false;
134 if (Base->isDependentContext() && !Base->isCurrentInstantiation(Record))
135 return false;
136
137 Queue.push_back(Base);
138 if (!BaseMatches(Base))
139 return false;
140 }
141
142 if (Queue.empty())
143 break;
144 Record = Queue.pop_back_val(); // not actually a queue.
145 }
146
147 return true;
148}
149
150bool CXXBasePaths::lookupInBases(ASTContext &Context,
151 const CXXRecordDecl *Record,
153 bool LookupInDependent) {
154 bool FoundPath = false;
155
156 // The access of the path down to this record.
157 AccessSpecifier AccessToHere = ScratchPath.Access;
158 bool IsFirstStep = ScratchPath.empty();
159
160 for (const auto &BaseSpec : Record->bases()) {
161 // Find the record of the base class subobjects for this type.
162 QualType BaseType =
163 Context.getCanonicalType(BaseSpec.getType()).getUnqualifiedType();
164
165 bool isCurrentInstantiation = isa<InjectedClassNameType>(BaseType);
166 if (!isCurrentInstantiation) {
167 if (auto *BaseRecord = cast_if_present<CXXRecordDecl>(
168 BaseSpec.getType()->getAsRecordDecl()))
169 isCurrentInstantiation = BaseRecord->isDependentContext() &&
170 BaseRecord->isCurrentInstantiation(Record);
171 }
172 // C++ [temp.dep]p3:
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 &&
179 (BaseType->isDependentType() && !isCurrentInstantiation))
180 continue;
181
182 // Determine whether we need to visit this base class at all,
183 // updating the count of subobjects appropriately.
184 IsVirtBaseAndNumberNonVirtBases &Subobjects = ClassSubobjects[BaseType];
185 bool VisitBase = true;
186 bool SetVirtual = false;
187 if (BaseSpec.isVirtual()) {
188 VisitBase = !Subobjects.IsVirtBase;
189 Subobjects.IsVirtBase = true;
190 if (isDetectingVirtual() && DetectedVirtual == nullptr) {
191 // If this is the first virtual we find, remember it. If it turns out
192 // there is no base path here, we'll reset it later.
193 DetectedVirtual = BaseType->getAsCanonical<RecordType>();
194 SetVirtual = true;
195 }
196 } else {
197 ++Subobjects.NumberOfNonVirtBases;
198 }
199 if (isRecordingPaths()) {
200 // Add this base specifier to the current path.
201 CXXBasePathElement Element;
202 Element.Base = &BaseSpec;
203 Element.Class = Record;
204 if (BaseSpec.isVirtual())
205 Element.SubobjectNumber = 0;
206 else
207 Element.SubobjectNumber = Subobjects.NumberOfNonVirtBases;
208 ScratchPath.push_back(Element);
209
210 // Calculate the "top-down" access to this base class.
211 // The spec actually describes this bottom-up, but top-down is
212 // equivalent because the definition works out as follows:
213 // 1. Write down the access along each step in the inheritance
214 // chain, followed by the access of the decl itself.
215 // For example, in
216 // class A { public: int foo; };
217 // class B : protected A {};
218 // class C : public B {};
219 // class D : private C {};
220 // we would write:
221 // private public protected public
222 // 2. If 'private' appears anywhere except far-left, access is denied.
223 // 3. Otherwise, overall access is determined by the most restrictive
224 // access in the sequence.
225 if (IsFirstStep)
226 ScratchPath.Access = BaseSpec.getAccessSpecifier();
227 else
228 ScratchPath.Access = CXXRecordDecl::MergeAccess(AccessToHere,
229 BaseSpec.getAccessSpecifier());
230 }
231
232 // Track whether there's a path involving this specific base.
233 bool FoundPathThroughBase = false;
234
235 if (BaseMatches(&BaseSpec, ScratchPath)) {
236 // We've found a path that terminates at this base.
237 FoundPath = FoundPathThroughBase = true;
238 if (isRecordingPaths()) {
239 // We have a path. Make a copy of it before moving on.
240 Paths.push_back(ScratchPath);
241 } else if (!isFindingAmbiguities()) {
242 // We found a path and we don't care about ambiguities;
243 // return immediately.
244 return FoundPath;
245 }
246 } else if (VisitBase) {
247 CXXRecordDecl *BaseRecord = nullptr;
248 if (LookupInDependent) {
249 const TemplateSpecializationType *TST =
250 BaseSpec.getType()->getAs<TemplateSpecializationType>();
251 if (!TST) {
252 BaseRecord = BaseSpec.getType()->getAsCXXRecordDecl();
253 } else {
254 TemplateName TN = TST->getTemplateName();
255 if (auto *TD =
256 dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl()))
257 BaseRecord = TD->getTemplatedDecl();
258 }
259 if (BaseRecord) {
260 if (!BaseRecord->hasDefinition())
261 BaseRecord = nullptr;
262 else if (!VisitedDependentRecords.insert(BaseRecord).second)
263 BaseRecord = nullptr;
264 }
265 } else {
266 BaseRecord = BaseSpec.getType()->castAsCXXRecordDecl();
267 }
268 if (BaseRecord &&
269 lookupInBases(Context, BaseRecord, BaseMatches, LookupInDependent)) {
270 // C++ [class.member.lookup]p2:
271 // A member name f in one sub-object B hides a member name f in
272 // a sub-object A if A is a base class sub-object of B. Any
273 // declarations that are so hidden are eliminated from
274 // consideration.
275
276 // There is a path to a base class that meets the criteria. If we're
277 // not collecting paths or finding ambiguities, we're done.
278 FoundPath = FoundPathThroughBase = true;
280 return FoundPath;
281 }
282 }
283
284 // Pop this base specifier off the current path (if we're
285 // collecting paths).
286 if (isRecordingPaths()) {
287 ScratchPath.pop_back();
288 }
289
290 // If we set a virtual earlier, and this isn't a path, forget it again.
291 if (SetVirtual && !FoundPathThroughBase) {
292 DetectedVirtual = nullptr;
293 }
294 }
295
296 // Reset the scratch path access.
297 ScratchPath.Access = AccessToHere;
298
299 return FoundPath;
300}
301
303 CXXBasePaths &Paths,
304 bool LookupInDependent) const {
305 // If we didn't find anything, report that.
306 if (!Paths.lookupInBases(getASTContext(), this, BaseMatches,
307 LookupInDependent))
308 return false;
309
310 // If we're not recording paths or we won't ever find ambiguities,
311 // we're done.
312 if (!Paths.isRecordingPaths() || !Paths.isFindingAmbiguities())
313 return true;
314
315 // C++ [class.member.lookup]p6:
316 // When virtual base classes are used, a hidden declaration can be
317 // reached along a path through the sub-object lattice that does
318 // not pass through the hiding declaration. This is not an
319 // ambiguity. The identical use with nonvirtual base classes is an
320 // ambiguity; in that case there is no unique instance of the name
321 // that hides all the others.
322 //
323 // FIXME: This is an O(N^2) algorithm, but DPG doesn't see an easy
324 // way to make it any faster.
325 Paths.Paths.remove_if([&Paths](const CXXBasePath &Path) {
326 for (const CXXBasePathElement &PE : Path) {
327 if (!PE.Base->isVirtual())
328 continue;
329
330 auto *VBase = PE.Base->getType()->getAsCXXRecordDecl();
331 if (!VBase)
332 break;
333
334 // The declaration(s) we found along this path were found in a
335 // subobject of a virtual base. Check whether this virtual
336 // base is a subobject of any other path; if so, then the
337 // declaration in this path are hidden by that patch.
338 for (const CXXBasePath &HidingP : Paths) {
339 auto *HidingClass =
340 HidingP.back().Base->getType()->getAsCXXRecordDecl();
341 if (!HidingClass)
342 break;
343
344 if (HidingClass->isVirtuallyDerivedFrom(VBase))
345 return true;
346 }
347 }
348 return false;
349 });
350
351 return true;
352}
353
355 CXXBasePath &Path,
356 const CXXRecordDecl *BaseRecord) {
357 assert(BaseRecord->getCanonicalDecl() == BaseRecord &&
358 "User data for FindBaseClass is not canonical!");
359 return cast<CXXRecordDecl>(Specifier->getType()->getAsRecordDecl())
360 ->getCanonicalDecl() == BaseRecord;
361}
362
364 CXXBasePath &Path,
365 const CXXRecordDecl *BaseRecord) {
366 assert(BaseRecord->getCanonicalDecl() == BaseRecord &&
367 "User data for FindBaseClass is not canonical!");
368 return Specifier->isVirtual() &&
369 cast<CXXRecordDecl>(Specifier->getType()->getAsRecordDecl())
370 ->getCanonicalDecl() == BaseRecord;
371}
372
377
378static bool findOrdinaryMember(const CXXRecordDecl *RD, CXXBasePath &Path,
379 DeclarationName Name) {
380 Path.Decls = RD->lookup(Name).begin();
381 for (DeclContext::lookup_iterator I = Path.Decls, E = I.end(); I != E; ++I)
382 if (isOrdinaryMember(*I))
383 return true;
384
385 return false;
386}
387
389 CXXBasePath P;
390 if (findOrdinaryMember(this, P, Name))
391 return true;
392
393 CXXBasePaths Paths(false, false, false);
394 return lookupInBases(
395 [Name](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
396 return findOrdinaryMember(Specifier->getType()->castAsCXXRecordDecl(),
397 Path, Name);
398 },
399 Paths);
400}
401
402void OverridingMethods::add(unsigned OverriddenSubobject,
403 UniqueVirtualMethod Overriding) {
404 SmallVectorImpl<UniqueVirtualMethod> &SubobjectOverrides
405 = Overrides[OverriddenSubobject];
406 if (!llvm::is_contained(SubobjectOverrides, Overriding))
407 SubobjectOverrides.push_back(Overriding);
408}
409
411 for (const_iterator I = Other.begin(), IE = Other.end(); I != IE; ++I) {
412 for (overriding_const_iterator M = I->second.begin(),
413 MEnd = I->second.end();
414 M != MEnd;
415 ++M)
416 add(I->first, *M);
417 }
418}
419
421 for (iterator I = begin(), IEnd = end(); I != IEnd; ++I) {
422 I->second.clear();
423 I->second.push_back(Overriding);
424 }
425}
426
427namespace {
428
429class FinalOverriderCollector {
430 /// The number of subobjects of a given class type that
431 /// occur within the class hierarchy.
432 llvm::DenseMap<const CXXRecordDecl *, unsigned> SubobjectCount;
433
434 /// Overriders for each virtual base subobject.
435 llvm::DenseMap<const CXXRecordDecl *, CXXFinalOverriderMap *> VirtualOverriders;
436
437 CXXFinalOverriderMap FinalOverriders;
438
439public:
440 ~FinalOverriderCollector();
441
442 void Collect(const CXXRecordDecl *RD, bool VirtualBase,
443 const CXXRecordDecl *InVirtualSubobject,
444 CXXFinalOverriderMap &Overriders);
445};
446
447} // namespace
448
449void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
450 bool VirtualBase,
451 const CXXRecordDecl *InVirtualSubobject,
452 CXXFinalOverriderMap &Overriders) {
453 unsigned SubobjectNumber = 0;
454 if (!VirtualBase)
455 SubobjectNumber
456 = ++SubobjectCount[cast<CXXRecordDecl>(RD->getCanonicalDecl())];
457
458 for (const auto &Base : RD->bases()) {
459 if (const auto *BaseDecl = Base.getType()->getAsCXXRecordDecl()) {
460 if (!BaseDecl->isPolymorphic())
461 continue;
462
463 if (Overriders.empty() && !Base.isVirtual()) {
464 // There are no other overriders of virtual member functions,
465 // so let the base class fill in our overriders for us.
466 Collect(BaseDecl, false, InVirtualSubobject, Overriders);
467 continue;
468 }
469
470 // Collect all of the overridders from the base class subobject
471 // and merge them into the set of overridders for this class.
472 // For virtual base classes, populate or use the cached virtual
473 // overrides so that we do not walk the virtual base class (and
474 // its base classes) more than once.
475 CXXFinalOverriderMap ComputedBaseOverriders;
476 CXXFinalOverriderMap *BaseOverriders = &ComputedBaseOverriders;
477 if (Base.isVirtual()) {
478 CXXFinalOverriderMap *&MyVirtualOverriders = VirtualOverriders[BaseDecl];
479 BaseOverriders = MyVirtualOverriders;
480 if (!MyVirtualOverriders) {
481 MyVirtualOverriders = new CXXFinalOverriderMap;
482
483 // Collect may cause VirtualOverriders to reallocate, invalidating the
484 // MyVirtualOverriders reference. Set BaseOverriders to the right
485 // value now.
486 BaseOverriders = MyVirtualOverriders;
487
488 Collect(BaseDecl, true, BaseDecl, *MyVirtualOverriders);
489 }
490 } else
491 Collect(BaseDecl, false, InVirtualSubobject, ComputedBaseOverriders);
492
493 // Merge the overriders from this base class into our own set of
494 // overriders.
495 for (CXXFinalOverriderMap::iterator OM = BaseOverriders->begin(),
496 OMEnd = BaseOverriders->end();
497 OM != OMEnd;
498 ++OM) {
499 const CXXMethodDecl *CanonOM = OM->first->getCanonicalDecl();
500 Overriders[CanonOM].add(OM->second);
501 }
502 }
503 }
504
505 for (auto *M : RD->methods()) {
506 // We only care about virtual methods.
507 if (!M->isVirtual())
508 continue;
509
510 CXXMethodDecl *CanonM = M->getCanonicalDecl();
511 using OverriddenMethodsRange =
512 llvm::iterator_range<CXXMethodDecl::method_iterator>;
513 OverriddenMethodsRange OverriddenMethods = CanonM->overridden_methods();
514
515 if (OverriddenMethods.begin() == OverriddenMethods.end()) {
516 // This is a new virtual function that does not override any
517 // other virtual function. Add it to the map of virtual
518 // functions for which we are tracking overridders.
519
520 // C++ [class.virtual]p2:
521 // For convenience we say that any virtual function overrides itself.
522 Overriders[CanonM].add(SubobjectNumber,
523 UniqueVirtualMethod(CanonM, SubobjectNumber,
524 InVirtualSubobject));
525 continue;
526 }
527
528 // This virtual method overrides other virtual methods, so it does
529 // not add any new slots into the set of overriders. Instead, we
530 // replace entries in the set of overriders with the new
531 // overrider. To do so, we dig down to the original virtual
532 // functions using data recursion and update all of the methods it
533 // overrides.
534 SmallVector<OverriddenMethodsRange, 4> Stack(1, OverriddenMethods);
535 while (!Stack.empty()) {
536 for (const CXXMethodDecl *OM : Stack.pop_back_val()) {
537 const CXXMethodDecl *CanonOM = OM->getCanonicalDecl();
538
539 // C++ [class.virtual]p2:
540 // A virtual member function C::vf of a class object S is
541 // a final overrider unless the most derived class (1.8)
542 // of which S is a base class subobject (if any) declares
543 // or inherits another member function that overrides vf.
544 //
545 // Treating this object like the most derived class, we
546 // replace any overrides from base classes with this
547 // overriding virtual function.
548 Overriders[CanonOM].replaceAll(
549 UniqueVirtualMethod(CanonM, SubobjectNumber,
550 InVirtualSubobject));
551
552 auto OverriddenMethods = CanonOM->overridden_methods();
553 if (OverriddenMethods.begin() == OverriddenMethods.end())
554 continue;
555
556 // Continue recursion to the methods that this virtual method
557 // overrides.
558 Stack.push_back(OverriddenMethods);
559 }
560 }
561
562 // C++ [class.virtual]p2:
563 // For convenience we say that any virtual function overrides itself.
564 Overriders[CanonM].add(SubobjectNumber,
565 UniqueVirtualMethod(CanonM, SubobjectNumber,
566 InVirtualSubobject));
567 }
568}
569
570FinalOverriderCollector::~FinalOverriderCollector() {
571 for (llvm::DenseMap<const CXXRecordDecl *, CXXFinalOverriderMap *>::iterator
572 VO = VirtualOverriders.begin(), VOEnd = VirtualOverriders.end();
573 VO != VOEnd;
574 ++VO)
575 delete VO->second;
576}
577
578void
580 FinalOverriderCollector Collector;
581 Collector.Collect(this, false, nullptr, FinalOverriders);
582
583 // Weed out any final overriders that come from virtual base class
584 // subobjects that were hidden by other subobjects along any path.
585 // This is the final-overrider variant of C++ [class.member.lookup]p10.
586 for (auto &OM : FinalOverriders) {
587 for (auto &SO : OM.second) {
588 SmallVectorImpl<UniqueVirtualMethod> &Overriding = SO.second;
589 if (Overriding.size() < 2)
590 continue;
591
592 auto IsHidden = [&Overriding](const UniqueVirtualMethod &M) {
593 if (!M.InVirtualSubobject)
594 return false;
595
596 // We have an overriding method in a virtual base class
597 // subobject (or non-virtual base class subobject thereof);
598 // determine whether there exists an other overriding method
599 // in a base class subobject that hides the virtual base class
600 // subobject.
601 for (const UniqueVirtualMethod &OP : Overriding)
602 if (&M != &OP &&
603 OP.Method->getParent()->isVirtuallyDerivedFrom(
604 M.InVirtualSubobject))
605 return true;
606 return false;
607 };
608
609 // FIXME: IsHidden reads from Overriding from the middle of a remove_if
610 // over the same sequence! Is this guaranteed to work?
611 llvm::erase_if(Overriding, IsHidden);
612 }
613 }
614}
615
616static void
619 // If the record has a virtual primary base class, add it to our set.
620 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
621 if (Layout.isPrimaryBaseVirtual())
622 Bases.insert(Layout.getPrimaryBase());
623
624 for (const auto &I : RD->bases()) {
625 assert(!I.getType()->isDependentType() &&
626 "Cannot get indirect primary bases for class with dependent bases.");
627
628 const CXXRecordDecl *BaseDecl =
629 cast<CXXRecordDecl>(I.getType()->getAsRecordDecl());
630
631 // Only bases with virtual bases participate in computing the
632 // indirect primary virtual base classes.
633 if (BaseDecl->getNumVBases())
634 AddIndirectPrimaryBases(BaseDecl, Context, Bases);
635 }
636
637}
638
639void
641 ASTContext &Context = getASTContext();
642
643 if (!getNumVBases())
644 return;
645
646 for (const auto &I : bases()) {
647 assert(!I.getType()->isDependentType() &&
648 "Cannot get indirect primary bases for class with dependent bases.");
649
650 const CXXRecordDecl *BaseDecl =
651 cast<CXXRecordDecl>(I.getType()->getAsRecordDecl());
652
653 // Only bases with virtual bases participate in computing the
654 // indirect primary virtual base classes.
655 if (BaseDecl->getNumVBases())
656 AddIndirectPrimaryBases(BaseDecl, Context, Bases);
657 }
658}
Defines the clang::ASTContext interface.
static void AddIndirectPrimaryBases(const CXXRecordDecl *RD, ASTContext &Context, CXXIndirectPrimaryBaseSet &Bases)
static bool isOrdinaryMember(const NamedDecl *ND)
static bool findOrdinaryMember(const CXXRecordDecl *RD, CXXBasePath &Path, DeclarationName Name)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
llvm::MachO::Record Record
Definition MachO.h:31
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:188
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
bool isPrimaryBaseVirtual() const
isPrimaryBaseVirtual - Get whether the primary base for this record is virtual or not.
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
DeclContext::lookup_iterator Decls
The declarations found inside this base class subobject.
AccessSpecifier Access
The access along this inheritance path.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
CXXBasePaths(bool FindAmbiguities=true, bool RecordPaths=true, bool DetectVirtual=true)
BasePaths - Construct a new BasePaths structure to record the paths for a derived-to-base search.
bool isRecordingPaths() const
Whether we are recording paths.
void setOrigin(const CXXRecordDecl *Rec)
bool isDetectingVirtual() const
Whether we are detecting virtual bases.
bool isAmbiguous(CanQualType BaseType)
Determine whether the path from the most-derived type to the given base type is ambiguous (i....
void clear()
Clear the base-paths results.
friend class CXXRecordDecl
bool isFindingAmbiguities() const
Whether we are finding multiple paths to detect ambiguities.
void swap(CXXBasePaths &Other)
Swap this data structure's contents with another CXXBasePaths object.
Represents a base class of a C++ class.
Definition DeclCXX.h:146
A mapping from each virtual member function to its set of final overriders.
A set of all the primary bases for a class.
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2129
overridden_method_range overridden_methods() const
Definition DeclCXX.cpp:2778
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition DeclCXX.h:2225
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
llvm::function_ref< bool(const CXXBaseSpecifier *Specifier, CXXBasePath &Path)> BaseMatchesCallback
Function type used by lookupInBases() to determine whether a specific base class subobject matches th...
Definition DeclCXX.h:1647
void getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet &Bases) const
Get the indirect primary bases for this class.
base_class_range bases()
Definition DeclCXX.h:608
llvm::function_ref< bool(const CXXRecordDecl *BaseDefinition)> ForallBasesCallback
Function type used by forallBases() as a callback.
Definition DeclCXX.h:1624
bool isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is provably not derived from the type Base.
method_range methods() const
Definition DeclCXX.h:650
static AccessSpecifier MergeAccess(AccessSpecifier PathAccess, AccessSpecifier DeclAccess)
Calculates the access of a decl that is reached along a path.
Definition DeclCXX.h:1721
bool lookupInBases(BaseMatchesCallback BaseMatches, CXXBasePaths &Paths, bool LookupInDependent=false) const
Look for entities within the base classes of this C++ class, transitively searching all base class su...
CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl *PrevDecl)
Definition DeclCXX.cpp:124
bool hasDefinition() const
Definition DeclCXX.h:561
void getFinalOverriders(CXXFinalOverriderMap &FinaOverriders) const
Retrieve the final overriders for each virtual member function in the class hierarchy where this clas...
bool isCurrentInstantiation(const DeclContext *CurContext) const
Determine whether this dependent class is a current instantiation, when viewed from within the given ...
bool hasMemberName(DeclarationName N) const
Determine whether this class has a member with the given name, possibly in a non-dependent base class...
static bool FindVirtualBaseClass(const CXXBaseSpecifier *Specifier, CXXBasePath &Path, const CXXRecordDecl *BaseRecord)
Base-class lookup callback that determines whether the given base class specifier refers to a specifi...
static bool FindBaseClass(const CXXBaseSpecifier *Specifier, CXXBasePath &Path, const CXXRecordDecl *BaseRecord)
Base-class lookup callback that determines whether the given base class specifier refers to a specifi...
bool isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is virtually derived from the class Base.
friend class DeclContext
Definition DeclCXX.h:266
bool forallBases(ForallBasesCallback BaseMatches) const
Determines if the given callback holds for all the direct or indirect base classes of this type.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition DeclCXX.h:522
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
Definition DeclCXX.h:623
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2109
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
Definition DeclBase.h:2238
lookup_result::iterator lookup_iterator
Definition DeclBase.h:2578
bool isFileContext() const
Definition DeclBase.h:2180
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:524
bool isInIdentifierNamespace(unsigned NS) const
Definition DeclBase.h:893
@ IDNS_Ordinary
Ordinary names.
Definition DeclBase.h:144
@ IDNS_Member
Members, declared with object declarations within tag definitions.
Definition DeclBase.h:136
@ IDNS_Tag
Tags, declared with 'struct foo;' and referenced with 'struct foo'.
Definition DeclBase.h:125
The name of a declaration.
This represents a decl that may have a name.
Definition Decl.h:273
The set of methods that override a given virtual method in each subobject where it occurs.
void replaceAll(UniqueVirtualMethod Overriding)
MapType::iterator iterator
MapType::const_iterator const_iterator
void add(unsigned OverriddenSubobject, UniqueVirtualMethod Overriding)
SmallVectorImpl< UniqueVirtualMethod >::const_iterator overriding_const_iterator
A (possibly-)qualified type.
Definition TypeBase.h:937
QualType getCanonicalType() const
Definition TypeBase.h:8337
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition TypeBase.h:8379
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
Definition Parser.h:61
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Definition Specifiers.h:123
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Other
Other implicit parameter.
Definition Decl.h:1745
Represents an element in a path from a derived class to a base class.
int SubobjectNumber
Identifies which base class subobject (of type Base->getType()) this base path element refers to.
const CXXRecordDecl * Class
The record decl of the class that the base is a base of.
const CXXBaseSpecifier * Base
The base specifier that states the link from a derived class to a base class, which will be followed ...
Uniquely identifies a virtual method within a class hierarchy by the method itself and a class subobj...