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 
14 #include "clang/AST/ASTContext.h"
17 #include "clang/AST/RecordLayout.h"
18 #include "clang/Basic/TargetInfo.h"
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 
27 using namespace clang;
28 
29 #define DUMP_OVERRIDERS 0
30 
31 namespace {
32 
33 /// BaseOffset - Represents an offset from a derived class to a direct or
34 /// indirect base class.
35 struct 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.
62 class FinalOverriders {
63 public:
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.
75 
76  OverriderInfo() : Method(nullptr), VirtualBase(nullptr),
77  Offset(CharUnits::Zero()) { }
78  };
79 
80 private:
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 
134 public:
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 
158 FinalOverriders::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 
219 static 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 
258 static 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 
270 static BaseOffset
271 ComputeReturnAdjustmentBaseOffset(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 
324 void
325 FinalOverriders::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 
378 void 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.
443 struct 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 
456 public:
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 
470 static 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 
488 bool 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 
509 bool 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 
522 CharUnits 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.
533 class VCallAndVBaseOffsetBuilder {
534 public:
535  typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits>
536  VBaseOffsetOffsetsMapTy;
537 
538 private:
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 
588 public:
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 
614 void
615 VCallAndVBaseOffsetBuilder::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 
663 CharUnits 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
680  CharUnits OffsetOffset = OffsetWidth * OffsetIndex;
681 
682  return OffsetOffset;
683 }
684 
685 void 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 
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 
751 void
752 VCallAndVBaseOffsetBuilder::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.
784 class ItaniumVTableBuilder {
785 public:
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 
798 private:
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 
998 public:
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 
1071 void 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 
1085 typedef 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).
1091 template <class VisitorTy>
1092 static void
1093 visitAllOverriddenMethods(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.
1105 static void
1106 ComputeAllOverriddenMethods(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 
1115 void 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 
1221 ItaniumVTableBuilder::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 
1244 BaseOffset 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 
1290 ThisAdjustment 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 
1339 void 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.
1350  if (!ReturnAdjustment.isEmpty())
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.
1369 static 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 
1384 bool 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 
1446 typedef 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.
1451 static const CXXMethodDecl *
1452 FindNearestOverriddenMethod(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 
1469 void 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()) {
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 
1664 void 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 
1686 void 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 
1783 void
1784 ItaniumVTableBuilder::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 
1841 void 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 
1897 void 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 
1935 static void printThunkMethod(const ThunkInfo &Info, raw_ostream &Out) {
1936  if (!Info.Method)
1937  return;
1938  std::string Str = PredefinedExpr::ComputeName(
1940  Out << " method: " << Str;
1941 }
1942 
1943 /// dumpLayout - Dump the vtable layout.
1944 void 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 =
1953  P.first);
1954  std::string Str1 =
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(
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 
2051  if (Thunk.This.Virtual.Itanium.VCallOffsetOffset) {
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 
2087  if (Thunk.This.Virtual.Itanium.VCallOffsetOffset) {
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(
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(
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 
2222  if (Thunk.This.Virtual.Itanium.VCallOffsetOffset) {
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.
2242  continue;
2243  MD = MD->getCanonicalDecl();
2244 
2245  std::string MethodName = PredefinedExpr::ComputeName(
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 
2353 CharUnits
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 
2391 const 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 
2410 static std::unique_ptr<VTableLayout>
2411 CreateVTableLayout(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 
2420 void
2421 ItaniumVTableContext::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 
2458 std::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 
2467 namespace {
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 
2511 class VFTableBuilder {
2512 public:
2513  typedef llvm::DenseMap<GlobalDecl, MethodVFTableLocation>
2514  MethodVFTableLocationsTy;
2515 
2516  typedef llvm::iterator_range<MethodVFTableLocationsTy::const_iterator>
2517  method_locations_range;
2518 
2519 private:
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 
2665 public:
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.
2768 CharUnits
2769 VFTableBuilder::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.
2959 void 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,
3000  SmallVector<const CXXMethodDecl *, 10> &VirtualMethods) {
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 
3030 static 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 
3038 void 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 ||
3151  MD->size_overridden_methods()) {
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 
3197 static 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 
3205 static 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 << ", ";
3217  if (R.Virtual.Microsoft.VBIndex)
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 
3243 void 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 
3368 static 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.
3391 void 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 
3468 static 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 
3477 static 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 
3511 namespace {
3512 typedef 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.
3518 static void findPathsToSubobject(ASTContext &Context,
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.
3544 static 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.
3591 static 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 
3683 static 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 
3695 void 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 
3743 void 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 
3802 const 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 
3848 const VPtrInfoVector &
3850  return computeVBTableRelatedInformation(RD).VBPtrPaths;
3851 }
3852 
3853 const VPtrInfoVector &
3855  computeVTableRelatedInformation(RD);
3856 
3857  assert(VFPtrLocations.count(RD) && "Couldn't find vfptr locations");
3858  return *VFPtrLocations[RD];
3859 }
3860 
3861 const 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
unsigned Offset
Definition: Format.cpp:3003
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 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 const FullPathTy * selectBestPath(ASTContext &Context, const CXXRecordDecl *RD, const VPtrInfo &Info, std::list< FullPathTy > &FullPaths)
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:2633
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.
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:779
DiagnosticsEngine & getDiagnostics() const
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 * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
Definition: RecordLayout.h:234
bool hasOwnVBPtr() const
hasOwnVBPtr - Does this class provide its own virtual-base table pointer, rather than inheriting one ...
Definition: RecordLayout.h:300
const CXXRecordDecl * getBaseSharingVBPtr() const
Definition: RecordLayout.h:329
llvm::DenseMap< const CXXRecordDecl *, VBaseInfo > VBaseOffsetsMapTy
Definition: RecordLayout.h:59
const VBaseOffsetsMapTy & getVBaseOffsetsMap() const
Definition: RecordLayout.h:334
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
bool isPrimaryBaseVirtual() const
isPrimaryBaseVirtual - Get whether the primary base for this record is virtual or not.
Definition: RecordLayout.h:242
CharUnits getBaseOffset() const
getBaseOffset - Returns the base class offset.
Definition: BaseSubobject.h:46
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
Definition: BaseSubobject.h:43
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
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
overridden_method_range overridden_methods() const
Definition: DeclCXX.cpp:2572
unsigned size_overridden_methods() const
Definition: DeclCXX.cpp:2566
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:193
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1553
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
Definition: Diagnostic.h:879
bool isImmediateFunction() const
Definition: Decl.cpp:3280
QualType getReturnType() const
Definition: Decl.h:2718
bool isDeleted() const
Whether this function has been deleted.
Definition: Decl.h:2466
bool isPureVirtual() const
Whether this virtual function is pure, i.e.
Definition: Decl.h:2286
Represents a prototype with parameter type info, e.g.
Definition: Type.h:5012
ArrayRef< QualType > getParamTypes() const
Definition: Type.h:5272
Qualifiers getMethodQuals() const
Definition: Type.h:5407
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:4318
QualType getReturnType() const
Definition: Type.h:4640
GlobalDecl - represents a global declaration.
Definition: GlobalDecl.h:56
GlobalDecl getCanonicalDecl() const
Definition: GlobalDecl.h:94
const Decl * getDecl() const
Definition: GlobalDecl.h:103
CXXDtorType getDtorType() const
Definition: GlobalDecl.h:110
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(bool WithGlobalNsPrefix=false) 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:1676
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:3197
static std::string ComputeName(PredefinedIdentKind IK, const Decl *CurrentDecl, bool ForceElaboratedPrinting=false)
Definition: Expr.cpp:733
A (possibly-)qualified type.
Definition: Type.h:941
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:7760
QualType getCanonicalType() const
Definition: Type.h:7812
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3438
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:8635
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
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
static VTableComponent MakeDeletingDtor(const CXXDestructorDecl *DD)
Definition: VTableBuilder.h:84
const CXXRecordDecl * getRTTIDecl() const
const CXXMethodDecl * getFunctionDecl() const
const CXXDestructorDecl * getDestructorDecl() const
CharUnits getOffsetToTop() const
static VTableComponent MakeVCallOffset(CharUnits Offset)
Definition: VTableBuilder.h:55
CharUnits getVCallOffset() const
const CXXMethodDecl * getUnusedFunctionDecl() 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:679
Defines the clang::TargetInfo interface.
bool Ret(InterpState &S, CodePtr &PC, APValue &Result)
Definition: Interp.h:275
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
long int64_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