Coverage Report

Created: 2020-02-18 08:44

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