1//===--- MicrosoftCXXABI.cpp - Emit LLVM Code from ASTs for a Module ------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This provides C++ code generation targeting the Microsoft Visual C++ ABI.
10// The class in this file generates structures that follow the Microsoft
11// Visual C++ ABI, which is actually not very well documented at all outside
12// of Microsoft.
13//
14//===----------------------------------------------------------------------===//
15
16#include "ABIInfo.h"
17#include "CGCXXABI.h"
18#include "CGCleanup.h"
19#include "CGDebugInfo.h"
20#include "CGVTables.h"
21#include "CodeGenModule.h"
22#include "CodeGenTypes.h"
23#include "TargetInfo.h"
24#include "clang/AST/Attr.h"
25#include "clang/AST/CXXInheritance.h"
26#include "clang/AST/Decl.h"
27#include "clang/AST/DeclCXX.h"
28#include "clang/AST/StmtCXX.h"
29#include "clang/AST/VTableBuilder.h"
30#include "clang/CodeGen/ConstantInitBuilder.h"
31#include "llvm/ADT/StringExtras.h"
32#include "llvm/ADT/StringSet.h"
33#include "llvm/IR/Intrinsics.h"
34
35using namespace clang;
36using namespace CodeGen;
37
38namespace {
39
40/// Holds all the vbtable globals for a given class.
41struct VBTableGlobals {
42 const VPtrInfoVector *VBTables;
43 SmallVector<llvm::GlobalVariable *, 2> Globals;
44};
45
46class MicrosoftCXXABI : public CGCXXABI {
47public:
48 MicrosoftCXXABI(CodeGenModule &CGM)
49 : CGCXXABI(CGM), BaseClassDescriptorType(nullptr),
50 ClassHierarchyDescriptorType(nullptr),
51 CompleteObjectLocatorType(nullptr), CatchableTypeType(nullptr),
52 ThrowInfoType(nullptr) {
53 assert(!(CGM.getLangOpts().isExplicitDefaultVisibilityExportMapping() ||
54 CGM.getLangOpts().isAllDefaultVisibilityExportMapping()) &&
55 "visibility export mapping option unimplemented in this ABI");
56 }
57
58 bool HasThisReturn(GlobalDecl GD) const override;
59 bool hasMostDerivedReturn(GlobalDecl GD) const override;
60
61 bool classifyReturnType(CGFunctionInfo &FI) const override;
62
63 RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const override;
64
65 bool isSRetParameterAfterThis() const override { return true; }
66
67 bool isThisCompleteObject(GlobalDecl GD) const override {
68 // The Microsoft ABI doesn't use separate complete-object vs.
69 // base-object variants of constructors, but it does of destructors.
70 if (isa<CXXDestructorDecl>(Val: GD.getDecl())) {
71 switch (GD.getDtorType()) {
72 case Dtor_Complete:
73 case Dtor_Deleting:
74 return true;
75
76 case Dtor_Base:
77 return false;
78
79 case Dtor_Comdat: llvm_unreachable("emitting dtor comdat as function?");
80 }
81 llvm_unreachable("bad dtor kind");
82 }
83
84 // No other kinds.
85 return false;
86 }
87
88 size_t getSrcArgforCopyCtor(const CXXConstructorDecl *CD,
89 FunctionArgList &Args) const override {
90 assert(Args.size() >= 2 &&
91 "expected the arglist to have at least two args!");
92 // The 'most_derived' parameter goes second if the ctor is variadic and
93 // has v-bases.
94 if (CD->getParent()->getNumVBases() > 0 &&
95 CD->getType()->castAs<FunctionProtoType>()->isVariadic())
96 return 2;
97 return 1;
98 }
99
100 std::vector<CharUnits> getVBPtrOffsets(const CXXRecordDecl *RD) override {
101 std::vector<CharUnits> VBPtrOffsets;
102 const ASTContext &Context = getContext();
103 const ASTRecordLayout &Layout = Context.getASTRecordLayout(D: RD);
104
105 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
106 for (const std::unique_ptr<VPtrInfo> &VBT : *VBGlobals.VBTables) {
107 const ASTRecordLayout &SubobjectLayout =
108 Context.getASTRecordLayout(D: VBT->IntroducingObject);
109 CharUnits Offs = VBT->NonVirtualOffset;
110 Offs += SubobjectLayout.getVBPtrOffset();
111 if (VBT->getVBaseWithVPtr())
112 Offs += Layout.getVBaseClassOffset(VBase: VBT->getVBaseWithVPtr());
113 VBPtrOffsets.push_back(x: Offs);
114 }
115 llvm::array_pod_sort(Start: VBPtrOffsets.begin(), End: VBPtrOffsets.end());
116 return VBPtrOffsets;
117 }
118
119 StringRef GetPureVirtualCallName() override { return "_purecall"; }
120 StringRef GetDeletedVirtualCallName() override { return "_purecall"; }
121
122 void emitVirtualObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE,
123 Address Ptr, QualType ElementType,
124 const CXXDestructorDecl *Dtor) override;
125
126 void emitRethrow(CodeGenFunction &CGF, bool isNoReturn) override;
127 void emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) override;
128
129 void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C) override;
130
131 llvm::GlobalVariable *getMSCompleteObjectLocator(const CXXRecordDecl *RD,
132 const VPtrInfo &Info);
133
134 llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) override;
135 CatchTypeInfo
136 getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType) override;
137
138 /// MSVC needs an extra flag to indicate a catchall.
139 CatchTypeInfo getCatchAllTypeInfo() override {
140 // For -EHa catch(...) must handle HW exception
141 // Adjective = HT_IsStdDotDot (0x40), only catch C++ exceptions
142 if (getContext().getLangOpts().EHAsynch)
143 return CatchTypeInfo{.RTTI: nullptr, .Flags: 0};
144 else
145 return CatchTypeInfo{.RTTI: nullptr, .Flags: 0x40};
146 }
147
148 bool shouldTypeidBeNullChecked(QualType SrcRecordTy) override;
149 void EmitBadTypeidCall(CodeGenFunction &CGF) override;
150 llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
151 Address ThisPtr,
152 llvm::Type *StdTypeInfoPtrTy) override;
153
154 bool shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
155 QualType SrcRecordTy) override;
156
157 bool shouldEmitExactDynamicCast(QualType DestRecordTy) override {
158 // TODO: Add support for exact dynamic_casts.
159 return false;
160 }
161 llvm::Value *emitExactDynamicCast(CodeGenFunction &CGF, Address Value,
162 QualType SrcRecordTy, QualType DestTy,
163 QualType DestRecordTy,
164 llvm::BasicBlock *CastSuccess,
165 llvm::BasicBlock *CastFail) override {
166 llvm_unreachable("unsupported");
167 }
168
169 llvm::Value *emitDynamicCastCall(CodeGenFunction &CGF, Address Value,
170 QualType SrcRecordTy, QualType DestTy,
171 QualType DestRecordTy,
172 llvm::BasicBlock *CastEnd) override;
173
174 llvm::Value *emitDynamicCastToVoid(CodeGenFunction &CGF, Address Value,
175 QualType SrcRecordTy) override;
176
177 bool EmitBadCastCall(CodeGenFunction &CGF) override;
178 bool canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const override {
179 return false;
180 }
181
182 llvm::Value *
183 GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This,
184 const CXXRecordDecl *ClassDecl,
185 const CXXRecordDecl *BaseClassDecl) override;
186
187 llvm::BasicBlock *
188 EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
189 const CXXRecordDecl *RD) override;
190
191 llvm::BasicBlock *
192 EmitDtorCompleteObjectHandler(CodeGenFunction &CGF);
193
194 void initializeHiddenVirtualInheritanceMembers(CodeGenFunction &CGF,
195 const CXXRecordDecl *RD) override;
196
197 void EmitCXXConstructors(const CXXConstructorDecl *D) override;
198
199 // Background on MSVC destructors
200 // ==============================
201 //
202 // Both Itanium and MSVC ABIs have destructor variants. The variant names
203 // roughly correspond in the following way:
204 // Itanium Microsoft
205 // Base -> no name, just ~Class
206 // Complete -> vbase destructor
207 // Deleting -> scalar deleting destructor
208 // vector deleting destructor
209 //
210 // The base and complete destructors are the same as in Itanium, although the
211 // complete destructor does not accept a VTT parameter when there are virtual
212 // bases. A separate mechanism involving vtordisps is used to ensure that
213 // virtual methods of destroyed subobjects are not called.
214 //
215 // The deleting destructors accept an i32 bitfield as a second parameter. Bit
216 // 1 indicates if the memory should be deleted. Bit 2 indicates if the this
217 // pointer points to an array. The scalar deleting destructor assumes that
218 // bit 2 is zero, and therefore does not contain a loop.
219 //
220 // For virtual destructors, only one entry is reserved in the vftable, and it
221 // always points to the vector deleting destructor. The vector deleting
222 // destructor is the most general, so it can be used to destroy objects in
223 // place, delete single heap objects, or delete arrays.
224 //
225 // A TU defining a non-inline destructor is only guaranteed to emit a base
226 // destructor, and all of the other variants are emitted on an as-needed basis
227 // in COMDATs. Because a non-base destructor can be emitted in a TU that
228 // lacks a definition for the destructor, non-base destructors must always
229 // delegate to or alias the base destructor.
230
231 AddedStructorArgCounts
232 buildStructorSignature(GlobalDecl GD,
233 SmallVectorImpl<CanQualType> &ArgTys) override;
234
235 /// Non-base dtors should be emitted as delegating thunks in this ABI.
236 bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor,
237 CXXDtorType DT) const override {
238 return DT != Dtor_Base;
239 }
240
241 void setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
242 const CXXDestructorDecl *Dtor,
243 CXXDtorType DT) const override;
244
245 llvm::GlobalValue::LinkageTypes
246 getCXXDestructorLinkage(GVALinkage Linkage, const CXXDestructorDecl *Dtor,
247 CXXDtorType DT) const override;
248
249 void EmitCXXDestructors(const CXXDestructorDecl *D) override;
250
251 const CXXRecordDecl *getThisArgumentTypeForMethod(GlobalDecl GD) override {
252 auto *MD = cast<CXXMethodDecl>(Val: GD.getDecl());
253
254 if (MD->isVirtual()) {
255 GlobalDecl LookupGD = GD;
256 if (const auto *DD = dyn_cast<CXXDestructorDecl>(Val: MD)) {
257 // Complete dtors take a pointer to the complete object,
258 // thus don't need adjustment.
259 if (GD.getDtorType() == Dtor_Complete)
260 return MD->getParent();
261
262 // There's only Dtor_Deleting in vftable but it shares the this
263 // adjustment with the base one, so look up the deleting one instead.
264 LookupGD = GlobalDecl(DD, Dtor_Deleting);
265 }
266 MethodVFTableLocation ML =
267 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD: LookupGD);
268
269 // The vbases might be ordered differently in the final overrider object
270 // and the complete object, so the "this" argument may sometimes point to
271 // memory that has no particular type (e.g. past the complete object).
272 // In this case, we just use a generic pointer type.
273 // FIXME: might want to have a more precise type in the non-virtual
274 // multiple inheritance case.
275 if (ML.VBase || !ML.VFPtrOffset.isZero())
276 return nullptr;
277 }
278 return MD->getParent();
279 }
280
281 Address
282 adjustThisArgumentForVirtualFunctionCall(CodeGenFunction &CGF, GlobalDecl GD,
283 Address This,
284 bool VirtualCall) override;
285
286 void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy,
287 FunctionArgList &Params) override;
288
289 void EmitInstanceFunctionProlog(CodeGenFunction &CGF) override;
290
291 AddedStructorArgs getImplicitConstructorArgs(CodeGenFunction &CGF,
292 const CXXConstructorDecl *D,
293 CXXCtorType Type,
294 bool ForVirtualBase,
295 bool Delegating) override;
296
297 llvm::Value *getCXXDestructorImplicitParam(CodeGenFunction &CGF,
298 const CXXDestructorDecl *DD,
299 CXXDtorType Type,
300 bool ForVirtualBase,
301 bool Delegating) override;
302
303 void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD,
304 CXXDtorType Type, bool ForVirtualBase,
305 bool Delegating, Address This,
306 QualType ThisTy) override;
307
308 void emitVTableTypeMetadata(const VPtrInfo &Info, const CXXRecordDecl *RD,
309 llvm::GlobalVariable *VTable);
310
311 void emitVTableDefinitions(CodeGenVTables &CGVT,
312 const CXXRecordDecl *RD) override;
313
314 bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF,
315 CodeGenFunction::VPtr Vptr) override;
316
317 /// Don't initialize vptrs if dynamic class
318 /// is marked with the 'novtable' attribute.
319 bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass) override {
320 return !VTableClass->hasAttr<MSNoVTableAttr>();
321 }
322
323 llvm::Constant *
324 getVTableAddressPoint(BaseSubobject Base,
325 const CXXRecordDecl *VTableClass) override;
326
327 llvm::Value *getVTableAddressPointInStructor(
328 CodeGenFunction &CGF, const CXXRecordDecl *VTableClass,
329 BaseSubobject Base, const CXXRecordDecl *NearestVBase) override;
330
331 llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD,
332 CharUnits VPtrOffset) override;
333
334 CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
335 Address This, llvm::Type *Ty,
336 SourceLocation Loc) override;
337
338 llvm::Value *
339 EmitVirtualDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *Dtor,
340 CXXDtorType DtorType, Address This,
341 DeleteOrMemberCallExpr E,
342 llvm::CallBase **CallOrInvoke) override;
343
344 void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, GlobalDecl GD,
345 CallArgList &CallArgs) override {
346 assert(GD.getDtorType() == Dtor_Deleting &&
347 "Only deleting destructor thunks are available in this ABI");
348 CallArgs.add(rvalue: RValue::get(V: getStructorImplicitParamValue(CGF)),
349 type: getContext().IntTy);
350 }
351
352 void emitVirtualInheritanceTables(const CXXRecordDecl *RD) override;
353
354 llvm::GlobalVariable *
355 getAddrOfVBTable(const VPtrInfo &VBT, const CXXRecordDecl *RD,
356 llvm::GlobalVariable::LinkageTypes Linkage);
357
358 llvm::GlobalVariable *
359 getAddrOfVirtualDisplacementMap(const CXXRecordDecl *SrcRD,
360 const CXXRecordDecl *DstRD) {
361 SmallString<256> OutName;
362 llvm::raw_svector_ostream Out(OutName);
363 getMangleContext().mangleCXXVirtualDisplacementMap(SrcRD, DstRD, Out);
364 StringRef MangledName = OutName.str();
365
366 if (auto *VDispMap = CGM.getModule().getNamedGlobal(Name: MangledName))
367 return VDispMap;
368
369 MicrosoftVTableContext &VTContext = CGM.getMicrosoftVTableContext();
370 unsigned NumEntries = 1 + SrcRD->getNumVBases();
371 SmallVector<llvm::Constant *, 4> Map(NumEntries,
372 llvm::PoisonValue::get(T: CGM.IntTy));
373 Map[0] = llvm::ConstantInt::get(Ty: CGM.IntTy, V: 0);
374 bool AnyDifferent = false;
375 for (const auto &I : SrcRD->vbases()) {
376 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
377 if (!DstRD->isVirtuallyDerivedFrom(Base: VBase))
378 continue;
379
380 unsigned SrcVBIndex = VTContext.getVBTableIndex(Derived: SrcRD, VBase);
381 unsigned DstVBIndex = VTContext.getVBTableIndex(Derived: DstRD, VBase);
382 Map[SrcVBIndex] = llvm::ConstantInt::get(Ty: CGM.IntTy, V: DstVBIndex * 4);
383 AnyDifferent |= SrcVBIndex != DstVBIndex;
384 }
385 // This map would be useless, don't use it.
386 if (!AnyDifferent)
387 return nullptr;
388
389 llvm::ArrayType *VDispMapTy = llvm::ArrayType::get(ElementType: CGM.IntTy, NumElements: Map.size());
390 llvm::Constant *Init = llvm::ConstantArray::get(T: VDispMapTy, V: Map);
391 llvm::GlobalValue::LinkageTypes Linkage =
392 SrcRD->isExternallyVisible() && DstRD->isExternallyVisible()
393 ? llvm::GlobalValue::LinkOnceODRLinkage
394 : llvm::GlobalValue::InternalLinkage;
395 auto *VDispMap = new llvm::GlobalVariable(
396 CGM.getModule(), VDispMapTy, /*isConstant=*/true, Linkage,
397 /*Initializer=*/Init, MangledName);
398 return VDispMap;
399 }
400
401 void emitVBTableDefinition(const VPtrInfo &VBT, const CXXRecordDecl *RD,
402 llvm::GlobalVariable *GV) const;
403
404 void setThunkLinkage(llvm::Function *Thunk, bool ForVTable,
405 GlobalDecl GD, bool ReturnAdjustment) override {
406 GVALinkage Linkage =
407 getContext().GetGVALinkageForFunction(FD: cast<FunctionDecl>(Val: GD.getDecl()));
408
409 if (Linkage == GVA_Internal)
410 Thunk->setLinkage(llvm::GlobalValue::InternalLinkage);
411 else if (ReturnAdjustment)
412 Thunk->setLinkage(llvm::GlobalValue::WeakODRLinkage);
413 else
414 Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
415 }
416
417 bool exportThunk() override { return false; }
418
419 llvm::Value *performThisAdjustment(CodeGenFunction &CGF, Address This,
420 const CXXRecordDecl * /*UnadjustedClass*/,
421 const ThunkInfo &TI) override;
422
423 llvm::Value *performReturnAdjustment(CodeGenFunction &CGF, Address Ret,
424 const CXXRecordDecl * /*UnadjustedClass*/,
425 const ReturnAdjustment &RA) override;
426
427 void EmitThreadLocalInitFuncs(
428 CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals,
429 ArrayRef<llvm::Function *> CXXThreadLocalInits,
430 ArrayRef<const VarDecl *> CXXThreadLocalInitVars) override;
431
432 bool usesThreadWrapperFunction(const VarDecl *VD) const override {
433 return getContext().getLangOpts().isCompatibleWithMSVC(
434 MajorVersion: LangOptions::MSVC2019_5) &&
435 CGM.getCodeGenOpts().TlsGuards &&
436 (!isEmittedWithConstantInitializer(VD) || mayNeedDestruction(VD));
437 }
438 LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD,
439 QualType LValType) override;
440
441 void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
442 llvm::GlobalVariable *DeclPtr,
443 bool PerformInit) override;
444 void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
445 llvm::FunctionCallee Dtor,
446 llvm::Constant *Addr) override;
447
448 // ==== Notes on array cookies =========
449 //
450 // MSVC seems to only use cookies when the class has a destructor; a
451 // two-argument usual array deallocation function isn't sufficient.
452 //
453 // For example, this code prints "100" and "1":
454 // struct A {
455 // char x;
456 // void *operator new[](size_t sz) {
457 // printf("%u\n", sz);
458 // return malloc(sz);
459 // }
460 // void operator delete[](void *p, size_t sz) {
461 // printf("%u\n", sz);
462 // free(p);
463 // }
464 // };
465 // int main() {
466 // A *p = new A[100];
467 // delete[] p;
468 // }
469 // Whereas it prints "104" and "104" if you give A a destructor.
470
471 bool requiresArrayCookie(const CXXDeleteExpr *expr,
472 QualType elementType) override;
473 bool requiresArrayCookie(const CXXNewExpr *expr) override;
474 CharUnits getArrayCookieSizeImpl(QualType type) override;
475 Address InitializeArrayCookie(CodeGenFunction &CGF,
476 Address NewPtr,
477 llvm::Value *NumElements,
478 const CXXNewExpr *expr,
479 QualType ElementType) override;
480 llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
481 Address allocPtr,
482 CharUnits cookieSize) override;
483
484 friend struct MSRTTIBuilder;
485
486 bool isImageRelative() const {
487 return CGM.getTarget().getPointerWidth(AddrSpace: LangAS::Default) == 64;
488 }
489
490 // 5 routines for constructing the llvm types for MS RTTI structs.
491 llvm::StructType *getTypeDescriptorType(StringRef TypeInfoString) {
492 llvm::SmallString<32> TDTypeName("rtti.TypeDescriptor");
493 TDTypeName += llvm::utostr(X: TypeInfoString.size());
494 llvm::StructType *&TypeDescriptorType =
495 TypeDescriptorTypeMap[TypeInfoString.size()];
496 if (TypeDescriptorType)
497 return TypeDescriptorType;
498 llvm::Type *FieldTypes[] = {
499 CGM.Int8PtrPtrTy,
500 CGM.Int8PtrTy,
501 llvm::ArrayType::get(ElementType: CGM.Int8Ty, NumElements: TypeInfoString.size() + 1)};
502 TypeDescriptorType =
503 llvm::StructType::create(Context&: CGM.getLLVMContext(), Elements: FieldTypes, Name: TDTypeName);
504 return TypeDescriptorType;
505 }
506
507 llvm::Type *getImageRelativeType(llvm::Type *PtrType) {
508 if (!isImageRelative())
509 return PtrType;
510 return CGM.IntTy;
511 }
512
513 llvm::StructType *getBaseClassDescriptorType() {
514 if (BaseClassDescriptorType)
515 return BaseClassDescriptorType;
516 llvm::Type *FieldTypes[] = {
517 getImageRelativeType(PtrType: CGM.Int8PtrTy),
518 CGM.IntTy,
519 CGM.IntTy,
520 CGM.IntTy,
521 CGM.IntTy,
522 CGM.IntTy,
523 getImageRelativeType(PtrType: CGM.UnqualPtrTy),
524 };
525 BaseClassDescriptorType = llvm::StructType::create(
526 Context&: CGM.getLLVMContext(), Elements: FieldTypes, Name: "rtti.BaseClassDescriptor");
527 return BaseClassDescriptorType;
528 }
529
530 llvm::StructType *getClassHierarchyDescriptorType() {
531 if (ClassHierarchyDescriptorType)
532 return ClassHierarchyDescriptorType;
533 // Forward-declare RTTIClassHierarchyDescriptor to break a cycle.
534 llvm::Type *FieldTypes[] = {CGM.IntTy, CGM.IntTy, CGM.IntTy,
535 getImageRelativeType(PtrType: CGM.UnqualPtrTy)};
536 ClassHierarchyDescriptorType =
537 llvm::StructType::create(Elements: FieldTypes, Name: "rtti.ClassHierarchyDescriptor");
538 return ClassHierarchyDescriptorType;
539 }
540
541 llvm::StructType *getCompleteObjectLocatorType() {
542 if (CompleteObjectLocatorType)
543 return CompleteObjectLocatorType;
544 llvm::Type *FieldTypes[] = {
545 CGM.IntTy,
546 CGM.IntTy,
547 CGM.IntTy,
548 getImageRelativeType(PtrType: CGM.Int8PtrTy),
549 getImageRelativeType(PtrType: CGM.UnqualPtrTy),
550 getImageRelativeType(PtrType: CGM.VoidTy),
551 };
552 llvm::ArrayRef<llvm::Type *> FieldTypesRef(FieldTypes);
553 if (!isImageRelative())
554 FieldTypesRef = FieldTypesRef.drop_back();
555 CompleteObjectLocatorType =
556 llvm::StructType::create(Elements: FieldTypesRef, Name: "rtti.CompleteObjectLocator");
557 return CompleteObjectLocatorType;
558 }
559
560 llvm::GlobalVariable *getImageBase() {
561 StringRef Name = "__ImageBase";
562 if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name))
563 return GV;
564
565 auto *GV = new llvm::GlobalVariable(CGM.getModule(), CGM.Int8Ty,
566 /*isConstant=*/true,
567 llvm::GlobalValue::ExternalLinkage,
568 /*Initializer=*/nullptr, Name);
569 CGM.setDSOLocal(GV);
570 return GV;
571 }
572
573 llvm::Constant *getImageRelativeConstant(llvm::Constant *PtrVal) {
574 if (!isImageRelative())
575 return PtrVal;
576
577 if (PtrVal->isNullValue())
578 return llvm::Constant::getNullValue(Ty: CGM.IntTy);
579
580 llvm::Constant *ImageBaseAsInt =
581 llvm::ConstantExpr::getPtrToInt(C: getImageBase(), Ty: CGM.IntPtrTy);
582 llvm::Constant *PtrValAsInt =
583 llvm::ConstantExpr::getPtrToInt(C: PtrVal, Ty: CGM.IntPtrTy);
584 llvm::Constant *Diff =
585 llvm::ConstantExpr::getSub(C1: PtrValAsInt, C2: ImageBaseAsInt,
586 /*HasNUW=*/true, /*HasNSW=*/true);
587 return llvm::ConstantExpr::getTrunc(C: Diff, Ty: CGM.IntTy);
588 }
589
590private:
591 MicrosoftMangleContext &getMangleContext() {
592 return cast<MicrosoftMangleContext>(Val&: CodeGen::CGCXXABI::getMangleContext());
593 }
594
595 llvm::Constant *getZeroInt() {
596 return llvm::ConstantInt::get(Ty: CGM.IntTy, V: 0);
597 }
598
599 llvm::Constant *getAllOnesInt() {
600 return llvm::Constant::getAllOnesValue(Ty: CGM.IntTy);
601 }
602
603 CharUnits getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD) override;
604
605 void
606 GetNullMemberPointerFields(const MemberPointerType *MPT,
607 llvm::SmallVectorImpl<llvm::Constant *> &fields);
608
609 /// Shared code for virtual base adjustment. Returns the offset from
610 /// the vbptr to the virtual base. Optionally returns the address of the
611 /// vbptr itself.
612 llvm::Value *GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF,
613 Address Base,
614 llvm::Value *VBPtrOffset,
615 llvm::Value *VBTableOffset,
616 llvm::Value **VBPtr = nullptr);
617
618 llvm::Value *GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF,
619 Address Base,
620 int32_t VBPtrOffset,
621 int32_t VBTableOffset,
622 llvm::Value **VBPtr = nullptr) {
623 assert(VBTableOffset % 4 == 0 && "should be byte offset into table of i32s");
624 llvm::Value *VBPOffset = llvm::ConstantInt::get(Ty: CGM.IntTy, V: VBPtrOffset),
625 *VBTOffset = llvm::ConstantInt::get(Ty: CGM.IntTy, V: VBTableOffset);
626 return GetVBaseOffsetFromVBPtr(CGF, Base, VBPtrOffset: VBPOffset, VBTableOffset: VBTOffset, VBPtr);
627 }
628
629 std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
630 performBaseAdjustment(CodeGenFunction &CGF, Address Value,
631 QualType SrcRecordTy);
632
633 /// Performs a full virtual base adjustment. Used to dereference
634 /// pointers to members of virtual bases.
635 llvm::Value *AdjustVirtualBase(CodeGenFunction &CGF, const Expr *E,
636 const CXXRecordDecl *RD, Address Base,
637 llvm::Value *VirtualBaseAdjustmentOffset,
638 llvm::Value *VBPtrOffset /* optional */);
639
640 /// Emits a full member pointer with the fields common to data and
641 /// function member pointers.
642 llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField,
643 bool IsMemberFunction,
644 const CXXRecordDecl *RD,
645 CharUnits NonVirtualBaseAdjustment,
646 unsigned VBTableIndex);
647
648 bool MemberPointerConstantIsNull(const MemberPointerType *MPT,
649 llvm::Constant *MP);
650
651 /// - Initialize all vbptrs of 'this' with RD as the complete type.
652 void EmitVBPtrStores(CodeGenFunction &CGF, const CXXRecordDecl *RD);
653
654 /// Caching wrapper around VBTableBuilder::enumerateVBTables().
655 const VBTableGlobals &enumerateVBTables(const CXXRecordDecl *RD);
656
657 /// Generate a thunk for calling a virtual member function MD.
658 llvm::Function *EmitVirtualMemPtrThunk(const CXXMethodDecl *MD,
659 const MethodVFTableLocation &ML);
660
661 llvm::Constant *EmitMemberDataPointer(const CXXRecordDecl *RD,
662 CharUnits offset);
663
664public:
665 llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT) override;
666
667 bool isZeroInitializable(const MemberPointerType *MPT) override;
668
669 bool isMemberPointerConvertible(const MemberPointerType *MPT) const override {
670 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
671 return RD->hasAttr<MSInheritanceAttr>();
672 }
673
674 llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT) override;
675
676 llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT,
677 CharUnits offset) override;
678 llvm::Constant *EmitMemberFunctionPointer(const CXXMethodDecl *MD) override;
679 llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT) override;
680
681 llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
682 llvm::Value *L,
683 llvm::Value *R,
684 const MemberPointerType *MPT,
685 bool Inequality) override;
686
687 llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
688 llvm::Value *MemPtr,
689 const MemberPointerType *MPT) override;
690
691 llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E,
692 Address Base, llvm::Value *MemPtr,
693 const MemberPointerType *MPT,
694 bool IsInBounds) override;
695
696 llvm::Value *EmitNonNullMemberPointerConversion(
697 const MemberPointerType *SrcTy, const MemberPointerType *DstTy,
698 CastKind CK, CastExpr::path_const_iterator PathBegin,
699 CastExpr::path_const_iterator PathEnd, llvm::Value *Src,
700 CGBuilderTy &Builder);
701
702 llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
703 const CastExpr *E,
704 llvm::Value *Src) override;
705
706 llvm::Constant *EmitMemberPointerConversion(const CastExpr *E,
707 llvm::Constant *Src) override;
708
709 llvm::Constant *EmitMemberPointerConversion(
710 const MemberPointerType *SrcTy, const MemberPointerType *DstTy,
711 CastKind CK, CastExpr::path_const_iterator PathBegin,
712 CastExpr::path_const_iterator PathEnd, llvm::Constant *Src);
713
714 CGCallee
715 EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, const Expr *E,
716 Address This, llvm::Value *&ThisPtrForCall,
717 llvm::Value *MemPtr,
718 const MemberPointerType *MPT) override;
719
720 void emitCXXStructor(GlobalDecl GD) override;
721
722 llvm::StructType *getCatchableTypeType() {
723 if (CatchableTypeType)
724 return CatchableTypeType;
725 llvm::Type *FieldTypes[] = {
726 CGM.IntTy, // Flags
727 getImageRelativeType(PtrType: CGM.Int8PtrTy), // TypeDescriptor
728 CGM.IntTy, // NonVirtualAdjustment
729 CGM.IntTy, // OffsetToVBPtr
730 CGM.IntTy, // VBTableIndex
731 CGM.IntTy, // Size
732 getImageRelativeType(PtrType: CGM.Int8PtrTy) // CopyCtor
733 };
734 CatchableTypeType = llvm::StructType::create(
735 Context&: CGM.getLLVMContext(), Elements: FieldTypes, Name: "eh.CatchableType");
736 return CatchableTypeType;
737 }
738
739 llvm::StructType *getCatchableTypeArrayType(uint32_t NumEntries) {
740 llvm::StructType *&CatchableTypeArrayType =
741 CatchableTypeArrayTypeMap[NumEntries];
742 if (CatchableTypeArrayType)
743 return CatchableTypeArrayType;
744
745 llvm::SmallString<23> CTATypeName("eh.CatchableTypeArray.");
746 CTATypeName += llvm::utostr(X: NumEntries);
747 llvm::Type *CTType = getImageRelativeType(PtrType: CGM.UnqualPtrTy);
748 llvm::Type *FieldTypes[] = {
749 CGM.IntTy, // NumEntries
750 llvm::ArrayType::get(ElementType: CTType, NumElements: NumEntries) // CatchableTypes
751 };
752 CatchableTypeArrayType =
753 llvm::StructType::create(Context&: CGM.getLLVMContext(), Elements: FieldTypes, Name: CTATypeName);
754 return CatchableTypeArrayType;
755 }
756
757 llvm::StructType *getThrowInfoType() {
758 if (ThrowInfoType)
759 return ThrowInfoType;
760 llvm::Type *FieldTypes[] = {
761 CGM.IntTy, // Flags
762 getImageRelativeType(PtrType: CGM.Int8PtrTy), // CleanupFn
763 getImageRelativeType(PtrType: CGM.Int8PtrTy), // ForwardCompat
764 getImageRelativeType(PtrType: CGM.Int8PtrTy) // CatchableTypeArray
765 };
766 ThrowInfoType = llvm::StructType::create(Context&: CGM.getLLVMContext(), Elements: FieldTypes,
767 Name: "eh.ThrowInfo");
768 return ThrowInfoType;
769 }
770
771 llvm::FunctionCallee getThrowFn() {
772 // _CxxThrowException is passed an exception object and a ThrowInfo object
773 // which describes the exception.
774 llvm::Type *Args[] = {CGM.Int8PtrTy, CGM.UnqualPtrTy};
775 llvm::FunctionType *FTy =
776 llvm::FunctionType::get(Result: CGM.VoidTy, Params: Args, /*isVarArg=*/false);
777 llvm::FunctionCallee Throw =
778 CGM.CreateRuntimeFunction(Ty: FTy, Name: "_CxxThrowException");
779 // _CxxThrowException is stdcall on 32-bit x86 platforms.
780 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {
781 if (auto *Fn = dyn_cast<llvm::Function>(Val: Throw.getCallee()))
782 Fn->setCallingConv(llvm::CallingConv::X86_StdCall);
783 }
784 return Throw;
785 }
786
787 llvm::Function *getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD,
788 CXXCtorType CT);
789
790 llvm::Constant *getCatchableType(QualType T,
791 uint32_t NVOffset = 0,
792 int32_t VBPtrOffset = -1,
793 uint32_t VBIndex = 0);
794
795 llvm::GlobalVariable *getCatchableTypeArray(QualType T);
796
797 llvm::GlobalVariable *getThrowInfo(QualType T) override;
798
799 std::pair<llvm::Value *, const CXXRecordDecl *>
800 LoadVTablePtr(CodeGenFunction &CGF, Address This,
801 const CXXRecordDecl *RD) override;
802
803 bool
804 isPermittedToBeHomogeneousAggregate(const CXXRecordDecl *RD) const override;
805
806private:
807 typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
808 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
809 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalValue *> VFTablesMapTy;
810 /// All the vftables that have been referenced.
811 VFTablesMapTy VFTablesMap;
812 VTablesMapTy VTablesMap;
813
814 /// This set holds the record decls we've deferred vtable emission for.
815 llvm::SmallPtrSet<const CXXRecordDecl *, 4> DeferredVFTables;
816
817
818 /// All the vbtables which have been referenced.
819 llvm::DenseMap<const CXXRecordDecl *, VBTableGlobals> VBTablesMap;
820
821 /// Info on the global variable used to guard initialization of static locals.
822 /// The BitIndex field is only used for externally invisible declarations.
823 struct GuardInfo {
824 GuardInfo() = default;
825 llvm::GlobalVariable *Guard = nullptr;
826 unsigned BitIndex = 0;
827 };
828
829 /// Map from DeclContext to the current guard variable. We assume that the
830 /// AST is visited in source code order.
831 llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap;
832 llvm::DenseMap<const DeclContext *, GuardInfo> ThreadLocalGuardVariableMap;
833 llvm::DenseMap<const DeclContext *, unsigned> ThreadSafeGuardNumMap;
834
835 llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;
836 llvm::StructType *BaseClassDescriptorType;
837 llvm::StructType *ClassHierarchyDescriptorType;
838 llvm::StructType *CompleteObjectLocatorType;
839
840 llvm::DenseMap<QualType, llvm::GlobalVariable *> CatchableTypeArrays;
841
842 llvm::StructType *CatchableTypeType;
843 llvm::DenseMap<uint32_t, llvm::StructType *> CatchableTypeArrayTypeMap;
844 llvm::StructType *ThrowInfoType;
845};
846
847}
848
849CGCXXABI::RecordArgABI
850MicrosoftCXXABI::getRecordArgABI(const CXXRecordDecl *RD) const {
851 // Use the default C calling convention rules for things that can be passed in
852 // registers, i.e. non-trivially copyable records or records marked with
853 // [[trivial_abi]].
854 if (RD->canPassInRegisters())
855 return RAA_Default;
856
857 switch (CGM.getTarget().getTriple().getArch()) {
858 default:
859 // FIXME: Implement for other architectures.
860 return RAA_Indirect;
861
862 case llvm::Triple::thumb:
863 // Pass things indirectly for now because it is simple.
864 // FIXME: This is incompatible with MSVC for arguments with a dtor and no
865 // copy ctor.
866 return RAA_Indirect;
867
868 case llvm::Triple::x86: {
869 // If the argument has *required* alignment greater than four bytes, pass
870 // it indirectly. Prior to MSVC version 19.14, passing overaligned
871 // arguments was not supported and resulted in a compiler error. In 19.14
872 // and later versions, such arguments are now passed indirectly.
873 TypeInfo Info = getContext().getTypeInfo(T: RD->getTypeForDecl());
874 if (Info.isAlignRequired() && Info.Align > 4)
875 return RAA_Indirect;
876
877 // If C++ prohibits us from making a copy, construct the arguments directly
878 // into argument memory.
879 return RAA_DirectInMemory;
880 }
881
882 case llvm::Triple::x86_64:
883 case llvm::Triple::aarch64:
884 return RAA_Indirect;
885 }
886
887 llvm_unreachable("invalid enum");
888}
889
890void MicrosoftCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF,
891 const CXXDeleteExpr *DE,
892 Address Ptr,
893 QualType ElementType,
894 const CXXDestructorDecl *Dtor) {
895 // FIXME: Provide a source location here even though there's no
896 // CXXMemberCallExpr for dtor call.
897 bool UseGlobalDelete = DE->isGlobalDelete();
898 CXXDtorType DtorType = UseGlobalDelete ? Dtor_Complete : Dtor_Deleting;
899 llvm::Value *MDThis = EmitVirtualDestructorCall(CGF, Dtor, DtorType, This: Ptr, E: DE,
900 /*CallOrInvoke=*/nullptr);
901 if (UseGlobalDelete)
902 CGF.EmitDeleteCall(DeleteFD: DE->getOperatorDelete(), Ptr: MDThis, DeleteTy: ElementType);
903}
904
905void MicrosoftCXXABI::emitRethrow(CodeGenFunction &CGF, bool isNoReturn) {
906 llvm::Value *Args[] = {llvm::ConstantPointerNull::get(T: CGM.Int8PtrTy),
907 llvm::ConstantPointerNull::get(T: CGM.UnqualPtrTy)};
908 llvm::FunctionCallee Fn = getThrowFn();
909 if (isNoReturn)
910 CGF.EmitNoreturnRuntimeCallOrInvoke(callee: Fn, args: Args);
911 else
912 CGF.EmitRuntimeCallOrInvoke(callee: Fn, args: Args);
913}
914
915void MicrosoftCXXABI::emitBeginCatch(CodeGenFunction &CGF,
916 const CXXCatchStmt *S) {
917 // In the MS ABI, the runtime handles the copy, and the catch handler is
918 // responsible for destruction.
919 VarDecl *CatchParam = S->getExceptionDecl();
920 llvm::BasicBlock *CatchPadBB = CGF.Builder.GetInsertBlock();
921 llvm::CatchPadInst *CPI =
922 cast<llvm::CatchPadInst>(Val: CatchPadBB->getFirstNonPHIIt());
923 CGF.CurrentFuncletPad = CPI;
924
925 // If this is a catch-all or the catch parameter is unnamed, we don't need to
926 // emit an alloca to the object.
927 if (!CatchParam || !CatchParam->getDeclName()) {
928 CGF.EHStack.pushCleanup<CatchRetScope>(Kind: NormalCleanup, A: CPI);
929 return;
930 }
931
932 CodeGenFunction::AutoVarEmission var = CGF.EmitAutoVarAlloca(var: *CatchParam);
933 CPI->setArgOperand(i: 2, v: var.getObjectAddress(CGF).emitRawPointer(CGF));
934 CGF.EHStack.pushCleanup<CatchRetScope>(Kind: NormalCleanup, A: CPI);
935 CGF.EmitAutoVarCleanups(emission: var);
936}
937
938/// We need to perform a generic polymorphic operation (like a typeid
939/// or a cast), which requires an object with a vfptr. Adjust the
940/// address to point to an object with a vfptr.
941std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
942MicrosoftCXXABI::performBaseAdjustment(CodeGenFunction &CGF, Address Value,
943 QualType SrcRecordTy) {
944 Value = Value.withElementType(ElemTy: CGF.Int8Ty);
945 const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();
946 const ASTContext &Context = getContext();
947
948 // If the class itself has a vfptr, great. This check implicitly
949 // covers non-virtual base subobjects: a class with its own virtual
950 // functions would be a candidate to be a primary base.
951 if (Context.getASTRecordLayout(D: SrcDecl).hasExtendableVFPtr())
952 return std::make_tuple(args&: Value, args: llvm::ConstantInt::get(Ty: CGF.Int32Ty, V: 0),
953 args&: SrcDecl);
954
955 // Okay, one of the vbases must have a vfptr, or else this isn't
956 // actually a polymorphic class.
957 const CXXRecordDecl *PolymorphicBase = nullptr;
958 for (auto &Base : SrcDecl->vbases()) {
959 const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
960 if (Context.getASTRecordLayout(D: BaseDecl).hasExtendableVFPtr()) {
961 PolymorphicBase = BaseDecl;
962 break;
963 }
964 }
965 assert(PolymorphicBase && "polymorphic class has no apparent vfptr?");
966
967 llvm::Value *Offset =
968 GetVirtualBaseClassOffset(CGF, This: Value, ClassDecl: SrcDecl, BaseClassDecl: PolymorphicBase);
969 llvm::Value *Ptr = CGF.Builder.CreateInBoundsGEP(
970 Ty: Value.getElementType(), Ptr: Value.emitRawPointer(CGF), IdxList: Offset);
971 CharUnits VBaseAlign =
972 CGF.CGM.getVBaseAlignment(DerivedAlign: Value.getAlignment(), Derived: SrcDecl, VBase: PolymorphicBase);
973 return std::make_tuple(args: Address(Ptr, CGF.Int8Ty, VBaseAlign), args&: Offset,
974 args&: PolymorphicBase);
975}
976
977bool MicrosoftCXXABI::shouldTypeidBeNullChecked(QualType SrcRecordTy) {
978 const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();
979 return !getContext().getASTRecordLayout(D: SrcDecl).hasExtendableVFPtr();
980}
981
982static llvm::CallBase *emitRTtypeidCall(CodeGenFunction &CGF,
983 llvm::Value *Argument) {
984 llvm::Type *ArgTypes[] = {CGF.Int8PtrTy};
985 llvm::FunctionType *FTy =
986 llvm::FunctionType::get(Result: CGF.Int8PtrTy, Params: ArgTypes, isVarArg: false);
987 llvm::Value *Args[] = {Argument};
988 llvm::FunctionCallee Fn = CGF.CGM.CreateRuntimeFunction(Ty: FTy, Name: "__RTtypeid");
989 return CGF.EmitRuntimeCallOrInvoke(callee: Fn, args: Args);
990}
991
992void MicrosoftCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) {
993 llvm::CallBase *Call =
994 emitRTtypeidCall(CGF, Argument: llvm::Constant::getNullValue(Ty: CGM.VoidPtrTy));
995 Call->setDoesNotReturn();
996 CGF.Builder.CreateUnreachable();
997}
998
999llvm::Value *MicrosoftCXXABI::EmitTypeid(CodeGenFunction &CGF,
1000 QualType SrcRecordTy,
1001 Address ThisPtr,
1002 llvm::Type *StdTypeInfoPtrTy) {
1003 std::tie(args&: ThisPtr, args: std::ignore, args: std::ignore) =
1004 performBaseAdjustment(CGF, Value: ThisPtr, SrcRecordTy);
1005 llvm::CallBase *Typeid = emitRTtypeidCall(CGF, Argument: ThisPtr.emitRawPointer(CGF));
1006 return CGF.Builder.CreateBitCast(V: Typeid, DestTy: StdTypeInfoPtrTy);
1007}
1008
1009bool MicrosoftCXXABI::shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
1010 QualType SrcRecordTy) {
1011 const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();
1012 return SrcIsPtr &&
1013 !getContext().getASTRecordLayout(D: SrcDecl).hasExtendableVFPtr();
1014}
1015
1016llvm::Value *MicrosoftCXXABI::emitDynamicCastCall(
1017 CodeGenFunction &CGF, Address This, QualType SrcRecordTy, QualType DestTy,
1018 QualType DestRecordTy, llvm::BasicBlock *CastEnd) {
1019 llvm::Value *SrcRTTI =
1020 CGF.CGM.GetAddrOfRTTIDescriptor(Ty: SrcRecordTy.getUnqualifiedType());
1021 llvm::Value *DestRTTI =
1022 CGF.CGM.GetAddrOfRTTIDescriptor(Ty: DestRecordTy.getUnqualifiedType());
1023
1024 llvm::Value *Offset;
1025 std::tie(args&: This, args&: Offset, args: std::ignore) =
1026 performBaseAdjustment(CGF, Value: This, SrcRecordTy);
1027 llvm::Value *ThisPtr = This.emitRawPointer(CGF);
1028 Offset = CGF.Builder.CreateTrunc(V: Offset, DestTy: CGF.Int32Ty);
1029
1030 // PVOID __RTDynamicCast(
1031 // PVOID inptr,
1032 // LONG VfDelta,
1033 // PVOID SrcType,
1034 // PVOID TargetType,
1035 // BOOL isReference)
1036 llvm::Type *ArgTypes[] = {CGF.Int8PtrTy, CGF.Int32Ty, CGF.Int8PtrTy,
1037 CGF.Int8PtrTy, CGF.Int32Ty};
1038 llvm::FunctionCallee Function = CGF.CGM.CreateRuntimeFunction(
1039 Ty: llvm::FunctionType::get(Result: CGF.Int8PtrTy, Params: ArgTypes, isVarArg: false),
1040 Name: "__RTDynamicCast");
1041 llvm::Value *Args[] = {
1042 ThisPtr, Offset, SrcRTTI, DestRTTI,
1043 llvm::ConstantInt::get(Ty: CGF.Int32Ty, V: DestTy->isReferenceType())};
1044 return CGF.EmitRuntimeCallOrInvoke(callee: Function, args: Args);
1045}
1046
1047llvm::Value *MicrosoftCXXABI::emitDynamicCastToVoid(CodeGenFunction &CGF,
1048 Address Value,
1049 QualType SrcRecordTy) {
1050 std::tie(args&: Value, args: std::ignore, args: std::ignore) =
1051 performBaseAdjustment(CGF, Value, SrcRecordTy);
1052
1053 // PVOID __RTCastToVoid(
1054 // PVOID inptr)
1055 llvm::Type *ArgTypes[] = {CGF.Int8PtrTy};
1056 llvm::FunctionCallee Function = CGF.CGM.CreateRuntimeFunction(
1057 Ty: llvm::FunctionType::get(Result: CGF.Int8PtrTy, Params: ArgTypes, isVarArg: false),
1058 Name: "__RTCastToVoid");
1059 llvm::Value *Args[] = {Value.emitRawPointer(CGF)};
1060 return CGF.EmitRuntimeCall(callee: Function, args: Args);
1061}
1062
1063bool MicrosoftCXXABI::EmitBadCastCall(CodeGenFunction &CGF) {
1064 return false;
1065}
1066
1067llvm::Value *MicrosoftCXXABI::GetVirtualBaseClassOffset(
1068 CodeGenFunction &CGF, Address This, const CXXRecordDecl *ClassDecl,
1069 const CXXRecordDecl *BaseClassDecl) {
1070 const ASTContext &Context = getContext();
1071 int64_t VBPtrChars =
1072 Context.getASTRecordLayout(D: ClassDecl).getVBPtrOffset().getQuantity();
1073 llvm::Value *VBPtrOffset = llvm::ConstantInt::get(Ty: CGM.PtrDiffTy, V: VBPtrChars);
1074 CharUnits IntSize = Context.getTypeSizeInChars(T: Context.IntTy);
1075 CharUnits VBTableChars =
1076 IntSize *
1077 CGM.getMicrosoftVTableContext().getVBTableIndex(Derived: ClassDecl, VBase: BaseClassDecl);
1078 llvm::Value *VBTableOffset =
1079 llvm::ConstantInt::get(Ty: CGM.IntTy, V: VBTableChars.getQuantity());
1080
1081 llvm::Value *VBPtrToNewBase =
1082 GetVBaseOffsetFromVBPtr(CGF, Base: This, VBPtrOffset, VBTableOffset);
1083 VBPtrToNewBase =
1084 CGF.Builder.CreateSExtOrBitCast(V: VBPtrToNewBase, DestTy: CGM.PtrDiffTy);
1085 return CGF.Builder.CreateNSWAdd(LHS: VBPtrOffset, RHS: VBPtrToNewBase);
1086}
1087
1088bool MicrosoftCXXABI::HasThisReturn(GlobalDecl GD) const {
1089 return isa<CXXConstructorDecl>(Val: GD.getDecl());
1090}
1091
1092static bool isDeletingDtor(GlobalDecl GD) {
1093 return isa<CXXDestructorDecl>(Val: GD.getDecl()) &&
1094 GD.getDtorType() == Dtor_Deleting;
1095}
1096
1097bool MicrosoftCXXABI::hasMostDerivedReturn(GlobalDecl GD) const {
1098 return isDeletingDtor(GD);
1099}
1100
1101static bool isTrivialForMSVC(const CXXRecordDecl *RD, QualType Ty,
1102 CodeGenModule &CGM) {
1103 // On AArch64, HVAs that can be passed in registers can also be returned
1104 // in registers. (Note this is using the MSVC definition of an HVA; see
1105 // isPermittedToBeHomogeneousAggregate().)
1106 const Type *Base = nullptr;
1107 uint64_t NumElts = 0;
1108 if (CGM.getTarget().getTriple().isAArch64() &&
1109 CGM.getABIInfo().isHomogeneousAggregate(Ty, Base, Members&: NumElts) &&
1110 isa<VectorType>(Val: Base)) {
1111 return true;
1112 }
1113
1114 // We use the C++14 definition of an aggregate, so we also
1115 // check for:
1116 // No private or protected non static data members.
1117 // No base classes
1118 // No virtual functions
1119 // Additionally, we need to ensure that there is a trivial copy assignment
1120 // operator, a trivial destructor, no user-provided constructors and no
1121 // deleted copy assignment operator.
1122
1123 // We need to cover two cases when checking for a deleted copy assignment
1124 // operator.
1125 //
1126 // struct S { int& r; };
1127 // The above will have an implicit copy assignment operator that is deleted
1128 // and there will not be a `CXXMethodDecl` for the copy assignment operator.
1129 // This is handled by the `needsImplicitCopyAssignment()` check below.
1130 //
1131 // struct S { S& operator=(const S&) = delete; int i; };
1132 // The above will not have an implicit copy assignment operator that is
1133 // deleted but there is a deleted `CXXMethodDecl` for the declared copy
1134 // assignment operator. This is handled by the `isDeleted()` check below.
1135
1136 if (RD->hasProtectedFields() || RD->hasPrivateFields())
1137 return false;
1138 if (RD->getNumBases() > 0)
1139 return false;
1140 if (RD->isPolymorphic())
1141 return false;
1142 if (RD->hasNonTrivialCopyAssignment())
1143 return false;
1144 if (RD->needsImplicitCopyAssignment() && !RD->hasSimpleCopyAssignment())
1145 return false;
1146 for (const Decl *D : RD->decls()) {
1147 if (auto *Ctor = dyn_cast<CXXConstructorDecl>(Val: D)) {
1148 if (Ctor->isUserProvided())
1149 return false;
1150 } else if (auto *Template = dyn_cast<FunctionTemplateDecl>(Val: D)) {
1151 if (isa<CXXConstructorDecl>(Val: Template->getTemplatedDecl()))
1152 return false;
1153 } else if (auto *MethodDecl = dyn_cast<CXXMethodDecl>(Val: D)) {
1154 if (MethodDecl->isCopyAssignmentOperator() && MethodDecl->isDeleted())
1155 return false;
1156 }
1157 }
1158 if (RD->hasNonTrivialDestructor())
1159 return false;
1160 return true;
1161}
1162
1163bool MicrosoftCXXABI::classifyReturnType(CGFunctionInfo &FI) const {
1164 const CXXRecordDecl *RD = FI.getReturnType()->getAsCXXRecordDecl();
1165 if (!RD)
1166 return false;
1167
1168 bool isTrivialForABI = RD->canPassInRegisters() &&
1169 isTrivialForMSVC(RD, Ty: FI.getReturnType(), CGM);
1170
1171 // MSVC always returns structs indirectly from C++ instance methods.
1172 bool isIndirectReturn = !isTrivialForABI || FI.isInstanceMethod();
1173
1174 if (isIndirectReturn) {
1175 CharUnits Align = CGM.getContext().getTypeAlignInChars(T: FI.getReturnType());
1176 FI.getReturnInfo() = ABIArgInfo::getIndirect(
1177 Alignment: Align, /*AddrSpace=*/CGM.getDataLayout().getAllocaAddrSpace(),
1178 /*ByVal=*/false);
1179
1180 // MSVC always passes `this` before the `sret` parameter.
1181 FI.getReturnInfo().setSRetAfterThis(FI.isInstanceMethod());
1182
1183 // On AArch64, use the `inreg` attribute if the object is considered to not
1184 // be trivially copyable, or if this is an instance method struct return.
1185 FI.getReturnInfo().setInReg(CGM.getTarget().getTriple().isAArch64());
1186
1187 return true;
1188 }
1189
1190 // Otherwise, use the C ABI rules.
1191 return false;
1192}
1193
1194llvm::BasicBlock *
1195MicrosoftCXXABI::EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
1196 const CXXRecordDecl *RD) {
1197 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1198 assert(IsMostDerivedClass &&
1199 "ctor for a class with virtual bases must have an implicit parameter");
1200 llvm::Value *IsCompleteObject =
1201 CGF.Builder.CreateIsNotNull(Arg: IsMostDerivedClass, Name: "is_complete_object");
1202
1203 llvm::BasicBlock *CallVbaseCtorsBB = CGF.createBasicBlock(name: "ctor.init_vbases");
1204 llvm::BasicBlock *SkipVbaseCtorsBB = CGF.createBasicBlock(name: "ctor.skip_vbases");
1205 CGF.Builder.CreateCondBr(Cond: IsCompleteObject,
1206 True: CallVbaseCtorsBB, False: SkipVbaseCtorsBB);
1207
1208 CGF.EmitBlock(BB: CallVbaseCtorsBB);
1209
1210 // Fill in the vbtable pointers here.
1211 EmitVBPtrStores(CGF, RD);
1212
1213 // CGF will put the base ctor calls in this basic block for us later.
1214
1215 return SkipVbaseCtorsBB;
1216}
1217
1218llvm::BasicBlock *
1219MicrosoftCXXABI::EmitDtorCompleteObjectHandler(CodeGenFunction &CGF) {
1220 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1221 assert(IsMostDerivedClass &&
1222 "ctor for a class with virtual bases must have an implicit parameter");
1223 llvm::Value *IsCompleteObject =
1224 CGF.Builder.CreateIsNotNull(Arg: IsMostDerivedClass, Name: "is_complete_object");
1225
1226 llvm::BasicBlock *CallVbaseDtorsBB = CGF.createBasicBlock(name: "Dtor.dtor_vbases");
1227 llvm::BasicBlock *SkipVbaseDtorsBB = CGF.createBasicBlock(name: "Dtor.skip_vbases");
1228 CGF.Builder.CreateCondBr(Cond: IsCompleteObject,
1229 True: CallVbaseDtorsBB, False: SkipVbaseDtorsBB);
1230
1231 CGF.EmitBlock(BB: CallVbaseDtorsBB);
1232 // CGF will put the base dtor calls in this basic block for us later.
1233
1234 return SkipVbaseDtorsBB;
1235}
1236
1237void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(
1238 CodeGenFunction &CGF, const CXXRecordDecl *RD) {
1239 // In most cases, an override for a vbase virtual method can adjust
1240 // the "this" parameter by applying a constant offset.
1241 // However, this is not enough while a constructor or a destructor of some
1242 // class X is being executed if all the following conditions are met:
1243 // - X has virtual bases, (1)
1244 // - X overrides a virtual method M of a vbase Y, (2)
1245 // - X itself is a vbase of the most derived class.
1246 //
1247 // If (1) and (2) are true, the vtorDisp for vbase Y is a hidden member of X
1248 // which holds the extra amount of "this" adjustment we must do when we use
1249 // the X vftables (i.e. during X ctor or dtor).
1250 // Outside the ctors and dtors, the values of vtorDisps are zero.
1251
1252 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(D: RD);
1253 typedef ASTRecordLayout::VBaseOffsetsMapTy VBOffsets;
1254 const VBOffsets &VBaseMap = Layout.getVBaseOffsetsMap();
1255 CGBuilderTy &Builder = CGF.Builder;
1256
1257 llvm::Value *Int8This = nullptr; // Initialize lazily.
1258
1259 for (const CXXBaseSpecifier &S : RD->vbases()) {
1260 const CXXRecordDecl *VBase = S.getType()->getAsCXXRecordDecl();
1261 auto I = VBaseMap.find(Val: VBase);
1262 assert(I != VBaseMap.end());
1263 if (!I->second.hasVtorDisp())
1264 continue;
1265
1266 llvm::Value *VBaseOffset =
1267 GetVirtualBaseClassOffset(CGF, This: getThisAddress(CGF), ClassDecl: RD, BaseClassDecl: VBase);
1268 uint64_t ConstantVBaseOffset = I->second.VBaseOffset.getQuantity();
1269
1270 // vtorDisp_for_vbase = vbptr[vbase_idx] - offsetof(RD, vbase).
1271 llvm::Value *VtorDispValue = Builder.CreateSub(
1272 LHS: VBaseOffset, RHS: llvm::ConstantInt::get(Ty: CGM.PtrDiffTy, V: ConstantVBaseOffset),
1273 Name: "vtordisp.value");
1274 VtorDispValue = Builder.CreateTruncOrBitCast(V: VtorDispValue, DestTy: CGF.Int32Ty);
1275
1276 if (!Int8This)
1277 Int8This = getThisValue(CGF);
1278
1279 llvm::Value *VtorDispPtr =
1280 Builder.CreateInBoundsGEP(Ty: CGF.Int8Ty, Ptr: Int8This, IdxList: VBaseOffset);
1281 // vtorDisp is always the 32-bits before the vbase in the class layout.
1282 VtorDispPtr = Builder.CreateConstGEP1_32(Ty: CGF.Int8Ty, Ptr: VtorDispPtr, Idx0: -4);
1283
1284 Builder.CreateAlignedStore(Val: VtorDispValue, Addr: VtorDispPtr,
1285 Align: CharUnits::fromQuantity(Quantity: 4));
1286 }
1287}
1288
1289static bool hasDefaultCXXMethodCC(ASTContext &Context,
1290 const CXXMethodDecl *MD) {
1291 CallingConv ExpectedCallingConv = Context.getDefaultCallingConvention(
1292 /*IsVariadic=*/false, /*IsCXXMethod=*/true);
1293 CallingConv ActualCallingConv =
1294 MD->getType()->castAs<FunctionProtoType>()->getCallConv();
1295 return ExpectedCallingConv == ActualCallingConv;
1296}
1297
1298void MicrosoftCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) {
1299 // There's only one constructor type in this ABI.
1300 CGM.EmitGlobal(D: GlobalDecl(D, Ctor_Complete));
1301
1302 // Exported default constructors either have a simple call-site where they use
1303 // the typical calling convention and have a single 'this' pointer for an
1304 // argument -or- they get a wrapper function which appropriately thunks to the
1305 // real default constructor. This thunk is the default constructor closure.
1306 if (D->hasAttr<DLLExportAttr>() && D->isDefaultConstructor() &&
1307 D->isDefined()) {
1308 if (!hasDefaultCXXMethodCC(Context&: getContext(), MD: D) || D->getNumParams() != 0) {
1309 llvm::Function *Fn = getAddrOfCXXCtorClosure(CD: D, CT: Ctor_DefaultClosure);
1310 Fn->setLinkage(llvm::GlobalValue::WeakODRLinkage);
1311 CGM.setGVProperties(GV: Fn, D);
1312 }
1313 }
1314}
1315
1316void MicrosoftCXXABI::EmitVBPtrStores(CodeGenFunction &CGF,
1317 const CXXRecordDecl *RD) {
1318 Address This = getThisAddress(CGF);
1319 This = This.withElementType(ElemTy: CGM.Int8Ty);
1320 const ASTContext &Context = getContext();
1321 const ASTRecordLayout &Layout = Context.getASTRecordLayout(D: RD);
1322
1323 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
1324 for (unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
1325 const std::unique_ptr<VPtrInfo> &VBT = (*VBGlobals.VBTables)[I];
1326 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
1327 const ASTRecordLayout &SubobjectLayout =
1328 Context.getASTRecordLayout(D: VBT->IntroducingObject);
1329 CharUnits Offs = VBT->NonVirtualOffset;
1330 Offs += SubobjectLayout.getVBPtrOffset();
1331 if (VBT->getVBaseWithVPtr())
1332 Offs += Layout.getVBaseClassOffset(VBase: VBT->getVBaseWithVPtr());
1333 Address VBPtr = CGF.Builder.CreateConstInBoundsByteGEP(Addr: This, Offset: Offs);
1334 llvm::Value *GVPtr =
1335 CGF.Builder.CreateConstInBoundsGEP2_32(Ty: GV->getValueType(), Ptr: GV, Idx0: 0, Idx1: 0);
1336 VBPtr = VBPtr.withElementType(ElemTy: GVPtr->getType());
1337 CGF.Builder.CreateStore(Val: GVPtr, Addr: VBPtr);
1338 }
1339}
1340
1341CGCXXABI::AddedStructorArgCounts
1342MicrosoftCXXABI::buildStructorSignature(GlobalDecl GD,
1343 SmallVectorImpl<CanQualType> &ArgTys) {
1344 AddedStructorArgCounts Added;
1345 // TODO: 'for base' flag
1346 if (isa<CXXDestructorDecl>(Val: GD.getDecl()) &&
1347 GD.getDtorType() == Dtor_Deleting) {
1348 // The scalar deleting destructor takes an implicit int parameter.
1349 ArgTys.push_back(Elt: getContext().IntTy);
1350 ++Added.Suffix;
1351 }
1352 auto *CD = dyn_cast<CXXConstructorDecl>(Val: GD.getDecl());
1353 if (!CD)
1354 return Added;
1355
1356 // All parameters are already in place except is_most_derived, which goes
1357 // after 'this' if it's variadic and last if it's not.
1358
1359 const CXXRecordDecl *Class = CD->getParent();
1360 const FunctionProtoType *FPT = CD->getType()->castAs<FunctionProtoType>();
1361 if (Class->getNumVBases()) {
1362 if (FPT->isVariadic()) {
1363 ArgTys.insert(I: ArgTys.begin() + 1, Elt: getContext().IntTy);
1364 ++Added.Prefix;
1365 } else {
1366 ArgTys.push_back(Elt: getContext().IntTy);
1367 ++Added.Suffix;
1368 }
1369 }
1370
1371 return Added;
1372}
1373
1374void MicrosoftCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
1375 const CXXDestructorDecl *Dtor,
1376 CXXDtorType DT) const {
1377 // Deleting destructor variants are never imported or exported. Give them the
1378 // default storage class.
1379 if (DT == Dtor_Deleting) {
1380 GV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
1381 } else {
1382 const NamedDecl *ND = Dtor;
1383 CGM.setDLLImportDLLExport(GV, D: ND);
1384 }
1385}
1386
1387llvm::GlobalValue::LinkageTypes MicrosoftCXXABI::getCXXDestructorLinkage(
1388 GVALinkage Linkage, const CXXDestructorDecl *Dtor, CXXDtorType DT) const {
1389 // Internal things are always internal, regardless of attributes. After this,
1390 // we know the thunk is externally visible.
1391 if (Linkage == GVA_Internal)
1392 return llvm::GlobalValue::InternalLinkage;
1393
1394 switch (DT) {
1395 case Dtor_Base:
1396 // The base destructor most closely tracks the user-declared constructor, so
1397 // we delegate back to the normal declarator case.
1398 return CGM.getLLVMLinkageForDeclarator(D: Dtor, Linkage);
1399 case Dtor_Complete:
1400 // The complete destructor is like an inline function, but it may be
1401 // imported and therefore must be exported as well. This requires changing
1402 // the linkage if a DLL attribute is present.
1403 if (Dtor->hasAttr<DLLExportAttr>())
1404 return llvm::GlobalValue::WeakODRLinkage;
1405 if (Dtor->hasAttr<DLLImportAttr>())
1406 return llvm::GlobalValue::AvailableExternallyLinkage;
1407 return llvm::GlobalValue::LinkOnceODRLinkage;
1408 case Dtor_Deleting:
1409 // Deleting destructors are like inline functions. They have vague linkage
1410 // and are emitted everywhere they are used. They are internal if the class
1411 // is internal.
1412 return llvm::GlobalValue::LinkOnceODRLinkage;
1413 case Dtor_Comdat:
1414 llvm_unreachable("MS C++ ABI does not support comdat dtors");
1415 }
1416 llvm_unreachable("invalid dtor type");
1417}
1418
1419void MicrosoftCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) {
1420 // The TU defining a dtor is only guaranteed to emit a base destructor. All
1421 // other destructor variants are delegating thunks.
1422 CGM.EmitGlobal(D: GlobalDecl(D, Dtor_Base));
1423
1424 // If the class is dllexported, emit the complete (vbase) destructor wherever
1425 // the base dtor is emitted.
1426 // FIXME: To match MSVC, this should only be done when the class is exported
1427 // with -fdllexport-inlines enabled.
1428 if (D->getParent()->getNumVBases() > 0 && D->hasAttr<DLLExportAttr>())
1429 CGM.EmitGlobal(D: GlobalDecl(D, Dtor_Complete));
1430}
1431
1432CharUnits
1433MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD) {
1434 const CXXMethodDecl *MD = cast<CXXMethodDecl>(Val: GD.getDecl());
1435
1436 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(Val: MD)) {
1437 // Complete destructors take a pointer to the complete object as a
1438 // parameter, thus don't need this adjustment.
1439 if (GD.getDtorType() == Dtor_Complete)
1440 return CharUnits();
1441
1442 // There's no Dtor_Base in vftable but it shares the this adjustment with
1443 // the deleting one, so look it up instead.
1444 GD = GlobalDecl(DD, Dtor_Deleting);
1445 }
1446
1447 MethodVFTableLocation ML =
1448 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
1449 CharUnits Adjustment = ML.VFPtrOffset;
1450
1451 // Normal virtual instance methods need to adjust from the vfptr that first
1452 // defined the virtual method to the virtual base subobject, but destructors
1453 // do not. The vector deleting destructor thunk applies this adjustment for
1454 // us if necessary.
1455 if (isa<CXXDestructorDecl>(Val: MD))
1456 Adjustment = CharUnits::Zero();
1457
1458 if (ML.VBase) {
1459 const ASTRecordLayout &DerivedLayout =
1460 getContext().getASTRecordLayout(D: MD->getParent());
1461 Adjustment += DerivedLayout.getVBaseClassOffset(VBase: ML.VBase);
1462 }
1463
1464 return Adjustment;
1465}
1466
1467Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(
1468 CodeGenFunction &CGF, GlobalDecl GD, Address This,
1469 bool VirtualCall) {
1470 if (!VirtualCall) {
1471 // If the call of a virtual function is not virtual, we just have to
1472 // compensate for the adjustment the virtual function does in its prologue.
1473 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
1474 if (Adjustment.isZero())
1475 return This;
1476
1477 This = This.withElementType(ElemTy: CGF.Int8Ty);
1478 assert(Adjustment.isPositive());
1479 return CGF.Builder.CreateConstByteGEP(Addr: This, Offset: Adjustment);
1480 }
1481
1482 const CXXMethodDecl *MD = cast<CXXMethodDecl>(Val: GD.getDecl());
1483
1484 GlobalDecl LookupGD = GD;
1485 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(Val: MD)) {
1486 // Complete dtors take a pointer to the complete object,
1487 // thus don't need adjustment.
1488 if (GD.getDtorType() == Dtor_Complete)
1489 return This;
1490
1491 // There's only Dtor_Deleting in vftable but it shares the this adjustment
1492 // with the base one, so look up the deleting one instead.
1493 LookupGD = GlobalDecl(DD, Dtor_Deleting);
1494 }
1495 MethodVFTableLocation ML =
1496 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD: LookupGD);
1497
1498 CharUnits StaticOffset = ML.VFPtrOffset;
1499
1500 // Base destructors expect 'this' to point to the beginning of the base
1501 // subobject, not the first vfptr that happens to contain the virtual dtor.
1502 // However, we still need to apply the virtual base adjustment.
1503 if (isa<CXXDestructorDecl>(Val: MD) && GD.getDtorType() == Dtor_Base)
1504 StaticOffset = CharUnits::Zero();
1505
1506 Address Result = This;
1507 if (ML.VBase) {
1508 Result = Result.withElementType(ElemTy: CGF.Int8Ty);
1509
1510 const CXXRecordDecl *Derived = MD->getParent();
1511 const CXXRecordDecl *VBase = ML.VBase;
1512 llvm::Value *VBaseOffset =
1513 GetVirtualBaseClassOffset(CGF, This: Result, ClassDecl: Derived, BaseClassDecl: VBase);
1514 llvm::Value *VBasePtr = CGF.Builder.CreateInBoundsGEP(
1515 Ty: Result.getElementType(), Ptr: Result.emitRawPointer(CGF), IdxList: VBaseOffset);
1516 CharUnits VBaseAlign =
1517 CGF.CGM.getVBaseAlignment(DerivedAlign: Result.getAlignment(), Derived, VBase);
1518 Result = Address(VBasePtr, CGF.Int8Ty, VBaseAlign);
1519 }
1520 if (!StaticOffset.isZero()) {
1521 assert(StaticOffset.isPositive());
1522 Result = Result.withElementType(ElemTy: CGF.Int8Ty);
1523 if (ML.VBase) {
1524 // Non-virtual adjustment might result in a pointer outside the allocated
1525 // object, e.g. if the final overrider class is laid out after the virtual
1526 // base that declares a method in the most derived class.
1527 // FIXME: Update the code that emits this adjustment in thunks prologues.
1528 Result = CGF.Builder.CreateConstByteGEP(Addr: Result, Offset: StaticOffset);
1529 } else {
1530 Result = CGF.Builder.CreateConstInBoundsByteGEP(Addr: Result, Offset: StaticOffset);
1531 }
1532 }
1533 return Result;
1534}
1535
1536void MicrosoftCXXABI::addImplicitStructorParams(CodeGenFunction &CGF,
1537 QualType &ResTy,
1538 FunctionArgList &Params) {
1539 ASTContext &Context = getContext();
1540 const CXXMethodDecl *MD = cast<CXXMethodDecl>(Val: CGF.CurGD.getDecl());
1541 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1542 if (isa<CXXConstructorDecl>(Val: MD) && MD->getParent()->getNumVBases()) {
1543 auto *IsMostDerived = ImplicitParamDecl::Create(
1544 C&: Context, /*DC=*/nullptr, IdLoc: CGF.CurGD.getDecl()->getLocation(),
1545 Id: &Context.Idents.get(Name: "is_most_derived"), T: Context.IntTy,
1546 ParamKind: ImplicitParamKind::Other);
1547 // The 'most_derived' parameter goes second if the ctor is variadic and last
1548 // if it's not. Dtors can't be variadic.
1549 const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
1550 if (FPT->isVariadic())
1551 Params.insert(I: Params.begin() + 1, Elt: IsMostDerived);
1552 else
1553 Params.push_back(Elt: IsMostDerived);
1554 getStructorImplicitParamDecl(CGF) = IsMostDerived;
1555 } else if (isDeletingDtor(GD: CGF.CurGD)) {
1556 auto *ShouldDelete = ImplicitParamDecl::Create(
1557 C&: Context, /*DC=*/nullptr, IdLoc: CGF.CurGD.getDecl()->getLocation(),
1558 Id: &Context.Idents.get(Name: "should_call_delete"), T: Context.IntTy,
1559 ParamKind: ImplicitParamKind::Other);
1560 Params.push_back(Elt: ShouldDelete);
1561 getStructorImplicitParamDecl(CGF) = ShouldDelete;
1562 }
1563}
1564
1565void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
1566 // Naked functions have no prolog.
1567 if (CGF.CurFuncDecl && CGF.CurFuncDecl->hasAttr<NakedAttr>())
1568 return;
1569
1570 // Overridden virtual methods of non-primary bases need to adjust the incoming
1571 // 'this' pointer in the prologue. In this hierarchy, C::b will subtract
1572 // sizeof(void*) to adjust from B* to C*:
1573 // struct A { virtual void a(); };
1574 // struct B { virtual void b(); };
1575 // struct C : A, B { virtual void b(); };
1576 //
1577 // Leave the value stored in the 'this' alloca unadjusted, so that the
1578 // debugger sees the unadjusted value. Microsoft debuggers require this, and
1579 // will apply the ThisAdjustment in the method type information.
1580 // FIXME: Do something better for DWARF debuggers, which won't expect this,
1581 // without making our codegen depend on debug info settings.
1582 llvm::Value *This = loadIncomingCXXThis(CGF);
1583 const CXXMethodDecl *MD = cast<CXXMethodDecl>(Val: CGF.CurGD.getDecl());
1584 if (!CGF.CurFuncIsThunk && MD->isVirtual()) {
1585 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD: CGF.CurGD);
1586 if (!Adjustment.isZero()) {
1587 assert(Adjustment.isPositive());
1588 This = CGF.Builder.CreateConstInBoundsGEP1_32(Ty: CGF.Int8Ty, Ptr: This,
1589 Idx0: -Adjustment.getQuantity());
1590 }
1591 }
1592 setCXXABIThisValue(CGF, ThisPtr: This);
1593
1594 // If this is a function that the ABI specifies returns 'this', initialize
1595 // the return slot to 'this' at the start of the function.
1596 //
1597 // Unlike the setting of return types, this is done within the ABI
1598 // implementation instead of by clients of CGCXXABI because:
1599 // 1) getThisValue is currently protected
1600 // 2) in theory, an ABI could implement 'this' returns some other way;
1601 // HasThisReturn only specifies a contract, not the implementation
1602 if (HasThisReturn(GD: CGF.CurGD) || hasMostDerivedReturn(GD: CGF.CurGD))
1603 CGF.Builder.CreateStore(Val: getThisValue(CGF), Addr: CGF.ReturnValue);
1604
1605 if (isa<CXXConstructorDecl>(Val: MD) && MD->getParent()->getNumVBases()) {
1606 assert(getStructorImplicitParamDecl(CGF) &&
1607 "no implicit parameter for a constructor with virtual bases?");
1608 getStructorImplicitParamValue(CGF)
1609 = CGF.Builder.CreateLoad(
1610 Addr: CGF.GetAddrOfLocalVar(VD: getStructorImplicitParamDecl(CGF)),
1611 Name: "is_most_derived");
1612 }
1613
1614 if (isDeletingDtor(GD: CGF.CurGD)) {
1615 assert(getStructorImplicitParamDecl(CGF) &&
1616 "no implicit parameter for a deleting destructor?");
1617 getStructorImplicitParamValue(CGF)
1618 = CGF.Builder.CreateLoad(
1619 Addr: CGF.GetAddrOfLocalVar(VD: getStructorImplicitParamDecl(CGF)),
1620 Name: "should_call_delete");
1621 }
1622}
1623
1624CGCXXABI::AddedStructorArgs MicrosoftCXXABI::getImplicitConstructorArgs(
1625 CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type,
1626 bool ForVirtualBase, bool Delegating) {
1627 assert(Type == Ctor_Complete || Type == Ctor_Base);
1628
1629 // Check if we need a 'most_derived' parameter.
1630 if (!D->getParent()->getNumVBases())
1631 return AddedStructorArgs{};
1632
1633 // Add the 'most_derived' argument second if we are variadic or last if not.
1634 const FunctionProtoType *FPT = D->getType()->castAs<FunctionProtoType>();
1635 llvm::Value *MostDerivedArg;
1636 if (Delegating) {
1637 MostDerivedArg = getStructorImplicitParamValue(CGF);
1638 } else {
1639 MostDerivedArg = llvm::ConstantInt::get(Ty: CGM.Int32Ty, V: Type == Ctor_Complete);
1640 }
1641 if (FPT->isVariadic()) {
1642 return AddedStructorArgs::prefix(Args: {{.Value: MostDerivedArg, .Type: getContext().IntTy}});
1643 }
1644 return AddedStructorArgs::suffix(Args: {{.Value: MostDerivedArg, .Type: getContext().IntTy}});
1645}
1646
1647llvm::Value *MicrosoftCXXABI::getCXXDestructorImplicitParam(
1648 CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type,
1649 bool ForVirtualBase, bool Delegating) {
1650 return nullptr;
1651}
1652
1653void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
1654 const CXXDestructorDecl *DD,
1655 CXXDtorType Type, bool ForVirtualBase,
1656 bool Delegating, Address This,
1657 QualType ThisTy) {
1658 // Use the base destructor variant in place of the complete destructor variant
1659 // if the class has no virtual bases. This effectively implements some of the
1660 // -mconstructor-aliases optimization, but as part of the MS C++ ABI.
1661 if (Type == Dtor_Complete && DD->getParent()->getNumVBases() == 0)
1662 Type = Dtor_Base;
1663
1664 GlobalDecl GD(DD, Type);
1665 CGCallee Callee = CGCallee::forDirect(functionPtr: CGM.getAddrOfCXXStructor(GD), abstractInfo: GD);
1666
1667 if (DD->isVirtual()) {
1668 assert(Type != CXXDtorType::Dtor_Deleting &&
1669 "The deleting destructor should only be called via a virtual call");
1670 This = adjustThisArgumentForVirtualFunctionCall(CGF, GD: GlobalDecl(DD, Type),
1671 This, VirtualCall: false);
1672 }
1673
1674 llvm::BasicBlock *BaseDtorEndBB = nullptr;
1675 if (ForVirtualBase && isa<CXXConstructorDecl>(Val: CGF.CurCodeDecl)) {
1676 BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF);
1677 }
1678
1679 llvm::Value *Implicit =
1680 getCXXDestructorImplicitParam(CGF, DD, Type, ForVirtualBase,
1681 Delegating); // = nullptr
1682 CGF.EmitCXXDestructorCall(Dtor: GD, Callee, This: CGF.getAsNaturalPointerTo(Addr: This, PointeeType: ThisTy),
1683 ThisTy,
1684 /*ImplicitParam=*/Implicit,
1685 /*ImplicitParamTy=*/QualType(), /*E=*/nullptr);
1686 if (BaseDtorEndBB) {
1687 // Complete object handler should continue to be the remaining
1688 CGF.Builder.CreateBr(Dest: BaseDtorEndBB);
1689 CGF.EmitBlock(BB: BaseDtorEndBB);
1690 }
1691}
1692
1693void MicrosoftCXXABI::emitVTableTypeMetadata(const VPtrInfo &Info,
1694 const CXXRecordDecl *RD,
1695 llvm::GlobalVariable *VTable) {
1696 // Emit type metadata on vtables with LTO or IR instrumentation.
1697 // In IR instrumentation, the type metadata could be used to find out vtable
1698 // definitions (for type profiling) among all global variables.
1699 if (!CGM.getCodeGenOpts().LTOUnit &&
1700 !CGM.getCodeGenOpts().hasProfileIRInstr())
1701 return;
1702
1703 // TODO: Should VirtualFunctionElimination also be supported here?
1704 // See similar handling in CodeGenModule::EmitVTableTypeMetadata.
1705 if (CGM.getCodeGenOpts().WholeProgramVTables) {
1706 llvm::DenseSet<const CXXRecordDecl *> Visited;
1707 llvm::GlobalObject::VCallVisibility TypeVis =
1708 CGM.GetVCallVisibilityLevel(RD, Visited);
1709 if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic)
1710 VTable->setVCallVisibilityMetadata(TypeVis);
1711 }
1712
1713 // The location of the first virtual function pointer in the virtual table,
1714 // aka the "address point" on Itanium. This is at offset 0 if RTTI is
1715 // disabled, or sizeof(void*) if RTTI is enabled.
1716 CharUnits AddressPoint =
1717 getContext().getLangOpts().RTTIData
1718 ? getContext().toCharUnitsFromBits(
1719 BitSize: getContext().getTargetInfo().getPointerWidth(AddrSpace: LangAS::Default))
1720 : CharUnits::Zero();
1721
1722 if (Info.PathToIntroducingObject.empty()) {
1723 CGM.AddVTableTypeMetadata(VTable, Offset: AddressPoint, RD);
1724 return;
1725 }
1726
1727 // Add a bitset entry for the least derived base belonging to this vftable.
1728 CGM.AddVTableTypeMetadata(VTable, Offset: AddressPoint,
1729 RD: Info.PathToIntroducingObject.back());
1730
1731 // Add a bitset entry for each derived class that is laid out at the same
1732 // offset as the least derived base.
1733 for (unsigned I = Info.PathToIntroducingObject.size() - 1; I != 0; --I) {
1734 const CXXRecordDecl *DerivedRD = Info.PathToIntroducingObject[I - 1];
1735 const CXXRecordDecl *BaseRD = Info.PathToIntroducingObject[I];
1736
1737 const ASTRecordLayout &Layout =
1738 getContext().getASTRecordLayout(D: DerivedRD);
1739 CharUnits Offset;
1740 auto VBI = Layout.getVBaseOffsetsMap().find(Val: BaseRD);
1741 if (VBI == Layout.getVBaseOffsetsMap().end())
1742 Offset = Layout.getBaseClassOffset(Base: BaseRD);
1743 else
1744 Offset = VBI->second.VBaseOffset;
1745 if (!Offset.isZero())
1746 return;
1747 CGM.AddVTableTypeMetadata(VTable, Offset: AddressPoint, RD: DerivedRD);
1748 }
1749
1750 // Finally do the same for the most derived class.
1751 if (Info.FullOffsetInMDC.isZero())
1752 CGM.AddVTableTypeMetadata(VTable, Offset: AddressPoint, RD);
1753}
1754
1755void MicrosoftCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
1756 const CXXRecordDecl *RD) {
1757 MicrosoftVTableContext &VFTContext = CGM.getMicrosoftVTableContext();
1758 const VPtrInfoVector &VFPtrs = VFTContext.getVFPtrOffsets(RD);
1759
1760 for (const std::unique_ptr<VPtrInfo>& Info : VFPtrs) {
1761 llvm::GlobalVariable *VTable = getAddrOfVTable(RD, VPtrOffset: Info->FullOffsetInMDC);
1762 if (VTable->hasInitializer())
1763 continue;
1764
1765 const VTableLayout &VTLayout =
1766 VFTContext.getVFTableLayout(RD, VFPtrOffset: Info->FullOffsetInMDC);
1767
1768 llvm::Constant *RTTI = nullptr;
1769 if (any_of(Range: VTLayout.vtable_components(),
1770 P: [](const VTableComponent &VTC) { return VTC.isRTTIKind(); }))
1771 RTTI = getMSCompleteObjectLocator(RD, Info: *Info);
1772
1773 ConstantInitBuilder builder(CGM);
1774 auto components = builder.beginStruct();
1775 CGVT.createVTableInitializer(builder&: components, layout: VTLayout, rtti: RTTI,
1776 vtableHasLocalLinkage: VTable->hasLocalLinkage());
1777 components.finishAndSetAsInitializer(global: VTable);
1778
1779 emitVTableTypeMetadata(Info: *Info, RD, VTable);
1780 }
1781}
1782
1783bool MicrosoftCXXABI::isVirtualOffsetNeededForVTableField(
1784 CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr) {
1785 return Vptr.NearestVBase != nullptr;
1786}
1787
1788llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(
1789 CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base,
1790 const CXXRecordDecl *NearestVBase) {
1791 llvm::Constant *VTableAddressPoint = getVTableAddressPoint(Base, VTableClass);
1792 if (!VTableAddressPoint) {
1793 assert(Base.getBase()->getNumVBases() &&
1794 !getContext().getASTRecordLayout(Base.getBase()).hasOwnVFPtr());
1795 }
1796 return VTableAddressPoint;
1797}
1798
1799static void mangleVFTableName(MicrosoftMangleContext &MangleContext,
1800 const CXXRecordDecl *RD, const VPtrInfo &VFPtr,
1801 SmallString<256> &Name) {
1802 llvm::raw_svector_ostream Out(Name);
1803 MangleContext.mangleCXXVFTable(Derived: RD, BasePath: VFPtr.MangledPath, Out);
1804}
1805
1806llvm::Constant *
1807MicrosoftCXXABI::getVTableAddressPoint(BaseSubobject Base,
1808 const CXXRecordDecl *VTableClass) {
1809 (void)getAddrOfVTable(RD: VTableClass, VPtrOffset: Base.getBaseOffset());
1810 VFTableIdTy ID(VTableClass, Base.getBaseOffset());
1811 return VFTablesMap[ID];
1812}
1813
1814llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
1815 CharUnits VPtrOffset) {
1816 // getAddrOfVTable may return 0 if asked to get an address of a vtable which
1817 // shouldn't be used in the given record type. We want to cache this result in
1818 // VFTablesMap, thus a simple zero check is not sufficient.
1819
1820 VFTableIdTy ID(RD, VPtrOffset);
1821 auto [I, Inserted] = VTablesMap.try_emplace(Key: ID);
1822 if (!Inserted)
1823 return I->second;
1824
1825 llvm::GlobalVariable *&VTable = I->second;
1826
1827 MicrosoftVTableContext &VTContext = CGM.getMicrosoftVTableContext();
1828 const VPtrInfoVector &VFPtrs = VTContext.getVFPtrOffsets(RD);
1829
1830 if (DeferredVFTables.insert(Ptr: RD).second) {
1831 // We haven't processed this record type before.
1832 // Queue up this vtable for possible deferred emission.
1833 CGM.addDeferredVTable(RD);
1834
1835#ifndef NDEBUG
1836 // Create all the vftables at once in order to make sure each vftable has
1837 // a unique mangled name.
1838 llvm::StringSet<> ObservedMangledNames;
1839 for (const auto &VFPtr : VFPtrs) {
1840 SmallString<256> Name;
1841 mangleVFTableName(getMangleContext(), RD, *VFPtr, Name);
1842 if (!ObservedMangledNames.insert(Name.str()).second)
1843 llvm_unreachable("Already saw this mangling before?");
1844 }
1845#endif
1846 }
1847
1848 const std::unique_ptr<VPtrInfo> *VFPtrI =
1849 llvm::find_if(Range: VFPtrs, P: [&](const std::unique_ptr<VPtrInfo> &VPI) {
1850 return VPI->FullOffsetInMDC == VPtrOffset;
1851 });
1852 if (VFPtrI == VFPtrs.end()) {
1853 VFTablesMap[ID] = nullptr;
1854 return nullptr;
1855 }
1856 const std::unique_ptr<VPtrInfo> &VFPtr = *VFPtrI;
1857
1858 SmallString<256> VFTableName;
1859 mangleVFTableName(MangleContext&: getMangleContext(), RD, VFPtr: *VFPtr, Name&: VFTableName);
1860
1861 // Classes marked __declspec(dllimport) need vftables generated on the
1862 // import-side in order to support features like constexpr. No other
1863 // translation unit relies on the emission of the local vftable, translation
1864 // units are expected to generate them as needed.
1865 //
1866 // Because of this unique behavior, we maintain this logic here instead of
1867 // getVTableLinkage.
1868 llvm::GlobalValue::LinkageTypes VFTableLinkage =
1869 RD->hasAttr<DLLImportAttr>() ? llvm::GlobalValue::LinkOnceODRLinkage
1870 : CGM.getVTableLinkage(RD);
1871 bool VFTableComesFromAnotherTU =
1872 llvm::GlobalValue::isAvailableExternallyLinkage(Linkage: VFTableLinkage) ||
1873 llvm::GlobalValue::isExternalLinkage(Linkage: VFTableLinkage);
1874 bool VTableAliasIsRequred =
1875 !VFTableComesFromAnotherTU && getContext().getLangOpts().RTTIData;
1876
1877 if (llvm::GlobalValue *VFTable =
1878 CGM.getModule().getNamedGlobal(Name: VFTableName)) {
1879 VFTablesMap[ID] = VFTable;
1880 VTable = VTableAliasIsRequred
1881 ? cast<llvm::GlobalVariable>(
1882 Val: cast<llvm::GlobalAlias>(Val: VFTable)->getAliaseeObject())
1883 : cast<llvm::GlobalVariable>(Val: VFTable);
1884 return VTable;
1885 }
1886
1887 const VTableLayout &VTLayout =
1888 VTContext.getVFTableLayout(RD, VFPtrOffset: VFPtr->FullOffsetInMDC);
1889 llvm::GlobalValue::LinkageTypes VTableLinkage =
1890 VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
1891
1892 StringRef VTableName = VTableAliasIsRequred ? StringRef() : VFTableName.str();
1893
1894 llvm::Type *VTableType = CGM.getVTables().getVTableType(layout: VTLayout);
1895
1896 // Create a backing variable for the contents of VTable. The VTable may
1897 // or may not include space for a pointer to RTTI data.
1898 llvm::GlobalValue *VFTable;
1899 VTable = new llvm::GlobalVariable(CGM.getModule(), VTableType,
1900 /*isConstant=*/true, VTableLinkage,
1901 /*Initializer=*/nullptr, VTableName);
1902 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1903
1904 llvm::Comdat *C = nullptr;
1905 if (!VFTableComesFromAnotherTU &&
1906 llvm::GlobalValue::isWeakForLinker(Linkage: VFTableLinkage))
1907 C = CGM.getModule().getOrInsertComdat(Name: VFTableName.str());
1908
1909 // Only insert a pointer into the VFTable for RTTI data if we are not
1910 // importing it. We never reference the RTTI data directly so there is no
1911 // need to make room for it.
1912 if (VTableAliasIsRequred) {
1913 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(Ty: CGM.Int32Ty, V: 0),
1914 llvm::ConstantInt::get(Ty: CGM.Int32Ty, V: 0),
1915 llvm::ConstantInt::get(Ty: CGM.Int32Ty, V: 1)};
1916 // Create a GEP which points just after the first entry in the VFTable,
1917 // this should be the location of the first virtual method.
1918 llvm::Constant *VTableGEP = llvm::ConstantExpr::getInBoundsGetElementPtr(
1919 Ty: VTable->getValueType(), C: VTable, IdxList: GEPIndices);
1920 if (llvm::GlobalValue::isWeakForLinker(Linkage: VFTableLinkage)) {
1921 VFTableLinkage = llvm::GlobalValue::ExternalLinkage;
1922 if (C)
1923 C->setSelectionKind(llvm::Comdat::Largest);
1924 }
1925 VFTable = llvm::GlobalAlias::create(Ty: CGM.Int8PtrTy,
1926 /*AddressSpace=*/0, Linkage: VFTableLinkage,
1927 Name: VFTableName.str(), Aliasee: VTableGEP,
1928 Parent: &CGM.getModule());
1929 VFTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1930 } else {
1931 // We don't need a GlobalAlias to be a symbol for the VTable if we won't
1932 // be referencing any RTTI data.
1933 // The GlobalVariable will end up being an appropriate definition of the
1934 // VFTable.
1935 VFTable = VTable;
1936 }
1937 if (C)
1938 VTable->setComdat(C);
1939
1940 if (RD->hasAttr<DLLExportAttr>())
1941 VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1942
1943 VFTablesMap[ID] = VFTable;
1944 return VTable;
1945}
1946
1947CGCallee MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
1948 GlobalDecl GD,
1949 Address This,
1950 llvm::Type *Ty,
1951 SourceLocation Loc) {
1952 CGBuilderTy &Builder = CGF.Builder;
1953
1954 Ty = CGF.UnqualPtrTy;
1955 Address VPtr =
1956 adjustThisArgumentForVirtualFunctionCall(CGF, GD, This, VirtualCall: true);
1957
1958 auto *MethodDecl = cast<CXXMethodDecl>(Val: GD.getDecl());
1959 llvm::Value *VTable =
1960 CGF.GetVTablePtr(This: VPtr, VTableTy: CGF.UnqualPtrTy, VTableClass: MethodDecl->getParent());
1961
1962 MicrosoftVTableContext &VFTContext = CGM.getMicrosoftVTableContext();
1963 MethodVFTableLocation ML = VFTContext.getMethodVFTableLocation(GD);
1964
1965 // Compute the identity of the most derived class whose virtual table is
1966 // located at the MethodVFTableLocation ML.
1967 auto getObjectWithVPtr = [&] {
1968 return llvm::find_if(Range: VFTContext.getVFPtrOffsets(
1969 RD: ML.VBase ? ML.VBase : MethodDecl->getParent()),
1970 P: [&](const std::unique_ptr<VPtrInfo> &Info) {
1971 return Info->FullOffsetInMDC == ML.VFPtrOffset;
1972 })
1973 ->get()
1974 ->ObjectWithVPtr;
1975 };
1976
1977 llvm::Value *VFunc;
1978 if (CGF.ShouldEmitVTableTypeCheckedLoad(RD: MethodDecl->getParent())) {
1979 VFunc = CGF.EmitVTableTypeCheckedLoad(
1980 RD: getObjectWithVPtr(), VTable, VTableTy: Ty,
1981 VTableByteOffset: ML.Index *
1982 CGM.getContext().getTargetInfo().getPointerWidth(AddrSpace: LangAS::Default) /
1983 8);
1984 } else {
1985 if (CGM.getCodeGenOpts().PrepareForLTO)
1986 CGF.EmitTypeMetadataCodeForVCall(RD: getObjectWithVPtr(), VTable, Loc);
1987
1988 llvm::Value *VFuncPtr =
1989 Builder.CreateConstInBoundsGEP1_64(Ty, Ptr: VTable, Idx0: ML.Index, Name: "vfn");
1990 VFunc = Builder.CreateAlignedLoad(Ty, Addr: VFuncPtr, Align: CGF.getPointerAlign());
1991 }
1992
1993 CGCallee Callee(GD, VFunc);
1994 return Callee;
1995}
1996
1997llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
1998 CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType DtorType,
1999 Address This, DeleteOrMemberCallExpr E, llvm::CallBase **CallOrInvoke) {
2000 auto *CE = dyn_cast<const CXXMemberCallExpr *>(Val&: E);
2001 auto *D = dyn_cast<const CXXDeleteExpr *>(Val&: E);
2002 assert((CE != nullptr) ^ (D != nullptr));
2003 assert(CE == nullptr || CE->arg_begin() == CE->arg_end());
2004 assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);
2005
2006 // We have only one destructor in the vftable but can get both behaviors
2007 // by passing an implicit int parameter.
2008 GlobalDecl GD(Dtor, Dtor_Deleting);
2009 const CGFunctionInfo *FInfo =
2010 &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
2011 llvm::FunctionType *Ty = CGF.CGM.getTypes().GetFunctionType(Info: *FInfo);
2012 CGCallee Callee = CGCallee::forVirtual(CE, MD: GD, Addr: This, FTy: Ty);
2013
2014 ASTContext &Context = getContext();
2015 llvm::Value *ImplicitParam = llvm::ConstantInt::get(
2016 Ty: llvm::IntegerType::getInt32Ty(C&: CGF.getLLVMContext()),
2017 V: DtorType == Dtor_Deleting);
2018
2019 QualType ThisTy;
2020 if (CE) {
2021 ThisTy = CE->getObjectType();
2022 } else {
2023 ThisTy = D->getDestroyedType();
2024 }
2025
2026 This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This, VirtualCall: true);
2027 RValue RV =
2028 CGF.EmitCXXDestructorCall(Dtor: GD, Callee, This: This.emitRawPointer(CGF), ThisTy,
2029 ImplicitParam, ImplicitParamTy: Context.IntTy, E: CE, CallOrInvoke);
2030 return RV.getScalarVal();
2031}
2032
2033const VBTableGlobals &
2034MicrosoftCXXABI::enumerateVBTables(const CXXRecordDecl *RD) {
2035 // At this layer, we can key the cache off of a single class, which is much
2036 // easier than caching each vbtable individually.
2037 auto [Entry, Added] = VBTablesMap.try_emplace(Key: RD);
2038 VBTableGlobals &VBGlobals = Entry->second;
2039 if (!Added)
2040 return VBGlobals;
2041
2042 MicrosoftVTableContext &Context = CGM.getMicrosoftVTableContext();
2043 VBGlobals.VBTables = &Context.enumerateVBTables(RD);
2044
2045 // Cache the globals for all vbtables so we don't have to recompute the
2046 // mangled names.
2047 llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);
2048 for (VPtrInfoVector::const_iterator I = VBGlobals.VBTables->begin(),
2049 E = VBGlobals.VBTables->end();
2050 I != E; ++I) {
2051 VBGlobals.Globals.push_back(Elt: getAddrOfVBTable(VBT: **I, RD, Linkage));
2052 }
2053
2054 return VBGlobals;
2055}
2056
2057llvm::Function *
2058MicrosoftCXXABI::EmitVirtualMemPtrThunk(const CXXMethodDecl *MD,
2059 const MethodVFTableLocation &ML) {
2060 assert(!isa<CXXConstructorDecl>(MD) && !isa<CXXDestructorDecl>(MD) &&
2061 "can't form pointers to ctors or virtual dtors");
2062
2063 // Calculate the mangled name.
2064 SmallString<256> ThunkName;
2065 llvm::raw_svector_ostream Out(ThunkName);
2066 getMangleContext().mangleVirtualMemPtrThunk(MD, ML, Out);
2067
2068 // If the thunk has been generated previously, just return it.
2069 if (llvm::GlobalValue *GV = CGM.getModule().getNamedValue(Name: ThunkName))
2070 return cast<llvm::Function>(Val: GV);
2071
2072 // Create the llvm::Function.
2073 const CGFunctionInfo &FnInfo =
2074 CGM.getTypes().arrangeUnprototypedMustTailThunk(MD);
2075 llvm::FunctionType *ThunkTy = CGM.getTypes().GetFunctionType(Info: FnInfo);
2076 llvm::Function *ThunkFn =
2077 llvm::Function::Create(Ty: ThunkTy, Linkage: llvm::Function::ExternalLinkage,
2078 N: ThunkName.str(), M: &CGM.getModule());
2079 assert(ThunkFn->getName() == ThunkName && "name was uniqued!");
2080
2081 ThunkFn->setLinkage(MD->isExternallyVisible()
2082 ? llvm::GlobalValue::LinkOnceODRLinkage
2083 : llvm::GlobalValue::InternalLinkage);
2084 if (MD->isExternallyVisible())
2085 ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(Name: ThunkFn->getName()));
2086
2087 CGM.SetLLVMFunctionAttributes(GD: MD, Info: FnInfo, F: ThunkFn, /*IsThunk=*/false);
2088 CGM.SetLLVMFunctionAttributesForDefinition(D: MD, F: ThunkFn);
2089
2090 // Add the "thunk" attribute so that LLVM knows that the return type is
2091 // meaningless. These thunks can be used to call functions with differing
2092 // return types, and the caller is required to cast the prototype
2093 // appropriately to extract the correct value.
2094 ThunkFn->addFnAttr(Kind: "thunk");
2095
2096 // These thunks can be compared, so they are not unnamed.
2097 ThunkFn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::None);
2098
2099 // Start codegen.
2100 CodeGenFunction CGF(CGM);
2101 CGF.CurGD = GlobalDecl(MD);
2102 CGF.CurFuncIsThunk = true;
2103
2104 // Build FunctionArgs, but only include the implicit 'this' parameter
2105 // declaration.
2106 FunctionArgList FunctionArgs;
2107 buildThisParam(CGF, Params&: FunctionArgs);
2108
2109 // Start defining the function.
2110 CGF.StartFunction(GD: GlobalDecl(), RetTy: FnInfo.getReturnType(), Fn: ThunkFn, FnInfo,
2111 Args: FunctionArgs, Loc: MD->getLocation(), StartLoc: SourceLocation());
2112
2113 ApplyDebugLocation AL(CGF, MD->getLocation());
2114 setCXXABIThisValue(CGF, ThisPtr: loadIncomingCXXThis(CGF));
2115
2116 // Load the vfptr and then callee from the vftable. The callee should have
2117 // adjusted 'this' so that the vfptr is at offset zero.
2118 llvm::Type *ThunkPtrTy = CGF.UnqualPtrTy;
2119 llvm::Value *VTable =
2120 CGF.GetVTablePtr(This: getThisAddress(CGF), VTableTy: CGF.UnqualPtrTy, VTableClass: MD->getParent());
2121
2122 llvm::Value *VFuncPtr = CGF.Builder.CreateConstInBoundsGEP1_64(
2123 Ty: ThunkPtrTy, Ptr: VTable, Idx0: ML.Index, Name: "vfn");
2124 llvm::Value *Callee =
2125 CGF.Builder.CreateAlignedLoad(Ty: ThunkPtrTy, Addr: VFuncPtr, Align: CGF.getPointerAlign());
2126
2127 CGF.EmitMustTailThunk(GD: MD, AdjustedThisPtr: getThisValue(CGF), Callee: {ThunkTy, Callee});
2128
2129 return ThunkFn;
2130}
2131
2132void MicrosoftCXXABI::emitVirtualInheritanceTables(const CXXRecordDecl *RD) {
2133 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
2134 for (unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
2135 const std::unique_ptr<VPtrInfo>& VBT = (*VBGlobals.VBTables)[I];
2136 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
2137 if (GV->isDeclaration())
2138 emitVBTableDefinition(VBT: *VBT, RD, GV);
2139 }
2140}
2141
2142llvm::GlobalVariable *
2143MicrosoftCXXABI::getAddrOfVBTable(const VPtrInfo &VBT, const CXXRecordDecl *RD,
2144 llvm::GlobalVariable::LinkageTypes Linkage) {
2145 SmallString<256> OutName;
2146 llvm::raw_svector_ostream Out(OutName);
2147 getMangleContext().mangleCXXVBTable(Derived: RD, BasePath: VBT.MangledPath, Out);
2148 StringRef Name = OutName.str();
2149
2150 llvm::ArrayType *VBTableType =
2151 llvm::ArrayType::get(ElementType: CGM.IntTy, NumElements: 1 + VBT.ObjectWithVPtr->getNumVBases());
2152
2153 assert(!CGM.getModule().getNamedGlobal(Name) &&
2154 "vbtable with this name already exists: mangling bug?");
2155 CharUnits Alignment =
2156 CGM.getContext().getTypeAlignInChars(T: CGM.getContext().IntTy);
2157 llvm::GlobalVariable *GV = CGM.CreateOrReplaceCXXRuntimeVariable(
2158 Name, Ty: VBTableType, Linkage, Alignment: Alignment.getAsAlign());
2159 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2160
2161 if (RD->hasAttr<DLLImportAttr>())
2162 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2163 else if (RD->hasAttr<DLLExportAttr>())
2164 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2165
2166 if (!GV->hasExternalLinkage())
2167 emitVBTableDefinition(VBT, RD, GV);
2168
2169 return GV;
2170}
2171
2172void MicrosoftCXXABI::emitVBTableDefinition(const VPtrInfo &VBT,
2173 const CXXRecordDecl *RD,
2174 llvm::GlobalVariable *GV) const {
2175 const CXXRecordDecl *ObjectWithVPtr = VBT.ObjectWithVPtr;
2176
2177 assert(RD->getNumVBases() && ObjectWithVPtr->getNumVBases() &&
2178 "should only emit vbtables for classes with vbtables");
2179
2180 const ASTRecordLayout &BaseLayout =
2181 getContext().getASTRecordLayout(D: VBT.IntroducingObject);
2182 const ASTRecordLayout &DerivedLayout = getContext().getASTRecordLayout(D: RD);
2183
2184 SmallVector<llvm::Constant *, 4> Offsets(1 + ObjectWithVPtr->getNumVBases(),
2185 nullptr);
2186
2187 // The offset from ObjectWithVPtr's vbptr to itself always leads.
2188 CharUnits VBPtrOffset = BaseLayout.getVBPtrOffset();
2189 Offsets[0] = llvm::ConstantInt::get(Ty: CGM.IntTy, V: -VBPtrOffset.getQuantity());
2190
2191 MicrosoftVTableContext &Context = CGM.getMicrosoftVTableContext();
2192 for (const auto &I : ObjectWithVPtr->vbases()) {
2193 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
2194 CharUnits Offset = DerivedLayout.getVBaseClassOffset(VBase);
2195 assert(!Offset.isNegative());
2196
2197 // Make it relative to the subobject vbptr.
2198 CharUnits CompleteVBPtrOffset = VBT.NonVirtualOffset + VBPtrOffset;
2199 if (VBT.getVBaseWithVPtr())
2200 CompleteVBPtrOffset +=
2201 DerivedLayout.getVBaseClassOffset(VBase: VBT.getVBaseWithVPtr());
2202 Offset -= CompleteVBPtrOffset;
2203
2204 unsigned VBIndex = Context.getVBTableIndex(Derived: ObjectWithVPtr, VBase);
2205 assert(Offsets[VBIndex] == nullptr && "The same vbindex seen twice?");
2206 Offsets[VBIndex] = llvm::ConstantInt::get(Ty: CGM.IntTy, V: Offset.getQuantity());
2207 }
2208
2209 assert(Offsets.size() ==
2210 cast<llvm::ArrayType>(GV->getValueType())->getNumElements());
2211 llvm::ArrayType *VBTableType =
2212 llvm::ArrayType::get(ElementType: CGM.IntTy, NumElements: Offsets.size());
2213 llvm::Constant *Init = llvm::ConstantArray::get(T: VBTableType, V: Offsets);
2214 GV->setInitializer(Init);
2215
2216 if (RD->hasAttr<DLLImportAttr>())
2217 GV->setLinkage(llvm::GlobalVariable::AvailableExternallyLinkage);
2218}
2219
2220llvm::Value *MicrosoftCXXABI::performThisAdjustment(
2221 CodeGenFunction &CGF, Address This,
2222 const CXXRecordDecl * /*UnadjustedClass*/, const ThunkInfo &TI) {
2223 const ThisAdjustment &TA = TI.This;
2224 if (TA.isEmpty())
2225 return This.emitRawPointer(CGF);
2226
2227 This = This.withElementType(ElemTy: CGF.Int8Ty);
2228
2229 llvm::Value *V;
2230 if (TA.Virtual.isEmpty()) {
2231 V = This.emitRawPointer(CGF);
2232 } else {
2233 assert(TA.Virtual.Microsoft.VtordispOffset < 0);
2234 // Adjust the this argument based on the vtordisp value.
2235 Address VtorDispPtr =
2236 CGF.Builder.CreateConstInBoundsByteGEP(Addr: This,
2237 Offset: CharUnits::fromQuantity(Quantity: TA.Virtual.Microsoft.VtordispOffset));
2238 VtorDispPtr = VtorDispPtr.withElementType(ElemTy: CGF.Int32Ty);
2239 llvm::Value *VtorDisp = CGF.Builder.CreateLoad(Addr: VtorDispPtr, Name: "vtordisp");
2240 V = CGF.Builder.CreateGEP(Ty: This.getElementType(), Ptr: This.emitRawPointer(CGF),
2241 IdxList: CGF.Builder.CreateNeg(V: VtorDisp));
2242
2243 // Unfortunately, having applied the vtordisp means that we no
2244 // longer really have a known alignment for the vbptr step.
2245 // We'll assume the vbptr is pointer-aligned.
2246
2247 if (TA.Virtual.Microsoft.VBPtrOffset) {
2248 // If the final overrider is defined in a virtual base other than the one
2249 // that holds the vfptr, we have to use a vtordispex thunk which looks up
2250 // the vbtable of the derived class.
2251 assert(TA.Virtual.Microsoft.VBPtrOffset > 0);
2252 assert(TA.Virtual.Microsoft.VBOffsetOffset >= 0);
2253 llvm::Value *VBPtr;
2254 llvm::Value *VBaseOffset = GetVBaseOffsetFromVBPtr(
2255 CGF, Base: Address(V, CGF.Int8Ty, CGF.getPointerAlign()),
2256 VBPtrOffset: -TA.Virtual.Microsoft.VBPtrOffset,
2257 VBTableOffset: TA.Virtual.Microsoft.VBOffsetOffset, VBPtr: &VBPtr);
2258 V = CGF.Builder.CreateInBoundsGEP(Ty: CGF.Int8Ty, Ptr: VBPtr, IdxList: VBaseOffset);
2259 }
2260 }
2261
2262 if (TA.NonVirtual) {
2263 // Non-virtual adjustment might result in a pointer outside the allocated
2264 // object, e.g. if the final overrider class is laid out after the virtual
2265 // base that declares a method in the most derived class.
2266 V = CGF.Builder.CreateConstGEP1_32(Ty: CGF.Int8Ty, Ptr: V, Idx0: TA.NonVirtual);
2267 }
2268
2269 // Don't need to bitcast back, the call CodeGen will handle this.
2270 return V;
2271}
2272
2273llvm::Value *MicrosoftCXXABI::performReturnAdjustment(
2274 CodeGenFunction &CGF, Address Ret,
2275 const CXXRecordDecl * /*UnadjustedClass*/, const ReturnAdjustment &RA) {
2276
2277 if (RA.isEmpty())
2278 return Ret.emitRawPointer(CGF);
2279
2280 Ret = Ret.withElementType(ElemTy: CGF.Int8Ty);
2281
2282 llvm::Value *V = Ret.emitRawPointer(CGF);
2283 if (RA.Virtual.Microsoft.VBIndex) {
2284 assert(RA.Virtual.Microsoft.VBIndex > 0);
2285 int32_t IntSize = CGF.getIntSize().getQuantity();
2286 llvm::Value *VBPtr;
2287 llvm::Value *VBaseOffset =
2288 GetVBaseOffsetFromVBPtr(CGF, Base: Ret, VBPtrOffset: RA.Virtual.Microsoft.VBPtrOffset,
2289 VBTableOffset: IntSize * RA.Virtual.Microsoft.VBIndex, VBPtr: &VBPtr);
2290 V = CGF.Builder.CreateInBoundsGEP(Ty: CGF.Int8Ty, Ptr: VBPtr, IdxList: VBaseOffset);
2291 }
2292
2293 if (RA.NonVirtual)
2294 V = CGF.Builder.CreateConstInBoundsGEP1_32(Ty: CGF.Int8Ty, Ptr: V, Idx0: RA.NonVirtual);
2295
2296 return V;
2297}
2298
2299bool MicrosoftCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr,
2300 QualType elementType) {
2301 // Microsoft seems to completely ignore the possibility of a
2302 // two-argument usual deallocation function.
2303 return elementType.isDestructedType();
2304}
2305
2306bool MicrosoftCXXABI::requiresArrayCookie(const CXXNewExpr *expr) {
2307 // Microsoft seems to completely ignore the possibility of a
2308 // two-argument usual deallocation function.
2309 return expr->getAllocatedType().isDestructedType();
2310}
2311
2312CharUnits MicrosoftCXXABI::getArrayCookieSizeImpl(QualType type) {
2313 // The array cookie is always a size_t; we then pad that out to the
2314 // alignment of the element type.
2315 ASTContext &Ctx = getContext();
2316 return std::max(a: Ctx.getTypeSizeInChars(T: Ctx.getSizeType()),
2317 b: Ctx.getTypeAlignInChars(T: type));
2318}
2319
2320llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
2321 Address allocPtr,
2322 CharUnits cookieSize) {
2323 Address numElementsPtr = allocPtr.withElementType(ElemTy: CGF.SizeTy);
2324 return CGF.Builder.CreateLoad(Addr: numElementsPtr);
2325}
2326
2327Address MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
2328 Address newPtr,
2329 llvm::Value *numElements,
2330 const CXXNewExpr *expr,
2331 QualType elementType) {
2332 assert(requiresArrayCookie(expr));
2333
2334 // The size of the cookie.
2335 CharUnits cookieSize = getArrayCookieSizeImpl(type: elementType);
2336
2337 // Compute an offset to the cookie.
2338 Address cookiePtr = newPtr;
2339
2340 // Write the number of elements into the appropriate slot.
2341 Address numElementsPtr = cookiePtr.withElementType(ElemTy: CGF.SizeTy);
2342 CGF.Builder.CreateStore(Val: numElements, Addr: numElementsPtr);
2343
2344 // Finally, compute a pointer to the actual data buffer by skipping
2345 // over the cookie completely.
2346 return CGF.Builder.CreateConstInBoundsByteGEP(Addr: newPtr, Offset: cookieSize);
2347}
2348
2349static void emitGlobalDtorWithTLRegDtor(CodeGenFunction &CGF, const VarDecl &VD,
2350 llvm::FunctionCallee Dtor,
2351 llvm::Constant *Addr) {
2352 // Create a function which calls the destructor.
2353 llvm::Constant *DtorStub = CGF.createAtExitStub(VD, Dtor, Addr);
2354
2355 // extern "C" int __tlregdtor(void (*f)(void));
2356 llvm::FunctionType *TLRegDtorTy = llvm::FunctionType::get(
2357 Result: CGF.IntTy, Params: DtorStub->getType(), /*isVarArg=*/false);
2358
2359 llvm::FunctionCallee TLRegDtor = CGF.CGM.CreateRuntimeFunction(
2360 Ty: TLRegDtorTy, Name: "__tlregdtor", ExtraAttrs: llvm::AttributeList(), /*Local=*/true);
2361 if (llvm::Function *TLRegDtorFn =
2362 dyn_cast<llvm::Function>(Val: TLRegDtor.getCallee()))
2363 TLRegDtorFn->setDoesNotThrow();
2364
2365 CGF.EmitNounwindRuntimeCall(callee: TLRegDtor, args: DtorStub);
2366}
2367
2368void MicrosoftCXXABI::registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
2369 llvm::FunctionCallee Dtor,
2370 llvm::Constant *Addr) {
2371 if (D.isNoDestroy(CGM.getContext()))
2372 return;
2373
2374 if (D.getTLSKind())
2375 return emitGlobalDtorWithTLRegDtor(CGF, VD: D, Dtor, Addr);
2376
2377 // HLSL doesn't support atexit.
2378 if (CGM.getLangOpts().HLSL)
2379 return CGM.AddCXXDtorEntry(DtorFn: Dtor, Object: Addr);
2380
2381 // The default behavior is to use atexit.
2382 CGF.registerGlobalDtorWithAtExit(D, fn: Dtor, addr: Addr);
2383}
2384
2385void MicrosoftCXXABI::EmitThreadLocalInitFuncs(
2386 CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals,
2387 ArrayRef<llvm::Function *> CXXThreadLocalInits,
2388 ArrayRef<const VarDecl *> CXXThreadLocalInitVars) {
2389 if (CXXThreadLocalInits.empty())
2390 return;
2391
2392 CGM.AppendLinkerOptions(Opts: CGM.getTarget().getTriple().getArch() ==
2393 llvm::Triple::x86
2394 ? "/include:___dyn_tls_init@12"
2395 : "/include:__dyn_tls_init");
2396
2397 // This will create a GV in the .CRT$XDU section. It will point to our
2398 // initialization function. The CRT will call all of these function
2399 // pointers at start-up time and, eventually, at thread-creation time.
2400 auto AddToXDU = [&CGM](llvm::Function *InitFunc) {
2401 llvm::GlobalVariable *InitFuncPtr = new llvm::GlobalVariable(
2402 CGM.getModule(), InitFunc->getType(), /*isConstant=*/true,
2403 llvm::GlobalVariable::InternalLinkage, InitFunc,
2404 Twine(InitFunc->getName(), "$initializer$"));
2405 InitFuncPtr->setSection(".CRT$XDU");
2406 // This variable has discardable linkage, we have to add it to @llvm.used to
2407 // ensure it won't get discarded.
2408 CGM.addUsedGlobal(GV: InitFuncPtr);
2409 return InitFuncPtr;
2410 };
2411
2412 std::vector<llvm::Function *> NonComdatInits;
2413 for (size_t I = 0, E = CXXThreadLocalInitVars.size(); I != E; ++I) {
2414 llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
2415 Val: CGM.GetGlobalValue(Ref: CGM.getMangledName(GD: CXXThreadLocalInitVars[I])));
2416 llvm::Function *F = CXXThreadLocalInits[I];
2417
2418 // If the GV is already in a comdat group, then we have to join it.
2419 if (llvm::Comdat *C = GV->getComdat())
2420 AddToXDU(F)->setComdat(C);
2421 else
2422 NonComdatInits.push_back(x: F);
2423 }
2424
2425 if (!NonComdatInits.empty()) {
2426 llvm::FunctionType *FTy =
2427 llvm::FunctionType::get(Result: CGM.VoidTy, /*isVarArg=*/false);
2428 llvm::Function *InitFunc = CGM.CreateGlobalInitOrCleanUpFunction(
2429 ty: FTy, name: "__tls_init", FI: CGM.getTypes().arrangeNullaryFunction(),
2430 Loc: SourceLocation(), /*TLS=*/true);
2431 CodeGenFunction(CGM).GenerateCXXGlobalInitFunc(Fn: InitFunc, CXXThreadLocals: NonComdatInits);
2432
2433 AddToXDU(InitFunc);
2434 }
2435}
2436
2437static llvm::GlobalValue *getTlsGuardVar(CodeGenModule &CGM) {
2438 // __tls_guard comes from the MSVC runtime and reflects
2439 // whether TLS has been initialized for a particular thread.
2440 // It is set from within __dyn_tls_init by the runtime.
2441 // Every library and executable has its own variable.
2442 llvm::Type *VTy = llvm::Type::getInt8Ty(C&: CGM.getLLVMContext());
2443 llvm::Constant *TlsGuardConstant =
2444 CGM.CreateRuntimeVariable(Ty: VTy, Name: "__tls_guard");
2445 llvm::GlobalValue *TlsGuard = cast<llvm::GlobalValue>(Val: TlsGuardConstant);
2446
2447 TlsGuard->setThreadLocal(true);
2448
2449 return TlsGuard;
2450}
2451
2452static llvm::FunctionCallee getDynTlsOnDemandInitFn(CodeGenModule &CGM) {
2453 // __dyn_tls_on_demand_init comes from the MSVC runtime and triggers
2454 // dynamic TLS initialization by calling __dyn_tls_init internally.
2455 llvm::FunctionType *FTy =
2456 llvm::FunctionType::get(Result: llvm::Type::getVoidTy(C&: CGM.getLLVMContext()), Params: {},
2457 /*isVarArg=*/false);
2458 return CGM.CreateRuntimeFunction(
2459 Ty: FTy, Name: "__dyn_tls_on_demand_init",
2460 ExtraAttrs: llvm::AttributeList::get(C&: CGM.getLLVMContext(),
2461 Index: llvm::AttributeList::FunctionIndex,
2462 Kinds: llvm::Attribute::NoUnwind),
2463 /*Local=*/true);
2464}
2465
2466static void emitTlsGuardCheck(CodeGenFunction &CGF, llvm::GlobalValue *TlsGuard,
2467 llvm::BasicBlock *DynInitBB,
2468 llvm::BasicBlock *ContinueBB) {
2469 llvm::LoadInst *TlsGuardValue =
2470 CGF.Builder.CreateLoad(Addr: Address(TlsGuard, CGF.Int8Ty, CharUnits::One()));
2471 llvm::Value *CmpResult =
2472 CGF.Builder.CreateICmpEQ(LHS: TlsGuardValue, RHS: CGF.Builder.getInt8(C: 0));
2473 CGF.Builder.CreateCondBr(Cond: CmpResult, True: DynInitBB, False: ContinueBB);
2474}
2475
2476static void emitDynamicTlsInitializationCall(CodeGenFunction &CGF,
2477 llvm::GlobalValue *TlsGuard,
2478 llvm::BasicBlock *ContinueBB) {
2479 llvm::FunctionCallee Initializer = getDynTlsOnDemandInitFn(CGM&: CGF.CGM);
2480 llvm::Function *InitializerFunction =
2481 cast<llvm::Function>(Val: Initializer.getCallee());
2482 llvm::CallInst *CallVal = CGF.Builder.CreateCall(Callee: InitializerFunction);
2483 CallVal->setCallingConv(InitializerFunction->getCallingConv());
2484
2485 CGF.Builder.CreateBr(Dest: ContinueBB);
2486}
2487
2488static void emitDynamicTlsInitialization(CodeGenFunction &CGF) {
2489 llvm::BasicBlock *DynInitBB =
2490 CGF.createBasicBlock(name: "dyntls.dyn_init", parent: CGF.CurFn);
2491 llvm::BasicBlock *ContinueBB =
2492 CGF.createBasicBlock(name: "dyntls.continue", parent: CGF.CurFn);
2493
2494 llvm::GlobalValue *TlsGuard = getTlsGuardVar(CGM&: CGF.CGM);
2495
2496 emitTlsGuardCheck(CGF, TlsGuard, DynInitBB, ContinueBB);
2497 CGF.Builder.SetInsertPoint(DynInitBB);
2498 emitDynamicTlsInitializationCall(CGF, TlsGuard, ContinueBB);
2499 CGF.Builder.SetInsertPoint(ContinueBB);
2500}
2501
2502LValue MicrosoftCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
2503 const VarDecl *VD,
2504 QualType LValType) {
2505 // Dynamic TLS initialization works by checking the state of a
2506 // guard variable (__tls_guard) to see whether TLS initialization
2507 // for a thread has happend yet.
2508 // If not, the initialization is triggered on-demand
2509 // by calling __dyn_tls_on_demand_init.
2510 emitDynamicTlsInitialization(CGF);
2511
2512 // Emit the variable just like any regular global variable.
2513
2514 llvm::Value *V = CGF.CGM.GetAddrOfGlobalVar(D: VD);
2515 llvm::Type *RealVarTy = CGF.getTypes().ConvertTypeForMem(T: VD->getType());
2516
2517 CharUnits Alignment = CGF.getContext().getDeclAlign(D: VD);
2518 Address Addr(V, RealVarTy, Alignment);
2519
2520 LValue LV = VD->getType()->isReferenceType()
2521 ? CGF.EmitLoadOfReferenceLValue(RefAddr: Addr, RefTy: VD->getType(),
2522 Source: AlignmentSource::Decl)
2523 : CGF.MakeAddrLValue(Addr, T: LValType, Source: AlignmentSource::Decl);
2524 return LV;
2525}
2526
2527static ConstantAddress getInitThreadEpochPtr(CodeGenModule &CGM) {
2528 StringRef VarName("_Init_thread_epoch");
2529 CharUnits Align = CGM.getIntAlign();
2530 if (auto *GV = CGM.getModule().getNamedGlobal(Name: VarName))
2531 return ConstantAddress(GV, GV->getValueType(), Align);
2532 auto *GV = new llvm::GlobalVariable(
2533 CGM.getModule(), CGM.IntTy,
2534 /*isConstant=*/false, llvm::GlobalVariable::ExternalLinkage,
2535 /*Initializer=*/nullptr, VarName,
2536 /*InsertBefore=*/nullptr, llvm::GlobalVariable::GeneralDynamicTLSModel);
2537 GV->setAlignment(Align.getAsAlign());
2538 return ConstantAddress(GV, GV->getValueType(), Align);
2539}
2540
2541static llvm::FunctionCallee getInitThreadHeaderFn(CodeGenModule &CGM) {
2542 llvm::FunctionType *FTy =
2543 llvm::FunctionType::get(Result: llvm::Type::getVoidTy(C&: CGM.getLLVMContext()),
2544 Params: CGM.UnqualPtrTy, /*isVarArg=*/false);
2545 return CGM.CreateRuntimeFunction(
2546 Ty: FTy, Name: "_Init_thread_header",
2547 ExtraAttrs: llvm::AttributeList::get(C&: CGM.getLLVMContext(),
2548 Index: llvm::AttributeList::FunctionIndex,
2549 Kinds: llvm::Attribute::NoUnwind),
2550 /*Local=*/true);
2551}
2552
2553static llvm::FunctionCallee getInitThreadFooterFn(CodeGenModule &CGM) {
2554 llvm::FunctionType *FTy =
2555 llvm::FunctionType::get(Result: llvm::Type::getVoidTy(C&: CGM.getLLVMContext()),
2556 Params: CGM.UnqualPtrTy, /*isVarArg=*/false);
2557 return CGM.CreateRuntimeFunction(
2558 Ty: FTy, Name: "_Init_thread_footer",
2559 ExtraAttrs: llvm::AttributeList::get(C&: CGM.getLLVMContext(),
2560 Index: llvm::AttributeList::FunctionIndex,
2561 Kinds: llvm::Attribute::NoUnwind),
2562 /*Local=*/true);
2563}
2564
2565static llvm::FunctionCallee getInitThreadAbortFn(CodeGenModule &CGM) {
2566 llvm::FunctionType *FTy =
2567 llvm::FunctionType::get(Result: llvm::Type::getVoidTy(C&: CGM.getLLVMContext()),
2568 Params: CGM.UnqualPtrTy, /*isVarArg=*/false);
2569 return CGM.CreateRuntimeFunction(
2570 Ty: FTy, Name: "_Init_thread_abort",
2571 ExtraAttrs: llvm::AttributeList::get(C&: CGM.getLLVMContext(),
2572 Index: llvm::AttributeList::FunctionIndex,
2573 Kinds: llvm::Attribute::NoUnwind),
2574 /*Local=*/true);
2575}
2576
2577namespace {
2578struct ResetGuardBit final : EHScopeStack::Cleanup {
2579 Address Guard;
2580 unsigned GuardNum;
2581 ResetGuardBit(Address Guard, unsigned GuardNum)
2582 : Guard(Guard), GuardNum(GuardNum) {}
2583
2584 void Emit(CodeGenFunction &CGF, Flags flags) override {
2585 // Reset the bit in the mask so that the static variable may be
2586 // reinitialized.
2587 CGBuilderTy &Builder = CGF.Builder;
2588 llvm::LoadInst *LI = Builder.CreateLoad(Addr: Guard);
2589 llvm::ConstantInt *Mask =
2590 llvm::ConstantInt::get(Ty: CGF.IntTy, V: ~(1ULL << GuardNum));
2591 Builder.CreateStore(Val: Builder.CreateAnd(LHS: LI, RHS: Mask), Addr: Guard);
2592 }
2593};
2594
2595struct CallInitThreadAbort final : EHScopeStack::Cleanup {
2596 llvm::Value *Guard;
2597 CallInitThreadAbort(RawAddress Guard) : Guard(Guard.getPointer()) {}
2598
2599 void Emit(CodeGenFunction &CGF, Flags flags) override {
2600 // Calling _Init_thread_abort will reset the guard's state.
2601 CGF.EmitNounwindRuntimeCall(callee: getInitThreadAbortFn(CGM&: CGF.CGM), args: Guard);
2602 }
2603};
2604}
2605
2606void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
2607 llvm::GlobalVariable *GV,
2608 bool PerformInit) {
2609 // MSVC only uses guards for static locals.
2610 if (!D.isStaticLocal()) {
2611 assert(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage());
2612 // GlobalOpt is allowed to discard the initializer, so use linkonce_odr.
2613 llvm::Function *F = CGF.CurFn;
2614 F->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
2615 F->setComdat(CGM.getModule().getOrInsertComdat(Name: F->getName()));
2616 CGF.EmitCXXGlobalVarDeclInit(D, GV, PerformInit);
2617 return;
2618 }
2619
2620 bool ThreadlocalStatic = D.getTLSKind();
2621 bool ThreadsafeStatic = getContext().getLangOpts().ThreadsafeStatics;
2622
2623 // Thread-safe static variables which aren't thread-specific have a
2624 // per-variable guard.
2625 bool HasPerVariableGuard = ThreadsafeStatic && !ThreadlocalStatic;
2626
2627 CGBuilderTy &Builder = CGF.Builder;
2628 llvm::IntegerType *GuardTy = CGF.Int32Ty;
2629 llvm::ConstantInt *Zero = llvm::ConstantInt::get(Ty: GuardTy, V: 0);
2630 CharUnits GuardAlign = CharUnits::fromQuantity(Quantity: 4);
2631
2632 // Get the guard variable for this function if we have one already.
2633 GuardInfo *GI = nullptr;
2634 if (ThreadlocalStatic)
2635 GI = &ThreadLocalGuardVariableMap[D.getDeclContext()];
2636 else if (!ThreadsafeStatic)
2637 GI = &GuardVariableMap[D.getDeclContext()];
2638
2639 llvm::GlobalVariable *GuardVar = GI ? GI->Guard : nullptr;
2640 unsigned GuardNum;
2641 if (D.isExternallyVisible()) {
2642 // Externally visible variables have to be numbered in Sema to properly
2643 // handle unreachable VarDecls.
2644 GuardNum = getContext().getStaticLocalNumber(VD: &D);
2645 assert(GuardNum > 0);
2646 GuardNum--;
2647 } else if (HasPerVariableGuard) {
2648 GuardNum = ThreadSafeGuardNumMap[D.getDeclContext()]++;
2649 } else {
2650 // Non-externally visible variables are numbered here in CodeGen.
2651 GuardNum = GI->BitIndex++;
2652 }
2653
2654 if (!HasPerVariableGuard && GuardNum >= 32) {
2655 if (D.isExternallyVisible())
2656 ErrorUnsupportedABI(CGF, S: "more than 32 guarded initializations");
2657 GuardNum %= 32;
2658 GuardVar = nullptr;
2659 }
2660
2661 if (!GuardVar) {
2662 // Mangle the name for the guard.
2663 SmallString<256> GuardName;
2664 {
2665 llvm::raw_svector_ostream Out(GuardName);
2666 if (HasPerVariableGuard)
2667 getMangleContext().mangleThreadSafeStaticGuardVariable(VD: &D, GuardNum,
2668 Out);
2669 else
2670 getMangleContext().mangleStaticGuardVariable(D: &D, Out);
2671 }
2672
2673 // Create the guard variable with a zero-initializer. Just absorb linkage,
2674 // visibility and dll storage class from the guarded variable.
2675 GuardVar =
2676 new llvm::GlobalVariable(CGM.getModule(), GuardTy, /*isConstant=*/false,
2677 GV->getLinkage(), Zero, GuardName.str());
2678 GuardVar->setVisibility(GV->getVisibility());
2679 GuardVar->setDLLStorageClass(GV->getDLLStorageClass());
2680 GuardVar->setAlignment(GuardAlign.getAsAlign());
2681 if (GuardVar->isWeakForLinker())
2682 GuardVar->setComdat(
2683 CGM.getModule().getOrInsertComdat(Name: GuardVar->getName()));
2684 if (D.getTLSKind())
2685 CGM.setTLSMode(GV: GuardVar, D);
2686 if (GI && !HasPerVariableGuard)
2687 GI->Guard = GuardVar;
2688 }
2689
2690 ConstantAddress GuardAddr(GuardVar, GuardTy, GuardAlign);
2691
2692 assert(GuardVar->getLinkage() == GV->getLinkage() &&
2693 "static local from the same function had different linkage");
2694
2695 if (!HasPerVariableGuard) {
2696 // Pseudo code for the test:
2697 // if (!(GuardVar & MyGuardBit)) {
2698 // GuardVar |= MyGuardBit;
2699 // ... initialize the object ...;
2700 // }
2701
2702 // Test our bit from the guard variable.
2703 llvm::ConstantInt *Bit = llvm::ConstantInt::get(Ty: GuardTy, V: 1ULL << GuardNum);
2704 llvm::LoadInst *LI = Builder.CreateLoad(Addr: GuardAddr);
2705 llvm::Value *NeedsInit =
2706 Builder.CreateICmpEQ(LHS: Builder.CreateAnd(LHS: LI, RHS: Bit), RHS: Zero);
2707 llvm::BasicBlock *InitBlock = CGF.createBasicBlock(name: "init");
2708 llvm::BasicBlock *EndBlock = CGF.createBasicBlock(name: "init.end");
2709 CGF.EmitCXXGuardedInitBranch(NeedsInit, InitBlock, NoInitBlock: EndBlock,
2710 Kind: CodeGenFunction::GuardKind::VariableGuard, D: &D);
2711
2712 // Set our bit in the guard variable and emit the initializer and add a global
2713 // destructor if appropriate.
2714 CGF.EmitBlock(BB: InitBlock);
2715 Builder.CreateStore(Val: Builder.CreateOr(LHS: LI, RHS: Bit), Addr: GuardAddr);
2716 CGF.EHStack.pushCleanup<ResetGuardBit>(Kind: EHCleanup, A: GuardAddr, A: GuardNum);
2717 CGF.EmitCXXGlobalVarDeclInit(D, GV, PerformInit);
2718 CGF.PopCleanupBlock();
2719 Builder.CreateBr(Dest: EndBlock);
2720
2721 // Continue.
2722 CGF.EmitBlock(BB: EndBlock);
2723 } else {
2724 // Pseudo code for the test:
2725 // if (TSS > _Init_thread_epoch) {
2726 // _Init_thread_header(&TSS);
2727 // if (TSS == -1) {
2728 // ... initialize the object ...;
2729 // _Init_thread_footer(&TSS);
2730 // }
2731 // }
2732 //
2733 // The algorithm is almost identical to what can be found in the appendix
2734 // found in N2325.
2735
2736 // This BasicBLock determines whether or not we have any work to do.
2737 llvm::LoadInst *FirstGuardLoad = Builder.CreateLoad(Addr: GuardAddr);
2738 FirstGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2739 llvm::LoadInst *InitThreadEpoch =
2740 Builder.CreateLoad(Addr: getInitThreadEpochPtr(CGM));
2741 llvm::Value *IsUninitialized =
2742 Builder.CreateICmpSGT(LHS: FirstGuardLoad, RHS: InitThreadEpoch);
2743 llvm::BasicBlock *AttemptInitBlock = CGF.createBasicBlock(name: "init.attempt");
2744 llvm::BasicBlock *EndBlock = CGF.createBasicBlock(name: "init.end");
2745 CGF.EmitCXXGuardedInitBranch(NeedsInit: IsUninitialized, InitBlock: AttemptInitBlock, NoInitBlock: EndBlock,
2746 Kind: CodeGenFunction::GuardKind::VariableGuard, D: &D);
2747
2748 // This BasicBlock attempts to determine whether or not this thread is
2749 // responsible for doing the initialization.
2750 CGF.EmitBlock(BB: AttemptInitBlock);
2751 CGF.EmitNounwindRuntimeCall(callee: getInitThreadHeaderFn(CGM),
2752 args: GuardAddr.getPointer());
2753 llvm::LoadInst *SecondGuardLoad = Builder.CreateLoad(Addr: GuardAddr);
2754 SecondGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2755 llvm::Value *ShouldDoInit =
2756 Builder.CreateICmpEQ(LHS: SecondGuardLoad, RHS: getAllOnesInt());
2757 llvm::BasicBlock *InitBlock = CGF.createBasicBlock(name: "init");
2758 Builder.CreateCondBr(Cond: ShouldDoInit, True: InitBlock, False: EndBlock);
2759
2760 // Ok, we ended up getting selected as the initializing thread.
2761 CGF.EmitBlock(BB: InitBlock);
2762 CGF.EHStack.pushCleanup<CallInitThreadAbort>(Kind: EHCleanup, A: GuardAddr);
2763 CGF.EmitCXXGlobalVarDeclInit(D, GV, PerformInit);
2764 CGF.PopCleanupBlock();
2765 CGF.EmitNounwindRuntimeCall(callee: getInitThreadFooterFn(CGM),
2766 args: GuardAddr.getPointer());
2767 Builder.CreateBr(Dest: EndBlock);
2768
2769 CGF.EmitBlock(BB: EndBlock);
2770 }
2771}
2772
2773bool MicrosoftCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
2774 // Null-ness for function memptrs only depends on the first field, which is
2775 // the function pointer. The rest don't matter, so we can zero initialize.
2776 if (MPT->isMemberFunctionPointer())
2777 return true;
2778
2779 // The virtual base adjustment field is always -1 for null, so if we have one
2780 // we can't zero initialize. The field offset is sometimes also -1 if 0 is a
2781 // valid field offset.
2782 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
2783 MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
2784 return (!inheritanceModelHasVBTableOffsetField(Inheritance) &&
2785 RD->nullFieldOffsetIsZero());
2786}
2787
2788llvm::Type *
2789MicrosoftCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
2790 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
2791 MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
2792 llvm::SmallVector<llvm::Type *, 4> fields;
2793 if (MPT->isMemberFunctionPointer())
2794 fields.push_back(Elt: CGM.VoidPtrTy); // FunctionPointerOrVirtualThunk
2795 else
2796 fields.push_back(Elt: CGM.IntTy); // FieldOffset
2797
2798 if (inheritanceModelHasNVOffsetField(IsMemberFunction: MPT->isMemberFunctionPointer(),
2799 Inheritance))
2800 fields.push_back(Elt: CGM.IntTy);
2801 if (inheritanceModelHasVBPtrOffsetField(Inheritance))
2802 fields.push_back(Elt: CGM.IntTy);
2803 if (inheritanceModelHasVBTableOffsetField(Inheritance))
2804 fields.push_back(Elt: CGM.IntTy); // VirtualBaseAdjustmentOffset
2805
2806 if (fields.size() == 1)
2807 return fields[0];
2808 return llvm::StructType::get(Context&: CGM.getLLVMContext(), Elements: fields);
2809}
2810
2811void MicrosoftCXXABI::
2812GetNullMemberPointerFields(const MemberPointerType *MPT,
2813 llvm::SmallVectorImpl<llvm::Constant *> &fields) {
2814 assert(fields.empty());
2815 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
2816 MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
2817 if (MPT->isMemberFunctionPointer()) {
2818 // FunctionPointerOrVirtualThunk
2819 fields.push_back(Elt: llvm::Constant::getNullValue(Ty: CGM.VoidPtrTy));
2820 } else {
2821 if (RD->nullFieldOffsetIsZero())
2822 fields.push_back(Elt: getZeroInt()); // FieldOffset
2823 else
2824 fields.push_back(Elt: getAllOnesInt()); // FieldOffset
2825 }
2826
2827 if (inheritanceModelHasNVOffsetField(IsMemberFunction: MPT->isMemberFunctionPointer(),
2828 Inheritance))
2829 fields.push_back(Elt: getZeroInt());
2830 if (inheritanceModelHasVBPtrOffsetField(Inheritance))
2831 fields.push_back(Elt: getZeroInt());
2832 if (inheritanceModelHasVBTableOffsetField(Inheritance))
2833 fields.push_back(Elt: getAllOnesInt());
2834}
2835
2836llvm::Constant *
2837MicrosoftCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
2838 llvm::SmallVector<llvm::Constant *, 4> fields;
2839 GetNullMemberPointerFields(MPT, fields);
2840 if (fields.size() == 1)
2841 return fields[0];
2842 llvm::Constant *Res = llvm::ConstantStruct::getAnon(V: fields);
2843 assert(Res->getType() == ConvertMemberPointerType(MPT));
2844 return Res;
2845}
2846
2847llvm::Constant *
2848MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
2849 bool IsMemberFunction,
2850 const CXXRecordDecl *RD,
2851 CharUnits NonVirtualBaseAdjustment,
2852 unsigned VBTableIndex) {
2853 MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
2854
2855 // Single inheritance class member pointer are represented as scalars instead
2856 // of aggregates.
2857 if (inheritanceModelHasOnlyOneField(IsMemberFunction, Inheritance))
2858 return FirstField;
2859
2860 llvm::SmallVector<llvm::Constant *, 4> fields;
2861 fields.push_back(Elt: FirstField);
2862
2863 if (inheritanceModelHasNVOffsetField(IsMemberFunction, Inheritance))
2864 fields.push_back(Elt: llvm::ConstantInt::get(
2865 Ty: CGM.IntTy, V: NonVirtualBaseAdjustment.getQuantity()));
2866
2867 if (inheritanceModelHasVBPtrOffsetField(Inheritance)) {
2868 CharUnits Offs = CharUnits::Zero();
2869 if (VBTableIndex)
2870 Offs = getContext().getASTRecordLayout(D: RD).getVBPtrOffset();
2871 fields.push_back(Elt: llvm::ConstantInt::get(Ty: CGM.IntTy, V: Offs.getQuantity()));
2872 }
2873
2874 // The rest of the fields are adjusted by conversions to a more derived class.
2875 if (inheritanceModelHasVBTableOffsetField(Inheritance))
2876 fields.push_back(Elt: llvm::ConstantInt::get(Ty: CGM.IntTy, V: VBTableIndex));
2877
2878 return llvm::ConstantStruct::getAnon(V: fields);
2879}
2880
2881llvm::Constant *
2882MicrosoftCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
2883 CharUnits offset) {
2884 return EmitMemberDataPointer(RD: MPT->getMostRecentCXXRecordDecl(), offset);
2885}
2886
2887llvm::Constant *MicrosoftCXXABI::EmitMemberDataPointer(const CXXRecordDecl *RD,
2888 CharUnits offset) {
2889 if (RD->getMSInheritanceModel() ==
2890 MSInheritanceModel::Virtual)
2891 offset -= getContext().getOffsetOfBaseWithVBPtr(RD);
2892 llvm::Constant *FirstField =
2893 llvm::ConstantInt::get(Ty: CGM.IntTy, V: offset.getQuantity());
2894 return EmitFullMemberPointer(FirstField, /*IsMemberFunction=*/false, RD,
2895 NonVirtualBaseAdjustment: CharUnits::Zero(), /*VBTableIndex=*/0);
2896}
2897
2898llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(const APValue &MP,
2899 QualType MPType) {
2900 const MemberPointerType *DstTy = MPType->castAs<MemberPointerType>();
2901 const ValueDecl *MPD = MP.getMemberPointerDecl();
2902 if (!MPD)
2903 return EmitNullMemberPointer(MPT: DstTy);
2904
2905 ASTContext &Ctx = getContext();
2906 ArrayRef<const CXXRecordDecl *> MemberPointerPath = MP.getMemberPointerPath();
2907
2908 llvm::Constant *C;
2909 if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Val: MPD)) {
2910 C = EmitMemberFunctionPointer(MD);
2911 } else {
2912 // For a pointer to data member, start off with the offset of the field in
2913 // the class in which it was declared, and convert from there if necessary.
2914 // For indirect field decls, get the outermost anonymous field and use the
2915 // parent class.
2916 CharUnits FieldOffset = Ctx.toCharUnitsFromBits(BitSize: Ctx.getFieldOffset(FD: MPD));
2917 const FieldDecl *FD = dyn_cast<FieldDecl>(Val: MPD);
2918 if (!FD)
2919 FD = cast<FieldDecl>(Val: *cast<IndirectFieldDecl>(Val: MPD)->chain_begin());
2920 const CXXRecordDecl *RD = cast<CXXRecordDecl>(Val: FD->getParent());
2921 RD = RD->getMostRecentNonInjectedDecl();
2922 C = EmitMemberDataPointer(RD, offset: FieldOffset);
2923 }
2924
2925 if (!MemberPointerPath.empty()) {
2926 const CXXRecordDecl *SrcRD = cast<CXXRecordDecl>(Val: MPD->getDeclContext());
2927 const MemberPointerType *SrcTy =
2928 Ctx.getMemberPointerType(T: DstTy->getPointeeType(), /*Qualifier=*/nullptr,
2929 Cls: SrcRD)
2930 ->castAs<MemberPointerType>();
2931
2932 bool DerivedMember = MP.isMemberPointerToDerivedMember();
2933 SmallVector<const CXXBaseSpecifier *, 4> DerivedToBasePath;
2934 const CXXRecordDecl *PrevRD = SrcRD;
2935 for (const CXXRecordDecl *PathElem : MemberPointerPath) {
2936 const CXXRecordDecl *Base = nullptr;
2937 const CXXRecordDecl *Derived = nullptr;
2938 if (DerivedMember) {
2939 Base = PathElem;
2940 Derived = PrevRD;
2941 } else {
2942 Base = PrevRD;
2943 Derived = PathElem;
2944 }
2945 for (const CXXBaseSpecifier &BS : Derived->bases())
2946 if (BS.getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
2947 Base->getCanonicalDecl())
2948 DerivedToBasePath.push_back(Elt: &BS);
2949 PrevRD = PathElem;
2950 }
2951 assert(DerivedToBasePath.size() == MemberPointerPath.size());
2952
2953 CastKind CK = DerivedMember ? CK_DerivedToBaseMemberPointer
2954 : CK_BaseToDerivedMemberPointer;
2955 C = EmitMemberPointerConversion(SrcTy, DstTy, CK, PathBegin: DerivedToBasePath.begin(),
2956 PathEnd: DerivedToBasePath.end(), Src: C);
2957 }
2958 return C;
2959}
2960
2961llvm::Constant *
2962MicrosoftCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) {
2963 assert(MD->isInstance() && "Member function must not be static!");
2964
2965 CharUnits NonVirtualBaseAdjustment = CharUnits::Zero();
2966 const CXXRecordDecl *RD = MD->getParent()->getMostRecentNonInjectedDecl();
2967 CodeGenTypes &Types = CGM.getTypes();
2968
2969 unsigned VBTableIndex = 0;
2970 llvm::Constant *FirstField;
2971 const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
2972 if (!MD->isVirtual()) {
2973 llvm::Type *Ty;
2974 // Check whether the function has a computable LLVM signature.
2975 if (Types.isFuncTypeConvertible(FT: FPT)) {
2976 // The function has a computable LLVM signature; use the correct type.
2977 Ty = Types.GetFunctionType(Info: Types.arrangeCXXMethodDeclaration(MD));
2978 } else {
2979 // Use an arbitrary non-function type to tell GetAddrOfFunction that the
2980 // function type is incomplete.
2981 Ty = CGM.PtrDiffTy;
2982 }
2983 FirstField = CGM.GetAddrOfFunction(GD: MD, Ty);
2984 } else {
2985 auto &VTableContext = CGM.getMicrosoftVTableContext();
2986 MethodVFTableLocation ML = VTableContext.getMethodVFTableLocation(GD: MD);
2987 FirstField = EmitVirtualMemPtrThunk(MD, ML);
2988 // Include the vfptr adjustment if the method is in a non-primary vftable.
2989 NonVirtualBaseAdjustment += ML.VFPtrOffset;
2990 if (ML.VBase)
2991 VBTableIndex = VTableContext.getVBTableIndex(Derived: RD, VBase: ML.VBase) * 4;
2992 }
2993
2994 if (VBTableIndex == 0 &&
2995 RD->getMSInheritanceModel() ==
2996 MSInheritanceModel::Virtual)
2997 NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD);
2998
2999 // The rest of the fields are common with data member pointers.
3000 return EmitFullMemberPointer(FirstField, /*IsMemberFunction=*/true, RD,
3001 NonVirtualBaseAdjustment, VBTableIndex);
3002}
3003
3004/// Member pointers are the same if they're either bitwise identical *or* both
3005/// null. Null-ness for function members is determined by the first field,
3006/// while for data member pointers we must compare all fields.
3007llvm::Value *
3008MicrosoftCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
3009 llvm::Value *L,
3010 llvm::Value *R,
3011 const MemberPointerType *MPT,
3012 bool Inequality) {
3013 CGBuilderTy &Builder = CGF.Builder;
3014
3015 // Handle != comparisons by switching the sense of all boolean operations.
3016 llvm::ICmpInst::Predicate Eq;
3017 llvm::Instruction::BinaryOps And, Or;
3018 if (Inequality) {
3019 Eq = llvm::ICmpInst::ICMP_NE;
3020 And = llvm::Instruction::Or;
3021 Or = llvm::Instruction::And;
3022 } else {
3023 Eq = llvm::ICmpInst::ICMP_EQ;
3024 And = llvm::Instruction::And;
3025 Or = llvm::Instruction::Or;
3026 }
3027
3028 // If this is a single field member pointer (single inheritance), this is a
3029 // single icmp.
3030 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
3031 MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
3032 if (inheritanceModelHasOnlyOneField(IsMemberFunction: MPT->isMemberFunctionPointer(),
3033 Inheritance))
3034 return Builder.CreateICmp(P: Eq, LHS: L, RHS: R);
3035
3036 // Compare the first field.
3037 llvm::Value *L0 = Builder.CreateExtractValue(Agg: L, Idxs: 0, Name: "lhs.0");
3038 llvm::Value *R0 = Builder.CreateExtractValue(Agg: R, Idxs: 0, Name: "rhs.0");
3039 llvm::Value *Cmp0 = Builder.CreateICmp(P: Eq, LHS: L0, RHS: R0, Name: "memptr.cmp.first");
3040
3041 // Compare everything other than the first field.
3042 llvm::Value *Res = nullptr;
3043 llvm::StructType *LType = cast<llvm::StructType>(Val: L->getType());
3044 for (unsigned I = 1, E = LType->getNumElements(); I != E; ++I) {
3045 llvm::Value *LF = Builder.CreateExtractValue(Agg: L, Idxs: I);
3046 llvm::Value *RF = Builder.CreateExtractValue(Agg: R, Idxs: I);
3047 llvm::Value *Cmp = Builder.CreateICmp(P: Eq, LHS: LF, RHS: RF, Name: "memptr.cmp.rest");
3048 if (Res)
3049 Res = Builder.CreateBinOp(Opc: And, LHS: Res, RHS: Cmp);
3050 else
3051 Res = Cmp;
3052 }
3053
3054 // Check if the first field is 0 if this is a function pointer.
3055 if (MPT->isMemberFunctionPointer()) {
3056 // (l1 == r1 && ...) || l0 == 0
3057 llvm::Value *Zero = llvm::Constant::getNullValue(Ty: L0->getType());
3058 llvm::Value *IsZero = Builder.CreateICmp(P: Eq, LHS: L0, RHS: Zero, Name: "memptr.cmp.iszero");
3059 Res = Builder.CreateBinOp(Opc: Or, LHS: Res, RHS: IsZero);
3060 }
3061
3062 // Combine the comparison of the first field, which must always be true for
3063 // this comparison to succeeed.
3064 return Builder.CreateBinOp(Opc: And, LHS: Res, RHS: Cmp0, Name: "memptr.cmp");
3065}
3066
3067llvm::Value *
3068MicrosoftCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
3069 llvm::Value *MemPtr,
3070 const MemberPointerType *MPT) {
3071 CGBuilderTy &Builder = CGF.Builder;
3072 llvm::SmallVector<llvm::Constant *, 4> fields;
3073 // We only need one field for member functions.
3074 if (MPT->isMemberFunctionPointer())
3075 fields.push_back(Elt: llvm::Constant::getNullValue(Ty: CGM.VoidPtrTy));
3076 else
3077 GetNullMemberPointerFields(MPT, fields);
3078 assert(!fields.empty());
3079 llvm::Value *FirstField = MemPtr;
3080 if (MemPtr->getType()->isStructTy())
3081 FirstField = Builder.CreateExtractValue(Agg: MemPtr, Idxs: 0);
3082 llvm::Value *Res = Builder.CreateICmpNE(LHS: FirstField, RHS: fields[0], Name: "memptr.cmp0");
3083
3084 // For function member pointers, we only need to test the function pointer
3085 // field. The other fields if any can be garbage.
3086 if (MPT->isMemberFunctionPointer())
3087 return Res;
3088
3089 // Otherwise, emit a series of compares and combine the results.
3090 for (int I = 1, E = fields.size(); I < E; ++I) {
3091 llvm::Value *Field = Builder.CreateExtractValue(Agg: MemPtr, Idxs: I);
3092 llvm::Value *Next = Builder.CreateICmpNE(LHS: Field, RHS: fields[I], Name: "memptr.cmp");
3093 Res = Builder.CreateOr(LHS: Res, RHS: Next, Name: "memptr.tobool");
3094 }
3095 return Res;
3096}
3097
3098bool MicrosoftCXXABI::MemberPointerConstantIsNull(const MemberPointerType *MPT,
3099 llvm::Constant *Val) {
3100 // Function pointers are null if the pointer in the first field is null.
3101 if (MPT->isMemberFunctionPointer()) {
3102 llvm::Constant *FirstField = Val->getType()->isStructTy() ?
3103 Val->getAggregateElement(Elt: 0U) : Val;
3104 return FirstField->isNullValue();
3105 }
3106
3107 // If it's not a function pointer and it's zero initializable, we can easily
3108 // check zero.
3109 if (isZeroInitializable(MPT) && Val->isNullValue())
3110 return true;
3111
3112 // Otherwise, break down all the fields for comparison. Hopefully these
3113 // little Constants are reused, while a big null struct might not be.
3114 llvm::SmallVector<llvm::Constant *, 4> Fields;
3115 GetNullMemberPointerFields(MPT, fields&: Fields);
3116 if (Fields.size() == 1) {
3117 assert(Val->getType()->isIntegerTy());
3118 return Val == Fields[0];
3119 }
3120
3121 unsigned I, E;
3122 for (I = 0, E = Fields.size(); I != E; ++I) {
3123 if (Val->getAggregateElement(Elt: I) != Fields[I])
3124 break;
3125 }
3126 return I == E;
3127}
3128
3129llvm::Value *
3130MicrosoftCXXABI::GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF,
3131 Address This,
3132 llvm::Value *VBPtrOffset,
3133 llvm::Value *VBTableOffset,
3134 llvm::Value **VBPtrOut) {
3135 CGBuilderTy &Builder = CGF.Builder;
3136 // Load the vbtable pointer from the vbptr in the instance.
3137 llvm::Value *VBPtr = Builder.CreateInBoundsGEP(
3138 Ty: CGM.Int8Ty, Ptr: This.emitRawPointer(CGF), IdxList: VBPtrOffset, Name: "vbptr");
3139 if (VBPtrOut)
3140 *VBPtrOut = VBPtr;
3141
3142 CharUnits VBPtrAlign;
3143 if (auto CI = dyn_cast<llvm::ConstantInt>(Val: VBPtrOffset)) {
3144 VBPtrAlign = This.getAlignment().alignmentAtOffset(
3145 offset: CharUnits::fromQuantity(Quantity: CI->getSExtValue()));
3146 } else {
3147 VBPtrAlign = CGF.getPointerAlign();
3148 }
3149
3150 llvm::Value *VBTable =
3151 Builder.CreateAlignedLoad(Ty: CGM.UnqualPtrTy, Addr: VBPtr, Align: VBPtrAlign, Name: "vbtable");
3152
3153 // Translate from byte offset to table index. It improves analyzability.
3154 llvm::Value *VBTableIndex = Builder.CreateAShr(
3155 LHS: VBTableOffset, RHS: llvm::ConstantInt::get(Ty: VBTableOffset->getType(), V: 2),
3156 Name: "vbtindex", /*isExact=*/true);
3157
3158 // Load an i32 offset from the vb-table.
3159 llvm::Value *VBaseOffs =
3160 Builder.CreateInBoundsGEP(Ty: CGM.Int32Ty, Ptr: VBTable, IdxList: VBTableIndex);
3161 return Builder.CreateAlignedLoad(Ty: CGM.Int32Ty, Addr: VBaseOffs,
3162 Align: CharUnits::fromQuantity(Quantity: 4), Name: "vbase_offs");
3163}
3164
3165// Returns an adjusted base cast to i8*, since we do more address arithmetic on
3166// it.
3167llvm::Value *MicrosoftCXXABI::AdjustVirtualBase(
3168 CodeGenFunction &CGF, const Expr *E, const CXXRecordDecl *RD,
3169 Address Base, llvm::Value *VBTableOffset, llvm::Value *VBPtrOffset) {
3170 CGBuilderTy &Builder = CGF.Builder;
3171 Base = Base.withElementType(ElemTy: CGM.Int8Ty);
3172 llvm::BasicBlock *OriginalBB = nullptr;
3173 llvm::BasicBlock *SkipAdjustBB = nullptr;
3174 llvm::BasicBlock *VBaseAdjustBB = nullptr;
3175
3176 // In the unspecified inheritance model, there might not be a vbtable at all,
3177 // in which case we need to skip the virtual base lookup. If there is a
3178 // vbtable, the first entry is a no-op entry that gives back the original
3179 // base, so look for a virtual base adjustment offset of zero.
3180 if (VBPtrOffset) {
3181 OriginalBB = Builder.GetInsertBlock();
3182 VBaseAdjustBB = CGF.createBasicBlock(name: "memptr.vadjust");
3183 SkipAdjustBB = CGF.createBasicBlock(name: "memptr.skip_vadjust");
3184 llvm::Value *IsVirtual =
3185 Builder.CreateICmpNE(LHS: VBTableOffset, RHS: getZeroInt(),
3186 Name: "memptr.is_vbase");
3187 Builder.CreateCondBr(Cond: IsVirtual, True: VBaseAdjustBB, False: SkipAdjustBB);
3188 CGF.EmitBlock(BB: VBaseAdjustBB);
3189 }
3190
3191 // If we weren't given a dynamic vbptr offset, RD should be complete and we'll
3192 // know the vbptr offset.
3193 if (!VBPtrOffset) {
3194 CharUnits offs = CharUnits::Zero();
3195 if (!RD->hasDefinition()) {
3196 DiagnosticsEngine &Diags = CGF.CGM.getDiags();
3197 unsigned DiagID = Diags.getCustomDiagID(
3198 L: DiagnosticsEngine::Error,
3199 FormatString: "member pointer representation requires a "
3200 "complete class type for %0 to perform this expression");
3201 Diags.Report(Loc: E->getExprLoc(), DiagID) << RD << E->getSourceRange();
3202 } else if (RD->getNumVBases())
3203 offs = getContext().getASTRecordLayout(D: RD).getVBPtrOffset();
3204 VBPtrOffset = llvm::ConstantInt::get(Ty: CGM.IntTy, V: offs.getQuantity());
3205 }
3206 llvm::Value *VBPtr = nullptr;
3207 llvm::Value *VBaseOffs =
3208 GetVBaseOffsetFromVBPtr(CGF, This: Base, VBPtrOffset, VBTableOffset, VBPtrOut: &VBPtr);
3209 llvm::Value *AdjustedBase =
3210 Builder.CreateInBoundsGEP(Ty: CGM.Int8Ty, Ptr: VBPtr, IdxList: VBaseOffs);
3211
3212 // Merge control flow with the case where we didn't have to adjust.
3213 if (VBaseAdjustBB) {
3214 Builder.CreateBr(Dest: SkipAdjustBB);
3215 CGF.EmitBlock(BB: SkipAdjustBB);
3216 llvm::PHINode *Phi = Builder.CreatePHI(Ty: CGM.Int8PtrTy, NumReservedValues: 2, Name: "memptr.base");
3217 Phi->addIncoming(V: Base.emitRawPointer(CGF), BB: OriginalBB);
3218 Phi->addIncoming(V: AdjustedBase, BB: VBaseAdjustBB);
3219 return Phi;
3220 }
3221 return AdjustedBase;
3222}
3223
3224llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
3225 CodeGenFunction &CGF, const Expr *E, Address Base, llvm::Value *MemPtr,
3226 const MemberPointerType *MPT, bool IsInBounds) {
3227 assert(MPT->isMemberDataPointer());
3228 CGBuilderTy &Builder = CGF.Builder;
3229 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
3230 MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
3231
3232 // Extract the fields we need, regardless of model. We'll apply them if we
3233 // have them.
3234 llvm::Value *FieldOffset = MemPtr;
3235 llvm::Value *VirtualBaseAdjustmentOffset = nullptr;
3236 llvm::Value *VBPtrOffset = nullptr;
3237 if (MemPtr->getType()->isStructTy()) {
3238 // We need to extract values.
3239 unsigned I = 0;
3240 FieldOffset = Builder.CreateExtractValue(Agg: MemPtr, Idxs: I++);
3241 if (inheritanceModelHasVBPtrOffsetField(Inheritance))
3242 VBPtrOffset = Builder.CreateExtractValue(Agg: MemPtr, Idxs: I++);
3243 if (inheritanceModelHasVBTableOffsetField(Inheritance))
3244 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Agg: MemPtr, Idxs: I++);
3245 }
3246
3247 llvm::Value *Addr;
3248 if (VirtualBaseAdjustmentOffset) {
3249 Addr = AdjustVirtualBase(CGF, E, RD, Base, VBTableOffset: VirtualBaseAdjustmentOffset,
3250 VBPtrOffset);
3251 } else {
3252 Addr = Base.emitRawPointer(CGF);
3253 }
3254
3255 // Apply the offset.
3256 return Builder.CreateGEP(Ty: CGF.Int8Ty, Ptr: Addr, IdxList: FieldOffset, Name: "memptr.offset",
3257 NW: IsInBounds ? llvm::GEPNoWrapFlags::inBounds()
3258 : llvm::GEPNoWrapFlags::none());
3259}
3260
3261llvm::Value *
3262MicrosoftCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
3263 const CastExpr *E,
3264 llvm::Value *Src) {
3265 assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
3266 E->getCastKind() == CK_BaseToDerivedMemberPointer ||
3267 E->getCastKind() == CK_ReinterpretMemberPointer);
3268
3269 // Use constant emission if we can.
3270 if (isa<llvm::Constant>(Val: Src))
3271 return EmitMemberPointerConversion(E, Src: cast<llvm::Constant>(Val: Src));
3272
3273 // We may be adding or dropping fields from the member pointer, so we need
3274 // both types and the inheritance models of both records.
3275 const MemberPointerType *SrcTy =
3276 E->getSubExpr()->getType()->castAs<MemberPointerType>();
3277 const MemberPointerType *DstTy = E->getType()->castAs<MemberPointerType>();
3278 bool IsFunc = SrcTy->isMemberFunctionPointer();
3279
3280 // If the classes use the same null representation, reinterpret_cast is a nop.
3281 bool IsReinterpret = E->getCastKind() == CK_ReinterpretMemberPointer;
3282 if (IsReinterpret && IsFunc)
3283 return Src;
3284
3285 CXXRecordDecl *SrcRD = SrcTy->getMostRecentCXXRecordDecl();
3286 CXXRecordDecl *DstRD = DstTy->getMostRecentCXXRecordDecl();
3287 if (IsReinterpret &&
3288 SrcRD->nullFieldOffsetIsZero() == DstRD->nullFieldOffsetIsZero())
3289 return Src;
3290
3291 CGBuilderTy &Builder = CGF.Builder;
3292
3293 // Branch past the conversion if Src is null.
3294 llvm::Value *IsNotNull = EmitMemberPointerIsNotNull(CGF, MemPtr: Src, MPT: SrcTy);
3295 llvm::Constant *DstNull = EmitNullMemberPointer(MPT: DstTy);
3296
3297 // C++ 5.2.10p9: The null member pointer value is converted to the null member
3298 // pointer value of the destination type.
3299 if (IsReinterpret) {
3300 // For reinterpret casts, sema ensures that src and dst are both functions
3301 // or data and have the same size, which means the LLVM types should match.
3302 assert(Src->getType() == DstNull->getType());
3303 return Builder.CreateSelect(C: IsNotNull, True: Src, False: DstNull);
3304 }
3305
3306 llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock();
3307 llvm::BasicBlock *ConvertBB = CGF.createBasicBlock(name: "memptr.convert");
3308 llvm::BasicBlock *ContinueBB = CGF.createBasicBlock(name: "memptr.converted");
3309 Builder.CreateCondBr(Cond: IsNotNull, True: ConvertBB, False: ContinueBB);
3310 CGF.EmitBlock(BB: ConvertBB);
3311
3312 llvm::Value *Dst = EmitNonNullMemberPointerConversion(
3313 SrcTy, DstTy, CK: E->getCastKind(), PathBegin: E->path_begin(), PathEnd: E->path_end(), Src,
3314 Builder);
3315
3316 Builder.CreateBr(Dest: ContinueBB);
3317
3318 // In the continuation, choose between DstNull and Dst.
3319 CGF.EmitBlock(BB: ContinueBB);
3320 llvm::PHINode *Phi = Builder.CreatePHI(Ty: DstNull->getType(), NumReservedValues: 2, Name: "memptr.converted");
3321 Phi->addIncoming(V: DstNull, BB: OriginalBB);
3322 Phi->addIncoming(V: Dst, BB: ConvertBB);
3323 return Phi;
3324}
3325
3326llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
3327 const MemberPointerType *SrcTy, const MemberPointerType *DstTy, CastKind CK,
3328 CastExpr::path_const_iterator PathBegin,
3329 CastExpr::path_const_iterator PathEnd, llvm::Value *Src,
3330 CGBuilderTy &Builder) {
3331 const CXXRecordDecl *SrcRD = SrcTy->getMostRecentCXXRecordDecl();
3332 const CXXRecordDecl *DstRD = DstTy->getMostRecentCXXRecordDecl();
3333 MSInheritanceModel SrcInheritance = SrcRD->getMSInheritanceModel();
3334 MSInheritanceModel DstInheritance = DstRD->getMSInheritanceModel();
3335 bool IsFunc = SrcTy->isMemberFunctionPointer();
3336 bool IsConstant = isa<llvm::Constant>(Val: Src);
3337
3338 // Decompose src.
3339 llvm::Value *FirstField = Src;
3340 llvm::Value *NonVirtualBaseAdjustment = getZeroInt();
3341 llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt();
3342 llvm::Value *VBPtrOffset = getZeroInt();
3343 if (!inheritanceModelHasOnlyOneField(IsMemberFunction: IsFunc, Inheritance: SrcInheritance)) {
3344 // We need to extract values.
3345 unsigned I = 0;
3346 FirstField = Builder.CreateExtractValue(Agg: Src, Idxs: I++);
3347 if (inheritanceModelHasNVOffsetField(IsMemberFunction: IsFunc, Inheritance: SrcInheritance))
3348 NonVirtualBaseAdjustment = Builder.CreateExtractValue(Agg: Src, Idxs: I++);
3349 if (inheritanceModelHasVBPtrOffsetField(Inheritance: SrcInheritance))
3350 VBPtrOffset = Builder.CreateExtractValue(Agg: Src, Idxs: I++);
3351 if (inheritanceModelHasVBTableOffsetField(Inheritance: SrcInheritance))
3352 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Agg: Src, Idxs: I++);
3353 }
3354
3355 bool IsDerivedToBase = (CK == CK_DerivedToBaseMemberPointer);
3356 const MemberPointerType *DerivedTy = IsDerivedToBase ? SrcTy : DstTy;
3357 const CXXRecordDecl *DerivedClass = DerivedTy->getMostRecentCXXRecordDecl();
3358
3359 // For data pointers, we adjust the field offset directly. For functions, we
3360 // have a separate field.
3361 llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField;
3362
3363 // The virtual inheritance model has a quirk: the virtual base table is always
3364 // referenced when dereferencing a member pointer even if the member pointer
3365 // is non-virtual. This is accounted for by adjusting the non-virtual offset
3366 // to point backwards to the top of the MDC from the first VBase. Undo this
3367 // adjustment to normalize the member pointer.
3368 llvm::Value *SrcVBIndexEqZero =
3369 Builder.CreateICmpEQ(LHS: VirtualBaseAdjustmentOffset, RHS: getZeroInt());
3370 if (SrcInheritance == MSInheritanceModel::Virtual) {
3371 if (int64_t SrcOffsetToFirstVBase =
3372 getContext().getOffsetOfBaseWithVBPtr(RD: SrcRD).getQuantity()) {
3373 llvm::Value *UndoSrcAdjustment = Builder.CreateSelect(
3374 C: SrcVBIndexEqZero,
3375 True: llvm::ConstantInt::get(Ty: CGM.IntTy, V: SrcOffsetToFirstVBase),
3376 False: getZeroInt());
3377 NVAdjustField = Builder.CreateNSWAdd(LHS: NVAdjustField, RHS: UndoSrcAdjustment);
3378 }
3379 }
3380
3381 // A non-zero vbindex implies that we are dealing with a source member in a
3382 // floating virtual base in addition to some non-virtual offset. If the
3383 // vbindex is zero, we are dealing with a source that exists in a non-virtual,
3384 // fixed, base. The difference between these two cases is that the vbindex +
3385 // nvoffset *always* point to the member regardless of what context they are
3386 // evaluated in so long as the vbindex is adjusted. A member inside a fixed
3387 // base requires explicit nv adjustment.
3388 llvm::Constant *BaseClassOffset = llvm::ConstantInt::get(
3389 Ty: CGM.IntTy,
3390 V: CGM.computeNonVirtualBaseClassOffset(DerivedClass, Start: PathBegin, End: PathEnd)
3391 .getQuantity());
3392
3393 llvm::Value *NVDisp;
3394 if (IsDerivedToBase)
3395 NVDisp = Builder.CreateNSWSub(LHS: NVAdjustField, RHS: BaseClassOffset, Name: "adj");
3396 else
3397 NVDisp = Builder.CreateNSWAdd(LHS: NVAdjustField, RHS: BaseClassOffset, Name: "adj");
3398
3399 NVAdjustField = Builder.CreateSelect(C: SrcVBIndexEqZero, True: NVDisp, False: getZeroInt());
3400
3401 // Update the vbindex to an appropriate value in the destination because
3402 // SrcRD's vbtable might not be a strict prefix of the one in DstRD.
3403 llvm::Value *DstVBIndexEqZero = SrcVBIndexEqZero;
3404 if (inheritanceModelHasVBTableOffsetField(Inheritance: DstInheritance) &&
3405 inheritanceModelHasVBTableOffsetField(Inheritance: SrcInheritance)) {
3406 if (llvm::GlobalVariable *VDispMap =
3407 getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) {
3408 llvm::Value *VBIndex = Builder.CreateExactUDiv(
3409 LHS: VirtualBaseAdjustmentOffset, RHS: llvm::ConstantInt::get(Ty: CGM.IntTy, V: 4));
3410 if (IsConstant) {
3411 llvm::Constant *Mapping = VDispMap->getInitializer();
3412 VirtualBaseAdjustmentOffset =
3413 Mapping->getAggregateElement(Elt: cast<llvm::Constant>(Val: VBIndex));
3414 } else {
3415 llvm::Value *Idxs[] = {getZeroInt(), VBIndex};
3416 VirtualBaseAdjustmentOffset = Builder.CreateAlignedLoad(
3417 Ty: CGM.IntTy, Addr: Builder.CreateInBoundsGEP(Ty: VDispMap->getValueType(),
3418 Ptr: VDispMap, IdxList: Idxs),
3419 Align: CharUnits::fromQuantity(Quantity: 4));
3420 }
3421
3422 DstVBIndexEqZero =
3423 Builder.CreateICmpEQ(LHS: VirtualBaseAdjustmentOffset, RHS: getZeroInt());
3424 }
3425 }
3426
3427 // Set the VBPtrOffset to zero if the vbindex is zero. Otherwise, initialize
3428 // it to the offset of the vbptr.
3429 if (inheritanceModelHasVBPtrOffsetField(Inheritance: DstInheritance)) {
3430 llvm::Value *DstVBPtrOffset = llvm::ConstantInt::get(
3431 Ty: CGM.IntTy,
3432 V: getContext().getASTRecordLayout(D: DstRD).getVBPtrOffset().getQuantity());
3433 VBPtrOffset =
3434 Builder.CreateSelect(C: DstVBIndexEqZero, True: getZeroInt(), False: DstVBPtrOffset);
3435 }
3436
3437 // Likewise, apply a similar adjustment so that dereferencing the member
3438 // pointer correctly accounts for the distance between the start of the first
3439 // virtual base and the top of the MDC.
3440 if (DstInheritance == MSInheritanceModel::Virtual) {
3441 if (int64_t DstOffsetToFirstVBase =
3442 getContext().getOffsetOfBaseWithVBPtr(RD: DstRD).getQuantity()) {
3443 llvm::Value *DoDstAdjustment = Builder.CreateSelect(
3444 C: DstVBIndexEqZero,
3445 True: llvm::ConstantInt::get(Ty: CGM.IntTy, V: DstOffsetToFirstVBase),
3446 False: getZeroInt());
3447 NVAdjustField = Builder.CreateNSWSub(LHS: NVAdjustField, RHS: DoDstAdjustment);
3448 }
3449 }
3450
3451 // Recompose dst from the null struct and the adjusted fields from src.
3452 llvm::Value *Dst;
3453 if (inheritanceModelHasOnlyOneField(IsMemberFunction: IsFunc, Inheritance: DstInheritance)) {
3454 Dst = FirstField;
3455 } else {
3456 Dst = llvm::PoisonValue::get(T: ConvertMemberPointerType(MPT: DstTy));
3457 unsigned Idx = 0;
3458 Dst = Builder.CreateInsertValue(Agg: Dst, Val: FirstField, Idxs: Idx++);
3459 if (inheritanceModelHasNVOffsetField(IsMemberFunction: IsFunc, Inheritance: DstInheritance))
3460 Dst = Builder.CreateInsertValue(Agg: Dst, Val: NonVirtualBaseAdjustment, Idxs: Idx++);
3461 if (inheritanceModelHasVBPtrOffsetField(Inheritance: DstInheritance))
3462 Dst = Builder.CreateInsertValue(Agg: Dst, Val: VBPtrOffset, Idxs: Idx++);
3463 if (inheritanceModelHasVBTableOffsetField(Inheritance: DstInheritance))
3464 Dst = Builder.CreateInsertValue(Agg: Dst, Val: VirtualBaseAdjustmentOffset, Idxs: Idx++);
3465 }
3466 return Dst;
3467}
3468
3469llvm::Constant *
3470MicrosoftCXXABI::EmitMemberPointerConversion(const CastExpr *E,
3471 llvm::Constant *Src) {
3472 const MemberPointerType *SrcTy =
3473 E->getSubExpr()->getType()->castAs<MemberPointerType>();
3474 const MemberPointerType *DstTy = E->getType()->castAs<MemberPointerType>();
3475
3476 CastKind CK = E->getCastKind();
3477
3478 return EmitMemberPointerConversion(SrcTy, DstTy, CK, PathBegin: E->path_begin(),
3479 PathEnd: E->path_end(), Src);
3480}
3481
3482llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion(
3483 const MemberPointerType *SrcTy, const MemberPointerType *DstTy, CastKind CK,
3484 CastExpr::path_const_iterator PathBegin,
3485 CastExpr::path_const_iterator PathEnd, llvm::Constant *Src) {
3486 assert(CK == CK_DerivedToBaseMemberPointer ||
3487 CK == CK_BaseToDerivedMemberPointer ||
3488 CK == CK_ReinterpretMemberPointer);
3489 // If src is null, emit a new null for dst. We can't return src because dst
3490 // might have a new representation.
3491 if (MemberPointerConstantIsNull(MPT: SrcTy, Val: Src))
3492 return EmitNullMemberPointer(MPT: DstTy);
3493
3494 // We don't need to do anything for reinterpret_casts of non-null member
3495 // pointers. We should only get here when the two type representations have
3496 // the same size.
3497 if (CK == CK_ReinterpretMemberPointer)
3498 return Src;
3499
3500 CGBuilderTy Builder(CGM, CGM.getLLVMContext());
3501 auto *Dst = cast<llvm::Constant>(Val: EmitNonNullMemberPointerConversion(
3502 SrcTy, DstTy, CK, PathBegin, PathEnd, Src, Builder));
3503
3504 return Dst;
3505}
3506
3507CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
3508 CodeGenFunction &CGF, const Expr *E, Address This,
3509 llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr,
3510 const MemberPointerType *MPT) {
3511 assert(MPT->isMemberFunctionPointer());
3512 const FunctionProtoType *FPT =
3513 MPT->getPointeeType()->castAs<FunctionProtoType>();
3514 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
3515 CGBuilderTy &Builder = CGF.Builder;
3516
3517 MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
3518
3519 // Extract the fields we need, regardless of model. We'll apply them if we
3520 // have them.
3521 llvm::Value *FunctionPointer = MemPtr;
3522 llvm::Value *NonVirtualBaseAdjustment = nullptr;
3523 llvm::Value *VirtualBaseAdjustmentOffset = nullptr;
3524 llvm::Value *VBPtrOffset = nullptr;
3525 if (MemPtr->getType()->isStructTy()) {
3526 // We need to extract values.
3527 unsigned I = 0;
3528 FunctionPointer = Builder.CreateExtractValue(Agg: MemPtr, Idxs: I++);
3529 if (inheritanceModelHasNVOffsetField(IsMemberFunction: MPT, Inheritance))
3530 NonVirtualBaseAdjustment = Builder.CreateExtractValue(Agg: MemPtr, Idxs: I++);
3531 if (inheritanceModelHasVBPtrOffsetField(Inheritance))
3532 VBPtrOffset = Builder.CreateExtractValue(Agg: MemPtr, Idxs: I++);
3533 if (inheritanceModelHasVBTableOffsetField(Inheritance))
3534 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Agg: MemPtr, Idxs: I++);
3535 }
3536
3537 if (VirtualBaseAdjustmentOffset) {
3538 ThisPtrForCall = AdjustVirtualBase(CGF, E, RD, Base: This,
3539 VBTableOffset: VirtualBaseAdjustmentOffset, VBPtrOffset);
3540 } else {
3541 ThisPtrForCall = This.emitRawPointer(CGF);
3542 }
3543
3544 if (NonVirtualBaseAdjustment)
3545 ThisPtrForCall = Builder.CreateInBoundsGEP(Ty: CGF.Int8Ty, Ptr: ThisPtrForCall,
3546 IdxList: NonVirtualBaseAdjustment);
3547
3548 CGCallee Callee(FPT, FunctionPointer);
3549 return Callee;
3550}
3551
3552CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
3553 return new MicrosoftCXXABI(CGM);
3554}
3555
3556// MS RTTI Overview:
3557// The run time type information emitted by cl.exe contains 5 distinct types of
3558// structures. Many of them reference each other.
3559//
3560// TypeInfo: Static classes that are returned by typeid.
3561//
3562// CompleteObjectLocator: Referenced by vftables. They contain information
3563// required for dynamic casting, including OffsetFromTop. They also contain
3564// a reference to the TypeInfo for the type and a reference to the
3565// CompleteHierarchyDescriptor for the type.
3566//
3567// ClassHierarchyDescriptor: Contains information about a class hierarchy.
3568// Used during dynamic_cast to walk a class hierarchy. References a base
3569// class array and the size of said array.
3570//
3571// BaseClassArray: Contains a list of classes in a hierarchy. BaseClassArray is
3572// somewhat of a misnomer because the most derived class is also in the list
3573// as well as multiple copies of virtual bases (if they occur multiple times
3574// in the hierarchy.) The BaseClassArray contains one BaseClassDescriptor for
3575// every path in the hierarchy, in pre-order depth first order. Note, we do
3576// not declare a specific llvm type for BaseClassArray, it's merely an array
3577// of BaseClassDescriptor pointers.
3578//
3579// BaseClassDescriptor: Contains information about a class in a class hierarchy.
3580// BaseClassDescriptor is also somewhat of a misnomer for the same reason that
3581// BaseClassArray is. It contains information about a class within a
3582// hierarchy such as: is this base is ambiguous and what is its offset in the
3583// vbtable. The names of the BaseClassDescriptors have all of their fields
3584// mangled into them so they can be aggressively deduplicated by the linker.
3585
3586static llvm::GlobalVariable *getTypeInfoVTable(CodeGenModule &CGM) {
3587 StringRef MangledName("??_7type_info@@6B@");
3588 if (auto VTable = CGM.getModule().getNamedGlobal(Name: MangledName))
3589 return VTable;
3590 return new llvm::GlobalVariable(CGM.getModule(), CGM.Int8PtrTy,
3591 /*isConstant=*/true,
3592 llvm::GlobalVariable::ExternalLinkage,
3593 /*Initializer=*/nullptr, MangledName);
3594}
3595
3596namespace {
3597
3598/// A Helper struct that stores information about a class in a class
3599/// hierarchy. The information stored in these structs struct is used during
3600/// the generation of ClassHierarchyDescriptors and BaseClassDescriptors.
3601// During RTTI creation, MSRTTIClasses are stored in a contiguous array with
3602// implicit depth first pre-order tree connectivity. getFirstChild and
3603// getNextSibling allow us to walk the tree efficiently.
3604struct MSRTTIClass {
3605 enum {
3606 IsPrivateOnPath = 1 | 8,
3607 IsAmbiguous = 2,
3608 IsPrivate = 4,
3609 IsVirtual = 16,
3610 HasHierarchyDescriptor = 64
3611 };
3612 MSRTTIClass(const CXXRecordDecl *RD) : RD(RD) {}
3613 uint32_t initialize(const MSRTTIClass *Parent,
3614 const CXXBaseSpecifier *Specifier);
3615
3616 MSRTTIClass *getFirstChild() { return this + 1; }
3617 static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
3618 return Child + 1 + Child->NumBases;
3619 }
3620
3621 const CXXRecordDecl *RD, *VirtualRoot;
3622 uint32_t Flags, NumBases, OffsetInVBase;
3623};
3624
3625/// Recursively initialize the base class array.
3626uint32_t MSRTTIClass::initialize(const MSRTTIClass *Parent,
3627 const CXXBaseSpecifier *Specifier) {
3628 Flags = HasHierarchyDescriptor;
3629 if (!Parent) {
3630 VirtualRoot = nullptr;
3631 OffsetInVBase = 0;
3632 } else {
3633 if (Specifier->getAccessSpecifier() != AS_public)
3634 Flags |= IsPrivate | IsPrivateOnPath;
3635 if (Specifier->isVirtual()) {
3636 Flags |= IsVirtual;
3637 VirtualRoot = RD;
3638 OffsetInVBase = 0;
3639 } else {
3640 if (Parent->Flags & IsPrivateOnPath)
3641 Flags |= IsPrivateOnPath;
3642 VirtualRoot = Parent->VirtualRoot;
3643 OffsetInVBase = Parent->OffsetInVBase + RD->getASTContext()
3644 .getASTRecordLayout(D: Parent->RD).getBaseClassOffset(Base: RD).getQuantity();
3645 }
3646 }
3647 NumBases = 0;
3648 MSRTTIClass *Child = getFirstChild();
3649 for (const CXXBaseSpecifier &Base : RD->bases()) {
3650 NumBases += Child->initialize(Parent: this, Specifier: &Base) + 1;
3651 Child = getNextChild(Child);
3652 }
3653 return NumBases;
3654}
3655
3656static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(QualType Ty) {
3657 switch (Ty->getLinkage()) {
3658 case Linkage::Invalid:
3659 llvm_unreachable("Linkage hasn't been computed!");
3660
3661 case Linkage::None:
3662 case Linkage::Internal:
3663 case Linkage::UniqueExternal:
3664 return llvm::GlobalValue::InternalLinkage;
3665
3666 case Linkage::VisibleNone:
3667 case Linkage::Module:
3668 case Linkage::External:
3669 return llvm::GlobalValue::LinkOnceODRLinkage;
3670 }
3671 llvm_unreachable("Invalid linkage!");
3672}
3673
3674/// An ephemeral helper class for building MS RTTI types. It caches some
3675/// calls to the module and information about the most derived class in a
3676/// hierarchy.
3677struct MSRTTIBuilder {
3678 enum {
3679 HasBranchingHierarchy = 1,
3680 HasVirtualBranchingHierarchy = 2,
3681 HasAmbiguousBases = 4
3682 };
3683
3684 MSRTTIBuilder(MicrosoftCXXABI &ABI, const CXXRecordDecl *RD)
3685 : CGM(ABI.CGM), Context(CGM.getContext()),
3686 VMContext(CGM.getLLVMContext()), Module(CGM.getModule()), RD(RD),
3687 Linkage(getLinkageForRTTI(Ty: CGM.getContext().getTagDeclType(Decl: RD))),
3688 ABI(ABI) {}
3689
3690 llvm::GlobalVariable *getBaseClassDescriptor(const MSRTTIClass &Classes);
3691 llvm::GlobalVariable *
3692 getBaseClassArray(SmallVectorImpl<MSRTTIClass> &Classes);
3693 llvm::GlobalVariable *getClassHierarchyDescriptor();
3694 llvm::GlobalVariable *getCompleteObjectLocator(const VPtrInfo &Info);
3695
3696 CodeGenModule &CGM;
3697 ASTContext &Context;
3698 llvm::LLVMContext &VMContext;
3699 llvm::Module &Module;
3700 const CXXRecordDecl *RD;
3701 llvm::GlobalVariable::LinkageTypes Linkage;
3702 MicrosoftCXXABI &ABI;
3703};
3704
3705} // namespace
3706
3707/// Recursively serializes a class hierarchy in pre-order depth first
3708/// order.
3709static void serializeClassHierarchy(SmallVectorImpl<MSRTTIClass> &Classes,
3710 const CXXRecordDecl *RD) {
3711 Classes.push_back(Elt: MSRTTIClass(RD));
3712 for (const CXXBaseSpecifier &Base : RD->bases())
3713 serializeClassHierarchy(Classes, RD: Base.getType()->getAsCXXRecordDecl());
3714}
3715
3716/// Find ambiguity among base classes.
3717static void
3718detectAmbiguousBases(SmallVectorImpl<MSRTTIClass> &Classes) {
3719 llvm::SmallPtrSet<const CXXRecordDecl *, 8> VirtualBases;
3720 llvm::SmallPtrSet<const CXXRecordDecl *, 8> UniqueBases;
3721 llvm::SmallPtrSet<const CXXRecordDecl *, 8> AmbiguousBases;
3722 for (MSRTTIClass *Class = &Classes.front(); Class <= &Classes.back();) {
3723 if ((Class->Flags & MSRTTIClass::IsVirtual) &&
3724 !VirtualBases.insert(Ptr: Class->RD).second) {
3725 Class = MSRTTIClass::getNextChild(Child: Class);
3726 continue;
3727 }
3728 if (!UniqueBases.insert(Ptr: Class->RD).second)
3729 AmbiguousBases.insert(Ptr: Class->RD);
3730 Class++;
3731 }
3732 if (AmbiguousBases.empty())
3733 return;
3734 for (MSRTTIClass &Class : Classes)
3735 if (AmbiguousBases.count(Ptr: Class.RD))
3736 Class.Flags |= MSRTTIClass::IsAmbiguous;
3737}
3738
3739llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
3740 SmallString<256> MangledName;
3741 {
3742 llvm::raw_svector_ostream Out(MangledName);
3743 ABI.getMangleContext().mangleCXXRTTIClassHierarchyDescriptor(Derived: RD, Out);
3744 }
3745
3746 // Check to see if we've already declared this ClassHierarchyDescriptor.
3747 if (auto CHD = Module.getNamedGlobal(Name: MangledName))
3748 return CHD;
3749
3750 // Serialize the class hierarchy and initialize the CHD Fields.
3751 SmallVector<MSRTTIClass, 8> Classes;
3752 serializeClassHierarchy(Classes, RD);
3753 Classes.front().initialize(/*Parent=*/nullptr, /*Specifier=*/nullptr);
3754 detectAmbiguousBases(Classes);
3755 int Flags = 0;
3756 for (const MSRTTIClass &Class : Classes) {
3757 if (Class.RD->getNumBases() > 1)
3758 Flags |= HasBranchingHierarchy;
3759 // Note: cl.exe does not calculate "HasAmbiguousBases" correctly. We
3760 // believe the field isn't actually used.
3761 if (Class.Flags & MSRTTIClass::IsAmbiguous)
3762 Flags |= HasAmbiguousBases;
3763 }
3764 if ((Flags & HasBranchingHierarchy) && RD->getNumVBases() != 0)
3765 Flags |= HasVirtualBranchingHierarchy;
3766 // These gep indices are used to get the address of the first element of the
3767 // base class array.
3768 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(Ty: CGM.IntTy, V: 0),
3769 llvm::ConstantInt::get(Ty: CGM.IntTy, V: 0)};
3770
3771 // Forward-declare the class hierarchy descriptor
3772 auto Type = ABI.getClassHierarchyDescriptorType();
3773 auto CHD = new llvm::GlobalVariable(Module, Type, /*isConstant=*/true, Linkage,
3774 /*Initializer=*/nullptr,
3775 MangledName);
3776 if (CHD->isWeakForLinker())
3777 CHD->setComdat(CGM.getModule().getOrInsertComdat(Name: CHD->getName()));
3778
3779 auto *Bases = getBaseClassArray(Classes);
3780
3781 // Initialize the base class ClassHierarchyDescriptor.
3782 llvm::Constant *Fields[] = {
3783 llvm::ConstantInt::get(Ty: CGM.IntTy, V: 0), // reserved by the runtime
3784 llvm::ConstantInt::get(Ty: CGM.IntTy, V: Flags),
3785 llvm::ConstantInt::get(Ty: CGM.IntTy, V: Classes.size()),
3786 ABI.getImageRelativeConstant(PtrVal: llvm::ConstantExpr::getInBoundsGetElementPtr(
3787 Ty: Bases->getValueType(), C: Bases,
3788 IdxList: llvm::ArrayRef<llvm::Value *>(GEPIndices))),
3789 };
3790 CHD->setInitializer(llvm::ConstantStruct::get(T: Type, V: Fields));
3791 return CHD;
3792}
3793
3794llvm::GlobalVariable *
3795MSRTTIBuilder::getBaseClassArray(SmallVectorImpl<MSRTTIClass> &Classes) {
3796 SmallString<256> MangledName;
3797 {
3798 llvm::raw_svector_ostream Out(MangledName);
3799 ABI.getMangleContext().mangleCXXRTTIBaseClassArray(Derived: RD, Out);
3800 }
3801
3802 // Forward-declare the base class array.
3803 // cl.exe pads the base class array with 1 (in 32 bit mode) or 4 (in 64 bit
3804 // mode) bytes of padding. We provide a pointer sized amount of padding by
3805 // adding +1 to Classes.size(). The sections have pointer alignment and are
3806 // marked pick-any so it shouldn't matter.
3807 llvm::Type *PtrType = ABI.getImageRelativeType(PtrType: CGM.UnqualPtrTy);
3808 auto *ArrType = llvm::ArrayType::get(ElementType: PtrType, NumElements: Classes.size() + 1);
3809 auto *BCA =
3810 new llvm::GlobalVariable(Module, ArrType,
3811 /*isConstant=*/true, Linkage,
3812 /*Initializer=*/nullptr, MangledName);
3813 if (BCA->isWeakForLinker())
3814 BCA->setComdat(CGM.getModule().getOrInsertComdat(Name: BCA->getName()));
3815
3816 // Initialize the BaseClassArray.
3817 SmallVector<llvm::Constant *, 8> BaseClassArrayData;
3818 for (MSRTTIClass &Class : Classes)
3819 BaseClassArrayData.push_back(
3820 Elt: ABI.getImageRelativeConstant(PtrVal: getBaseClassDescriptor(Classes: Class)));
3821 BaseClassArrayData.push_back(Elt: llvm::Constant::getNullValue(Ty: PtrType));
3822 BCA->setInitializer(llvm::ConstantArray::get(T: ArrType, V: BaseClassArrayData));
3823 return BCA;
3824}
3825
3826llvm::GlobalVariable *
3827MSRTTIBuilder::getBaseClassDescriptor(const MSRTTIClass &Class) {
3828 // Compute the fields for the BaseClassDescriptor. They are computed up front
3829 // because they are mangled into the name of the object.
3830 uint32_t OffsetInVBTable = 0;
3831 int32_t VBPtrOffset = -1;
3832 if (Class.VirtualRoot) {
3833 auto &VTableContext = CGM.getMicrosoftVTableContext();
3834 OffsetInVBTable = VTableContext.getVBTableIndex(Derived: RD, VBase: Class.VirtualRoot) * 4;
3835 VBPtrOffset = Context.getASTRecordLayout(D: RD).getVBPtrOffset().getQuantity();
3836 }
3837
3838 SmallString<256> MangledName;
3839 {
3840 llvm::raw_svector_ostream Out(MangledName);
3841 ABI.getMangleContext().mangleCXXRTTIBaseClassDescriptor(
3842 Derived: Class.RD, NVOffset: Class.OffsetInVBase, VBPtrOffset, VBTableOffset: OffsetInVBTable,
3843 Flags: Class.Flags, Out);
3844 }
3845
3846 // Check to see if we've already declared this object.
3847 if (auto BCD = Module.getNamedGlobal(Name: MangledName))
3848 return BCD;
3849
3850 // Forward-declare the base class descriptor.
3851 auto Type = ABI.getBaseClassDescriptorType();
3852 auto BCD =
3853 new llvm::GlobalVariable(Module, Type, /*isConstant=*/true, Linkage,
3854 /*Initializer=*/nullptr, MangledName);
3855 if (BCD->isWeakForLinker())
3856 BCD->setComdat(CGM.getModule().getOrInsertComdat(Name: BCD->getName()));
3857
3858 // Initialize the BaseClassDescriptor.
3859 llvm::Constant *Fields[] = {
3860 ABI.getImageRelativeConstant(
3861 PtrVal: ABI.getAddrOfRTTIDescriptor(Ty: Context.getTypeDeclType(Decl: Class.RD))),
3862 llvm::ConstantInt::get(Ty: CGM.IntTy, V: Class.NumBases),
3863 llvm::ConstantInt::get(Ty: CGM.IntTy, V: Class.OffsetInVBase),
3864 llvm::ConstantInt::get(Ty: CGM.IntTy, V: VBPtrOffset),
3865 llvm::ConstantInt::get(Ty: CGM.IntTy, V: OffsetInVBTable),
3866 llvm::ConstantInt::get(Ty: CGM.IntTy, V: Class.Flags),
3867 ABI.getImageRelativeConstant(
3868 PtrVal: MSRTTIBuilder(ABI, Class.RD).getClassHierarchyDescriptor()),
3869 };
3870 BCD->setInitializer(llvm::ConstantStruct::get(T: Type, V: Fields));
3871 return BCD;
3872}
3873
3874llvm::GlobalVariable *
3875MSRTTIBuilder::getCompleteObjectLocator(const VPtrInfo &Info) {
3876 SmallString<256> MangledName;
3877 {
3878 llvm::raw_svector_ostream Out(MangledName);
3879 ABI.getMangleContext().mangleCXXRTTICompleteObjectLocator(Derived: RD, BasePath: Info.MangledPath, Out);
3880 }
3881
3882 // Check to see if we've already computed this complete object locator.
3883 if (auto COL = Module.getNamedGlobal(Name: MangledName))
3884 return COL;
3885
3886 // Compute the fields of the complete object locator.
3887 int OffsetToTop = Info.FullOffsetInMDC.getQuantity();
3888 int VFPtrOffset = 0;
3889 // The offset includes the vtordisp if one exists.
3890 if (const CXXRecordDecl *VBase = Info.getVBaseWithVPtr())
3891 if (Context.getASTRecordLayout(D: RD)
3892 .getVBaseOffsetsMap()
3893 .find(Val: VBase)
3894 ->second.hasVtorDisp())
3895 VFPtrOffset = Info.NonVirtualOffset.getQuantity() + 4;
3896
3897 // Forward-declare the complete object locator.
3898 llvm::StructType *Type = ABI.getCompleteObjectLocatorType();
3899 auto COL = new llvm::GlobalVariable(Module, Type, /*isConstant=*/true, Linkage,
3900 /*Initializer=*/nullptr, MangledName);
3901
3902 // Initialize the CompleteObjectLocator.
3903 llvm::Constant *Fields[] = {
3904 llvm::ConstantInt::get(Ty: CGM.IntTy, V: ABI.isImageRelative()),
3905 llvm::ConstantInt::get(Ty: CGM.IntTy, V: OffsetToTop),
3906 llvm::ConstantInt::get(Ty: CGM.IntTy, V: VFPtrOffset),
3907 ABI.getImageRelativeConstant(
3908 PtrVal: CGM.GetAddrOfRTTIDescriptor(Ty: Context.getTypeDeclType(Decl: RD))),
3909 ABI.getImageRelativeConstant(PtrVal: getClassHierarchyDescriptor()),
3910 ABI.getImageRelativeConstant(PtrVal: COL),
3911 };
3912 llvm::ArrayRef<llvm::Constant *> FieldsRef(Fields);
3913 if (!ABI.isImageRelative())
3914 FieldsRef = FieldsRef.drop_back();
3915 COL->setInitializer(llvm::ConstantStruct::get(T: Type, V: FieldsRef));
3916 if (COL->isWeakForLinker())
3917 COL->setComdat(CGM.getModule().getOrInsertComdat(Name: COL->getName()));
3918 return COL;
3919}
3920
3921static QualType decomposeTypeForEH(ASTContext &Context, QualType T,
3922 bool &IsConst, bool &IsVolatile,
3923 bool &IsUnaligned) {
3924 T = Context.getExceptionObjectType(T);
3925
3926 // C++14 [except.handle]p3:
3927 // A handler is a match for an exception object of type E if [...]
3928 // - the handler is of type cv T or const T& where T is a pointer type and
3929 // E is a pointer type that can be converted to T by [...]
3930 // - a qualification conversion
3931 IsConst = false;
3932 IsVolatile = false;
3933 IsUnaligned = false;
3934 QualType PointeeType = T->getPointeeType();
3935 if (!PointeeType.isNull()) {
3936 IsConst = PointeeType.isConstQualified();
3937 IsVolatile = PointeeType.isVolatileQualified();
3938 IsUnaligned = PointeeType.getQualifiers().hasUnaligned();
3939 }
3940
3941 // Member pointer types like "const int A::*" are represented by having RTTI
3942 // for "int A::*" and separately storing the const qualifier.
3943 if (const auto *MPTy = T->getAs<MemberPointerType>())
3944 T = Context.getMemberPointerType(T: PointeeType.getUnqualifiedType(),
3945 Qualifier: MPTy->getQualifier(),
3946 Cls: MPTy->getMostRecentCXXRecordDecl());
3947
3948 // Pointer types like "const int * const *" are represented by having RTTI
3949 // for "const int **" and separately storing the const qualifier.
3950 if (T->isPointerType())
3951 T = Context.getPointerType(T: PointeeType.getUnqualifiedType());
3952
3953 return T;
3954}
3955
3956CatchTypeInfo
3957MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(QualType Type,
3958 QualType CatchHandlerType) {
3959 // TypeDescriptors for exceptions never have qualified pointer types,
3960 // qualifiers are stored separately in order to support qualification
3961 // conversions.
3962 bool IsConst, IsVolatile, IsUnaligned;
3963 Type =
3964 decomposeTypeForEH(Context&: getContext(), T: Type, IsConst, IsVolatile, IsUnaligned);
3965
3966 bool IsReference = CatchHandlerType->isReferenceType();
3967
3968 uint32_t Flags = 0;
3969 if (IsConst)
3970 Flags |= 1;
3971 if (IsVolatile)
3972 Flags |= 2;
3973 if (IsUnaligned)
3974 Flags |= 4;
3975 if (IsReference)
3976 Flags |= 8;
3977
3978 return CatchTypeInfo{.RTTI: getAddrOfRTTIDescriptor(Ty: Type)->stripPointerCasts(),
3979 .Flags: Flags};
3980}
3981
3982/// Gets a TypeDescriptor. Returns a llvm::Constant * rather than a
3983/// llvm::GlobalVariable * because different type descriptors have different
3984/// types, and need to be abstracted. They are abstracting by casting the
3985/// address to an Int8PtrTy.
3986llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(QualType Type) {
3987 SmallString<256> MangledName;
3988 {
3989 llvm::raw_svector_ostream Out(MangledName);
3990 getMangleContext().mangleCXXRTTI(T: Type, Out);
3991 }
3992
3993 // Check to see if we've already declared this TypeDescriptor.
3994 if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name: MangledName))
3995 return GV;
3996
3997 // Note for the future: If we would ever like to do deferred emission of
3998 // RTTI, check if emitting vtables opportunistically need any adjustment.
3999
4000 // Compute the fields for the TypeDescriptor.
4001 SmallString<256> TypeInfoString;
4002 {
4003 llvm::raw_svector_ostream Out(TypeInfoString);
4004 getMangleContext().mangleCXXRTTIName(T: Type, Out);
4005 }
4006
4007 // Declare and initialize the TypeDescriptor.
4008 llvm::Constant *Fields[] = {
4009 getTypeInfoVTable(CGM), // VFPtr
4010 llvm::ConstantPointerNull::get(T: CGM.Int8PtrTy), // Runtime data
4011 llvm::ConstantDataArray::getString(Context&: CGM.getLLVMContext(), Initializer: TypeInfoString)};
4012 llvm::StructType *TypeDescriptorType =
4013 getTypeDescriptorType(TypeInfoString);
4014 auto *Var = new llvm::GlobalVariable(
4015 CGM.getModule(), TypeDescriptorType, /*isConstant=*/false,
4016 getLinkageForRTTI(Ty: Type),
4017 llvm::ConstantStruct::get(T: TypeDescriptorType, V: Fields),
4018 MangledName);
4019 if (Var->isWeakForLinker())
4020 Var->setComdat(CGM.getModule().getOrInsertComdat(Name: Var->getName()));
4021 return Var;
4022}
4023
4024/// Gets or a creates a Microsoft CompleteObjectLocator.
4025llvm::GlobalVariable *
4026MicrosoftCXXABI::getMSCompleteObjectLocator(const CXXRecordDecl *RD,
4027 const VPtrInfo &Info) {
4028 return MSRTTIBuilder(*this, RD).getCompleteObjectLocator(Info);
4029}
4030
4031void MicrosoftCXXABI::emitCXXStructor(GlobalDecl GD) {
4032 if (auto *ctor = dyn_cast<CXXConstructorDecl>(Val: GD.getDecl())) {
4033 // There are no constructor variants, always emit the complete destructor.
4034 llvm::Function *Fn =
4035 CGM.codegenCXXStructor(GD: GD.getWithCtorType(Type: Ctor_Complete));
4036 CGM.maybeSetTrivialComdat(D: *ctor, GO&: *Fn);
4037 return;
4038 }
4039
4040 auto *dtor = cast<CXXDestructorDecl>(Val: GD.getDecl());
4041
4042 // Emit the base destructor if the base and complete (vbase) destructors are
4043 // equivalent. This effectively implements -mconstructor-aliases as part of
4044 // the ABI.
4045 if (GD.getDtorType() == Dtor_Complete &&
4046 dtor->getParent()->getNumVBases() == 0)
4047 GD = GD.getWithDtorType(Type: Dtor_Base);
4048
4049 // The base destructor is equivalent to the base destructor of its
4050 // base class if there is exactly one non-virtual base class with a
4051 // non-trivial destructor, there are no fields with a non-trivial
4052 // destructor, and the body of the destructor is trivial.
4053 if (GD.getDtorType() == Dtor_Base && !CGM.TryEmitBaseDestructorAsAlias(D: dtor))
4054 return;
4055
4056 llvm::Function *Fn = CGM.codegenCXXStructor(GD);
4057 if (Fn->isWeakForLinker())
4058 Fn->setComdat(CGM.getModule().getOrInsertComdat(Name: Fn->getName()));
4059}
4060
4061llvm::Function *
4062MicrosoftCXXABI::getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD,
4063 CXXCtorType CT) {
4064 assert(CT == Ctor_CopyingClosure || CT == Ctor_DefaultClosure);
4065
4066 // Calculate the mangled name.
4067 SmallString<256> ThunkName;
4068 llvm::raw_svector_ostream Out(ThunkName);
4069 getMangleContext().mangleName(GD: GlobalDecl(CD, CT), Out);
4070
4071 // If the thunk has been generated previously, just return it.
4072 if (llvm::GlobalValue *GV = CGM.getModule().getNamedValue(Name: ThunkName))
4073 return cast<llvm::Function>(Val: GV);
4074
4075 // Create the llvm::Function.
4076 const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeMSCtorClosure(CD, CT);
4077 llvm::FunctionType *ThunkTy = CGM.getTypes().GetFunctionType(Info: FnInfo);
4078 const CXXRecordDecl *RD = CD->getParent();
4079 QualType RecordTy = getContext().getRecordType(Decl: RD);
4080 llvm::Function *ThunkFn = llvm::Function::Create(
4081 Ty: ThunkTy, Linkage: getLinkageForRTTI(Ty: RecordTy), N: ThunkName.str(), M: &CGM.getModule());
4082 ThunkFn->setCallingConv(static_cast<llvm::CallingConv::ID>(
4083 FnInfo.getEffectiveCallingConvention()));
4084 if (ThunkFn->isWeakForLinker())
4085 ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(Name: ThunkFn->getName()));
4086 bool IsCopy = CT == Ctor_CopyingClosure;
4087
4088 // Start codegen.
4089 CodeGenFunction CGF(CGM);
4090 CGF.CurGD = GlobalDecl(CD, Ctor_Complete);
4091
4092 // Build FunctionArgs.
4093 FunctionArgList FunctionArgs;
4094
4095 // A constructor always starts with a 'this' pointer as its first argument.
4096 buildThisParam(CGF, Params&: FunctionArgs);
4097
4098 // Following the 'this' pointer is a reference to the source object that we
4099 // are copying from.
4100 ImplicitParamDecl SrcParam(
4101 getContext(), /*DC=*/nullptr, SourceLocation(),
4102 &getContext().Idents.get(Name: "src"),
4103 getContext().getLValueReferenceType(T: RecordTy,
4104 /*SpelledAsLValue=*/true),
4105 ImplicitParamKind::Other);
4106 if (IsCopy)
4107 FunctionArgs.push_back(Elt: &SrcParam);
4108
4109 // Constructors for classes which utilize virtual bases have an additional
4110 // parameter which indicates whether or not it is being delegated to by a more
4111 // derived constructor.
4112 ImplicitParamDecl IsMostDerived(getContext(), /*DC=*/nullptr,
4113 SourceLocation(),
4114 &getContext().Idents.get(Name: "is_most_derived"),
4115 getContext().IntTy, ImplicitParamKind::Other);
4116 // Only add the parameter to the list if the class has virtual bases.
4117 if (RD->getNumVBases() > 0)
4118 FunctionArgs.push_back(Elt: &IsMostDerived);
4119
4120 // Start defining the function.
4121 auto NL = ApplyDebugLocation::CreateEmpty(CGF);
4122 CGF.StartFunction(GD: GlobalDecl(), RetTy: FnInfo.getReturnType(), Fn: ThunkFn, FnInfo,
4123 Args: FunctionArgs, Loc: CD->getLocation(), StartLoc: SourceLocation());
4124 // Create a scope with an artificial location for the body of this function.
4125 auto AL = ApplyDebugLocation::CreateArtificial(CGF);
4126 setCXXABIThisValue(CGF, ThisPtr: loadIncomingCXXThis(CGF));
4127 llvm::Value *This = getThisValue(CGF);
4128
4129 llvm::Value *SrcVal =
4130 IsCopy ? CGF.Builder.CreateLoad(Addr: CGF.GetAddrOfLocalVar(VD: &SrcParam), Name: "src")
4131 : nullptr;
4132
4133 CallArgList Args;
4134
4135 // Push the this ptr.
4136 Args.add(rvalue: RValue::get(V: This), type: CD->getThisType());
4137
4138 // Push the src ptr.
4139 if (SrcVal)
4140 Args.add(rvalue: RValue::get(V: SrcVal), type: SrcParam.getType());
4141
4142 // Add the rest of the default arguments.
4143 SmallVector<const Stmt *, 4> ArgVec;
4144 ArrayRef<ParmVarDecl *> params = CD->parameters().drop_front(N: IsCopy ? 1 : 0);
4145 for (const ParmVarDecl *PD : params) {
4146 assert(PD->hasDefaultArg() && "ctor closure lacks default args");
4147 ArgVec.push_back(Elt: PD->getDefaultArg());
4148 }
4149
4150 CodeGenFunction::RunCleanupsScope Cleanups(CGF);
4151
4152 const auto *FPT = CD->getType()->castAs<FunctionProtoType>();
4153 CGF.EmitCallArgs(Args, Prototype: FPT, ArgRange: llvm::ArrayRef(ArgVec), AC: CD, ParamsToSkip: IsCopy ? 1 : 0);
4154
4155 // Insert any ABI-specific implicit constructor arguments.
4156 AddedStructorArgCounts ExtraArgs =
4157 addImplicitConstructorArgs(CGF, D: CD, Type: Ctor_Complete,
4158 /*ForVirtualBase=*/false,
4159 /*Delegating=*/false, Args);
4160 // Call the destructor with our arguments.
4161 llvm::Constant *CalleePtr =
4162 CGM.getAddrOfCXXStructor(GD: GlobalDecl(CD, Ctor_Complete));
4163 CGCallee Callee =
4164 CGCallee::forDirect(functionPtr: CalleePtr, abstractInfo: GlobalDecl(CD, Ctor_Complete));
4165 const CGFunctionInfo &CalleeInfo = CGM.getTypes().arrangeCXXConstructorCall(
4166 Args, D: CD, CtorKind: Ctor_Complete, ExtraPrefixArgs: ExtraArgs.Prefix, ExtraSuffixArgs: ExtraArgs.Suffix);
4167 CGF.EmitCall(CallInfo: CalleeInfo, Callee, ReturnValue: ReturnValueSlot(), Args);
4168
4169 Cleanups.ForceCleanup();
4170
4171 // Emit the ret instruction, remove any temporary instructions created for the
4172 // aid of CodeGen.
4173 CGF.FinishFunction(EndLoc: SourceLocation());
4174
4175 return ThunkFn;
4176}
4177
4178llvm::Constant *MicrosoftCXXABI::getCatchableType(QualType T,
4179 uint32_t NVOffset,
4180 int32_t VBPtrOffset,
4181 uint32_t VBIndex) {
4182 assert(!T->isReferenceType());
4183
4184 CXXRecordDecl *RD = T->getAsCXXRecordDecl();
4185 const CXXConstructorDecl *CD =
4186 RD ? CGM.getContext().getCopyConstructorForExceptionObject(RD) : nullptr;
4187 CXXCtorType CT = Ctor_Complete;
4188 if (CD)
4189 if (!hasDefaultCXXMethodCC(Context&: getContext(), MD: CD) || CD->getNumParams() != 1)
4190 CT = Ctor_CopyingClosure;
4191
4192 uint32_t Size = getContext().getTypeSizeInChars(T).getQuantity();
4193 SmallString<256> MangledName;
4194 {
4195 llvm::raw_svector_ostream Out(MangledName);
4196 getMangleContext().mangleCXXCatchableType(T, CD, CT, Size, NVOffset,
4197 VBPtrOffset, VBIndex, Out);
4198 }
4199 if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name: MangledName))
4200 return getImageRelativeConstant(PtrVal: GV);
4201
4202 // The TypeDescriptor is used by the runtime to determine if a catch handler
4203 // is appropriate for the exception object.
4204 llvm::Constant *TD = getImageRelativeConstant(PtrVal: getAddrOfRTTIDescriptor(Type: T));
4205
4206 // The runtime is responsible for calling the copy constructor if the
4207 // exception is caught by value.
4208 llvm::Constant *CopyCtor;
4209 if (CD) {
4210 if (CT == Ctor_CopyingClosure)
4211 CopyCtor = getAddrOfCXXCtorClosure(CD, CT: Ctor_CopyingClosure);
4212 else
4213 CopyCtor = CGM.getAddrOfCXXStructor(GD: GlobalDecl(CD, Ctor_Complete));
4214 } else {
4215 CopyCtor = llvm::Constant::getNullValue(Ty: CGM.Int8PtrTy);
4216 }
4217 CopyCtor = getImageRelativeConstant(PtrVal: CopyCtor);
4218
4219 bool IsScalar = !RD;
4220 bool HasVirtualBases = false;
4221 bool IsStdBadAlloc = false; // std::bad_alloc is special for some reason.
4222 QualType PointeeType = T;
4223 if (T->isPointerType())
4224 PointeeType = T->getPointeeType();
4225 if (const CXXRecordDecl *RD = PointeeType->getAsCXXRecordDecl()) {
4226 HasVirtualBases = RD->getNumVBases() > 0;
4227 if (IdentifierInfo *II = RD->getIdentifier())
4228 IsStdBadAlloc = II->isStr(Str: "bad_alloc") && RD->isInStdNamespace();
4229 }
4230
4231 // Encode the relevant CatchableType properties into the Flags bitfield.
4232 // FIXME: Figure out how bits 2 or 8 can get set.
4233 uint32_t Flags = 0;
4234 if (IsScalar)
4235 Flags |= 1;
4236 if (HasVirtualBases)
4237 Flags |= 4;
4238 if (IsStdBadAlloc)
4239 Flags |= 16;
4240
4241 llvm::Constant *Fields[] = {
4242 llvm::ConstantInt::get(Ty: CGM.IntTy, V: Flags), // Flags
4243 TD, // TypeDescriptor
4244 llvm::ConstantInt::get(Ty: CGM.IntTy, V: NVOffset), // NonVirtualAdjustment
4245 llvm::ConstantInt::get(Ty: CGM.IntTy, V: VBPtrOffset), // OffsetToVBPtr
4246 llvm::ConstantInt::get(Ty: CGM.IntTy, V: VBIndex), // VBTableIndex
4247 llvm::ConstantInt::get(Ty: CGM.IntTy, V: Size), // Size
4248 CopyCtor // CopyCtor
4249 };
4250 llvm::StructType *CTType = getCatchableTypeType();
4251 auto *GV = new llvm::GlobalVariable(
4252 CGM.getModule(), CTType, /*isConstant=*/true, getLinkageForRTTI(Ty: T),
4253 llvm::ConstantStruct::get(T: CTType, V: Fields), MangledName);
4254 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4255 GV->setSection(".xdata");
4256 if (GV->isWeakForLinker())
4257 GV->setComdat(CGM.getModule().getOrInsertComdat(Name: GV->getName()));
4258 return getImageRelativeConstant(PtrVal: GV);
4259}
4260
4261llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(QualType T) {
4262 assert(!T->isReferenceType());
4263
4264 // See if we've already generated a CatchableTypeArray for this type before.
4265 llvm::GlobalVariable *&CTA = CatchableTypeArrays[T];
4266 if (CTA)
4267 return CTA;
4268
4269 // Ensure that we don't have duplicate entries in our CatchableTypeArray by
4270 // using a SmallSetVector. Duplicates may arise due to virtual bases
4271 // occurring more than once in the hierarchy.
4272 llvm::SmallSetVector<llvm::Constant *, 2> CatchableTypes;
4273
4274 // C++14 [except.handle]p3:
4275 // A handler is a match for an exception object of type E if [...]
4276 // - the handler is of type cv T or cv T& and T is an unambiguous public
4277 // base class of E, or
4278 // - the handler is of type cv T or const T& where T is a pointer type and
4279 // E is a pointer type that can be converted to T by [...]
4280 // - a standard pointer conversion (4.10) not involving conversions to
4281 // pointers to private or protected or ambiguous classes
4282 const CXXRecordDecl *MostDerivedClass = nullptr;
4283 bool IsPointer = T->isPointerType();
4284 if (IsPointer)
4285 MostDerivedClass = T->getPointeeType()->getAsCXXRecordDecl();
4286 else
4287 MostDerivedClass = T->getAsCXXRecordDecl();
4288
4289 // Collect all the unambiguous public bases of the MostDerivedClass.
4290 if (MostDerivedClass) {
4291 const ASTContext &Context = getContext();
4292 const ASTRecordLayout &MostDerivedLayout =
4293 Context.getASTRecordLayout(D: MostDerivedClass);
4294 MicrosoftVTableContext &VTableContext = CGM.getMicrosoftVTableContext();
4295 SmallVector<MSRTTIClass, 8> Classes;
4296 serializeClassHierarchy(Classes, RD: MostDerivedClass);
4297 Classes.front().initialize(/*Parent=*/nullptr, /*Specifier=*/nullptr);
4298 detectAmbiguousBases(Classes);
4299 for (const MSRTTIClass &Class : Classes) {
4300 // Skip any ambiguous or private bases.
4301 if (Class.Flags &
4302 (MSRTTIClass::IsPrivateOnPath | MSRTTIClass::IsAmbiguous))
4303 continue;
4304 // Write down how to convert from a derived pointer to a base pointer.
4305 uint32_t OffsetInVBTable = 0;
4306 int32_t VBPtrOffset = -1;
4307 if (Class.VirtualRoot) {
4308 OffsetInVBTable =
4309 VTableContext.getVBTableIndex(Derived: MostDerivedClass, VBase: Class.VirtualRoot)*4;
4310 VBPtrOffset = MostDerivedLayout.getVBPtrOffset().getQuantity();
4311 }
4312
4313 // Turn our record back into a pointer if the exception object is a
4314 // pointer.
4315 QualType RTTITy = QualType(Class.RD->getTypeForDecl(), 0);
4316 if (IsPointer)
4317 RTTITy = Context.getPointerType(T: RTTITy);
4318 CatchableTypes.insert(X: getCatchableType(T: RTTITy, NVOffset: Class.OffsetInVBase,
4319 VBPtrOffset, VBIndex: OffsetInVBTable));
4320 }
4321 }
4322
4323 // C++14 [except.handle]p3:
4324 // A handler is a match for an exception object of type E if
4325 // - The handler is of type cv T or cv T& and E and T are the same type
4326 // (ignoring the top-level cv-qualifiers)
4327 CatchableTypes.insert(X: getCatchableType(T));
4328
4329 // C++14 [except.handle]p3:
4330 // A handler is a match for an exception object of type E if
4331 // - the handler is of type cv T or const T& where T is a pointer type and
4332 // E is a pointer type that can be converted to T by [...]
4333 // - a standard pointer conversion (4.10) not involving conversions to
4334 // pointers to private or protected or ambiguous classes
4335 //
4336 // C++14 [conv.ptr]p2:
4337 // A prvalue of type "pointer to cv T," where T is an object type, can be
4338 // converted to a prvalue of type "pointer to cv void".
4339 if (IsPointer && T->getPointeeType()->isObjectType())
4340 CatchableTypes.insert(X: getCatchableType(T: getContext().VoidPtrTy));
4341
4342 // C++14 [except.handle]p3:
4343 // A handler is a match for an exception object of type E if [...]
4344 // - the handler is of type cv T or const T& where T is a pointer or
4345 // pointer to member type and E is std::nullptr_t.
4346 //
4347 // We cannot possibly list all possible pointer types here, making this
4348 // implementation incompatible with the standard. However, MSVC includes an
4349 // entry for pointer-to-void in this case. Let's do the same.
4350 if (T->isNullPtrType())
4351 CatchableTypes.insert(X: getCatchableType(T: getContext().VoidPtrTy));
4352
4353 uint32_t NumEntries = CatchableTypes.size();
4354 llvm::Type *CTType = getImageRelativeType(PtrType: CGM.UnqualPtrTy);
4355 llvm::ArrayType *AT = llvm::ArrayType::get(ElementType: CTType, NumElements: NumEntries);
4356 llvm::StructType *CTAType = getCatchableTypeArrayType(NumEntries);
4357 llvm::Constant *Fields[] = {
4358 llvm::ConstantInt::get(Ty: CGM.IntTy, V: NumEntries), // NumEntries
4359 llvm::ConstantArray::get(
4360 T: AT, V: llvm::ArrayRef(CatchableTypes.begin(),
4361 CatchableTypes.end())) // CatchableTypes
4362 };
4363 SmallString<256> MangledName;
4364 {
4365 llvm::raw_svector_ostream Out(MangledName);
4366 getMangleContext().mangleCXXCatchableTypeArray(T, NumEntries, Out);
4367 }
4368 CTA = new llvm::GlobalVariable(
4369 CGM.getModule(), CTAType, /*isConstant=*/true, getLinkageForRTTI(Ty: T),
4370 llvm::ConstantStruct::get(T: CTAType, V: Fields), MangledName);
4371 CTA->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4372 CTA->setSection(".xdata");
4373 if (CTA->isWeakForLinker())
4374 CTA->setComdat(CGM.getModule().getOrInsertComdat(Name: CTA->getName()));
4375 return CTA;
4376}
4377
4378llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(QualType T) {
4379 bool IsConst, IsVolatile, IsUnaligned;
4380 T = decomposeTypeForEH(Context&: getContext(), T, IsConst, IsVolatile, IsUnaligned);
4381
4382 // The CatchableTypeArray enumerates the various (CV-unqualified) types that
4383 // the exception object may be caught as.
4384 llvm::GlobalVariable *CTA = getCatchableTypeArray(T);
4385 // The first field in a CatchableTypeArray is the number of CatchableTypes.
4386 // This is used as a component of the mangled name which means that we need to
4387 // know what it is in order to see if we have previously generated the
4388 // ThrowInfo.
4389 uint32_t NumEntries =
4390 cast<llvm::ConstantInt>(Val: CTA->getInitializer()->getAggregateElement(Elt: 0U))
4391 ->getLimitedValue();
4392
4393 SmallString<256> MangledName;
4394 {
4395 llvm::raw_svector_ostream Out(MangledName);
4396 getMangleContext().mangleCXXThrowInfo(T, IsConst, IsVolatile, IsUnaligned,
4397 NumEntries, Out);
4398 }
4399
4400 // Reuse a previously generated ThrowInfo if we have generated an appropriate
4401 // one before.
4402 if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name: MangledName))
4403 return GV;
4404
4405 // The RTTI TypeDescriptor uses an unqualified type but catch clauses must
4406 // be at least as CV qualified. Encode this requirement into the Flags
4407 // bitfield.
4408 uint32_t Flags = 0;
4409 if (IsConst)
4410 Flags |= 1;
4411 if (IsVolatile)
4412 Flags |= 2;
4413 if (IsUnaligned)
4414 Flags |= 4;
4415
4416 // The cleanup-function (a destructor) must be called when the exception
4417 // object's lifetime ends.
4418 llvm::Constant *CleanupFn = llvm::Constant::getNullValue(Ty: CGM.Int8PtrTy);
4419 if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
4420 if (CXXDestructorDecl *DtorD = RD->getDestructor())
4421 if (!DtorD->isTrivial())
4422 CleanupFn = CGM.getAddrOfCXXStructor(GD: GlobalDecl(DtorD, Dtor_Complete));
4423 // This is unused as far as we can tell, initialize it to null.
4424 llvm::Constant *ForwardCompat =
4425 getImageRelativeConstant(PtrVal: llvm::Constant::getNullValue(Ty: CGM.Int8PtrTy));
4426 llvm::Constant *PointerToCatchableTypes = getImageRelativeConstant(PtrVal: CTA);
4427 llvm::StructType *TIType = getThrowInfoType();
4428 llvm::Constant *Fields[] = {
4429 llvm::ConstantInt::get(Ty: CGM.IntTy, V: Flags), // Flags
4430 getImageRelativeConstant(PtrVal: CleanupFn), // CleanupFn
4431 ForwardCompat, // ForwardCompat
4432 PointerToCatchableTypes // CatchableTypeArray
4433 };
4434 auto *GV = new llvm::GlobalVariable(
4435 CGM.getModule(), TIType, /*isConstant=*/true, getLinkageForRTTI(Ty: T),
4436 llvm::ConstantStruct::get(T: TIType, V: Fields), MangledName.str());
4437 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4438 GV->setSection(".xdata");
4439 if (GV->isWeakForLinker())
4440 GV->setComdat(CGM.getModule().getOrInsertComdat(Name: GV->getName()));
4441 return GV;
4442}
4443
4444void MicrosoftCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) {
4445 const Expr *SubExpr = E->getSubExpr();
4446 assert(SubExpr && "SubExpr cannot be null");
4447 QualType ThrowType = SubExpr->getType();
4448 // The exception object lives on the stack and it's address is passed to the
4449 // runtime function.
4450 Address AI = CGF.CreateMemTemp(T: ThrowType);
4451 CGF.EmitAnyExprToMem(E: SubExpr, Location: AI, Quals: ThrowType.getQualifiers(),
4452 /*IsInit=*/IsInitializer: true);
4453
4454 // The so-called ThrowInfo is used to describe how the exception object may be
4455 // caught.
4456 llvm::GlobalVariable *TI = getThrowInfo(T: ThrowType);
4457
4458 // Call into the runtime to throw the exception.
4459 llvm::Value *Args[] = {AI.emitRawPointer(CGF), TI};
4460 CGF.EmitNoreturnRuntimeCallOrInvoke(callee: getThrowFn(), args: Args);
4461}
4462
4463std::pair<llvm::Value *, const CXXRecordDecl *>
4464MicrosoftCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,
4465 const CXXRecordDecl *RD) {
4466 std::tie(args&: This, args: std::ignore, args&: RD) =
4467 performBaseAdjustment(CGF, Value: This, SrcRecordTy: QualType(RD->getTypeForDecl(), 0));
4468 return {CGF.GetVTablePtr(This, VTableTy: CGM.Int8PtrTy, VTableClass: RD), RD};
4469}
4470
4471bool MicrosoftCXXABI::isPermittedToBeHomogeneousAggregate(
4472 const CXXRecordDecl *RD) const {
4473 // All aggregates are permitted to be HFA on non-ARM platforms, which mostly
4474 // affects vectorcall on x64/x86.
4475 if (!CGM.getTarget().getTriple().isAArch64())
4476 return true;
4477 // MSVC Windows on Arm64 has its own rules for determining if a type is HFA
4478 // that are inconsistent with the AAPCS64 ABI. The following are our best
4479 // determination of those rules so far, based on observation of MSVC's
4480 // behavior.
4481 if (RD->isEmpty())
4482 return false;
4483 if (RD->isPolymorphic())
4484 return false;
4485 if (RD->hasNonTrivialCopyAssignment())
4486 return false;
4487 if (RD->hasNonTrivialDestructor())
4488 return false;
4489 if (RD->hasNonTrivialDefaultConstructor())
4490 return false;
4491 // These two are somewhat redundant given the caller
4492 // (ABIInfo::isHomogeneousAggregate) checks the bases and fields, but that
4493 // caller doesn't consider empty bases/fields to be non-homogenous, but it
4494 // looks like Microsoft's AArch64 ABI does care about these empty types &
4495 // anything containing/derived from one is non-homogeneous.
4496 // Instead we could add another CXXABI entry point to query this property and
4497 // have ABIInfo::isHomogeneousAggregate use that property.
4498 // I don't think any other of the features listed above could be true of a
4499 // base/field while not true of the outer struct. For example, if you have a
4500 // base/field that has an non-trivial copy assignment/dtor/default ctor, then
4501 // the outer struct's corresponding operation must be non-trivial.
4502 for (const CXXBaseSpecifier &B : RD->bases()) {
4503 if (const CXXRecordDecl *FRD = B.getType()->getAsCXXRecordDecl()) {
4504 if (!isPermittedToBeHomogeneousAggregate(RD: FRD))
4505 return false;
4506 }
4507 }
4508 // empty fields seem to be caught by the ABIInfo::isHomogeneousAggregate
4509 // checking for padding - but maybe there are ways to end up with an empty
4510 // field without padding? Not that I know of, so don't check fields here &
4511 // rely on the padding check.
4512 return true;
4513}
4514