clang 20.0.0git
VTableBuilder.cpp
Go to the documentation of this file.
1//===--- VTableBuilder.cpp - C++ vtable layout builder --------------------===//
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 contains code dealing with generation of the layout of virtual tables.
10//
11//===----------------------------------------------------------------------===//
12
19#include "llvm/ADT/SetOperations.h"
20#include "llvm/ADT/SetVector.h"
21#include "llvm/ADT/SmallPtrSet.h"
22#include "llvm/Support/Format.h"
23#include "llvm/Support/raw_ostream.h"
24#include <algorithm>
25#include <cstdio>
26
27using namespace clang;
28
29#define DUMP_OVERRIDERS 0
30
31namespace {
32
33/// BaseOffset - Represents an offset from a derived class to a direct or
34/// indirect base class.
35struct BaseOffset {
36 /// DerivedClass - The derived class.
37 const CXXRecordDecl *DerivedClass;
38
39 /// VirtualBase - If the path from the derived class to the base class
40 /// involves virtual base classes, this holds the declaration of the last
41 /// virtual base in this path (i.e. closest to the base class).
43
44 /// NonVirtualOffset - The offset from the derived class to the base class.
45 /// (Or the offset from the virtual base class to the base class, if the
46 /// path from the derived class to the base class involves a virtual base
47 /// class.
48 CharUnits NonVirtualOffset;
49
50 BaseOffset() : DerivedClass(nullptr), VirtualBase(nullptr),
51 NonVirtualOffset(CharUnits::Zero()) { }
52 BaseOffset(const CXXRecordDecl *DerivedClass,
53 const CXXRecordDecl *VirtualBase, CharUnits NonVirtualOffset)
54 : DerivedClass(DerivedClass), VirtualBase(VirtualBase),
55 NonVirtualOffset(NonVirtualOffset) { }
56
57 bool isEmpty() const { return NonVirtualOffset.isZero() && !VirtualBase; }
58};
59
60/// FinalOverriders - Contains the final overrider member functions for all
61/// member functions in the base subobjects of a class.
62class FinalOverriders {
63public:
64 /// OverriderInfo - Information about a final overrider.
65 struct OverriderInfo {
66 /// Method - The method decl of the overrider.
67 const CXXMethodDecl *Method;
68
69 /// VirtualBase - The virtual base class subobject of this overrider.
70 /// Note that this records the closest derived virtual base class subobject.
72
73 /// Offset - the base offset of the overrider's parent in the layout class.
74 CharUnits Offset;
75
76 OverriderInfo() : Method(nullptr), VirtualBase(nullptr),
77 Offset(CharUnits::Zero()) { }
78 };
79
80private:
81 /// MostDerivedClass - The most derived class for which the final overriders
82 /// are stored.
83 const CXXRecordDecl *MostDerivedClass;
84
85 /// MostDerivedClassOffset - If we're building final overriders for a
86 /// construction vtable, this holds the offset from the layout class to the
87 /// most derived class.
88 const CharUnits MostDerivedClassOffset;
89
90 /// LayoutClass - The class we're using for layout information. Will be
91 /// different than the most derived class if the final overriders are for a
92 /// construction vtable.
93 const CXXRecordDecl *LayoutClass;
94
95 ASTContext &Context;
96
97 /// MostDerivedClassLayout - the AST record layout of the most derived class.
98 const ASTRecordLayout &MostDerivedClassLayout;
99
100 /// MethodBaseOffsetPairTy - Uniquely identifies a member function
101 /// in a base subobject.
102 typedef std::pair<const CXXMethodDecl *, CharUnits> MethodBaseOffsetPairTy;
103
104 typedef llvm::DenseMap<MethodBaseOffsetPairTy,
105 OverriderInfo> OverridersMapTy;
106
107 /// OverridersMap - The final overriders for all virtual member functions of
108 /// all the base subobjects of the most derived class.
109 OverridersMapTy OverridersMap;
110
111 /// SubobjectsToOffsetsMapTy - A mapping from a base subobject (represented
112 /// as a record decl and a subobject number) and its offsets in the most
113 /// derived class as well as the layout class.
114 typedef llvm::DenseMap<std::pair<const CXXRecordDecl *, unsigned>,
115 CharUnits> SubobjectOffsetMapTy;
116
117 typedef llvm::DenseMap<const CXXRecordDecl *, unsigned> SubobjectCountMapTy;
118
119 /// ComputeBaseOffsets - Compute the offsets for all base subobjects of the
120 /// given base.
121 void ComputeBaseOffsets(BaseSubobject Base, bool IsVirtual,
122 CharUnits OffsetInLayoutClass,
123 SubobjectOffsetMapTy &SubobjectOffsets,
124 SubobjectOffsetMapTy &SubobjectLayoutClassOffsets,
125 SubobjectCountMapTy &SubobjectCounts);
126
127 typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
128
129 /// dump - dump the final overriders for a base subobject, and all its direct
130 /// and indirect base subobjects.
131 void dump(raw_ostream &Out, BaseSubobject Base,
132 VisitedVirtualBasesSetTy& VisitedVirtualBases);
133
134public:
135 FinalOverriders(const CXXRecordDecl *MostDerivedClass,
136 CharUnits MostDerivedClassOffset,
137 const CXXRecordDecl *LayoutClass);
138
139 /// getOverrider - Get the final overrider for the given method declaration in
140 /// the subobject with the given base offset.
141 OverriderInfo getOverrider(const CXXMethodDecl *MD,
142 CharUnits BaseOffset) const {
143 assert(OverridersMap.count(std::make_pair(MD, BaseOffset)) &&
144 "Did not find overrider!");
145
146 return OverridersMap.lookup(std::make_pair(MD, BaseOffset));
147 }
148
149 /// dump - dump the final overriders.
150 void dump() {
151 VisitedVirtualBasesSetTy VisitedVirtualBases;
152 dump(llvm::errs(), BaseSubobject(MostDerivedClass, CharUnits::Zero()),
153 VisitedVirtualBases);
154 }
155
156};
157
158FinalOverriders::FinalOverriders(const CXXRecordDecl *MostDerivedClass,
159 CharUnits MostDerivedClassOffset,
160 const CXXRecordDecl *LayoutClass)
161 : MostDerivedClass(MostDerivedClass),
162 MostDerivedClassOffset(MostDerivedClassOffset), LayoutClass(LayoutClass),
163 Context(MostDerivedClass->getASTContext()),
164 MostDerivedClassLayout(Context.getASTRecordLayout(MostDerivedClass)) {
165
166 // Compute base offsets.
167 SubobjectOffsetMapTy SubobjectOffsets;
168 SubobjectOffsetMapTy SubobjectLayoutClassOffsets;
169 SubobjectCountMapTy SubobjectCounts;
170 ComputeBaseOffsets(BaseSubobject(MostDerivedClass, CharUnits::Zero()),
171 /*IsVirtual=*/false,
172 MostDerivedClassOffset,
173 SubobjectOffsets, SubobjectLayoutClassOffsets,
174 SubobjectCounts);
175
176 // Get the final overriders.
177 CXXFinalOverriderMap FinalOverriders;
178 MostDerivedClass->getFinalOverriders(FinalOverriders);
179
180 for (const auto &Overrider : FinalOverriders) {
181 const CXXMethodDecl *MD = Overrider.first;
182 const OverridingMethods &Methods = Overrider.second;
183
184 for (const auto &M : Methods) {
185 unsigned SubobjectNumber = M.first;
186 assert(SubobjectOffsets.count(std::make_pair(MD->getParent(),
187 SubobjectNumber)) &&
188 "Did not find subobject offset!");
189
190 CharUnits BaseOffset = SubobjectOffsets[std::make_pair(MD->getParent(),
191 SubobjectNumber)];
192
193 assert(M.second.size() == 1 && "Final overrider is not unique!");
194 const UniqueVirtualMethod &Method = M.second.front();
195
196 const CXXRecordDecl *OverriderRD = Method.Method->getParent();
197 assert(SubobjectLayoutClassOffsets.count(
198 std::make_pair(OverriderRD, Method.Subobject))
199 && "Did not find subobject offset!");
200 CharUnits OverriderOffset =
201 SubobjectLayoutClassOffsets[std::make_pair(OverriderRD,
202 Method.Subobject)];
203
204 OverriderInfo& Overrider = OverridersMap[std::make_pair(MD, BaseOffset)];
205 assert(!Overrider.Method && "Overrider should not exist yet!");
206
207 Overrider.Offset = OverriderOffset;
208 Overrider.Method = Method.Method;
209 Overrider.VirtualBase = Method.InVirtualSubobject;
210 }
211 }
212
213#if DUMP_OVERRIDERS
214 // And dump them (for now).
215 dump();
216#endif
217}
218
219static BaseOffset ComputeBaseOffset(const ASTContext &Context,
220 const CXXRecordDecl *DerivedRD,
221 const CXXBasePath &Path) {
222 CharUnits NonVirtualOffset = CharUnits::Zero();
223
224 unsigned NonVirtualStart = 0;
225 const CXXRecordDecl *VirtualBase = nullptr;
226
227 // First, look for the virtual base class.
228 for (int I = Path.size(), E = 0; I != E; --I) {
229 const CXXBasePathElement &Element = Path[I - 1];
230
231 if (Element.Base->isVirtual()) {
232 NonVirtualStart = I;
233 QualType VBaseType = Element.Base->getType();
234 VirtualBase = VBaseType->getAsCXXRecordDecl();
235 break;
236 }
237 }
238
239 // Now compute the non-virtual offset.
240 for (unsigned I = NonVirtualStart, E = Path.size(); I != E; ++I) {
241 const CXXBasePathElement &Element = Path[I];
242
243 // Check the base class offset.
244 const ASTRecordLayout &Layout = Context.getASTRecordLayout(Element.Class);
245
246 const CXXRecordDecl *Base = Element.Base->getType()->getAsCXXRecordDecl();
247
248 NonVirtualOffset += Layout.getBaseClassOffset(Base);
249 }
250
251 // FIXME: This should probably use CharUnits or something. Maybe we should
252 // even change the base offsets in ASTRecordLayout to be specified in
253 // CharUnits.
254 return BaseOffset(DerivedRD, VirtualBase, NonVirtualOffset);
255
256}
257
258static BaseOffset ComputeBaseOffset(const ASTContext &Context,
259 const CXXRecordDecl *BaseRD,
260 const CXXRecordDecl *DerivedRD) {
261 CXXBasePaths Paths(/*FindAmbiguities=*/false,
262 /*RecordPaths=*/true, /*DetectVirtual=*/false);
263
264 if (!DerivedRD->isDerivedFrom(BaseRD, Paths))
265 llvm_unreachable("Class must be derived from the passed in base class!");
266
267 return ComputeBaseOffset(Context, DerivedRD, Paths.front());
268}
269
270static BaseOffset
271ComputeReturnAdjustmentBaseOffset(ASTContext &Context,
272 const CXXMethodDecl *DerivedMD,
273 const CXXMethodDecl *BaseMD) {
274 const auto *BaseFT = BaseMD->getType()->castAs<FunctionType>();
275 const auto *DerivedFT = DerivedMD->getType()->castAs<FunctionType>();
276
277 // Canonicalize the return types.
278 CanQualType CanDerivedReturnType =
279 Context.getCanonicalType(DerivedFT->getReturnType());
280 CanQualType CanBaseReturnType =
281 Context.getCanonicalType(BaseFT->getReturnType());
282
283 assert(CanDerivedReturnType->getTypeClass() ==
284 CanBaseReturnType->getTypeClass() &&
285 "Types must have same type class!");
286
287 if (CanDerivedReturnType == CanBaseReturnType) {
288 // No adjustment needed.
289 return BaseOffset();
290 }
291
292 if (isa<ReferenceType>(CanDerivedReturnType)) {
293 CanDerivedReturnType =
294 CanDerivedReturnType->getAs<ReferenceType>()->getPointeeType();
295 CanBaseReturnType =
296 CanBaseReturnType->getAs<ReferenceType>()->getPointeeType();
297 } else if (isa<PointerType>(CanDerivedReturnType)) {
298 CanDerivedReturnType =
299 CanDerivedReturnType->getAs<PointerType>()->getPointeeType();
300 CanBaseReturnType =
301 CanBaseReturnType->getAs<PointerType>()->getPointeeType();
302 } else {
303 llvm_unreachable("Unexpected return type!");
304 }
305
306 // We need to compare unqualified types here; consider
307 // const T *Base::foo();
308 // T *Derived::foo();
309 if (CanDerivedReturnType.getUnqualifiedType() ==
310 CanBaseReturnType.getUnqualifiedType()) {
311 // No adjustment needed.
312 return BaseOffset();
313 }
314
315 const CXXRecordDecl *DerivedRD =
316 cast<CXXRecordDecl>(cast<RecordType>(CanDerivedReturnType)->getDecl());
317
318 const CXXRecordDecl *BaseRD =
319 cast<CXXRecordDecl>(cast<RecordType>(CanBaseReturnType)->getDecl());
320
321 return ComputeBaseOffset(Context, BaseRD, DerivedRD);
322}
323
324void
325FinalOverriders::ComputeBaseOffsets(BaseSubobject Base, bool IsVirtual,
326 CharUnits OffsetInLayoutClass,
327 SubobjectOffsetMapTy &SubobjectOffsets,
328 SubobjectOffsetMapTy &SubobjectLayoutClassOffsets,
329 SubobjectCountMapTy &SubobjectCounts) {
330 const CXXRecordDecl *RD = Base.getBase();
331
332 unsigned SubobjectNumber = 0;
333 if (!IsVirtual)
334 SubobjectNumber = ++SubobjectCounts[RD];
335
336 // Set up the subobject to offset mapping.
337 assert(!SubobjectOffsets.count(std::make_pair(RD, SubobjectNumber))
338 && "Subobject offset already exists!");
339 assert(!SubobjectLayoutClassOffsets.count(std::make_pair(RD, SubobjectNumber))
340 && "Subobject offset already exists!");
341
342 SubobjectOffsets[std::make_pair(RD, SubobjectNumber)] = Base.getBaseOffset();
343 SubobjectLayoutClassOffsets[std::make_pair(RD, SubobjectNumber)] =
344 OffsetInLayoutClass;
345
346 // Traverse our bases.
347 for (const auto &B : RD->bases()) {
348 const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl();
349
350 CharUnits BaseOffset;
351 CharUnits BaseOffsetInLayoutClass;
352 if (B.isVirtual()) {
353 // Check if we've visited this virtual base before.
354 if (SubobjectOffsets.count(std::make_pair(BaseDecl, 0)))
355 continue;
356
357 const ASTRecordLayout &LayoutClassLayout =
358 Context.getASTRecordLayout(LayoutClass);
359
360 BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
361 BaseOffsetInLayoutClass =
362 LayoutClassLayout.getVBaseClassOffset(BaseDecl);
363 } else {
364 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
365 CharUnits Offset = Layout.getBaseClassOffset(BaseDecl);
366
367 BaseOffset = Base.getBaseOffset() + Offset;
368 BaseOffsetInLayoutClass = OffsetInLayoutClass + Offset;
369 }
370
371 ComputeBaseOffsets(BaseSubobject(BaseDecl, BaseOffset),
372 B.isVirtual(), BaseOffsetInLayoutClass,
373 SubobjectOffsets, SubobjectLayoutClassOffsets,
374 SubobjectCounts);
375 }
376}
377
378void FinalOverriders::dump(raw_ostream &Out, BaseSubobject Base,
379 VisitedVirtualBasesSetTy &VisitedVirtualBases) {
380 const CXXRecordDecl *RD = Base.getBase();
381 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
382
383 for (const auto &B : RD->bases()) {
384 const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl();
385
386 // Ignore bases that don't have any virtual member functions.
387 if (!BaseDecl->isPolymorphic())
388 continue;
389
390 CharUnits BaseOffset;
391 if (B.isVirtual()) {
392 if (!VisitedVirtualBases.insert(BaseDecl).second) {
393 // We've visited this base before.
394 continue;
395 }
396
397 BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
398 } else {
399 BaseOffset = Layout.getBaseClassOffset(BaseDecl) + Base.getBaseOffset();
400 }
401
402 dump(Out, BaseSubobject(BaseDecl, BaseOffset), VisitedVirtualBases);
403 }
404
405 Out << "Final overriders for (";
406 RD->printQualifiedName(Out);
407 Out << ", ";
408 Out << Base.getBaseOffset().getQuantity() << ")\n";
409
410 // Now dump the overriders for this base subobject.
411 for (const auto *MD : RD->methods()) {
413 continue;
414 MD = MD->getCanonicalDecl();
415
416 OverriderInfo Overrider = getOverrider(MD, Base.getBaseOffset());
417
418 Out << " ";
419 MD->printQualifiedName(Out);
420 Out << " - (";
421 Overrider.Method->printQualifiedName(Out);
422 Out << ", " << Overrider.Offset.getQuantity() << ')';
423
424 BaseOffset Offset;
425 if (!Overrider.Method->isPureVirtual())
426 Offset = ComputeReturnAdjustmentBaseOffset(Context, Overrider.Method, MD);
427
428 if (!Offset.isEmpty()) {
429 Out << " [ret-adj: ";
430 if (Offset.VirtualBase) {
431 Offset.VirtualBase->printQualifiedName(Out);
432 Out << " vbase, ";
433 }
434
435 Out << Offset.NonVirtualOffset.getQuantity() << " nv]";
436 }
437
438 Out << "\n";
439 }
440}
441
442/// VCallOffsetMap - Keeps track of vcall offsets when building a vtable.
443struct VCallOffsetMap {
444
445 typedef std::pair<const CXXMethodDecl *, CharUnits> MethodAndOffsetPairTy;
446
447 /// Offsets - Keeps track of methods and their offsets.
448 // FIXME: This should be a real map and not a vector.
450
451 /// MethodsCanShareVCallOffset - Returns whether two virtual member functions
452 /// can share the same vcall offset.
453 static bool MethodsCanShareVCallOffset(const CXXMethodDecl *LHS,
454 const CXXMethodDecl *RHS);
455
456public:
457 /// AddVCallOffset - Adds a vcall offset to the map. Returns true if the
458 /// add was successful, or false if there was already a member function with
459 /// the same signature in the map.
460 bool AddVCallOffset(const CXXMethodDecl *MD, CharUnits OffsetOffset);
461
462 /// getVCallOffsetOffset - Returns the vcall offset offset (relative to the
463 /// vtable address point) for the given virtual member function.
464 CharUnits getVCallOffsetOffset(const CXXMethodDecl *MD);
465
466 // empty - Return whether the offset map is empty or not.
467 bool empty() const { return Offsets.empty(); }
468};
469
470static bool HasSameVirtualSignature(const CXXMethodDecl *LHS,
471 const CXXMethodDecl *RHS) {
472 const FunctionProtoType *LT =
473 cast<FunctionProtoType>(LHS->getType().getCanonicalType());
474 const FunctionProtoType *RT =
475 cast<FunctionProtoType>(RHS->getType().getCanonicalType());
476
477 // Fast-path matches in the canonical types.
478 if (LT == RT) return true;
479
480 // Force the signatures to match. We can't rely on the overrides
481 // list here because there isn't necessarily an inheritance
482 // relationship between the two methods.
483 if (LT->getMethodQuals() != RT->getMethodQuals())
484 return false;
485 return LT->getParamTypes() == RT->getParamTypes();
486}
487
488bool VCallOffsetMap::MethodsCanShareVCallOffset(const CXXMethodDecl *LHS,
489 const CXXMethodDecl *RHS) {
490 assert(VTableContextBase::hasVtableSlot(LHS) && "LHS must be virtual!");
491 assert(VTableContextBase::hasVtableSlot(RHS) && "RHS must be virtual!");
492
493 // A destructor can share a vcall offset with another destructor.
494 if (isa<CXXDestructorDecl>(LHS))
495 return isa<CXXDestructorDecl>(RHS);
496
497 // FIXME: We need to check more things here.
498
499 // The methods must have the same name.
500 DeclarationName LHSName = LHS->getDeclName();
501 DeclarationName RHSName = RHS->getDeclName();
502 if (LHSName != RHSName)
503 return false;
504
505 // And the same signatures.
506 return HasSameVirtualSignature(LHS, RHS);
507}
508
509bool VCallOffsetMap::AddVCallOffset(const CXXMethodDecl *MD,
510 CharUnits OffsetOffset) {
511 // Check if we can reuse an offset.
512 for (const auto &OffsetPair : Offsets) {
513 if (MethodsCanShareVCallOffset(OffsetPair.first, MD))
514 return false;
515 }
516
517 // Add the offset.
518 Offsets.push_back(MethodAndOffsetPairTy(MD, OffsetOffset));
519 return true;
520}
521
522CharUnits VCallOffsetMap::getVCallOffsetOffset(const CXXMethodDecl *MD) {
523 // Look for an offset.
524 for (const auto &OffsetPair : Offsets) {
525 if (MethodsCanShareVCallOffset(OffsetPair.first, MD))
526 return OffsetPair.second;
527 }
528
529 llvm_unreachable("Should always find a vcall offset offset!");
530}
531
532/// VCallAndVBaseOffsetBuilder - Class for building vcall and vbase offsets.
533class VCallAndVBaseOffsetBuilder {
534public:
535 typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits>
536 VBaseOffsetOffsetsMapTy;
537
538private:
539 const ItaniumVTableContext &VTables;
540
541 /// MostDerivedClass - The most derived class for which we're building vcall
542 /// and vbase offsets.
543 const CXXRecordDecl *MostDerivedClass;
544
545 /// LayoutClass - The class we're using for layout information. Will be
546 /// different than the most derived class if we're building a construction
547 /// vtable.
548 const CXXRecordDecl *LayoutClass;
549
550 /// Context - The ASTContext which we will use for layout information.
551 ASTContext &Context;
552
553 /// Components - vcall and vbase offset components
554 typedef SmallVector<VTableComponent, 64> VTableComponentVectorTy;
555 VTableComponentVectorTy Components;
556
557 /// VisitedVirtualBases - Visited virtual bases.
559
560 /// VCallOffsets - Keeps track of vcall offsets.
561 VCallOffsetMap VCallOffsets;
562
563
564 /// VBaseOffsetOffsets - Contains the offsets of the virtual base offsets,
565 /// relative to the address point.
566 VBaseOffsetOffsetsMapTy VBaseOffsetOffsets;
567
568 /// FinalOverriders - The final overriders of the most derived class.
569 /// (Can be null when we're not building a vtable of the most derived class).
570 const FinalOverriders *Overriders;
571
572 /// AddVCallAndVBaseOffsets - Add vcall offsets and vbase offsets for the
573 /// given base subobject.
574 void AddVCallAndVBaseOffsets(BaseSubobject Base, bool BaseIsVirtual,
575 CharUnits RealBaseOffset);
576
577 /// AddVCallOffsets - Add vcall offsets for the given base subobject.
578 void AddVCallOffsets(BaseSubobject Base, CharUnits VBaseOffset);
579
580 /// AddVBaseOffsets - Add vbase offsets for the given class.
581 void AddVBaseOffsets(const CXXRecordDecl *Base,
582 CharUnits OffsetInLayoutClass);
583
584 /// getCurrentOffsetOffset - Get the current vcall or vbase offset offset in
585 /// chars, relative to the vtable address point.
586 CharUnits getCurrentOffsetOffset() const;
587
588public:
589 VCallAndVBaseOffsetBuilder(const ItaniumVTableContext &VTables,
590 const CXXRecordDecl *MostDerivedClass,
591 const CXXRecordDecl *LayoutClass,
592 const FinalOverriders *Overriders,
593 BaseSubobject Base, bool BaseIsVirtual,
594 CharUnits OffsetInLayoutClass)
595 : VTables(VTables), MostDerivedClass(MostDerivedClass),
596 LayoutClass(LayoutClass), Context(MostDerivedClass->getASTContext()),
597 Overriders(Overriders) {
598
599 // Add vcall and vbase offsets.
600 AddVCallAndVBaseOffsets(Base, BaseIsVirtual, OffsetInLayoutClass);
601 }
602
603 /// Methods for iterating over the components.
604 typedef VTableComponentVectorTy::const_reverse_iterator const_iterator;
605 const_iterator components_begin() const { return Components.rbegin(); }
606 const_iterator components_end() const { return Components.rend(); }
607
608 const VCallOffsetMap &getVCallOffsets() const { return VCallOffsets; }
609 const VBaseOffsetOffsetsMapTy &getVBaseOffsetOffsets() const {
610 return VBaseOffsetOffsets;
611 }
612};
613
614void
615VCallAndVBaseOffsetBuilder::AddVCallAndVBaseOffsets(BaseSubobject Base,
616 bool BaseIsVirtual,
617 CharUnits RealBaseOffset) {
618 const ASTRecordLayout &Layout = Context.getASTRecordLayout(Base.getBase());
619
620 // Itanium C++ ABI 2.5.2:
621 // ..in classes sharing a virtual table with a primary base class, the vcall
622 // and vbase offsets added by the derived class all come before the vcall
623 // and vbase offsets required by the base class, so that the latter may be
624 // laid out as required by the base class without regard to additions from
625 // the derived class(es).
626
627 // (Since we're emitting the vcall and vbase offsets in reverse order, we'll
628 // emit them for the primary base first).
629 if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) {
630 bool PrimaryBaseIsVirtual = Layout.isPrimaryBaseVirtual();
631
632 CharUnits PrimaryBaseOffset;
633
634 // Get the base offset of the primary base.
635 if (PrimaryBaseIsVirtual) {
636 assert(Layout.getVBaseClassOffset(PrimaryBase).isZero() &&
637 "Primary vbase should have a zero offset!");
638
639 const ASTRecordLayout &MostDerivedClassLayout =
640 Context.getASTRecordLayout(MostDerivedClass);
641
642 PrimaryBaseOffset =
643 MostDerivedClassLayout.getVBaseClassOffset(PrimaryBase);
644 } else {
645 assert(Layout.getBaseClassOffset(PrimaryBase).isZero() &&
646 "Primary base should have a zero offset!");
647
648 PrimaryBaseOffset = Base.getBaseOffset();
649 }
650
651 AddVCallAndVBaseOffsets(
652 BaseSubobject(PrimaryBase,PrimaryBaseOffset),
653 PrimaryBaseIsVirtual, RealBaseOffset);
654 }
655
656 AddVBaseOffsets(Base.getBase(), RealBaseOffset);
657
658 // We only want to add vcall offsets for virtual bases.
659 if (BaseIsVirtual)
660 AddVCallOffsets(Base, RealBaseOffset);
661}
662
663CharUnits VCallAndVBaseOffsetBuilder::getCurrentOffsetOffset() const {
664 // OffsetIndex is the index of this vcall or vbase offset, relative to the
665 // vtable address point. (We subtract 3 to account for the information just
666 // above the address point, the RTTI info, the offset to top, and the
667 // vcall offset itself).
668 size_t NumComponentsAboveAddrPoint = 3;
669 if (Context.getLangOpts().OmitVTableRTTI)
670 NumComponentsAboveAddrPoint--;
671 int64_t OffsetIndex =
672 -(int64_t)(NumComponentsAboveAddrPoint + Components.size());
673
674 // Under the relative ABI, the offset widths are 32-bit ints instead of
675 // pointer widths.
676 CharUnits OffsetWidth = Context.toCharUnitsFromBits(
677 VTables.isRelativeLayout()
678 ? 32
679 : Context.getTargetInfo().getPointerWidth(LangAS::Default));
680 CharUnits OffsetOffset = OffsetWidth * OffsetIndex;
681
682 return OffsetOffset;
683}
684
685void VCallAndVBaseOffsetBuilder::AddVCallOffsets(BaseSubobject Base,
686 CharUnits VBaseOffset) {
687 const CXXRecordDecl *RD = Base.getBase();
688 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
689
690 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
691
692 // Handle the primary base first.
693 // We only want to add vcall offsets if the base is non-virtual; a virtual
694 // primary base will have its vcall and vbase offsets emitted already.
695 if (PrimaryBase && !Layout.isPrimaryBaseVirtual()) {
696 // Get the base offset of the primary base.
697 assert(Layout.getBaseClassOffset(PrimaryBase).isZero() &&
698 "Primary base should have a zero offset!");
699
700 AddVCallOffsets(BaseSubobject(PrimaryBase, Base.getBaseOffset()),
701 VBaseOffset);
702 }
703
704 // Add the vcall offsets.
705 for (const auto *MD : RD->methods()) {
707 continue;
708 MD = MD->getCanonicalDecl();
709
710 CharUnits OffsetOffset = getCurrentOffsetOffset();
711
712 // Don't add a vcall offset if we already have one for this member function
713 // signature.
714 if (!VCallOffsets.AddVCallOffset(MD, OffsetOffset))
715 continue;
716
717 CharUnits Offset = CharUnits::Zero();
718
719 if (Overriders) {
720 // Get the final overrider.
721 FinalOverriders::OverriderInfo Overrider =
722 Overriders->getOverrider(MD, Base.getBaseOffset());
723
724 /// The vcall offset is the offset from the virtual base to the object
725 /// where the function was overridden.
726 Offset = Overrider.Offset - VBaseOffset;
727 }
728
729 Components.push_back(
731 }
732
733 // And iterate over all non-virtual bases (ignoring the primary base).
734 for (const auto &B : RD->bases()) {
735 if (B.isVirtual())
736 continue;
737
738 const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl();
739 if (BaseDecl == PrimaryBase)
740 continue;
741
742 // Get the base offset of this base.
743 CharUnits BaseOffset = Base.getBaseOffset() +
744 Layout.getBaseClassOffset(BaseDecl);
745
746 AddVCallOffsets(BaseSubobject(BaseDecl, BaseOffset),
747 VBaseOffset);
748 }
749}
750
751void
752VCallAndVBaseOffsetBuilder::AddVBaseOffsets(const CXXRecordDecl *RD,
753 CharUnits OffsetInLayoutClass) {
754 const ASTRecordLayout &LayoutClassLayout =
755 Context.getASTRecordLayout(LayoutClass);
756
757 // Add vbase offsets.
758 for (const auto &B : RD->bases()) {
759 const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl();
760
761 // Check if this is a virtual base that we haven't visited before.
762 if (B.isVirtual() && VisitedVirtualBases.insert(BaseDecl).second) {
763 CharUnits Offset =
764 LayoutClassLayout.getVBaseClassOffset(BaseDecl) - OffsetInLayoutClass;
765
766 // Add the vbase offset offset.
767 assert(!VBaseOffsetOffsets.count(BaseDecl) &&
768 "vbase offset offset already exists!");
769
770 CharUnits VBaseOffsetOffset = getCurrentOffsetOffset();
771 VBaseOffsetOffsets.insert(
772 std::make_pair(BaseDecl, VBaseOffsetOffset));
773
774 Components.push_back(
776 }
777
778 // Check the base class looking for more vbase offsets.
779 AddVBaseOffsets(BaseDecl, OffsetInLayoutClass);
780 }
781}
782
783/// ItaniumVTableBuilder - Class for building vtable layout information.
784class ItaniumVTableBuilder {
785public:
786 /// PrimaryBasesSetVectorTy - A set vector of direct and indirect
787 /// primary bases.
789 PrimaryBasesSetVectorTy;
790
791 typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits>
792 VBaseOffsetOffsetsMapTy;
793
794 typedef VTableLayout::AddressPointsMapTy AddressPointsMapTy;
795
796 typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVTableIndicesTy;
797
798private:
799 /// VTables - Global vtable information.
800 ItaniumVTableContext &VTables;
801
802 /// MostDerivedClass - The most derived class for which we're building this
803 /// vtable.
804 const CXXRecordDecl *MostDerivedClass;
805
806 /// MostDerivedClassOffset - If we're building a construction vtable, this
807 /// holds the offset from the layout class to the most derived class.
808 const CharUnits MostDerivedClassOffset;
809
810 /// MostDerivedClassIsVirtual - Whether the most derived class is a virtual
811 /// base. (This only makes sense when building a construction vtable).
812 bool MostDerivedClassIsVirtual;
813
814 /// LayoutClass - The class we're using for layout information. Will be
815 /// different than the most derived class if we're building a construction
816 /// vtable.
817 const CXXRecordDecl *LayoutClass;
818
819 /// Context - The ASTContext which we will use for layout information.
820 ASTContext &Context;
821
822 /// FinalOverriders - The final overriders of the most derived class.
823 const FinalOverriders Overriders;
824
825 /// VCallOffsetsForVBases - Keeps track of vcall offsets for the virtual
826 /// bases in this vtable.
827 llvm::DenseMap<const CXXRecordDecl *, VCallOffsetMap> VCallOffsetsForVBases;
828
829 /// VBaseOffsetOffsets - Contains the offsets of the virtual base offsets for
830 /// the most derived class.
831 VBaseOffsetOffsetsMapTy VBaseOffsetOffsets;
832
833 /// Components - The components of the vtable being built.
835
836 /// AddressPoints - Address points for the vtable being built.
837 AddressPointsMapTy AddressPoints;
838
839 /// MethodInfo - Contains information about a method in a vtable.
840 /// (Used for computing 'this' pointer adjustment thunks.
841 struct MethodInfo {
842 /// BaseOffset - The base offset of this method.
843 const CharUnits BaseOffset;
844
845 /// BaseOffsetInLayoutClass - The base offset in the layout class of this
846 /// method.
847 const CharUnits BaseOffsetInLayoutClass;
848
849 /// VTableIndex - The index in the vtable that this method has.
850 /// (For destructors, this is the index of the complete destructor).
851 const uint64_t VTableIndex;
852
853 MethodInfo(CharUnits BaseOffset, CharUnits BaseOffsetInLayoutClass,
854 uint64_t VTableIndex)
855 : BaseOffset(BaseOffset),
856 BaseOffsetInLayoutClass(BaseOffsetInLayoutClass),
857 VTableIndex(VTableIndex) { }
858
859 MethodInfo()
860 : BaseOffset(CharUnits::Zero()),
861 BaseOffsetInLayoutClass(CharUnits::Zero()),
862 VTableIndex(0) { }
863
864 MethodInfo(MethodInfo const&) = default;
865 };
866
867 typedef llvm::DenseMap<const CXXMethodDecl *, MethodInfo> MethodInfoMapTy;
868
869 /// MethodInfoMap - The information for all methods in the vtable we're
870 /// currently building.
871 MethodInfoMapTy MethodInfoMap;
872
873 /// MethodVTableIndices - Contains the index (relative to the vtable address
874 /// point) where the function pointer for a virtual function is stored.
875 MethodVTableIndicesTy MethodVTableIndices;
876
877 typedef llvm::DenseMap<uint64_t, ThunkInfo> VTableThunksMapTy;
878
879 /// VTableThunks - The thunks by vtable index in the vtable currently being
880 /// built.
881 VTableThunksMapTy VTableThunks;
882
883 typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy;
884 typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy;
885
886 /// Thunks - A map that contains all the thunks needed for all methods in the
887 /// most derived class for which the vtable is currently being built.
888 ThunksMapTy Thunks;
889
890 /// AddThunk - Add a thunk for the given method.
891 void AddThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk);
892
893 /// ComputeThisAdjustments - Compute the 'this' pointer adjustments for the
894 /// part of the vtable we're currently building.
895 void ComputeThisAdjustments();
896
897 typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
898
899 /// PrimaryVirtualBases - All known virtual bases who are a primary base of
900 /// some other base.
901 VisitedVirtualBasesSetTy PrimaryVirtualBases;
902
903 /// ComputeReturnAdjustment - Compute the return adjustment given a return
904 /// adjustment base offset.
905 ReturnAdjustment ComputeReturnAdjustment(BaseOffset Offset);
906
907 /// ComputeThisAdjustmentBaseOffset - Compute the base offset for adjusting
908 /// the 'this' pointer from the base subobject to the derived subobject.
909 BaseOffset ComputeThisAdjustmentBaseOffset(BaseSubobject Base,
910 BaseSubobject Derived) const;
911
912 /// ComputeThisAdjustment - Compute the 'this' pointer adjustment for the
913 /// given virtual member function, its offset in the layout class and its
914 /// final overrider.
916 ComputeThisAdjustment(const CXXMethodDecl *MD,
917 CharUnits BaseOffsetInLayoutClass,
918 FinalOverriders::OverriderInfo Overrider);
919
920 /// AddMethod - Add a single virtual member function to the vtable
921 /// components vector.
922 void AddMethod(const CXXMethodDecl *MD, ReturnAdjustment ReturnAdjustment);
923
924 /// IsOverriderUsed - Returns whether the overrider will ever be used in this
925 /// part of the vtable.
926 ///
927 /// Itanium C++ ABI 2.5.2:
928 ///
929 /// struct A { virtual void f(); };
930 /// struct B : virtual public A { int i; };
931 /// struct C : virtual public A { int j; };
932 /// struct D : public B, public C {};
933 ///
934 /// When B and C are declared, A is a primary base in each case, so although
935 /// vcall offsets are allocated in the A-in-B and A-in-C vtables, no this
936 /// adjustment is required and no thunk is generated. However, inside D
937 /// objects, A is no longer a primary base of C, so if we allowed calls to
938 /// C::f() to use the copy of A's vtable in the C subobject, we would need
939 /// to adjust this from C* to B::A*, which would require a third-party
940 /// thunk. Since we require that a call to C::f() first convert to A*,
941 /// C-in-D's copy of A's vtable is never referenced, so this is not
942 /// necessary.
943 bool IsOverriderUsed(const CXXMethodDecl *Overrider,
944 CharUnits BaseOffsetInLayoutClass,
945 const CXXRecordDecl *FirstBaseInPrimaryBaseChain,
946 CharUnits FirstBaseOffsetInLayoutClass) const;
947
948
949 /// AddMethods - Add the methods of this base subobject and all its
950 /// primary bases to the vtable components vector.
951 void AddMethods(BaseSubobject Base, CharUnits BaseOffsetInLayoutClass,
952 const CXXRecordDecl *FirstBaseInPrimaryBaseChain,
953 CharUnits FirstBaseOffsetInLayoutClass,
954 PrimaryBasesSetVectorTy &PrimaryBases);
955
956 // LayoutVTable - Layout the vtable for the given base class, including its
957 // secondary vtables and any vtables for virtual bases.
958 void LayoutVTable();
959
960 /// LayoutPrimaryAndSecondaryVTables - Layout the primary vtable for the
961 /// given base subobject, as well as all its secondary vtables.
962 ///
963 /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
964 /// or a direct or indirect base of a virtual base.
965 ///
966 /// \param BaseIsVirtualInLayoutClass - Whether the base subobject is virtual
967 /// in the layout class.
968 void LayoutPrimaryAndSecondaryVTables(BaseSubobject Base,
969 bool BaseIsMorallyVirtual,
970 bool BaseIsVirtualInLayoutClass,
971 CharUnits OffsetInLayoutClass);
972
973 /// LayoutSecondaryVTables - Layout the secondary vtables for the given base
974 /// subobject.
975 ///
976 /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
977 /// or a direct or indirect base of a virtual base.
978 void LayoutSecondaryVTables(BaseSubobject Base, bool BaseIsMorallyVirtual,
979 CharUnits OffsetInLayoutClass);
980
981 /// DeterminePrimaryVirtualBases - Determine the primary virtual bases in this
982 /// class hierarchy.
983 void DeterminePrimaryVirtualBases(const CXXRecordDecl *RD,
984 CharUnits OffsetInLayoutClass,
985 VisitedVirtualBasesSetTy &VBases);
986
987 /// LayoutVTablesForVirtualBases - Layout vtables for all virtual bases of the
988 /// given base (excluding any primary bases).
989 void LayoutVTablesForVirtualBases(const CXXRecordDecl *RD,
990 VisitedVirtualBasesSetTy &VBases);
991
992 /// isBuildingConstructionVTable - Return whether this vtable builder is
993 /// building a construction vtable.
994 bool isBuildingConstructorVTable() const {
995 return MostDerivedClass != LayoutClass;
996 }
997
998public:
999 /// Component indices of the first component of each of the vtables in the
1000 /// vtable group.
1001 SmallVector<size_t, 4> VTableIndices;
1002
1003 ItaniumVTableBuilder(ItaniumVTableContext &VTables,
1004 const CXXRecordDecl *MostDerivedClass,
1005 CharUnits MostDerivedClassOffset,
1006 bool MostDerivedClassIsVirtual,
1007 const CXXRecordDecl *LayoutClass)
1008 : VTables(VTables), MostDerivedClass(MostDerivedClass),
1009 MostDerivedClassOffset(MostDerivedClassOffset),
1010 MostDerivedClassIsVirtual(MostDerivedClassIsVirtual),
1011 LayoutClass(LayoutClass), Context(MostDerivedClass->getASTContext()),
1012 Overriders(MostDerivedClass, MostDerivedClassOffset, LayoutClass) {
1013 assert(!Context.getTargetInfo().getCXXABI().isMicrosoft());
1014
1015 LayoutVTable();
1016
1017 if (Context.getLangOpts().DumpVTableLayouts)
1018 dumpLayout(llvm::outs());
1019 }
1020
1021 uint64_t getNumThunks() const {
1022 return Thunks.size();
1023 }
1024
1025 ThunksMapTy::const_iterator thunks_begin() const {
1026 return Thunks.begin();
1027 }
1028
1029 ThunksMapTy::const_iterator thunks_end() const {
1030 return Thunks.end();
1031 }
1032
1033 const VBaseOffsetOffsetsMapTy &getVBaseOffsetOffsets() const {
1034 return VBaseOffsetOffsets;
1035 }
1036
1037 const AddressPointsMapTy &getAddressPoints() const {
1038 return AddressPoints;
1039 }
1040
1041 MethodVTableIndicesTy::const_iterator vtable_indices_begin() const {
1042 return MethodVTableIndices.begin();
1043 }
1044
1045 MethodVTableIndicesTy::const_iterator vtable_indices_end() const {
1046 return MethodVTableIndices.end();
1047 }
1048
1049 ArrayRef<VTableComponent> vtable_components() const { return Components; }
1050
1051 AddressPointsMapTy::const_iterator address_points_begin() const {
1052 return AddressPoints.begin();
1053 }
1054
1055 AddressPointsMapTy::const_iterator address_points_end() const {
1056 return AddressPoints.end();
1057 }
1058
1059 VTableThunksMapTy::const_iterator vtable_thunks_begin() const {
1060 return VTableThunks.begin();
1061 }
1062
1063 VTableThunksMapTy::const_iterator vtable_thunks_end() const {
1064 return VTableThunks.end();
1065 }
1066
1067 /// dumpLayout - Dump the vtable layout.
1068 void dumpLayout(raw_ostream&);
1069};
1070
1071void ItaniumVTableBuilder::AddThunk(const CXXMethodDecl *MD,
1072 const ThunkInfo &Thunk) {
1073 assert(!isBuildingConstructorVTable() &&
1074 "Can't add thunks for construction vtable");
1075
1076 SmallVectorImpl<ThunkInfo> &ThunksVector = Thunks[MD];
1077
1078 // Check if we have this thunk already.
1079 if (llvm::is_contained(ThunksVector, Thunk))
1080 return;
1081
1082 ThunksVector.push_back(Thunk);
1083}
1084
1085typedef llvm::SmallPtrSet<const CXXMethodDecl *, 8> OverriddenMethodsSetTy;
1086
1087/// Visit all the methods overridden by the given method recursively,
1088/// in a depth-first pre-order. The Visitor's visitor method returns a bool
1089/// indicating whether to continue the recursion for the given overridden
1090/// method (i.e. returning false stops the iteration).
1091template <class VisitorTy>
1092static void
1093visitAllOverriddenMethods(const CXXMethodDecl *MD, VisitorTy &Visitor) {
1094 assert(VTableContextBase::hasVtableSlot(MD) && "Method is not virtual!");
1095
1096 for (const CXXMethodDecl *OverriddenMD : MD->overridden_methods()) {
1097 if (!Visitor(OverriddenMD))
1098 continue;
1099 visitAllOverriddenMethods(OverriddenMD, Visitor);
1100 }
1101}
1102
1103/// ComputeAllOverriddenMethods - Given a method decl, will return a set of all
1104/// the overridden methods that the function decl overrides.
1105static void
1106ComputeAllOverriddenMethods(const CXXMethodDecl *MD,
1107 OverriddenMethodsSetTy& OverriddenMethods) {
1108 auto OverriddenMethodsCollector = [&](const CXXMethodDecl *MD) {
1109 // Don't recurse on this method if we've already collected it.
1110 return OverriddenMethods.insert(MD).second;
1111 };
1112 visitAllOverriddenMethods(MD, OverriddenMethodsCollector);
1113}
1114
1115void ItaniumVTableBuilder::ComputeThisAdjustments() {
1116 // Now go through the method info map and see if any of the methods need
1117 // 'this' pointer adjustments.
1118 for (const auto &MI : MethodInfoMap) {
1119 const CXXMethodDecl *MD = MI.first;
1120 const MethodInfo &MethodInfo = MI.second;
1121
1122 // Ignore adjustments for unused function pointers.
1123 uint64_t VTableIndex = MethodInfo.VTableIndex;
1124 if (Components[VTableIndex].getKind() ==
1126 continue;
1127
1128 // Get the final overrider for this method.
1129 FinalOverriders::OverriderInfo Overrider =
1130 Overriders.getOverrider(MD, MethodInfo.BaseOffset);
1131
1132 // Check if we need an adjustment at all.
1133 if (MethodInfo.BaseOffsetInLayoutClass == Overrider.Offset) {
1134 // When a return thunk is needed by a derived class that overrides a
1135 // virtual base, gcc uses a virtual 'this' adjustment as well.
1136 // While the thunk itself might be needed by vtables in subclasses or
1137 // in construction vtables, there doesn't seem to be a reason for using
1138 // the thunk in this vtable. Still, we do so to match gcc.
1139 if (VTableThunks.lookup(VTableIndex).Return.isEmpty())
1140 continue;
1141 }
1142
1144 ComputeThisAdjustment(MD, MethodInfo.BaseOffsetInLayoutClass, Overrider);
1145
1146 if (ThisAdjustment.isEmpty())
1147 continue;
1148
1149 // Add it.
1150 auto SetThisAdjustmentThunk = [&](uint64_t Idx) {
1151 // If a this pointer adjustment is required, record the method that
1152 // created the vtable entry. MD is not necessarily the method that
1153 // created the entry since derived classes overwrite base class
1154 // information in MethodInfoMap, hence findOriginalMethodInMap is called
1155 // here.
1156 //
1157 // For example, in the following class hierarchy, if MD = D1::m and
1158 // Overrider = D2:m, the original method that created the entry is B0:m,
1159 // which is what findOriginalMethodInMap(MD) returns:
1160 //
1161 // struct B0 { int a; virtual void m(); };
1162 // struct D0 : B0 { int a; void m() override; };
1163 // struct D1 : B0 { int a; void m() override; };
1164 // struct D2 : D0, D1 { int a; void m() override; };
1165 //
1166 // We need to record the method because we cannot
1167 // call findOriginalMethod to find the method that created the entry if
1168 // the method in the entry requires adjustment.
1169 //
1170 // Do not set ThunkInfo::Method if Idx is already in VTableThunks. This
1171 // can happen when covariant return adjustment is required too.
1172 if (!VTableThunks.count(Idx)) {
1173 const CXXMethodDecl *Method = VTables.findOriginalMethodInMap(MD);
1174 VTableThunks[Idx].Method = Method;
1175 VTableThunks[Idx].ThisType = Method->getThisType().getTypePtr();
1176 }
1177 VTableThunks[Idx].This = ThisAdjustment;
1178 };
1179
1180 SetThisAdjustmentThunk(VTableIndex);
1181
1182 if (isa<CXXDestructorDecl>(MD)) {
1183 // Add an adjustment for the deleting destructor as well.
1184 SetThisAdjustmentThunk(VTableIndex + 1);
1185 }
1186 }
1187
1188 /// Clear the method info map.
1189 MethodInfoMap.clear();
1190
1191 if (isBuildingConstructorVTable()) {
1192 // We don't need to store thunk information for construction vtables.
1193 return;
1194 }
1195
1196 for (const auto &TI : VTableThunks) {
1197 const VTableComponent &Component = Components[TI.first];
1198 const ThunkInfo &Thunk = TI.second;
1199 const CXXMethodDecl *MD;
1200
1201 switch (Component.getKind()) {
1202 default:
1203 llvm_unreachable("Unexpected vtable component kind!");
1205 MD = Component.getFunctionDecl();
1206 break;
1208 MD = Component.getDestructorDecl();
1209 break;
1211 // We've already added the thunk when we saw the complete dtor pointer.
1212 continue;
1213 }
1214
1215 if (MD->getParent() == MostDerivedClass)
1216 AddThunk(MD, Thunk);
1217 }
1218}
1219
1221ItaniumVTableBuilder::ComputeReturnAdjustment(BaseOffset Offset) {
1222 ReturnAdjustment Adjustment;
1223
1224 if (!Offset.isEmpty()) {
1225 if (Offset.VirtualBase) {
1226 // Get the virtual base offset offset.
1227 if (Offset.DerivedClass == MostDerivedClass) {
1228 // We can get the offset offset directly from our map.
1229 Adjustment.Virtual.Itanium.VBaseOffsetOffset =
1230 VBaseOffsetOffsets.lookup(Offset.VirtualBase).getQuantity();
1231 } else {
1232 Adjustment.Virtual.Itanium.VBaseOffsetOffset =
1233 VTables.getVirtualBaseOffsetOffset(Offset.DerivedClass,
1234 Offset.VirtualBase).getQuantity();
1235 }
1236 }
1237
1238 Adjustment.NonVirtual = Offset.NonVirtualOffset.getQuantity();
1239 }
1240
1241 return Adjustment;
1242}
1243
1244BaseOffset ItaniumVTableBuilder::ComputeThisAdjustmentBaseOffset(
1245 BaseSubobject Base, BaseSubobject Derived) const {
1246 const CXXRecordDecl *BaseRD = Base.getBase();
1247 const CXXRecordDecl *DerivedRD = Derived.getBase();
1248
1249 CXXBasePaths Paths(/*FindAmbiguities=*/true,
1250 /*RecordPaths=*/true, /*DetectVirtual=*/true);
1251
1252 if (!DerivedRD->isDerivedFrom(BaseRD, Paths))
1253 llvm_unreachable("Class must be derived from the passed in base class!");
1254
1255 // We have to go through all the paths, and see which one leads us to the
1256 // right base subobject.
1257 for (const CXXBasePath &Path : Paths) {
1258 BaseOffset Offset = ComputeBaseOffset(Context, DerivedRD, Path);
1259
1260 CharUnits OffsetToBaseSubobject = Offset.NonVirtualOffset;
1261
1262 if (Offset.VirtualBase) {
1263 // If we have a virtual base class, the non-virtual offset is relative
1264 // to the virtual base class offset.
1265 const ASTRecordLayout &LayoutClassLayout =
1266 Context.getASTRecordLayout(LayoutClass);
1267
1268 /// Get the virtual base offset, relative to the most derived class
1269 /// layout.
1270 OffsetToBaseSubobject +=
1271 LayoutClassLayout.getVBaseClassOffset(Offset.VirtualBase);
1272 } else {
1273 // Otherwise, the non-virtual offset is relative to the derived class
1274 // offset.
1275 OffsetToBaseSubobject += Derived.getBaseOffset();
1276 }
1277
1278 // Check if this path gives us the right base subobject.
1279 if (OffsetToBaseSubobject == Base.getBaseOffset()) {
1280 // Since we're going from the base class _to_ the derived class, we'll
1281 // invert the non-virtual offset here.
1282 Offset.NonVirtualOffset = -Offset.NonVirtualOffset;
1283 return Offset;
1284 }
1285 }
1286
1287 return BaseOffset();
1288}
1289
1290ThisAdjustment ItaniumVTableBuilder::ComputeThisAdjustment(
1291 const CXXMethodDecl *MD, CharUnits BaseOffsetInLayoutClass,
1292 FinalOverriders::OverriderInfo Overrider) {
1293 // Ignore adjustments for pure virtual member functions.
1294 if (Overrider.Method->isPureVirtual())
1295 return ThisAdjustment();
1296
1297 BaseSubobject OverriddenBaseSubobject(MD->getParent(),
1298 BaseOffsetInLayoutClass);
1299
1300 BaseSubobject OverriderBaseSubobject(Overrider.Method->getParent(),
1301 Overrider.Offset);
1302
1303 // Compute the adjustment offset.
1304 BaseOffset Offset = ComputeThisAdjustmentBaseOffset(OverriddenBaseSubobject,
1305 OverriderBaseSubobject);
1306 if (Offset.isEmpty())
1307 return ThisAdjustment();
1308
1309 ThisAdjustment Adjustment;
1310
1311 if (Offset.VirtualBase) {
1312 // Get the vcall offset map for this virtual base.
1313 VCallOffsetMap &VCallOffsets = VCallOffsetsForVBases[Offset.VirtualBase];
1314
1315 if (VCallOffsets.empty()) {
1316 // We don't have vcall offsets for this virtual base, go ahead and
1317 // build them.
1318 VCallAndVBaseOffsetBuilder Builder(
1319 VTables, MostDerivedClass, MostDerivedClass,
1320 /*Overriders=*/nullptr,
1321 BaseSubobject(Offset.VirtualBase, CharUnits::Zero()),
1322 /*BaseIsVirtual=*/true,
1323 /*OffsetInLayoutClass=*/
1324 CharUnits::Zero());
1325
1326 VCallOffsets = Builder.getVCallOffsets();
1327 }
1328
1329 Adjustment.Virtual.Itanium.VCallOffsetOffset =
1330 VCallOffsets.getVCallOffsetOffset(MD).getQuantity();
1331 }
1332
1333 // Set the non-virtual part of the adjustment.
1334 Adjustment.NonVirtual = Offset.NonVirtualOffset.getQuantity();
1335
1336 return Adjustment;
1337}
1338
1339void ItaniumVTableBuilder::AddMethod(const CXXMethodDecl *MD,
1341 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
1342 assert(ReturnAdjustment.isEmpty() &&
1343 "Destructor can't have return adjustment!");
1344
1345 // Add both the complete destructor and the deleting destructor.
1346 Components.push_back(VTableComponent::MakeCompleteDtor(DD));
1347 Components.push_back(VTableComponent::MakeDeletingDtor(DD));
1348 } else {
1349 // Add the return adjustment if necessary.
1351 VTableThunks[Components.size()].Return = ReturnAdjustment;
1352
1353 // Add the function.
1354 Components.push_back(VTableComponent::MakeFunction(MD));
1355 }
1356}
1357
1358/// OverridesIndirectMethodInBase - Return whether the given member function
1359/// overrides any methods in the set of given bases.
1360/// Unlike OverridesMethodInBase, this checks "overriders of overriders".
1361/// For example, if we have:
1362///
1363/// struct A { virtual void f(); }
1364/// struct B : A { virtual void f(); }
1365/// struct C : B { virtual void f(); }
1366///
1367/// OverridesIndirectMethodInBase will return true if given C::f as the method
1368/// and { A } as the set of bases.
1369static bool OverridesIndirectMethodInBases(
1370 const CXXMethodDecl *MD,
1372 if (Bases.count(MD->getParent()))
1373 return true;
1374
1375 for (const CXXMethodDecl *OverriddenMD : MD->overridden_methods()) {
1376 // Check "indirect overriders".
1377 if (OverridesIndirectMethodInBases(OverriddenMD, Bases))
1378 return true;
1379 }
1380
1381 return false;
1382}
1383
1384bool ItaniumVTableBuilder::IsOverriderUsed(
1385 const CXXMethodDecl *Overrider, CharUnits BaseOffsetInLayoutClass,
1386 const CXXRecordDecl *FirstBaseInPrimaryBaseChain,
1387 CharUnits FirstBaseOffsetInLayoutClass) const {
1388 // If the base and the first base in the primary base chain have the same
1389 // offsets, then this overrider will be used.
1390 if (BaseOffsetInLayoutClass == FirstBaseOffsetInLayoutClass)
1391 return true;
1392
1393 // We know now that Base (or a direct or indirect base of it) is a primary
1394 // base in part of the class hierarchy, but not a primary base in the most
1395 // derived class.
1396
1397 // If the overrider is the first base in the primary base chain, we know
1398 // that the overrider will be used.
1399 if (Overrider->getParent() == FirstBaseInPrimaryBaseChain)
1400 return true;
1401
1403
1404 const CXXRecordDecl *RD = FirstBaseInPrimaryBaseChain;
1405 PrimaryBases.insert(RD);
1406
1407 // Now traverse the base chain, starting with the first base, until we find
1408 // the base that is no longer a primary base.
1409 while (true) {
1410 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
1411 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
1412
1413 if (!PrimaryBase)
1414 break;
1415
1416 if (Layout.isPrimaryBaseVirtual()) {
1417 assert(Layout.getVBaseClassOffset(PrimaryBase).isZero() &&
1418 "Primary base should always be at offset 0!");
1419
1420 const ASTRecordLayout &LayoutClassLayout =
1421 Context.getASTRecordLayout(LayoutClass);
1422
1423 // Now check if this is the primary base that is not a primary base in the
1424 // most derived class.
1425 if (LayoutClassLayout.getVBaseClassOffset(PrimaryBase) !=
1426 FirstBaseOffsetInLayoutClass) {
1427 // We found it, stop walking the chain.
1428 break;
1429 }
1430 } else {
1431 assert(Layout.getBaseClassOffset(PrimaryBase).isZero() &&
1432 "Primary base should always be at offset 0!");
1433 }
1434
1435 if (!PrimaryBases.insert(PrimaryBase))
1436 llvm_unreachable("Found a duplicate primary base!");
1437
1438 RD = PrimaryBase;
1439 }
1440
1441 // If the final overrider is an override of one of the primary bases,
1442 // then we know that it will be used.
1443 return OverridesIndirectMethodInBases(Overrider, PrimaryBases);
1444}
1445
1446typedef llvm::SmallSetVector<const CXXRecordDecl *, 8> BasesSetVectorTy;
1447
1448/// FindNearestOverriddenMethod - Given a method, returns the overridden method
1449/// from the nearest base. Returns null if no method was found.
1450/// The Bases are expected to be sorted in a base-to-derived order.
1451static const CXXMethodDecl *
1452FindNearestOverriddenMethod(const CXXMethodDecl *MD,
1453 BasesSetVectorTy &Bases) {
1454 OverriddenMethodsSetTy OverriddenMethods;
1455 ComputeAllOverriddenMethods(MD, OverriddenMethods);
1456
1457 for (const CXXRecordDecl *PrimaryBase : llvm::reverse(Bases)) {
1458 // Now check the overridden methods.
1459 for (const CXXMethodDecl *OverriddenMD : OverriddenMethods) {
1460 // We found our overridden method.
1461 if (OverriddenMD->getParent() == PrimaryBase)
1462 return OverriddenMD;
1463 }
1464 }
1465
1466 return nullptr;
1467}
1468
1469void ItaniumVTableBuilder::AddMethods(
1470 BaseSubobject Base, CharUnits BaseOffsetInLayoutClass,
1471 const CXXRecordDecl *FirstBaseInPrimaryBaseChain,
1472 CharUnits FirstBaseOffsetInLayoutClass,
1473 PrimaryBasesSetVectorTy &PrimaryBases) {
1474 // Itanium C++ ABI 2.5.2:
1475 // The order of the virtual function pointers in a virtual table is the
1476 // order of declaration of the corresponding member functions in the class.
1477 //
1478 // There is an entry for any virtual function declared in a class,
1479 // whether it is a new function or overrides a base class function,
1480 // unless it overrides a function from the primary base, and conversion
1481 // between their return types does not require an adjustment.
1482
1483 const CXXRecordDecl *RD = Base.getBase();
1484 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
1485
1486 if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) {
1487 CharUnits PrimaryBaseOffset;
1488 CharUnits PrimaryBaseOffsetInLayoutClass;
1489 if (Layout.isPrimaryBaseVirtual()) {
1490 assert(Layout.getVBaseClassOffset(PrimaryBase).isZero() &&
1491 "Primary vbase should have a zero offset!");
1492
1493 const ASTRecordLayout &MostDerivedClassLayout =
1494 Context.getASTRecordLayout(MostDerivedClass);
1495
1496 PrimaryBaseOffset =
1497 MostDerivedClassLayout.getVBaseClassOffset(PrimaryBase);
1498
1499 const ASTRecordLayout &LayoutClassLayout =
1500 Context.getASTRecordLayout(LayoutClass);
1501
1502 PrimaryBaseOffsetInLayoutClass =
1503 LayoutClassLayout.getVBaseClassOffset(PrimaryBase);
1504 } else {
1505 assert(Layout.getBaseClassOffset(PrimaryBase).isZero() &&
1506 "Primary base should have a zero offset!");
1507
1508 PrimaryBaseOffset = Base.getBaseOffset();
1509 PrimaryBaseOffsetInLayoutClass = BaseOffsetInLayoutClass;
1510 }
1511
1512 AddMethods(BaseSubobject(PrimaryBase, PrimaryBaseOffset),
1513 PrimaryBaseOffsetInLayoutClass, FirstBaseInPrimaryBaseChain,
1514 FirstBaseOffsetInLayoutClass, PrimaryBases);
1515
1516 if (!PrimaryBases.insert(PrimaryBase))
1517 llvm_unreachable("Found a duplicate primary base!");
1518 }
1519
1520 typedef llvm::SmallVector<const CXXMethodDecl *, 8> NewVirtualFunctionsTy;
1521 NewVirtualFunctionsTy NewVirtualFunctions;
1522
1523 llvm::SmallVector<const CXXMethodDecl*, 4> NewImplicitVirtualFunctions;
1524
1525 // Now go through all virtual member functions and add them.
1526 for (const auto *MD : RD->methods()) {
1527 if (!ItaniumVTableContext::hasVtableSlot(MD))
1528 continue;
1529 MD = MD->getCanonicalDecl();
1530
1531 // Get the final overrider.
1532 FinalOverriders::OverriderInfo Overrider =
1533 Overriders.getOverrider(MD, Base.getBaseOffset());
1534
1535 // Check if this virtual member function overrides a method in a primary
1536 // base. If this is the case, and the return type doesn't require adjustment
1537 // then we can just use the member function from the primary base.
1538 if (const CXXMethodDecl *OverriddenMD =
1539 FindNearestOverriddenMethod(MD, PrimaryBases)) {
1540 if (ComputeReturnAdjustmentBaseOffset(Context, MD,
1541 OverriddenMD).isEmpty()) {
1542 VTables.setOriginalMethod(MD, OverriddenMD);
1543
1544 // Replace the method info of the overridden method with our own
1545 // method.
1546 assert(MethodInfoMap.count(OverriddenMD) &&
1547 "Did not find the overridden method!");
1548 MethodInfo &OverriddenMethodInfo = MethodInfoMap[OverriddenMD];
1549
1550 MethodInfo MethodInfo(Base.getBaseOffset(), BaseOffsetInLayoutClass,
1551 OverriddenMethodInfo.VTableIndex);
1552
1553 assert(!MethodInfoMap.count(MD) &&
1554 "Should not have method info for this method yet!");
1555
1556 MethodInfoMap.insert(std::make_pair(MD, MethodInfo));
1557 MethodInfoMap.erase(OverriddenMD);
1558
1559 // If the overridden method exists in a virtual base class or a direct
1560 // or indirect base class of a virtual base class, we need to emit a
1561 // thunk if we ever have a class hierarchy where the base class is not
1562 // a primary base in the complete object.
1563 if (!isBuildingConstructorVTable() && OverriddenMD != MD) {
1564 // Compute the this adjustment.
1566 ComputeThisAdjustment(OverriddenMD, BaseOffsetInLayoutClass,
1567 Overrider);
1568
1570 Overrider.Method->getParent() == MostDerivedClass) {
1571
1572 // There's no return adjustment from OverriddenMD and MD,
1573 // but that doesn't mean there isn't one between MD and
1574 // the final overrider.
1575 BaseOffset ReturnAdjustmentOffset =
1576 ComputeReturnAdjustmentBaseOffset(Context, Overrider.Method, MD);
1578 ComputeReturnAdjustment(ReturnAdjustmentOffset);
1579
1580 // This is a virtual thunk for the most derived class, add it.
1581 AddThunk(Overrider.Method,
1583 OverriddenMD->getThisType().getTypePtr()));
1584 }
1585 }
1586
1587 continue;
1588 }
1589 }
1590
1591 if (MD->isImplicit())
1592 NewImplicitVirtualFunctions.push_back(MD);
1593 else
1594 NewVirtualFunctions.push_back(MD);
1595 }
1596
1597 std::stable_sort(
1598 NewImplicitVirtualFunctions.begin(), NewImplicitVirtualFunctions.end(),
1599 [](const CXXMethodDecl *A, const CXXMethodDecl *B) {
1600 if (A == B)
1601 return false;
1602 if (A->isCopyAssignmentOperator() != B->isCopyAssignmentOperator())
1603 return A->isCopyAssignmentOperator();
1604 if (A->isMoveAssignmentOperator() != B->isMoveAssignmentOperator())
1605 return A->isMoveAssignmentOperator();
1606 if (isa<CXXDestructorDecl>(A) != isa<CXXDestructorDecl>(B))
1607 return isa<CXXDestructorDecl>(A);
1608 assert(A->getOverloadedOperator() == OO_EqualEqual &&
1609 B->getOverloadedOperator() == OO_EqualEqual &&
1610 "unexpected or duplicate implicit virtual function");
1611 // We rely on Sema to have declared the operator== members in the
1612 // same order as the corresponding operator<=> members.
1613 return false;
1614 });
1615 NewVirtualFunctions.append(NewImplicitVirtualFunctions.begin(),
1616 NewImplicitVirtualFunctions.end());
1617
1618 for (const CXXMethodDecl *MD : NewVirtualFunctions) {
1619 // Get the final overrider.
1620 FinalOverriders::OverriderInfo Overrider =
1621 Overriders.getOverrider(MD, Base.getBaseOffset());
1622
1623 // Insert the method info for this method.
1624 MethodInfo MethodInfo(Base.getBaseOffset(), BaseOffsetInLayoutClass,
1625 Components.size());
1626
1627 assert(!MethodInfoMap.count(MD) &&
1628 "Should not have method info for this method yet!");
1629 MethodInfoMap.insert(std::make_pair(MD, MethodInfo));
1630
1631 // Check if this overrider is going to be used.
1632 const CXXMethodDecl *OverriderMD = Overrider.Method;
1633 if (!IsOverriderUsed(OverriderMD, BaseOffsetInLayoutClass,
1634 FirstBaseInPrimaryBaseChain,
1635 FirstBaseOffsetInLayoutClass)) {
1636 Components.push_back(VTableComponent::MakeUnusedFunction(OverriderMD));
1637 continue;
1638 }
1639
1640 // Check if this overrider needs a return adjustment.
1641 // We don't want to do this for pure virtual member functions.
1642 BaseOffset ReturnAdjustmentOffset;
1643 if (!OverriderMD->isPureVirtual()) {
1644 ReturnAdjustmentOffset =
1645 ComputeReturnAdjustmentBaseOffset(Context, OverriderMD, MD);
1646 }
1647
1649 ComputeReturnAdjustment(ReturnAdjustmentOffset);
1650
1651 // If a return adjustment is required, record the method that created the
1652 // vtable entry. We need to record the method because we cannot call
1653 // findOriginalMethod to find the method that created the entry if the
1654 // method in the entry requires adjustment.
1655 if (!ReturnAdjustment.isEmpty()) {
1656 VTableThunks[Components.size()].Method = MD;
1657 VTableThunks[Components.size()].ThisType = MD->getThisType().getTypePtr();
1658 }
1659
1660 AddMethod(Overrider.Method, ReturnAdjustment);
1661 }
1662}
1663
1664void ItaniumVTableBuilder::LayoutVTable() {
1665 LayoutPrimaryAndSecondaryVTables(BaseSubobject(MostDerivedClass,
1666 CharUnits::Zero()),
1667 /*BaseIsMorallyVirtual=*/false,
1668 MostDerivedClassIsVirtual,
1669 MostDerivedClassOffset);
1670
1671 VisitedVirtualBasesSetTy VBases;
1672
1673 // Determine the primary virtual bases.
1674 DeterminePrimaryVirtualBases(MostDerivedClass, MostDerivedClassOffset,
1675 VBases);
1676 VBases.clear();
1677
1678 LayoutVTablesForVirtualBases(MostDerivedClass, VBases);
1679
1680 // -fapple-kext adds an extra entry at end of vtbl.
1681 bool IsAppleKext = Context.getLangOpts().AppleKext;
1682 if (IsAppleKext)
1683 Components.push_back(VTableComponent::MakeVCallOffset(CharUnits::Zero()));
1684}
1685
1686void ItaniumVTableBuilder::LayoutPrimaryAndSecondaryVTables(
1687 BaseSubobject Base, bool BaseIsMorallyVirtual,
1688 bool BaseIsVirtualInLayoutClass, CharUnits OffsetInLayoutClass) {
1689 assert(Base.getBase()->isDynamicClass() && "class does not have a vtable!");
1690
1691 unsigned VTableIndex = Components.size();
1692 VTableIndices.push_back(VTableIndex);
1693
1694 // Add vcall and vbase offsets for this vtable.
1695 VCallAndVBaseOffsetBuilder Builder(
1696 VTables, MostDerivedClass, LayoutClass, &Overriders, Base,
1697 BaseIsVirtualInLayoutClass, OffsetInLayoutClass);
1698 Components.append(Builder.components_begin(), Builder.components_end());
1699
1700 // Check if we need to add these vcall offsets.
1701 if (BaseIsVirtualInLayoutClass && !Builder.getVCallOffsets().empty()) {
1702 VCallOffsetMap &VCallOffsets = VCallOffsetsForVBases[Base.getBase()];
1703
1704 if (VCallOffsets.empty())
1705 VCallOffsets = Builder.getVCallOffsets();
1706 }
1707
1708 // If we're laying out the most derived class we want to keep track of the
1709 // virtual base class offset offsets.
1710 if (Base.getBase() == MostDerivedClass)
1711 VBaseOffsetOffsets = Builder.getVBaseOffsetOffsets();
1712
1713 // Add the offset to top.
1714 CharUnits OffsetToTop = MostDerivedClassOffset - OffsetInLayoutClass;
1715 Components.push_back(VTableComponent::MakeOffsetToTop(OffsetToTop));
1716
1717 // Next, add the RTTI.
1718 if (!Context.getLangOpts().OmitVTableRTTI)
1719 Components.push_back(VTableComponent::MakeRTTI(MostDerivedClass));
1720
1721 uint64_t AddressPoint = Components.size();
1722
1723 // Now go through all virtual member functions and add them.
1724 PrimaryBasesSetVectorTy PrimaryBases;
1725 AddMethods(Base, OffsetInLayoutClass,
1726 Base.getBase(), OffsetInLayoutClass,
1727 PrimaryBases);
1728
1729 const CXXRecordDecl *RD = Base.getBase();
1730 if (RD == MostDerivedClass) {
1731 assert(MethodVTableIndices.empty());
1732 for (const auto &I : MethodInfoMap) {
1733 const CXXMethodDecl *MD = I.first;
1734 const MethodInfo &MI = I.second;
1735 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
1736 MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)]
1737 = MI.VTableIndex - AddressPoint;
1738 MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)]
1739 = MI.VTableIndex + 1 - AddressPoint;
1740 } else {
1741 MethodVTableIndices[MD] = MI.VTableIndex - AddressPoint;
1742 }
1743 }
1744 }
1745
1746 // Compute 'this' pointer adjustments.
1747 ComputeThisAdjustments();
1748
1749 // Add all address points.
1750 while (true) {
1751 AddressPoints.insert(
1752 std::make_pair(BaseSubobject(RD, OffsetInLayoutClass),
1754 unsigned(VTableIndices.size() - 1),
1755 unsigned(AddressPoint - VTableIndex)}));
1756
1757 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
1758 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
1759
1760 if (!PrimaryBase)
1761 break;
1762
1763 if (Layout.isPrimaryBaseVirtual()) {
1764 // Check if this virtual primary base is a primary base in the layout
1765 // class. If it's not, we don't want to add it.
1766 const ASTRecordLayout &LayoutClassLayout =
1767 Context.getASTRecordLayout(LayoutClass);
1768
1769 if (LayoutClassLayout.getVBaseClassOffset(PrimaryBase) !=
1770 OffsetInLayoutClass) {
1771 // We don't want to add this class (or any of its primary bases).
1772 break;
1773 }
1774 }
1775
1776 RD = PrimaryBase;
1777 }
1778
1779 // Layout secondary vtables.
1780 LayoutSecondaryVTables(Base, BaseIsMorallyVirtual, OffsetInLayoutClass);
1781}
1782
1783void
1784ItaniumVTableBuilder::LayoutSecondaryVTables(BaseSubobject Base,
1785 bool BaseIsMorallyVirtual,
1786 CharUnits OffsetInLayoutClass) {
1787 // Itanium C++ ABI 2.5.2:
1788 // Following the primary virtual table of a derived class are secondary
1789 // virtual tables for each of its proper base classes, except any primary
1790 // base(s) with which it shares its primary virtual table.
1791
1792 const CXXRecordDecl *RD = Base.getBase();
1793 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
1794 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
1795
1796 for (const auto &B : RD->bases()) {
1797 // Ignore virtual bases, we'll emit them later.
1798 if (B.isVirtual())
1799 continue;
1800
1801 const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl();
1802
1803 // Ignore bases that don't have a vtable.
1804 if (!BaseDecl->isDynamicClass())
1805 continue;
1806
1807 if (isBuildingConstructorVTable()) {
1808 // Itanium C++ ABI 2.6.4:
1809 // Some of the base class subobjects may not need construction virtual
1810 // tables, which will therefore not be present in the construction
1811 // virtual table group, even though the subobject virtual tables are
1812 // present in the main virtual table group for the complete object.
1813 if (!BaseIsMorallyVirtual && !BaseDecl->getNumVBases())
1814 continue;
1815 }
1816
1817 // Get the base offset of this base.
1818 CharUnits RelativeBaseOffset = Layout.getBaseClassOffset(BaseDecl);
1819 CharUnits BaseOffset = Base.getBaseOffset() + RelativeBaseOffset;
1820
1821 CharUnits BaseOffsetInLayoutClass =
1822 OffsetInLayoutClass + RelativeBaseOffset;
1823
1824 // Don't emit a secondary vtable for a primary base. We might however want
1825 // to emit secondary vtables for other bases of this base.
1826 if (BaseDecl == PrimaryBase) {
1827 LayoutSecondaryVTables(BaseSubobject(BaseDecl, BaseOffset),
1828 BaseIsMorallyVirtual, BaseOffsetInLayoutClass);
1829 continue;
1830 }
1831
1832 // Layout the primary vtable (and any secondary vtables) for this base.
1833 LayoutPrimaryAndSecondaryVTables(
1834 BaseSubobject(BaseDecl, BaseOffset),
1835 BaseIsMorallyVirtual,
1836 /*BaseIsVirtualInLayoutClass=*/false,
1837 BaseOffsetInLayoutClass);
1838 }
1839}
1840
1841void ItaniumVTableBuilder::DeterminePrimaryVirtualBases(
1842 const CXXRecordDecl *RD, CharUnits OffsetInLayoutClass,
1843 VisitedVirtualBasesSetTy &VBases) {
1844 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
1845
1846 // Check if this base has a primary base.
1847 if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) {
1848
1849 // Check if it's virtual.
1850 if (Layout.isPrimaryBaseVirtual()) {
1851 bool IsPrimaryVirtualBase = true;
1852
1853 if (isBuildingConstructorVTable()) {
1854 // Check if the base is actually a primary base in the class we use for
1855 // layout.
1856 const ASTRecordLayout &LayoutClassLayout =
1857 Context.getASTRecordLayout(LayoutClass);
1858
1859 CharUnits PrimaryBaseOffsetInLayoutClass =
1860 LayoutClassLayout.getVBaseClassOffset(PrimaryBase);
1861
1862 // We know that the base is not a primary base in the layout class if
1863 // the base offsets are different.
1864 if (PrimaryBaseOffsetInLayoutClass != OffsetInLayoutClass)
1865 IsPrimaryVirtualBase = false;
1866 }
1867
1868 if (IsPrimaryVirtualBase)
1869 PrimaryVirtualBases.insert(PrimaryBase);
1870 }
1871 }
1872
1873 // Traverse bases, looking for more primary virtual bases.
1874 for (const auto &B : RD->bases()) {
1875 const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl();
1876
1877 CharUnits BaseOffsetInLayoutClass;
1878
1879 if (B.isVirtual()) {
1880 if (!VBases.insert(BaseDecl).second)
1881 continue;
1882
1883 const ASTRecordLayout &LayoutClassLayout =
1884 Context.getASTRecordLayout(LayoutClass);
1885
1886 BaseOffsetInLayoutClass =
1887 LayoutClassLayout.getVBaseClassOffset(BaseDecl);
1888 } else {
1889 BaseOffsetInLayoutClass =
1890 OffsetInLayoutClass + Layout.getBaseClassOffset(BaseDecl);
1891 }
1892
1893 DeterminePrimaryVirtualBases(BaseDecl, BaseOffsetInLayoutClass, VBases);
1894 }
1895}
1896
1897void ItaniumVTableBuilder::LayoutVTablesForVirtualBases(
1898 const CXXRecordDecl *RD, VisitedVirtualBasesSetTy &VBases) {
1899 // Itanium C++ ABI 2.5.2:
1900 // Then come the virtual base virtual tables, also in inheritance graph
1901 // order, and again excluding primary bases (which share virtual tables with
1902 // the classes for which they are primary).
1903 for (const auto &B : RD->bases()) {
1904 const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl();
1905
1906 // Check if this base needs a vtable. (If it's virtual, not a primary base
1907 // of some other class, and we haven't visited it before).
1908 if (B.isVirtual() && BaseDecl->isDynamicClass() &&
1909 !PrimaryVirtualBases.count(BaseDecl) &&
1910 VBases.insert(BaseDecl).second) {
1911 const ASTRecordLayout &MostDerivedClassLayout =
1912 Context.getASTRecordLayout(MostDerivedClass);
1913 CharUnits BaseOffset =
1914 MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
1915
1916 const ASTRecordLayout &LayoutClassLayout =
1917 Context.getASTRecordLayout(LayoutClass);
1918 CharUnits BaseOffsetInLayoutClass =
1919 LayoutClassLayout.getVBaseClassOffset(BaseDecl);
1920
1921 LayoutPrimaryAndSecondaryVTables(
1922 BaseSubobject(BaseDecl, BaseOffset),
1923 /*BaseIsMorallyVirtual=*/true,
1924 /*BaseIsVirtualInLayoutClass=*/true,
1925 BaseOffsetInLayoutClass);
1926 }
1927
1928 // We only need to check the base for virtual base vtables if it actually
1929 // has virtual bases.
1930 if (BaseDecl->getNumVBases())
1931 LayoutVTablesForVirtualBases(BaseDecl, VBases);
1932 }
1933}
1934
1935static void printThunkMethod(const ThunkInfo &Info, raw_ostream &Out) {
1936 if (!Info.Method)
1937 return;
1938 std::string Str = PredefinedExpr::ComputeName(
1939 PredefinedIdentKind::PrettyFunctionNoVirtual, Info.Method);
1940 Out << " method: " << Str;
1941}
1942
1943/// dumpLayout - Dump the vtable layout.
1944void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
1945 // FIXME: write more tests that actually use the dumpLayout output to prevent
1946 // ItaniumVTableBuilder regressions.
1947
1948 Out << "Original map\n";
1949
1950 for (const auto &P : VTables.getOriginalMethodMap()) {
1951 std::string Str0 =
1952 PredefinedExpr::ComputeName(PredefinedIdentKind::PrettyFunctionNoVirtual,
1953 P.first);
1954 std::string Str1 =
1955 PredefinedExpr::ComputeName(PredefinedIdentKind::PrettyFunctionNoVirtual,
1956 P.second);
1957 Out << " " << Str0 << " -> " << Str1 << "\n";
1958 }
1959
1960 if (isBuildingConstructorVTable()) {
1961 Out << "Construction vtable for ('";
1962 MostDerivedClass->printQualifiedName(Out);
1963 Out << "', ";
1964 Out << MostDerivedClassOffset.getQuantity() << ") in '";
1965 LayoutClass->printQualifiedName(Out);
1966 } else {
1967 Out << "Vtable for '";
1968 MostDerivedClass->printQualifiedName(Out);
1969 }
1970 Out << "' (" << Components.size() << " entries).\n";
1971
1972 // Iterate through the address points and insert them into a new map where
1973 // they are keyed by the index and not the base object.
1974 // Since an address point can be shared by multiple subobjects, we use an
1975 // STL multimap.
1976 std::multimap<uint64_t, BaseSubobject> AddressPointsByIndex;
1977 for (const auto &AP : AddressPoints) {
1978 const BaseSubobject &Base = AP.first;
1979 uint64_t Index =
1980 VTableIndices[AP.second.VTableIndex] + AP.second.AddressPointIndex;
1981
1982 AddressPointsByIndex.insert(std::make_pair(Index, Base));
1983 }
1984
1985 for (unsigned I = 0, E = Components.size(); I != E; ++I) {
1986 uint64_t Index = I;
1987
1988 Out << llvm::format("%4d | ", I);
1989
1990 const VTableComponent &Component = Components[I];
1991
1992 // Dump the component.
1993 switch (Component.getKind()) {
1994
1996 Out << "vcall_offset ("
1997 << Component.getVCallOffset().getQuantity()
1998 << ")";
1999 break;
2000
2002 Out << "vbase_offset ("
2003 << Component.getVBaseOffset().getQuantity()
2004 << ")";
2005 break;
2006
2008 Out << "offset_to_top ("
2009 << Component.getOffsetToTop().getQuantity()
2010 << ")";
2011 break;
2012
2014 Component.getRTTIDecl()->printQualifiedName(Out);
2015 Out << " RTTI";
2016 break;
2017
2019 const CXXMethodDecl *MD = Component.getFunctionDecl();
2020
2021 std::string Str = PredefinedExpr::ComputeName(
2022 PredefinedIdentKind::PrettyFunctionNoVirtual, MD);
2023 Out << Str;
2024 if (MD->isPureVirtual())
2025 Out << " [pure]";
2026
2027 if (MD->isDeleted())
2028 Out << " [deleted]";
2029
2030 ThunkInfo Thunk = VTableThunks.lookup(I);
2031 if (!Thunk.isEmpty()) {
2032 // If this function pointer has a return adjustment, dump it.
2033 if (!Thunk.Return.isEmpty()) {
2034 Out << "\n [return adjustment: ";
2035 Out << Thunk.Return.NonVirtual << " non-virtual";
2036
2038 Out << ", " << Thunk.Return.Virtual.Itanium.VBaseOffsetOffset;
2039 Out << " vbase offset offset";
2040 }
2041
2042 Out << ']';
2043 printThunkMethod(Thunk, Out);
2044 }
2045
2046 // If this function pointer has a 'this' pointer adjustment, dump it.
2047 if (!Thunk.This.isEmpty()) {
2048 Out << "\n [this adjustment: ";
2049 Out << Thunk.This.NonVirtual << " non-virtual";
2050
2052 Out << ", " << Thunk.This.Virtual.Itanium.VCallOffsetOffset;
2053 Out << " vcall offset offset";
2054 }
2055
2056 Out << ']';
2057 printThunkMethod(Thunk, Out);
2058 }
2059 }
2060
2061 break;
2062 }
2063
2066 bool IsComplete =
2068
2069 const CXXDestructorDecl *DD = Component.getDestructorDecl();
2070
2071 DD->printQualifiedName(Out);
2072 if (IsComplete)
2073 Out << "() [complete]";
2074 else
2075 Out << "() [deleting]";
2076
2077 if (DD->isPureVirtual())
2078 Out << " [pure]";
2079
2080 ThunkInfo Thunk = VTableThunks.lookup(I);
2081 if (!Thunk.isEmpty()) {
2082 // If this destructor has a 'this' pointer adjustment, dump it.
2083 if (!Thunk.This.isEmpty()) {
2084 Out << "\n [this adjustment: ";
2085 Out << Thunk.This.NonVirtual << " non-virtual";
2086
2088 Out << ", " << Thunk.This.Virtual.Itanium.VCallOffsetOffset;
2089 Out << " vcall offset offset";
2090 }
2091
2092 Out << ']';
2093 }
2094 printThunkMethod(Thunk, Out);
2095 }
2096
2097 break;
2098 }
2099
2101 const CXXMethodDecl *MD = Component.getUnusedFunctionDecl();
2102
2103 std::string Str = PredefinedExpr::ComputeName(
2104 PredefinedIdentKind::PrettyFunctionNoVirtual, MD);
2105 Out << "[unused] " << Str;
2106 if (MD->isPureVirtual())
2107 Out << " [pure]";
2108 }
2109
2110 }
2111
2112 Out << '\n';
2113
2114 // Dump the next address point.
2115 uint64_t NextIndex = Index + 1;
2116 if (AddressPointsByIndex.count(NextIndex)) {
2117 if (AddressPointsByIndex.count(NextIndex) == 1) {
2118 const BaseSubobject &Base =
2119 AddressPointsByIndex.find(NextIndex)->second;
2120
2121 Out << " -- (";
2122 Base.getBase()->printQualifiedName(Out);
2123 Out << ", " << Base.getBaseOffset().getQuantity();
2124 Out << ") vtable address --\n";
2125 } else {
2126 CharUnits BaseOffset =
2127 AddressPointsByIndex.lower_bound(NextIndex)->second.getBaseOffset();
2128
2129 // We store the class names in a set to get a stable order.
2130 std::set<std::string> ClassNames;
2131 for (const auto &I :
2132 llvm::make_range(AddressPointsByIndex.equal_range(NextIndex))) {
2133 assert(I.second.getBaseOffset() == BaseOffset &&
2134 "Invalid base offset!");
2135 const CXXRecordDecl *RD = I.second.getBase();
2136 ClassNames.insert(RD->getQualifiedNameAsString());
2137 }
2138
2139 for (const std::string &Name : ClassNames) {
2140 Out << " -- (" << Name;
2141 Out << ", " << BaseOffset.getQuantity() << ") vtable address --\n";
2142 }
2143 }
2144 }
2145 }
2146
2147 Out << '\n';
2148
2149 if (isBuildingConstructorVTable())
2150 return;
2151
2152 if (MostDerivedClass->getNumVBases()) {
2153 // We store the virtual base class names and their offsets in a map to get
2154 // a stable order.
2155
2156 std::map<std::string, CharUnits> ClassNamesAndOffsets;
2157 for (const auto &I : VBaseOffsetOffsets) {
2158 std::string ClassName = I.first->getQualifiedNameAsString();
2159 CharUnits OffsetOffset = I.second;
2160 ClassNamesAndOffsets.insert(std::make_pair(ClassName, OffsetOffset));
2161 }
2162
2163 Out << "Virtual base offset offsets for '";
2164 MostDerivedClass->printQualifiedName(Out);
2165 Out << "' (";
2166 Out << ClassNamesAndOffsets.size();
2167 Out << (ClassNamesAndOffsets.size() == 1 ? " entry" : " entries") << ").\n";
2168
2169 for (const auto &I : ClassNamesAndOffsets)
2170 Out << " " << I.first << " | " << I.second.getQuantity() << '\n';
2171
2172 Out << "\n";
2173 }
2174
2175 if (!Thunks.empty()) {
2176 // We store the method names in a map to get a stable order.
2177 std::map<std::string, const CXXMethodDecl *> MethodNamesAndDecls;
2178
2179 for (const auto &I : Thunks) {
2180 const CXXMethodDecl *MD = I.first;
2181 std::string MethodName = PredefinedExpr::ComputeName(
2182 PredefinedIdentKind::PrettyFunctionNoVirtual, MD);
2183
2184 MethodNamesAndDecls.insert(std::make_pair(MethodName, MD));
2185 }
2186
2187 for (const auto &I : MethodNamesAndDecls) {
2188 const std::string &MethodName = I.first;
2189 const CXXMethodDecl *MD = I.second;
2190
2191 ThunkInfoVectorTy ThunksVector = Thunks[MD];
2192 llvm::sort(ThunksVector, [](const ThunkInfo &LHS, const ThunkInfo &RHS) {
2193 return std::tie(LHS.This, LHS.Return) < std::tie(RHS.This, RHS.Return);
2194 });
2195
2196 Out << "Thunks for '" << MethodName << "' (" << ThunksVector.size();
2197 Out << (ThunksVector.size() == 1 ? " entry" : " entries") << ").\n";
2198
2199 for (unsigned I = 0, E = ThunksVector.size(); I != E; ++I) {
2200 const ThunkInfo &Thunk = ThunksVector[I];
2201
2202 Out << llvm::format("%4d | ", I);
2203
2204 // If this function pointer has a return pointer adjustment, dump it.
2205 if (!Thunk.Return.isEmpty()) {
2206 Out << "return adjustment: " << Thunk.Return.NonVirtual;
2207 Out << " non-virtual";
2209 Out << ", " << Thunk.Return.Virtual.Itanium.VBaseOffsetOffset;
2210 Out << " vbase offset offset";
2211 }
2212
2213 if (!Thunk.This.isEmpty())
2214 Out << "\n ";
2215 }
2216
2217 // If this function pointer has a 'this' pointer adjustment, dump it.
2218 if (!Thunk.This.isEmpty()) {
2219 Out << "this adjustment: ";
2220 Out << Thunk.This.NonVirtual << " non-virtual";
2221
2223 Out << ", " << Thunk.This.Virtual.Itanium.VCallOffsetOffset;
2224 Out << " vcall offset offset";
2225 }
2226 }
2227
2228 Out << '\n';
2229 }
2230
2231 Out << '\n';
2232 }
2233 }
2234
2235 // Compute the vtable indices for all the member functions.
2236 // Store them in a map keyed by the index so we'll get a sorted table.
2237 std::map<uint64_t, std::string> IndicesMap;
2238
2239 for (const auto *MD : MostDerivedClass->methods()) {
2240 // We only want virtual member functions.
2241 if (!ItaniumVTableContext::hasVtableSlot(MD))
2242 continue;
2243 MD = MD->getCanonicalDecl();
2244
2245 std::string MethodName = PredefinedExpr::ComputeName(
2246 PredefinedIdentKind::PrettyFunctionNoVirtual, MD);
2247
2248 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
2249 GlobalDecl GD(DD, Dtor_Complete);
2250 assert(MethodVTableIndices.count(GD));
2251 uint64_t VTableIndex = MethodVTableIndices[GD];
2252 IndicesMap[VTableIndex] = MethodName + " [complete]";
2253 IndicesMap[VTableIndex + 1] = MethodName + " [deleting]";
2254 } else {
2255 assert(MethodVTableIndices.count(MD));
2256 IndicesMap[MethodVTableIndices[MD]] = MethodName;
2257 }
2258 }
2259
2260 // Print the vtable indices for all the member functions.
2261 if (!IndicesMap.empty()) {
2262 Out << "VTable indices for '";
2263 MostDerivedClass->printQualifiedName(Out);
2264 Out << "' (" << IndicesMap.size() << " entries).\n";
2265
2266 for (const auto &I : IndicesMap) {
2267 uint64_t VTableIndex = I.first;
2268 const std::string &MethodName = I.second;
2269
2270 Out << llvm::format("%4" PRIu64 " | ", VTableIndex) << MethodName
2271 << '\n';
2272 }
2273 }
2274
2275 Out << '\n';
2276}
2277}
2278
2281 unsigned numVTables) {
2282 VTableLayout::AddressPointsIndexMapTy indexMap(numVTables);
2283
2284 for (auto it = addressPoints.begin(); it != addressPoints.end(); ++it) {
2285 const auto &addressPointLoc = it->second;
2286 unsigned vtableIndex = addressPointLoc.VTableIndex;
2287 unsigned addressPoint = addressPointLoc.AddressPointIndex;
2288 if (indexMap[vtableIndex]) {
2289 // Multiple BaseSubobjects can map to the same AddressPointLocation, but
2290 // every vtable index should have a unique address point.
2291 assert(indexMap[vtableIndex] == addressPoint &&
2292 "Every vtable index should have a unique address point. Found a "
2293 "vtable that has two different address points.");
2294 } else {
2295 indexMap[vtableIndex] = addressPoint;
2296 }
2297 }
2298
2299 // Note that by this point, not all the address may be initialized if the
2300 // AddressPoints map is empty. This is ok if the map isn't needed. See
2301 // MicrosoftVTableContext::computeVTableRelatedInformation() which uses an
2302 // emprt map.
2303 return indexMap;
2304}
2305
2307 ArrayRef<VTableComponent> VTableComponents,
2308 ArrayRef<VTableThunkTy> VTableThunks,
2309 const AddressPointsMapTy &AddressPoints)
2310 : VTableComponents(VTableComponents), VTableThunks(VTableThunks),
2311 AddressPoints(AddressPoints), AddressPointIndices(MakeAddressPointIndices(
2312 AddressPoints, VTableIndices.size())) {
2313 if (VTableIndices.size() <= 1)
2314 assert(VTableIndices.size() == 1 && VTableIndices[0] == 0);
2315 else
2316 this->VTableIndices = OwningArrayRef<size_t>(VTableIndices);
2317
2318 llvm::sort(this->VTableThunks, [](const VTableLayout::VTableThunkTy &LHS,
2319 const VTableLayout::VTableThunkTy &RHS) {
2320 assert((LHS.first != RHS.first || LHS.second == RHS.second) &&
2321 "Different thunks should have unique indices!");
2322 return LHS.first < RHS.first;
2323 });
2324}
2325
2327
2329 return MD->isVirtual() && !MD->isImmediateFunction();
2330}
2331
2333 ASTContext &Context, VTableComponentLayout ComponentLayout)
2334 : VTableContextBase(/*MS=*/false), ComponentLayout(ComponentLayout) {}
2335
2337
2339 GD = GD.getCanonicalDecl();
2340 MethodVTableIndicesTy::iterator I = MethodVTableIndices.find(GD);
2341 if (I != MethodVTableIndices.end())
2342 return I->second;
2343
2344 const CXXRecordDecl *RD = cast<CXXMethodDecl>(GD.getDecl())->getParent();
2345
2346 computeVTableRelatedInformation(RD);
2347
2348 I = MethodVTableIndices.find(GD);
2349 assert(I != MethodVTableIndices.end() && "Did not find index!");
2350 return I->second;
2351}
2352
2355 const CXXRecordDecl *VBase) {
2356 ClassPairTy ClassPair(RD, VBase);
2357
2358 VirtualBaseClassOffsetOffsetsMapTy::iterator I =
2359 VirtualBaseClassOffsetOffsets.find(ClassPair);
2360 if (I != VirtualBaseClassOffsetOffsets.end())
2361 return I->second;
2362
2363 VCallAndVBaseOffsetBuilder Builder(*this, RD, RD, /*Overriders=*/nullptr,
2365 /*BaseIsVirtual=*/false,
2366 /*OffsetInLayoutClass=*/CharUnits::Zero());
2367
2368 for (const auto &I : Builder.getVBaseOffsetOffsets()) {
2369 // Insert all types.
2370 ClassPairTy ClassPair(RD, I.first);
2371
2372 VirtualBaseClassOffsetOffsets.insert(std::make_pair(ClassPair, I.second));
2373 }
2374
2375 I = VirtualBaseClassOffsetOffsets.find(ClassPair);
2376 assert(I != VirtualBaseClassOffsetOffsets.end() && "Did not find index!");
2377
2378 return I->second;
2379}
2380
2382 const auto *MD = cast<CXXMethodDecl>(GD.getDecl());
2383 computeVTableRelatedInformation(MD->getParent());
2384 const CXXMethodDecl *OriginalMD = findOriginalMethodInMap(MD);
2385
2386 if (const auto *DD = dyn_cast<CXXDestructorDecl>(OriginalMD))
2387 return GlobalDecl(DD, GD.getDtorType());
2388 return OriginalMD;
2389}
2390
2391const CXXMethodDecl *
2393 // Traverse the chain of virtual methods until we find the method that added
2394 // the v-table slot.
2395 while (true) {
2396 auto I = OriginalMethodMap.find(MD);
2397
2398 // MD doesn't exist in OriginalMethodMap, so it must be the method we are
2399 // looking for.
2400 if (I == OriginalMethodMap.end())
2401 break;
2402
2403 // Set MD to the overridden method.
2404 MD = I->second;
2405 }
2406
2407 return MD;
2408}
2409
2410static std::unique_ptr<VTableLayout>
2411CreateVTableLayout(const ItaniumVTableBuilder &Builder) {
2413 VTableThunks(Builder.vtable_thunks_begin(), Builder.vtable_thunks_end());
2414
2415 return std::make_unique<VTableLayout>(
2416 Builder.VTableIndices, Builder.vtable_components(), VTableThunks,
2417 Builder.getAddressPoints());
2418}
2419
2420void
2421ItaniumVTableContext::computeVTableRelatedInformation(const CXXRecordDecl *RD) {
2422 std::unique_ptr<const VTableLayout> &Entry = VTableLayouts[RD];
2423
2424 // Check if we've computed this information before.
2425 if (Entry)
2426 return;
2427
2428 ItaniumVTableBuilder Builder(*this, RD, CharUnits::Zero(),
2429 /*MostDerivedClassIsVirtual=*/false, RD);
2430 Entry = CreateVTableLayout(Builder);
2431
2432 MethodVTableIndices.insert(Builder.vtable_indices_begin(),
2433 Builder.vtable_indices_end());
2434
2435 // Add the known thunks.
2436 Thunks.insert(Builder.thunks_begin(), Builder.thunks_end());
2437
2438 // If we don't have the vbase information for this class, insert it.
2439 // getVirtualBaseOffsetOffset will compute it separately without computing
2440 // the rest of the vtable related information.
2441 if (!RD->getNumVBases())
2442 return;
2443
2444 const CXXRecordDecl *VBase =
2446
2447 if (VirtualBaseClassOffsetOffsets.count(std::make_pair(RD, VBase)))
2448 return;
2449
2450 for (const auto &I : Builder.getVBaseOffsetOffsets()) {
2451 // Insert all types.
2452 ClassPairTy ClassPair(RD, I.first);
2453
2454 VirtualBaseClassOffsetOffsets.insert(std::make_pair(ClassPair, I.second));
2455 }
2456}
2457
2458std::unique_ptr<VTableLayout>
2460 const CXXRecordDecl *MostDerivedClass, CharUnits MostDerivedClassOffset,
2461 bool MostDerivedClassIsVirtual, const CXXRecordDecl *LayoutClass) {
2462 ItaniumVTableBuilder Builder(*this, MostDerivedClass, MostDerivedClassOffset,
2463 MostDerivedClassIsVirtual, LayoutClass);
2464 return CreateVTableLayout(Builder);
2465}
2466
2467namespace {
2468
2469// Vtables in the Microsoft ABI are different from the Itanium ABI.
2470//
2471// The main differences are:
2472// 1. Separate vftable and vbtable.
2473//
2474// 2. Each subobject with a vfptr gets its own vftable rather than an address
2475// point in a single vtable shared between all the subobjects.
2476// Each vftable is represented by a separate section and virtual calls
2477// must be done using the vftable which has a slot for the function to be
2478// called.
2479//
2480// 3. Virtual method definitions expect their 'this' parameter to point to the
2481// first vfptr whose table provides a compatible overridden method. In many
2482// cases, this permits the original vf-table entry to directly call
2483// the method instead of passing through a thunk.
2484// See example before VFTableBuilder::ComputeThisOffset below.
2485//
2486// A compatible overridden method is one which does not have a non-trivial
2487// covariant-return adjustment.
2488//
2489// The first vfptr is the one with the lowest offset in the complete-object
2490// layout of the defining class, and the method definition will subtract
2491// that constant offset from the parameter value to get the real 'this'
2492// value. Therefore, if the offset isn't really constant (e.g. if a virtual
2493// function defined in a virtual base is overridden in a more derived
2494// virtual base and these bases have a reverse order in the complete
2495// object), the vf-table may require a this-adjustment thunk.
2496//
2497// 4. vftables do not contain new entries for overrides that merely require
2498// this-adjustment. Together with #3, this keeps vf-tables smaller and
2499// eliminates the need for this-adjustment thunks in many cases, at the cost
2500// of often requiring redundant work to adjust the "this" pointer.
2501//
2502// 5. Instead of VTT and constructor vtables, vbtables and vtordisps are used.
2503// Vtordisps are emitted into the class layout if a class has
2504// a) a user-defined ctor/dtor
2505// and
2506// b) a method overriding a method in a virtual base.
2507//
2508// To get a better understanding of this code,
2509// you might want to see examples in test/CodeGenCXX/microsoft-abi-vtables-*.cpp
2510
2511class VFTableBuilder {
2512public:
2513 typedef llvm::DenseMap<GlobalDecl, MethodVFTableLocation>
2514 MethodVFTableLocationsTy;
2515
2516 typedef llvm::iterator_range<MethodVFTableLocationsTy::const_iterator>
2517 method_locations_range;
2518
2519private:
2520 /// VTables - Global vtable information.
2521 MicrosoftVTableContext &VTables;
2522
2523 /// Context - The ASTContext which we will use for layout information.
2524 ASTContext &Context;
2525
2526 /// MostDerivedClass - The most derived class for which we're building this
2527 /// vtable.
2528 const CXXRecordDecl *MostDerivedClass;
2529
2530 const ASTRecordLayout &MostDerivedClassLayout;
2531
2532 const VPtrInfo &WhichVFPtr;
2533
2534 /// FinalOverriders - The final overriders of the most derived class.
2535 const FinalOverriders Overriders;
2536
2537 /// Components - The components of the vftable being built.
2539
2540 MethodVFTableLocationsTy MethodVFTableLocations;
2541
2542 /// Does this class have an RTTI component?
2543 bool HasRTTIComponent = false;
2544
2545 /// MethodInfo - Contains information about a method in a vtable.
2546 /// (Used for computing 'this' pointer adjustment thunks.
2547 struct MethodInfo {
2548 /// VBTableIndex - The nonzero index in the vbtable that
2549 /// this method's base has, or zero.
2550 const uint64_t VBTableIndex;
2551
2552 /// VFTableIndex - The index in the vftable that this method has.
2553 const uint64_t VFTableIndex;
2554
2555 /// Shadowed - Indicates if this vftable slot is shadowed by
2556 /// a slot for a covariant-return override. If so, it shouldn't be printed
2557 /// or used for vcalls in the most derived class.
2558 bool Shadowed;
2559
2560 /// UsesExtraSlot - Indicates if this vftable slot was created because
2561 /// any of the overridden slots required a return adjusting thunk.
2562 bool UsesExtraSlot;
2563
2564 MethodInfo(uint64_t VBTableIndex, uint64_t VFTableIndex,
2565 bool UsesExtraSlot = false)
2566 : VBTableIndex(VBTableIndex), VFTableIndex(VFTableIndex),
2567 Shadowed(false), UsesExtraSlot(UsesExtraSlot) {}
2568
2569 MethodInfo()
2570 : VBTableIndex(0), VFTableIndex(0), Shadowed(false),
2571 UsesExtraSlot(false) {}
2572 };
2573
2574 typedef llvm::DenseMap<const CXXMethodDecl *, MethodInfo> MethodInfoMapTy;
2575
2576 /// MethodInfoMap - The information for all methods in the vftable we're
2577 /// currently building.
2578 MethodInfoMapTy MethodInfoMap;
2579
2580 typedef llvm::DenseMap<uint64_t, ThunkInfo> VTableThunksMapTy;
2581
2582 /// VTableThunks - The thunks by vftable index in the vftable currently being
2583 /// built.
2584 VTableThunksMapTy VTableThunks;
2585
2586 typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy;
2587 typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy;
2588
2589 /// Thunks - A map that contains all the thunks needed for all methods in the
2590 /// most derived class for which the vftable is currently being built.
2591 ThunksMapTy Thunks;
2592
2593 /// AddThunk - Add a thunk for the given method.
2594 void AddThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk) {
2595 SmallVector<ThunkInfo, 1> &ThunksVector = Thunks[MD];
2596
2597 // Check if we have this thunk already.
2598 if (llvm::is_contained(ThunksVector, Thunk))
2599 return;
2600
2601 ThunksVector.push_back(Thunk);
2602 }
2603
2604 /// ComputeThisOffset - Returns the 'this' argument offset for the given
2605 /// method, relative to the beginning of the MostDerivedClass.
2606 CharUnits ComputeThisOffset(FinalOverriders::OverriderInfo Overrider);
2607
2608 void CalculateVtordispAdjustment(FinalOverriders::OverriderInfo Overrider,
2609 CharUnits ThisOffset, ThisAdjustment &TA);
2610
2611 /// AddMethod - Add a single virtual member function to the vftable
2612 /// components vector.
2613 void AddMethod(const CXXMethodDecl *MD, ThunkInfo TI) {
2614 if (!TI.isEmpty()) {
2615 VTableThunks[Components.size()] = TI;
2616 AddThunk(MD, TI);
2617 }
2618 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
2619 assert(TI.Return.isEmpty() &&
2620 "Destructor can't have return adjustment!");
2621 Components.push_back(VTableComponent::MakeDeletingDtor(DD));
2622 } else {
2623 Components.push_back(VTableComponent::MakeFunction(MD));
2624 }
2625 }
2626
2627 /// AddMethods - Add the methods of this base subobject and the relevant
2628 /// subbases to the vftable we're currently laying out.
2629 void AddMethods(BaseSubobject Base, unsigned BaseDepth,
2630 const CXXRecordDecl *LastVBase,
2631 BasesSetVectorTy &VisitedBases);
2632
2633 void LayoutVFTable() {
2634 // RTTI data goes before all other entries.
2635 if (HasRTTIComponent)
2636 Components.push_back(VTableComponent::MakeRTTI(MostDerivedClass));
2637
2638 BasesSetVectorTy VisitedBases;
2639 AddMethods(BaseSubobject(MostDerivedClass, CharUnits::Zero()), 0, nullptr,
2640 VisitedBases);
2641 // Note that it is possible for the vftable to contain only an RTTI
2642 // pointer, if all virtual functions are constewval.
2643 assert(!Components.empty() && "vftable can't be empty");
2644
2645 assert(MethodVFTableLocations.empty());
2646 for (const auto &I : MethodInfoMap) {
2647 const CXXMethodDecl *MD = I.first;
2648 const MethodInfo &MI = I.second;
2649 assert(MD == MD->getCanonicalDecl());
2650
2651 // Skip the methods that the MostDerivedClass didn't override
2652 // and the entries shadowed by return adjusting thunks.
2653 if (MD->getParent() != MostDerivedClass || MI.Shadowed)
2654 continue;
2655 MethodVFTableLocation Loc(MI.VBTableIndex, WhichVFPtr.getVBaseWithVPtr(),
2656 WhichVFPtr.NonVirtualOffset, MI.VFTableIndex);
2657 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
2658 MethodVFTableLocations[GlobalDecl(DD, Dtor_Deleting)] = Loc;
2659 } else {
2660 MethodVFTableLocations[MD] = Loc;
2661 }
2662 }
2663 }
2664
2665public:
2666 VFTableBuilder(MicrosoftVTableContext &VTables,
2667 const CXXRecordDecl *MostDerivedClass, const VPtrInfo &Which)
2668 : VTables(VTables),
2669 Context(MostDerivedClass->getASTContext()),
2670 MostDerivedClass(MostDerivedClass),
2671 MostDerivedClassLayout(Context.getASTRecordLayout(MostDerivedClass)),
2672 WhichVFPtr(Which),
2673 Overriders(MostDerivedClass, CharUnits(), MostDerivedClass) {
2674 // Provide the RTTI component if RTTIData is enabled. If the vftable would
2675 // be available externally, we should not provide the RTTI componenent. It
2676 // is currently impossible to get available externally vftables with either
2677 // dllimport or extern template instantiations, but eventually we may add a
2678 // flag to support additional devirtualization that needs this.
2679 if (Context.getLangOpts().RTTIData)
2680 HasRTTIComponent = true;
2681
2682 LayoutVFTable();
2683
2684 if (Context.getLangOpts().DumpVTableLayouts)
2685 dumpLayout(llvm::outs());
2686 }
2687
2688 uint64_t getNumThunks() const { return Thunks.size(); }
2689
2690 ThunksMapTy::const_iterator thunks_begin() const { return Thunks.begin(); }
2691
2692 ThunksMapTy::const_iterator thunks_end() const { return Thunks.end(); }
2693
2694 method_locations_range vtable_locations() const {
2695 return method_locations_range(MethodVFTableLocations.begin(),
2696 MethodVFTableLocations.end());
2697 }
2698
2699 ArrayRef<VTableComponent> vtable_components() const { return Components; }
2700
2701 VTableThunksMapTy::const_iterator vtable_thunks_begin() const {
2702 return VTableThunks.begin();
2703 }
2704
2705 VTableThunksMapTy::const_iterator vtable_thunks_end() const {
2706 return VTableThunks.end();
2707 }
2708
2709 void dumpLayout(raw_ostream &);
2710};
2711
2712} // end namespace
2713
2714// Let's study one class hierarchy as an example:
2715// struct A {
2716// virtual void f();
2717// int x;
2718// };
2719//
2720// struct B : virtual A {
2721// virtual void f();
2722// };
2723//
2724// Record layouts:
2725// struct A:
2726// 0 | (A vftable pointer)
2727// 4 | int x
2728//
2729// struct B:
2730// 0 | (B vbtable pointer)
2731// 4 | struct A (virtual base)
2732// 4 | (A vftable pointer)
2733// 8 | int x
2734//
2735// Let's assume we have a pointer to the A part of an object of dynamic type B:
2736// B b;
2737// A *a = (A*)&b;
2738// a->f();
2739//
2740// In this hierarchy, f() belongs to the vftable of A, so B::f() expects
2741// "this" parameter to point at the A subobject, which is B+4.
2742// In the B::f() prologue, it adjusts "this" back to B by subtracting 4,
2743// performed as a *static* adjustment.
2744//
2745// Interesting thing happens when we alter the relative placement of A and B
2746// subobjects in a class:
2747// struct C : virtual B { };
2748//
2749// C c;
2750// A *a = (A*)&c;
2751// a->f();
2752//
2753// Respective record layout is:
2754// 0 | (C vbtable pointer)
2755// 4 | struct A (virtual base)
2756// 4 | (A vftable pointer)
2757// 8 | int x
2758// 12 | struct B (virtual base)
2759// 12 | (B vbtable pointer)
2760//
2761// The final overrider of f() in class C is still B::f(), so B+4 should be
2762// passed as "this" to that code. However, "a" points at B-8, so the respective
2763// vftable entry should hold a thunk that adds 12 to the "this" argument before
2764// performing a tail call to B::f().
2765//
2766// With this example in mind, we can now calculate the 'this' argument offset
2767// for the given method, relative to the beginning of the MostDerivedClass.
2769VFTableBuilder::ComputeThisOffset(FinalOverriders::OverriderInfo Overrider) {
2770 BasesSetVectorTy Bases;
2771
2772 {
2773 // Find the set of least derived bases that define the given method.
2774 OverriddenMethodsSetTy VisitedOverriddenMethods;
2775 auto InitialOverriddenDefinitionCollector = [&](
2776 const CXXMethodDecl *OverriddenMD) {
2777 if (OverriddenMD->size_overridden_methods() == 0)
2778 Bases.insert(OverriddenMD->getParent());
2779 // Don't recurse on this method if we've already collected it.
2780 return VisitedOverriddenMethods.insert(OverriddenMD).second;
2781 };
2782 visitAllOverriddenMethods(Overrider.Method,
2783 InitialOverriddenDefinitionCollector);
2784 }
2785
2786 // If there are no overrides then 'this' is located
2787 // in the base that defines the method.
2788 if (Bases.size() == 0)
2789 return Overrider.Offset;
2790
2791 CXXBasePaths Paths;
2792 Overrider.Method->getParent()->lookupInBases(
2793 [&Bases](const CXXBaseSpecifier *Specifier, CXXBasePath &) {
2794 return Bases.count(Specifier->getType()->getAsCXXRecordDecl());
2795 },
2796 Paths);
2797
2798 // This will hold the smallest this offset among overridees of MD.
2799 // This implies that an offset of a non-virtual base will dominate an offset
2800 // of a virtual base to potentially reduce the number of thunks required
2801 // in the derived classes that inherit this method.
2802 CharUnits Ret;
2803 bool First = true;
2804
2805 const ASTRecordLayout &OverriderRDLayout =
2806 Context.getASTRecordLayout(Overrider.Method->getParent());
2807 for (const CXXBasePath &Path : Paths) {
2808 CharUnits ThisOffset = Overrider.Offset;
2809 CharUnits LastVBaseOffset;
2810
2811 // For each path from the overrider to the parents of the overridden
2812 // methods, traverse the path, calculating the this offset in the most
2813 // derived class.
2814 for (const CXXBasePathElement &Element : Path) {
2815 QualType CurTy = Element.Base->getType();
2816 const CXXRecordDecl *PrevRD = Element.Class,
2817 *CurRD = CurTy->getAsCXXRecordDecl();
2818 const ASTRecordLayout &Layout = Context.getASTRecordLayout(PrevRD);
2819
2820 if (Element.Base->isVirtual()) {
2821 // The interesting things begin when you have virtual inheritance.
2822 // The final overrider will use a static adjustment equal to the offset
2823 // of the vbase in the final overrider class.
2824 // For example, if the final overrider is in a vbase B of the most
2825 // derived class and it overrides a method of the B's own vbase A,
2826 // it uses A* as "this". In its prologue, it can cast A* to B* with
2827 // a static offset. This offset is used regardless of the actual
2828 // offset of A from B in the most derived class, requiring an
2829 // this-adjusting thunk in the vftable if A and B are laid out
2830 // differently in the most derived class.
2831 LastVBaseOffset = ThisOffset =
2832 Overrider.Offset + OverriderRDLayout.getVBaseClassOffset(CurRD);
2833 } else {
2834 ThisOffset += Layout.getBaseClassOffset(CurRD);
2835 }
2836 }
2837
2838 if (isa<CXXDestructorDecl>(Overrider.Method)) {
2839 if (LastVBaseOffset.isZero()) {
2840 // If a "Base" class has at least one non-virtual base with a virtual
2841 // destructor, the "Base" virtual destructor will take the address
2842 // of the "Base" subobject as the "this" argument.
2843 ThisOffset = Overrider.Offset;
2844 } else {
2845 // A virtual destructor of a virtual base takes the address of the
2846 // virtual base subobject as the "this" argument.
2847 ThisOffset = LastVBaseOffset;
2848 }
2849 }
2850
2851 if (Ret > ThisOffset || First) {
2852 First = false;
2853 Ret = ThisOffset;
2854 }
2855 }
2856
2857 assert(!First && "Method not found in the given subobject?");
2858 return Ret;
2859}
2860
2861// Things are getting even more complex when the "this" adjustment has to
2862// use a dynamic offset instead of a static one, or even two dynamic offsets.
2863// This is sometimes required when a virtual call happens in the middle of
2864// a non-most-derived class construction or destruction.
2865//
2866// Let's take a look at the following example:
2867// struct A {
2868// virtual void f();
2869// };
2870//
2871// void foo(A *a) { a->f(); } // Knows nothing about siblings of A.
2872//
2873// struct B : virtual A {
2874// virtual void f();
2875// B() {
2876// foo(this);
2877// }
2878// };
2879//
2880// struct C : virtual B {
2881// virtual void f();
2882// };
2883//
2884// Record layouts for these classes are:
2885// struct A
2886// 0 | (A vftable pointer)
2887//
2888// struct B
2889// 0 | (B vbtable pointer)
2890// 4 | (vtordisp for vbase A)
2891// 8 | struct A (virtual base)
2892// 8 | (A vftable pointer)
2893//
2894// struct C
2895// 0 | (C vbtable pointer)
2896// 4 | (vtordisp for vbase A)
2897// 8 | struct A (virtual base) // A precedes B!
2898// 8 | (A vftable pointer)
2899// 12 | struct B (virtual base)
2900// 12 | (B vbtable pointer)
2901//
2902// When one creates an object of type C, the C constructor:
2903// - initializes all the vbptrs, then
2904// - calls the A subobject constructor
2905// (initializes A's vfptr with an address of A vftable), then
2906// - calls the B subobject constructor
2907// (initializes A's vfptr with an address of B vftable and vtordisp for A),
2908// that in turn calls foo(), then
2909// - initializes A's vfptr with an address of C vftable and zeroes out the
2910// vtordisp
2911// FIXME: if a structor knows it belongs to MDC, why doesn't it use a vftable
2912// without vtordisp thunks?
2913// FIXME: how are vtordisp handled in the presence of nooverride/final?
2914//
2915// When foo() is called, an object with a layout of class C has a vftable
2916// referencing B::f() that assumes a B layout, so the "this" adjustments are
2917// incorrect, unless an extra adjustment is done. This adjustment is called
2918// "vtordisp adjustment". Vtordisp basically holds the difference between the
2919// actual location of a vbase in the layout class and the location assumed by
2920// the vftable of the class being constructed/destructed. Vtordisp is only
2921// needed if "this" escapes a
2922// structor (or we can't prove otherwise).
2923// [i.e. vtordisp is a dynamic adjustment for a static adjustment, which is an
2924// estimation of a dynamic adjustment]
2925//
2926// foo() gets a pointer to the A vbase and doesn't know anything about B or C,
2927// so it just passes that pointer as "this" in a virtual call.
2928// If there was no vtordisp, that would just dispatch to B::f().
2929// However, B::f() assumes B+8 is passed as "this",
2930// yet the pointer foo() passes along is B-4 (i.e. C+8).
2931// An extra adjustment is needed, so we emit a thunk into the B vftable.
2932// This vtordisp thunk subtracts the value of vtordisp
2933// from the "this" argument (-12) before making a tailcall to B::f().
2934//
2935// Let's consider an even more complex example:
2936// struct D : virtual B, virtual C {
2937// D() {
2938// foo(this);
2939// }
2940// };
2941//
2942// struct D
2943// 0 | (D vbtable pointer)
2944// 4 | (vtordisp for vbase A)
2945// 8 | struct A (virtual base) // A precedes both B and C!
2946// 8 | (A vftable pointer)
2947// 12 | struct B (virtual base) // B precedes C!
2948// 12 | (B vbtable pointer)
2949// 16 | struct C (virtual base)
2950// 16 | (C vbtable pointer)
2951//
2952// When D::D() calls foo(), we find ourselves in a thunk that should tailcall
2953// to C::f(), which assumes C+8 as its "this" parameter. This time, foo()
2954// passes along A, which is C-8. The A vtordisp holds
2955// "D.vbptr[index_of_A] - offset_of_A_in_D"
2956// and we statically know offset_of_A_in_D, so can get a pointer to D.
2957// When we know it, we can make an extra vbtable lookup to locate the C vbase
2958// and one extra static adjustment to calculate the expected value of C+8.
2959void VFTableBuilder::CalculateVtordispAdjustment(
2960 FinalOverriders::OverriderInfo Overrider, CharUnits ThisOffset,
2961 ThisAdjustment &TA) {
2962 const ASTRecordLayout::VBaseOffsetsMapTy &VBaseMap =
2963 MostDerivedClassLayout.getVBaseOffsetsMap();
2964 const ASTRecordLayout::VBaseOffsetsMapTy::const_iterator &VBaseMapEntry =
2965 VBaseMap.find(WhichVFPtr.getVBaseWithVPtr());
2966 assert(VBaseMapEntry != VBaseMap.end());
2967
2968 // If there's no vtordisp or the final overrider is defined in the same vbase
2969 // as the initial declaration, we don't need any vtordisp adjustment.
2970 if (!VBaseMapEntry->second.hasVtorDisp() ||
2971 Overrider.VirtualBase == WhichVFPtr.getVBaseWithVPtr())
2972 return;
2973
2974 // OK, now we know we need to use a vtordisp thunk.
2975 // The implicit vtordisp field is located right before the vbase.
2976 CharUnits OffsetOfVBaseWithVFPtr = VBaseMapEntry->second.VBaseOffset;
2978 (OffsetOfVBaseWithVFPtr - WhichVFPtr.FullOffsetInMDC).getQuantity() - 4;
2979
2980 // A simple vtordisp thunk will suffice if the final overrider is defined
2981 // in either the most derived class or its non-virtual base.
2982 if (Overrider.Method->getParent() == MostDerivedClass ||
2983 !Overrider.VirtualBase)
2984 return;
2985
2986 // Otherwise, we need to do use the dynamic offset of the final overrider
2987 // in order to get "this" adjustment right.
2989 (OffsetOfVBaseWithVFPtr + WhichVFPtr.NonVirtualOffset -
2990 MostDerivedClassLayout.getVBPtrOffset()).getQuantity();
2992 Context.getTypeSizeInChars(Context.IntTy).getQuantity() *
2993 VTables.getVBTableIndex(MostDerivedClass, Overrider.VirtualBase);
2994
2995 TA.NonVirtual = (ThisOffset - Overrider.Offset).getQuantity();
2996}
2997
2999 const CXXRecordDecl *RD,
3001 // Put the virtual methods into VirtualMethods in the proper order:
3002 // 1) Group overloads by declaration name. New groups are added to the
3003 // vftable in the order of their first declarations in this class
3004 // (including overrides, non-virtual methods and any other named decl that
3005 // might be nested within the class).
3006 // 2) In each group, new overloads appear in the reverse order of declaration.
3007 typedef SmallVector<const CXXMethodDecl *, 1> MethodGroup;
3009 typedef llvm::DenseMap<DeclarationName, unsigned> VisitedGroupIndicesTy;
3010 VisitedGroupIndicesTy VisitedGroupIndices;
3011 for (const auto *D : RD->decls()) {
3012 const auto *ND = dyn_cast<NamedDecl>(D);
3013 if (!ND)
3014 continue;
3015 VisitedGroupIndicesTy::iterator J;
3016 bool Inserted;
3017 std::tie(J, Inserted) = VisitedGroupIndices.insert(
3018 std::make_pair(ND->getDeclName(), Groups.size()));
3019 if (Inserted)
3020 Groups.push_back(MethodGroup());
3021 if (const auto *MD = dyn_cast<CXXMethodDecl>(ND))
3023 Groups[J->second].push_back(MD->getCanonicalDecl());
3024 }
3025
3026 for (const MethodGroup &Group : Groups)
3027 VirtualMethods.append(Group.rbegin(), Group.rend());
3028}
3029
3030static bool isDirectVBase(const CXXRecordDecl *Base, const CXXRecordDecl *RD) {
3031 for (const auto &B : RD->bases()) {
3032 if (B.isVirtual() && B.getType()->getAsCXXRecordDecl() == Base)
3033 return true;
3034 }
3035 return false;
3036}
3037
3038void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth,
3039 const CXXRecordDecl *LastVBase,
3040 BasesSetVectorTy &VisitedBases) {
3041 const CXXRecordDecl *RD = Base.getBase();
3042 if (!RD->isPolymorphic())
3043 return;
3044
3045 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
3046
3047 // See if this class expands a vftable of the base we look at, which is either
3048 // the one defined by the vfptr base path or the primary base of the current
3049 // class.
3050 const CXXRecordDecl *NextBase = nullptr, *NextLastVBase = LastVBase;
3051 CharUnits NextBaseOffset;
3052 if (BaseDepth < WhichVFPtr.PathToIntroducingObject.size()) {
3053 NextBase = WhichVFPtr.PathToIntroducingObject[BaseDepth];
3054 if (isDirectVBase(NextBase, RD)) {
3055 NextLastVBase = NextBase;
3056 NextBaseOffset = MostDerivedClassLayout.getVBaseClassOffset(NextBase);
3057 } else {
3058 NextBaseOffset =
3059 Base.getBaseOffset() + Layout.getBaseClassOffset(NextBase);
3060 }
3061 } else if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) {
3062 assert(!Layout.isPrimaryBaseVirtual() &&
3063 "No primary virtual bases in this ABI");
3064 NextBase = PrimaryBase;
3065 NextBaseOffset = Base.getBaseOffset();
3066 }
3067
3068 if (NextBase) {
3069 AddMethods(BaseSubobject(NextBase, NextBaseOffset), BaseDepth + 1,
3070 NextLastVBase, VisitedBases);
3071 if (!VisitedBases.insert(NextBase))
3072 llvm_unreachable("Found a duplicate primary base!");
3073 }
3074
3076 // Put virtual methods in the proper order.
3077 GroupNewVirtualOverloads(RD, VirtualMethods);
3078
3079 // Now go through all virtual member functions and add them to the current
3080 // vftable. This is done by
3081 // - replacing overridden methods in their existing slots, as long as they
3082 // don't require return adjustment; calculating This adjustment if needed.
3083 // - adding new slots for methods of the current base not present in any
3084 // sub-bases;
3085 // - adding new slots for methods that require Return adjustment.
3086 // We keep track of the methods visited in the sub-bases in MethodInfoMap.
3087 for (const CXXMethodDecl *MD : VirtualMethods) {
3088 FinalOverriders::OverriderInfo FinalOverrider =
3089 Overriders.getOverrider(MD, Base.getBaseOffset());
3090 const CXXMethodDecl *FinalOverriderMD = FinalOverrider.Method;
3091 const CXXMethodDecl *OverriddenMD =
3092 FindNearestOverriddenMethod(MD, VisitedBases);
3093
3094 ThisAdjustment ThisAdjustmentOffset;
3095 bool ReturnAdjustingThunk = false, ForceReturnAdjustmentMangling = false;
3096 CharUnits ThisOffset = ComputeThisOffset(FinalOverrider);
3097 ThisAdjustmentOffset.NonVirtual =
3098 (ThisOffset - WhichVFPtr.FullOffsetInMDC).getQuantity();
3099 if ((OverriddenMD || FinalOverriderMD != MD) &&
3100 WhichVFPtr.getVBaseWithVPtr())
3101 CalculateVtordispAdjustment(FinalOverrider, ThisOffset,
3102 ThisAdjustmentOffset);
3103
3104 unsigned VBIndex =
3105 LastVBase ? VTables.getVBTableIndex(MostDerivedClass, LastVBase) : 0;
3106
3107 if (OverriddenMD) {
3108 // If MD overrides anything in this vftable, we need to update the
3109 // entries.
3110 MethodInfoMapTy::iterator OverriddenMDIterator =
3111 MethodInfoMap.find(OverriddenMD);
3112
3113 // If the overridden method went to a different vftable, skip it.
3114 if (OverriddenMDIterator == MethodInfoMap.end())
3115 continue;
3116
3117 MethodInfo &OverriddenMethodInfo = OverriddenMDIterator->second;
3118
3119 VBIndex = OverriddenMethodInfo.VBTableIndex;
3120
3121 // Let's check if the overrider requires any return adjustments.
3122 // We must create a new slot if the MD's return type is not trivially
3123 // convertible to the OverriddenMD's one.
3124 // Once a chain of method overrides adds a return adjusting vftable slot,
3125 // all subsequent overrides will also use an extra method slot.
3126 ReturnAdjustingThunk = !ComputeReturnAdjustmentBaseOffset(
3127 Context, MD, OverriddenMD).isEmpty() ||
3128 OverriddenMethodInfo.UsesExtraSlot;
3129
3130 if (!ReturnAdjustingThunk) {
3131 // No return adjustment needed - just replace the overridden method info
3132 // with the current info.
3133 MethodInfo MI(VBIndex, OverriddenMethodInfo.VFTableIndex);
3134 MethodInfoMap.erase(OverriddenMDIterator);
3135
3136 assert(!MethodInfoMap.count(MD) &&
3137 "Should not have method info for this method yet!");
3138 MethodInfoMap.insert(std::make_pair(MD, MI));
3139 continue;
3140 }
3141
3142 // In case we need a return adjustment, we'll add a new slot for
3143 // the overrider. Mark the overridden method as shadowed by the new slot.
3144 OverriddenMethodInfo.Shadowed = true;
3145
3146 // Force a special name mangling for a return-adjusting thunk
3147 // unless the method is the final overrider without this adjustment.
3148 ForceReturnAdjustmentMangling =
3149 !(MD == FinalOverriderMD && ThisAdjustmentOffset.isEmpty());
3150 } else if (Base.getBaseOffset() != WhichVFPtr.FullOffsetInMDC ||
3152 // Skip methods that don't belong to the vftable of the current class,
3153 // e.g. each method that wasn't seen in any of the visited sub-bases
3154 // but overrides multiple methods of other sub-bases.
3155 continue;
3156 }
3157
3158 // If we got here, MD is a method not seen in any of the sub-bases or
3159 // it requires return adjustment. Insert the method info for this method.
3160 MethodInfo MI(VBIndex,
3161 HasRTTIComponent ? Components.size() - 1 : Components.size(),
3162 ReturnAdjustingThunk);
3163
3164 assert(!MethodInfoMap.count(MD) &&
3165 "Should not have method info for this method yet!");
3166 MethodInfoMap.insert(std::make_pair(MD, MI));
3167
3168 // Check if this overrider needs a return adjustment.
3169 // We don't want to do this for pure virtual member functions.
3170 BaseOffset ReturnAdjustmentOffset;
3172 if (!FinalOverriderMD->isPureVirtual()) {
3173 ReturnAdjustmentOffset =
3174 ComputeReturnAdjustmentBaseOffset(Context, FinalOverriderMD, MD);
3175 }
3176 if (!ReturnAdjustmentOffset.isEmpty()) {
3177 ForceReturnAdjustmentMangling = true;
3179 ReturnAdjustmentOffset.NonVirtualOffset.getQuantity();
3180 if (ReturnAdjustmentOffset.VirtualBase) {
3181 const ASTRecordLayout &DerivedLayout =
3182 Context.getASTRecordLayout(ReturnAdjustmentOffset.DerivedClass);
3184 DerivedLayout.getVBPtrOffset().getQuantity();
3186 VTables.getVBTableIndex(ReturnAdjustmentOffset.DerivedClass,
3187 ReturnAdjustmentOffset.VirtualBase);
3188 }
3189 }
3190 auto ThisType = (OverriddenMD ? OverriddenMD : MD)->getThisType().getTypePtr();
3191 AddMethod(FinalOverriderMD,
3192 ThunkInfo(ThisAdjustmentOffset, ReturnAdjustment, ThisType,
3193 ForceReturnAdjustmentMangling ? MD : nullptr));
3194 }
3195}
3196
3197static void PrintBasePath(const VPtrInfo::BasePath &Path, raw_ostream &Out) {
3198 for (const CXXRecordDecl *Elem : llvm::reverse(Path)) {
3199 Out << "'";
3200 Elem->printQualifiedName(Out);
3201 Out << "' in ";
3202 }
3203}
3204
3205static void dumpMicrosoftThunkAdjustment(const ThunkInfo &TI, raw_ostream &Out,
3206 bool ContinueFirstLine) {
3207 const ReturnAdjustment &R = TI.Return;
3208 bool Multiline = false;
3209 const char *LinePrefix = "\n ";
3210 if (!R.isEmpty() || TI.Method) {
3211 if (!ContinueFirstLine)
3212 Out << LinePrefix;
3213 Out << "[return adjustment (to type '"
3214 << TI.Method->getReturnType().getCanonicalType() << "'): ";
3216 Out << "vbptr at offset " << R.Virtual.Microsoft.VBPtrOffset << ", ";
3218 Out << "vbase #" << R.Virtual.Microsoft.VBIndex << ", ";
3219 Out << R.NonVirtual << " non-virtual]";
3220 Multiline = true;
3221 }
3222
3223 const ThisAdjustment &T = TI.This;
3224 if (!T.isEmpty()) {
3225 if (Multiline || !ContinueFirstLine)
3226 Out << LinePrefix;
3227 Out << "[this adjustment: ";
3228 if (!TI.This.Virtual.isEmpty()) {
3229 assert(T.Virtual.Microsoft.VtordispOffset < 0);
3230 Out << "vtordisp at " << T.Virtual.Microsoft.VtordispOffset << ", ";
3231 if (T.Virtual.Microsoft.VBPtrOffset) {
3232 Out << "vbptr at " << T.Virtual.Microsoft.VBPtrOffset
3233 << " to the left,";
3234 assert(T.Virtual.Microsoft.VBOffsetOffset > 0);
3235 Out << LinePrefix << " vboffset at "
3236 << T.Virtual.Microsoft.VBOffsetOffset << " in the vbtable, ";
3237 }
3238 }
3239 Out << T.NonVirtual << " non-virtual]";
3240 }
3241}
3242
3243void VFTableBuilder::dumpLayout(raw_ostream &Out) {
3244 Out << "VFTable for ";
3245 PrintBasePath(WhichVFPtr.PathToIntroducingObject, Out);
3246 Out << "'";
3247 MostDerivedClass->printQualifiedName(Out);
3248 Out << "' (" << Components.size()
3249 << (Components.size() == 1 ? " entry" : " entries") << ").\n";
3250
3251 for (unsigned I = 0, E = Components.size(); I != E; ++I) {
3252 Out << llvm::format("%4d | ", I);
3253
3254 const VTableComponent &Component = Components[I];
3255
3256 // Dump the component.
3257 switch (Component.getKind()) {
3259 Component.getRTTIDecl()->printQualifiedName(Out);
3260 Out << " RTTI";
3261 break;
3262
3264 const CXXMethodDecl *MD = Component.getFunctionDecl();
3265
3266 // FIXME: Figure out how to print the real thunk type, since they can
3267 // differ in the return type.
3268 std::string Str = PredefinedExpr::ComputeName(
3270 Out << Str;
3271 if (MD->isPureVirtual())
3272 Out << " [pure]";
3273
3274 if (MD->isDeleted())
3275 Out << " [deleted]";
3276
3277 ThunkInfo Thunk = VTableThunks.lookup(I);
3278 if (!Thunk.isEmpty())
3279 dumpMicrosoftThunkAdjustment(Thunk, Out, /*ContinueFirstLine=*/false);
3280
3281 break;
3282 }
3283
3285 const CXXDestructorDecl *DD = Component.getDestructorDecl();
3286
3287 DD->printQualifiedName(Out);
3288 Out << "() [scalar deleting]";
3289
3290 if (DD->isPureVirtual())
3291 Out << " [pure]";
3292
3293 ThunkInfo Thunk = VTableThunks.lookup(I);
3294 if (!Thunk.isEmpty()) {
3295 assert(Thunk.Return.isEmpty() &&
3296 "No return adjustment needed for destructors!");
3297 dumpMicrosoftThunkAdjustment(Thunk, Out, /*ContinueFirstLine=*/false);
3298 }
3299
3300 break;
3301 }
3302
3303 default:
3304 DiagnosticsEngine &Diags = Context.getDiagnostics();
3305 unsigned DiagID = Diags.getCustomDiagID(
3307 "Unexpected vftable component type %0 for component number %1");
3308 Diags.Report(MostDerivedClass->getLocation(), DiagID)
3309 << I << Component.getKind();
3310 }
3311
3312 Out << '\n';
3313 }
3314
3315 Out << '\n';
3316
3317 if (!Thunks.empty()) {
3318 // We store the method names in a map to get a stable order.
3319 std::map<std::string, const CXXMethodDecl *> MethodNamesAndDecls;
3320
3321 for (const auto &I : Thunks) {
3322 const CXXMethodDecl *MD = I.first;
3323 std::string MethodName = PredefinedExpr::ComputeName(
3325
3326 MethodNamesAndDecls.insert(std::make_pair(MethodName, MD));
3327 }
3328
3329 for (const auto &MethodNameAndDecl : MethodNamesAndDecls) {
3330 const std::string &MethodName = MethodNameAndDecl.first;
3331 const CXXMethodDecl *MD = MethodNameAndDecl.second;
3332
3333 ThunkInfoVectorTy ThunksVector = Thunks[MD];
3334 llvm::stable_sort(ThunksVector, [](const ThunkInfo &LHS,
3335 const ThunkInfo &RHS) {
3336 // Keep different thunks with the same adjustments in the order they
3337 // were put into the vector.
3338 return std::tie(LHS.This, LHS.Return) < std::tie(RHS.This, RHS.Return);
3339 });
3340
3341 Out << "Thunks for '" << MethodName << "' (" << ThunksVector.size();
3342 Out << (ThunksVector.size() == 1 ? " entry" : " entries") << ").\n";
3343
3344 for (unsigned I = 0, E = ThunksVector.size(); I != E; ++I) {
3345 const ThunkInfo &Thunk = ThunksVector[I];
3346
3347 Out << llvm::format("%4d | ", I);
3348 dumpMicrosoftThunkAdjustment(Thunk, Out, /*ContinueFirstLine=*/true);
3349 Out << '\n';
3350 }
3351
3352 Out << '\n';
3353 }
3354 }
3355
3356 Out.flush();
3357}
3358
3361 for (const CXXRecordDecl *Decl : B) {
3362 if (A.count(Decl))
3363 return true;
3364 }
3365 return false;
3366}
3367
3368static bool rebucketPaths(VPtrInfoVector &Paths);
3369
3370/// Produces MSVC-compatible vbtable data. The symbols produced by this
3371/// algorithm match those produced by MSVC 2012 and newer, which is different
3372/// from MSVC 2010.
3373///
3374/// MSVC 2012 appears to minimize the vbtable names using the following
3375/// algorithm. First, walk the class hierarchy in the usual order, depth first,
3376/// left to right, to find all of the subobjects which contain a vbptr field.
3377/// Visiting each class node yields a list of inheritance paths to vbptrs. Each
3378/// record with a vbptr creates an initially empty path.
3379///
3380/// To combine paths from child nodes, the paths are compared to check for
3381/// ambiguity. Paths are "ambiguous" if multiple paths have the same set of
3382/// components in the same order. Each group of ambiguous paths is extended by
3383/// appending the class of the base from which it came. If the current class
3384/// node produced an ambiguous path, its path is extended with the current class.
3385/// After extending paths, MSVC again checks for ambiguity, and extends any
3386/// ambiguous path which wasn't already extended. Because each node yields an
3387/// unambiguous set of paths, MSVC doesn't need to extend any path more than once
3388/// to produce an unambiguous set of paths.
3389///
3390/// TODO: Presumably vftables use the same algorithm.
3391void MicrosoftVTableContext::computeVTablePaths(bool ForVBTables,
3392 const CXXRecordDecl *RD,
3393 VPtrInfoVector &Paths) {
3394 assert(Paths.empty());
3395 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
3396
3397 // Base case: this subobject has its own vptr.
3398 if (ForVBTables ? Layout.hasOwnVBPtr() : Layout.hasOwnVFPtr())
3399 Paths.push_back(std::make_unique<VPtrInfo>(RD));
3400
3401 // Recursive case: get all the vbtables from our bases and remove anything
3402 // that shares a virtual base.
3404 for (const auto &B : RD->bases()) {
3405 const CXXRecordDecl *Base = B.getType()->getAsCXXRecordDecl();
3406 if (B.isVirtual() && VBasesSeen.count(Base))
3407 continue;
3408
3409 if (!Base->isDynamicClass())
3410 continue;
3411
3412 const VPtrInfoVector &BasePaths =
3413 ForVBTables ? enumerateVBTables(Base) : getVFPtrOffsets(Base);
3414
3415 for (const std::unique_ptr<VPtrInfo> &BaseInfo : BasePaths) {
3416 // Don't include the path if it goes through a virtual base that we've
3417 // already included.
3418 if (setsIntersect(VBasesSeen, BaseInfo->ContainingVBases))
3419 continue;
3420
3421 // Copy the path and adjust it as necessary.
3422 auto P = std::make_unique<VPtrInfo>(*BaseInfo);
3423
3424 // We mangle Base into the path if the path would've been ambiguous and it
3425 // wasn't already extended with Base.
3426 if (P->MangledPath.empty() || P->MangledPath.back() != Base)
3427 P->NextBaseToMangle = Base;
3428
3429 // Keep track of which vtable the derived class is going to extend with
3430 // new methods or bases. We append to either the vftable of our primary
3431 // base, or the first non-virtual base that has a vbtable.
3432 if (P->ObjectWithVPtr == Base &&
3433 Base == (ForVBTables ? Layout.getBaseSharingVBPtr()
3434 : Layout.getPrimaryBase()))
3435 P->ObjectWithVPtr = RD;
3436
3437 // Keep track of the full adjustment from the MDC to this vtable. The
3438 // adjustment is captured by an optional vbase and a non-virtual offset.
3439 if (B.isVirtual())
3440 P->ContainingVBases.push_back(Base);
3441 else if (P->ContainingVBases.empty())
3442 P->NonVirtualOffset += Layout.getBaseClassOffset(Base);
3443
3444 // Update the full offset in the MDC.
3445 P->FullOffsetInMDC = P->NonVirtualOffset;
3446 if (const CXXRecordDecl *VB = P->getVBaseWithVPtr())
3447 P->FullOffsetInMDC += Layout.getVBaseClassOffset(VB);
3448
3449 Paths.push_back(std::move(P));
3450 }
3451
3452 if (B.isVirtual())
3453 VBasesSeen.insert(Base);
3454
3455 // After visiting any direct base, we've transitively visited all of its
3456 // morally virtual bases.
3457 for (const auto &VB : Base->vbases())
3458 VBasesSeen.insert(VB.getType()->getAsCXXRecordDecl());
3459 }
3460
3461 // Sort the paths into buckets, and if any of them are ambiguous, extend all
3462 // paths in ambiguous buckets.
3463 bool Changed = true;
3464 while (Changed)
3465 Changed = rebucketPaths(Paths);
3466}
3467
3468static bool extendPath(VPtrInfo &P) {
3469 if (P.NextBaseToMangle) {
3470 P.MangledPath.push_back(P.NextBaseToMangle);
3471 P.NextBaseToMangle = nullptr;// Prevent the path from being extended twice.
3472 return true;
3473 }
3474 return false;
3475}
3476
3477static bool rebucketPaths(VPtrInfoVector &Paths) {
3478 // What we're essentially doing here is bucketing together ambiguous paths.
3479 // Any bucket with more than one path in it gets extended by NextBase, which
3480 // is usually the direct base of the inherited the vbptr. This code uses a
3481 // sorted vector to implement a multiset to form the buckets. Note that the
3482 // ordering is based on pointers, but it doesn't change our output order. The
3483 // current algorithm is designed to match MSVC 2012's names.
3485 llvm::make_pointee_range(Paths));
3486 llvm::sort(PathsSorted, [](const VPtrInfo &LHS, const VPtrInfo &RHS) {
3487 return LHS.MangledPath < RHS.MangledPath;
3488 });
3489 bool Changed = false;
3490 for (size_t I = 0, E = PathsSorted.size(); I != E;) {
3491 // Scan forward to find the end of the bucket.
3492 size_t BucketStart = I;
3493 do {
3494 ++I;
3495 } while (I != E &&
3496 PathsSorted[BucketStart].get().MangledPath ==
3497 PathsSorted[I].get().MangledPath);
3498
3499 // If this bucket has multiple paths, extend them all.
3500 if (I - BucketStart > 1) {
3501 for (size_t II = BucketStart; II != I; ++II)
3502 Changed |= extendPath(PathsSorted[II]);
3503 assert(Changed && "no paths were extended to fix ambiguity");
3504 }
3505 }
3506 return Changed;
3507}
3508
3510
3511namespace {
3512typedef llvm::SetVector<BaseSubobject, std::vector<BaseSubobject>,
3513 llvm::DenseSet<BaseSubobject>> FullPathTy;
3514}
3515
3516// This recursive function finds all paths from a subobject centered at
3517// (RD, Offset) to the subobject located at IntroducingObject.
3519 const ASTRecordLayout &MostDerivedLayout,
3520 const CXXRecordDecl *RD, CharUnits Offset,
3521 BaseSubobject IntroducingObject,
3522 FullPathTy &FullPath,
3523 std::list<FullPathTy> &Paths) {
3524 if (BaseSubobject(RD, Offset) == IntroducingObject) {
3525 Paths.push_back(FullPath);
3526 return;
3527 }
3528
3529 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
3530
3531 for (const CXXBaseSpecifier &BS : RD->bases()) {
3532 const CXXRecordDecl *Base = BS.getType()->getAsCXXRecordDecl();
3533 CharUnits NewOffset = BS.isVirtual()
3534 ? MostDerivedLayout.getVBaseClassOffset(Base)
3535 : Offset + Layout.getBaseClassOffset(Base);
3536 FullPath.insert(BaseSubobject(Base, NewOffset));
3537 findPathsToSubobject(Context, MostDerivedLayout, Base, NewOffset,
3538 IntroducingObject, FullPath, Paths);
3539 FullPath.pop_back();
3540 }
3541}
3542
3543// Return the paths which are not subsets of other paths.
3544static void removeRedundantPaths(std::list<FullPathTy> &FullPaths) {
3545 FullPaths.remove_if([&](const FullPathTy &SpecificPath) {
3546 for (const FullPathTy &OtherPath : FullPaths) {
3547 if (&SpecificPath == &OtherPath)
3548 continue;
3549 if (llvm::all_of(SpecificPath, [&](const BaseSubobject &BSO) {
3550 return OtherPath.contains(BSO);
3551 })) {
3552 return true;
3553 }
3554 }
3555 return false;
3556 });
3557}
3558
3560 const CXXRecordDecl *RD,
3561 const FullPathTy &FullPath) {
3562 const ASTRecordLayout &MostDerivedLayout =
3563 Context.getASTRecordLayout(RD);
3565 for (const BaseSubobject &BSO : FullPath) {
3566 const CXXRecordDecl *Base = BSO.getBase();
3567 // The first entry in the path is always the most derived record, skip it.
3568 if (Base == RD) {
3569 assert(Offset.getQuantity() == -1);
3570 Offset = CharUnits::Zero();
3571 continue;
3572 }
3573 assert(Offset.getQuantity() != -1);
3574 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
3575 // While we know which base has to be traversed, we don't know if that base
3576 // was a virtual base.
3577 const CXXBaseSpecifier *BaseBS = std::find_if(
3578 RD->bases_begin(), RD->bases_end(), [&](const CXXBaseSpecifier &BS) {
3579 return BS.getType()->getAsCXXRecordDecl() == Base;
3580 });
3581 Offset = BaseBS->isVirtual() ? MostDerivedLayout.getVBaseClassOffset(Base)
3582 : Offset + Layout.getBaseClassOffset(Base);
3583 RD = Base;
3584 }
3585 return Offset;
3586}
3587
3588// We want to select the path which introduces the most covariant overrides. If
3589// two paths introduce overrides which the other path doesn't contain, issue a
3590// diagnostic.
3591static const FullPathTy *selectBestPath(ASTContext &Context,
3592 const CXXRecordDecl *RD,
3593 const VPtrInfo &Info,
3594 std::list<FullPathTy> &FullPaths) {
3595 // Handle some easy cases first.
3596 if (FullPaths.empty())
3597 return nullptr;
3598 if (FullPaths.size() == 1)
3599 return &FullPaths.front();
3600
3601 const FullPathTy *BestPath = nullptr;
3602 typedef std::set<const CXXMethodDecl *> OverriderSetTy;
3603 OverriderSetTy LastOverrides;
3604 for (const FullPathTy &SpecificPath : FullPaths) {
3605 assert(!SpecificPath.empty());
3606 OverriderSetTy CurrentOverrides;
3607 const CXXRecordDecl *TopLevelRD = SpecificPath.begin()->getBase();
3608 // Find the distance from the start of the path to the subobject with the
3609 // VPtr.
3610 CharUnits BaseOffset =
3611 getOffsetOfFullPath(Context, TopLevelRD, SpecificPath);
3612 FinalOverriders Overriders(TopLevelRD, CharUnits::Zero(), TopLevelRD);
3613 for (const CXXMethodDecl *MD : Info.IntroducingObject->methods()) {
3615 continue;
3616 FinalOverriders::OverriderInfo OI =
3617 Overriders.getOverrider(MD->getCanonicalDecl(), BaseOffset);
3618 const CXXMethodDecl *OverridingMethod = OI.Method;
3619 // Only overriders which have a return adjustment introduce problematic
3620 // thunks.
3621 if (ComputeReturnAdjustmentBaseOffset(Context, OverridingMethod, MD)
3622 .isEmpty())
3623 continue;
3624 // It's possible that the overrider isn't in this path. If so, skip it
3625 // because this path didn't introduce it.
3626 const CXXRecordDecl *OverridingParent = OverridingMethod->getParent();
3627 if (llvm::none_of(SpecificPath, [&](const BaseSubobject &BSO) {
3628 return BSO.getBase() == OverridingParent;
3629 }))
3630 continue;
3631 CurrentOverrides.insert(OverridingMethod);
3632 }
3633 OverriderSetTy NewOverrides =
3634 llvm::set_difference(CurrentOverrides, LastOverrides);
3635 if (NewOverrides.empty())
3636 continue;
3637 OverriderSetTy MissingOverrides =
3638 llvm::set_difference(LastOverrides, CurrentOverrides);
3639 if (MissingOverrides.empty()) {
3640 // This path is a strict improvement over the last path, let's use it.
3641 BestPath = &SpecificPath;
3642 std::swap(CurrentOverrides, LastOverrides);
3643 } else {
3644 // This path introduces an overrider with a conflicting covariant thunk.
3645 DiagnosticsEngine &Diags = Context.getDiagnostics();
3646 const CXXMethodDecl *CovariantMD = *NewOverrides.begin();
3647 const CXXMethodDecl *ConflictMD = *MissingOverrides.begin();
3648 Diags.Report(RD->getLocation(), diag::err_vftable_ambiguous_component)
3649 << RD;
3650 Diags.Report(CovariantMD->getLocation(), diag::note_covariant_thunk)
3651 << CovariantMD;
3652 Diags.Report(ConflictMD->getLocation(), diag::note_covariant_thunk)
3653 << ConflictMD;
3654 }
3655 }
3656 // Go with the path that introduced the most covariant overrides. If there is
3657 // no such path, pick the first path.
3658 return BestPath ? BestPath : &FullPaths.front();
3659}
3660
3662 const CXXRecordDecl *RD,
3663 VPtrInfoVector &Paths) {
3664 const ASTRecordLayout &MostDerivedLayout = Context.getASTRecordLayout(RD);
3665 FullPathTy FullPath;
3666 std::list<FullPathTy> FullPaths;
3667 for (const std::unique_ptr<VPtrInfo>& Info : Paths) {
3669 Context, MostDerivedLayout, RD, CharUnits::Zero(),
3670 BaseSubobject(Info->IntroducingObject, Info->FullOffsetInMDC), FullPath,
3671 FullPaths);
3672 FullPath.clear();
3673 removeRedundantPaths(FullPaths);
3674 Info->PathToIntroducingObject.clear();
3675 if (const FullPathTy *BestPath =
3676 selectBestPath(Context, RD, *Info, FullPaths))
3677 for (const BaseSubobject &BSO : *BestPath)
3678 Info->PathToIntroducingObject.push_back(BSO.getBase());
3679 FullPaths.clear();
3680 }
3681}
3682
3683static bool vfptrIsEarlierInMDC(const ASTRecordLayout &Layout,
3684 const MethodVFTableLocation &LHS,
3685 const MethodVFTableLocation &RHS) {
3686 CharUnits L = LHS.VFPtrOffset;
3687 CharUnits R = RHS.VFPtrOffset;
3688 if (LHS.VBase)
3689 L += Layout.getVBaseClassOffset(LHS.VBase);
3690 if (RHS.VBase)
3691 R += Layout.getVBaseClassOffset(RHS.VBase);
3692 return L < R;
3693}
3694
3695void MicrosoftVTableContext::computeVTableRelatedInformation(
3696 const CXXRecordDecl *RD) {
3697 assert(RD->isDynamicClass());
3698
3699 // Check if we've computed this information before.
3700 if (VFPtrLocations.count(RD))
3701 return;
3702
3703 const VTableLayout::AddressPointsMapTy EmptyAddressPointsMap;
3704
3705 {
3706 auto VFPtrs = std::make_unique<VPtrInfoVector>();
3707 computeVTablePaths(/*ForVBTables=*/false, RD, *VFPtrs);
3708 computeFullPathsForVFTables(Context, RD, *VFPtrs);
3709 VFPtrLocations[RD] = std::move(VFPtrs);
3710 }
3711
3712 MethodVFTableLocationsTy NewMethodLocations;
3713 for (const std::unique_ptr<VPtrInfo> &VFPtr : *VFPtrLocations[RD]) {
3714 VFTableBuilder Builder(*this, RD, *VFPtr);
3715
3716 VFTableIdTy id(RD, VFPtr->FullOffsetInMDC);
3717 assert(VFTableLayouts.count(id) == 0);
3719 Builder.vtable_thunks_begin(), Builder.vtable_thunks_end());
3720 VFTableLayouts[id] = std::make_unique<VTableLayout>(
3721 ArrayRef<size_t>{0}, Builder.vtable_components(), VTableThunks,
3722 EmptyAddressPointsMap);
3723 Thunks.insert(Builder.thunks_begin(), Builder.thunks_end());
3724
3725 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
3726 for (const auto &Loc : Builder.vtable_locations()) {
3727 auto Insert = NewMethodLocations.insert(Loc);
3728 if (!Insert.second) {
3729 const MethodVFTableLocation &NewLoc = Loc.second;
3730 MethodVFTableLocation &OldLoc = Insert.first->second;
3731 if (vfptrIsEarlierInMDC(Layout, NewLoc, OldLoc))
3732 OldLoc = NewLoc;
3733 }
3734 }
3735 }
3736
3737 MethodVFTableLocations.insert(NewMethodLocations.begin(),
3738 NewMethodLocations.end());
3739 if (Context.getLangOpts().DumpVTableLayouts)
3740 dumpMethodLocations(RD, NewMethodLocations, llvm::outs());
3741}
3742
3743void MicrosoftVTableContext::dumpMethodLocations(
3744 const CXXRecordDecl *RD, const MethodVFTableLocationsTy &NewMethods,
3745 raw_ostream &Out) {
3746 // Compute the vtable indices for all the member functions.
3747 // Store them in a map keyed by the location so we'll get a sorted table.
3748 std::map<MethodVFTableLocation, std::string> IndicesMap;
3749 bool HasNonzeroOffset = false;
3750
3751 for (const auto &I : NewMethods) {
3752 const CXXMethodDecl *MD = cast<const CXXMethodDecl>(I.first.getDecl());
3753 assert(hasVtableSlot(MD));
3754
3755 std::string MethodName = PredefinedExpr::ComputeName(
3757
3758 if (isa<CXXDestructorDecl>(MD)) {
3759 IndicesMap[I.second] = MethodName + " [scalar deleting]";
3760 } else {
3761 IndicesMap[I.second] = MethodName;
3762 }
3763
3764 if (!I.second.VFPtrOffset.isZero() || I.second.VBTableIndex != 0)
3765 HasNonzeroOffset = true;
3766 }
3767
3768 // Print the vtable indices for all the member functions.
3769 if (!IndicesMap.empty()) {
3770 Out << "VFTable indices for ";
3771 Out << "'";
3772 RD->printQualifiedName(Out);
3773 Out << "' (" << IndicesMap.size()
3774 << (IndicesMap.size() == 1 ? " entry" : " entries") << ").\n";
3775
3776 CharUnits LastVFPtrOffset = CharUnits::fromQuantity(-1);
3777 uint64_t LastVBIndex = 0;
3778 for (const auto &I : IndicesMap) {
3779 CharUnits VFPtrOffset = I.first.VFPtrOffset;
3780 uint64_t VBIndex = I.first.VBTableIndex;
3781 if (HasNonzeroOffset &&
3782 (VFPtrOffset != LastVFPtrOffset || VBIndex != LastVBIndex)) {
3783 assert(VBIndex > LastVBIndex || VFPtrOffset > LastVFPtrOffset);
3784 Out << " -- accessible via ";
3785 if (VBIndex)
3786 Out << "vbtable index " << VBIndex << ", ";
3787 Out << "vfptr at offset " << VFPtrOffset.getQuantity() << " --\n";
3788 LastVFPtrOffset = VFPtrOffset;
3789 LastVBIndex = VBIndex;
3790 }
3791
3792 uint64_t VTableIndex = I.first.Index;
3793 const std::string &MethodName = I.second;
3794 Out << llvm::format("%4" PRIu64 " | ", VTableIndex) << MethodName << '\n';
3795 }
3796 Out << '\n';
3797 }
3798
3799 Out.flush();
3800}
3801
3802const VirtualBaseInfo &MicrosoftVTableContext::computeVBTableRelatedInformation(
3803 const CXXRecordDecl *RD) {
3804 VirtualBaseInfo *VBI;
3805
3806 {
3807 // Get or create a VBI for RD. Don't hold a reference to the DenseMap cell,
3808 // as it may be modified and rehashed under us.
3809 std::unique_ptr<VirtualBaseInfo> &Entry = VBaseInfo[RD];
3810 if (Entry)
3811 return *Entry;
3812 Entry = std::make_unique<VirtualBaseInfo>();
3813 VBI = Entry.get();
3814 }
3815
3816 computeVTablePaths(/*ForVBTables=*/true, RD, VBI->VBPtrPaths);
3817
3818 // First, see if the Derived class shared the vbptr with a non-virtual base.
3819 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
3820 if (const CXXRecordDecl *VBPtrBase = Layout.getBaseSharingVBPtr()) {
3821 // If the Derived class shares the vbptr with a non-virtual base, the shared
3822 // virtual bases come first so that the layout is the same.
3823 const VirtualBaseInfo &BaseInfo =
3824 computeVBTableRelatedInformation(VBPtrBase);
3825 VBI->VBTableIndices.insert(BaseInfo.VBTableIndices.begin(),
3826 BaseInfo.VBTableIndices.end());
3827 }
3828
3829 // New vbases are added to the end of the vbtable.
3830 // Skip the self entry and vbases visited in the non-virtual base, if any.
3831 unsigned VBTableIndex = 1 + VBI->VBTableIndices.size();
3832 for (const auto &VB : RD->vbases()) {
3833 const CXXRecordDecl *CurVBase = VB.getType()->getAsCXXRecordDecl();
3834 if (!VBI->VBTableIndices.count(CurVBase))
3835 VBI->VBTableIndices[CurVBase] = VBTableIndex++;
3836 }
3837
3838 return *VBI;
3839}
3840
3842 const CXXRecordDecl *VBase) {
3843 const VirtualBaseInfo &VBInfo = computeVBTableRelatedInformation(Derived);
3844 assert(VBInfo.VBTableIndices.count(VBase));
3845 return VBInfo.VBTableIndices.find(VBase)->second;
3846}
3847
3848const VPtrInfoVector &
3850 return computeVBTableRelatedInformation(RD).VBPtrPaths;
3851}
3852
3853const VPtrInfoVector &
3855 computeVTableRelatedInformation(RD);
3856
3857 assert(VFPtrLocations.count(RD) && "Couldn't find vfptr locations");
3858 return *VFPtrLocations[RD];
3859}
3860
3861const VTableLayout &
3863 CharUnits VFPtrOffset) {
3864 computeVTableRelatedInformation(RD);
3865
3866 VFTableIdTy id(RD, VFPtrOffset);
3867 assert(VFTableLayouts.count(id) && "Couldn't find a VFTable at this offset");
3868 return *VFTableLayouts[id];
3869}
3870
3873 assert(hasVtableSlot(cast<CXXMethodDecl>(GD.getDecl())) &&
3874 "Only use this method for virtual methods or dtors");
3875 if (isa<CXXDestructorDecl>(GD.getDecl()))
3876 assert(GD.getDtorType() == Dtor_Deleting);
3877
3878 GD = GD.getCanonicalDecl();
3879
3880 MethodVFTableLocationsTy::iterator I = MethodVFTableLocations.find(GD);
3881 if (I != MethodVFTableLocations.end())
3882 return I->second;
3883
3884 const CXXRecordDecl *RD = cast<CXXMethodDecl>(GD.getDecl())->getParent();
3885
3886 computeVTableRelatedInformation(RD);
3887
3888 I = MethodVFTableLocations.find(GD);
3889 assert(I != MethodVFTableLocations.end() && "Did not find index!");
3890 return I->second;
3891}
Defines the clang::ASTContext interface.
ASTImporterLookupTable & LT
StringRef P
const Decl * D
IndirectLocalPath & Path
Expr * E
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
static Decl::Kind getKind(const Decl *D)
Definition: DeclBase.cpp:1171
SourceLocation Loc
Definition: SemaObjC.cpp:759
static QualType getPointeeType(const MemRegion *R)
const NestedNameSpecifier * Specifier
static void findPathsToSubobject(ASTContext &Context, const ASTRecordLayout &MostDerivedLayout, const CXXRecordDecl *RD, CharUnits Offset, BaseSubobject IntroducingObject, FullPathTy &FullPath, std::list< FullPathTy > &Paths)
static const FullPathTy * selectBestPath(ASTContext &Context, const CXXRecordDecl *RD, const VPtrInfo &Info, std::list< FullPathTy > &FullPaths)
static CharUnits getOffsetOfFullPath(ASTContext &Context, const CXXRecordDecl *RD, const FullPathTy &FullPath)
static void removeRedundantPaths(std::list< FullPathTy > &FullPaths)
static std::unique_ptr< VTableLayout > CreateVTableLayout(const ItaniumVTableBuilder &Builder)
static bool vfptrIsEarlierInMDC(const ASTRecordLayout &Layout, const MethodVFTableLocation &LHS, const MethodVFTableLocation &RHS)
static bool isDirectVBase(const CXXRecordDecl *Base, const CXXRecordDecl *RD)
static void PrintBasePath(const VPtrInfo::BasePath &Path, raw_ostream &Out)
static VTableLayout::AddressPointsIndexMapTy MakeAddressPointIndices(const VTableLayout::AddressPointsMapTy &addressPoints, unsigned numVTables)
static bool rebucketPaths(VPtrInfoVector &Paths)
static bool extendPath(VPtrInfo &P)
static void dumpMicrosoftThunkAdjustment(const ThunkInfo &TI, raw_ostream &Out, bool ContinueFirstLine)
static void GroupNewVirtualOverloads(const CXXRecordDecl *RD, SmallVector< const CXXMethodDecl *, 10 > &VirtualMethods)
static void computeFullPathsForVFTables(ASTContext &Context, const CXXRecordDecl *RD, VPtrInfoVector &Paths)
static bool setsIntersect(const llvm::SmallPtrSet< const CXXRecordDecl *, 4 > &A, ArrayRef< const CXXRecordDecl * > B)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:187
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:2628
const LangOptions & getLangOpts() const
Definition: ASTContext.h:797
CanQualType IntTy
Definition: ASTContext.h:1128
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
DiagnosticsEngine & getDiagnostics() const
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:779
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
Definition: RecordLayout.h:38
bool hasOwnVFPtr() const
hasOwnVFPtr - Does this class provide its own virtual-function table pointer, rather than inheriting ...
Definition: RecordLayout.h:280
const CXXRecordDecl * getBaseSharingVBPtr() const
Definition: RecordLayout.h:329
bool hasOwnVBPtr() const
hasOwnVBPtr - Does this class provide its own virtual-base table pointer, rather than inheriting one ...
Definition: RecordLayout.h:300
llvm::DenseMap< const CXXRecordDecl *, VBaseInfo > VBaseOffsetsMapTy
Definition: RecordLayout.h:59
CharUnits getVBPtrOffset() const
getVBPtrOffset - Get the offset for virtual base table pointer.
Definition: RecordLayout.h:324
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Definition: RecordLayout.h:249
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
Definition: RecordLayout.h:259
const VBaseOffsetsMapTy & getVBaseOffsetsMap() const
Definition: RecordLayout.h:334
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
Definition: RecordLayout.h:234
bool isPrimaryBaseVirtual() const
isPrimaryBaseVirtual - Get whether the primary base for this record is virtual or not.
Definition: RecordLayout.h:242
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
Definition: BaseSubobject.h:43
CharUnits getBaseOffset() const
getBaseOffset - Returns the base class offset.
Definition: BaseSubobject.h:46
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
Definition: DeclCXX.h:203
QualType getType() const
Retrieves the type of the base class.
Definition: DeclCXX.h:249
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2803
A mapping from each virtual member function to its set of final overriders.
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2064
bool isVirtual() const
Definition: DeclCXX.h:2119
overridden_method_range overridden_methods() const
Definition: DeclCXX.cpp:2572
unsigned size_overridden_methods() const
Definition: DeclCXX.cpp:2566
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition: DeclCXX.h:2190
QualType getThisType() const
Return the type of the this pointer.
Definition: DeclCXX.cpp:2603
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclCXX.h:2160
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
base_class_iterator bases_end()
Definition: DeclCXX.h:629
base_class_range bases()
Definition: DeclCXX.h:620
method_range methods() const
Definition: DeclCXX.h:662
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
Definition: DeclCXX.h:1219
base_class_iterator bases_begin()
Definition: DeclCXX.h:627
base_class_range vbases()
Definition: DeclCXX.h:637
base_class_iterator vbases_begin()
Definition: DeclCXX.h:644
bool isDynamicClass() const
Definition: DeclCXX.h:586
void getFinalOverriders(CXXFinalOverriderMap &FinaOverriders) const
Retrieve the final overriders for each virtual member function in the class hierarchy where this clas...
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
Definition: DeclCXX.h:635
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.
CanProxy< U > getAs() const
Retrieve a canonical type pointer with a different static type, upcasting or downcasting as needed.
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
bool isZero() const
isZero - Test whether the quantity equals zero.
Definition: CharUnits.h:122
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition: CharUnits.h:185
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Definition: CharUnits.h:63
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Definition: CharUnits.h:53
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2090
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition: DeclBase.h:2350
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:523
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:600
SourceLocation getLocation() const
Definition: DeclBase.h:446
The name of a declaration.
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:192
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1547
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
Definition: Diagnostic.h:873
bool isImmediateFunction() const
Definition: Decl.cpp:3276
QualType getReturnType() const
Definition: Decl.h:2717
bool isDeleted() const
Whether this function has been deleted.
Definition: Decl.h:2465
bool isPureVirtual() const
Whether this virtual function is pure, i.e.
Definition: Decl.h:2285
Represents a prototype with parameter type info, e.g.
Definition: Type.h:5002
Qualifiers getMethodQuals() const
Definition: Type.h:5397
ArrayRef< QualType > getParamTypes() const
Definition: Type.h:5262
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:4308
QualType getReturnType() const
Definition: Type.h:4630
GlobalDecl - represents a global declaration.
Definition: GlobalDecl.h:56
GlobalDecl getCanonicalDecl() const
Definition: GlobalDecl.h:94
CXXDtorType getDtorType() const
Definition: GlobalDecl.h:110
const Decl * getDecl() const
Definition: GlobalDecl.h:103
const CXXMethodDecl * findOriginalMethodInMap(const CXXMethodDecl *MD) const
uint64_t getMethodVTableIndex(GlobalDecl GD)
Locate a virtual function in the vtable.
std::unique_ptr< VTableLayout > createConstructionVTableLayout(const CXXRecordDecl *MostDerivedClass, CharUnits MostDerivedClassOffset, bool MostDerivedClassIsVirtual, const CXXRecordDecl *LayoutClass)
CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, const CXXRecordDecl *VBase)
Return the offset in chars (relative to the vtable address point) where the offset of the virtual bas...
ItaniumVTableContext(ASTContext &Context, VTableComponentLayout ComponentLayout=Pointer)
GlobalDecl findOriginalMethod(GlobalDecl GD)
Return the method that added the v-table slot that will be used to call the given method.
unsigned getVBTableIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the index of VBase in the vbtable of Derived.
const VPtrInfoVector & enumerateVBTables(const CXXRecordDecl *RD)
MethodVFTableLocation getMethodVFTableLocation(GlobalDecl GD)
const VPtrInfoVector & getVFPtrOffsets(const CXXRecordDecl *RD)
const VTableLayout & getVFTableLayout(const CXXRecordDecl *RD, CharUnits VFPtrOffset)
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:315
std::string getQualifiedNameAsString() const
Definition: Decl.cpp:1668
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
Definition: Decl.cpp:1675
The set of methods that override a given virtual method in each subobject where it occurs.
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:3187
static std::string ComputeName(PredefinedIdentKind IK, const Decl *CurrentDecl, bool ForceElaboratedPrinting=false)
Definition: Expr.cpp:678
A (possibly-)qualified type.
Definition: Type.h:941
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:7750
QualType getCanonicalType() const
Definition: Type.h:7802
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3428
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
Definition: TargetCXXABI.h:136
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
Definition: TargetInfo.h:472
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
Definition: TargetInfo.h:1327
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1882
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8607
Represents a single component in a vtable.
Definition: VTableBuilder.h:30
static VTableComponent MakeCompleteDtor(const CXXDestructorDecl *DD)
Definition: VTableBuilder.h:79
static VTableComponent MakeRTTI(const CXXRecordDecl *RD)
Definition: VTableBuilder.h:67
const CXXMethodDecl * getUnusedFunctionDecl() const
static VTableComponent MakeOffsetToTop(CharUnits Offset)
Definition: VTableBuilder.h:63
CharUnits getVBaseOffset() const
static VTableComponent MakeUnusedFunction(const CXXMethodDecl *MD)
Definition: VTableBuilder.h:89
Kind getKind() const
Get the kind of this vtable component.
Definition: VTableBuilder.h:97
static VTableComponent MakeFunction(const CXXMethodDecl *MD)
Definition: VTableBuilder.h:71
@ CK_DeletingDtorPointer
A pointer to the deleting destructor.
Definition: VTableBuilder.h:43
@ CK_UnusedFunctionPointer
An entry that is never used.
Definition: VTableBuilder.h:50
@ CK_CompleteDtorPointer
A pointer to the complete destructor.
Definition: VTableBuilder.h:40
static VTableComponent MakeVBaseOffset(CharUnits Offset)
Definition: VTableBuilder.h:59
const CXXRecordDecl * getRTTIDecl() const
static VTableComponent MakeDeletingDtor(const CXXDestructorDecl *DD)
Definition: VTableBuilder.h:84
CharUnits getOffsetToTop() const
const CXXMethodDecl * getFunctionDecl() const
static VTableComponent MakeVCallOffset(CharUnits Offset)
Definition: VTableBuilder.h:55
CharUnits getVCallOffset() const
const CXXDestructorDecl * getDestructorDecl() const
static bool hasVtableSlot(const CXXMethodDecl *MD)
Determine whether this function should be assigned a vtable slot.
ThunksMapTy Thunks
Contains all thunks that a given method decl will need.
VTableLayout(ArrayRef< size_t > VTableIndices, ArrayRef< VTableComponent > VTableComponents, ArrayRef< VTableThunkTy > VTableThunks, const AddressPointsMapTy &AddressPoints)
llvm::DenseMap< BaseSubobject, AddressPointLocation > AddressPointsMapTy
std::pair< uint64_t, ThunkInfo > VTableThunkTy
QualType getType() const
Definition: Decl.h:678
Defines the clang::TargetInfo interface.
bool Ret(InterpState &S, CodePtr &PC, APValue &Result)
Definition: Interp.h:276
The JSON file list parser is used to communicate input to InstallAPI.
@ Dtor_Complete
Complete object dtor.
Definition: ABI.h:35
@ Dtor_Deleting
Deleting dtor.
Definition: ABI.h:34
const FunctionProtoType * T
@ PrettyFunctionNoVirtual
The same as PrettyFunction, except that the 'virtual' keyword is omitted for virtual member functions...
unsigned long uint64_t
#define false
Definition: stdbool.h:26
Represents an element in a path from a derived class to a base class.
const CXXRecordDecl * VBase
If nonnull, holds the last vbase which contains the vfptr that the method definition is adjusted to.
CharUnits VFPtrOffset
This is the offset of the vfptr from the start of the last vbase, or the complete type if there are n...
A return adjustment.
Definition: Thunk.h:27
bool isEmpty() const
Definition: Thunk.h:70
union clang::ReturnAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
Definition: Thunk.h:30
A this pointer adjustment.
Definition: Thunk.h:92
union clang::ThisAdjustment::VirtualAdjustment Virtual
bool isEmpty() const
Definition: Thunk.h:137
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
Definition: Thunk.h:95
The this pointer adjustment as well as an optional return adjustment for a thunk.
Definition: Thunk.h:157
bool isEmpty() const
Definition: Thunk.h:186
ThisAdjustment This
The this pointer adjustment.
Definition: Thunk.h:159
const CXXMethodDecl * Method
Holds a pointer to the overridden method this thunk is for, if needed by the ABI to distinguish diffe...
Definition: Thunk.h:172
ReturnAdjustment Return
The return adjustment.
Definition: Thunk.h:162
Uniquely identifies a virtual method within a class hierarchy by the method itself and a class subobj...
CXXMethodDecl * Method
The overriding virtual method.
unsigned Subobject
The subobject in which the overriding virtual method resides.
const CXXRecordDecl * InVirtualSubobject
The virtual base class subobject of which this overridden virtual method is a part.
Holds information about the inheritance path to a virtual base or function table pointer.
CharUnits NonVirtualOffset
IntroducingObject is at this offset from its containing complete object or virtual base.
CharUnits FullOffsetInMDC
Static offset from the top of the most derived class to this vfptr, including any virtual base offset...
const CXXRecordDecl * getVBaseWithVPtr() const
The vptr is stored inside the non-virtual component of this virtual base.
const CXXRecordDecl * IntroducingObject
This is the class that introduced the vptr by declaring new virtual methods or virtual bases.
BasePath MangledPath
The bases from the inheritance path that got used to mangle the vbtable name.
BasePath PathToIntroducingObject
This holds the base classes path from the complete type to the first base with the given vfptr offset...
All virtual base related information about a given record decl.
VPtrInfoVector VBPtrPaths
Information on all virtual base tables used when this record is the most derived class.
llvm::DenseMap< const CXXRecordDecl *, unsigned > VBTableIndices
A map from virtual base to vbtable index for doing a conversion from the the derived class to the a b...
uint32_t VBPtrOffset
The offset (in bytes) of the vbptr, relative to the beginning of the derived class.
Definition: Thunk.h:46
int64_t VBaseOffsetOffset
The offset (in bytes), relative to the address point of the virtual base class offset.
Definition: Thunk.h:39
struct clang::ReturnAdjustment::VirtualAdjustment::@189 Itanium
uint32_t VBIndex
Index of the virtual base in the vbtable.
Definition: Thunk.h:49
struct clang::ReturnAdjustment::VirtualAdjustment::@190 Microsoft
int32_t VtordispOffset
The offset of the vtordisp (in bytes), relative to the ECX.
Definition: Thunk.h:109
struct clang::ThisAdjustment::VirtualAdjustment::@192 Microsoft
int32_t VBOffsetOffset
The offset (in bytes) of the vbase offset in the vbtable.
Definition: Thunk.h:116
struct clang::ThisAdjustment::VirtualAdjustment::@191 Itanium
int64_t VCallOffsetOffset
The offset (in bytes), relative to the address point, of the virtual call offset.
Definition: Thunk.h:104
int32_t VBPtrOffset
The offset of the vbptr of the derived class (in bytes), relative to the ECX after vtordisp adjustmen...
Definition: Thunk.h:113