blob: c0291486f7bd983376987175558f6fbb3e875335 [file] [log] [blame]
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001//===--- CGVtable.cpp - Emit LLVM Code for C++ vtables --------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This contains code dealing with C++ code generation of virtual tables.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CodeGenModule.h"
15#include "CodeGenFunction.h"
Anders Carlssonf942ee02009-11-27 20:47:55 +000016#include "clang/AST/CXXInheritance.h"
Anders Carlsson2bb27f52009-10-11 22:13:54 +000017#include "clang/AST/RecordLayout.h"
Anders Carlssond420a312009-11-26 19:32:45 +000018#include "llvm/ADT/DenseSet.h"
Anders Carlsson5d40c6f2010-02-11 08:02:13 +000019#include "llvm/Support/Format.h"
Zhongxing Xu1721ef72009-11-13 05:46:16 +000020#include <cstdio>
Anders Carlsson2bb27f52009-10-11 22:13:54 +000021
22using namespace clang;
23using namespace CodeGen;
24
Anders Carlsson727ffb12010-02-11 19:39:49 +000025/// TypeConversionRequiresAdjustment - Returns whether conversion from a
26/// derived type to a base type requires adjustment.
27static bool
28TypeConversionRequiresAdjustment(ASTContext &Ctx,
29 const CXXRecordDecl *DerivedDecl,
30 const CXXRecordDecl *BaseDecl) {
31 CXXBasePaths Paths(/*FindAmbiguities=*/false,
32 /*RecordPaths=*/true, /*DetectVirtual=*/true);
33 if (!const_cast<CXXRecordDecl *>(DerivedDecl)->
34 isDerivedFrom(const_cast<CXXRecordDecl *>(BaseDecl), Paths)) {
35 assert(false && "Class must be derived from the passed in base class!");
36 return false;
37 }
38
39 // If we found a virtual base we always want to require adjustment.
40 if (Paths.getDetectedVirtual())
41 return true;
42
43 const CXXBasePath &Path = Paths.front();
44
45 for (size_t Start = 0, End = Path.size(); Start != End; ++Start) {
46 const CXXBasePathElement &Element = Path[Start];
47
48 // Check the base class offset.
49 const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(Element.Class);
50
51 const RecordType *BaseType = Element.Base->getType()->getAs<RecordType>();
52 const CXXRecordDecl *Base = cast<CXXRecordDecl>(BaseType->getDecl());
53
54 if (Layout.getBaseClassOffset(Base) != 0) {
55 // This requires an adjustment.
56 return true;
57 }
58 }
59
60 return false;
61}
62
63static bool
64TypeConversionRequiresAdjustment(ASTContext &Ctx,
65 QualType DerivedType, QualType BaseType) {
66 // Canonicalize the types.
John McCall84c416b92010-02-12 06:15:07 +000067 CanQualType CanDerivedType = Ctx.getCanonicalType(DerivedType);
68 CanQualType CanBaseType = Ctx.getCanonicalType(BaseType);
Anders Carlsson727ffb12010-02-11 19:39:49 +000069
70 assert(CanDerivedType->getTypeClass() == CanBaseType->getTypeClass() &&
71 "Types must have same type class!");
72
73 if (CanDerivedType == CanBaseType) {
74 // No adjustment needed.
75 return false;
76 }
77
John McCall84c416b92010-02-12 06:15:07 +000078 if (isa<ReferenceType>(CanDerivedType)) {
79 CanDerivedType = CanDerivedType->getAs<ReferenceType>()->getPointeeType();
Anders Carlssondd27b5d2010-02-11 19:45:15 +000080 CanBaseType = CanBaseType->getAs<ReferenceType>()->getPointeeType();
John McCall84c416b92010-02-12 06:15:07 +000081 } else if (isa<PointerType>(CanDerivedType)) {
82 CanDerivedType = CanDerivedType->getAs<PointerType>()->getPointeeType();
Anders Carlssondd27b5d2010-02-11 19:45:15 +000083 CanBaseType = CanBaseType->getAs<PointerType>()->getPointeeType();
Anders Carlsson727ffb12010-02-11 19:39:49 +000084 } else {
85 assert(false && "Unexpected return type!");
86 }
87
John McCall84c416b92010-02-12 06:15:07 +000088 // We need to compare unqualified types here; consider
89 // const T *Base::foo();
90 // T *Derived::foo();
91 if (CanDerivedType.getUnqualifiedType() == CanBaseType.getUnqualifiedType()) {
Anders Carlsson727ffb12010-02-11 19:39:49 +000092 // No adjustment needed.
93 return false;
94 }
95
96 const CXXRecordDecl *DerivedDecl =
John McCall84c416b92010-02-12 06:15:07 +000097 cast<CXXRecordDecl>(cast<RecordType>(CanDerivedType)->getDecl());
Anders Carlsson727ffb12010-02-11 19:39:49 +000098
99 const CXXRecordDecl *BaseDecl =
John McCall84c416b92010-02-12 06:15:07 +0000100 cast<CXXRecordDecl>(cast<RecordType>(CanBaseType)->getDecl());
Anders Carlsson727ffb12010-02-11 19:39:49 +0000101
102 return TypeConversionRequiresAdjustment(Ctx, DerivedDecl, BaseDecl);
103}
104
Anders Carlsson65b49782010-02-12 05:25:12 +0000105static bool
Anders Carlsson5272c252010-02-12 17:37:14 +0000106ReturnTypeConversionRequiresAdjustment(const CXXMethodDecl *DerivedMD,
Anders Carlsson65b49782010-02-12 05:25:12 +0000107 const CXXMethodDecl *BaseMD) {
Anders Carlsson5272c252010-02-12 17:37:14 +0000108 ASTContext &Context = DerivedMD->getASTContext();
109
Anders Carlsson65b49782010-02-12 05:25:12 +0000110 const FunctionType *BaseFT = BaseMD->getType()->getAs<FunctionType>();
111 const FunctionType *DerivedFT = DerivedMD->getType()->getAs<FunctionType>();
112
113 return TypeConversionRequiresAdjustment(Context, DerivedFT->getResultType(),
114 BaseFT->getResultType());
115}
116
Anders Carlssond59885022009-11-27 22:21:51 +0000117namespace {
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000118
Anders Carlssone8ac42a2010-02-11 21:24:32 +0000119/// FinalOverriders - Contains the final overrider member functions for all
120/// member functions in the base subobjects of a class.
121class FinalOverriders {
Anders Carlsson136bd192010-02-12 16:55:34 +0000122public:
Anders Carlssoneee53d92010-02-13 02:02:03 +0000123 /// BaseOffset - Represents an offset from a derived class to a direct or
124 /// indirect base class.
125 struct BaseOffset {
126 /// VirtualBase - If the path from the derived class to the base class
127 /// involves a virtual base class, this holds its declaration.
128 const CXXRecordDecl *VirtualBase;
129
130 /// NonVirtualOffset - The offset from the derived class to the base class.
131 /// Or the offset from the virtual base class to the base class, if the path
132 /// from the derived class to the base class involves a virtual base class.
133 uint64_t NonVirtualOffset;
134
135 BaseOffset() : VirtualBase(0), NonVirtualOffset(0) { }
136 BaseOffset(const CXXRecordDecl *VirtualBase, uint64_t NonVirtualOffset)
137 : VirtualBase(VirtualBase), NonVirtualOffset(NonVirtualOffset) { }
138
Benjamin Kramere047e112010-02-13 09:15:07 +0000139 bool isEmpty() const { return !NonVirtualOffset && !VirtualBase; }
Anders Carlssoneee53d92010-02-13 02:02:03 +0000140 };
141
Anders Carlsson136bd192010-02-12 16:55:34 +0000142 /// OverriderInfo - Information about a final overrider.
143 struct OverriderInfo {
144 /// Method - The method decl of the overrider.
145 const CXXMethodDecl *Method;
146
Anders Carlssoneee53d92010-02-13 02:02:03 +0000147 OverriderInfo() : Method(0) { }
Anders Carlsson136bd192010-02-12 16:55:34 +0000148 };
149
150private:
Anders Carlssone8ac42a2010-02-11 21:24:32 +0000151 /// MostDerivedClass - The most derived class for which the final overriders
152 /// are stored.
153 const CXXRecordDecl *MostDerivedClass;
154
155 ASTContext &Context;
156
157 /// MostDerivedClassLayout - the AST record layout of the most derived class.
158 const ASTRecordLayout &MostDerivedClassLayout;
159
Anders Carlssoneee53d92010-02-13 02:02:03 +0000160 /// BaseSubobjectMethodPairTy - Uniquely identifies a member function
161 /// in a base subobject.
162 typedef std::pair<BaseSubobject, const CXXMethodDecl *>
163 BaseSubobjectMethodPairTy;
164
165 typedef llvm::DenseMap<BaseSubobjectMethodPairTy,
Anders Carlsson136bd192010-02-12 16:55:34 +0000166 OverriderInfo> OverridersMapTy;
Anders Carlssone8ac42a2010-02-11 21:24:32 +0000167
168 /// OverridersMap - The final overriders for all virtual member functions of
169 /// all the base subobjects of the most derived class.
170 OverridersMapTy OverridersMap;
171
Anders Carlssoneee53d92010-02-13 02:02:03 +0000172 typedef llvm::DenseMap<BaseSubobjectMethodPairTy, BaseOffset>
173 AdjustmentOffsetsMapTy;
174
175 /// ReturnAdjustments - Holds return adjustments for all the overriders that
176 /// need to perform return value adjustments.
177 AdjustmentOffsetsMapTy ReturnAdjustments;
178
Anders Carlsson9fbf6d92010-02-12 01:40:03 +0000179 typedef llvm::SmallVector<uint64_t, 1> OffsetVectorTy;
180
181 /// SubobjectOffsetsMapTy - This map is used for keeping track of all the
182 /// base subobject offsets that a single class declaration might refer to.
183 ///
184 /// For example, in:
185 ///
186 /// struct A { virtual void f(); };
187 /// struct B1 : A { };
188 /// struct B2 : A { };
189 /// struct C : B1, B2 { virtual void f(); };
190 ///
191 /// when we determine that C::f() overrides A::f(), we need to update the
192 /// overriders map for both A-in-B1 and A-in-B2 and the subobject offsets map
193 /// will have the subobject offsets for both A copies.
194 typedef llvm::DenseMap<const CXXRecordDecl *, OffsetVectorTy>
195 SubobjectOffsetsMapTy;
196
Anders Carlssone8ac42a2010-02-11 21:24:32 +0000197 /// ComputeFinalOverriders - Compute the final overriders for a given base
198 /// subobject (and all its direct and indirect bases).
Anders Carlsson9fbf6d92010-02-12 01:40:03 +0000199 void ComputeFinalOverriders(BaseSubobject Base,
200 SubobjectOffsetsMapTy &Offsets);
Anders Carlssone8ac42a2010-02-11 21:24:32 +0000201
202 /// AddOverriders - Add the final overriders for this base subobject to the
203 /// map of final overriders.
Anders Carlsson9fbf6d92010-02-12 01:40:03 +0000204 void AddOverriders(BaseSubobject Base, SubobjectOffsetsMapTy &Offsets);
205
206 /// PropagateOverrider - Propagate the NewMD overrider to all the functions
207 /// that OldMD overrides. For example, if we have:
208 ///
209 /// struct A { virtual void f(); };
210 /// struct B : A { virtual void f(); };
211 /// struct C : B { virtual void f(); };
212 ///
213 /// and we want to override B::f with C::f, we also need to override A::f with
214 /// C::f.
215 void PropagateOverrider(const CXXMethodDecl *OldMD,
216 const CXXMethodDecl *NewMD,
217 SubobjectOffsetsMapTy &Offsets);
Anders Carlssone8ac42a2010-02-11 21:24:32 +0000218
Anders Carlsson9fbf6d92010-02-12 01:40:03 +0000219 static void MergeSubobjectOffsets(const SubobjectOffsetsMapTy &NewOffsets,
220 SubobjectOffsetsMapTy &Offsets);
221
Anders Carlssone8ac42a2010-02-11 21:24:32 +0000222public:
223 explicit FinalOverriders(const CXXRecordDecl *MostDerivedClass);
224
225 /// getOverrider - Get the final overrider for the given method declaration in
226 /// the given base subobject.
Anders Carlsson136bd192010-02-12 16:55:34 +0000227 const OverriderInfo getOverrider(BaseSubobject Base,
228 const CXXMethodDecl *MD) const {
Anders Carlssone8ac42a2010-02-11 21:24:32 +0000229 assert(OverridersMap.count(std::make_pair(Base, MD)) &&
230 "Did not find overrider!");
231
232 return OverridersMap.lookup(std::make_pair(Base, MD));
233 }
234
235 /// dump - dump the final overriders.
236 void dump() const {
237 dump(llvm::errs(), BaseSubobject(MostDerivedClass, 0));
238 }
239
240 /// dump - dump the final overriders for a base subobject, and all its direct
241 /// and indirect base subobjects.
242 void dump(llvm::raw_ostream &Out, BaseSubobject Base) const;
243};
Anders Carlssoneee53d92010-02-13 02:02:03 +0000244
Anders Carlssone8ac42a2010-02-11 21:24:32 +0000245FinalOverriders::FinalOverriders(const CXXRecordDecl *MostDerivedClass)
246 : MostDerivedClass(MostDerivedClass),
247 Context(MostDerivedClass->getASTContext()),
248 MostDerivedClassLayout(Context.getASTRecordLayout(MostDerivedClass)) {
249
250 // Compute the final overriders.
Anders Carlsson9fbf6d92010-02-12 01:40:03 +0000251 SubobjectOffsetsMapTy Offsets;
252 ComputeFinalOverriders(BaseSubobject(MostDerivedClass, 0), Offsets);
Anders Carlssone8ac42a2010-02-11 21:24:32 +0000253
254 // And dump them (for now).
255 dump();
256}
257
Anders Carlsson9fbf6d92010-02-12 01:40:03 +0000258void FinalOverriders::AddOverriders(BaseSubobject Base,
259 SubobjectOffsetsMapTy &Offsets) {
Anders Carlssone8ac42a2010-02-11 21:24:32 +0000260 const CXXRecordDecl *RD = Base.getBase();
261
262 for (CXXRecordDecl::method_iterator I = RD->method_begin(),
263 E = RD->method_end(); I != E; ++I) {
264 const CXXMethodDecl *MD = *I;
265
266 if (!MD->isVirtual())
267 continue;
268
Anders Carlsson9fbf6d92010-02-12 01:40:03 +0000269 // First, propagate the overrider.
270 PropagateOverrider(MD, MD, Offsets);
271
272 // Add the overrider as the final overrider of itself.
Anders Carlsson136bd192010-02-12 16:55:34 +0000273 OverriderInfo& Overrider = OverridersMap[std::make_pair(Base, MD)];
274 assert(!Overrider.Method && "Overrider should not exist yet!");
Anders Carlssone8ac42a2010-02-11 21:24:32 +0000275
Anders Carlsson136bd192010-02-12 16:55:34 +0000276 Overrider.Method = MD;
Anders Carlssone8ac42a2010-02-11 21:24:32 +0000277 }
278}
279
Anders Carlssoneee53d92010-02-13 02:02:03 +0000280static FinalOverriders::BaseOffset
281ComputeBaseOffset(ASTContext &Context,
282 const CXXRecordDecl *DerivedRD,
283 const CXXRecordDecl *BaseRD) {
284 CXXBasePaths Paths(/*FindAmbiguities=*/false,
285 /*RecordPaths=*/true, /*DetectVirtual=*/true);
286
287 if (!const_cast<CXXRecordDecl *>(DerivedRD)->
288 isDerivedFrom(const_cast<CXXRecordDecl *>(BaseRD), Paths)) {
289 assert(false && "Class must be derived from the passed in base class!");
290 return FinalOverriders::BaseOffset();
291 }
292
293 assert(!Paths.getDetectedVirtual() &&
294 "FIXME: Handle virtual bases!");
295
296 uint64_t NonVirtualOffset = 0;
297
298 const CXXBasePath &Path = Paths.front();
299
300 for (size_t Start = 0, End = Path.size(); Start != End; ++Start) {
301 const CXXBasePathElement &Element = Path[Start];
302
303 // Check the base class offset.
304 const ASTRecordLayout &Layout = Context.getASTRecordLayout(Element.Class);
305
306 const RecordType *BaseType = Element.Base->getType()->getAs<RecordType>();
307 const CXXRecordDecl *Base = cast<CXXRecordDecl>(BaseType->getDecl());
308
309 NonVirtualOffset += Layout.getBaseClassOffset(Base);
310 }
311
312 // FIXME: This should probably use CharUnits or something. Maybe we should
313 // even change the base offsets in ASTRecordLayout to be specified in
314 // CharUnits.
315 return FinalOverriders::BaseOffset(0, NonVirtualOffset / 8);
316}
317
318static FinalOverriders::BaseOffset
319ComputeReturnTypeBaseOffset(ASTContext &Context,
320 const CXXMethodDecl *DerivedMD,
321 const CXXMethodDecl *BaseMD) {
322 const FunctionType *BaseFT = BaseMD->getType()->getAs<FunctionType>();
323 const FunctionType *DerivedFT = DerivedMD->getType()->getAs<FunctionType>();
324
325 // Canonicalize the return types.
326 CanQualType CanDerivedReturnType =
327 Context.getCanonicalType(DerivedFT->getResultType());
328 CanQualType CanBaseReturnType =
329 Context.getCanonicalType(BaseFT->getResultType());
330
331 assert(CanDerivedReturnType->getTypeClass() ==
332 CanBaseReturnType->getTypeClass() &&
333 "Types must have same type class!");
334
335 if (CanDerivedReturnType == CanBaseReturnType) {
336 // No adjustment needed.
337 return FinalOverriders::BaseOffset();
338 }
339
340 if (isa<ReferenceType>(CanDerivedReturnType)) {
341 CanDerivedReturnType =
342 CanDerivedReturnType->getAs<ReferenceType>()->getPointeeType();
343 CanBaseReturnType =
344 CanBaseReturnType->getAs<ReferenceType>()->getPointeeType();
345 } else if (isa<PointerType>(CanDerivedReturnType)) {
346 CanDerivedReturnType =
347 CanDerivedReturnType->getAs<PointerType>()->getPointeeType();
348 CanBaseReturnType =
349 CanBaseReturnType->getAs<PointerType>()->getPointeeType();
350 } else {
351 assert(false && "Unexpected return type!");
352 }
353
354 // We need to compare unqualified types here; consider
355 // const T *Base::foo();
356 // T *Derived::foo();
357 if (CanDerivedReturnType.getUnqualifiedType() ==
358 CanBaseReturnType.getUnqualifiedType()) {
359 // No adjustment needed.
360 return FinalOverriders::BaseOffset();
361 }
362
363 const CXXRecordDecl *DerivedRD =
364 cast<CXXRecordDecl>(cast<RecordType>(CanDerivedReturnType)->getDecl());
365
366 const CXXRecordDecl *BaseRD =
367 cast<CXXRecordDecl>(cast<RecordType>(CanBaseReturnType)->getDecl());
368
369 return ComputeBaseOffset(Context, DerivedRD, BaseRD);
370}
371
Anders Carlsson9fbf6d92010-02-12 01:40:03 +0000372void FinalOverriders::PropagateOverrider(const CXXMethodDecl *OldMD,
373 const CXXMethodDecl *NewMD,
374 SubobjectOffsetsMapTy &Offsets) {
375 for (CXXMethodDecl::method_iterator I = OldMD->begin_overridden_methods(),
376 E = OldMD->end_overridden_methods(); I != E; ++I) {
377 const CXXMethodDecl *OverriddenMD = *I;
378 const CXXRecordDecl *OverriddenRD = OverriddenMD->getParent();
379
380 // We want to override OverriddenMD in all subobjects, for example:
381 //
382 /// struct A { virtual void f(); };
383 /// struct B1 : A { };
384 /// struct B2 : A { };
385 /// struct C : B1, B2 { virtual void f(); };
386 ///
387 /// When overriding A::f with C::f we need to do so in both A subobjects.
388 const OffsetVectorTy &OffsetVector = Offsets[OverriddenRD];
389
390 // Go through all the subobjects.
391 for (unsigned I = 0, E = OffsetVector.size(); I != E; ++I) {
392 uint64_t Offset = OffsetVector[I];
393
Anders Carlssoneee53d92010-02-13 02:02:03 +0000394 BaseSubobjectMethodPairTy SubobjectAndMethod =
395 std::make_pair(BaseSubobject(OverriddenRD, Offset), OverriddenMD);
396
397 OverriderInfo &Overrider = OverridersMap[SubobjectAndMethod];
398
Anders Carlsson136bd192010-02-12 16:55:34 +0000399 assert(Overrider.Method && "Did not find existing overrider!");
Anders Carlsson9fbf6d92010-02-12 01:40:03 +0000400
Anders Carlssoneee53d92010-02-13 02:02:03 +0000401 // Get the return adjustment base offset.
402 BaseOffset ReturnBaseOffset =
403 ComputeReturnTypeBaseOffset(Context, NewMD, OverriddenMD);
404 if (!ReturnBaseOffset.isEmpty()) {
405 // Store the return adjustment base offset.
406 ReturnAdjustments[SubobjectAndMethod] = ReturnBaseOffset;
Anders Carlsson8e661e12010-02-12 17:13:23 +0000407 }
408
Anders Carlsson9fbf6d92010-02-12 01:40:03 +0000409 // Set the new overrider.
Anders Carlsson136bd192010-02-12 16:55:34 +0000410 Overrider.Method = NewMD;
Anders Carlsson9fbf6d92010-02-12 01:40:03 +0000411
412 // And propagate it further.
413 PropagateOverrider(OverriddenMD, NewMD, Offsets);
414 }
415 }
416}
417
418void
419FinalOverriders::MergeSubobjectOffsets(const SubobjectOffsetsMapTy &NewOffsets,
420 SubobjectOffsetsMapTy &Offsets) {
421 // Iterate over the new offsets.
422 for (SubobjectOffsetsMapTy::const_iterator I = NewOffsets.begin(),
423 E = NewOffsets.end(); I != E; ++I) {
424 const CXXRecordDecl *NewRD = I->first;
425 const OffsetVectorTy& NewOffsetsVector = I->second;
426
427 OffsetVectorTy &OffsetsVector = Offsets[NewRD];
428 if (OffsetsVector.empty()) {
429 // There were no previous offsets in this vector, just insert all entries
430 // from the new offsets vector.
431 OffsetsVector.append(NewOffsetsVector.begin(), NewOffsetsVector.end());
432 continue;
433 }
434
435 assert(false && "FIXME: Handle merging the subobject offsets!");
436 }
437}
438
439void FinalOverriders::ComputeFinalOverriders(BaseSubobject Base,
440 SubobjectOffsetsMapTy &Offsets) {
Anders Carlssone8ac42a2010-02-11 21:24:32 +0000441 const CXXRecordDecl *RD = Base.getBase();
Anders Carlsson9fbf6d92010-02-12 01:40:03 +0000442 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
Anders Carlssone8ac42a2010-02-11 21:24:32 +0000443
Anders Carlsson9fbf6d92010-02-12 01:40:03 +0000444 SubobjectOffsetsMapTy NewOffsets;
445
446 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
447 E = RD->bases_end(); I != E; ++I) {
448 const CXXRecordDecl *BaseDecl =
449 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
450
451 assert(!I->isVirtual() && "FIXME: Handle virtual bases!");
452
453 uint64_t BaseOffset = Layout.getBaseClassOffset(BaseDecl) +
454 Base.getBaseOffset();
455
456 // Compute the final overriders for this base.
457 ComputeFinalOverriders(BaseSubobject(BaseDecl, BaseOffset), NewOffsets);
458 }
459
460 /// Now add the overriders for this particular subobject.
461 AddOverriders(Base, NewOffsets);
462
463 // And merge the newly discovered subobject offsets.
464 MergeSubobjectOffsets(NewOffsets, Offsets);
465
466 /// Finally, add the offset for our own subobject.
467 Offsets[RD].push_back(Base.getBaseOffset());
Anders Carlssone8ac42a2010-02-11 21:24:32 +0000468}
469
470void FinalOverriders::dump(llvm::raw_ostream &Out, BaseSubobject Base) const {
471
472 const CXXRecordDecl *RD = Base.getBase();
473 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
474
475 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
476 E = RD->bases_end(); I != E; ++I) {
477 assert(!I->isVirtual() && "FIXME: Handle virtual bases!");
478
479 const CXXRecordDecl *BaseDecl =
480 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
481
482 uint64_t BaseOffset = Layout.getBaseClassOffset(BaseDecl) +
483 Base.getBaseOffset();
484
485 dump(Out, BaseSubobject(BaseDecl, BaseOffset));
486 }
487
488 Out << "Final overriders for (" << RD->getQualifiedNameAsString() << ", ";
489 Out << Base.getBaseOffset() << ")\n";
490
491 // Now dump the overriders for this base subobject.
492 for (CXXRecordDecl::method_iterator I = RD->method_begin(),
493 E = RD->method_end(); I != E; ++I) {
494 const CXXMethodDecl *MD = *I;
495
496 if (!MD->isVirtual())
497 continue;
498
Anders Carlsson136bd192010-02-12 16:55:34 +0000499 OverriderInfo Overrider = getOverrider(Base, MD);
Anders Carlssone8ac42a2010-02-11 21:24:32 +0000500
501 Out << " " << MD->getQualifiedNameAsString() << " - ";
Anders Carlsson8e661e12010-02-12 17:13:23 +0000502 Out << Overrider.Method->getQualifiedNameAsString();
Anders Carlssoneee53d92010-02-13 02:02:03 +0000503
Benjamin Kramer02c67372010-02-13 09:11:28 +0000504 AdjustmentOffsetsMapTy::const_iterator AI =
Anders Carlssoneee53d92010-02-13 02:02:03 +0000505 ReturnAdjustments.find(std::make_pair(Base, MD));
Benjamin Kramer02c67372010-02-13 09:11:28 +0000506 if (AI != ReturnAdjustments.end()) {
507 const BaseOffset &Offset = AI->second;
Anders Carlssoneee53d92010-02-13 02:02:03 +0000508
509 assert(!Offset.VirtualBase && "FIXME: Handle vbases!");
510
511 Out << " [ret-adj: " << Offset.NonVirtualOffset << " nv]";
512 }
Anders Carlsson8e661e12010-02-12 17:13:23 +0000513 Out << "\n";
Anders Carlssone8ac42a2010-02-11 21:24:32 +0000514 }
515}
516
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000517/// VtableComponent - Represents a single component in a vtable.
518class VtableComponent {
519public:
520 enum Kind {
521 CK_VCallOffset,
522 CK_VBaseOffset,
523 CK_OffsetToTop,
524 CK_RTTI,
Anders Carlsson5bd8d192010-02-11 18:20:28 +0000525 CK_FunctionPointer,
526
527 /// CK_CompleteDtorPointer - A pointer to the complete destructor.
528 CK_CompleteDtorPointer,
529
530 /// CK_DeletingDtorPointer - A pointer to the deleting destructor.
531 CK_DeletingDtorPointer
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000532 };
533
534 /// dump - Dump the contents of this component to the given stream.
535 void dump(llvm::raw_ostream &Out);
536
537 static VtableComponent MakeOffsetToTop(int64_t Offset) {
538 return VtableComponent(CK_OffsetToTop, Offset);
539 }
540
541 static VtableComponent MakeRTTI(const CXXRecordDecl *RD) {
542 return VtableComponent(CK_RTTI, reinterpret_cast<uintptr_t>(RD));
543 }
544
545 static VtableComponent MakeFunction(const CXXMethodDecl *MD) {
546 assert(!isa<CXXDestructorDecl>(MD) &&
Anders Carlsson5bd8d192010-02-11 18:20:28 +0000547 "Don't use MakeFunction with destructors!");
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000548
Anders Carlsson5bd8d192010-02-11 18:20:28 +0000549 return VtableComponent(CK_FunctionPointer,
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000550 reinterpret_cast<uintptr_t>(MD));
551 }
552
Anders Carlsson5bd8d192010-02-11 18:20:28 +0000553 static VtableComponent MakeCompleteDtor(const CXXDestructorDecl *DD) {
554 return VtableComponent(CK_CompleteDtorPointer,
555 reinterpret_cast<uintptr_t>(DD));
556 }
557
558 static VtableComponent MakeDeletingDtor(const CXXDestructorDecl *DD) {
559 return VtableComponent(CK_DeletingDtorPointer,
560 reinterpret_cast<uintptr_t>(DD));
561 }
562
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000563 /// getKind - Get the kind of this vtable component.
564 Kind getKind() const {
565 return (Kind)(Value & 0x7);
566 }
567
568 int64_t getOffsetToTop() const {
569 assert(getKind() == CK_OffsetToTop && "Invalid component kind!");
570
571 return getOffset();
572 }
573
574 const CXXRecordDecl *getRTTIDecl() const {
575 assert(getKind() == CK_RTTI && "Invalid component kind!");
576
577 return reinterpret_cast<CXXRecordDecl *>(getPointer());
578 }
579
580 const CXXMethodDecl *getFunctionDecl() const {
Anders Carlsson5bd8d192010-02-11 18:20:28 +0000581 assert(getKind() == CK_FunctionPointer);
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000582
583 return reinterpret_cast<CXXMethodDecl *>(getPointer());
584 }
Anders Carlsson5bd8d192010-02-11 18:20:28 +0000585
586 const CXXDestructorDecl *getDestructorDecl() const {
587 assert((getKind() == CK_CompleteDtorPointer ||
588 getKind() == CK_DeletingDtorPointer) && "Invalid component kind!");
589
590 return reinterpret_cast<CXXDestructorDecl *>(getPointer());
591 }
592
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000593private:
594 VtableComponent(Kind ComponentKind, int64_t Offset) {
595 assert((ComponentKind == CK_VCallOffset ||
596 ComponentKind == CK_VBaseOffset ||
597 ComponentKind == CK_OffsetToTop) && "Invalid component kind!");
598 assert(Offset <= ((1LL << 56) - 1) && "Offset is too big!");
599
600 Value = ((Offset << 3) | ComponentKind);
601 }
602
603 VtableComponent(Kind ComponentKind, uintptr_t Ptr) {
604 assert((ComponentKind == CK_RTTI ||
Anders Carlsson5bd8d192010-02-11 18:20:28 +0000605 ComponentKind == CK_FunctionPointer ||
606 ComponentKind == CK_CompleteDtorPointer ||
607 ComponentKind == CK_DeletingDtorPointer) &&
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000608 "Invalid component kind!");
609
610 assert((Ptr & 7) == 0 && "Pointer not sufficiently aligned!");
611
612 Value = Ptr | ComponentKind;
613 }
614
615 int64_t getOffset() const {
616 assert((getKind() == CK_VCallOffset || getKind() == CK_VBaseOffset ||
617 getKind() == CK_OffsetToTop) && "Invalid component kind!");
618
619 return Value >> 3;
620 }
621
622 uintptr_t getPointer() const {
Anders Carlsson5bd8d192010-02-11 18:20:28 +0000623 assert((getKind() == CK_RTTI ||
624 getKind() == CK_FunctionPointer ||
625 getKind() == CK_CompleteDtorPointer ||
626 getKind() == CK_DeletingDtorPointer) &&
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000627 "Invalid component kind!");
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000628
629 return static_cast<uintptr_t>(Value & ~7ULL);
630 }
631
632 /// The kind is stored in the lower 3 bits of the value. For offsets, we
633 /// make use of the facts that classes can't be larger than 2^55 bytes,
634 /// so we store the offset in the lower part of the 61 bytes that remain.
635 /// (The reason that we're not simply using a PointerIntPair here is that we
636 /// need the offsets to be 64-bit, even when on a 32-bit machine).
637 int64_t Value;
638};
639
640/// VtableBuilder - Class for building vtable layout information.
Benjamin Kramer337e3a52009-11-28 19:45:26 +0000641class VtableBuilder {
Anders Carlsson65b49782010-02-12 05:25:12 +0000642public:
643 /// PrimaryBasesSetTy - A set of direct and indirect primary bases.
644 typedef llvm::SmallPtrSet<const CXXRecordDecl *, 8> PrimaryBasesSetTy;
645
646private:
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000647 /// MostDerivedClass - The most derived class for which we're building this
648 /// vtable.
649 const CXXRecordDecl *MostDerivedClass;
650
651 /// Context - The ASTContext which we will use for layout information.
Anders Carlsson65b49782010-02-12 05:25:12 +0000652 ASTContext &Context;
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000653
Anders Carlssone8ac42a2010-02-11 21:24:32 +0000654 /// FinalOverriders - The final overriders of the most derived class.
655 FinalOverriders Overriders;
656
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000657 /// Components - The components of the vtable being built.
658 llvm::SmallVector<VtableComponent, 64> Components;
659
Anders Carlsson932c2f22010-02-11 17:18:51 +0000660 /// AddressPoints - Address points for the vtable being built.
661 CGVtableInfo::AddressPointsMapTy AddressPoints;
662
Anders Carlsson5272c252010-02-12 17:37:14 +0000663 /// ReturnAdjustment - A return adjustment thunk.
664 struct ReturnAdjustment {
665 /// NonVirtual - The non-virtual adjustment from the derived object to its
666 /// nearest virtual base.
667 int64_t NonVirtual;
668
669 /// VBaseOffsetIndex - The index relative to the address point of the
670 /// virtual base class offset.
671 int64_t VBaseOffsetIndex;
672 };
673
Anders Carlsson65b49782010-02-12 05:25:12 +0000674 void layoutVirtualMemberFunctions(BaseSubobject Base,
675 PrimaryBasesSetTy &PrimaryBases);
676
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000677 /// layoutSimpleVtable - A test function that will layout very simple vtables
678 /// without any bases. Just used for testing for now.
Anders Carlsson65b49782010-02-12 05:25:12 +0000679 void layoutSimpleVtable(BaseSubobject Base);
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000680
681public:
682 VtableBuilder(const CXXRecordDecl *MostDerivedClass)
683 : MostDerivedClass(MostDerivedClass),
Anders Carlssone8ac42a2010-02-11 21:24:32 +0000684 Context(MostDerivedClass->getASTContext()), Overriders(MostDerivedClass) {
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000685
Anders Carlsson65b49782010-02-12 05:25:12 +0000686 layoutSimpleVtable(BaseSubobject(MostDerivedClass, 0));
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000687 }
688
689 /// dumpLayout - Dump the vtable layout.
690 void dumpLayout(llvm::raw_ostream&);
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000691};
692
Anders Carlsson65b49782010-02-12 05:25:12 +0000693/// OverridesMethodInPrimaryBase - Checks whether whether this virtual member
694/// function overrides a member function in a direct or indirect primary base.
695/// Returns the overridden member function, or null if none was found.
696static const CXXMethodDecl *
697OverridesMethodInPrimaryBase(const CXXMethodDecl *MD,
698 VtableBuilder::PrimaryBasesSetTy &PrimaryBases) {
699 for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
700 E = MD->end_overridden_methods(); I != E; ++I) {
701 const CXXMethodDecl *OverriddenMD = *I;
702 const CXXRecordDecl *OverriddenRD = OverriddenMD->getParent();
703 assert(OverriddenMD->isCanonicalDecl() &&
704 "Should have the canonical decl of the overridden RD!");
705
706 if (PrimaryBases.count(OverriddenRD))
707 return OverriddenMD;
708 }
709
710 return 0;
711}
712
713void
714VtableBuilder::layoutVirtualMemberFunctions(BaseSubobject Base,
715 PrimaryBasesSetTy &PrimaryBases) {
716 const CXXRecordDecl *RD = Base.getBase();
717
718 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
719
720 if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) {
721 if (Layout.getPrimaryBaseWasVirtual())
722 assert(false && "FIXME: Handle vbases here.");
723 else
724 assert(Layout.getBaseClassOffset(PrimaryBase) == 0 &&
725 "Primary base should have a zero offset!");
726
727 layoutVirtualMemberFunctions(BaseSubobject(PrimaryBase, 0), PrimaryBases);
728
729 if (!PrimaryBases.insert(PrimaryBase))
730 assert(false && "Found a duplicate primary base!");
731 }
Anders Carlsson932c2f22010-02-11 17:18:51 +0000732
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000733 // Now go through all virtual member functions and add them.
734 for (CXXRecordDecl::method_iterator I = RD->method_begin(),
735 E = RD->method_end(); I != E; ++I) {
736 const CXXMethodDecl *MD = *I;
Anders Carlsson65b49782010-02-12 05:25:12 +0000737
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000738 if (!MD->isVirtual())
739 continue;
Anders Carlsson65b49782010-02-12 05:25:12 +0000740
741 // Get the final overrider.
Anders Carlsson136bd192010-02-12 16:55:34 +0000742 FinalOverriders::OverriderInfo Overrider =
743 Overriders.getOverrider(Base, MD);
Anders Carlsson65b49782010-02-12 05:25:12 +0000744
745 // Check if this virtual member function overrides a method in a primary
746 // base. If this is the case, and the return type doesn't require adjustment
747 // then we can just use the member function from the primary base.
Anders Carlsson5272c252010-02-12 17:37:14 +0000748 if (const CXXMethodDecl *OverriddenMD =
749 OverridesMethodInPrimaryBase(MD, PrimaryBases)) {
Anders Carlssoneee53d92010-02-13 02:02:03 +0000750 assert(!ReturnTypeConversionRequiresAdjustment(MD, OverriddenMD)
Anders Carlsson5272c252010-02-12 17:37:14 +0000751 && "FIXME: Handle covariant thunks!");
Anders Carlssoneee53d92010-02-13 02:02:03 +0000752
Anders Carlsson65b49782010-02-12 05:25:12 +0000753 continue;
754 }
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000755
Anders Carlsson5bd8d192010-02-11 18:20:28 +0000756 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
757 // Add both the complete destructor and the deleting destructor.
758 Components.push_back(VtableComponent::MakeCompleteDtor(DD));
759 Components.push_back(VtableComponent::MakeDeletingDtor(DD));
760 } else {
761 // Add the function.
762 Components.push_back(VtableComponent::MakeFunction(MD));
763 }
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000764 }
765}
766
Anders Carlsson65b49782010-02-12 05:25:12 +0000767void VtableBuilder::layoutSimpleVtable(BaseSubobject Base) {
768 const CXXRecordDecl *RD = Base.getBase();
769
770 // First, add the offset to top.
771 Components.push_back(VtableComponent::MakeOffsetToTop(0));
772
773 // Next, add the RTTI.
774 Components.push_back(VtableComponent::MakeRTTI(RD));
775
Anders Carlssone8a97562010-02-12 07:43:48 +0000776 uint64_t AddressPoint = Components.size();
Anders Carlsson65b49782010-02-12 05:25:12 +0000777
778 // Now go through all virtual member functions and add them.
779 PrimaryBasesSetTy PrimaryBases;
780 layoutVirtualMemberFunctions(Base, PrimaryBases);
781
Anders Carlssone8a97562010-02-12 07:43:48 +0000782 // Record the address point.
783 AddressPoints.insert(std::make_pair(Base, AddressPoint));
784
785 // Record the address points for all primary bases.
786 for (PrimaryBasesSetTy::const_iterator I = PrimaryBases.begin(),
787 E = PrimaryBases.end(); I != E; ++I) {
788 const CXXRecordDecl *BaseDecl = *I;
789
790 // We know that all the primary bases have the same offset as the base
791 // subobject.
792 BaseSubobject PrimaryBase(BaseDecl, Base.getBaseOffset());
793 AddressPoints.insert(std::make_pair(PrimaryBase, AddressPoint));
794 }
795
Anders Carlsson65b49782010-02-12 05:25:12 +0000796 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
797 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
798
799 // Traverse bases.
800 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
801 E = RD->bases_end(); I != E; ++I) {
802 const CXXRecordDecl *BaseDecl =
803 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
804
805 // Ignore the primary base.
806 if (BaseDecl == PrimaryBase)
807 continue;
808
809 assert(!I->isVirtual() && "FIXME: Handle virtual bases");
810
811 assert(false && "FIXME: Handle secondary virtual tables!");
812 }
813}
814
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000815/// dumpLayout - Dump the vtable layout.
816void VtableBuilder::dumpLayout(llvm::raw_ostream& Out) {
817
818 Out << "Vtable for '" << MostDerivedClass->getQualifiedNameAsString();
819 Out << "' (" << Components.size() << " entries).\n";
820
Anders Carlsson932c2f22010-02-11 17:18:51 +0000821 // Iterate through the address points and insert them into a new map where
822 // they are keyed by the index and not the base object.
823 // Since an address point can be shared by multiple subobjects, we use an
824 // STL multimap.
825 std::multimap<uint64_t, BaseSubobject> AddressPointsByIndex;
826 for (CGVtableInfo::AddressPointsMapTy::const_iterator I =
827 AddressPoints.begin(), E = AddressPoints.end(); I != E; ++I) {
828 const BaseSubobject& Base = I->first;
829 uint64_t Index = I->second;
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000830
Anders Carlsson932c2f22010-02-11 17:18:51 +0000831 AddressPointsByIndex.insert(std::make_pair(Index, Base));
832 }
833
834 for (unsigned I = 0, E = Components.size(); I != E; ++I) {
Anders Carlssone8a97562010-02-12 07:43:48 +0000835 uint64_t Index = I;
836
Anders Carlsson932c2f22010-02-11 17:18:51 +0000837 if (AddressPointsByIndex.count(I)) {
Anders Carlssone8a97562010-02-12 07:43:48 +0000838 if (AddressPointsByIndex.count(Index) == 1) {
839 const BaseSubobject &Base = AddressPointsByIndex.find(Index)->second;
840
841 // FIXME: Instead of dividing by 8, we should be using CharUnits.
842 Out << " -- (" << Base.getBase()->getQualifiedNameAsString();
843 Out << ", " << Base.getBaseOffset() / 8 << ") vtable address --\n";
844 } else {
845 uint64_t BaseOffset =
846 AddressPointsByIndex.lower_bound(Index)->second.getBaseOffset();
847
848 // We store the class names in a set to get a stable order.
849 std::set<std::string> ClassNames;
850 for (std::multimap<uint64_t, BaseSubobject>::const_iterator I =
851 AddressPointsByIndex.lower_bound(Index), E =
852 AddressPointsByIndex.upper_bound(Index); I != E; ++I) {
853 assert(I->second.getBaseOffset() == BaseOffset &&
854 "Invalid base offset!");
855 const CXXRecordDecl *RD = I->second.getBase();
856 ClassNames.insert(RD->getQualifiedNameAsString());
857 }
858
859 for (std::set<std::string>::const_iterator I = ClassNames.begin(),
860 E = ClassNames.end(); I != E; ++I) {
861 // FIXME: Instead of dividing by 8, we should be using CharUnits.
862 Out << " -- (" << *I;
863 Out << ", " << BaseOffset / 8 << ") vtable address --\n";
864 }
865 }
Anders Carlsson932c2f22010-02-11 17:18:51 +0000866 }
867
868 Out << llvm::format("%4d | ", I);
869
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000870 const VtableComponent &Component = Components[I];
871
872 // Dump the component.
873 switch (Component.getKind()) {
874 // FIXME: Remove this default case.
875 default:
876 assert(false && "Unhandled component kind!");
877 break;
878
879 case VtableComponent::CK_OffsetToTop:
880 Out << "offset_to_top (" << Component.getOffsetToTop() << ")";
881 break;
882
883 case VtableComponent::CK_RTTI:
884 Out << Component.getRTTIDecl()->getQualifiedNameAsString() << " RTTI";
885 break;
886
Anders Carlsson5bd8d192010-02-11 18:20:28 +0000887 case VtableComponent::CK_FunctionPointer: {
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000888 const CXXMethodDecl *MD = Component.getFunctionDecl();
889
Anders Carlsson5bd8d192010-02-11 18:20:28 +0000890 std::string Str =
891 PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual,
892 MD);
893 Out << Str;
Anders Carlsson09da3372010-02-12 02:38:13 +0000894 if (MD->isPure())
895 Out << " [pure]";
896
Anders Carlsson5bd8d192010-02-11 18:20:28 +0000897 break;
898 }
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000899
Anders Carlsson5bd8d192010-02-11 18:20:28 +0000900 case VtableComponent::CK_CompleteDtorPointer: {
901 const CXXDestructorDecl *DD = Component.getDestructorDecl();
902
903 Out << DD->getQualifiedNameAsString() << "() [complete]";
Anders Carlsson09da3372010-02-12 02:38:13 +0000904 if (DD->isPure())
905 Out << " [pure]";
906
Anders Carlsson5bd8d192010-02-11 18:20:28 +0000907 break;
908 }
909
910 case VtableComponent::CK_DeletingDtorPointer: {
911 const CXXDestructorDecl *DD = Component.getDestructorDecl();
912
913 Out << DD->getQualifiedNameAsString() << "() [deleting]";
Anders Carlsson09da3372010-02-12 02:38:13 +0000914 if (DD->isPure())
915 Out << " [pure]";
916
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000917 break;
918 }
919
920 }
Anders Carlsson932c2f22010-02-11 17:18:51 +0000921
Anders Carlsson5d40c6f2010-02-11 08:02:13 +0000922 Out << '\n';
923 }
924
925}
926
927}
928
929namespace {
930class OldVtableBuilder {
Anders Carlsson2bb27f52009-10-11 22:13:54 +0000931public:
932 /// Index_t - Vtable index type.
933 typedef uint64_t Index_t;
Eli Friedman31bc3ad2009-12-07 23:56:34 +0000934 typedef std::vector<std::pair<GlobalDecl,
935 std::pair<GlobalDecl, ThunkAdjustment> > >
936 SavedAdjustmentsVectorTy;
Anders Carlsson2bb27f52009-10-11 22:13:54 +0000937private:
Anders Carlsson472404f2009-12-04 16:19:30 +0000938
Anders Carlssonfe5f7d92009-12-06 01:09:21 +0000939 // VtableComponents - The components of the vtable being built.
940 typedef llvm::SmallVector<llvm::Constant *, 64> VtableComponentsVectorTy;
941 VtableComponentsVectorTy VtableComponents;
942
Eli Friedman6c08ce72009-12-05 01:05:03 +0000943 const bool BuildVtable;
944
Anders Carlsson2bb27f52009-10-11 22:13:54 +0000945 llvm::Type *Ptr8Ty;
Anders Carlssonbad80eb2009-12-04 18:36:22 +0000946
947 /// MostDerivedClass - The most derived class that this vtable is being
948 /// built for.
949 const CXXRecordDecl *MostDerivedClass;
950
Mike Stump83066c82009-11-13 01:54:23 +0000951 /// LayoutClass - The most derived class used for virtual base layout
952 /// information.
953 const CXXRecordDecl *LayoutClass;
Mike Stump653d0b92009-11-13 02:13:54 +0000954 /// LayoutOffset - The offset for Class in LayoutClass.
955 uint64_t LayoutOffset;
Anders Carlsson2bb27f52009-10-11 22:13:54 +0000956 /// BLayout - Layout for the most derived class that this vtable is being
957 /// built for.
958 const ASTRecordLayout &BLayout;
959 llvm::SmallSet<const CXXRecordDecl *, 32> IndirectPrimary;
960 llvm::SmallSet<const CXXRecordDecl *, 32> SeenVBase;
961 llvm::Constant *rtti;
962 llvm::LLVMContext &VMContext;
963 CodeGenModule &CGM; // Per-module state.
Anders Carlssonf2f31f42009-12-04 03:46:21 +0000964
Mike Stump90181eb2010-01-26 00:05:04 +0000965 llvm::DenseMap<const CXXMethodDecl *, Index_t> VCall;
Anders Carlssonfb4dda42009-11-13 17:08:56 +0000966 llvm::DenseMap<GlobalDecl, Index_t> VCallOffset;
Mike Stump77537b12010-01-26 03:42:22 +0000967 llvm::DenseMap<GlobalDecl, Index_t> VCallOffsetForVCall;
Mike Stumpcd6f9ed2009-11-06 23:27:42 +0000968 // This is the offset to the nearest virtual base
Mike Stump90181eb2010-01-26 00:05:04 +0000969 llvm::DenseMap<const CXXMethodDecl *, Index_t> NonVirtualOffset;
Anders Carlsson2bb27f52009-10-11 22:13:54 +0000970 llvm::DenseMap<const CXXRecordDecl *, Index_t> VBIndex;
Mike Stumpbb9ff052009-10-27 23:46:47 +0000971
Anders Carlsson323bb042009-11-26 19:54:33 +0000972 /// PureVirtualFunction - Points to __cxa_pure_virtual.
973 llvm::Constant *PureVirtualFn;
974
Anders Carlssona84b6e82009-12-04 02:01:07 +0000975 /// VtableMethods - A data structure for keeping track of methods in a vtable.
976 /// Can add methods, override methods and iterate in vtable order.
977 class VtableMethods {
978 // MethodToIndexMap - Maps from a global decl to the index it has in the
979 // Methods vector.
980 llvm::DenseMap<GlobalDecl, uint64_t> MethodToIndexMap;
981
982 /// Methods - The methods, in vtable order.
983 typedef llvm::SmallVector<GlobalDecl, 16> MethodsVectorTy;
984 MethodsVectorTy Methods;
Eli Friedman8174f2c2009-12-06 22:01:30 +0000985 MethodsVectorTy OrigMethods;
Anders Carlssona84b6e82009-12-04 02:01:07 +0000986
987 public:
988 /// AddMethod - Add a method to the vtable methods.
989 void AddMethod(GlobalDecl GD) {
990 assert(!MethodToIndexMap.count(GD) &&
991 "Method has already been added!");
992
993 MethodToIndexMap[GD] = Methods.size();
994 Methods.push_back(GD);
Eli Friedman8174f2c2009-12-06 22:01:30 +0000995 OrigMethods.push_back(GD);
Anders Carlssona84b6e82009-12-04 02:01:07 +0000996 }
997
998 /// OverrideMethod - Replace a method with another.
999 void OverrideMethod(GlobalDecl OverriddenGD, GlobalDecl GD) {
1000 llvm::DenseMap<GlobalDecl, uint64_t>::iterator i
1001 = MethodToIndexMap.find(OverriddenGD);
1002 assert(i != MethodToIndexMap.end() && "Did not find entry!");
1003
1004 // Get the index of the old decl.
1005 uint64_t Index = i->second;
1006
1007 // Replace the old decl with the new decl.
1008 Methods[Index] = GD;
1009
Anders Carlssona84b6e82009-12-04 02:01:07 +00001010 // And add the new.
1011 MethodToIndexMap[GD] = Index;
1012 }
1013
Anders Carlsson7bb70762009-12-04 15:49:02 +00001014 /// getIndex - Gives the index of a passed in GlobalDecl. Returns false if
1015 /// the index couldn't be found.
Benjamin Kramer62ab6162009-12-04 22:45:27 +00001016 bool getIndex(GlobalDecl GD, uint64_t &Index) const {
Anders Carlsson7bb70762009-12-04 15:49:02 +00001017 llvm::DenseMap<GlobalDecl, uint64_t>::const_iterator i
1018 = MethodToIndexMap.find(GD);
Eli Friedman3d2e9de2009-12-04 08:34:14 +00001019
Anders Carlsson7bb70762009-12-04 15:49:02 +00001020 if (i == MethodToIndexMap.end())
1021 return false;
Anders Carlssone6096362009-12-04 03:41:37 +00001022
Anders Carlsson7bb70762009-12-04 15:49:02 +00001023 Index = i->second;
1024 return true;
Anders Carlssone6096362009-12-04 03:41:37 +00001025 }
1026
Eli Friedman8174f2c2009-12-06 22:01:30 +00001027 GlobalDecl getOrigMethod(uint64_t Index) const {
1028 return OrigMethods[Index];
1029 }
1030
Anders Carlssona84b6e82009-12-04 02:01:07 +00001031 MethodsVectorTy::size_type size() const {
1032 return Methods.size();
1033 }
1034
1035 void clear() {
1036 MethodToIndexMap.clear();
1037 Methods.clear();
Eli Friedman8174f2c2009-12-06 22:01:30 +00001038 OrigMethods.clear();
Anders Carlssona84b6e82009-12-04 02:01:07 +00001039 }
1040
Anders Carlssone6096362009-12-04 03:41:37 +00001041 GlobalDecl operator[](uint64_t Index) const {
Anders Carlssona84b6e82009-12-04 02:01:07 +00001042 return Methods[Index];
1043 }
1044 };
1045
1046 /// Methods - The vtable methods we're currently building.
1047 VtableMethods Methods;
1048
Anders Carlsson4c837d22009-12-04 02:26:15 +00001049 /// ThisAdjustments - For a given index in the vtable, contains the 'this'
1050 /// pointer adjustment needed for a method.
1051 typedef llvm::DenseMap<uint64_t, ThunkAdjustment> ThisAdjustmentsMapTy;
1052 ThisAdjustmentsMapTy ThisAdjustments;
Anders Carlssond420a312009-11-26 19:32:45 +00001053
Eli Friedman31bc3ad2009-12-07 23:56:34 +00001054 SavedAdjustmentsVectorTy SavedAdjustments;
Eli Friedman8174f2c2009-12-06 22:01:30 +00001055
Anders Carlssonc521f952009-12-04 02:22:02 +00001056 /// BaseReturnTypes - Contains the base return types of methods who have been
1057 /// overridden with methods whose return types require adjustment. Used for
1058 /// generating covariant thunk information.
1059 typedef llvm::DenseMap<uint64_t, CanQualType> BaseReturnTypesMapTy;
1060 BaseReturnTypesMapTy BaseReturnTypes;
Anders Carlssond420a312009-11-26 19:32:45 +00001061
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001062 std::vector<Index_t> VCalls;
Mike Stump2cefe382009-11-12 20:47:57 +00001063
1064 typedef std::pair<const CXXRecordDecl *, uint64_t> CtorVtable_t;
Mike Stumpcd2b8212009-11-19 20:52:19 +00001065 // subAddressPoints - Used to hold the AddressPoints (offsets) into the built
1066 // vtable for use in computing the initializers for the VTT.
1067 llvm::DenseMap<CtorVtable_t, int64_t> &subAddressPoints;
Mike Stump2cefe382009-11-12 20:47:57 +00001068
Anders Carlsson5f9a8812010-01-14 02:29:07 +00001069 /// AddressPoints - Address points for this vtable.
1070 CGVtableInfo::AddressPointsMapTy& AddressPoints;
1071
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001072 typedef CXXRecordDecl::method_iterator method_iter;
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001073 const uint32_t LLVMPointerWidth;
1074 Index_t extra;
Mike Stump37dbe962009-10-15 02:04:03 +00001075 typedef std::vector<std::pair<const CXXRecordDecl *, int64_t> > Path_t;
Mike Stumpcd2b8212009-11-19 20:52:19 +00001076 static llvm::DenseMap<CtorVtable_t, int64_t>&
1077 AllocAddressPoint(CodeGenModule &cgm, const CXXRecordDecl *l,
1078 const CXXRecordDecl *c) {
Anders Carlsson93a18842010-01-02 18:02:32 +00001079 CGVtableInfo::AddrMap_t *&oref = cgm.getVtableInfo().AddressPoints[l];
Mike Stumpcd2b8212009-11-19 20:52:19 +00001080 if (oref == 0)
Anders Carlsson93a18842010-01-02 18:02:32 +00001081 oref = new CGVtableInfo::AddrMap_t;
Mike Stumpcd2b8212009-11-19 20:52:19 +00001082
1083 llvm::DenseMap<CtorVtable_t, int64_t> *&ref = (*oref)[c];
1084 if (ref == 0)
1085 ref = new llvm::DenseMap<CtorVtable_t, int64_t>;
1086 return *ref;
1087 }
Anders Carlsson323bb042009-11-26 19:54:33 +00001088
Mike Stump90181eb2010-01-26 00:05:04 +00001089 bool DclIsSame(const FunctionDecl *New, const FunctionDecl *Old) {
1090 FunctionTemplateDecl *OldTemplate = Old->getDescribedFunctionTemplate();
1091 FunctionTemplateDecl *NewTemplate = New->getDescribedFunctionTemplate();
1092
1093 // C++ [temp.fct]p2:
1094 // A function template can be overloaded with other function templates
1095 // and with normal (non-template) functions.
1096 if ((OldTemplate == 0) != (NewTemplate == 0))
1097 return false;
1098
1099 // Is the function New an overload of the function Old?
1100 QualType OldQType = CGM.getContext().getCanonicalType(Old->getType());
1101 QualType NewQType = CGM.getContext().getCanonicalType(New->getType());
1102
1103 // Compare the signatures (C++ 1.3.10) of the two functions to
1104 // determine whether they are overloads. If we find any mismatch
1105 // in the signature, they are overloads.
1106
1107 // If either of these functions is a K&R-style function (no
1108 // prototype), then we consider them to have matching signatures.
1109 if (isa<FunctionNoProtoType>(OldQType.getTypePtr()) ||
1110 isa<FunctionNoProtoType>(NewQType.getTypePtr()))
1111 return true;
1112
1113 FunctionProtoType* OldType = cast<FunctionProtoType>(OldQType);
1114 FunctionProtoType* NewType = cast<FunctionProtoType>(NewQType);
1115
1116 // The signature of a function includes the types of its
1117 // parameters (C++ 1.3.10), which includes the presence or absence
1118 // of the ellipsis; see C++ DR 357).
1119 if (OldQType != NewQType &&
1120 (OldType->getNumArgs() != NewType->getNumArgs() ||
1121 OldType->isVariadic() != NewType->isVariadic() ||
1122 !std::equal(OldType->arg_type_begin(), OldType->arg_type_end(),
1123 NewType->arg_type_begin())))
1124 return false;
1125
1126#if 0
1127 // C++ [temp.over.link]p4:
1128 // The signature of a function template consists of its function
1129 // signature, its return type and its template parameter list. The names
1130 // of the template parameters are significant only for establishing the
1131 // relationship between the template parameters and the rest of the
1132 // signature.
1133 //
1134 // We check the return type and template parameter lists for function
1135 // templates first; the remaining checks follow.
1136 if (NewTemplate &&
1137 (!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
1138 OldTemplate->getTemplateParameters(),
1139 TPL_TemplateMatch) ||
1140 OldType->getResultType() != NewType->getResultType()))
1141 return false;
1142#endif
1143
1144 // If the function is a class member, its signature includes the
1145 // cv-qualifiers (if any) on the function itself.
1146 //
1147 // As part of this, also check whether one of the member functions
1148 // is static, in which case they are not overloads (C++
1149 // 13.1p2). While not part of the definition of the signature,
1150 // this check is important to determine whether these functions
1151 // can be overloaded.
1152 const CXXMethodDecl* OldMethod = dyn_cast<CXXMethodDecl>(Old);
1153 const CXXMethodDecl* NewMethod = dyn_cast<CXXMethodDecl>(New);
1154 if (OldMethod && NewMethod &&
1155 !OldMethod->isStatic() && !NewMethod->isStatic() &&
1156 OldMethod->getTypeQualifiers() != NewMethod->getTypeQualifiers())
1157 return false;
1158
1159 // The signatures match; this is not an overload.
1160 return true;
1161 }
1162
1163 typedef llvm::DenseMap<const CXXMethodDecl *, const CXXMethodDecl*>
1164 ForwardUnique_t;
1165 ForwardUnique_t ForwardUnique;
1166 llvm::DenseMap<const CXXMethodDecl*, const CXXMethodDecl*> UniqueOverrider;
1167
1168 void BuildUniqueOverrider(const CXXMethodDecl *U, const CXXMethodDecl *MD) {
1169 const CXXMethodDecl *PrevU = UniqueOverrider[MD];
1170 assert(U && "no unique overrider");
1171 if (PrevU == U)
1172 return;
1173 if (PrevU != U && PrevU != 0) {
1174 // If already set, note the two sets as the same
1175 if (0)
1176 printf("%s::%s same as %s::%s\n",
1177 PrevU->getParent()->getNameAsCString(),
1178 PrevU->getNameAsCString(),
1179 U->getParent()->getNameAsCString(),
1180 U->getNameAsCString());
1181 ForwardUnique[PrevU] = U;
1182 return;
1183 }
1184
1185 // Not set, set it now
1186 if (0)
1187 printf("marking %s::%s %p override as %s::%s\n",
1188 MD->getParent()->getNameAsCString(),
1189 MD->getNameAsCString(),
1190 (void*)MD,
1191 U->getParent()->getNameAsCString(),
1192 U->getNameAsCString());
1193 UniqueOverrider[MD] = U;
1194
1195 for (CXXMethodDecl::method_iterator mi = MD->begin_overridden_methods(),
1196 me = MD->end_overridden_methods(); mi != me; ++mi) {
1197 BuildUniqueOverrider(U, *mi);
1198 }
1199 }
1200
1201 void BuildUniqueOverriders(const CXXRecordDecl *RD) {
1202 if (0) printf("walking %s\n", RD->getNameAsCString());
1203 for (CXXRecordDecl::method_iterator i = RD->method_begin(),
1204 e = RD->method_end(); i != e; ++i) {
1205 const CXXMethodDecl *MD = *i;
1206 if (!MD->isVirtual())
1207 continue;
1208
1209 if (UniqueOverrider[MD] == 0) {
1210 // Only set this, if it hasn't been set yet.
1211 BuildUniqueOverrider(MD, MD);
1212 if (0)
1213 printf("top set is %s::%s %p\n",
1214 MD->getParent()->getNameAsCString(),
1215 MD->getNameAsCString(),
1216 (void*)MD);
1217 ForwardUnique[MD] = MD;
1218 }
1219 }
1220 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
1221 e = RD->bases_end(); i != e; ++i) {
1222 const CXXRecordDecl *Base =
1223 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
1224 BuildUniqueOverriders(Base);
1225 }
1226 }
1227
1228 static int DclCmp(const void *p1, const void *p2) {
John McCallef3057c2010-02-13 01:04:05 +00001229 const CXXMethodDecl *MD1 = *(const CXXMethodDecl *const *)p1;
1230 const CXXMethodDecl *MD2 = *(const CXXMethodDecl *const *)p2;
1231
1232 return (DeclarationName::compare(MD1->getDeclName(), MD2->getDeclName()));
Mike Stump90181eb2010-01-26 00:05:04 +00001233 }
1234
1235 void MergeForwarding() {
1236 typedef llvm::SmallVector<const CXXMethodDecl *, 100> A_t;
1237 A_t A;
1238 for (ForwardUnique_t::iterator I = ForwardUnique.begin(),
1239 E = ForwardUnique.end(); I != E; ++I) {
1240 if (I->first == I->second)
1241 // Only add the roots of all trees
1242 A.push_back(I->first);
1243 }
1244 llvm::array_pod_sort(A.begin(), A.end(), DclCmp);
1245 for (A_t::iterator I = A.begin(),
1246 E = A.end(); I != E; ++I) {
1247 A_t::iterator J = I;
John McCallef3057c2010-02-13 01:04:05 +00001248 while (++J != E && DclCmp(I, J) == 0)
Mike Stump90181eb2010-01-26 00:05:04 +00001249 if (DclIsSame(*I, *J)) {
Eli Friedman18c28f62010-02-13 00:03:21 +00001250 if (0) printf("connecting %s\n", (*I)->getNameAsCString());
Mike Stump90181eb2010-01-26 00:05:04 +00001251 ForwardUnique[*J] = *I;
1252 }
1253 }
1254 }
1255
1256 const CXXMethodDecl *getUnique(const CXXMethodDecl *MD) {
1257 const CXXMethodDecl *U = UniqueOverrider[MD];
1258 assert(U && "unique overrider not found");
1259 while (ForwardUnique.count(U)) {
1260 const CXXMethodDecl *NU = ForwardUnique[U];
1261 if (NU == U) break;
1262 U = NU;
1263 }
1264 return U;
1265 }
Anders Carlsson72281172010-01-26 17:36:47 +00001266
1267 GlobalDecl getUnique(GlobalDecl GD) {
1268 const CXXMethodDecl *Unique = getUnique(cast<CXXMethodDecl>(GD.getDecl()));
1269
1270 if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(Unique))
1271 return GlobalDecl(CD, GD.getCtorType());
1272
1273 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(Unique))
1274 return GlobalDecl(DD, GD.getDtorType());
1275
1276 return Unique;
Mike Stump90181eb2010-01-26 00:05:04 +00001277 }
1278
Anders Carlsson323bb042009-11-26 19:54:33 +00001279 /// getPureVirtualFn - Return the __cxa_pure_virtual function.
1280 llvm::Constant* getPureVirtualFn() {
1281 if (!PureVirtualFn) {
1282 const llvm::FunctionType *Ty =
1283 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
1284 /*isVarArg=*/false);
1285 PureVirtualFn = wrap(CGM.CreateRuntimeFunction(Ty, "__cxa_pure_virtual"));
1286 }
1287
1288 return PureVirtualFn;
1289 }
1290
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001291public:
Anders Carlsson5d40c6f2010-02-11 08:02:13 +00001292 OldVtableBuilder(const CXXRecordDecl *MostDerivedClass,
Eli Friedman6c08ce72009-12-05 01:05:03 +00001293 const CXXRecordDecl *l, uint64_t lo, CodeGenModule &cgm,
Anders Carlsson5f9a8812010-01-14 02:29:07 +00001294 bool build, CGVtableInfo::AddressPointsMapTy& AddressPoints)
Eli Friedman6c08ce72009-12-05 01:05:03 +00001295 : BuildVtable(build), MostDerivedClass(MostDerivedClass), LayoutClass(l),
1296 LayoutOffset(lo), BLayout(cgm.getContext().getASTRecordLayout(l)),
1297 rtti(0), VMContext(cgm.getModule().getContext()),CGM(cgm),
1298 PureVirtualFn(0),
Anders Carlssonbad80eb2009-12-04 18:36:22 +00001299 subAddressPoints(AllocAddressPoint(cgm, l, MostDerivedClass)),
Anders Carlsson5f9a8812010-01-14 02:29:07 +00001300 AddressPoints(AddressPoints),
1301 LLVMPointerWidth(cgm.getContext().Target.getPointerWidth(0))
1302 {
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001303 Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
Anders Carlsson3f4336c2009-12-17 07:09:17 +00001304 if (BuildVtable) {
1305 QualType ClassType = CGM.getContext().getTagDeclType(MostDerivedClass);
1306 rtti = CGM.GetAddrOfRTTIDescriptor(ClassType);
1307 }
Mike Stump90181eb2010-01-26 00:05:04 +00001308 BuildUniqueOverriders(MostDerivedClass);
1309 MergeForwarding();
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001310 }
1311
Anders Carlssonfe5f7d92009-12-06 01:09:21 +00001312 // getVtableComponents - Returns a reference to the vtable components.
1313 const VtableComponentsVectorTy &getVtableComponents() const {
1314 return VtableComponents;
Anders Carlsson472404f2009-12-04 16:19:30 +00001315 }
1316
Anders Carlssone36a6b32010-01-02 01:01:18 +00001317 llvm::DenseMap<const CXXRecordDecl *, uint64_t> &getVBIndex()
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001318 { return VBIndex; }
1319
Eli Friedman31bc3ad2009-12-07 23:56:34 +00001320 SavedAdjustmentsVectorTy &getSavedAdjustments()
1321 { return SavedAdjustments; }
Eli Friedman8174f2c2009-12-06 22:01:30 +00001322
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001323 llvm::Constant *wrap(Index_t i) {
1324 llvm::Constant *m;
1325 m = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), i);
1326 return llvm::ConstantExpr::getIntToPtr(m, Ptr8Ty);
1327 }
1328
1329 llvm::Constant *wrap(llvm::Constant *m) {
1330 return llvm::ConstantExpr::getBitCast(m, Ptr8Ty);
1331 }
1332
Mike Stumpd2808442010-01-22 02:51:26 +00001333//#define D1(x)
1334#define D1(X) do { if (getenv("DEBUG")) { X; } } while (0)
Mike Stump75ce5732009-10-31 20:06:59 +00001335
1336 void GenerateVBaseOffsets(const CXXRecordDecl *RD, uint64_t Offset,
Mike Stump28431212009-10-13 22:54:56 +00001337 bool updateVBIndex, Index_t current_vbindex) {
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001338 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
1339 e = RD->bases_end(); i != e; ++i) {
1340 const CXXRecordDecl *Base =
1341 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
Mike Stump28431212009-10-13 22:54:56 +00001342 Index_t next_vbindex = current_vbindex;
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001343 if (i->isVirtual() && !SeenVBase.count(Base)) {
1344 SeenVBase.insert(Base);
Mike Stump28431212009-10-13 22:54:56 +00001345 if (updateVBIndex) {
Mike Stump75ce5732009-10-31 20:06:59 +00001346 next_vbindex = (ssize_t)(-(VCalls.size()*LLVMPointerWidth/8)
Mike Stump28431212009-10-13 22:54:56 +00001347 - 3*LLVMPointerWidth/8);
1348 VBIndex[Base] = next_vbindex;
1349 }
Mike Stump75ce5732009-10-31 20:06:59 +00001350 int64_t BaseOffset = -(Offset/8) + BLayout.getVBaseClassOffset(Base)/8;
1351 VCalls.push_back((0?700:0) + BaseOffset);
1352 D1(printf(" vbase for %s at %d delta %d most derived %s\n",
1353 Base->getNameAsCString(),
1354 (int)-VCalls.size()-3, (int)BaseOffset,
Mike Stumpd2808442010-01-22 02:51:26 +00001355 MostDerivedClass->getNameAsCString()));
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001356 }
Mike Stump28431212009-10-13 22:54:56 +00001357 // We also record offsets for non-virtual bases to closest enclosing
1358 // virtual base. We do this so that we don't have to search
1359 // for the nearst virtual base class when generating thunks.
1360 if (updateVBIndex && VBIndex.count(Base) == 0)
1361 VBIndex[Base] = next_vbindex;
Mike Stump75ce5732009-10-31 20:06:59 +00001362 GenerateVBaseOffsets(Base, Offset, updateVBIndex, next_vbindex);
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001363 }
1364 }
1365
1366 void StartNewTable() {
1367 SeenVBase.clear();
1368 }
1369
Mike Stump8bccbfd2009-10-15 09:30:16 +00001370 Index_t getNVOffset_1(const CXXRecordDecl *D, const CXXRecordDecl *B,
1371 Index_t Offset = 0) {
1372
1373 if (B == D)
1374 return Offset;
1375
1376 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(D);
1377 for (CXXRecordDecl::base_class_const_iterator i = D->bases_begin(),
1378 e = D->bases_end(); i != e; ++i) {
1379 const CXXRecordDecl *Base =
1380 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
1381 int64_t BaseOffset = 0;
1382 if (!i->isVirtual())
1383 BaseOffset = Offset + Layout.getBaseClassOffset(Base);
1384 int64_t o = getNVOffset_1(Base, B, BaseOffset);
1385 if (o >= 0)
1386 return o;
1387 }
1388
1389 return -1;
1390 }
1391
1392 /// getNVOffset - Returns the non-virtual offset for the given (B) base of the
1393 /// derived class D.
1394 Index_t getNVOffset(QualType qB, QualType qD) {
Mike Stump46271322009-11-03 19:03:17 +00001395 qD = qD->getPointeeType();
1396 qB = qB->getPointeeType();
Mike Stump8bccbfd2009-10-15 09:30:16 +00001397 CXXRecordDecl *D = cast<CXXRecordDecl>(qD->getAs<RecordType>()->getDecl());
1398 CXXRecordDecl *B = cast<CXXRecordDecl>(qB->getAs<RecordType>()->getDecl());
1399 int64_t o = getNVOffset_1(D, B);
1400 if (o >= 0)
1401 return o;
1402
1403 assert(false && "FIXME: non-virtual base not found");
1404 return 0;
1405 }
1406
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001407 /// getVbaseOffset - Returns the index into the vtable for the virtual base
1408 /// offset for the given (B) virtual base of the derived class D.
1409 Index_t getVbaseOffset(QualType qB, QualType qD) {
Mike Stump46271322009-11-03 19:03:17 +00001410 qD = qD->getPointeeType();
1411 qB = qB->getPointeeType();
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001412 CXXRecordDecl *D = cast<CXXRecordDecl>(qD->getAs<RecordType>()->getDecl());
1413 CXXRecordDecl *B = cast<CXXRecordDecl>(qB->getAs<RecordType>()->getDecl());
Anders Carlssonbad80eb2009-12-04 18:36:22 +00001414 if (D != MostDerivedClass)
Eli Friedman03aa2f12009-11-30 01:19:33 +00001415 return CGM.getVtableInfo().getVirtualBaseOffsetIndex(D, B);
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001416 llvm::DenseMap<const CXXRecordDecl *, Index_t>::iterator i;
1417 i = VBIndex.find(B);
1418 if (i != VBIndex.end())
1419 return i->second;
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001420
Mike Stump28431212009-10-13 22:54:56 +00001421 assert(false && "FIXME: Base not found");
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001422 return 0;
1423 }
1424
Eli Friedman81fb0d22009-12-04 08:40:51 +00001425 bool OverrideMethod(GlobalDecl GD, bool MorallyVirtual,
1426 Index_t OverrideOffset, Index_t Offset,
1427 int64_t CurrentVBaseOffset);
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001428
Anders Carlsson495634e2009-12-04 02:39:04 +00001429 /// AppendMethods - Append the current methods to the vtable.
Anders Carlssonddf42c82009-12-04 02:56:03 +00001430 void AppendMethodsToVtable();
Anders Carlsson495634e2009-12-04 02:39:04 +00001431
Anders Carlssonfb4dda42009-11-13 17:08:56 +00001432 llvm::Constant *WrapAddrOf(GlobalDecl GD) {
1433 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
1434
Anders Carlsson64457732009-11-24 05:08:52 +00001435 const llvm::Type *Ty = CGM.getTypes().GetFunctionTypeForVtable(MD);
Mike Stump18e8b472009-10-27 23:36:26 +00001436
Mike Stumpcdeb8002009-12-03 16:55:20 +00001437 return wrap(CGM.GetAddrOfFunction(GD, Ty));
Mike Stump18e8b472009-10-27 23:36:26 +00001438 }
1439
Mike Stumpcd6f9ed2009-11-06 23:27:42 +00001440 void OverrideMethods(Path_t *Path, bool MorallyVirtual, int64_t Offset,
1441 int64_t CurrentVBaseOffset) {
Mike Stump37dbe962009-10-15 02:04:03 +00001442 for (Path_t::reverse_iterator i = Path->rbegin(),
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001443 e = Path->rend(); i != e; ++i) {
1444 const CXXRecordDecl *RD = i->first;
Mike Stump8bccbfd2009-10-15 09:30:16 +00001445 int64_t OverrideOffset = i->second;
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001446 for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;
1447 ++mi) {
Anders Carlssonfb4dda42009-11-13 17:08:56 +00001448 const CXXMethodDecl *MD = *mi;
1449
1450 if (!MD->isVirtual())
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001451 continue;
1452
Anders Carlssonfb4dda42009-11-13 17:08:56 +00001453 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
1454 // Override both the complete and the deleting destructor.
1455 GlobalDecl CompDtor(DD, Dtor_Complete);
Eli Friedman81fb0d22009-12-04 08:40:51 +00001456 OverrideMethod(CompDtor, MorallyVirtual, OverrideOffset, Offset,
1457 CurrentVBaseOffset);
1458
Anders Carlssonfb4dda42009-11-13 17:08:56 +00001459 GlobalDecl DeletingDtor(DD, Dtor_Deleting);
Eli Friedman81fb0d22009-12-04 08:40:51 +00001460 OverrideMethod(DeletingDtor, MorallyVirtual, OverrideOffset, Offset,
1461 CurrentVBaseOffset);
Anders Carlssonfb4dda42009-11-13 17:08:56 +00001462 } else {
Eli Friedman81fb0d22009-12-04 08:40:51 +00001463 OverrideMethod(MD, MorallyVirtual, OverrideOffset, Offset,
1464 CurrentVBaseOffset);
Anders Carlssonfb4dda42009-11-13 17:08:56 +00001465 }
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001466 }
1467 }
1468 }
1469
Anders Carlssonfb4dda42009-11-13 17:08:56 +00001470 void AddMethod(const GlobalDecl GD, bool MorallyVirtual, Index_t Offset,
Eli Friedman03aa2f12009-11-30 01:19:33 +00001471 int64_t CurrentVBaseOffset) {
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001472 // If we can find a previously allocated slot for this, reuse it.
Eli Friedman81fb0d22009-12-04 08:40:51 +00001473 if (OverrideMethod(GD, MorallyVirtual, Offset, Offset,
Mike Stumpcd6f9ed2009-11-06 23:27:42 +00001474 CurrentVBaseOffset))
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001475 return;
1476
Mike Stump1f49d652010-01-22 18:48:47 +00001477 D1(printf(" vfn for %s at %d\n",
1478 dyn_cast<CXXMethodDecl>(GD.getDecl())->getNameAsCString(),
1479 (int)Methods.size()));
1480
Anders Carlssoncdf18982009-12-04 02:08:24 +00001481 // We didn't find an entry in the vtable that we could use, add a new
1482 // entry.
1483 Methods.AddMethod(GD);
1484
Mike Stumpa04ecfb2010-01-26 21:35:27 +00001485 VCallOffset[GD] = Offset/8 - CurrentVBaseOffset/8;
1486
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001487 if (MorallyVirtual) {
Anders Carlsson72281172010-01-26 17:36:47 +00001488 GlobalDecl UGD = getUnique(GD);
1489 const CXXMethodDecl *UMD = cast<CXXMethodDecl>(UGD.getDecl());
1490
Mike Stump90181eb2010-01-26 00:05:04 +00001491 assert(UMD && "final overrider not found");
1492
1493 Index_t &idx = VCall[UMD];
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001494 // Allocate the first one, after that, we reuse the previous one.
1495 if (idx == 0) {
Anders Carlsson72281172010-01-26 17:36:47 +00001496 VCallOffsetForVCall[UGD] = Offset/8;
Mike Stumpa04ecfb2010-01-26 21:35:27 +00001497 NonVirtualOffset[UMD] = Offset/8 - CurrentVBaseOffset/8;
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001498 idx = VCalls.size()+1;
Mike Stump90181eb2010-01-26 00:05:04 +00001499 VCalls.push_back(Offset/8 - CurrentVBaseOffset/8);
Mike Stump75ce5732009-10-31 20:06:59 +00001500 D1(printf(" vcall for %s at %d with delta %d\n",
Mike Stumpd2808442010-01-22 02:51:26 +00001501 dyn_cast<CXXMethodDecl>(GD.getDecl())->getNameAsCString(),
Mike Stump90181eb2010-01-26 00:05:04 +00001502 (int)-VCalls.size()-3, (int)VCalls[idx-1]));
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001503 }
1504 }
1505 }
1506
1507 void AddMethods(const CXXRecordDecl *RD, bool MorallyVirtual,
Eli Friedman03aa2f12009-11-30 01:19:33 +00001508 Index_t Offset, int64_t CurrentVBaseOffset) {
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001509 for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;
Anders Carlssonfb4dda42009-11-13 17:08:56 +00001510 ++mi) {
1511 const CXXMethodDecl *MD = *mi;
1512 if (!MD->isVirtual())
1513 continue;
1514
1515 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
1516 // For destructors, add both the complete and the deleting destructor
1517 // to the vtable.
1518 AddMethod(GlobalDecl(DD, Dtor_Complete), MorallyVirtual, Offset,
Mike Stumpcd6f9ed2009-11-06 23:27:42 +00001519 CurrentVBaseOffset);
Eli Friedman03aa2f12009-11-30 01:19:33 +00001520 AddMethod(GlobalDecl(DD, Dtor_Deleting), MorallyVirtual, Offset,
1521 CurrentVBaseOffset);
1522 } else
1523 AddMethod(MD, MorallyVirtual, Offset, CurrentVBaseOffset);
Anders Carlssonfb4dda42009-11-13 17:08:56 +00001524 }
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001525 }
1526
1527 void NonVirtualBases(const CXXRecordDecl *RD, const ASTRecordLayout &Layout,
1528 const CXXRecordDecl *PrimaryBase,
1529 bool PrimaryBaseWasVirtual, bool MorallyVirtual,
Mike Stumpcd6f9ed2009-11-06 23:27:42 +00001530 int64_t Offset, int64_t CurrentVBaseOffset,
1531 Path_t *Path) {
Mike Stump37dbe962009-10-15 02:04:03 +00001532 Path->push_back(std::make_pair(RD, Offset));
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001533 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
1534 e = RD->bases_end(); i != e; ++i) {
1535 if (i->isVirtual())
1536 continue;
1537 const CXXRecordDecl *Base =
1538 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
Mike Stump9eb76d42010-01-22 06:45:05 +00001539 uint64_t o = Offset + Layout.getBaseClassOffset(Base);
1540 StartNewTable();
1541 GenerateVtableForBase(Base, o, MorallyVirtual, false,
1542 true, Base == PrimaryBase && !PrimaryBaseWasVirtual,
1543 CurrentVBaseOffset, Path);
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001544 }
Mike Stump37dbe962009-10-15 02:04:03 +00001545 Path->pop_back();
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001546 }
1547
Mike Stumpb21c4ee2009-10-14 18:14:51 +00001548// #define D(X) do { X; } while (0)
1549#define D(X)
1550
1551 void insertVCalls(int InsertionPoint) {
Mike Stump75ce5732009-10-31 20:06:59 +00001552 D1(printf("============= combining vbase/vcall\n"));
Mike Stumpb21c4ee2009-10-14 18:14:51 +00001553 D(VCalls.insert(VCalls.begin(), 673));
1554 D(VCalls.push_back(672));
Eli Friedman6c08ce72009-12-05 01:05:03 +00001555
Anders Carlssonfe5f7d92009-12-06 01:09:21 +00001556 VtableComponents.insert(VtableComponents.begin() + InsertionPoint,
1557 VCalls.size(), 0);
Eli Friedman6c08ce72009-12-05 01:05:03 +00001558 if (BuildVtable) {
1559 // The vcalls come first...
1560 for (std::vector<Index_t>::reverse_iterator i = VCalls.rbegin(),
1561 e = VCalls.rend();
1562 i != e; ++i)
Anders Carlssonfe5f7d92009-12-06 01:09:21 +00001563 VtableComponents[InsertionPoint++] = wrap((0?600:0) + *i);
Eli Friedman6c08ce72009-12-05 01:05:03 +00001564 }
Mike Stumpb21c4ee2009-10-14 18:14:51 +00001565 VCalls.clear();
Mike Stump9f23a142009-11-10 02:30:51 +00001566 VCall.clear();
Mike Stumpa04ecfb2010-01-26 21:35:27 +00001567 VCallOffsetForVCall.clear();
1568 VCallOffset.clear();
1569 NonVirtualOffset.clear();
Mike Stumpb21c4ee2009-10-14 18:14:51 +00001570 }
1571
Mike Stump559387f2009-11-13 23:13:20 +00001572 void AddAddressPoints(const CXXRecordDecl *RD, uint64_t Offset,
1573 Index_t AddressPoint) {
1574 D1(printf("XXX address point for %s in %s layout %s at offset %d is %d\n",
Mike Stumpd2808442010-01-22 02:51:26 +00001575 RD->getNameAsCString(), MostDerivedClass->getNameAsCString(),
Mike Stump559387f2009-11-13 23:13:20 +00001576 LayoutClass->getNameAsCString(), (int)Offset, (int)AddressPoint));
Mike Stumpcd2b8212009-11-19 20:52:19 +00001577 subAddressPoints[std::make_pair(RD, Offset)] = AddressPoint;
Anders Carlsson5f9a8812010-01-14 02:29:07 +00001578 AddressPoints[BaseSubobject(RD, Offset)] = AddressPoint;
Mike Stump559387f2009-11-13 23:13:20 +00001579
1580 // Now also add the address point for all our primary bases.
1581 while (1) {
1582 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
1583 RD = Layout.getPrimaryBase();
1584 const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
1585 // FIXME: Double check this.
1586 if (RD == 0)
1587 break;
1588 if (PrimaryBaseWasVirtual &&
1589 BLayout.getVBaseClassOffset(RD) != Offset)
1590 break;
1591 D1(printf("XXX address point for %s in %s layout %s at offset %d is %d\n",
Mike Stumpd2808442010-01-22 02:51:26 +00001592 RD->getNameAsCString(), MostDerivedClass->getNameAsCString(),
Mike Stump559387f2009-11-13 23:13:20 +00001593 LayoutClass->getNameAsCString(), (int)Offset, (int)AddressPoint));
Mike Stumpcd2b8212009-11-19 20:52:19 +00001594 subAddressPoints[std::make_pair(RD, Offset)] = AddressPoint;
Anders Carlsson5f9a8812010-01-14 02:29:07 +00001595 AddressPoints[BaseSubobject(RD, Offset)] = AddressPoint;
Mike Stump559387f2009-11-13 23:13:20 +00001596 }
1597 }
1598
1599
Mike Stumpd538a6d2009-12-24 07:29:41 +00001600 void FinishGenerateVtable(const CXXRecordDecl *RD,
1601 const ASTRecordLayout &Layout,
1602 const CXXRecordDecl *PrimaryBase,
Mike Stump9eb76d42010-01-22 06:45:05 +00001603 bool ForNPNVBases, bool WasPrimaryBase,
Mike Stumpd538a6d2009-12-24 07:29:41 +00001604 bool PrimaryBaseWasVirtual,
1605 bool MorallyVirtual, int64_t Offset,
1606 bool ForVirtualBase, int64_t CurrentVBaseOffset,
1607 Path_t *Path) {
Mike Stump37dbe962009-10-15 02:04:03 +00001608 bool alloc = false;
1609 if (Path == 0) {
1610 alloc = true;
1611 Path = new Path_t;
1612 }
1613
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001614 StartNewTable();
1615 extra = 0;
Mike Stump9eb76d42010-01-22 06:45:05 +00001616 Index_t AddressPoint = 0;
1617 int VCallInsertionPoint = 0;
1618 if (!ForNPNVBases || !WasPrimaryBase) {
1619 bool DeferVCalls = MorallyVirtual || ForVirtualBase;
1620 VCallInsertionPoint = VtableComponents.size();
1621 if (!DeferVCalls) {
1622 insertVCalls(VCallInsertionPoint);
1623 } else
1624 // FIXME: just for extra, or for all uses of VCalls.size post this?
1625 extra = -VCalls.size();
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001626
Mike Stump9eb76d42010-01-22 06:45:05 +00001627 // Add the offset to top.
1628 VtableComponents.push_back(BuildVtable ? wrap(-((Offset-LayoutOffset)/8)) : 0);
Anders Carlsson472404f2009-12-04 16:19:30 +00001629
Mike Stump9eb76d42010-01-22 06:45:05 +00001630 // Add the RTTI information.
1631 VtableComponents.push_back(rtti);
Anders Carlsson472404f2009-12-04 16:19:30 +00001632
Mike Stump9eb76d42010-01-22 06:45:05 +00001633 AddressPoint = VtableComponents.size();
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001634
Mike Stump9eb76d42010-01-22 06:45:05 +00001635 AppendMethodsToVtable();
1636 }
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001637
1638 // and then the non-virtual bases.
1639 NonVirtualBases(RD, Layout, PrimaryBase, PrimaryBaseWasVirtual,
Mike Stumpcd6f9ed2009-11-06 23:27:42 +00001640 MorallyVirtual, Offset, CurrentVBaseOffset, Path);
Mike Stumpb21c4ee2009-10-14 18:14:51 +00001641
1642 if (ForVirtualBase) {
Mike Stump2cefe382009-11-12 20:47:57 +00001643 // FIXME: We're adding to VCalls in callers, we need to do the overrides
1644 // in the inner part, so that we know the complete set of vcalls during
1645 // the build and don't have to insert into methods. Saving out the
1646 // AddressPoint here, would need to be fixed, if we didn't do that. Also
1647 // retroactively adding vcalls for overrides later wind up in the wrong
1648 // place, the vcall slot has to be alloted during the walk of the base
1649 // when the function is first introduces.
Mike Stumpb21c4ee2009-10-14 18:14:51 +00001650 AddressPoint += VCalls.size();
Mike Stump2cefe382009-11-12 20:47:57 +00001651 insertVCalls(VCallInsertionPoint);
Mike Stumpb21c4ee2009-10-14 18:14:51 +00001652 }
1653
Mike Stump9eb76d42010-01-22 06:45:05 +00001654 if (!ForNPNVBases || !WasPrimaryBase)
1655 AddAddressPoints(RD, Offset, AddressPoint);
Mike Stump2cefe382009-11-12 20:47:57 +00001656
Mike Stump37dbe962009-10-15 02:04:03 +00001657 if (alloc) {
1658 delete Path;
1659 }
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001660 }
1661
Mike Stump75ce5732009-10-31 20:06:59 +00001662 void Primaries(const CXXRecordDecl *RD, bool MorallyVirtual, int64_t Offset,
1663 bool updateVBIndex, Index_t current_vbindex,
Eli Friedman03aa2f12009-11-30 01:19:33 +00001664 int64_t CurrentVBaseOffset) {
Mike Stump75ce5732009-10-31 20:06:59 +00001665 if (!RD->isDynamicClass())
1666 return;
1667
1668 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
1669 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
1670 const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
1671
1672 // vtables are composed from the chain of primaries.
Eli Friedman65d87222009-12-04 08:52:11 +00001673 if (PrimaryBase && !PrimaryBaseWasVirtual) {
Mike Stump75ce5732009-10-31 20:06:59 +00001674 D1(printf(" doing primaries for %s most derived %s\n",
Mike Stumpd2808442010-01-22 02:51:26 +00001675 RD->getNameAsCString(), MostDerivedClass->getNameAsCString()));
Eli Friedman65d87222009-12-04 08:52:11 +00001676 Primaries(PrimaryBase, PrimaryBaseWasVirtual|MorallyVirtual, Offset,
1677 updateVBIndex, current_vbindex, CurrentVBaseOffset);
Mike Stump75ce5732009-10-31 20:06:59 +00001678 }
1679
1680 D1(printf(" doing vcall entries for %s most derived %s\n",
Mike Stumpd2808442010-01-22 02:51:26 +00001681 RD->getNameAsCString(), MostDerivedClass->getNameAsCString()));
Mike Stump75ce5732009-10-31 20:06:59 +00001682
1683 // And add the virtuals for the class to the primary vtable.
Eli Friedman03aa2f12009-11-30 01:19:33 +00001684 AddMethods(RD, MorallyVirtual, Offset, CurrentVBaseOffset);
Mike Stump75ce5732009-10-31 20:06:59 +00001685 }
1686
1687 void VBPrimaries(const CXXRecordDecl *RD, bool MorallyVirtual, int64_t Offset,
1688 bool updateVBIndex, Index_t current_vbindex,
Mike Stumpcd6f9ed2009-11-06 23:27:42 +00001689 bool RDisVirtualBase, int64_t CurrentVBaseOffset,
Eli Friedman03aa2f12009-11-30 01:19:33 +00001690 bool bottom) {
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001691 if (!RD->isDynamicClass())
1692 return;
1693
1694 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
1695 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
1696 const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
1697
1698 // vtables are composed from the chain of primaries.
1699 if (PrimaryBase) {
Mike Stumpcd6f9ed2009-11-06 23:27:42 +00001700 int BaseCurrentVBaseOffset = CurrentVBaseOffset;
1701 if (PrimaryBaseWasVirtual) {
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001702 IndirectPrimary.insert(PrimaryBase);
Mike Stumpcd6f9ed2009-11-06 23:27:42 +00001703 BaseCurrentVBaseOffset = BLayout.getVBaseClassOffset(PrimaryBase);
1704 }
Mike Stump75ce5732009-10-31 20:06:59 +00001705
1706 D1(printf(" doing primaries for %s most derived %s\n",
Mike Stumpd2808442010-01-22 02:51:26 +00001707 RD->getNameAsCString(), MostDerivedClass->getNameAsCString()));
Mike Stump75ce5732009-10-31 20:06:59 +00001708
1709 VBPrimaries(PrimaryBase, PrimaryBaseWasVirtual|MorallyVirtual, Offset,
Mike Stumpcd6f9ed2009-11-06 23:27:42 +00001710 updateVBIndex, current_vbindex, PrimaryBaseWasVirtual,
Eli Friedman03aa2f12009-11-30 01:19:33 +00001711 BaseCurrentVBaseOffset, false);
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001712 }
1713
Mike Stump75ce5732009-10-31 20:06:59 +00001714 D1(printf(" doing vbase entries for %s most derived %s\n",
Mike Stumpd2808442010-01-22 02:51:26 +00001715 RD->getNameAsCString(), MostDerivedClass->getNameAsCString()));
Mike Stump75ce5732009-10-31 20:06:59 +00001716 GenerateVBaseOffsets(RD, Offset, updateVBIndex, current_vbindex);
1717
1718 if (RDisVirtualBase || bottom) {
1719 Primaries(RD, MorallyVirtual, Offset, updateVBIndex, current_vbindex,
Eli Friedman03aa2f12009-11-30 01:19:33 +00001720 CurrentVBaseOffset);
Mike Stump75ce5732009-10-31 20:06:59 +00001721 }
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001722 }
1723
Mike Stumpd538a6d2009-12-24 07:29:41 +00001724 void GenerateVtableForBase(const CXXRecordDecl *RD, int64_t Offset = 0,
1725 bool MorallyVirtual = false,
1726 bool ForVirtualBase = false,
Mike Stump9eb76d42010-01-22 06:45:05 +00001727 bool ForNPNVBases = false,
1728 bool WasPrimaryBase = true,
Mike Stumpd538a6d2009-12-24 07:29:41 +00001729 int CurrentVBaseOffset = 0,
1730 Path_t *Path = 0) {
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001731 if (!RD->isDynamicClass())
Mike Stumpd538a6d2009-12-24 07:29:41 +00001732 return;
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001733
Mike Stumpfa818082009-11-13 02:35:38 +00001734 // Construction vtable don't need parts that have no virtual bases and
1735 // aren't morally virtual.
Anders Carlssonbad80eb2009-12-04 18:36:22 +00001736 if ((LayoutClass != MostDerivedClass) &&
1737 RD->getNumVBases() == 0 && !MorallyVirtual)
Mike Stumpd538a6d2009-12-24 07:29:41 +00001738 return;
Mike Stumpfa818082009-11-13 02:35:38 +00001739
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001740 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
1741 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
1742 const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
1743
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001744 extra = 0;
Mike Stump75ce5732009-10-31 20:06:59 +00001745 D1(printf("building entries for base %s most derived %s\n",
Mike Stumpd2808442010-01-22 02:51:26 +00001746 RD->getNameAsCString(), MostDerivedClass->getNameAsCString()));
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001747
Mike Stump75ce5732009-10-31 20:06:59 +00001748 if (ForVirtualBase)
1749 extra = VCalls.size();
1750
Mike Stump9eb76d42010-01-22 06:45:05 +00001751 if (!ForNPNVBases || !WasPrimaryBase) {
1752 VBPrimaries(RD, MorallyVirtual, Offset, !ForVirtualBase, 0,
1753 ForVirtualBase, CurrentVBaseOffset, true);
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001754
Mike Stump9eb76d42010-01-22 06:45:05 +00001755 if (Path)
1756 OverrideMethods(Path, MorallyVirtual, Offset, CurrentVBaseOffset);
1757 }
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001758
Mike Stump9eb76d42010-01-22 06:45:05 +00001759 FinishGenerateVtable(RD, Layout, PrimaryBase, ForNPNVBases, WasPrimaryBase,
1760 PrimaryBaseWasVirtual, MorallyVirtual, Offset,
1761 ForVirtualBase, CurrentVBaseOffset, Path);
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001762 }
1763
1764 void GenerateVtableForVBases(const CXXRecordDecl *RD,
1765 int64_t Offset = 0,
Mike Stump37dbe962009-10-15 02:04:03 +00001766 Path_t *Path = 0) {
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001767 bool alloc = false;
1768 if (Path == 0) {
1769 alloc = true;
Mike Stump37dbe962009-10-15 02:04:03 +00001770 Path = new Path_t;
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001771 }
1772 // FIXME: We also need to override using all paths to a virtual base,
1773 // right now, we just process the first path
1774 Path->push_back(std::make_pair(RD, Offset));
1775 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
1776 e = RD->bases_end(); i != e; ++i) {
1777 const CXXRecordDecl *Base =
1778 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
1779 if (i->isVirtual() && !IndirectPrimary.count(Base)) {
1780 // Mark it so we don't output it twice.
1781 IndirectPrimary.insert(Base);
1782 StartNewTable();
Mike Stumpb21c4ee2009-10-14 18:14:51 +00001783 VCall.clear();
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001784 int64_t BaseOffset = BLayout.getVBaseClassOffset(Base);
Mike Stumpcd6f9ed2009-11-06 23:27:42 +00001785 int64_t CurrentVBaseOffset = BaseOffset;
Mike Stump75ce5732009-10-31 20:06:59 +00001786 D1(printf("vtable %s virtual base %s\n",
Mike Stumpd2808442010-01-22 02:51:26 +00001787 MostDerivedClass->getNameAsCString(), Base->getNameAsCString()));
Mike Stump9eb76d42010-01-22 06:45:05 +00001788 GenerateVtableForBase(Base, BaseOffset, true, true, false,
1789 true, CurrentVBaseOffset, Path);
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001790 }
Mike Stump2cefe382009-11-12 20:47:57 +00001791 int64_t BaseOffset;
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001792 if (i->isVirtual())
1793 BaseOffset = BLayout.getVBaseClassOffset(Base);
Mike Stump2cefe382009-11-12 20:47:57 +00001794 else {
1795 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
1796 BaseOffset = Offset + Layout.getBaseClassOffset(Base);
1797 }
1798
Mike Stump37dbe962009-10-15 02:04:03 +00001799 if (Base->getNumVBases()) {
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001800 GenerateVtableForVBases(Base, BaseOffset, Path);
Mike Stump37dbe962009-10-15 02:04:03 +00001801 }
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001802 }
1803 Path->pop_back();
1804 if (alloc)
1805 delete Path;
1806 }
1807};
Anders Carlssonca1bf682009-12-03 01:54:02 +00001808} // end anonymous namespace
1809
Anders Carlsson5d40c6f2010-02-11 08:02:13 +00001810bool OldVtableBuilder::OverrideMethod(GlobalDecl GD, bool MorallyVirtual,
Eli Friedman81fb0d22009-12-04 08:40:51 +00001811 Index_t OverrideOffset, Index_t Offset,
1812 int64_t CurrentVBaseOffset) {
Anders Carlssonca1bf682009-12-03 01:54:02 +00001813 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
1814
1815 const bool isPure = MD->isPure();
Anders Carlsson21bbc1e2009-12-05 17:04:47 +00001816
Anders Carlssonca1bf682009-12-03 01:54:02 +00001817 // FIXME: Should OverrideOffset's be Offset?
1818
Anders Carlsson21bbc1e2009-12-05 17:04:47 +00001819 for (CXXMethodDecl::method_iterator mi = MD->begin_overridden_methods(),
1820 e = MD->end_overridden_methods(); mi != e; ++mi) {
Anders Carlssonca1bf682009-12-03 01:54:02 +00001821 GlobalDecl OGD;
Mike Stumpa04ecfb2010-01-26 21:35:27 +00001822 GlobalDecl OGD2;
Anders Carlssonca1bf682009-12-03 01:54:02 +00001823
Anders Carlssonf3935b42009-12-04 05:51:56 +00001824 const CXXMethodDecl *OMD = *mi;
Anders Carlssonca1bf682009-12-03 01:54:02 +00001825 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(OMD))
1826 OGD = GlobalDecl(DD, GD.getDtorType());
1827 else
1828 OGD = OMD;
Eli Friedman3d2e9de2009-12-04 08:34:14 +00001829
Eli Friedman8174f2c2009-12-06 22:01:30 +00001830 // Check whether this is the method being overridden in this section of
1831 // the vtable.
Anders Carlsson7bb70762009-12-04 15:49:02 +00001832 uint64_t Index;
1833 if (!Methods.getIndex(OGD, Index))
Eli Friedman3d2e9de2009-12-04 08:34:14 +00001834 continue;
1835
Mike Stumpa04ecfb2010-01-26 21:35:27 +00001836 OGD2 = OGD;
1837
Eli Friedman8174f2c2009-12-06 22:01:30 +00001838 // Get the original method, which we should be computing thunks, etc,
1839 // against.
1840 OGD = Methods.getOrigMethod(Index);
1841 OMD = cast<CXXMethodDecl>(OGD.getDecl());
1842
Eli Friedman3d2e9de2009-12-04 08:34:14 +00001843 QualType ReturnType =
1844 MD->getType()->getAs<FunctionType>()->getResultType();
1845 QualType OverriddenReturnType =
1846 OMD->getType()->getAs<FunctionType>()->getResultType();
Anders Carlssonca1bf682009-12-03 01:54:02 +00001847
Eli Friedman3d2e9de2009-12-04 08:34:14 +00001848 // Check if we need a return type adjustment.
1849 if (TypeConversionRequiresAdjustment(CGM.getContext(), ReturnType,
1850 OverriddenReturnType)) {
1851 CanQualType &BaseReturnType = BaseReturnTypes[Index];
Anders Carlssonca1bf682009-12-03 01:54:02 +00001852
Eli Friedman3d2e9de2009-12-04 08:34:14 +00001853 // Insert the base return type.
1854 if (BaseReturnType.isNull())
1855 BaseReturnType =
1856 CGM.getContext().getCanonicalType(OverriddenReturnType);
1857 }
Anders Carlssona93e9802009-12-04 03:52:52 +00001858
Eli Friedman3d2e9de2009-12-04 08:34:14 +00001859 Methods.OverrideMethod(OGD, GD);
1860
Anders Carlsson72281172010-01-26 17:36:47 +00001861 GlobalDecl UGD = getUnique(GD);
1862 const CXXMethodDecl *UMD = cast<CXXMethodDecl>(UGD.getDecl());
1863 assert(UGD.getDecl() && "unique overrider not found");
1864 assert(UGD == getUnique(OGD) && "unique overrider not unique");
Mike Stump90181eb2010-01-26 00:05:04 +00001865
Eli Friedman3d2e9de2009-12-04 08:34:14 +00001866 ThisAdjustments.erase(Index);
Mike Stump90181eb2010-01-26 00:05:04 +00001867 if (MorallyVirtual || VCall.count(UMD)) {
Mike Stumpa04ecfb2010-01-26 21:35:27 +00001868
Mike Stump90181eb2010-01-26 00:05:04 +00001869 Index_t &idx = VCall[UMD];
Eli Friedman3d2e9de2009-12-04 08:34:14 +00001870 if (idx == 0) {
Mike Stumpa04ecfb2010-01-26 21:35:27 +00001871 VCallOffset[GD] = VCallOffset[OGD];
1872 // NonVirtualOffset[UMD] = CurrentVBaseOffset/8 - OverrideOffset/8;
1873 NonVirtualOffset[UMD] = VCallOffset[OGD];
Mike Stump77537b12010-01-26 03:42:22 +00001874 VCallOffsetForVCall[UMD] = OverrideOffset/8;
Eli Friedman3d2e9de2009-12-04 08:34:14 +00001875 idx = VCalls.size()+1;
Mike Stump77537b12010-01-26 03:42:22 +00001876 VCalls.push_back(OverrideOffset/8 - CurrentVBaseOffset/8);
Eli Friedman3d2e9de2009-12-04 08:34:14 +00001877 D1(printf(" vcall for %s at %d with delta %d most derived %s\n",
1878 MD->getNameAsString().c_str(), (int)-idx-3,
Mike Stumpd2808442010-01-22 02:51:26 +00001879 (int)VCalls[idx-1], MostDerivedClass->getNameAsCString()));
Eli Friedman3d2e9de2009-12-04 08:34:14 +00001880 } else {
Mike Stumpa04ecfb2010-01-26 21:35:27 +00001881 VCallOffset[GD] = NonVirtualOffset[UMD];
Anders Carlsson72281172010-01-26 17:36:47 +00001882 VCalls[idx-1] = -VCallOffsetForVCall[UGD] + OverrideOffset/8;
Eli Friedman3d2e9de2009-12-04 08:34:14 +00001883 D1(printf(" vcall patch for %s at %d with delta %d most derived %s\n",
1884 MD->getNameAsString().c_str(), (int)-idx-3,
Mike Stumpd2808442010-01-22 02:51:26 +00001885 (int)VCalls[idx-1], MostDerivedClass->getNameAsCString()));
Eli Friedman3d2e9de2009-12-04 08:34:14 +00001886 }
Mike Stumpa04ecfb2010-01-26 21:35:27 +00001887 int64_t NonVirtualAdjustment = -VCallOffset[OGD];
Mike Stumpded0a402010-01-26 22:44:01 +00001888 QualType DerivedType = MD->getThisType(CGM.getContext());
1889 QualType BaseType = cast<const CXXMethodDecl>(OGD.getDecl())->getThisType(CGM.getContext());
1890 int64_t NonVirtualAdjustment2 = -(getNVOffset(BaseType, DerivedType)/8);
1891 if (NonVirtualAdjustment2 != NonVirtualAdjustment) {
1892 NonVirtualAdjustment = NonVirtualAdjustment2;
1893 }
Eli Friedman3d2e9de2009-12-04 08:34:14 +00001894 int64_t VirtualAdjustment =
1895 -((idx + extra + 2) * LLVMPointerWidth / 8);
Anders Carlsson657f1392009-12-03 02:32:59 +00001896
Eli Friedman3d2e9de2009-12-04 08:34:14 +00001897 // Optimize out virtual adjustments of 0.
1898 if (VCalls[idx-1] == 0)
1899 VirtualAdjustment = 0;
Anders Carlsson657f1392009-12-03 02:32:59 +00001900
Eli Friedman3d2e9de2009-12-04 08:34:14 +00001901 ThunkAdjustment ThisAdjustment(NonVirtualAdjustment,
1902 VirtualAdjustment);
Anders Carlsson2ca285f2009-12-03 02:22:59 +00001903
Eli Friedman8174f2c2009-12-06 22:01:30 +00001904 if (!isPure && !ThisAdjustment.isEmpty()) {
Eli Friedman3d2e9de2009-12-04 08:34:14 +00001905 ThisAdjustments[Index] = ThisAdjustment;
Eli Friedman31bc3ad2009-12-07 23:56:34 +00001906 SavedAdjustments.push_back(
1907 std::make_pair(GD, std::make_pair(OGD, ThisAdjustment)));
Eli Friedman8174f2c2009-12-06 22:01:30 +00001908 }
Anders Carlssonca1bf682009-12-03 01:54:02 +00001909 return true;
1910 }
Eli Friedman3d2e9de2009-12-04 08:34:14 +00001911
Mike Stumpa04ecfb2010-01-26 21:35:27 +00001912 VCallOffset[GD] = VCallOffset[OGD2] - OverrideOffset/8;
Eli Friedman3d2e9de2009-12-04 08:34:14 +00001913
Mike Stumpa04ecfb2010-01-26 21:35:27 +00001914 int64_t NonVirtualAdjustment = -VCallOffset[GD];
1915 QualType DerivedType = MD->getThisType(CGM.getContext());
1916 QualType BaseType = cast<const CXXMethodDecl>(OGD.getDecl())->getThisType(CGM.getContext());
1917 int64_t NonVirtualAdjustment2 = -(getNVOffset(BaseType, DerivedType)/8);
1918 if (NonVirtualAdjustment2 != NonVirtualAdjustment) {
1919 NonVirtualAdjustment = NonVirtualAdjustment2;
1920 }
1921
Eli Friedman3d2e9de2009-12-04 08:34:14 +00001922 if (NonVirtualAdjustment) {
1923 ThunkAdjustment ThisAdjustment(NonVirtualAdjustment, 0);
1924
Eli Friedmanf2eda5e2009-12-06 22:33:51 +00001925 if (!isPure) {
Eli Friedman3d2e9de2009-12-04 08:34:14 +00001926 ThisAdjustments[Index] = ThisAdjustment;
Eli Friedman31bc3ad2009-12-07 23:56:34 +00001927 SavedAdjustments.push_back(
1928 std::make_pair(GD, std::make_pair(OGD, ThisAdjustment)));
Eli Friedmanf2eda5e2009-12-06 22:33:51 +00001929 }
Eli Friedman3d2e9de2009-12-04 08:34:14 +00001930 }
1931 return true;
Anders Carlssonca1bf682009-12-03 01:54:02 +00001932 }
1933
1934 return false;
Anders Carlssond59885022009-11-27 22:21:51 +00001935}
1936
Anders Carlsson5d40c6f2010-02-11 08:02:13 +00001937void OldVtableBuilder::AppendMethodsToVtable() {
Eli Friedman6c08ce72009-12-05 01:05:03 +00001938 if (!BuildVtable) {
Anders Carlssonfe5f7d92009-12-06 01:09:21 +00001939 VtableComponents.insert(VtableComponents.end(), Methods.size(),
1940 (llvm::Constant *)0);
Eli Friedman6c08ce72009-12-05 01:05:03 +00001941 ThisAdjustments.clear();
1942 BaseReturnTypes.clear();
1943 Methods.clear();
1944 return;
1945 }
1946
Anders Carlsson472404f2009-12-04 16:19:30 +00001947 // Reserve room in the vtable for our new methods.
Anders Carlssonfe5f7d92009-12-06 01:09:21 +00001948 VtableComponents.reserve(VtableComponents.size() + Methods.size());
Anders Carlssonb07567c2009-12-04 03:07:26 +00001949
Anders Carlsson86809cd2009-12-04 02:43:50 +00001950 for (unsigned i = 0, e = Methods.size(); i != e; ++i) {
1951 GlobalDecl GD = Methods[i];
Anders Carlsson5b3ea9b2009-12-04 02:52:22 +00001952 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
1953
1954 // Get the 'this' pointer adjustment.
Anders Carlsson86809cd2009-12-04 02:43:50 +00001955 ThunkAdjustment ThisAdjustment = ThisAdjustments.lookup(i);
Anders Carlsson5b3ea9b2009-12-04 02:52:22 +00001956
1957 // Construct the return type adjustment.
1958 ThunkAdjustment ReturnAdjustment;
1959
1960 QualType BaseReturnType = BaseReturnTypes.lookup(i);
1961 if (!BaseReturnType.isNull() && !MD->isPure()) {
1962 QualType DerivedType =
1963 MD->getType()->getAs<FunctionType>()->getResultType();
1964
1965 int64_t NonVirtualAdjustment =
1966 getNVOffset(BaseReturnType, DerivedType) / 8;
1967
1968 int64_t VirtualAdjustment =
1969 getVbaseOffset(BaseReturnType, DerivedType);
1970
1971 ReturnAdjustment = ThunkAdjustment(NonVirtualAdjustment,
1972 VirtualAdjustment);
1973 }
1974
Anders Carlsson50f14742009-12-04 03:06:03 +00001975 llvm::Constant *Method = 0;
Anders Carlsson5b3ea9b2009-12-04 02:52:22 +00001976 if (!ReturnAdjustment.isEmpty()) {
1977 // Build a covariant thunk.
1978 CovariantThunkAdjustment Adjustment(ThisAdjustment, ReturnAdjustment);
Eli Friedman8174f2c2009-12-06 22:01:30 +00001979 Method = wrap(CGM.GetAddrOfCovariantThunk(GD, Adjustment));
Anders Carlsson5b3ea9b2009-12-04 02:52:22 +00001980 } else if (!ThisAdjustment.isEmpty()) {
1981 // Build a "regular" thunk.
Eli Friedman8174f2c2009-12-06 22:01:30 +00001982 Method = wrap(CGM.GetAddrOfThunk(GD, ThisAdjustment));
Anders Carlssonddf42c82009-12-04 02:56:03 +00001983 } else if (MD->isPure()) {
1984 // We have a pure virtual method.
Anders Carlsson50f14742009-12-04 03:06:03 +00001985 Method = getPureVirtualFn();
1986 } else {
1987 // We have a good old regular method.
1988 Method = WrapAddrOf(GD);
Anders Carlsson5b3ea9b2009-12-04 02:52:22 +00001989 }
Anders Carlsson50f14742009-12-04 03:06:03 +00001990
1991 // Add the method to the vtable.
Anders Carlssonfe5f7d92009-12-06 01:09:21 +00001992 VtableComponents.push_back(Method);
Anders Carlsson86809cd2009-12-04 02:43:50 +00001993 }
1994
Anders Carlsson50f14742009-12-04 03:06:03 +00001995
Anders Carlsson86809cd2009-12-04 02:43:50 +00001996 ThisAdjustments.clear();
Anders Carlsson5b3ea9b2009-12-04 02:52:22 +00001997 BaseReturnTypes.clear();
Anders Carlsson86809cd2009-12-04 02:43:50 +00001998
Anders Carlsson495634e2009-12-04 02:39:04 +00001999 Methods.clear();
Anders Carlsson495634e2009-12-04 02:39:04 +00002000}
2001
Anders Carlssonf942ee02009-11-27 20:47:55 +00002002void CGVtableInfo::ComputeMethodVtableIndices(const CXXRecordDecl *RD) {
2003
2004 // Itanium C++ ABI 2.5.2:
Anders Carlsson259688c2010-02-02 03:37:46 +00002005 // The order of the virtual function pointers in a virtual table is the
2006 // order of declaration of the corresponding member functions in the class.
Anders Carlssonf942ee02009-11-27 20:47:55 +00002007 //
Anders Carlsson259688c2010-02-02 03:37:46 +00002008 // There is an entry for any virtual function declared in a class,
2009 // whether it is a new function or overrides a base class function,
2010 // unless it overrides a function from the primary base, and conversion
2011 // between their return types does not require an adjustment.
Anders Carlssonf942ee02009-11-27 20:47:55 +00002012
2013 int64_t CurrentIndex = 0;
2014
2015 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
2016 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
2017
2018 if (PrimaryBase) {
Anders Carlssonc920fa22009-11-30 19:43:26 +00002019 assert(PrimaryBase->isDefinition() &&
2020 "Should have the definition decl of the primary base!");
Anders Carlssonf942ee02009-11-27 20:47:55 +00002021
2022 // Since the record decl shares its vtable pointer with the primary base
2023 // we need to start counting at the end of the primary base's vtable.
2024 CurrentIndex = getNumVirtualFunctionPointers(PrimaryBase);
2025 }
Eli Friedman21517252009-12-15 03:31:17 +00002026
2027 // Collect all the primary bases, so we can check whether methods override
2028 // a method from the base.
Anders Carlsson65b49782010-02-12 05:25:12 +00002029 VtableBuilder::PrimaryBasesSetTy PrimaryBases;
Eli Friedman21517252009-12-15 03:31:17 +00002030 for (ASTRecordLayout::primary_base_info_iterator
2031 I = Layout.primary_base_begin(), E = Layout.primary_base_end();
2032 I != E; ++I)
2033 PrimaryBases.insert((*I).getBase());
2034
Anders Carlssonf942ee02009-11-27 20:47:55 +00002035 const CXXDestructorDecl *ImplicitVirtualDtor = 0;
2036
2037 for (CXXRecordDecl::method_iterator i = RD->method_begin(),
2038 e = RD->method_end(); i != e; ++i) {
2039 const CXXMethodDecl *MD = *i;
2040
2041 // We only want virtual methods.
2042 if (!MD->isVirtual())
2043 continue;
2044
Anders Carlssonf942ee02009-11-27 20:47:55 +00002045 // Check if this method overrides a method in the primary base.
Anders Carlsson65b49782010-02-12 05:25:12 +00002046 if (const CXXMethodDecl *OverriddenMD =
2047 OverridesMethodInPrimaryBase(MD, PrimaryBases)) {
2048 // Check if converting from the return type of the method to the
2049 // return type of the overridden method requires conversion.
Anders Carlsson5272c252010-02-12 17:37:14 +00002050 if (!ReturnTypeConversionRequiresAdjustment(MD, OverriddenMD)) {
Anders Carlsson65b49782010-02-12 05:25:12 +00002051 // This index is shared between the index in the vtable of the primary
2052 // base class.
2053 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
2054 const CXXDestructorDecl *OverriddenDD =
2055 cast<CXXDestructorDecl>(OverriddenMD);
Anders Carlssonf942ee02009-11-27 20:47:55 +00002056
Anders Carlsson65b49782010-02-12 05:25:12 +00002057 // Add both the complete and deleting entries.
2058 MethodVtableIndices[GlobalDecl(DD, Dtor_Complete)] =
2059 getMethodVtableIndex(GlobalDecl(OverriddenDD, Dtor_Complete));
2060 MethodVtableIndices[GlobalDecl(DD, Dtor_Deleting)] =
2061 getMethodVtableIndex(GlobalDecl(OverriddenDD, Dtor_Deleting));
2062 } else {
2063 MethodVtableIndices[MD] = getMethodVtableIndex(OverriddenMD);
2064 }
2065
2066 // We don't need to add an entry for this method.
Anders Carlsson07604812010-02-12 18:14:46 +00002067 continue;
Anders Carlssonf942ee02009-11-27 20:47:55 +00002068 }
2069 }
2070
Anders Carlssonf942ee02009-11-27 20:47:55 +00002071 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
2072 if (MD->isImplicit()) {
2073 assert(!ImplicitVirtualDtor &&
2074 "Did already see an implicit virtual dtor!");
2075 ImplicitVirtualDtor = DD;
2076 continue;
2077 }
2078
2079 // Add the complete dtor.
2080 MethodVtableIndices[GlobalDecl(DD, Dtor_Complete)] = CurrentIndex++;
2081
2082 // Add the deleting dtor.
2083 MethodVtableIndices[GlobalDecl(DD, Dtor_Deleting)] = CurrentIndex++;
2084 } else {
2085 // Add the entry.
2086 MethodVtableIndices[MD] = CurrentIndex++;
2087 }
2088 }
2089
2090 if (ImplicitVirtualDtor) {
2091 // Itanium C++ ABI 2.5.2:
2092 // If a class has an implicitly-defined virtual destructor,
2093 // its entries come after the declared virtual function pointers.
2094
2095 // Add the complete dtor.
2096 MethodVtableIndices[GlobalDecl(ImplicitVirtualDtor, Dtor_Complete)] =
2097 CurrentIndex++;
2098
2099 // Add the deleting dtor.
2100 MethodVtableIndices[GlobalDecl(ImplicitVirtualDtor, Dtor_Deleting)] =
2101 CurrentIndex++;
2102 }
2103
2104 NumVirtualFunctionPointers[RD] = CurrentIndex;
2105}
2106
2107uint64_t CGVtableInfo::getNumVirtualFunctionPointers(const CXXRecordDecl *RD) {
2108 llvm::DenseMap<const CXXRecordDecl *, uint64_t>::iterator I =
2109 NumVirtualFunctionPointers.find(RD);
2110 if (I != NumVirtualFunctionPointers.end())
2111 return I->second;
2112
2113 ComputeMethodVtableIndices(RD);
2114
2115 I = NumVirtualFunctionPointers.find(RD);
2116 assert(I != NumVirtualFunctionPointers.end() && "Did not find entry!");
2117 return I->second;
2118}
2119
2120uint64_t CGVtableInfo::getMethodVtableIndex(GlobalDecl GD) {
Anders Carlssonfb4dda42009-11-13 17:08:56 +00002121 MethodVtableIndicesTy::iterator I = MethodVtableIndices.find(GD);
Anders Carlsson2bb27f52009-10-11 22:13:54 +00002122 if (I != MethodVtableIndices.end())
2123 return I->second;
2124
Anders Carlssonfb4dda42009-11-13 17:08:56 +00002125 const CXXRecordDecl *RD = cast<CXXMethodDecl>(GD.getDecl())->getParent();
Anders Carlssonf942ee02009-11-27 20:47:55 +00002126
2127 ComputeMethodVtableIndices(RD);
2128
Anders Carlssonfb4dda42009-11-13 17:08:56 +00002129 I = MethodVtableIndices.find(GD);
Anders Carlsson2bb27f52009-10-11 22:13:54 +00002130 assert(I != MethodVtableIndices.end() && "Did not find index!");
2131 return I->second;
2132}
2133
Eli Friedman31bc3ad2009-12-07 23:56:34 +00002134CGVtableInfo::AdjustmentVectorTy*
2135CGVtableInfo::getAdjustments(GlobalDecl GD) {
2136 SavedAdjustmentsTy::iterator I = SavedAdjustments.find(GD);
2137 if (I != SavedAdjustments.end())
2138 return &I->second;
Eli Friedman8174f2c2009-12-06 22:01:30 +00002139
2140 const CXXRecordDecl *RD = cast<CXXRecordDecl>(GD.getDecl()->getDeclContext());
Eli Friedman31bc3ad2009-12-07 23:56:34 +00002141 if (!SavedAdjustmentRecords.insert(RD).second)
2142 return 0;
Eli Friedman8174f2c2009-12-06 22:01:30 +00002143
Anders Carlsson5f9a8812010-01-14 02:29:07 +00002144 AddressPointsMapTy AddressPoints;
Anders Carlsson5d40c6f2010-02-11 08:02:13 +00002145 OldVtableBuilder b(RD, RD, 0, CGM, false, AddressPoints);
Eli Friedman8174f2c2009-12-06 22:01:30 +00002146 D1(printf("vtable %s\n", RD->getNameAsCString()));
2147 b.GenerateVtableForBase(RD);
2148 b.GenerateVtableForVBases(RD);
Eli Friedman8174f2c2009-12-06 22:01:30 +00002149
Anders Carlsson5d40c6f2010-02-11 08:02:13 +00002150 for (OldVtableBuilder::SavedAdjustmentsVectorTy::iterator
Eli Friedman31bc3ad2009-12-07 23:56:34 +00002151 i = b.getSavedAdjustments().begin(),
2152 e = b.getSavedAdjustments().end(); i != e; i++)
2153 SavedAdjustments[i->first].push_back(i->second);
Eli Friedman8174f2c2009-12-06 22:01:30 +00002154
Eli Friedman31bc3ad2009-12-07 23:56:34 +00002155 I = SavedAdjustments.find(GD);
2156 if (I != SavedAdjustments.end())
2157 return &I->second;
2158
2159 return 0;
Eli Friedman8174f2c2009-12-06 22:01:30 +00002160}
2161
Anders Carlsson2bb27f52009-10-11 22:13:54 +00002162int64_t CGVtableInfo::getVirtualBaseOffsetIndex(const CXXRecordDecl *RD,
2163 const CXXRecordDecl *VBase) {
2164 ClassPairTy ClassPair(RD, VBase);
2165
2166 VirtualBaseClassIndiciesTy::iterator I =
2167 VirtualBaseClassIndicies.find(ClassPair);
2168 if (I != VirtualBaseClassIndicies.end())
2169 return I->second;
2170
Anders Carlsson2bb27f52009-10-11 22:13:54 +00002171 // FIXME: This seems expensive. Can we do a partial job to get
2172 // just this data.
Anders Carlsson5f9a8812010-01-14 02:29:07 +00002173 AddressPointsMapTy AddressPoints;
Anders Carlsson5d40c6f2010-02-11 08:02:13 +00002174 OldVtableBuilder b(RD, RD, 0, CGM, false, AddressPoints);
Mike Stump75ce5732009-10-31 20:06:59 +00002175 D1(printf("vtable %s\n", RD->getNameAsCString()));
Anders Carlsson2bb27f52009-10-11 22:13:54 +00002176 b.GenerateVtableForBase(RD);
2177 b.GenerateVtableForVBases(RD);
2178
2179 for (llvm::DenseMap<const CXXRecordDecl *, uint64_t>::iterator I =
2180 b.getVBIndex().begin(), E = b.getVBIndex().end(); I != E; ++I) {
2181 // Insert all types.
2182 ClassPairTy ClassPair(RD, I->first);
2183
2184 VirtualBaseClassIndicies.insert(std::make_pair(ClassPair, I->second));
2185 }
2186
2187 I = VirtualBaseClassIndicies.find(ClassPair);
2188 assert(I != VirtualBaseClassIndicies.end() && "Did not find index!");
2189
2190 return I->second;
2191}
2192
Anders Carlssonc8e39ec2009-12-05 21:03:56 +00002193uint64_t CGVtableInfo::getVtableAddressPoint(const CXXRecordDecl *RD) {
2194 uint64_t AddressPoint =
Anders Carlsson93a18842010-01-02 18:02:32 +00002195 (*(*(CGM.getVtableInfo().AddressPoints[RD]))[RD])[std::make_pair(RD, 0)];
Anders Carlssonc8e39ec2009-12-05 21:03:56 +00002196
2197 return AddressPoint;
2198}
2199
Anders Carlsson7e28c5f2009-12-06 00:01:05 +00002200llvm::GlobalVariable *
Anders Carlsson0911ae82009-12-06 00:23:49 +00002201CGVtableInfo::GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage,
Anders Carlsson232324c2009-12-06 00:53:22 +00002202 bool GenerateDefinition,
Anders Carlsson0911ae82009-12-06 00:23:49 +00002203 const CXXRecordDecl *LayoutClass,
Anders Carlsson5f9a8812010-01-14 02:29:07 +00002204 const CXXRecordDecl *RD, uint64_t Offset,
2205 AddressPointsMapTy& AddressPoints) {
Anders Carlssoneee53d92010-02-13 02:02:03 +00002206 if (GenerateDefinition && CGM.getLangOptions().DumpVtableLayouts) {
2207 VtableBuilder Builder(RD);
2208
2209 Builder.dumpLayout(llvm::errs());
2210 }
2211
Anders Carlsson2bb27f52009-10-11 22:13:54 +00002212 llvm::SmallString<256> OutName;
Mike Stump2cefe382009-11-12 20:47:57 +00002213 if (LayoutClass != RD)
Anders Carlsson7e28c5f2009-12-06 00:01:05 +00002214 CGM.getMangleContext().mangleCXXCtorVtable(LayoutClass, Offset / 8,
2215 RD, OutName);
Mike Stumpeac45592009-11-11 20:26:26 +00002216 else
Anders Carlsson7e28c5f2009-12-06 00:01:05 +00002217 CGM.getMangleContext().mangleCXXVtable(RD, OutName);
Daniel Dunbare128dd12009-11-21 09:06:22 +00002218 llvm::StringRef Name = OutName.str();
Benjamin Kramerbb0a07b2009-10-11 22:57:54 +00002219
Anders Carlsson7e28c5f2009-12-06 00:01:05 +00002220 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
Anders Carlsson93a18842010-01-02 18:02:32 +00002221 if (GV == 0 || CGM.getVtableInfo().AddressPoints[LayoutClass] == 0 ||
2222 GV->isDeclaration()) {
Anders Carlsson5d40c6f2010-02-11 08:02:13 +00002223 OldVtableBuilder b(RD, LayoutClass, Offset, CGM, GenerateDefinition,
2224 AddressPoints);
Eli Friedman6c08ce72009-12-05 01:05:03 +00002225
2226 D1(printf("vtable %s\n", RD->getNameAsCString()));
2227 // First comes the vtables for all the non-virtual bases...
Mike Stumpd538a6d2009-12-24 07:29:41 +00002228 b.GenerateVtableForBase(RD, Offset);
Eli Friedman6c08ce72009-12-05 01:05:03 +00002229
2230 // then the vtables for all the virtual bases.
2231 b.GenerateVtableForVBases(RD, Offset);
2232
Anders Carlsson58b271d2009-12-05 22:19:10 +00002233 llvm::Constant *Init = 0;
Anders Carlsson7e28c5f2009-12-06 00:01:05 +00002234 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
Anders Carlsson58b271d2009-12-05 22:19:10 +00002235 llvm::ArrayType *ArrayType =
Anders Carlssonfe5f7d92009-12-06 01:09:21 +00002236 llvm::ArrayType::get(Int8PtrTy, b.getVtableComponents().size());
Anders Carlssona95d4c52009-12-05 21:09:05 +00002237
Anders Carlsson232324c2009-12-06 00:53:22 +00002238 if (GenerateDefinition)
Anders Carlssonfe5f7d92009-12-06 01:09:21 +00002239 Init = llvm::ConstantArray::get(ArrayType, &b.getVtableComponents()[0],
2240 b.getVtableComponents().size());
Anders Carlsson232324c2009-12-06 00:53:22 +00002241
Mike Stumpaa51ad62009-11-19 04:04:36 +00002242 llvm::GlobalVariable *OGV = GV;
Anders Carlsson232324c2009-12-06 00:53:22 +00002243
2244 GV = new llvm::GlobalVariable(CGM.getModule(), ArrayType,
2245 /*isConstant=*/true, Linkage, Init, Name);
Anders Carlssonfe5f7d92009-12-06 01:09:21 +00002246 CGM.setGlobalVisibility(GV, RD);
2247
Mike Stumpaa51ad62009-11-19 04:04:36 +00002248 if (OGV) {
2249 GV->takeName(OGV);
Anders Carlsson58b271d2009-12-05 22:19:10 +00002250 llvm::Constant *NewPtr =
2251 llvm::ConstantExpr::getBitCast(GV, OGV->getType());
Mike Stumpaa51ad62009-11-19 04:04:36 +00002252 OGV->replaceAllUsesWith(NewPtr);
2253 OGV->eraseFromParent();
2254 }
Mike Stumpaa51ad62009-11-19 04:04:36 +00002255 }
Anders Carlssonb3f54b72009-12-05 21:28:12 +00002256
2257 return GV;
Anders Carlsson2bb27f52009-10-11 22:13:54 +00002258}
Mike Stump9f23a142009-11-10 02:30:51 +00002259
Anders Carlsson232324c2009-12-06 00:53:22 +00002260void CGVtableInfo::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
2261 const CXXRecordDecl *RD) {
Anders Carlssone1b3e622009-12-07 07:59:52 +00002262 llvm::GlobalVariable *&Vtable = Vtables[RD];
2263 if (Vtable) {
2264 assert(Vtable->getInitializer() && "Vtable doesn't have a definition!");
2265 return;
2266 }
2267
Anders Carlsson5f9a8812010-01-14 02:29:07 +00002268 AddressPointsMapTy AddressPoints;
2269 Vtable = GenerateVtable(Linkage, /*GenerateDefinition=*/true, RD, RD, 0,
2270 AddressPoints);
Anders Carlssone36a6b32010-01-02 01:01:18 +00002271 GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD);
Mike Stump1a139f82009-11-19 01:08:19 +00002272}
2273
Anders Carlsson7e28c5f2009-12-06 00:01:05 +00002274llvm::GlobalVariable *CGVtableInfo::getVtable(const CXXRecordDecl *RD) {
Anders Carlsson232324c2009-12-06 00:53:22 +00002275 llvm::GlobalVariable *Vtable = Vtables.lookup(RD);
Anders Carlsson7e28c5f2009-12-06 00:01:05 +00002276
Anders Carlsson5f9a8812010-01-14 02:29:07 +00002277 if (!Vtable) {
2278 AddressPointsMapTy AddressPoints;
Anders Carlsson232324c2009-12-06 00:53:22 +00002279 Vtable = GenerateVtable(llvm::GlobalValue::ExternalLinkage,
Anders Carlsson5f9a8812010-01-14 02:29:07 +00002280 /*GenerateDefinition=*/false, RD, RD, 0,
2281 AddressPoints);
2282 }
Mike Stumpaa51ad62009-11-19 04:04:36 +00002283
Anders Carlsson4ed44eb2009-12-05 22:42:54 +00002284 return Vtable;
Mike Stumpd846d082009-11-10 07:44:33 +00002285}
Mike Stumpeac45592009-11-11 20:26:26 +00002286
Anders Carlssonb1d3f7c2009-11-30 23:41:22 +00002287void CGVtableInfo::MaybeEmitVtable(GlobalDecl GD) {
2288 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
2289 const CXXRecordDecl *RD = MD->getParent();
2290
Anders Carlsson4ed44eb2009-12-05 22:42:54 +00002291 // If the class doesn't have a vtable we don't need to emit one.
2292 if (!RD->isDynamicClass())
2293 return;
2294
Anders Carlssonb1d3f7c2009-11-30 23:41:22 +00002295 // Get the key function.
Anders Carlsson5ebf8b42009-12-07 04:35:11 +00002296 const CXXMethodDecl *KeyFunction = CGM.getContext().getKeyFunction(RD);
Anders Carlssonb1d3f7c2009-11-30 23:41:22 +00002297
Anders Carlsson4ed44eb2009-12-05 22:42:54 +00002298 if (KeyFunction) {
2299 // We don't have the right key function.
2300 if (KeyFunction->getCanonicalDecl() != MD->getCanonicalDecl())
2301 return;
Anders Carlssonb1d3f7c2009-11-30 23:41:22 +00002302 }
2303
Anders Carlssonb1d3f7c2009-11-30 23:41:22 +00002304 // Emit the data.
Douglas Gregorccecc1b2010-01-06 20:27:16 +00002305 GenerateClassData(CGM.getVtableLinkage(RD), RD);
Eli Friedman8174f2c2009-12-06 22:01:30 +00002306
2307 for (CXXRecordDecl::method_iterator i = RD->method_begin(),
2308 e = RD->method_end(); i != e; ++i) {
Eli Friedman31bc3ad2009-12-07 23:56:34 +00002309 if ((*i)->isVirtual() && ((*i)->hasInlineBody() || (*i)->isImplicit())) {
Eli Friedman8174f2c2009-12-06 22:01:30 +00002310 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(*i)) {
2311 CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Complete));
2312 CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Deleting));
2313 } else {
2314 CGM.BuildThunksForVirtual(GlobalDecl(*i));
2315 }
2316 }
2317 }
Anders Carlssonb1d3f7c2009-11-30 23:41:22 +00002318}
2319