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
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
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
373static bool isOrdinaryMember(const NamedDecl *ND) {
376}
377
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
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.
StringRef P
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)
IndirectLocalPath & Path
Expr * E
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
static RecordDecl * getAsRecordDecl(QualType BaseType, HeuristicResolver &Resolver)
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
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2851
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
Definition: RecordLayout.h:38
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
Definition: RecordLayout.h:235
bool isPrimaryBaseVirtual() const
isPrimaryBaseVirtual - Get whether the primary base for this record is virtual or not.
Definition: RecordLayout.h:243
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
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...
bool isRecordingPaths() const
Whether we are recording paths.
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.
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
void getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet &Bases) const
Get the indirect primary bases for this class.
base_class_range bases()
Definition: DeclCXX.h:608
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...
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...
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:1649
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...
llvm::function_ref< bool(const CXXRecordDecl *BaseDefinition)> ForallBasesCallback
Function type used by forallBases() as a callback.
Definition: DeclCXX.h:1625
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.
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.
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1449
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
bool isFileContext() const
Definition: DeclBase.h:2180
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:1358
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Definition: DeclBase.cpp:1879
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
SmallVectorImpl< UniqueVirtualMethod >::const_iterator overriding_const_iterator
MapType::const_iterator const_iterator
void add(unsigned OverriddenSubobject, UniqueVirtualMethod Overriding)
A (possibly-)qualified type.
Definition: TypeBase.h:937
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: TypeBase.h:6502
Represents a C++ template name within the type system.
Definition: TemplateName.h:222
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
Represents a type template specialization; the template must be a class template, a type alias templa...
Definition: TypeBase.h:7290
TemplateName getTemplateName() const
Retrieve the name of the template that we are specializing.
Definition: TypeBase.h:7355
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: TypeBase.h:2800
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition: TypeBase.h:2939
const T * getAs() const
Member-template getAs<specific type>'.
Definition: TypeBase.h:9159
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Definition: Specifiers.h:123
@ Other
Other implicit parameter.
Represents an element in a path from a derived class to a base class.
Uniquely identifies a virtual method within a class hierarchy by the method itself and a class subobj...