5342 lines · cpp
1//===------- ItaniumCXXABI.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-exception6//7//===----------------------------------------------------------------------===//8//9// This provides C++ code generation targeting the Itanium C++ ABI. The class10// in this file generates structures that follow the Itanium C++ ABI, which is11// documented at:12// https://itanium-cxx-abi.github.io/cxx-abi/abi.html13// https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html14//15// It also supports the closely-related ARM ABI, documented at:16// https://developer.arm.com/documentation/ihi0041/g/17//18//===----------------------------------------------------------------------===//19 20#include "CGCXXABI.h"21#include "CGCleanup.h"22#include "CGDebugInfo.h"23#include "CGRecordLayout.h"24#include "CGVTables.h"25#include "CodeGenFunction.h"26#include "CodeGenModule.h"27#include "TargetInfo.h"28#include "clang/AST/Attr.h"29#include "clang/AST/Mangle.h"30#include "clang/AST/StmtCXX.h"31#include "clang/AST/Type.h"32#include "clang/CodeGen/ConstantInitBuilder.h"33#include "llvm/IR/DataLayout.h"34#include "llvm/IR/GlobalValue.h"35#include "llvm/IR/Instructions.h"36#include "llvm/IR/Intrinsics.h"37#include "llvm/IR/Value.h"38#include "llvm/Support/ScopedPrinter.h"39 40#include <optional>41 42using namespace clang;43using namespace CodeGen;44 45namespace {46class ItaniumCXXABI : public CodeGen::CGCXXABI {47 /// VTables - All the vtables which have been defined.48 llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;49 50 /// All the thread wrapper functions that have been used.51 llvm::SmallVector<std::pair<const VarDecl *, llvm::Function *>, 8>52 ThreadWrappers;53 54protected:55 bool UseARMMethodPtrABI;56 bool UseARMGuardVarABI;57 bool Use32BitVTableOffsetABI;58 59 ItaniumMangleContext &getMangleContext() {60 return cast<ItaniumMangleContext>(CodeGen::CGCXXABI::getMangleContext());61 }62 63public:64 ItaniumCXXABI(CodeGen::CodeGenModule &CGM,65 bool UseARMMethodPtrABI = false,66 bool UseARMGuardVarABI = false) :67 CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI),68 UseARMGuardVarABI(UseARMGuardVarABI),69 Use32BitVTableOffsetABI(false) { }70 71 bool classifyReturnType(CGFunctionInfo &FI) const override;72 73 RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const override {74 // If C++ prohibits us from making a copy, pass by address.75 if (!RD->canPassInRegisters())76 return RAA_Indirect;77 return RAA_Default;78 }79 80 bool isThisCompleteObject(GlobalDecl GD) const override {81 // The Itanium ABI has separate complete-object vs. base-object82 // variants of both constructors and destructors.83 if (isa<CXXDestructorDecl>(GD.getDecl())) {84 switch (GD.getDtorType()) {85 case Dtor_Complete:86 case Dtor_Deleting:87 return true;88 89 case Dtor_Base:90 return false;91 92 case Dtor_Comdat:93 llvm_unreachable("emitting dtor comdat as function?");94 case Dtor_Unified:95 llvm_unreachable("emitting unified dtor as function?");96 }97 llvm_unreachable("bad dtor kind");98 }99 if (isa<CXXConstructorDecl>(GD.getDecl())) {100 switch (GD.getCtorType()) {101 case Ctor_Complete:102 return true;103 104 case Ctor_Base:105 return false;106 107 case Ctor_CopyingClosure:108 case Ctor_DefaultClosure:109 llvm_unreachable("closure ctors in Itanium ABI?");110 111 case Ctor_Comdat:112 llvm_unreachable("emitting ctor comdat as function?");113 114 case Ctor_Unified:115 llvm_unreachable("emitting unified ctor as function?");116 }117 llvm_unreachable("bad dtor kind");118 }119 120 // No other kinds.121 return false;122 }123 124 bool isZeroInitializable(const MemberPointerType *MPT) override;125 126 llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT) override;127 128 CGCallee129 EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,130 const Expr *E,131 Address This,132 llvm::Value *&ThisPtrForCall,133 llvm::Value *MemFnPtr,134 const MemberPointerType *MPT) override;135 136 llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E,137 Address Base, llvm::Value *MemPtr,138 const MemberPointerType *MPT,139 bool IsInBounds) override;140 141 llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,142 const CastExpr *E,143 llvm::Value *Src) override;144 llvm::Constant *EmitMemberPointerConversion(const CastExpr *E,145 llvm::Constant *Src) override;146 147 llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT) override;148 149 llvm::Constant *EmitMemberFunctionPointer(const CXXMethodDecl *MD) override;150 llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT,151 CharUnits offset) override;152 llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT) override;153 llvm::Constant *BuildMemberPointer(const CXXMethodDecl *MD,154 CharUnits ThisAdjustment);155 156 llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,157 llvm::Value *L, llvm::Value *R,158 const MemberPointerType *MPT,159 bool Inequality) override;160 161 llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,162 llvm::Value *Addr,163 const MemberPointerType *MPT) override;164 165 void emitVirtualObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE,166 Address Ptr, QualType ElementType,167 const CXXDestructorDecl *Dtor) override;168 169 void emitRethrow(CodeGenFunction &CGF, bool isNoReturn) override;170 void emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) override;171 172 void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C) override;173 174 llvm::CallInst *175 emitTerminateForUnexpectedException(CodeGenFunction &CGF,176 llvm::Value *Exn) override;177 178 void EmitFundamentalRTTIDescriptors(const CXXRecordDecl *RD);179 llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) override;180 CatchTypeInfo181 getAddrOfCXXCatchHandlerType(QualType Ty,182 QualType CatchHandlerType) override {183 return CatchTypeInfo{getAddrOfRTTIDescriptor(Ty), 0};184 }185 186 bool shouldTypeidBeNullChecked(QualType SrcRecordTy) override;187 void EmitBadTypeidCall(CodeGenFunction &CGF) override;188 llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,189 Address ThisPtr,190 llvm::Type *StdTypeInfoPtrTy) override;191 192 bool shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,193 QualType SrcRecordTy) override;194 195 /// Determine whether we know that all instances of type RecordTy will have196 /// the same vtable pointer values, that is distinct from all other vtable197 /// pointers. While this is required by the Itanium ABI, it doesn't happen in198 /// practice in some cases due to language extensions.199 bool hasUniqueVTablePointer(QualType RecordTy) {200 const CXXRecordDecl *RD = RecordTy->getAsCXXRecordDecl();201 202 // Under -fapple-kext, multiple definitions of the same vtable may be203 // emitted.204 if (!CGM.getCodeGenOpts().AssumeUniqueVTables ||205 getContext().getLangOpts().AppleKext)206 return false;207 208 // If the type_info* would be null, the vtable might be merged with that of209 // another type.210 if (!CGM.shouldEmitRTTI())211 return false;212 213 // If there's only one definition of the vtable in the program, it has a214 // unique address.215 if (!llvm::GlobalValue::isWeakForLinker(CGM.getVTableLinkage(RD)))216 return true;217 218 // Even if there are multiple definitions of the vtable, they are required219 // by the ABI to use the same symbol name, so should be merged at load220 // time. However, if the class has hidden visibility, there can be221 // different versions of the class in different modules, and the ABI222 // library might treat them as being the same.223 if (CGM.GetLLVMVisibility(RD->getVisibility()) !=224 llvm::GlobalValue::DefaultVisibility)225 return false;226 227 return true;228 }229 230 bool shouldEmitExactDynamicCast(QualType DestRecordTy) override {231 return hasUniqueVTablePointer(DestRecordTy);232 }233 234 std::optional<ExactDynamicCastInfo>235 getExactDynamicCastInfo(QualType SrcRecordTy, QualType DestTy,236 QualType DestRecordTy) override;237 238 llvm::Value *emitDynamicCastCall(CodeGenFunction &CGF, Address Value,239 QualType SrcRecordTy, QualType DestTy,240 QualType DestRecordTy,241 llvm::BasicBlock *CastEnd) override;242 243 llvm::Value *emitExactDynamicCast(CodeGenFunction &CGF, Address ThisAddr,244 QualType SrcRecordTy, QualType DestTy,245 QualType DestRecordTy,246 const ExactDynamicCastInfo &CastInfo,247 llvm::BasicBlock *CastSuccess,248 llvm::BasicBlock *CastFail) override;249 250 llvm::Value *emitDynamicCastToVoid(CodeGenFunction &CGF, Address Value,251 QualType SrcRecordTy) override;252 253 bool EmitBadCastCall(CodeGenFunction &CGF) override;254 255 llvm::Value *256 GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This,257 const CXXRecordDecl *ClassDecl,258 const CXXRecordDecl *BaseClassDecl) override;259 260 void EmitCXXConstructors(const CXXConstructorDecl *D) override;261 262 AddedStructorArgCounts263 buildStructorSignature(GlobalDecl GD,264 SmallVectorImpl<CanQualType> &ArgTys) override;265 266 bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor,267 CXXDtorType DT) const override {268 // Itanium does not emit any destructor variant as an inline thunk.269 // Delegating may occur as an optimization, but all variants are either270 // emitted with external linkage or as linkonce if they are inline and used.271 return false;272 }273 274 void EmitCXXDestructors(const CXXDestructorDecl *D) override;275 276 void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy,277 FunctionArgList &Params) override;278 279 void EmitInstanceFunctionProlog(CodeGenFunction &CGF) override;280 281 AddedStructorArgs getImplicitConstructorArgs(CodeGenFunction &CGF,282 const CXXConstructorDecl *D,283 CXXCtorType Type,284 bool ForVirtualBase,285 bool Delegating) override;286 287 llvm::Value *getCXXDestructorImplicitParam(CodeGenFunction &CGF,288 const CXXDestructorDecl *DD,289 CXXDtorType Type,290 bool ForVirtualBase,291 bool Delegating) override;292 293 void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD,294 CXXDtorType Type, bool ForVirtualBase,295 bool Delegating, Address This,296 QualType ThisTy) override;297 298 void emitVTableDefinitions(CodeGenVTables &CGVT,299 const CXXRecordDecl *RD) override;300 301 bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF,302 CodeGenFunction::VPtr Vptr) override;303 304 bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass) override {305 return true;306 }307 308 llvm::Constant *309 getVTableAddressPoint(BaseSubobject Base,310 const CXXRecordDecl *VTableClass) override;311 312 llvm::Value *getVTableAddressPointInStructor(313 CodeGenFunction &CGF, const CXXRecordDecl *VTableClass,314 BaseSubobject Base, const CXXRecordDecl *NearestVBase) override;315 316 llvm::Value *getVTableAddressPointInStructorWithVTT(317 CodeGenFunction &CGF, const CXXRecordDecl *VTableClass,318 BaseSubobject Base, const CXXRecordDecl *NearestVBase);319 320 llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD,321 CharUnits VPtrOffset) override;322 323 CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,324 Address This, llvm::Type *Ty,325 SourceLocation Loc) override;326 327 llvm::Value *328 EmitVirtualDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *Dtor,329 CXXDtorType DtorType, Address This,330 DeleteOrMemberCallExpr E,331 llvm::CallBase **CallOrInvoke) override;332 333 void emitVirtualInheritanceTables(const CXXRecordDecl *RD) override;334 335 bool canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const override;336 bool canSpeculativelyEmitVTableAsBaseClass(const CXXRecordDecl *RD) const;337 338 void setThunkLinkage(llvm::Function *Thunk, bool ForVTable, GlobalDecl GD,339 bool ReturnAdjustment) override {340 // Allow inlining of thunks by emitting them with available_externally341 // linkage together with vtables when needed.342 if (ForVTable && !Thunk->hasLocalLinkage())343 Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);344 CGM.setGVProperties(Thunk, GD);345 }346 347 bool exportThunk() override { return true; }348 349 llvm::Value *performThisAdjustment(CodeGenFunction &CGF, Address This,350 const CXXRecordDecl *UnadjustedThisClass,351 const ThunkInfo &TI) override;352 353 llvm::Value *performReturnAdjustment(CodeGenFunction &CGF, Address Ret,354 const CXXRecordDecl *UnadjustedRetClass,355 const ReturnAdjustment &RA) override;356 357 size_t getSrcArgforCopyCtor(const CXXConstructorDecl *,358 FunctionArgList &Args) const override {359 assert(!Args.empty() && "expected the arglist to not be empty!");360 return Args.size() - 1;361 }362 363 StringRef GetPureVirtualCallName() override { return "__cxa_pure_virtual"; }364 StringRef GetDeletedVirtualCallName() override365 { return "__cxa_deleted_virtual"; }366 367 CharUnits getArrayCookieSizeImpl(QualType elementType) override;368 Address InitializeArrayCookie(CodeGenFunction &CGF,369 Address NewPtr,370 llvm::Value *NumElements,371 const CXXNewExpr *expr,372 QualType ElementType) override;373 llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,374 Address allocPtr,375 CharUnits cookieSize) override;376 377 void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,378 llvm::GlobalVariable *DeclPtr,379 bool PerformInit) override;380 void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,381 llvm::FunctionCallee dtor,382 llvm::Constant *addr) override;383 384 llvm::Function *getOrCreateThreadLocalWrapper(const VarDecl *VD,385 llvm::Value *Val);386 void EmitThreadLocalInitFuncs(387 CodeGenModule &CGM,388 ArrayRef<const VarDecl *> CXXThreadLocals,389 ArrayRef<llvm::Function *> CXXThreadLocalInits,390 ArrayRef<const VarDecl *> CXXThreadLocalInitVars) override;391 392 bool usesThreadWrapperFunction(const VarDecl *VD) const override {393 return !isEmittedWithConstantInitializer(VD) ||394 mayNeedDestruction(VD);395 }396 LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD,397 QualType LValType) override;398 399 bool NeedsVTTParameter(GlobalDecl GD) override;400 401 llvm::Constant *402 getOrCreateVirtualFunctionPointerThunk(const CXXMethodDecl *MD);403 404 /**************************** RTTI Uniqueness ******************************/405 406protected:407 /// Returns true if the ABI requires RTTI type_info objects to be unique408 /// across a program.409 virtual bool shouldRTTIBeUnique() const { return true; }410 411public:412 /// What sort of unique-RTTI behavior should we use?413 enum RTTIUniquenessKind {414 /// We are guaranteeing, or need to guarantee, that the RTTI string415 /// is unique.416 RUK_Unique,417 418 /// We are not guaranteeing uniqueness for the RTTI string, so we419 /// can demote to hidden visibility but must use string comparisons.420 RUK_NonUniqueHidden,421 422 /// We are not guaranteeing uniqueness for the RTTI string, so we423 /// have to use string comparisons, but we also have to emit it with424 /// non-hidden visibility.425 RUK_NonUniqueVisible426 };427 428 /// Return the required visibility status for the given type and linkage in429 /// the current ABI.430 RTTIUniquenessKind431 classifyRTTIUniqueness(QualType CanTy,432 llvm::GlobalValue::LinkageTypes Linkage) const;433 friend class ItaniumRTTIBuilder;434 435 void emitCXXStructor(GlobalDecl GD) override;436 437 std::pair<llvm::Value *, const CXXRecordDecl *>438 LoadVTablePtr(CodeGenFunction &CGF, Address This,439 const CXXRecordDecl *RD) override;440 441 private:442 llvm::Constant *443 getSignedVirtualMemberFunctionPointer(const CXXMethodDecl *MD);444 445 bool hasAnyUnusedVirtualInlineFunction(const CXXRecordDecl *RD) const {446 const auto &VtableLayout =447 CGM.getItaniumVTableContext().getVTableLayout(RD);448 449 for (const auto &VtableComponent : VtableLayout.vtable_components()) {450 // Skip empty slot.451 if (!VtableComponent.isUsedFunctionPointerKind())452 continue;453 454 const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();455 const FunctionDecl *FD = Method->getDefinition();456 const bool IsInlined =457 Method->getCanonicalDecl()->isInlined() || (FD && FD->isInlined());458 if (!IsInlined)459 continue;460 461 StringRef Name = CGM.getMangledName(VtableComponent.getGlobalDecl());462 auto *Entry = CGM.GetGlobalValue(Name);463 // This checks if virtual inline function has already been emitted.464 // Note that it is possible that this inline function would be emitted465 // after trying to emit vtable speculatively. Because of this we do466 // an extra pass after emitting all deferred vtables to find and emit467 // these vtables opportunistically.468 if (!Entry || Entry->isDeclaration())469 return true;470 }471 return false;472 }473 474 bool isVTableHidden(const CXXRecordDecl *RD) const {475 const auto &VtableLayout =476 CGM.getItaniumVTableContext().getVTableLayout(RD);477 478 for (const auto &VtableComponent : VtableLayout.vtable_components()) {479 if (VtableComponent.isRTTIKind()) {480 const CXXRecordDecl *RTTIDecl = VtableComponent.getRTTIDecl();481 if (RTTIDecl->getVisibility() == Visibility::HiddenVisibility)482 return true;483 } else if (VtableComponent.isUsedFunctionPointerKind()) {484 const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();485 if (Method->getVisibility() == Visibility::HiddenVisibility &&486 !Method->isDefined())487 return true;488 }489 }490 return false;491 }492};493 494class ARMCXXABI : public ItaniumCXXABI {495public:496 ARMCXXABI(CodeGen::CodeGenModule &CGM) :497 ItaniumCXXABI(CGM, /*UseARMMethodPtrABI=*/true,498 /*UseARMGuardVarABI=*/true) {}499 500 bool constructorsAndDestructorsReturnThis() const override { return true; }501 502 void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV,503 QualType ResTy) override;504 505 CharUnits getArrayCookieSizeImpl(QualType elementType) override;506 Address InitializeArrayCookie(CodeGenFunction &CGF,507 Address NewPtr,508 llvm::Value *NumElements,509 const CXXNewExpr *expr,510 QualType ElementType) override;511 llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, Address allocPtr,512 CharUnits cookieSize) override;513};514 515class AppleARM64CXXABI : public ARMCXXABI {516public:517 AppleARM64CXXABI(CodeGen::CodeGenModule &CGM) : ARMCXXABI(CGM) {518 Use32BitVTableOffsetABI = true;519 }520 521 // ARM64 libraries are prepared for non-unique RTTI.522 bool shouldRTTIBeUnique() const override { return false; }523};524 525class FuchsiaCXXABI final : public ItaniumCXXABI {526public:527 explicit FuchsiaCXXABI(CodeGen::CodeGenModule &CGM)528 : ItaniumCXXABI(CGM) {}529 530private:531 bool constructorsAndDestructorsReturnThis() const override { return true; }532};533 534class WebAssemblyCXXABI final : public ItaniumCXXABI {535public:536 explicit WebAssemblyCXXABI(CodeGen::CodeGenModule &CGM)537 : ItaniumCXXABI(CGM, /*UseARMMethodPtrABI=*/true,538 /*UseARMGuardVarABI=*/true) {}539 void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C) override;540 llvm::CallInst *541 emitTerminateForUnexpectedException(CodeGenFunction &CGF,542 llvm::Value *Exn) override;543 544private:545 bool constructorsAndDestructorsReturnThis() const override { return true; }546 bool canCallMismatchedFunctionType() const override { return false; }547};548 549class XLCXXABI final : public ItaniumCXXABI {550public:551 explicit XLCXXABI(CodeGen::CodeGenModule &CGM)552 : ItaniumCXXABI(CGM) {}553 554 void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,555 llvm::FunctionCallee dtor,556 llvm::Constant *addr) override;557 558 bool useSinitAndSterm() const override { return true; }559 560private:561 void emitCXXStermFinalizer(const VarDecl &D, llvm::Function *dtorStub,562 llvm::Constant *addr);563};564}565 566CodeGen::CGCXXABI *CodeGen::CreateItaniumCXXABI(CodeGenModule &CGM) {567 switch (CGM.getContext().getCXXABIKind()) {568 // For IR-generation purposes, there's no significant difference569 // between the ARM and iOS ABIs.570 case TargetCXXABI::GenericARM:571 case TargetCXXABI::iOS:572 case TargetCXXABI::WatchOS:573 return new ARMCXXABI(CGM);574 575 case TargetCXXABI::AppleARM64:576 return new AppleARM64CXXABI(CGM);577 578 case TargetCXXABI::Fuchsia:579 return new FuchsiaCXXABI(CGM);580 581 // Note that AArch64 uses the generic ItaniumCXXABI class since it doesn't582 // include the other 32-bit ARM oddities: constructor/destructor return values583 // and array cookies.584 case TargetCXXABI::GenericAArch64:585 return new ItaniumCXXABI(CGM, /*UseARMMethodPtrABI=*/true,586 /*UseARMGuardVarABI=*/true);587 588 case TargetCXXABI::GenericMIPS:589 return new ItaniumCXXABI(CGM, /*UseARMMethodPtrABI=*/true);590 591 case TargetCXXABI::WebAssembly:592 return new WebAssemblyCXXABI(CGM);593 594 case TargetCXXABI::XL:595 return new XLCXXABI(CGM);596 597 case TargetCXXABI::GenericItanium:598 return new ItaniumCXXABI(CGM);599 600 case TargetCXXABI::Microsoft:601 llvm_unreachable("Microsoft ABI is not Itanium-based");602 }603 llvm_unreachable("bad ABI kind");604}605 606llvm::Type *607ItaniumCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {608 if (MPT->isMemberDataPointer())609 return CGM.PtrDiffTy;610 return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy);611}612 613/// In the Itanium and ARM ABIs, method pointers have the form:614/// struct { ptrdiff_t ptr; ptrdiff_t adj; } memptr;615///616/// In the Itanium ABI:617/// - method pointers are virtual if (memptr.ptr & 1) is nonzero618/// - the this-adjustment is (memptr.adj)619/// - the virtual offset is (memptr.ptr - 1)620///621/// In the ARM ABI:622/// - method pointers are virtual if (memptr.adj & 1) is nonzero623/// - the this-adjustment is (memptr.adj >> 1)624/// - the virtual offset is (memptr.ptr)625/// ARM uses 'adj' for the virtual flag because Thumb functions626/// may be only single-byte aligned.627///628/// If the member is virtual, the adjusted 'this' pointer points629/// to a vtable pointer from which the virtual offset is applied.630///631/// If the member is non-virtual, memptr.ptr is the address of632/// the function to call.633CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(634 CodeGenFunction &CGF, const Expr *E, Address ThisAddr,635 llvm::Value *&ThisPtrForCall,636 llvm::Value *MemFnPtr, const MemberPointerType *MPT) {637 CGBuilderTy &Builder = CGF.Builder;638 639 const FunctionProtoType *FPT =640 MPT->getPointeeType()->castAs<FunctionProtoType>();641 auto *RD = MPT->getMostRecentCXXRecordDecl();642 643 llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);644 645 llvm::BasicBlock *FnVirtual = CGF.createBasicBlock("memptr.virtual");646 llvm::BasicBlock *FnNonVirtual = CGF.createBasicBlock("memptr.nonvirtual");647 llvm::BasicBlock *FnEnd = CGF.createBasicBlock("memptr.end");648 649 // Extract memptr.adj, which is in the second field.650 llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1, "memptr.adj");651 652 // Compute the true adjustment.653 llvm::Value *Adj = RawAdj;654 if (UseARMMethodPtrABI)655 Adj = Builder.CreateAShr(Adj, ptrdiff_1, "memptr.adj.shifted");656 657 // Apply the adjustment and cast back to the original struct type658 // for consistency.659 llvm::Value *This = ThisAddr.emitRawPointer(CGF);660 This = Builder.CreateInBoundsGEP(Builder.getInt8Ty(), This, Adj);661 ThisPtrForCall = This;662 663 // Load the function pointer.664 llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0, "memptr.ptr");665 666 // If the LSB in the function pointer is 1, the function pointer points to667 // a virtual function.668 llvm::Value *IsVirtual;669 if (UseARMMethodPtrABI)670 IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);671 else672 IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);673 IsVirtual = Builder.CreateIsNotNull(IsVirtual, "memptr.isvirtual");674 Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);675 676 // In the virtual path, the adjustment left 'This' pointing to the677 // vtable of the correct base subobject. The "function pointer" is an678 // offset within the vtable (+1 for the virtual flag on non-ARM).679 CGF.EmitBlock(FnVirtual);680 681 // Cast the adjusted this to a pointer to vtable pointer and load.682 llvm::Type *VTableTy = CGF.CGM.GlobalsInt8PtrTy;683 CharUnits VTablePtrAlign =684 CGF.CGM.getDynamicOffsetAlignment(ThisAddr.getAlignment(), RD,685 CGF.getPointerAlign());686 llvm::Value *VTable = CGF.GetVTablePtr(687 Address(This, ThisAddr.getElementType(), VTablePtrAlign), VTableTy, RD);688 689 // Apply the offset.690 // On ARM64, to reserve extra space in virtual member function pointers,691 // we only pay attention to the low 32 bits of the offset.692 llvm::Value *VTableOffset = FnAsInt;693 if (!UseARMMethodPtrABI)694 VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);695 if (Use32BitVTableOffsetABI) {696 VTableOffset = Builder.CreateTrunc(VTableOffset, CGF.Int32Ty);697 VTableOffset = Builder.CreateZExt(VTableOffset, CGM.PtrDiffTy);698 }699 700 // Check the address of the function pointer if CFI on member function701 // pointers is enabled.702 llvm::Constant *CheckSourceLocation;703 llvm::Constant *CheckTypeDesc;704 bool ShouldEmitCFICheck = CGF.SanOpts.has(SanitizerKind::CFIMFCall) &&705 CGM.HasHiddenLTOVisibility(RD);706 707 if (ShouldEmitCFICheck) {708 if (const auto *BinOp = dyn_cast<BinaryOperator>(E)) {709 if (BinOp->isPtrMemOp() &&710 BinOp->getRHS()711 ->getType()712 ->hasPointeeToToCFIUncheckedCalleeFunctionType())713 ShouldEmitCFICheck = false;714 }715 }716 717 bool ShouldEmitVFEInfo = CGM.getCodeGenOpts().VirtualFunctionElimination &&718 CGM.HasHiddenLTOVisibility(RD);719 bool ShouldEmitWPDInfo =720 CGM.getCodeGenOpts().WholeProgramVTables &&721 // Don't insert type tests if we are forcing public visibility.722 !CGM.AlwaysHasLTOVisibilityPublic(RD);723 llvm::Value *VirtualFn = nullptr;724 725 {726 auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;727 auto CheckHandler = SanitizerHandler::CFICheckFail;728 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);729 730 llvm::Value *TypeId = nullptr;731 llvm::Value *CheckResult = nullptr;732 733 if (ShouldEmitCFICheck || ShouldEmitVFEInfo || ShouldEmitWPDInfo) {734 // If doing CFI, VFE or WPD, we will need the metadata node to check735 // against.736 llvm::Metadata *MD =737 CGM.CreateMetadataIdentifierForVirtualMemPtrType(QualType(MPT, 0));738 TypeId = llvm::MetadataAsValue::get(CGF.getLLVMContext(), MD);739 }740 741 if (ShouldEmitVFEInfo) {742 llvm::Value *VFPAddr =743 Builder.CreateGEP(CGF.Int8Ty, VTable, VTableOffset);744 745 // If doing VFE, load from the vtable with a type.checked.load intrinsic746 // call. Note that we use the GEP to calculate the address to load from747 // and pass 0 as the offset to the intrinsic. This is because every748 // vtable slot of the correct type is marked with matching metadata, and749 // we know that the load must be from one of these slots.750 llvm::Value *CheckedLoad = Builder.CreateCall(751 CGM.getIntrinsic(llvm::Intrinsic::type_checked_load),752 {VFPAddr, llvm::ConstantInt::get(CGM.Int32Ty, 0), TypeId});753 CheckResult = Builder.CreateExtractValue(CheckedLoad, 1);754 VirtualFn = Builder.CreateExtractValue(CheckedLoad, 0);755 } else {756 // When not doing VFE, emit a normal load, as it allows more757 // optimisations than type.checked.load.758 if (ShouldEmitCFICheck || ShouldEmitWPDInfo) {759 llvm::Value *VFPAddr =760 Builder.CreateGEP(CGF.Int8Ty, VTable, VTableOffset);761 llvm::Intrinsic::ID IID = CGM.HasHiddenLTOVisibility(RD)762 ? llvm::Intrinsic::type_test763 : llvm::Intrinsic::public_type_test;764 765 CheckResult =766 Builder.CreateCall(CGM.getIntrinsic(IID), {VFPAddr, TypeId});767 }768 769 if (CGM.getItaniumVTableContext().isRelativeLayout()) {770 VirtualFn = CGF.Builder.CreateCall(771 CGM.getIntrinsic(llvm::Intrinsic::load_relative,772 {VTableOffset->getType()}),773 {VTable, VTableOffset});774 } else {775 llvm::Value *VFPAddr =776 CGF.Builder.CreateGEP(CGF.Int8Ty, VTable, VTableOffset);777 VirtualFn = CGF.Builder.CreateAlignedLoad(CGF.DefaultPtrTy, VFPAddr,778 CGF.getPointerAlign(),779 "memptr.virtualfn");780 }781 }782 assert(VirtualFn && "Virtual fuction pointer not created!");783 assert((!ShouldEmitCFICheck || !ShouldEmitVFEInfo || !ShouldEmitWPDInfo ||784 CheckResult) &&785 "Check result required but not created!");786 787 if (ShouldEmitCFICheck) {788 // If doing CFI, emit the check.789 CheckSourceLocation = CGF.EmitCheckSourceLocation(E->getBeginLoc());790 CheckTypeDesc = CGF.EmitCheckTypeDescriptor(QualType(MPT, 0));791 llvm::Constant *StaticData[] = {792 llvm::ConstantInt::get(CGF.Int8Ty, CodeGenFunction::CFITCK_VMFCall),793 CheckSourceLocation,794 CheckTypeDesc,795 };796 797 if (CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIMFCall)) {798 CGF.EmitTrapCheck(CheckResult, CheckHandler);799 } else {800 llvm::Value *AllVtables = llvm::MetadataAsValue::get(801 CGM.getLLVMContext(),802 llvm::MDString::get(CGM.getLLVMContext(), "all-vtables"));803 llvm::Value *ValidVtable = Builder.CreateCall(804 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});805 CGF.EmitCheck(std::make_pair(CheckResult, CheckOrdinal), CheckHandler,806 StaticData, {VTable, ValidVtable});807 }808 809 FnVirtual = Builder.GetInsertBlock();810 }811 } // End of sanitizer scope812 813 CGF.EmitBranch(FnEnd);814 815 // In the non-virtual path, the function pointer is actually a816 // function pointer.817 CGF.EmitBlock(FnNonVirtual);818 llvm::Value *NonVirtualFn =819 Builder.CreateIntToPtr(FnAsInt, CGF.DefaultPtrTy, "memptr.nonvirtualfn");820 821 // Check the function pointer if CFI on member function pointers is enabled.822 if (ShouldEmitCFICheck) {823 CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();824 if (RD->hasDefinition()) {825 auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;826 auto CheckHandler = SanitizerHandler::CFICheckFail;827 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);828 829 llvm::Constant *StaticData[] = {830 llvm::ConstantInt::get(CGF.Int8Ty, CodeGenFunction::CFITCK_NVMFCall),831 CheckSourceLocation,832 CheckTypeDesc,833 };834 835 llvm::Value *Bit = Builder.getFalse();836 for (const CXXRecordDecl *Base : CGM.getMostBaseClasses(RD)) {837 llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(838 getContext().getMemberPointerType(MPT->getPointeeType(),839 /*Qualifier=*/std::nullopt,840 Base->getCanonicalDecl()));841 llvm::Value *TypeId =842 llvm::MetadataAsValue::get(CGF.getLLVMContext(), MD);843 844 llvm::Value *TypeTest =845 Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),846 {NonVirtualFn, TypeId});847 Bit = Builder.CreateOr(Bit, TypeTest);848 }849 850 CGF.EmitCheck(std::make_pair(Bit, CheckOrdinal), CheckHandler, StaticData,851 {NonVirtualFn, llvm::UndefValue::get(CGF.IntPtrTy)});852 853 FnNonVirtual = Builder.GetInsertBlock();854 }855 }856 857 // We're done.858 CGF.EmitBlock(FnEnd);859 llvm::PHINode *CalleePtr = Builder.CreatePHI(CGF.DefaultPtrTy, 2);860 CalleePtr->addIncoming(VirtualFn, FnVirtual);861 CalleePtr->addIncoming(NonVirtualFn, FnNonVirtual);862 863 CGPointerAuthInfo PointerAuth;864 865 if (const auto &Schema =866 CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers) {867 llvm::PHINode *DiscriminatorPHI = Builder.CreatePHI(CGF.IntPtrTy, 2);868 DiscriminatorPHI->addIncoming(llvm::ConstantInt::get(CGF.IntPtrTy, 0),869 FnVirtual);870 const auto &AuthInfo =871 CGM.getMemberFunctionPointerAuthInfo(QualType(MPT, 0));872 assert(Schema.getKey() == AuthInfo.getKey() &&873 "Keys for virtual and non-virtual member functions must match");874 auto *NonVirtualDiscriminator = AuthInfo.getDiscriminator();875 DiscriminatorPHI->addIncoming(NonVirtualDiscriminator, FnNonVirtual);876 PointerAuth = CGPointerAuthInfo(877 Schema.getKey(), Schema.getAuthenticationMode(), Schema.isIsaPointer(),878 Schema.authenticatesNullValues(), DiscriminatorPHI);879 }880 881 CGCallee Callee(FPT, CalleePtr, PointerAuth);882 return Callee;883}884 885/// Compute an l-value by applying the given pointer-to-member to a886/// base object.887llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(888 CodeGenFunction &CGF, const Expr *E, Address Base, llvm::Value *MemPtr,889 const MemberPointerType *MPT, bool IsInBounds) {890 assert(MemPtr->getType() == CGM.PtrDiffTy);891 892 CGBuilderTy &Builder = CGF.Builder;893 894 // Apply the offset.895 llvm::Value *BaseAddr = Base.emitRawPointer(CGF);896 return Builder.CreateGEP(CGF.Int8Ty, BaseAddr, MemPtr, "memptr.offset",897 IsInBounds ? llvm::GEPNoWrapFlags::inBounds()898 : llvm::GEPNoWrapFlags::none());899}900 901// See if it's possible to return a constant signed pointer.902static llvm::Constant *pointerAuthResignConstant(903 llvm::Value *Ptr, const CGPointerAuthInfo &CurAuthInfo,904 const CGPointerAuthInfo &NewAuthInfo, CodeGenModule &CGM) {905 const auto *CPA = dyn_cast<llvm::ConstantPtrAuth>(Ptr);906 907 if (!CPA)908 return nullptr;909 910 assert(CPA->getKey()->getZExtValue() == CurAuthInfo.getKey() &&911 CPA->getAddrDiscriminator()->isZeroValue() &&912 CPA->getDiscriminator() == CurAuthInfo.getDiscriminator() &&913 "unexpected key or discriminators");914 915 return CGM.getConstantSignedPointer(916 CPA->getPointer(), NewAuthInfo.getKey(), nullptr,917 cast<llvm::ConstantInt>(NewAuthInfo.getDiscriminator()));918}919 920/// Perform a bitcast, derived-to-base, or base-to-derived member pointer921/// conversion.922///923/// Bitcast conversions are always a no-op under Itanium.924///925/// Obligatory offset/adjustment diagram:926/// <-- offset --> <-- adjustment -->927/// |--------------------------|----------------------|--------------------|928/// ^Derived address point ^Base address point ^Member address point929///930/// So when converting a base member pointer to a derived member pointer,931/// we add the offset to the adjustment because the address point has932/// decreased; and conversely, when converting a derived MP to a base MP933/// we subtract the offset from the adjustment because the address point934/// has increased.935///936/// The standard forbids (at compile time) conversion to and from937/// virtual bases, which is why we don't have to consider them here.938///939/// The standard forbids (at run time) casting a derived MP to a base940/// MP when the derived MP does not point to a member of the base.941/// This is why -1 is a reasonable choice for null data member942/// pointers.943llvm::Value *944ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,945 const CastExpr *E,946 llvm::Value *src) {947 // Use constant emission if we can.948 if (isa<llvm::Constant>(src))949 return EmitMemberPointerConversion(E, cast<llvm::Constant>(src));950 951 assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||952 E->getCastKind() == CK_BaseToDerivedMemberPointer ||953 E->getCastKind() == CK_ReinterpretMemberPointer);954 955 CGBuilderTy &Builder = CGF.Builder;956 QualType DstType = E->getType();957 958 if (DstType->isMemberFunctionPointerType()) {959 if (const auto &NewAuthInfo =960 CGM.getMemberFunctionPointerAuthInfo(DstType)) {961 QualType SrcType = E->getSubExpr()->getType();962 assert(SrcType->isMemberFunctionPointerType());963 const auto &CurAuthInfo = CGM.getMemberFunctionPointerAuthInfo(SrcType);964 llvm::Value *MemFnPtr = Builder.CreateExtractValue(src, 0, "memptr.ptr");965 llvm::Type *OrigTy = MemFnPtr->getType();966 967 llvm::BasicBlock *StartBB = Builder.GetInsertBlock();968 llvm::BasicBlock *ResignBB = CGF.createBasicBlock("resign");969 llvm::BasicBlock *MergeBB = CGF.createBasicBlock("merge");970 971 // Check whether we have a virtual offset or a pointer to a function.972 assert(UseARMMethodPtrABI && "ARM ABI expected");973 llvm::Value *Adj = Builder.CreateExtractValue(src, 1, "memptr.adj");974 llvm::Constant *Ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);975 llvm::Value *AndVal = Builder.CreateAnd(Adj, Ptrdiff_1);976 llvm::Value *IsVirtualOffset =977 Builder.CreateIsNotNull(AndVal, "is.virtual.offset");978 Builder.CreateCondBr(IsVirtualOffset, MergeBB, ResignBB);979 980 CGF.EmitBlock(ResignBB);981 llvm::Type *PtrTy = llvm::PointerType::getUnqual(CGM.getLLVMContext());982 MemFnPtr = Builder.CreateIntToPtr(MemFnPtr, PtrTy);983 MemFnPtr =984 CGF.emitPointerAuthResign(MemFnPtr, SrcType, CurAuthInfo, NewAuthInfo,985 isa<llvm::Constant>(src));986 MemFnPtr = Builder.CreatePtrToInt(MemFnPtr, OrigTy);987 llvm::Value *ResignedVal = Builder.CreateInsertValue(src, MemFnPtr, 0);988 ResignBB = Builder.GetInsertBlock();989 990 CGF.EmitBlock(MergeBB);991 llvm::PHINode *NewSrc = Builder.CreatePHI(src->getType(), 2);992 NewSrc->addIncoming(src, StartBB);993 NewSrc->addIncoming(ResignedVal, ResignBB);994 src = NewSrc;995 }996 }997 998 // Under Itanium, reinterprets don't require any additional processing.999 if (E->getCastKind() == CK_ReinterpretMemberPointer) return src;1000 1001 llvm::Constant *adj = getMemberPointerAdjustment(E);1002 if (!adj) return src;1003 1004 bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer);1005 1006 const MemberPointerType *destTy =1007 E->getType()->castAs<MemberPointerType>();1008 1009 // For member data pointers, this is just a matter of adding the1010 // offset if the source is non-null.1011 if (destTy->isMemberDataPointer()) {1012 llvm::Value *dst;1013 if (isDerivedToBase)1014 dst = Builder.CreateNSWSub(src, adj, "adj");1015 else1016 dst = Builder.CreateNSWAdd(src, adj, "adj");1017 1018 // Null check.1019 llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());1020 llvm::Value *isNull = Builder.CreateICmpEQ(src, null, "memptr.isnull");1021 return Builder.CreateSelect(isNull, src, dst);1022 }1023 1024 // The this-adjustment is left-shifted by 1 on ARM.1025 if (UseARMMethodPtrABI) {1026 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();1027 offset <<= 1;1028 adj = llvm::ConstantInt::get(adj->getType(), offset);1029 }1030 1031 llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1, "src.adj");1032 llvm::Value *dstAdj;1033 if (isDerivedToBase)1034 dstAdj = Builder.CreateNSWSub(srcAdj, adj, "adj");1035 else1036 dstAdj = Builder.CreateNSWAdd(srcAdj, adj, "adj");1037 1038 return Builder.CreateInsertValue(src, dstAdj, 1);1039}1040 1041static llvm::Constant *1042pointerAuthResignMemberFunctionPointer(llvm::Constant *Src, QualType DestType,1043 QualType SrcType, CodeGenModule &CGM) {1044 assert(DestType->isMemberFunctionPointerType() &&1045 SrcType->isMemberFunctionPointerType() &&1046 "member function pointers expected");1047 if (DestType == SrcType)1048 return Src;1049 1050 const auto &NewAuthInfo = CGM.getMemberFunctionPointerAuthInfo(DestType);1051 const auto &CurAuthInfo = CGM.getMemberFunctionPointerAuthInfo(SrcType);1052 1053 if (!NewAuthInfo && !CurAuthInfo)1054 return Src;1055 1056 llvm::Constant *MemFnPtr = Src->getAggregateElement(0u);1057 if (MemFnPtr->getNumOperands() == 0) {1058 // src must be a pair of null pointers.1059 assert(isa<llvm::ConstantInt>(MemFnPtr) && "constant int expected");1060 return Src;1061 }1062 1063 llvm::Constant *ConstPtr = pointerAuthResignConstant(1064 cast<llvm::User>(MemFnPtr)->getOperand(0), CurAuthInfo, NewAuthInfo, CGM);1065 ConstPtr = llvm::ConstantExpr::getPtrToInt(ConstPtr, MemFnPtr->getType());1066 return ConstantFoldInsertValueInstruction(Src, ConstPtr, 0);1067}1068 1069llvm::Constant *1070ItaniumCXXABI::EmitMemberPointerConversion(const CastExpr *E,1071 llvm::Constant *src) {1072 assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||1073 E->getCastKind() == CK_BaseToDerivedMemberPointer ||1074 E->getCastKind() == CK_ReinterpretMemberPointer);1075 1076 QualType DstType = E->getType();1077 1078 if (DstType->isMemberFunctionPointerType())1079 src = pointerAuthResignMemberFunctionPointer(1080 src, DstType, E->getSubExpr()->getType(), CGM);1081 1082 // Under Itanium, reinterprets don't require any additional processing.1083 if (E->getCastKind() == CK_ReinterpretMemberPointer) return src;1084 1085 // If the adjustment is trivial, we don't need to do anything.1086 llvm::Constant *adj = getMemberPointerAdjustment(E);1087 if (!adj) return src;1088 1089 bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer);1090 1091 const MemberPointerType *destTy =1092 E->getType()->castAs<MemberPointerType>();1093 1094 // For member data pointers, this is just a matter of adding the1095 // offset if the source is non-null.1096 if (destTy->isMemberDataPointer()) {1097 // null maps to null.1098 if (src->isAllOnesValue()) return src;1099 1100 if (isDerivedToBase)1101 return llvm::ConstantExpr::getNSWSub(src, adj);1102 else1103 return llvm::ConstantExpr::getNSWAdd(src, adj);1104 }1105 1106 // The this-adjustment is left-shifted by 1 on ARM.1107 if (UseARMMethodPtrABI) {1108 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();1109 offset <<= 1;1110 adj = llvm::ConstantInt::get(adj->getType(), offset);1111 }1112 1113 llvm::Constant *srcAdj = src->getAggregateElement(1);1114 llvm::Constant *dstAdj;1115 if (isDerivedToBase)1116 dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);1117 else1118 dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);1119 1120 llvm::Constant *res = ConstantFoldInsertValueInstruction(src, dstAdj, 1);1121 assert(res != nullptr && "Folding must succeed");1122 return res;1123}1124 1125llvm::Constant *1126ItaniumCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {1127 // Itanium C++ ABI 2.3:1128 // A NULL pointer is represented as -1.1129 if (MPT->isMemberDataPointer())1130 return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL, /*isSigned=*/true);1131 1132 llvm::Constant *Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);1133 llvm::Constant *Values[2] = { Zero, Zero };1134 return llvm::ConstantStruct::getAnon(Values);1135}1136 1137llvm::Constant *1138ItaniumCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,1139 CharUnits offset) {1140 // Itanium C++ ABI 2.3:1141 // A pointer to data member is an offset from the base address of1142 // the class object containing it, represented as a ptrdiff_t1143 return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.getQuantity());1144}1145 1146llvm::Constant *1147ItaniumCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) {1148 return BuildMemberPointer(MD, CharUnits::Zero());1149}1150 1151llvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD,1152 CharUnits ThisAdjustment) {1153 assert(MD->isInstance() && "Member function must not be static!");1154 1155 CodeGenTypes &Types = CGM.getTypes();1156 1157 // Get the function pointer (or index if this is a virtual function).1158 llvm::Constant *MemPtr[2];1159 if (MD->isVirtual()) {1160 uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);1161 uint64_t VTableOffset;1162 if (CGM.getItaniumVTableContext().isRelativeLayout()) {1163 // Multiply by 4-byte relative offsets.1164 VTableOffset = Index * 4;1165 } else {1166 const ASTContext &Context = getContext();1167 CharUnits PointerWidth = Context.toCharUnitsFromBits(1168 Context.getTargetInfo().getPointerWidth(LangAS::Default));1169 VTableOffset = Index * PointerWidth.getQuantity();1170 }1171 1172 if (UseARMMethodPtrABI) {1173 // ARM C++ ABI 3.2.1:1174 // This ABI specifies that adj contains twice the this1175 // adjustment, plus 1 if the member function is virtual. The1176 // least significant bit of adj then makes exactly the same1177 // discrimination as the least significant bit of ptr does for1178 // Itanium.1179 1180 // We cannot use the Itanium ABI's representation for virtual member1181 // function pointers under pointer authentication because it would1182 // require us to store both the virtual offset and the constant1183 // discriminator in the pointer, which would be immediately vulnerable1184 // to attack. Instead we introduce a thunk that does the virtual dispatch1185 // and store it as if it were a non-virtual member function. This means1186 // that virtual function pointers may not compare equal anymore, but1187 // fortunately they aren't required to by the standard, and we do make1188 // a best-effort attempt to re-use the thunk.1189 //1190 // To support interoperation with code in which pointer authentication1191 // is disabled, derefencing a member function pointer must still handle1192 // the virtual case, but it can use a discriminator which should never1193 // be valid.1194 const auto &Schema =1195 CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers;1196 if (Schema)1197 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(1198 getSignedVirtualMemberFunctionPointer(MD), CGM.PtrDiffTy);1199 else1200 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);1201 // Don't set the LSB of adj to 1 if pointer authentication for member1202 // function pointers is enabled.1203 MemPtr[1] = llvm::ConstantInt::get(1204 CGM.PtrDiffTy, 2 * ThisAdjustment.getQuantity() + !Schema);1205 } else {1206 // Itanium C++ ABI 2.3:1207 // For a virtual function, [the pointer field] is 1 plus the1208 // virtual table offset (in bytes) of the function,1209 // represented as a ptrdiff_t.1210 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);1211 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,1212 ThisAdjustment.getQuantity());1213 }1214 } else {1215 const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();1216 llvm::Type *Ty;1217 // Check whether the function has a computable LLVM signature.1218 if (Types.isFuncTypeConvertible(FPT)) {1219 // The function has a computable LLVM signature; use the correct type.1220 Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));1221 } else {1222 // Use an arbitrary non-function type to tell GetAddrOfFunction that the1223 // function type is incomplete.1224 Ty = CGM.PtrDiffTy;1225 }1226 llvm::Constant *addr = CGM.getMemberFunctionPointer(MD, Ty);1227 1228 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);1229 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,1230 (UseARMMethodPtrABI ? 2 : 1) *1231 ThisAdjustment.getQuantity());1232 }1233 1234 return llvm::ConstantStruct::getAnon(MemPtr);1235}1236 1237llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const APValue &MP,1238 QualType MPType) {1239 const MemberPointerType *MPT = MPType->castAs<MemberPointerType>();1240 const ValueDecl *MPD = MP.getMemberPointerDecl();1241 if (!MPD)1242 return EmitNullMemberPointer(MPT);1243 1244 CharUnits ThisAdjustment = getContext().getMemberPointerPathAdjustment(MP);1245 1246 if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {1247 llvm::Constant *Src = BuildMemberPointer(MD, ThisAdjustment);1248 QualType SrcType = getContext().getMemberPointerType(1249 MD->getType(), /*Qualifier=*/std::nullopt, MD->getParent());1250 return pointerAuthResignMemberFunctionPointer(Src, MPType, SrcType, CGM);1251 }1252 1253 CharUnits FieldOffset =1254 getContext().toCharUnitsFromBits(getContext().getFieldOffset(MPD));1255 return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset);1256}1257 1258/// The comparison algorithm is pretty easy: the member pointers are1259/// the same if they're either bitwise identical *or* both null.1260///1261/// ARM is different here only because null-ness is more complicated.1262llvm::Value *1263ItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,1264 llvm::Value *L,1265 llvm::Value *R,1266 const MemberPointerType *MPT,1267 bool Inequality) {1268 CGBuilderTy &Builder = CGF.Builder;1269 1270 llvm::ICmpInst::Predicate Eq;1271 llvm::Instruction::BinaryOps And, Or;1272 if (Inequality) {1273 Eq = llvm::ICmpInst::ICMP_NE;1274 And = llvm::Instruction::Or;1275 Or = llvm::Instruction::And;1276 } else {1277 Eq = llvm::ICmpInst::ICMP_EQ;1278 And = llvm::Instruction::And;1279 Or = llvm::Instruction::Or;1280 }1281 1282 // Member data pointers are easy because there's a unique null1283 // value, so it just comes down to bitwise equality.1284 if (MPT->isMemberDataPointer())1285 return Builder.CreateICmp(Eq, L, R);1286 1287 // For member function pointers, the tautologies are more complex.1288 // The Itanium tautology is:1289 // (L == R) <==> (L.ptr == R.ptr && (L.ptr == 0 || L.adj == R.adj))1290 // The ARM tautology is:1291 // (L == R) <==> (L.ptr == R.ptr &&1292 // (L.adj == R.adj ||1293 // (L.ptr == 0 && ((L.adj|R.adj) & 1) == 0)))1294 // The inequality tautologies have exactly the same structure, except1295 // applying De Morgan's laws.1296 1297 llvm::Value *LPtr = Builder.CreateExtractValue(L, 0, "lhs.memptr.ptr");1298 llvm::Value *RPtr = Builder.CreateExtractValue(R, 0, "rhs.memptr.ptr");1299 1300 // This condition tests whether L.ptr == R.ptr. This must always be1301 // true for equality to hold.1302 llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr, "cmp.ptr");1303 1304 // This condition, together with the assumption that L.ptr == R.ptr,1305 // tests whether the pointers are both null. ARM imposes an extra1306 // condition.1307 llvm::Value *Zero = llvm::Constant::getNullValue(LPtr->getType());1308 llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr, Zero, "cmp.ptr.null");1309 1310 // This condition tests whether L.adj == R.adj. If this isn't1311 // true, the pointers are unequal unless they're both null.1312 llvm::Value *LAdj = Builder.CreateExtractValue(L, 1, "lhs.memptr.adj");1313 llvm::Value *RAdj = Builder.CreateExtractValue(R, 1, "rhs.memptr.adj");1314 llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj, "cmp.adj");1315 1316 // Null member function pointers on ARM clear the low bit of Adj,1317 // so the zero condition has to check that neither low bit is set.1318 if (UseARMMethodPtrABI) {1319 llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);1320 1321 // Compute (l.adj | r.adj) & 1 and test it against zero.1322 llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj, "or.adj");1323 llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);1324 llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, Zero,1325 "cmp.or.adj");1326 EqZero = Builder.CreateBinOp(And, EqZero, OrAdjAnd1EqZero);1327 }1328 1329 // Tie together all our conditions.1330 llvm::Value *Result = Builder.CreateBinOp(Or, EqZero, AdjEq);1331 Result = Builder.CreateBinOp(And, PtrEq, Result,1332 Inequality ? "memptr.ne" : "memptr.eq");1333 return Result;1334}1335 1336llvm::Value *1337ItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,1338 llvm::Value *MemPtr,1339 const MemberPointerType *MPT) {1340 CGBuilderTy &Builder = CGF.Builder;1341 1342 /// For member data pointers, this is just a check against -1.1343 if (MPT->isMemberDataPointer()) {1344 assert(MemPtr->getType() == CGM.PtrDiffTy);1345 llvm::Value *NegativeOne =1346 llvm::Constant::getAllOnesValue(MemPtr->getType());1347 return Builder.CreateICmpNE(MemPtr, NegativeOne, "memptr.tobool");1348 }1349 1350 // In Itanium, a member function pointer is not null if 'ptr' is not null.1351 llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0, "memptr.ptr");1352 1353 llvm::Constant *Zero = llvm::ConstantInt::get(Ptr->getType(), 0);1354 llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero, "memptr.tobool");1355 1356 // On ARM, a member function pointer is also non-null if the low bit of 'adj'1357 // (the virtual bit) is set.1358 if (UseARMMethodPtrABI) {1359 llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);1360 llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1, "memptr.adj");1361 llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One, "memptr.virtualbit");1362 llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero,1363 "memptr.isvirtual");1364 Result = Builder.CreateOr(Result, IsVirtual);1365 }1366 1367 return Result;1368}1369 1370bool ItaniumCXXABI::classifyReturnType(CGFunctionInfo &FI) const {1371 const CXXRecordDecl *RD = FI.getReturnType()->getAsCXXRecordDecl();1372 if (!RD)1373 return false;1374 1375 // If C++ prohibits us from making a copy, return by address.1376 if (!RD->canPassInRegisters()) {1377 auto Align = CGM.getContext().getTypeAlignInChars(FI.getReturnType());1378 FI.getReturnInfo() = ABIArgInfo::getIndirect(1379 Align, /*AddrSpace=*/CGM.getDataLayout().getAllocaAddrSpace(),1380 /*ByVal=*/false);1381 return true;1382 }1383 return false;1384}1385 1386/// The Itanium ABI requires non-zero initialization only for data1387/// member pointers, for which '0' is a valid offset.1388bool ItaniumCXXABI::isZeroInitializable(const MemberPointerType *MPT) {1389 return MPT->isMemberFunctionPointer();1390}1391 1392/// The Itanium ABI always places an offset to the complete object1393/// at entry -2 in the vtable.1394void ItaniumCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF,1395 const CXXDeleteExpr *DE,1396 Address Ptr,1397 QualType ElementType,1398 const CXXDestructorDecl *Dtor) {1399 bool UseGlobalDelete = DE->isGlobalDelete();1400 if (UseGlobalDelete) {1401 // Derive the complete-object pointer, which is what we need1402 // to pass to the deallocation function.1403 1404 // Grab the vtable pointer as an intptr_t*.1405 auto *ClassDecl = ElementType->castAsCXXRecordDecl();1406 llvm::Value *VTable = CGF.GetVTablePtr(Ptr, CGF.DefaultPtrTy, ClassDecl);1407 1408 // Track back to entry -2 and pull out the offset there.1409 llvm::Value *OffsetPtr = CGF.Builder.CreateConstInBoundsGEP1_64(1410 CGF.IntPtrTy, VTable, -2, "complete-offset.ptr");1411 llvm::Value *Offset = CGF.Builder.CreateAlignedLoad(CGF.IntPtrTy, OffsetPtr,1412 CGF.getPointerAlign());1413 1414 // Apply the offset.1415 llvm::Value *CompletePtr = Ptr.emitRawPointer(CGF);1416 CompletePtr =1417 CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, CompletePtr, Offset);1418 1419 // If we're supposed to call the global delete, make sure we do so1420 // even if the destructor throws.1421 CGF.pushCallObjectDeleteCleanup(DE->getOperatorDelete(), CompletePtr,1422 ElementType);1423 }1424 1425 // FIXME: Provide a source location here even though there's no1426 // CXXMemberCallExpr for dtor call.1427 CXXDtorType DtorType = UseGlobalDelete ? Dtor_Complete : Dtor_Deleting;1428 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE,1429 /*CallOrInvoke=*/nullptr);1430 1431 if (UseGlobalDelete)1432 CGF.PopCleanupBlock();1433}1434 1435void ItaniumCXXABI::emitRethrow(CodeGenFunction &CGF, bool isNoReturn) {1436 // void __cxa_rethrow();1437 1438 llvm::FunctionType *FTy =1439 llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);1440 1441 llvm::FunctionCallee Fn = CGM.CreateRuntimeFunction(FTy, "__cxa_rethrow");1442 1443 if (isNoReturn)1444 CGF.EmitNoreturnRuntimeCallOrInvoke(Fn, {});1445 else1446 CGF.EmitRuntimeCallOrInvoke(Fn);1447}1448 1449static llvm::FunctionCallee getAllocateExceptionFn(CodeGenModule &CGM) {1450 // void *__cxa_allocate_exception(size_t thrown_size);1451 1452 llvm::FunctionType *FTy =1453 llvm::FunctionType::get(CGM.Int8PtrTy, CGM.SizeTy, /*isVarArg=*/false);1454 1455 return CGM.CreateRuntimeFunction(FTy, "__cxa_allocate_exception");1456}1457 1458static llvm::FunctionCallee getThrowFn(CodeGenModule &CGM) {1459 // void __cxa_throw(void *thrown_exception, std::type_info *tinfo,1460 // void (*dest) (void *));1461 1462 llvm::Type *Args[3] = { CGM.Int8PtrTy, CGM.GlobalsInt8PtrTy, CGM.Int8PtrTy };1463 llvm::FunctionType *FTy =1464 llvm::FunctionType::get(CGM.VoidTy, Args, /*isVarArg=*/false);1465 1466 return CGM.CreateRuntimeFunction(FTy, "__cxa_throw");1467}1468 1469void ItaniumCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) {1470 QualType ThrowType = E->getSubExpr()->getType();1471 // Now allocate the exception object.1472 llvm::Type *SizeTy = CGF.ConvertType(getContext().getSizeType());1473 uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();1474 1475 llvm::FunctionCallee AllocExceptionFn = getAllocateExceptionFn(CGM);1476 llvm::CallInst *ExceptionPtr = CGF.EmitNounwindRuntimeCall(1477 AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize), "exception");1478 1479 CharUnits ExnAlign = CGF.getContext().getExnObjectAlignment();1480 CGF.EmitAnyExprToExn(1481 E->getSubExpr(), Address(ExceptionPtr, CGM.Int8Ty, ExnAlign));1482 1483 // Now throw the exception.1484 llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,1485 /*ForEH=*/true);1486 1487 // The address of the destructor. If the exception type has a1488 // trivial destructor (or isn't a record), we just pass null.1489 llvm::Constant *Dtor = nullptr;1490 if (const auto *Record = ThrowType->getAsCXXRecordDecl();1491 Record && !Record->hasTrivialDestructor()) {1492 // __cxa_throw is declared to take its destructor as void (*)(void *). We1493 // must match that if function pointers can be authenticated with a1494 // discriminator based on their type.1495 const ASTContext &Ctx = getContext();1496 QualType DtorTy = Ctx.getFunctionType(Ctx.VoidTy, {Ctx.VoidPtrTy},1497 FunctionProtoType::ExtProtoInfo());1498 1499 CXXDestructorDecl *DtorD = Record->getDestructor();1500 Dtor = CGM.getAddrOfCXXStructor(GlobalDecl(DtorD, Dtor_Complete));1501 Dtor = CGM.getFunctionPointer(Dtor, DtorTy);1502 }1503 if (!Dtor) Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);1504 1505 llvm::Value *args[] = { ExceptionPtr, TypeInfo, Dtor };1506 CGF.EmitNoreturnRuntimeCallOrInvoke(getThrowFn(CGM), args);1507}1508 1509static llvm::FunctionCallee getItaniumDynamicCastFn(CodeGenFunction &CGF) {1510 // void *__dynamic_cast(const void *sub,1511 // global_as const abi::__class_type_info *src,1512 // global_as const abi::__class_type_info *dst,1513 // std::ptrdiff_t src2dst_offset);1514 1515 llvm::Type *Int8PtrTy = CGF.Int8PtrTy;1516 llvm::Type *GlobInt8PtrTy = CGF.GlobalsInt8PtrTy;1517 llvm::Type *PtrDiffTy =1518 CGF.ConvertType(CGF.getContext().getPointerDiffType());1519 1520 llvm::Type *Args[4] = { Int8PtrTy, GlobInt8PtrTy, GlobInt8PtrTy, PtrDiffTy };1521 1522 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args, false);1523 1524 // Mark the function as nounwind willreturn readonly.1525 llvm::AttrBuilder FuncAttrs(CGF.getLLVMContext());1526 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);1527 FuncAttrs.addAttribute(llvm::Attribute::WillReturn);1528 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());1529 llvm::AttributeList Attrs = llvm::AttributeList::get(1530 CGF.getLLVMContext(), llvm::AttributeList::FunctionIndex, FuncAttrs);1531 1532 return CGF.CGM.CreateRuntimeFunction(FTy, "__dynamic_cast", Attrs);1533}1534 1535static llvm::FunctionCallee getBadCastFn(CodeGenFunction &CGF) {1536 // void __cxa_bad_cast();1537 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.VoidTy, false);1538 return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_bad_cast");1539}1540 1541/// Compute the src2dst_offset hint as described in the1542/// Itanium C++ ABI [2.9.7]1543static CharUnits computeOffsetHint(ASTContext &Context,1544 const CXXRecordDecl *Src,1545 const CXXRecordDecl *Dst) {1546 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,1547 /*DetectVirtual=*/false);1548 1549 // If Dst is not derived from Src we can skip the whole computation below and1550 // return that Src is not a public base of Dst. Record all inheritance paths.1551 if (!Dst->isDerivedFrom(Src, Paths))1552 return CharUnits::fromQuantity(-2ULL);1553 1554 unsigned NumPublicPaths = 0;1555 CharUnits Offset;1556 1557 // Now walk all possible inheritance paths.1558 for (const CXXBasePath &Path : Paths) {1559 if (Path.Access != AS_public) // Ignore non-public inheritance.1560 continue;1561 1562 ++NumPublicPaths;1563 1564 for (const CXXBasePathElement &PathElement : Path) {1565 // If the path contains a virtual base class we can't give any hint.1566 // -1: no hint.1567 if (PathElement.Base->isVirtual())1568 return CharUnits::fromQuantity(-1ULL);1569 1570 if (NumPublicPaths > 1) // Won't use offsets, skip computation.1571 continue;1572 1573 // Accumulate the base class offsets.1574 const ASTRecordLayout &L = Context.getASTRecordLayout(PathElement.Class);1575 Offset += L.getBaseClassOffset(1576 PathElement.Base->getType()->getAsCXXRecordDecl());1577 }1578 }1579 1580 // -2: Src is not a public base of Dst.1581 if (NumPublicPaths == 0)1582 return CharUnits::fromQuantity(-2ULL);1583 1584 // -3: Src is a multiple public base type but never a virtual base type.1585 if (NumPublicPaths > 1)1586 return CharUnits::fromQuantity(-3ULL);1587 1588 // Otherwise, the Src type is a unique public nonvirtual base type of Dst.1589 // Return the offset of Src from the origin of Dst.1590 return Offset;1591}1592 1593static llvm::FunctionCallee getBadTypeidFn(CodeGenFunction &CGF) {1594 // void __cxa_bad_typeid();1595 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.VoidTy, false);1596 1597 return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_bad_typeid");1598}1599 1600bool ItaniumCXXABI::shouldTypeidBeNullChecked(QualType SrcRecordTy) {1601 return true;1602}1603 1604void ItaniumCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) {1605 llvm::FunctionCallee Fn = getBadTypeidFn(CGF);1606 llvm::CallBase *Call = CGF.EmitRuntimeCallOrInvoke(Fn);1607 Call->setDoesNotReturn();1608 CGF.Builder.CreateUnreachable();1609}1610 1611llvm::Value *ItaniumCXXABI::EmitTypeid(CodeGenFunction &CGF,1612 QualType SrcRecordTy,1613 Address ThisPtr,1614 llvm::Type *StdTypeInfoPtrTy) {1615 auto *ClassDecl = SrcRecordTy->castAsCXXRecordDecl();1616 llvm::Value *Value = CGF.GetVTablePtr(ThisPtr, CGM.GlobalsInt8PtrTy,1617 ClassDecl);1618 1619 if (CGM.getItaniumVTableContext().isRelativeLayout()) {1620 // Load the type info.1621 Value = CGF.Builder.CreateCall(1622 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),1623 {Value, llvm::ConstantInt::get(CGM.Int32Ty, -4)});1624 } else {1625 // Load the type info.1626 Value =1627 CGF.Builder.CreateConstInBoundsGEP1_64(StdTypeInfoPtrTy, Value, -1ULL);1628 }1629 return CGF.Builder.CreateAlignedLoad(StdTypeInfoPtrTy, Value,1630 CGF.getPointerAlign());1631}1632 1633bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,1634 QualType SrcRecordTy) {1635 return SrcIsPtr;1636}1637 1638llvm::Value *ItaniumCXXABI::emitDynamicCastCall(1639 CodeGenFunction &CGF, Address ThisAddr, QualType SrcRecordTy,1640 QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd) {1641 llvm::Type *PtrDiffLTy =1642 CGF.ConvertType(CGF.getContext().getPointerDiffType());1643 1644 llvm::Value *SrcRTTI =1645 CGF.CGM.GetAddrOfRTTIDescriptor(SrcRecordTy.getUnqualifiedType());1646 llvm::Value *DestRTTI =1647 CGF.CGM.GetAddrOfRTTIDescriptor(DestRecordTy.getUnqualifiedType());1648 1649 // Compute the offset hint.1650 const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();1651 const CXXRecordDecl *DestDecl = DestRecordTy->getAsCXXRecordDecl();1652 llvm::Value *OffsetHint = llvm::ConstantInt::get(1653 PtrDiffLTy,1654 computeOffsetHint(CGF.getContext(), SrcDecl, DestDecl).getQuantity());1655 1656 // Emit the call to __dynamic_cast.1657 llvm::Value *Value = ThisAddr.emitRawPointer(CGF);1658 if (CGM.getCodeGenOpts().PointerAuth.CXXVTablePointers) {1659 // We perform a no-op load of the vtable pointer here to force an1660 // authentication. In environments that do not support pointer1661 // authentication this is a an actual no-op that will be elided. When1662 // pointer authentication is supported and enforced on vtable pointers this1663 // load can trap.1664 llvm::Value *Vtable =1665 CGF.GetVTablePtr(ThisAddr, CGM.Int8PtrTy, SrcDecl,1666 CodeGenFunction::VTableAuthMode::MustTrap);1667 assert(Vtable);1668 (void)Vtable;1669 }1670 1671 llvm::Value *args[] = {Value, SrcRTTI, DestRTTI, OffsetHint};1672 Value = CGF.EmitNounwindRuntimeCall(getItaniumDynamicCastFn(CGF), args);1673 1674 /// C++ [expr.dynamic.cast]p9:1675 /// A failed cast to reference type throws std::bad_cast1676 if (DestTy->isReferenceType()) {1677 llvm::BasicBlock *BadCastBlock =1678 CGF.createBasicBlock("dynamic_cast.bad_cast");1679 1680 llvm::Value *IsNull = CGF.Builder.CreateIsNull(Value);1681 CGF.Builder.CreateCondBr(IsNull, BadCastBlock, CastEnd);1682 1683 CGF.EmitBlock(BadCastBlock);1684 EmitBadCastCall(CGF);1685 }1686 1687 return Value;1688}1689 1690std::optional<CGCXXABI::ExactDynamicCastInfo>1691ItaniumCXXABI::getExactDynamicCastInfo(QualType SrcRecordTy, QualType DestTy,1692 QualType DestRecordTy) {1693 assert(shouldEmitExactDynamicCast(DestRecordTy));1694 1695 ASTContext &Context = getContext();1696 1697 // Find all the inheritance paths.1698 const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();1699 const CXXRecordDecl *DestDecl = DestRecordTy->getAsCXXRecordDecl();1700 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,1701 /*DetectVirtual=*/false);1702 (void)DestDecl->isDerivedFrom(SrcDecl, Paths);1703 1704 // Find an offset within `DestDecl` where a `SrcDecl` instance and its vptr1705 // might appear.1706 std::optional<CharUnits> Offset;1707 for (const CXXBasePath &Path : Paths) {1708 // dynamic_cast only finds public inheritance paths.1709 if (Path.Access != AS_public)1710 continue;1711 1712 CharUnits PathOffset;1713 for (const CXXBasePathElement &PathElement : Path) {1714 // Find the offset along this inheritance step.1715 const CXXRecordDecl *Base =1716 PathElement.Base->getType()->getAsCXXRecordDecl();1717 if (PathElement.Base->isVirtual()) {1718 // For a virtual base class, we know that the derived class is exactly1719 // DestDecl, so we can use the vbase offset from its layout.1720 const ASTRecordLayout &L = Context.getASTRecordLayout(DestDecl);1721 PathOffset = L.getVBaseClassOffset(Base);1722 } else {1723 const ASTRecordLayout &L =1724 Context.getASTRecordLayout(PathElement.Class);1725 PathOffset += L.getBaseClassOffset(Base);1726 }1727 }1728 1729 if (!Offset)1730 Offset = PathOffset;1731 else if (Offset != PathOffset) {1732 // Base appears in at least two different places.1733 return ExactDynamicCastInfo{/*RequiresCastToPrimaryBase=*/true,1734 CharUnits::Zero()};1735 }1736 }1737 if (!Offset)1738 return std::nullopt;1739 return ExactDynamicCastInfo{/*RequiresCastToPrimaryBase=*/false, *Offset};1740}1741 1742llvm::Value *ItaniumCXXABI::emitExactDynamicCast(1743 CodeGenFunction &CGF, Address ThisAddr, QualType SrcRecordTy,1744 QualType DestTy, QualType DestRecordTy,1745 const ExactDynamicCastInfo &ExactCastInfo, llvm::BasicBlock *CastSuccess,1746 llvm::BasicBlock *CastFail) {1747 const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();1748 const CXXRecordDecl *DestDecl = DestRecordTy->getAsCXXRecordDecl();1749 auto AuthenticateVTable = [&](Address ThisAddr, const CXXRecordDecl *Decl) {1750 if (!CGF.getLangOpts().PointerAuthCalls)1751 return;1752 (void)CGF.GetVTablePtr(ThisAddr, CGF.DefaultPtrTy, Decl,1753 CodeGenFunction::VTableAuthMode::MustTrap);1754 };1755 1756 bool PerformPostCastAuthentication = false;1757 llvm::Value *VTable = nullptr;1758 if (ExactCastInfo.RequiresCastToPrimaryBase) {1759 // Base appears in at least two different places. Find the most-derived1760 // object and see if it's a DestDecl. Note that the most-derived object1761 // must be at least as aligned as this base class subobject, and must1762 // have a vptr at offset 0.1763 llvm::Value *PrimaryBase =1764 emitDynamicCastToVoid(CGF, ThisAddr, SrcRecordTy);1765 ThisAddr = Address(PrimaryBase, CGF.VoidPtrTy, ThisAddr.getAlignment());1766 SrcDecl = DestDecl;1767 // This unauthenticated load is unavoidable, so we're relying on the1768 // authenticated load in the dynamic cast to void, and we'll manually1769 // authenticate the resulting v-table at the end of the cast check.1770 PerformPostCastAuthentication = CGF.getLangOpts().PointerAuthCalls;1771 CGPointerAuthInfo StrippingAuthInfo(0, PointerAuthenticationMode::Strip,1772 false, false, nullptr);1773 Address VTablePtrPtr = ThisAddr.withElementType(CGF.VoidPtrPtrTy);1774 VTable = CGF.Builder.CreateLoad(VTablePtrPtr, "vtable");1775 if (PerformPostCastAuthentication)1776 VTable = CGF.EmitPointerAuthAuth(StrippingAuthInfo, VTable);1777 } else1778 VTable = CGF.GetVTablePtr(ThisAddr, CGF.DefaultPtrTy, SrcDecl);1779 1780 // Compare the vptr against the expected vptr for the destination type at1781 // this offset.1782 llvm::Constant *ExpectedVTable = getVTableAddressPoint(1783 BaseSubobject(SrcDecl, ExactCastInfo.Offset), DestDecl);1784 llvm::Value *Success = CGF.Builder.CreateICmpEQ(VTable, ExpectedVTable);1785 llvm::Value *AdjustedThisPtr = ThisAddr.emitRawPointer(CGF);1786 1787 if (!ExactCastInfo.Offset.isZero()) {1788 CharUnits::QuantityType Offset = ExactCastInfo.Offset.getQuantity();1789 llvm::Constant *OffsetConstant =1790 llvm::ConstantInt::get(CGF.PtrDiffTy, -Offset);1791 AdjustedThisPtr = CGF.Builder.CreateInBoundsGEP(CGF.CharTy, AdjustedThisPtr,1792 OffsetConstant);1793 PerformPostCastAuthentication = CGF.getLangOpts().PointerAuthCalls;1794 }1795 1796 if (PerformPostCastAuthentication) {1797 // If we've changed the object pointer we authenticate the vtable pointer1798 // of the resulting object.1799 llvm::BasicBlock *NonNullBlock = CGF.Builder.GetInsertBlock();1800 llvm::BasicBlock *PostCastAuthSuccess =1801 CGF.createBasicBlock("dynamic_cast.postauth.success");1802 llvm::BasicBlock *PostCastAuthComplete =1803 CGF.createBasicBlock("dynamic_cast.postauth.complete");1804 CGF.Builder.CreateCondBr(Success, PostCastAuthSuccess,1805 PostCastAuthComplete);1806 CGF.EmitBlock(PostCastAuthSuccess);1807 Address AdjustedThisAddr =1808 Address(AdjustedThisPtr, CGF.IntPtrTy, CGF.getPointerAlign());1809 AuthenticateVTable(AdjustedThisAddr, DestDecl);1810 CGF.EmitBranch(PostCastAuthComplete);1811 CGF.EmitBlock(PostCastAuthComplete);1812 llvm::PHINode *PHI = CGF.Builder.CreatePHI(AdjustedThisPtr->getType(), 2);1813 PHI->addIncoming(AdjustedThisPtr, PostCastAuthSuccess);1814 llvm::Value *NullValue =1815 llvm::Constant::getNullValue(AdjustedThisPtr->getType());1816 PHI->addIncoming(NullValue, NonNullBlock);1817 AdjustedThisPtr = PHI;1818 }1819 CGF.Builder.CreateCondBr(Success, CastSuccess, CastFail);1820 return AdjustedThisPtr;1821}1822 1823llvm::Value *ItaniumCXXABI::emitDynamicCastToVoid(CodeGenFunction &CGF,1824 Address ThisAddr,1825 QualType SrcRecordTy) {1826 auto *ClassDecl = SrcRecordTy->castAsCXXRecordDecl();1827 llvm::Value *OffsetToTop;1828 if (CGM.getItaniumVTableContext().isRelativeLayout()) {1829 // Get the vtable pointer.1830 llvm::Value *VTable =1831 CGF.GetVTablePtr(ThisAddr, CGF.DefaultPtrTy, ClassDecl);1832 1833 // Get the offset-to-top from the vtable.1834 OffsetToTop =1835 CGF.Builder.CreateConstInBoundsGEP1_32(CGM.Int32Ty, VTable, -2U);1836 OffsetToTop = CGF.Builder.CreateAlignedLoad(1837 CGM.Int32Ty, OffsetToTop, CharUnits::fromQuantity(4), "offset.to.top");1838 } else {1839 llvm::Type *PtrDiffLTy =1840 CGF.ConvertType(CGF.getContext().getPointerDiffType());1841 1842 // Get the vtable pointer.1843 llvm::Value *VTable =1844 CGF.GetVTablePtr(ThisAddr, CGF.DefaultPtrTy, ClassDecl);1845 1846 // Get the offset-to-top from the vtable.1847 OffsetToTop =1848 CGF.Builder.CreateConstInBoundsGEP1_64(PtrDiffLTy, VTable, -2ULL);1849 OffsetToTop = CGF.Builder.CreateAlignedLoad(1850 PtrDiffLTy, OffsetToTop, CGF.getPointerAlign(), "offset.to.top");1851 }1852 // Finally, add the offset to the pointer.1853 return CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, ThisAddr.emitRawPointer(CGF),1854 OffsetToTop);1855}1856 1857bool ItaniumCXXABI::EmitBadCastCall(CodeGenFunction &CGF) {1858 llvm::FunctionCallee Fn = getBadCastFn(CGF);1859 llvm::CallBase *Call = CGF.EmitRuntimeCallOrInvoke(Fn);1860 Call->setDoesNotReturn();1861 CGF.Builder.CreateUnreachable();1862 return true;1863}1864 1865llvm::Value *1866ItaniumCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF,1867 Address This,1868 const CXXRecordDecl *ClassDecl,1869 const CXXRecordDecl *BaseClassDecl) {1870 llvm::Value *VTablePtr = CGF.GetVTablePtr(This, CGM.Int8PtrTy, ClassDecl);1871 CharUnits VBaseOffsetOffset =1872 CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,1873 BaseClassDecl);1874 llvm::Value *VBaseOffsetPtr =1875 CGF.Builder.CreateConstGEP1_64(1876 CGF.Int8Ty, VTablePtr, VBaseOffsetOffset.getQuantity(),1877 "vbase.offset.ptr");1878 1879 llvm::Value *VBaseOffset;1880 if (CGM.getItaniumVTableContext().isRelativeLayout()) {1881 VBaseOffset = CGF.Builder.CreateAlignedLoad(1882 CGF.Int32Ty, VBaseOffsetPtr, CharUnits::fromQuantity(4),1883 "vbase.offset");1884 } else {1885 VBaseOffset = CGF.Builder.CreateAlignedLoad(1886 CGM.PtrDiffTy, VBaseOffsetPtr, CGF.getPointerAlign(), "vbase.offset");1887 }1888 return VBaseOffset;1889}1890 1891void ItaniumCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) {1892 // Just make sure we're in sync with TargetCXXABI.1893 assert(CGM.getTarget().getCXXABI().hasConstructorVariants());1894 1895 // The constructor used for constructing this as a base class;1896 // ignores virtual bases.1897 CGM.EmitGlobal(GlobalDecl(D, Ctor_Base));1898 1899 // The constructor used for constructing this as a complete class;1900 // constructs the virtual bases, then calls the base constructor.1901 if (!D->getParent()->isAbstract()) {1902 // We don't need to emit the complete ctor if the class is abstract.1903 CGM.EmitGlobal(GlobalDecl(D, Ctor_Complete));1904 }1905}1906 1907CGCXXABI::AddedStructorArgCounts1908ItaniumCXXABI::buildStructorSignature(GlobalDecl GD,1909 SmallVectorImpl<CanQualType> &ArgTys) {1910 ASTContext &Context = getContext();1911 1912 // All parameters are already in place except VTT, which goes after 'this'.1913 // These are Clang types, so we don't need to worry about sret yet.1914 1915 // Check if we need to add a VTT parameter (which has type global void **).1916 if ((isa<CXXConstructorDecl>(GD.getDecl()) ? GD.getCtorType() == Ctor_Base1917 : GD.getDtorType() == Dtor_Base) &&1918 cast<CXXMethodDecl>(GD.getDecl())->getParent()->getNumVBases() != 0) {1919 LangAS AS = CGM.GetGlobalVarAddressSpace(nullptr);1920 QualType Q = Context.getAddrSpaceQualType(Context.VoidPtrTy, AS);1921 ArgTys.insert(ArgTys.begin() + 1,1922 Context.getPointerType(CanQualType::CreateUnsafe(Q)));1923 return AddedStructorArgCounts::prefix(1);1924 }1925 return AddedStructorArgCounts{};1926}1927 1928void ItaniumCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) {1929 // The destructor used for destructing this as a base class; ignores1930 // virtual bases.1931 CGM.EmitGlobal(GlobalDecl(D, Dtor_Base));1932 1933 // The destructor used for destructing this as a most-derived class;1934 // call the base destructor and then destructs any virtual bases.1935 CGM.EmitGlobal(GlobalDecl(D, Dtor_Complete));1936 1937 // The destructor in a virtual table is always a 'deleting'1938 // destructor, which calls the complete destructor and then uses the1939 // appropriate operator delete.1940 if (D->isVirtual())1941 CGM.EmitGlobal(GlobalDecl(D, Dtor_Deleting));1942}1943 1944void ItaniumCXXABI::addImplicitStructorParams(CodeGenFunction &CGF,1945 QualType &ResTy,1946 FunctionArgList &Params) {1947 const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());1948 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));1949 1950 // Check if we need a VTT parameter as well.1951 if (NeedsVTTParameter(CGF.CurGD)) {1952 ASTContext &Context = getContext();1953 1954 // FIXME: avoid the fake decl1955 LangAS AS = CGM.GetGlobalVarAddressSpace(nullptr);1956 QualType Q = Context.getAddrSpaceQualType(Context.VoidPtrTy, AS);1957 QualType T = Context.getPointerType(Q);1958 auto *VTTDecl = ImplicitParamDecl::Create(1959 Context, /*DC=*/nullptr, MD->getLocation(), &Context.Idents.get("vtt"),1960 T, ImplicitParamKind::CXXVTT);1961 Params.insert(Params.begin() + 1, VTTDecl);1962 getStructorImplicitParamDecl(CGF) = VTTDecl;1963 }1964}1965 1966void ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {1967 // Naked functions have no prolog.1968 if (CGF.CurFuncDecl && CGF.CurFuncDecl->hasAttr<NakedAttr>())1969 return;1970 1971 /// Initialize the 'this' slot. In the Itanium C++ ABI, no prologue1972 /// adjustments are required, because they are all handled by thunks.1973 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));1974 1975 /// Initialize the 'vtt' slot if needed.1976 if (getStructorImplicitParamDecl(CGF)) {1977 getStructorImplicitParamValue(CGF) = CGF.Builder.CreateLoad(1978 CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)), "vtt");1979 }1980 1981 /// If this is a function that the ABI specifies returns 'this', initialize1982 /// the return slot to 'this' at the start of the function.1983 ///1984 /// Unlike the setting of return types, this is done within the ABI1985 /// implementation instead of by clients of CGCXXABI because:1986 /// 1) getThisValue is currently protected1987 /// 2) in theory, an ABI could implement 'this' returns some other way;1988 /// HasThisReturn only specifies a contract, not the implementation1989 if (HasThisReturn(CGF.CurGD))1990 CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);1991}1992 1993CGCXXABI::AddedStructorArgs ItaniumCXXABI::getImplicitConstructorArgs(1994 CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type,1995 bool ForVirtualBase, bool Delegating) {1996 if (!NeedsVTTParameter(GlobalDecl(D, Type)))1997 return AddedStructorArgs{};1998 1999 // Insert the implicit 'vtt' argument as the second argument. Make sure to2000 // correctly reflect its address space, which can differ from generic on2001 // some targets.2002 llvm::Value *VTT =2003 CGF.GetVTTParameter(GlobalDecl(D, Type), ForVirtualBase, Delegating);2004 LangAS AS = CGM.GetGlobalVarAddressSpace(nullptr);2005 QualType Q = getContext().getAddrSpaceQualType(getContext().VoidPtrTy, AS);2006 QualType VTTTy = getContext().getPointerType(Q);2007 return AddedStructorArgs::prefix({{VTT, VTTTy}});2008}2009 2010llvm::Value *ItaniumCXXABI::getCXXDestructorImplicitParam(2011 CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type,2012 bool ForVirtualBase, bool Delegating) {2013 GlobalDecl GD(DD, Type);2014 return CGF.GetVTTParameter(GD, ForVirtualBase, Delegating);2015}2016 2017void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF,2018 const CXXDestructorDecl *DD,2019 CXXDtorType Type, bool ForVirtualBase,2020 bool Delegating, Address This,2021 QualType ThisTy) {2022 GlobalDecl GD(DD, Type);2023 llvm::Value *VTT =2024 getCXXDestructorImplicitParam(CGF, DD, Type, ForVirtualBase, Delegating);2025 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);2026 2027 CGCallee Callee;2028 if (getContext().getLangOpts().AppleKext &&2029 Type != Dtor_Base && DD->isVirtual())2030 Callee = CGF.BuildAppleKextVirtualDestructorCall(DD, Type, DD->getParent());2031 else2032 Callee = CGCallee::forDirect(CGM.getAddrOfCXXStructor(GD), GD);2033 2034 CGF.EmitCXXDestructorCall(GD, Callee, CGF.getAsNaturalPointerTo(This, ThisTy),2035 ThisTy, VTT, VTTTy, nullptr);2036}2037 2038// Check if any non-inline method has the specified attribute.2039template <typename T>2040static bool CXXRecordNonInlineHasAttr(const CXXRecordDecl *RD) {2041 for (const auto *D : RD->noload_decls()) {2042 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {2043 if (FD->isInlined() || FD->doesThisDeclarationHaveABody() ||2044 FD->isPureVirtual())2045 continue;2046 if (D->hasAttr<T>())2047 return true;2048 }2049 }2050 2051 return false;2052}2053 2054static void setVTableSelectiveDLLImportExport(CodeGenModule &CGM,2055 llvm::GlobalVariable *VTable,2056 const CXXRecordDecl *RD) {2057 if (VTable->getDLLStorageClass() !=2058 llvm::GlobalVariable::DefaultStorageClass ||2059 RD->hasAttr<DLLImportAttr>() || RD->hasAttr<DLLExportAttr>())2060 return;2061 2062 if (CGM.getVTables().isVTableExternal(RD)) {2063 if (CXXRecordNonInlineHasAttr<DLLImportAttr>(RD))2064 VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);2065 } else if (CXXRecordNonInlineHasAttr<DLLExportAttr>(RD))2066 VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);2067}2068 2069void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,2070 const CXXRecordDecl *RD) {2071 llvm::GlobalVariable *VTable = getAddrOfVTable(RD, CharUnits());2072 if (VTable->hasInitializer())2073 return;2074 2075 ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext();2076 const VTableLayout &VTLayout = VTContext.getVTableLayout(RD);2077 llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);2078 llvm::Constant *RTTI =2079 CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getCanonicalTagType(RD));2080 2081 // Create and set the initializer.2082 ConstantInitBuilder builder(CGM);2083 auto components = builder.beginStruct();2084 CGVT.createVTableInitializer(components, VTLayout, RTTI,2085 llvm::GlobalValue::isLocalLinkage(Linkage));2086 components.finishAndSetAsInitializer(VTable);2087 2088 // Set the correct linkage.2089 VTable->setLinkage(Linkage);2090 2091 if (CGM.supportsCOMDAT() && VTable->isWeakForLinker())2092 VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));2093 2094 if (CGM.getTarget().hasPS4DLLImportExport())2095 setVTableSelectiveDLLImportExport(CGM, VTable, RD);2096 2097 // Set the right visibility.2098 CGM.setGVProperties(VTable, RD);2099 2100 // If this is the magic class __cxxabiv1::__fundamental_type_info,2101 // we will emit the typeinfo for the fundamental types. This is the2102 // same behaviour as GCC.2103 const DeclContext *DC = RD->getDeclContext();2104 if (RD->getIdentifier() &&2105 RD->getIdentifier()->isStr("__fundamental_type_info") &&2106 isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() &&2107 cast<NamespaceDecl>(DC)->getIdentifier()->isStr("__cxxabiv1") &&2108 DC->getParent()->isTranslationUnit())2109 EmitFundamentalRTTIDescriptors(RD);2110 2111 // Always emit type metadata on non-available_externally definitions, and on2112 // available_externally definitions if we are performing whole program2113 // devirtualization. For WPD we need the type metadata on all vtable2114 // definitions to ensure we associate derived classes with base classes2115 // defined in headers but with a strong definition only in a shared library.2116 if (!VTable->isDeclarationForLinker() ||2117 CGM.getCodeGenOpts().WholeProgramVTables) {2118 CGM.EmitVTableTypeMetadata(RD, VTable, VTLayout);2119 // For available_externally definitions, add the vtable to2120 // @llvm.compiler.used so that it isn't deleted before whole program2121 // analysis.2122 if (VTable->isDeclarationForLinker()) {2123 assert(CGM.getCodeGenOpts().WholeProgramVTables);2124 CGM.addCompilerUsedGlobal(VTable);2125 }2126 }2127 2128 if (VTContext.isRelativeLayout()) {2129 CGVT.RemoveHwasanMetadata(VTable);2130 if (!VTable->isDSOLocal())2131 CGVT.GenerateRelativeVTableAlias(VTable, VTable->getName());2132 }2133 2134 // Emit symbol for debugger only if requested debug info.2135 if (CGDebugInfo *DI = CGM.getModuleDebugInfo())2136 DI->emitVTableSymbol(VTable, RD);2137}2138 2139bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(2140 CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr) {2141 if (Vptr.NearestVBase == nullptr)2142 return false;2143 return NeedsVTTParameter(CGF.CurGD);2144}2145 2146llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(2147 CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base,2148 const CXXRecordDecl *NearestVBase) {2149 2150 if ((Base.getBase()->getNumVBases() || NearestVBase != nullptr) &&2151 NeedsVTTParameter(CGF.CurGD)) {2152 return getVTableAddressPointInStructorWithVTT(CGF, VTableClass, Base,2153 NearestVBase);2154 }2155 return getVTableAddressPoint(Base, VTableClass);2156}2157 2158llvm::Constant *2159ItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base,2160 const CXXRecordDecl *VTableClass) {2161 llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass, CharUnits());2162 2163 // Find the appropriate vtable within the vtable group, and the address point2164 // within that vtable.2165 const VTableLayout &Layout =2166 CGM.getItaniumVTableContext().getVTableLayout(VTableClass);2167 VTableLayout::AddressPointLocation AddressPoint =2168 Layout.getAddressPoint(Base);2169 llvm::Value *Indices[] = {2170 llvm::ConstantInt::get(CGM.Int32Ty, 0),2171 llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.VTableIndex),2172 llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.AddressPointIndex),2173 };2174 2175 // Add inrange attribute to indicate that only the VTableIndex can be2176 // accessed.2177 unsigned ComponentSize =2178 CGM.getDataLayout().getTypeAllocSize(CGM.getVTableComponentType());2179 unsigned VTableSize =2180 ComponentSize * Layout.getVTableSize(AddressPoint.VTableIndex);2181 unsigned Offset = ComponentSize * AddressPoint.AddressPointIndex;2182 llvm::ConstantRange InRange(2183 llvm::APInt(32, (int)-Offset, true),2184 llvm::APInt(32, (int)(VTableSize - Offset), true));2185 return llvm::ConstantExpr::getGetElementPtr(2186 VTable->getValueType(), VTable, Indices, /*InBounds=*/true, InRange);2187}2188 2189llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(2190 CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base,2191 const CXXRecordDecl *NearestVBase) {2192 assert((Base.getBase()->getNumVBases() || NearestVBase != nullptr) &&2193 NeedsVTTParameter(CGF.CurGD) && "This class doesn't have VTT");2194 2195 // Get the secondary vpointer index.2196 uint64_t VirtualPointerIndex =2197 CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base);2198 2199 /// Load the VTT.2200 llvm::Value *VTT = CGF.LoadCXXVTT();2201 if (VirtualPointerIndex)2202 VTT = CGF.Builder.CreateConstInBoundsGEP1_64(CGF.GlobalsVoidPtrTy, VTT,2203 VirtualPointerIndex);2204 2205 // And load the address point from the VTT.2206 llvm::Value *AP =2207 CGF.Builder.CreateAlignedLoad(CGF.GlobalsVoidPtrTy, VTT,2208 CGF.getPointerAlign());2209 2210 if (auto &Schema = CGF.CGM.getCodeGenOpts().PointerAuth.CXXVTTVTablePointers) {2211 CGPointerAuthInfo PointerAuth = CGF.EmitPointerAuthInfo(Schema, VTT,2212 GlobalDecl(),2213 QualType());2214 AP = CGF.EmitPointerAuthAuth(PointerAuth, AP);2215 }2216 2217 return AP;2218}2219 2220llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,2221 CharUnits VPtrOffset) {2222 assert(VPtrOffset.isZero() && "Itanium ABI only supports zero vptr offsets");2223 2224 llvm::GlobalVariable *&VTable = VTables[RD];2225 if (VTable)2226 return VTable;2227 2228 // Queue up this vtable for possible deferred emission.2229 CGM.addDeferredVTable(RD);2230 2231 SmallString<256> Name;2232 llvm::raw_svector_ostream Out(Name);2233 getMangleContext().mangleCXXVTable(RD, Out);2234 2235 const VTableLayout &VTLayout =2236 CGM.getItaniumVTableContext().getVTableLayout(RD);2237 llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);2238 2239 // Use pointer to global alignment for the vtable. Otherwise we would align2240 // them based on the size of the initializer which doesn't make sense as only2241 // single values are read.2242 unsigned PAlign = CGM.getVtableGlobalVarAlignment();2243 2244 VTable = CGM.CreateOrReplaceCXXRuntimeVariable(2245 Name, VTableType, llvm::GlobalValue::ExternalLinkage,2246 getContext().toCharUnitsFromBits(PAlign).getAsAlign());2247 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);2248 2249 if (CGM.getTarget().hasPS4DLLImportExport())2250 setVTableSelectiveDLLImportExport(CGM, VTable, RD);2251 2252 CGM.setGVProperties(VTable, RD);2253 return VTable;2254}2255 2256CGCallee ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,2257 GlobalDecl GD,2258 Address This,2259 llvm::Type *Ty,2260 SourceLocation Loc) {2261 llvm::Type *PtrTy = CGM.GlobalsInt8PtrTy;2262 auto *MethodDecl = cast<CXXMethodDecl>(GD.getDecl());2263 llvm::Value *VTable = CGF.GetVTablePtr(This, PtrTy, MethodDecl->getParent());2264 2265 uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);2266 llvm::Value *VFunc, *VTableSlotPtr = nullptr;2267 auto &Schema = CGM.getCodeGenOpts().PointerAuth.CXXVirtualFunctionPointers;2268 2269 llvm::Type *ComponentTy = CGM.getVTables().getVTableComponentType();2270 uint64_t ByteOffset =2271 VTableIndex * CGM.getDataLayout().getTypeSizeInBits(ComponentTy) / 8;2272 2273 if (!Schema && CGF.ShouldEmitVTableTypeCheckedLoad(MethodDecl->getParent())) {2274 VFunc = CGF.EmitVTableTypeCheckedLoad(MethodDecl->getParent(), VTable,2275 PtrTy, ByteOffset);2276 } else {2277 CGF.EmitTypeMetadataCodeForVCall(MethodDecl->getParent(), VTable, Loc);2278 2279 llvm::Value *VFuncLoad;2280 if (CGM.getItaniumVTableContext().isRelativeLayout()) {2281 VFuncLoad = CGF.Builder.CreateCall(2282 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),2283 {VTable, llvm::ConstantInt::get(CGM.Int32Ty, ByteOffset)});2284 } else {2285 VTableSlotPtr = CGF.Builder.CreateConstInBoundsGEP1_64(2286 PtrTy, VTable, VTableIndex, "vfn");2287 VFuncLoad = CGF.Builder.CreateAlignedLoad(PtrTy, VTableSlotPtr,2288 CGF.getPointerAlign());2289 }2290 2291 // Add !invariant.load md to virtual function load to indicate that2292 // function didn't change inside vtable.2293 // It's safe to add it without -fstrict-vtable-pointers, but it would not2294 // help in devirtualization because it will only matter if we will have 22295 // the same virtual function loads from the same vtable load, which won't2296 // happen without enabled devirtualization with -fstrict-vtable-pointers.2297 if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&2298 CGM.getCodeGenOpts().StrictVTablePointers) {2299 if (auto *VFuncLoadInstr = dyn_cast<llvm::Instruction>(VFuncLoad)) {2300 VFuncLoadInstr->setMetadata(2301 llvm::LLVMContext::MD_invariant_load,2302 llvm::MDNode::get(CGM.getLLVMContext(),2303 llvm::ArrayRef<llvm::Metadata *>()));2304 }2305 }2306 VFunc = VFuncLoad;2307 }2308 2309 CGPointerAuthInfo PointerAuth;2310 if (Schema) {2311 assert(VTableSlotPtr && "virtual function pointer not set");2312 GD = CGM.getItaniumVTableContext().findOriginalMethod(GD.getCanonicalDecl());2313 PointerAuth = CGF.EmitPointerAuthInfo(Schema, VTableSlotPtr, GD, QualType());2314 }2315 CGCallee Callee(GD, VFunc, PointerAuth);2316 return Callee;2317}2318 2319llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(2320 CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType DtorType,2321 Address This, DeleteOrMemberCallExpr E, llvm::CallBase **CallOrInvoke) {2322 auto *CE = dyn_cast<const CXXMemberCallExpr *>(E);2323 auto *D = dyn_cast<const CXXDeleteExpr *>(E);2324 assert((CE != nullptr) ^ (D != nullptr));2325 assert(CE == nullptr || CE->arguments().empty());2326 assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);2327 2328 GlobalDecl GD(Dtor, DtorType);2329 const CGFunctionInfo *FInfo =2330 &CGM.getTypes().arrangeCXXStructorDeclaration(GD);2331 llvm::FunctionType *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo);2332 CGCallee Callee = CGCallee::forVirtual(CE, GD, This, Ty);2333 2334 QualType ThisTy;2335 if (CE) {2336 ThisTy = CE->getObjectType();2337 } else {2338 ThisTy = D->getDestroyedType();2339 }2340 2341 CGF.EmitCXXDestructorCall(GD, Callee, This.emitRawPointer(CGF), ThisTy,2342 nullptr, QualType(), nullptr, CallOrInvoke);2343 return nullptr;2344}2345 2346void ItaniumCXXABI::emitVirtualInheritanceTables(const CXXRecordDecl *RD) {2347 CodeGenVTables &VTables = CGM.getVTables();2348 llvm::GlobalVariable *VTT = VTables.GetAddrOfVTT(RD);2349 VTables.EmitVTTDefinition(VTT, CGM.getVTableLinkage(RD), RD);2350}2351 2352bool ItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass(2353 const CXXRecordDecl *RD) const {2354 // We don't emit available_externally vtables if we are in -fapple-kext mode2355 // because kext mode does not permit devirtualization.2356 if (CGM.getLangOpts().AppleKext)2357 return false;2358 2359 // If the vtable is hidden then it is not safe to emit an available_externally2360 // copy of vtable.2361 if (isVTableHidden(RD))2362 return false;2363 2364 if (CGM.getCodeGenOpts().ForceEmitVTables)2365 return true;2366 2367 // A speculative vtable can only be generated if all virtual inline functions2368 // defined by this class are emitted. The vtable in the final program contains2369 // for each virtual inline function not used in the current TU a function that2370 // is equivalent to the unused function. The function in the actual vtable2371 // does not have to be declared under the same symbol (e.g., a virtual2372 // destructor that can be substituted with its base class's destructor). Since2373 // inline functions are emitted lazily and this emissions does not account for2374 // speculative emission of a vtable, we might generate a speculative vtable2375 // with references to inline functions that are not emitted under that name.2376 // This can lead to problems when devirtualizing a call to such a function,2377 // that result in linking errors. Hence, if there are any unused virtual2378 // inline function, we cannot emit the speculative vtable.2379 // FIXME we can still emit a copy of the vtable if we2380 // can emit definition of the inline functions.2381 if (hasAnyUnusedVirtualInlineFunction(RD))2382 return false;2383 2384 // For a class with virtual bases, we must also be able to speculatively2385 // emit the VTT, because CodeGen doesn't have separate notions of "can emit2386 // the vtable" and "can emit the VTT". For a base subobject, this means we2387 // need to be able to emit non-virtual base vtables.2388 if (RD->getNumVBases()) {2389 for (const auto &B : RD->bases()) {2390 auto *BRD = B.getType()->getAsCXXRecordDecl();2391 assert(BRD && "no class for base specifier");2392 if (B.isVirtual() || !BRD->isDynamicClass())2393 continue;2394 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))2395 return false;2396 }2397 }2398 2399 return true;2400}2401 2402bool ItaniumCXXABI::canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const {2403 if (!canSpeculativelyEmitVTableAsBaseClass(RD))2404 return false;2405 2406 if (RD->shouldEmitInExternalSource())2407 return false;2408 2409 // For a complete-object vtable (or more specifically, for the VTT), we need2410 // to be able to speculatively emit the vtables of all dynamic virtual bases.2411 for (const auto &B : RD->vbases()) {2412 auto *BRD = B.getType()->getAsCXXRecordDecl();2413 assert(BRD && "no class for base specifier");2414 if (!BRD->isDynamicClass())2415 continue;2416 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))2417 return false;2418 }2419 2420 return true;2421}2422static llvm::Value *performTypeAdjustment(CodeGenFunction &CGF,2423 Address InitialPtr,2424 const CXXRecordDecl *UnadjustedClass,2425 int64_t NonVirtualAdjustment,2426 int64_t VirtualAdjustment,2427 bool IsReturnAdjustment) {2428 if (!NonVirtualAdjustment && !VirtualAdjustment)2429 return InitialPtr.emitRawPointer(CGF);2430 2431 Address V = InitialPtr.withElementType(CGF.Int8Ty);2432 2433 // In a base-to-derived cast, the non-virtual adjustment is applied first.2434 if (NonVirtualAdjustment && !IsReturnAdjustment) {2435 V = CGF.Builder.CreateConstInBoundsByteGEP(V,2436 CharUnits::fromQuantity(NonVirtualAdjustment));2437 }2438 2439 // Perform the virtual adjustment if we have one.2440 llvm::Value *ResultPtr;2441 if (VirtualAdjustment) {2442 llvm::Value *VTablePtr =2443 CGF.GetVTablePtr(V, CGF.Int8PtrTy, UnadjustedClass);2444 2445 llvm::Value *Offset;2446 llvm::Value *OffsetPtr = CGF.Builder.CreateConstInBoundsGEP1_64(2447 CGF.Int8Ty, VTablePtr, VirtualAdjustment);2448 if (CGF.CGM.getItaniumVTableContext().isRelativeLayout()) {2449 // Load the adjustment offset from the vtable as a 32-bit int.2450 Offset =2451 CGF.Builder.CreateAlignedLoad(CGF.Int32Ty, OffsetPtr,2452 CharUnits::fromQuantity(4));2453 } else {2454 llvm::Type *PtrDiffTy =2455 CGF.ConvertType(CGF.getContext().getPointerDiffType());2456 2457 // Load the adjustment offset from the vtable.2458 Offset = CGF.Builder.CreateAlignedLoad(PtrDiffTy, OffsetPtr,2459 CGF.getPointerAlign());2460 }2461 // Adjust our pointer.2462 ResultPtr = CGF.Builder.CreateInBoundsGEP(V.getElementType(),2463 V.emitRawPointer(CGF), Offset);2464 } else {2465 ResultPtr = V.emitRawPointer(CGF);2466 }2467 2468 // In a derived-to-base conversion, the non-virtual adjustment is2469 // applied second.2470 if (NonVirtualAdjustment && IsReturnAdjustment) {2471 ResultPtr = CGF.Builder.CreateConstInBoundsGEP1_64(CGF.Int8Ty, ResultPtr,2472 NonVirtualAdjustment);2473 }2474 2475 return ResultPtr;2476}2477 2478llvm::Value *2479ItaniumCXXABI::performThisAdjustment(CodeGenFunction &CGF, Address This,2480 const CXXRecordDecl *UnadjustedClass,2481 const ThunkInfo &TI) {2482 return performTypeAdjustment(CGF, This, UnadjustedClass, TI.This.NonVirtual,2483 TI.This.Virtual.Itanium.VCallOffsetOffset,2484 /*IsReturnAdjustment=*/false);2485}2486 2487llvm::Value *2488ItaniumCXXABI::performReturnAdjustment(CodeGenFunction &CGF, Address Ret,2489 const CXXRecordDecl *UnadjustedClass,2490 const ReturnAdjustment &RA) {2491 return performTypeAdjustment(CGF, Ret, UnadjustedClass, RA.NonVirtual,2492 RA.Virtual.Itanium.VBaseOffsetOffset,2493 /*IsReturnAdjustment=*/true);2494}2495 2496void ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,2497 RValue RV, QualType ResultType) {2498 if (!isa<CXXDestructorDecl>(CGF.CurGD.getDecl()))2499 return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);2500 2501 // Destructor thunks in the ARM ABI have indeterminate results.2502 llvm::Type *T = CGF.ReturnValue.getElementType();2503 RValue Undef = RValue::get(llvm::UndefValue::get(T));2504 return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);2505}2506 2507/************************** Array allocation cookies **************************/2508 2509CharUnits ItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {2510 // The array cookie is a size_t; pad that up to the element alignment.2511 // The cookie is actually right-justified in that space.2512 return std::max(CharUnits::fromQuantity(CGM.SizeSizeInBytes),2513 CGM.getContext().getPreferredTypeAlignInChars(elementType));2514}2515 2516Address ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,2517 Address NewPtr,2518 llvm::Value *NumElements,2519 const CXXNewExpr *expr,2520 QualType ElementType) {2521 assert(requiresArrayCookie(expr));2522 2523 unsigned AS = NewPtr.getAddressSpace();2524 2525 ASTContext &Ctx = getContext();2526 CharUnits SizeSize = CGF.getSizeSize();2527 2528 // The size of the cookie.2529 CharUnits CookieSize =2530 std::max(SizeSize, Ctx.getPreferredTypeAlignInChars(ElementType));2531 assert(CookieSize == getArrayCookieSizeImpl(ElementType));2532 2533 // Compute an offset to the cookie.2534 Address CookiePtr = NewPtr;2535 CharUnits CookieOffset = CookieSize - SizeSize;2536 if (!CookieOffset.isZero())2537 CookiePtr = CGF.Builder.CreateConstInBoundsByteGEP(CookiePtr, CookieOffset);2538 2539 // Write the number of elements into the appropriate slot.2540 Address NumElementsPtr = CookiePtr.withElementType(CGF.SizeTy);2541 llvm::Instruction *SI = CGF.Builder.CreateStore(NumElements, NumElementsPtr);2542 2543 // Handle the array cookie specially in ASan.2544 if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&2545 (expr->getOperatorNew()->isReplaceableGlobalAllocationFunction() ||2546 CGM.getCodeGenOpts().SanitizeAddressPoisonCustomArrayCookie)) {2547 // The store to the CookiePtr does not need to be instrumented.2548 SI->setNoSanitizeMetadata();2549 llvm::FunctionType *FTy =2550 llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.getType(), false);2551 llvm::FunctionCallee F =2552 CGM.CreateRuntimeFunction(FTy, "__asan_poison_cxx_array_cookie");2553 CGF.Builder.CreateCall(F, NumElementsPtr.emitRawPointer(CGF));2554 }2555 2556 // Finally, compute a pointer to the actual data buffer by skipping2557 // over the cookie completely.2558 return CGF.Builder.CreateConstInBoundsByteGEP(NewPtr, CookieSize);2559}2560 2561llvm::Value *ItaniumCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,2562 Address allocPtr,2563 CharUnits cookieSize) {2564 // The element size is right-justified in the cookie.2565 Address numElementsPtr = allocPtr;2566 CharUnits numElementsOffset = cookieSize - CGF.getSizeSize();2567 if (!numElementsOffset.isZero())2568 numElementsPtr =2569 CGF.Builder.CreateConstInBoundsByteGEP(numElementsPtr, numElementsOffset);2570 2571 unsigned AS = allocPtr.getAddressSpace();2572 numElementsPtr = numElementsPtr.withElementType(CGF.SizeTy);2573 if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0)2574 return CGF.Builder.CreateLoad(numElementsPtr);2575 // In asan mode emit a function call instead of a regular load and let the2576 // run-time deal with it: if the shadow is properly poisoned return the2577 // cookie, otherwise return 0 to avoid an infinite loop calling DTORs.2578 // We can't simply ignore this load using nosanitize metadata because2579 // the metadata may be lost.2580 llvm::FunctionType *FTy =2581 llvm::FunctionType::get(CGF.SizeTy, CGF.DefaultPtrTy, false);2582 llvm::FunctionCallee F =2583 CGM.CreateRuntimeFunction(FTy, "__asan_load_cxx_array_cookie");2584 return CGF.Builder.CreateCall(F, numElementsPtr.emitRawPointer(CGF));2585}2586 2587CharUnits ARMCXXABI::getArrayCookieSizeImpl(QualType elementType) {2588 // ARM says that the cookie is always:2589 // struct array_cookie {2590 // std::size_t element_size; // element_size != 02591 // std::size_t element_count;2592 // };2593 // But the base ABI doesn't give anything an alignment greater than2594 // 8, so we can dismiss this as typical ABI-author blindness to2595 // actual language complexity and round up to the element alignment.2596 return std::max(CharUnits::fromQuantity(2 * CGM.SizeSizeInBytes),2597 CGM.getContext().getTypeAlignInChars(elementType));2598}2599 2600Address ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,2601 Address newPtr,2602 llvm::Value *numElements,2603 const CXXNewExpr *expr,2604 QualType elementType) {2605 assert(requiresArrayCookie(expr));2606 2607 // The cookie is always at the start of the buffer.2608 Address cookie = newPtr;2609 2610 // The first element is the element size.2611 cookie = cookie.withElementType(CGF.SizeTy);2612 llvm::Value *elementSize = llvm::ConstantInt::get(CGF.SizeTy,2613 getContext().getTypeSizeInChars(elementType).getQuantity());2614 CGF.Builder.CreateStore(elementSize, cookie);2615 2616 // The second element is the element count.2617 cookie = CGF.Builder.CreateConstInBoundsGEP(cookie, 1);2618 CGF.Builder.CreateStore(numElements, cookie);2619 2620 // Finally, compute a pointer to the actual data buffer by skipping2621 // over the cookie completely.2622 CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);2623 return CGF.Builder.CreateConstInBoundsByteGEP(newPtr, cookieSize);2624}2625 2626llvm::Value *ARMCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,2627 Address allocPtr,2628 CharUnits cookieSize) {2629 // The number of elements is at offset sizeof(size_t) relative to2630 // the allocated pointer.2631 Address numElementsPtr2632 = CGF.Builder.CreateConstInBoundsByteGEP(allocPtr, CGF.getSizeSize());2633 2634 numElementsPtr = numElementsPtr.withElementType(CGF.SizeTy);2635 return CGF.Builder.CreateLoad(numElementsPtr);2636}2637 2638/*********************** Static local initialization **************************/2639 2640static llvm::FunctionCallee getGuardAcquireFn(CodeGenModule &CGM,2641 llvm::PointerType *GuardPtrTy) {2642 // int __cxa_guard_acquire(__guard *guard_object);2643 llvm::FunctionType *FTy =2644 llvm::FunctionType::get(CGM.getTypes().ConvertType(CGM.getContext().IntTy),2645 GuardPtrTy, /*isVarArg=*/false);2646 return CGM.CreateRuntimeFunction(2647 FTy, "__cxa_guard_acquire",2648 llvm::AttributeList::get(CGM.getLLVMContext(),2649 llvm::AttributeList::FunctionIndex,2650 llvm::Attribute::NoUnwind));2651}2652 2653static llvm::FunctionCallee getGuardReleaseFn(CodeGenModule &CGM,2654 llvm::PointerType *GuardPtrTy) {2655 // void __cxa_guard_release(__guard *guard_object);2656 llvm::FunctionType *FTy =2657 llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false);2658 return CGM.CreateRuntimeFunction(2659 FTy, "__cxa_guard_release",2660 llvm::AttributeList::get(CGM.getLLVMContext(),2661 llvm::AttributeList::FunctionIndex,2662 llvm::Attribute::NoUnwind));2663}2664 2665static llvm::FunctionCallee getGuardAbortFn(CodeGenModule &CGM,2666 llvm::PointerType *GuardPtrTy) {2667 // void __cxa_guard_abort(__guard *guard_object);2668 llvm::FunctionType *FTy =2669 llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false);2670 return CGM.CreateRuntimeFunction(2671 FTy, "__cxa_guard_abort",2672 llvm::AttributeList::get(CGM.getLLVMContext(),2673 llvm::AttributeList::FunctionIndex,2674 llvm::Attribute::NoUnwind));2675}2676 2677namespace {2678 struct CallGuardAbort final : EHScopeStack::Cleanup {2679 llvm::GlobalVariable *Guard;2680 CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}2681 2682 void Emit(CodeGenFunction &CGF, Flags flags) override {2683 CGF.EmitNounwindRuntimeCall(getGuardAbortFn(CGF.CGM, Guard->getType()),2684 Guard);2685 }2686 };2687}2688 2689/// The ARM code here follows the Itanium code closely enough that we2690/// just special-case it at particular places.2691void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,2692 const VarDecl &D,2693 llvm::GlobalVariable *var,2694 bool shouldPerformInit) {2695 CGBuilderTy &Builder = CGF.Builder;2696 2697 // Inline variables that weren't instantiated from variable templates have2698 // partially-ordered initialization within their translation unit.2699 bool NonTemplateInline =2700 D.isInline() &&2701 !isTemplateInstantiation(D.getTemplateSpecializationKind());2702 2703 // We only need to use thread-safe statics for local non-TLS variables and2704 // inline variables; other global initialization is always single-threaded2705 // or (through lazy dynamic loading in multiple threads) unsequenced.2706 bool threadsafe = getContext().getLangOpts().ThreadsafeStatics &&2707 (D.isLocalVarDecl() || NonTemplateInline) &&2708 !D.getTLSKind();2709 2710 // If we have a global variable with internal linkage and thread-safe statics2711 // are disabled, we can just let the guard variable be of type i8.2712 bool useInt8GuardVariable = !threadsafe && var->hasInternalLinkage();2713 2714 llvm::IntegerType *guardTy;2715 CharUnits guardAlignment;2716 if (useInt8GuardVariable) {2717 guardTy = CGF.Int8Ty;2718 guardAlignment = CharUnits::One();2719 } else {2720 // Guard variables are 64 bits in the generic ABI and size width on ARM2721 // (i.e. 32-bit on AArch32, 64-bit on AArch64).2722 if (UseARMGuardVarABI) {2723 guardTy = CGF.SizeTy;2724 guardAlignment = CGF.getSizeAlign();2725 } else {2726 guardTy = CGF.Int64Ty;2727 guardAlignment =2728 CharUnits::fromQuantity(CGM.getDataLayout().getABITypeAlign(guardTy));2729 }2730 }2731 llvm::PointerType *guardPtrTy = llvm::PointerType::get(2732 CGF.CGM.getLLVMContext(),2733 CGF.CGM.getDataLayout().getDefaultGlobalsAddressSpace());2734 2735 // Create the guard variable if we don't already have it (as we2736 // might if we're double-emitting this function body).2737 llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D);2738 if (!guard) {2739 // Mangle the name for the guard.2740 SmallString<256> guardName;2741 {2742 llvm::raw_svector_ostream out(guardName);2743 getMangleContext().mangleStaticGuardVariable(&D, out);2744 }2745 2746 // Create the guard variable with a zero-initializer.2747 // Just absorb linkage, visibility and dll storage class from the guarded2748 // variable.2749 guard = new llvm::GlobalVariable(CGM.getModule(), guardTy,2750 false, var->getLinkage(),2751 llvm::ConstantInt::get(guardTy, 0),2752 guardName.str());2753 guard->setDSOLocal(var->isDSOLocal());2754 guard->setVisibility(var->getVisibility());2755 guard->setDLLStorageClass(var->getDLLStorageClass());2756 // If the variable is thread-local, so is its guard variable.2757 guard->setThreadLocalMode(var->getThreadLocalMode());2758 guard->setAlignment(guardAlignment.getAsAlign());2759 2760 // The ABI says: "It is suggested that it be emitted in the same COMDAT2761 // group as the associated data object." In practice, this doesn't work for2762 // non-ELF and non-Wasm object formats, so only do it for ELF and Wasm.2763 llvm::Comdat *C = var->getComdat();2764 if (!D.isLocalVarDecl() && C &&2765 (CGM.getTarget().getTriple().isOSBinFormatELF() ||2766 CGM.getTarget().getTriple().isOSBinFormatWasm())) {2767 guard->setComdat(C);2768 } else if (CGM.supportsCOMDAT() && guard->isWeakForLinker()) {2769 guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName()));2770 }2771 2772 CGM.setStaticLocalDeclGuardAddress(&D, guard);2773 }2774 2775 Address guardAddr = Address(guard, guard->getValueType(), guardAlignment);2776 2777 // Test whether the variable has completed initialization.2778 //2779 // Itanium C++ ABI 3.3.2:2780 // The following is pseudo-code showing how these functions can be used:2781 // if (obj_guard.first_byte == 0) {2782 // if ( __cxa_guard_acquire (&obj_guard) ) {2783 // try {2784 // ... initialize the object ...;2785 // } catch (...) {2786 // __cxa_guard_abort (&obj_guard);2787 // throw;2788 // }2789 // ... queue object destructor with __cxa_atexit() ...;2790 // __cxa_guard_release (&obj_guard);2791 // }2792 // }2793 //2794 // If threadsafe statics are enabled, but we don't have inline atomics, just2795 // call __cxa_guard_acquire unconditionally. The "inline" check isn't2796 // actually inline, and the user might not expect calls to __atomic libcalls.2797 2798 unsigned MaxInlineWidthInBits = CGF.getTarget().getMaxAtomicInlineWidth();2799 llvm::BasicBlock *EndBlock = CGF.createBasicBlock("init.end");2800 if (!threadsafe || MaxInlineWidthInBits) {2801 // Load the first byte of the guard variable.2802 llvm::LoadInst *LI =2803 Builder.CreateLoad(guardAddr.withElementType(CGM.Int8Ty));2804 2805 // Itanium ABI:2806 // An implementation supporting thread-safety on multiprocessor2807 // systems must also guarantee that references to the initialized2808 // object do not occur before the load of the initialization flag.2809 //2810 // In LLVM, we do this by marking the load Acquire.2811 if (threadsafe)2812 LI->setAtomic(llvm::AtomicOrdering::Acquire);2813 2814 // For ARM, we should only check the first bit, rather than the entire byte:2815 //2816 // ARM C++ ABI 3.2.3.1:2817 // To support the potential use of initialization guard variables2818 // as semaphores that are the target of ARM SWP and LDREX/STREX2819 // synchronizing instructions we define a static initialization2820 // guard variable to be a 4-byte aligned, 4-byte word with the2821 // following inline access protocol.2822 // #define INITIALIZED 12823 // if ((obj_guard & INITIALIZED) != INITIALIZED) {2824 // if (__cxa_guard_acquire(&obj_guard))2825 // ...2826 // }2827 //2828 // and similarly for ARM64:2829 //2830 // ARM64 C++ ABI 3.2.2:2831 // This ABI instead only specifies the value bit 0 of the static guard2832 // variable; all other bits are platform defined. Bit 0 shall be 0 when the2833 // variable is not initialized and 1 when it is.2834 llvm::Value *V =2835 (UseARMGuardVarABI && !useInt8GuardVariable)2836 ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))2837 : LI;2838 llvm::Value *NeedsInit = Builder.CreateIsNull(V, "guard.uninitialized");2839 2840 llvm::BasicBlock *InitCheckBlock = CGF.createBasicBlock("init.check");2841 2842 // Check if the first byte of the guard variable is zero.2843 CGF.EmitCXXGuardedInitBranch(NeedsInit, InitCheckBlock, EndBlock,2844 CodeGenFunction::GuardKind::VariableGuard, &D);2845 2846 CGF.EmitBlock(InitCheckBlock);2847 }2848 2849 // The semantics of dynamic initialization of variables with static or thread2850 // storage duration depends on whether they are declared at block-scope. The2851 // initialization of such variables at block-scope can be aborted with an2852 // exception and later retried (per C++20 [stmt.dcl]p4), and recursive entry2853 // to their initialization has undefined behavior (also per C++202854 // [stmt.dcl]p4). For such variables declared at non-block scope, exceptions2855 // lead to termination (per C++20 [except.terminate]p1), and recursive2856 // references to the variables are governed only by the lifetime rules (per2857 // C++20 [class.cdtor]p2), which means such references are perfectly fine as2858 // long as they avoid touching memory. As a result, block-scope variables must2859 // not be marked as initialized until after initialization completes (unless2860 // the mark is reverted following an exception), but non-block-scope variables2861 // must be marked prior to initialization so that recursive accesses during2862 // initialization do not restart initialization.2863 2864 // Variables used when coping with thread-safe statics and exceptions.2865 if (threadsafe) {2866 // Call __cxa_guard_acquire.2867 llvm::Value *V2868 = CGF.EmitNounwindRuntimeCall(getGuardAcquireFn(CGM, guardPtrTy), guard);2869 2870 llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init");2871 2872 Builder.CreateCondBr(Builder.CreateIsNotNull(V, "tobool"),2873 InitBlock, EndBlock);2874 2875 // Call __cxa_guard_abort along the exceptional edge.2876 CGF.EHStack.pushCleanup<CallGuardAbort>(EHCleanup, guard);2877 2878 CGF.EmitBlock(InitBlock);2879 } else if (!D.isLocalVarDecl()) {2880 // For non-local variables, store 1 into the first byte of the guard2881 // variable before the object initialization begins so that references2882 // to the variable during initialization don't restart initialization.2883 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),2884 guardAddr.withElementType(CGM.Int8Ty));2885 }2886 2887 // Emit the initializer and add a global destructor if appropriate.2888 CGF.EmitCXXGlobalVarDeclInit(D, var, shouldPerformInit);2889 2890 if (threadsafe) {2891 // Pop the guard-abort cleanup if we pushed one.2892 CGF.PopCleanupBlock();2893 2894 // Call __cxa_guard_release. This cannot throw.2895 CGF.EmitNounwindRuntimeCall(getGuardReleaseFn(CGM, guardPtrTy),2896 guardAddr.emitRawPointer(CGF));2897 } else if (D.isLocalVarDecl()) {2898 // For local variables, store 1 into the first byte of the guard variable2899 // after the object initialization completes so that initialization is2900 // retried if initialization is interrupted by an exception.2901 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),2902 guardAddr.withElementType(CGM.Int8Ty));2903 }2904 2905 CGF.EmitBlock(EndBlock);2906}2907 2908/// Register a global destructor using __cxa_atexit.2909static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF,2910 llvm::FunctionCallee dtor,2911 llvm::Constant *addr, bool TLS) {2912 assert(!CGF.getTarget().getTriple().isOSAIX() &&2913 "unexpected call to emitGlobalDtorWithCXAAtExit");2914 assert((TLS || CGF.getTypes().getCodeGenOpts().CXAAtExit) &&2915 "__cxa_atexit is disabled");2916 const char *Name = "__cxa_atexit";2917 if (TLS) {2918 const llvm::Triple &T = CGF.getTarget().getTriple();2919 Name = T.isOSDarwin() ? "_tlv_atexit" : "__cxa_thread_atexit";2920 }2921 2922 // We're assuming that the destructor function is something we can2923 // reasonably call with the default CC.2924 llvm::Type *dtorTy = CGF.DefaultPtrTy;2925 2926 // Preserve address space of addr.2927 auto AddrAS = addr ? addr->getType()->getPointerAddressSpace() : 0;2928 auto AddrPtrTy = AddrAS ? llvm::PointerType::get(CGF.getLLVMContext(), AddrAS)2929 : CGF.Int8PtrTy;2930 2931 // Create a variable that binds the atexit to this shared object.2932 llvm::Constant *handle =2933 CGF.CGM.CreateRuntimeVariable(CGF.Int8Ty, "__dso_handle");2934 auto *GV = cast<llvm::GlobalValue>(handle->stripPointerCasts());2935 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);2936 2937 // extern "C" int __cxa_atexit(void (*f)(void *), void *p, void *d);2938 llvm::Type *paramTys[] = {dtorTy, AddrPtrTy, handle->getType()};2939 llvm::FunctionType *atexitTy =2940 llvm::FunctionType::get(CGF.IntTy, paramTys, false);2941 2942 // Fetch the actual function.2943 llvm::FunctionCallee atexit = CGF.CGM.CreateRuntimeFunction(atexitTy, Name);2944 if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit.getCallee()))2945 fn->setDoesNotThrow();2946 2947 const auto &Context = CGF.CGM.getContext();2948 FunctionProtoType::ExtProtoInfo EPI(Context.getDefaultCallingConvention(2949 /*IsVariadic=*/false, /*IsCXXMethod=*/false));2950 QualType fnType =2951 Context.getFunctionType(Context.VoidTy, {Context.VoidPtrTy}, EPI);2952 llvm::Constant *dtorCallee = cast<llvm::Constant>(dtor.getCallee());2953 dtorCallee = CGF.CGM.getFunctionPointer(dtorCallee, fnType);2954 2955 if (!addr)2956 // addr is null when we are trying to register a dtor annotated with2957 // __attribute__((destructor)) in a constructor function. Using null here is2958 // okay because this argument is just passed back to the destructor2959 // function.2960 addr = llvm::Constant::getNullValue(CGF.Int8PtrTy);2961 2962 llvm::Value *args[] = {dtorCallee, addr, handle};2963 CGF.EmitNounwindRuntimeCall(atexit, args);2964}2965 2966static llvm::Function *createGlobalInitOrCleanupFn(CodeGen::CodeGenModule &CGM,2967 StringRef FnName) {2968 // Create a function that registers/unregisters destructors that have the same2969 // priority.2970 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, false);2971 llvm::Function *GlobalInitOrCleanupFn = CGM.CreateGlobalInitOrCleanUpFunction(2972 FTy, FnName, CGM.getTypes().arrangeNullaryFunction(), SourceLocation());2973 2974 return GlobalInitOrCleanupFn;2975}2976 2977void CodeGenModule::unregisterGlobalDtorsWithUnAtExit() {2978 for (const auto &I : DtorsUsingAtExit) {2979 int Priority = I.first;2980 std::string GlobalCleanupFnName =2981 std::string("__GLOBAL_cleanup_") + llvm::to_string(Priority);2982 2983 llvm::Function *GlobalCleanupFn =2984 createGlobalInitOrCleanupFn(*this, GlobalCleanupFnName);2985 2986 CodeGenFunction CGF(*this);2987 CGF.StartFunction(GlobalDecl(), getContext().VoidTy, GlobalCleanupFn,2988 getTypes().arrangeNullaryFunction(), FunctionArgList(),2989 SourceLocation(), SourceLocation());2990 auto AL = ApplyDebugLocation::CreateArtificial(CGF);2991 2992 // Get the destructor function type, void(*)(void).2993 llvm::FunctionType *dtorFuncTy = llvm::FunctionType::get(CGF.VoidTy, false);2994 2995 // Destructor functions are run/unregistered in non-ascending2996 // order of their priorities.2997 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;2998 auto itv = Dtors.rbegin();2999 while (itv != Dtors.rend()) {3000 llvm::Function *Dtor = *itv;3001 3002 // We're assuming that the destructor function is something we can3003 // reasonably call with the correct CC.3004 llvm::Value *V = CGF.unregisterGlobalDtorWithUnAtExit(Dtor);3005 llvm::Value *NeedsDestruct =3006 CGF.Builder.CreateIsNull(V, "needs_destruct");3007 3008 llvm::BasicBlock *DestructCallBlock =3009 CGF.createBasicBlock("destruct.call");3010 llvm::BasicBlock *EndBlock = CGF.createBasicBlock(3011 (itv + 1) != Dtors.rend() ? "unatexit.call" : "destruct.end");3012 // Check if unatexit returns a value of 0. If it does, jump to3013 // DestructCallBlock, otherwise jump to EndBlock directly.3014 CGF.Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);3015 3016 CGF.EmitBlock(DestructCallBlock);3017 3018 // Emit the call to casted Dtor.3019 llvm::CallInst *CI = CGF.Builder.CreateCall(dtorFuncTy, Dtor);3020 // Make sure the call and the callee agree on calling convention.3021 CI->setCallingConv(Dtor->getCallingConv());3022 3023 CGF.EmitBlock(EndBlock);3024 3025 itv++;3026 }3027 3028 CGF.FinishFunction();3029 AddGlobalDtor(GlobalCleanupFn, Priority);3030 }3031}3032 3033void CodeGenModule::registerGlobalDtorsWithAtExit() {3034 for (const auto &I : DtorsUsingAtExit) {3035 int Priority = I.first;3036 std::string GlobalInitFnName =3037 std::string("__GLOBAL_init_") + llvm::to_string(Priority);3038 llvm::Function *GlobalInitFn =3039 createGlobalInitOrCleanupFn(*this, GlobalInitFnName);3040 3041 CodeGenFunction CGF(*this);3042 CGF.StartFunction(GlobalDecl(), getContext().VoidTy, GlobalInitFn,3043 getTypes().arrangeNullaryFunction(), FunctionArgList(),3044 SourceLocation(), SourceLocation());3045 auto AL = ApplyDebugLocation::CreateArtificial(CGF);3046 3047 // Since constructor functions are run in non-descending order of their3048 // priorities, destructors are registered in non-descending order of their3049 // priorities, and since destructor functions are run in the reverse order3050 // of their registration, destructor functions are run in non-ascending3051 // order of their priorities.3052 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;3053 for (auto *Dtor : Dtors) {3054 // Register the destructor function calling __cxa_atexit if it is3055 // available. Otherwise fall back on calling atexit.3056 if (getCodeGenOpts().CXAAtExit) {3057 emitGlobalDtorWithCXAAtExit(CGF, Dtor, nullptr, false);3058 } else {3059 // We're assuming that the destructor function is something we can3060 // reasonably call with the correct CC.3061 CGF.registerGlobalDtorWithAtExit(Dtor);3062 }3063 }3064 3065 CGF.FinishFunction();3066 AddGlobalCtor(GlobalInitFn, Priority);3067 }3068 3069 if (getCXXABI().useSinitAndSterm())3070 unregisterGlobalDtorsWithUnAtExit();3071}3072 3073/// Register a global destructor as best as we know how.3074void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,3075 llvm::FunctionCallee dtor,3076 llvm::Constant *addr) {3077 if (D.isNoDestroy(CGM.getContext()))3078 return;3079 3080 // HLSL doesn't support atexit.3081 if (CGM.getLangOpts().HLSL)3082 return CGM.AddCXXDtorEntry(dtor, addr);3083 3084 // OpenMP offloading supports C++ constructors and destructors but we do not3085 // always have 'atexit' available. Instead lower these to use the LLVM global3086 // destructors which we can handle directly in the runtime. Note that this is3087 // not strictly 1-to-1 with using `atexit` because we no longer tear down3088 // globals in reverse order of when they were constructed.3089 if (!CGM.getLangOpts().hasAtExit() && !D.isStaticLocal())3090 return CGF.registerGlobalDtorWithLLVM(D, dtor, addr);3091 3092 // emitGlobalDtorWithCXAAtExit will emit a call to either __cxa_thread_atexit3093 // or __cxa_atexit depending on whether this VarDecl is a thread-local storage3094 // or not. CXAAtExit controls only __cxa_atexit, so use it if it is enabled.3095 // We can always use __cxa_thread_atexit.3096 if (CGM.getCodeGenOpts().CXAAtExit || D.getTLSKind())3097 return emitGlobalDtorWithCXAAtExit(CGF, dtor, addr, D.getTLSKind());3098 3099 // In Apple kexts, we want to add a global destructor entry.3100 // FIXME: shouldn't this be guarded by some variable?3101 if (CGM.getLangOpts().AppleKext) {3102 // Generate a global destructor entry.3103 return CGM.AddCXXDtorEntry(dtor, addr);3104 }3105 3106 CGF.registerGlobalDtorWithAtExit(D, dtor, addr);3107}3108 3109static bool isThreadWrapperReplaceable(const VarDecl *VD,3110 CodeGen::CodeGenModule &CGM) {3111 assert(!VD->isStaticLocal() && "static local VarDecls don't need wrappers!");3112 // Darwin prefers to have references to thread local variables to go through3113 // the thread wrapper instead of directly referencing the backing variable.3114 return VD->getTLSKind() == VarDecl::TLS_Dynamic &&3115 CGM.getTarget().getTriple().isOSDarwin();3116}3117 3118/// Get the appropriate linkage for the wrapper function. This is essentially3119/// the weak form of the variable's linkage; every translation unit which needs3120/// the wrapper emits a copy, and we want the linker to merge them.3121static llvm::GlobalValue::LinkageTypes3122getThreadLocalWrapperLinkage(const VarDecl *VD, CodeGen::CodeGenModule &CGM) {3123 llvm::GlobalValue::LinkageTypes VarLinkage =3124 CGM.getLLVMLinkageVarDefinition(VD);3125 3126 // For internal linkage variables, we don't need an external or weak wrapper.3127 if (llvm::GlobalValue::isLocalLinkage(VarLinkage))3128 return VarLinkage;3129 3130 // If the thread wrapper is replaceable, give it appropriate linkage.3131 if (isThreadWrapperReplaceable(VD, CGM))3132 if (!llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) &&3133 !llvm::GlobalVariable::isWeakODRLinkage(VarLinkage))3134 return VarLinkage;3135 return llvm::GlobalValue::WeakODRLinkage;3136}3137 3138llvm::Function *3139ItaniumCXXABI::getOrCreateThreadLocalWrapper(const VarDecl *VD,3140 llvm::Value *Val) {3141 // Mangle the name for the thread_local wrapper function.3142 SmallString<256> WrapperName;3143 {3144 llvm::raw_svector_ostream Out(WrapperName);3145 getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);3146 }3147 3148 // FIXME: If VD is a definition, we should regenerate the function attributes3149 // before returning.3150 if (llvm::Value *V = CGM.getModule().getNamedValue(WrapperName))3151 return cast<llvm::Function>(V);3152 3153 QualType RetQT = VD->getType();3154 if (RetQT->isReferenceType())3155 RetQT = RetQT.getNonReferenceType();3156 3157 const CGFunctionInfo &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(3158 getContext().getPointerType(RetQT), FunctionArgList());3159 3160 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FI);3161 llvm::Function *Wrapper =3162 llvm::Function::Create(FnTy, getThreadLocalWrapperLinkage(VD, CGM),3163 WrapperName.str(), &CGM.getModule());3164 3165 if (CGM.supportsCOMDAT() && Wrapper->isWeakForLinker())3166 Wrapper->setComdat(CGM.getModule().getOrInsertComdat(Wrapper->getName()));3167 3168 CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, Wrapper, /*IsThunk=*/false);3169 3170 // Always resolve references to the wrapper at link time.3171 if (!Wrapper->hasLocalLinkage())3172 if (!isThreadWrapperReplaceable(VD, CGM) ||3173 llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) ||3174 llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()) ||3175 VD->getVisibility() == HiddenVisibility)3176 Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);3177 3178 if (isThreadWrapperReplaceable(VD, CGM)) {3179 Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);3180 Wrapper->addFnAttr(llvm::Attribute::NoUnwind);3181 }3182 3183 ThreadWrappers.push_back({VD, Wrapper});3184 return Wrapper;3185}3186 3187void ItaniumCXXABI::EmitThreadLocalInitFuncs(3188 CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals,3189 ArrayRef<llvm::Function *> CXXThreadLocalInits,3190 ArrayRef<const VarDecl *> CXXThreadLocalInitVars) {3191 llvm::Function *InitFunc = nullptr;3192 3193 // Separate initializers into those with ordered (or partially-ordered)3194 // initialization and those with unordered initialization.3195 llvm::SmallVector<llvm::Function *, 8> OrderedInits;3196 llvm::SmallDenseMap<const VarDecl *, llvm::Function *> UnorderedInits;3197 for (unsigned I = 0; I != CXXThreadLocalInits.size(); ++I) {3198 if (isTemplateInstantiation(3199 CXXThreadLocalInitVars[I]->getTemplateSpecializationKind()))3200 UnorderedInits[CXXThreadLocalInitVars[I]->getCanonicalDecl()] =3201 CXXThreadLocalInits[I];3202 else3203 OrderedInits.push_back(CXXThreadLocalInits[I]);3204 }3205 3206 if (!OrderedInits.empty()) {3207 // Generate a guarded initialization function.3208 llvm::FunctionType *FTy =3209 llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);3210 const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();3211 InitFunc = CGM.CreateGlobalInitOrCleanUpFunction(FTy, "__tls_init", FI,3212 SourceLocation(),3213 /*TLS=*/true);3214 llvm::GlobalVariable *Guard = new llvm::GlobalVariable(3215 CGM.getModule(), CGM.Int8Ty, /*isConstant=*/false,3216 llvm::GlobalVariable::InternalLinkage,3217 llvm::ConstantInt::get(CGM.Int8Ty, 0), "__tls_guard");3218 Guard->setThreadLocal(true);3219 Guard->setThreadLocalMode(CGM.GetDefaultLLVMTLSModel());3220 3221 CharUnits GuardAlign = CharUnits::One();3222 Guard->setAlignment(GuardAlign.getAsAlign());3223 3224 CodeGenFunction(CGM).GenerateCXXGlobalInitFunc(3225 InitFunc, OrderedInits, ConstantAddress(Guard, CGM.Int8Ty, GuardAlign));3226 // On Darwin platforms, use CXX_FAST_TLS calling convention.3227 if (CGM.getTarget().getTriple().isOSDarwin()) {3228 InitFunc->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);3229 InitFunc->addFnAttr(llvm::Attribute::NoUnwind);3230 }3231 }3232 3233 // Create declarations for thread wrappers for all thread-local variables3234 // with non-discardable definitions in this translation unit.3235 for (const VarDecl *VD : CXXThreadLocals) {3236 if (VD->hasDefinition() &&3237 !isDiscardableGVALinkage(getContext().GetGVALinkageForVariable(VD))) {3238 llvm::GlobalValue *GV = CGM.GetGlobalValue(CGM.getMangledName(VD));3239 getOrCreateThreadLocalWrapper(VD, GV);3240 }3241 }3242 3243 // Emit all referenced thread wrappers.3244 for (auto VDAndWrapper : ThreadWrappers) {3245 const VarDecl *VD = VDAndWrapper.first;3246 llvm::GlobalVariable *Var =3247 cast<llvm::GlobalVariable>(CGM.GetGlobalValue(CGM.getMangledName(VD)));3248 llvm::Function *Wrapper = VDAndWrapper.second;3249 3250 // Some targets require that all access to thread local variables go through3251 // the thread wrapper. This means that we cannot attempt to create a thread3252 // wrapper or a thread helper.3253 if (!VD->hasDefinition()) {3254 if (isThreadWrapperReplaceable(VD, CGM)) {3255 Wrapper->setLinkage(llvm::Function::ExternalLinkage);3256 continue;3257 }3258 3259 // If this isn't a TU in which this variable is defined, the thread3260 // wrapper is discardable.3261 if (Wrapper->getLinkage() == llvm::Function::WeakODRLinkage)3262 Wrapper->setLinkage(llvm::Function::LinkOnceODRLinkage);3263 }3264 3265 CGM.SetLLVMFunctionAttributesForDefinition(nullptr, Wrapper);3266 3267 // Mangle the name for the thread_local initialization function.3268 SmallString<256> InitFnName;3269 {3270 llvm::raw_svector_ostream Out(InitFnName);3271 getMangleContext().mangleItaniumThreadLocalInit(VD, Out);3272 }3273 3274 llvm::FunctionType *InitFnTy = llvm::FunctionType::get(CGM.VoidTy, false);3275 3276 // If we have a definition for the variable, emit the initialization3277 // function as an alias to the global Init function (if any). Otherwise,3278 // produce a declaration of the initialization function.3279 llvm::GlobalValue *Init = nullptr;3280 bool InitIsInitFunc = false;3281 bool HasConstantInitialization = false;3282 if (!usesThreadWrapperFunction(VD)) {3283 HasConstantInitialization = true;3284 } else if (VD->hasDefinition()) {3285 InitIsInitFunc = true;3286 llvm::Function *InitFuncToUse = InitFunc;3287 if (isTemplateInstantiation(VD->getTemplateSpecializationKind()))3288 InitFuncToUse = UnorderedInits.lookup(VD->getCanonicalDecl());3289 if (InitFuncToUse)3290 Init = llvm::GlobalAlias::create(Var->getLinkage(), InitFnName.str(),3291 InitFuncToUse);3292 } else {3293 // Emit a weak global function referring to the initialization function.3294 // This function will not exist if the TU defining the thread_local3295 // variable in question does not need any dynamic initialization for3296 // its thread_local variables.3297 Init = llvm::Function::Create(InitFnTy,3298 llvm::GlobalVariable::ExternalWeakLinkage,3299 InitFnName.str(), &CGM.getModule());3300 const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();3301 CGM.SetLLVMFunctionAttributes(3302 GlobalDecl(), FI, cast<llvm::Function>(Init), /*IsThunk=*/false);3303 }3304 3305 if (Init) {3306 Init->setVisibility(Var->getVisibility());3307 // Don't mark an extern_weak function DSO local on windows.3308 if (!CGM.getTriple().isOSWindows() || !Init->hasExternalWeakLinkage())3309 Init->setDSOLocal(Var->isDSOLocal());3310 }3311 3312 llvm::LLVMContext &Context = CGM.getModule().getContext();3313 3314 // The linker on AIX is not happy with missing weak symbols. However,3315 // other TUs will not know whether the initialization routine exists3316 // so create an empty, init function to satisfy the linker.3317 // This is needed whenever a thread wrapper function is not used, and3318 // also when the symbol is weak.3319 if (CGM.getTriple().isOSAIX() && VD->hasDefinition() &&3320 isEmittedWithConstantInitializer(VD, true) &&3321 !mayNeedDestruction(VD)) {3322 // Init should be null. If it were non-null, then the logic above would3323 // either be defining the function to be an alias or declaring the3324 // function with the expectation that the definition of the variable3325 // is elsewhere.3326 assert(Init == nullptr && "Expected Init to be null.");3327 3328 llvm::Function *Func = llvm::Function::Create(3329 InitFnTy, Var->getLinkage(), InitFnName.str(), &CGM.getModule());3330 const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();3331 CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI,3332 cast<llvm::Function>(Func),3333 /*IsThunk=*/false);3334 // Create a function body that just returns3335 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context, "", Func);3336 CGBuilderTy Builder(CGM, Entry);3337 Builder.CreateRetVoid();3338 }3339 3340 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context, "", Wrapper);3341 CGBuilderTy Builder(CGM, Entry);3342 if (HasConstantInitialization) {3343 // No dynamic initialization to invoke.3344 } else if (InitIsInitFunc) {3345 if (Init) {3346 llvm::CallInst *CallVal = Builder.CreateCall(InitFnTy, Init);3347 if (isThreadWrapperReplaceable(VD, CGM)) {3348 CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);3349 llvm::Function *Fn =3350 cast<llvm::Function>(cast<llvm::GlobalAlias>(Init)->getAliasee());3351 Fn->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);3352 }3353 }3354 } else if (CGM.getTriple().isOSAIX()) {3355 // On AIX, except if constinit and also neither of class type or of3356 // (possibly multi-dimensional) array of class type, thread_local vars3357 // will have init routines regardless of whether they are3358 // const-initialized. Since the routine is guaranteed to exist, we can3359 // unconditionally call it without testing for its existance. This3360 // avoids potentially unresolved weak symbols which the AIX linker3361 // isn't happy with.3362 Builder.CreateCall(InitFnTy, Init);3363 } else {3364 // Don't know whether we have an init function. Call it if it exists.3365 llvm::Value *Have = Builder.CreateIsNotNull(Init);3366 llvm::BasicBlock *InitBB = llvm::BasicBlock::Create(Context, "", Wrapper);3367 llvm::BasicBlock *ExitBB = llvm::BasicBlock::Create(Context, "", Wrapper);3368 Builder.CreateCondBr(Have, InitBB, ExitBB);3369 3370 Builder.SetInsertPoint(InitBB);3371 Builder.CreateCall(InitFnTy, Init);3372 Builder.CreateBr(ExitBB);3373 3374 Builder.SetInsertPoint(ExitBB);3375 }3376 3377 // For a reference, the result of the wrapper function is a pointer to3378 // the referenced object.3379 llvm::Value *Val = Builder.CreateThreadLocalAddress(Var);3380 3381 if (VD->getType()->isReferenceType()) {3382 CharUnits Align = CGM.getContext().getDeclAlign(VD);3383 Val = Builder.CreateAlignedLoad(Var->getValueType(), Val, Align);3384 }3385 Val = Builder.CreateAddrSpaceCast(Val, Wrapper->getReturnType());3386 3387 Builder.CreateRet(Val);3388 }3389}3390 3391LValue ItaniumCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,3392 const VarDecl *VD,3393 QualType LValType) {3394 llvm::Value *Val = CGF.CGM.GetAddrOfGlobalVar(VD);3395 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val);3396 3397 llvm::CallInst *CallVal = CGF.Builder.CreateCall(Wrapper);3398 CallVal->setCallingConv(Wrapper->getCallingConv());3399 3400 LValue LV;3401 if (VD->getType()->isReferenceType())3402 LV = CGF.MakeNaturalAlignRawAddrLValue(CallVal, LValType);3403 else3404 LV = CGF.MakeRawAddrLValue(CallVal, LValType,3405 CGF.getContext().getDeclAlign(VD));3406 // FIXME: need setObjCGCLValueClass?3407 return LV;3408}3409 3410/// Return whether the given global decl needs a VTT parameter, which it does3411/// if it's a base constructor or destructor with virtual bases.3412bool ItaniumCXXABI::NeedsVTTParameter(GlobalDecl GD) {3413 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());3414 3415 // We don't have any virtual bases, just return early.3416 if (!MD->getParent()->getNumVBases())3417 return false;3418 3419 // Check if we have a base constructor.3420 if (isa<CXXConstructorDecl>(MD) && GD.getCtorType() == Ctor_Base)3421 return true;3422 3423 // Check if we have a base destructor.3424 if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)3425 return true;3426 3427 return false;3428}3429 3430llvm::Constant *3431ItaniumCXXABI::getOrCreateVirtualFunctionPointerThunk(const CXXMethodDecl *MD) {3432 SmallString<256> MethodName;3433 llvm::raw_svector_ostream Out(MethodName);3434 getMangleContext().mangleCXXName(MD, Out);3435 MethodName += "_vfpthunk_";3436 StringRef ThunkName = MethodName.str();3437 llvm::Function *ThunkFn;3438 if ((ThunkFn = cast_or_null<llvm::Function>(3439 CGM.getModule().getNamedValue(ThunkName))))3440 return ThunkFn;3441 3442 const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeCXXMethodDeclaration(MD);3443 llvm::FunctionType *ThunkTy = CGM.getTypes().GetFunctionType(FnInfo);3444 llvm::GlobalValue::LinkageTypes Linkage =3445 MD->isExternallyVisible() ? llvm::GlobalValue::LinkOnceODRLinkage3446 : llvm::GlobalValue::InternalLinkage;3447 ThunkFn =3448 llvm::Function::Create(ThunkTy, Linkage, ThunkName, &CGM.getModule());3449 if (Linkage == llvm::GlobalValue::LinkOnceODRLinkage)3450 ThunkFn->setVisibility(llvm::GlobalValue::HiddenVisibility);3451 assert(ThunkFn->getName() == ThunkName && "name was uniqued!");3452 3453 CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn, /*IsThunk=*/true);3454 CGM.SetLLVMFunctionAttributesForDefinition(MD, ThunkFn);3455 3456 // Stack protection sometimes gets inserted after the musttail call.3457 ThunkFn->removeFnAttr(llvm::Attribute::StackProtect);3458 ThunkFn->removeFnAttr(llvm::Attribute::StackProtectStrong);3459 ThunkFn->removeFnAttr(llvm::Attribute::StackProtectReq);3460 3461 // Start codegen.3462 CodeGenFunction CGF(CGM);3463 CGF.CurGD = GlobalDecl(MD);3464 CGF.CurFuncIsThunk = true;3465 3466 // Build FunctionArgs.3467 FunctionArgList FunctionArgs;3468 CGF.BuildFunctionArgList(CGF.CurGD, FunctionArgs);3469 3470 CGF.StartFunction(GlobalDecl(), FnInfo.getReturnType(), ThunkFn, FnInfo,3471 FunctionArgs, MD->getLocation(), SourceLocation());3472 llvm::Value *ThisVal = loadIncomingCXXThis(CGF);3473 setCXXABIThisValue(CGF, ThisVal);3474 3475 CallArgList CallArgs;3476 for (const VarDecl *VD : FunctionArgs)3477 CGF.EmitDelegateCallArg(CallArgs, VD, SourceLocation());3478 3479 const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();3480 RequiredArgs Required = RequiredArgs::forPrototypePlus(FPT, /*this*/ 1);3481 const CGFunctionInfo &CallInfo =3482 CGM.getTypes().arrangeCXXMethodCall(CallArgs, FPT, Required, 0);3483 CGCallee Callee = CGCallee::forVirtual(nullptr, GlobalDecl(MD),3484 getThisAddress(CGF), ThunkTy);3485 llvm::CallBase *CallOrInvoke;3486 CGF.EmitCall(CallInfo, Callee, ReturnValueSlot(), CallArgs, &CallOrInvoke,3487 /*IsMustTail=*/true, SourceLocation(), true);3488 auto *Call = cast<llvm::CallInst>(CallOrInvoke);3489 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);3490 if (Call->getType()->isVoidTy())3491 CGF.Builder.CreateRetVoid();3492 else3493 CGF.Builder.CreateRet(Call);3494 3495 // Finish the function to maintain CodeGenFunction invariants.3496 // FIXME: Don't emit unreachable code.3497 CGF.EmitBlock(CGF.createBasicBlock());3498 CGF.FinishFunction();3499 return ThunkFn;3500}3501 3502namespace {3503class ItaniumRTTIBuilder {3504 CodeGenModule &CGM; // Per-module state.3505 llvm::LLVMContext &VMContext;3506 const ItaniumCXXABI &CXXABI; // Per-module state.3507 3508 /// Fields - The fields of the RTTI descriptor currently being built.3509 SmallVector<llvm::Constant *, 16> Fields;3510 3511 /// GetAddrOfTypeName - Returns the mangled type name of the given type.3512 llvm::GlobalVariable *3513 GetAddrOfTypeName(QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage);3514 3515 /// GetAddrOfExternalRTTIDescriptor - Returns the constant for the RTTI3516 /// descriptor of the given type.3517 llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty);3518 3519 /// BuildVTablePointer - Build the vtable pointer for the given type.3520 void BuildVTablePointer(const Type *Ty, llvm::Constant *StorageAddress);3521 3522 /// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single3523 /// inheritance, according to the Itanium C++ ABI, 2.9.5p6b.3524 void BuildSIClassTypeInfo(const CXXRecordDecl *RD);3525 3526 /// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for3527 /// classes with bases that do not satisfy the abi::__si_class_type_info3528 /// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.3529 void BuildVMIClassTypeInfo(const CXXRecordDecl *RD);3530 3531 /// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct, used3532 /// for pointer types.3533 void BuildPointerTypeInfo(QualType PointeeTy);3534 3535 /// BuildObjCObjectTypeInfo - Build the appropriate kind of3536 /// type_info for an object type.3537 void BuildObjCObjectTypeInfo(const ObjCObjectType *Ty);3538 3539 /// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info3540 /// struct, used for member pointer types.3541 void BuildPointerToMemberTypeInfo(const MemberPointerType *Ty);3542 3543public:3544 ItaniumRTTIBuilder(const ItaniumCXXABI &ABI)3545 : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()), CXXABI(ABI) {}3546 3547 // Pointer type info flags.3548 enum {3549 /// PTI_Const - Type has const qualifier.3550 PTI_Const = 0x1,3551 3552 /// PTI_Volatile - Type has volatile qualifier.3553 PTI_Volatile = 0x2,3554 3555 /// PTI_Restrict - Type has restrict qualifier.3556 PTI_Restrict = 0x4,3557 3558 /// PTI_Incomplete - Type is incomplete.3559 PTI_Incomplete = 0x8,3560 3561 /// PTI_ContainingClassIncomplete - Containing class is incomplete.3562 /// (in pointer to member).3563 PTI_ContainingClassIncomplete = 0x10,3564 3565 /// PTI_TransactionSafe - Pointee is transaction_safe function (C++ TM TS).3566 //PTI_TransactionSafe = 0x20,3567 3568 /// PTI_Noexcept - Pointee is noexcept function (C++1z).3569 PTI_Noexcept = 0x40,3570 };3571 3572 // VMI type info flags.3573 enum {3574 /// VMI_NonDiamondRepeat - Class has non-diamond repeated inheritance.3575 VMI_NonDiamondRepeat = 0x1,3576 3577 /// VMI_DiamondShaped - Class is diamond shaped.3578 VMI_DiamondShaped = 0x23579 };3580 3581 // Base class type info flags.3582 enum {3583 /// BCTI_Virtual - Base class is virtual.3584 BCTI_Virtual = 0x1,3585 3586 /// BCTI_Public - Base class is public.3587 BCTI_Public = 0x23588 };3589 3590 /// BuildTypeInfo - Build the RTTI type info struct for the given type, or3591 /// link to an existing RTTI descriptor if one already exists.3592 llvm::Constant *BuildTypeInfo(QualType Ty);3593 3594 /// BuildTypeInfo - Build the RTTI type info struct for the given type.3595 llvm::Constant *BuildTypeInfo(3596 QualType Ty,3597 llvm::GlobalVariable::LinkageTypes Linkage,3598 llvm::GlobalValue::VisibilityTypes Visibility,3599 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass);3600};3601}3602 3603llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(3604 QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage) {3605 SmallString<256> Name;3606 llvm::raw_svector_ostream Out(Name);3607 CGM.getCXXABI().getMangleContext().mangleCXXRTTIName(Ty, Out);3608 3609 // We know that the mangled name of the type starts at index 4 of the3610 // mangled name of the typename, so we can just index into it in order to3611 // get the mangled name of the type.3612 llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,3613 Name.substr(4));3614 auto Align = CGM.getContext().getTypeAlignInChars(CGM.getContext().CharTy);3615 3616 llvm::GlobalVariable *GV = CGM.CreateOrReplaceCXXRuntimeVariable(3617 Name, Init->getType(), Linkage, Align.getAsAlign());3618 3619 GV->setInitializer(Init);3620 3621 return GV;3622}3623 3624llvm::Constant *3625ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {3626 // Mangle the RTTI name.3627 SmallString<256> Name;3628 llvm::raw_svector_ostream Out(Name);3629 CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);3630 3631 // Look for an existing global.3632 llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name);3633 3634 if (!GV) {3635 // Create a new global variable.3636 // Note for the future: If we would ever like to do deferred emission of3637 // RTTI, check if emitting vtables opportunistically need any adjustment.3638 3639 GV = new llvm::GlobalVariable(3640 CGM.getModule(), CGM.GlobalsInt8PtrTy,3641 /*isConstant=*/true, llvm::GlobalValue::ExternalLinkage, nullptr, Name);3642 const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();3643 CGM.setGVProperties(GV, RD);3644 // Import the typeinfo symbol when all non-inline virtual methods are3645 // imported.3646 if (CGM.getTarget().hasPS4DLLImportExport()) {3647 if (RD && CXXRecordNonInlineHasAttr<DLLImportAttr>(RD)) {3648 GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);3649 CGM.setDSOLocal(GV);3650 }3651 }3652 }3653 3654 return GV;3655}3656 3657/// TypeInfoIsInStandardLibrary - Given a builtin type, returns whether the type3658/// info for that type is defined in the standard library.3659static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {3660 // Itanium C++ ABI 2.9.2:3661 // Basic type information (e.g. for "int", "bool", etc.) will be kept in3662 // the run-time support library. Specifically, the run-time support3663 // library should contain type_info objects for the types X, X* and3664 // X const*, for every X in: void, std::nullptr_t, bool, wchar_t, char,3665 // unsigned char, signed char, short, unsigned short, int, unsigned int,3666 // long, unsigned long, long long, unsigned long long, float, double,3667 // long double, char16_t, char32_t, and the IEEE 754r decimal and3668 // half-precision floating point types.3669 //3670 // GCC also emits RTTI for __int128.3671 // FIXME: We do not emit RTTI information for decimal types here.3672 3673 // Types added here must also be added to EmitFundamentalRTTIDescriptors.3674 switch (Ty->getKind()) {3675 case BuiltinType::Void:3676 case BuiltinType::NullPtr:3677 case BuiltinType::Bool:3678 case BuiltinType::WChar_S:3679 case BuiltinType::WChar_U:3680 case BuiltinType::Char_U:3681 case BuiltinType::Char_S:3682 case BuiltinType::UChar:3683 case BuiltinType::SChar:3684 case BuiltinType::Short:3685 case BuiltinType::UShort:3686 case BuiltinType::Int:3687 case BuiltinType::UInt:3688 case BuiltinType::Long:3689 case BuiltinType::ULong:3690 case BuiltinType::LongLong:3691 case BuiltinType::ULongLong:3692 case BuiltinType::Half:3693 case BuiltinType::Float:3694 case BuiltinType::Double:3695 case BuiltinType::LongDouble:3696 case BuiltinType::Float16:3697 case BuiltinType::Float128:3698 case BuiltinType::Ibm128:3699 case BuiltinType::Char8:3700 case BuiltinType::Char16:3701 case BuiltinType::Char32:3702 case BuiltinType::Int128:3703 case BuiltinType::UInt128:3704 return true;3705 3706#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \3707 case BuiltinType::Id:3708#include "clang/Basic/OpenCLImageTypes.def"3709#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \3710 case BuiltinType::Id:3711#include "clang/Basic/OpenCLExtensionTypes.def"3712 case BuiltinType::OCLSampler:3713 case BuiltinType::OCLEvent:3714 case BuiltinType::OCLClkEvent:3715 case BuiltinType::OCLQueue:3716 case BuiltinType::OCLReserveID:3717#define SVE_TYPE(Name, Id, SingletonId) \3718 case BuiltinType::Id:3719#include "clang/Basic/AArch64ACLETypes.def"3720#define PPC_VECTOR_TYPE(Name, Id, Size) \3721 case BuiltinType::Id:3722#include "clang/Basic/PPCTypes.def"3723#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:3724#include "clang/Basic/RISCVVTypes.def"3725#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:3726#include "clang/Basic/WebAssemblyReferenceTypes.def"3727#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:3728#include "clang/Basic/AMDGPUTypes.def"3729#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:3730#include "clang/Basic/HLSLIntangibleTypes.def"3731 case BuiltinType::ShortAccum:3732 case BuiltinType::Accum:3733 case BuiltinType::LongAccum:3734 case BuiltinType::UShortAccum:3735 case BuiltinType::UAccum:3736 case BuiltinType::ULongAccum:3737 case BuiltinType::ShortFract:3738 case BuiltinType::Fract:3739 case BuiltinType::LongFract:3740 case BuiltinType::UShortFract:3741 case BuiltinType::UFract:3742 case BuiltinType::ULongFract:3743 case BuiltinType::SatShortAccum:3744 case BuiltinType::SatAccum:3745 case BuiltinType::SatLongAccum:3746 case BuiltinType::SatUShortAccum:3747 case BuiltinType::SatUAccum:3748 case BuiltinType::SatULongAccum:3749 case BuiltinType::SatShortFract:3750 case BuiltinType::SatFract:3751 case BuiltinType::SatLongFract:3752 case BuiltinType::SatUShortFract:3753 case BuiltinType::SatUFract:3754 case BuiltinType::SatULongFract:3755 case BuiltinType::BFloat16:3756 return false;3757 3758 case BuiltinType::Dependent:3759#define BUILTIN_TYPE(Id, SingletonId)3760#define PLACEHOLDER_TYPE(Id, SingletonId) \3761 case BuiltinType::Id:3762#include "clang/AST/BuiltinTypes.def"3763 llvm_unreachable("asking for RRTI for a placeholder type!");3764 3765 case BuiltinType::ObjCId:3766 case BuiltinType::ObjCClass:3767 case BuiltinType::ObjCSel:3768 llvm_unreachable("FIXME: Objective-C types are unsupported!");3769 }3770 3771 llvm_unreachable("Invalid BuiltinType Kind!");3772}3773 3774static bool TypeInfoIsInStandardLibrary(const PointerType *PointerTy) {3775 QualType PointeeTy = PointerTy->getPointeeType();3776 const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);3777 if (!BuiltinTy)3778 return false;3779 3780 // Check the qualifiers.3781 Qualifiers Quals = PointeeTy.getQualifiers();3782 Quals.removeConst();3783 3784 if (!Quals.empty())3785 return false;3786 3787 return TypeInfoIsInStandardLibrary(BuiltinTy);3788}3789 3790/// IsStandardLibraryRTTIDescriptor - Returns whether the type3791/// information for the given type exists in the standard library.3792static bool IsStandardLibraryRTTIDescriptor(QualType Ty) {3793 // Type info for builtin types is defined in the standard library.3794 if (const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))3795 return TypeInfoIsInStandardLibrary(BuiltinTy);3796 3797 // Type info for some pointer types to builtin types is defined in the3798 // standard library.3799 if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))3800 return TypeInfoIsInStandardLibrary(PointerTy);3801 3802 return false;3803}3804 3805/// ShouldUseExternalRTTIDescriptor - Returns whether the type information for3806/// the given type exists somewhere else, and that we should not emit the type3807/// information in this translation unit. Assumes that it is not a3808/// standard-library type.3809static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM,3810 QualType Ty) {3811 ASTContext &Context = CGM.getContext();3812 3813 // If RTTI is disabled, assume it might be disabled in the3814 // translation unit that defines any potential key function, too.3815 if (!Context.getLangOpts().RTTI) return false;3816 3817 if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {3818 const CXXRecordDecl *RD =3819 cast<CXXRecordDecl>(RecordTy->getDecl())->getDefinitionOrSelf();3820 if (!RD->hasDefinition())3821 return false;3822 3823 if (!RD->isDynamicClass())3824 return false;3825 3826 // FIXME: this may need to be reconsidered if the key function3827 // changes.3828 // N.B. We must always emit the RTTI data ourselves if there exists a key3829 // function.3830 bool IsDLLImport = RD->hasAttr<DLLImportAttr>();3831 3832 // Don't import the RTTI but emit it locally.3833 if (CGM.getTriple().isOSCygMing())3834 return false;3835 3836 if (CGM.getVTables().isVTableExternal(RD)) {3837 if (CGM.getTarget().hasPS4DLLImportExport())3838 return true;3839 3840 return IsDLLImport && !CGM.getTriple().isWindowsItaniumEnvironment()3841 ? false3842 : true;3843 }3844 if (IsDLLImport)3845 return true;3846 }3847 3848 return false;3849}3850 3851/// IsIncompleteClassType - Returns whether the given record type is incomplete.3852static bool IsIncompleteClassType(const RecordType *RecordTy) {3853 return !RecordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition();3854}3855 3856/// ContainsIncompleteClassType - Returns whether the given type contains an3857/// incomplete class type. This is true if3858///3859/// * The given type is an incomplete class type.3860/// * The given type is a pointer type whose pointee type contains an3861/// incomplete class type.3862/// * The given type is a member pointer type whose class is an incomplete3863/// class type.3864/// * The given type is a member pointer type whoise pointee type contains an3865/// incomplete class type.3866/// is an indirect or direct pointer to an incomplete class type.3867static bool ContainsIncompleteClassType(QualType Ty) {3868 if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {3869 if (IsIncompleteClassType(RecordTy))3870 return true;3871 }3872 3873 if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))3874 return ContainsIncompleteClassType(PointerTy->getPointeeType());3875 3876 if (const MemberPointerType *MemberPointerTy =3877 dyn_cast<MemberPointerType>(Ty)) {3878 // Check if the class type is incomplete.3879 if (!MemberPointerTy->getMostRecentCXXRecordDecl()->hasDefinition())3880 return true;3881 3882 return ContainsIncompleteClassType(MemberPointerTy->getPointeeType());3883 }3884 3885 return false;3886}3887 3888// CanUseSingleInheritance - Return whether the given record decl has a "single,3889// public, non-virtual base at offset zero (i.e. the derived class is dynamic3890// iff the base is)", according to Itanium C++ ABI, 2.95p6b.3891static bool CanUseSingleInheritance(const CXXRecordDecl *RD) {3892 // Check the number of bases.3893 if (RD->getNumBases() != 1)3894 return false;3895 3896 // Get the base.3897 CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin();3898 3899 // Check that the base is not virtual.3900 if (Base->isVirtual())3901 return false;3902 3903 // Check that the base is public.3904 if (Base->getAccessSpecifier() != AS_public)3905 return false;3906 3907 // Check that the class is dynamic iff the base is.3908 auto *BaseDecl = Base->getType()->castAsCXXRecordDecl();3909 if (!BaseDecl->isEmpty() &&3910 BaseDecl->isDynamicClass() != RD->isDynamicClass())3911 return false;3912 3913 return true;3914}3915 3916void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty,3917 llvm::Constant *StorageAddress) {3918 // abi::__class_type_info.3919 static const char * const ClassTypeInfo =3920 "_ZTVN10__cxxabiv117__class_type_infoE";3921 // abi::__si_class_type_info.3922 static const char * const SIClassTypeInfo =3923 "_ZTVN10__cxxabiv120__si_class_type_infoE";3924 // abi::__vmi_class_type_info.3925 static const char * const VMIClassTypeInfo =3926 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";3927 3928 const char *VTableName = nullptr;3929 3930 switch (Ty->getTypeClass()) {3931#define TYPE(Class, Base)3932#define ABSTRACT_TYPE(Class, Base)3933#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:3934#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:3935#define DEPENDENT_TYPE(Class, Base) case Type::Class:3936#include "clang/AST/TypeNodes.inc"3937 llvm_unreachable("Non-canonical and dependent types shouldn't get here");3938 3939 case Type::LValueReference:3940 case Type::RValueReference:3941 llvm_unreachable("References shouldn't get here");3942 3943 case Type::Auto:3944 case Type::DeducedTemplateSpecialization:3945 llvm_unreachable("Undeduced type shouldn't get here");3946 3947 case Type::Pipe:3948 llvm_unreachable("Pipe types shouldn't get here");3949 3950 case Type::ArrayParameter:3951 llvm_unreachable("Array Parameter types should not get here.");3952 3953 case Type::Builtin:3954 case Type::BitInt:3955 // GCC treats vector and complex types as fundamental types.3956 case Type::Vector:3957 case Type::ExtVector:3958 case Type::ConstantMatrix:3959 case Type::Complex:3960 case Type::Atomic:3961 // FIXME: GCC treats block pointers as fundamental types?!3962 case Type::BlockPointer:3963 // abi::__fundamental_type_info.3964 VTableName = "_ZTVN10__cxxabiv123__fundamental_type_infoE";3965 break;3966 3967 case Type::ConstantArray:3968 case Type::IncompleteArray:3969 case Type::VariableArray:3970 // abi::__array_type_info.3971 VTableName = "_ZTVN10__cxxabiv117__array_type_infoE";3972 break;3973 3974 case Type::FunctionNoProto:3975 case Type::FunctionProto:3976 // abi::__function_type_info.3977 VTableName = "_ZTVN10__cxxabiv120__function_type_infoE";3978 break;3979 3980 case Type::Enum:3981 // abi::__enum_type_info.3982 VTableName = "_ZTVN10__cxxabiv116__enum_type_infoE";3983 break;3984 3985 case Type::Record: {3986 const auto *RD = cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl())3987 ->getDefinitionOrSelf();3988 3989 if (!RD->hasDefinition() || !RD->getNumBases()) {3990 VTableName = ClassTypeInfo;3991 } else if (CanUseSingleInheritance(RD)) {3992 VTableName = SIClassTypeInfo;3993 } else {3994 VTableName = VMIClassTypeInfo;3995 }3996 3997 break;3998 }3999 4000 case Type::ObjCObject:4001 // Ignore protocol qualifiers.4002 Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();4003 4004 // Handle id and Class.4005 if (isa<BuiltinType>(Ty)) {4006 VTableName = ClassTypeInfo;4007 break;4008 }4009 4010 assert(isa<ObjCInterfaceType>(Ty));4011 [[fallthrough]];4012 4013 case Type::ObjCInterface:4014 if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {4015 VTableName = SIClassTypeInfo;4016 } else {4017 VTableName = ClassTypeInfo;4018 }4019 break;4020 4021 case Type::ObjCObjectPointer:4022 case Type::Pointer:4023 // abi::__pointer_type_info.4024 VTableName = "_ZTVN10__cxxabiv119__pointer_type_infoE";4025 break;4026 4027 case Type::MemberPointer:4028 // abi::__pointer_to_member_type_info.4029 VTableName = "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";4030 break;4031 4032 case Type::HLSLAttributedResource:4033 case Type::HLSLInlineSpirv:4034 llvm_unreachable("HLSL doesn't support virtual functions");4035 }4036 4037 llvm::Constant *VTable = nullptr;4038 4039 // Check if the alias exists. If it doesn't, then get or create the global.4040 if (CGM.getItaniumVTableContext().isRelativeLayout())4041 VTable = CGM.getModule().getNamedAlias(VTableName);4042 if (!VTable) {4043 llvm::Type *Ty = llvm::ArrayType::get(CGM.GlobalsInt8PtrTy, 0);4044 VTable = CGM.getModule().getOrInsertGlobal(VTableName, Ty);4045 }4046 4047 CGM.setDSOLocal(cast<llvm::GlobalValue>(VTable->stripPointerCasts()));4048 4049 llvm::Type *PtrDiffTy =4050 CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());4051 4052 // The vtable address point is 2.4053 if (CGM.getItaniumVTableContext().isRelativeLayout()) {4054 // The vtable address point is 8 bytes after its start:4055 // 4 for the offset to top + 4 for the relative offset to rtti.4056 llvm::Constant *Eight = llvm::ConstantInt::get(CGM.Int32Ty, 8);4057 VTable =4058 llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.Int8Ty, VTable, Eight);4059 } else {4060 llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);4061 VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.GlobalsInt8PtrTy,4062 VTable, Two);4063 }4064 4065 if (const auto &Schema =4066 CGM.getCodeGenOpts().PointerAuth.CXXTypeInfoVTablePointer)4067 VTable = CGM.getConstantSignedPointer(4068 VTable, Schema,4069 Schema.isAddressDiscriminated() ? StorageAddress : nullptr,4070 GlobalDecl(), QualType(Ty, 0));4071 4072 Fields.push_back(VTable);4073}4074 4075/// Return the linkage that the type info and type info name constants4076/// should have for the given type.4077static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM,4078 QualType Ty) {4079 // Itanium C++ ABI 2.9.5p7:4080 // In addition, it and all of the intermediate abi::__pointer_type_info4081 // structs in the chain down to the abi::__class_type_info for the4082 // incomplete class type must be prevented from resolving to the4083 // corresponding type_info structs for the complete class type, possibly4084 // by making them local static objects. Finally, a dummy class RTTI is4085 // generated for the incomplete type that will not resolve to the final4086 // complete class RTTI (because the latter need not exist), possibly by4087 // making it a local static object.4088 if (ContainsIncompleteClassType(Ty))4089 return llvm::GlobalValue::InternalLinkage;4090 4091 switch (Ty->getLinkage()) {4092 case Linkage::Invalid:4093 llvm_unreachable("Linkage hasn't been computed!");4094 4095 case Linkage::None:4096 case Linkage::Internal:4097 case Linkage::UniqueExternal:4098 return llvm::GlobalValue::InternalLinkage;4099 4100 case Linkage::VisibleNone:4101 case Linkage::Module:4102 case Linkage::External:4103 // RTTI is not enabled, which means that this type info struct is going4104 // to be used for exception handling. Give it linkonce_odr linkage.4105 if (!CGM.getLangOpts().RTTI)4106 return llvm::GlobalValue::LinkOnceODRLinkage;4107 4108 if (const RecordType *Record = dyn_cast<RecordType>(Ty)) {4109 const auto *RD =4110 cast<CXXRecordDecl>(Record->getDecl())->getDefinitionOrSelf();4111 if (RD->hasAttr<WeakAttr>())4112 return llvm::GlobalValue::WeakODRLinkage;4113 if (CGM.getTriple().isWindowsItaniumEnvironment())4114 if (RD->hasAttr<DLLImportAttr>() &&4115 ShouldUseExternalRTTIDescriptor(CGM, Ty))4116 return llvm::GlobalValue::ExternalLinkage;4117 // MinGW always uses LinkOnceODRLinkage for type info.4118 if (RD->isDynamicClass() &&4119 !CGM.getContext().getTargetInfo().getTriple().isOSCygMing())4120 return CGM.getVTableLinkage(RD);4121 }4122 4123 return llvm::GlobalValue::LinkOnceODRLinkage;4124 }4125 4126 llvm_unreachable("Invalid linkage!");4127}4128 4129llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty) {4130 // We want to operate on the canonical type.4131 Ty = Ty.getCanonicalType();4132 4133 // Check if we've already emitted an RTTI descriptor for this type.4134 SmallString<256> Name;4135 llvm::raw_svector_ostream Out(Name);4136 CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);4137 4138 llvm::GlobalVariable *OldGV = CGM.getModule().getNamedGlobal(Name);4139 if (OldGV && !OldGV->isDeclaration()) {4140 assert(!OldGV->hasAvailableExternallyLinkage() &&4141 "available_externally typeinfos not yet implemented");4142 4143 return OldGV;4144 }4145 4146 // Check if there is already an external RTTI descriptor for this type.4147 if (IsStandardLibraryRTTIDescriptor(Ty) ||4148 ShouldUseExternalRTTIDescriptor(CGM, Ty))4149 return GetAddrOfExternalRTTIDescriptor(Ty);4150 4151 // Emit the standard library with external linkage.4152 llvm::GlobalVariable::LinkageTypes Linkage = getTypeInfoLinkage(CGM, Ty);4153 4154 // Give the type_info object and name the formal visibility of the4155 // type itself.4156 llvm::GlobalValue::VisibilityTypes llvmVisibility;4157 if (llvm::GlobalValue::isLocalLinkage(Linkage))4158 // If the linkage is local, only default visibility makes sense.4159 llvmVisibility = llvm::GlobalValue::DefaultVisibility;4160 else if (CXXABI.classifyRTTIUniqueness(Ty, Linkage) ==4161 ItaniumCXXABI::RUK_NonUniqueHidden)4162 llvmVisibility = llvm::GlobalValue::HiddenVisibility;4163 else4164 llvmVisibility = CodeGenModule::GetLLVMVisibility(Ty->getVisibility());4165 4166 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =4167 llvm::GlobalValue::DefaultStorageClass;4168 if (auto RD = Ty->getAsCXXRecordDecl()) {4169 if ((CGM.getTriple().isWindowsItaniumEnvironment() &&4170 RD->hasAttr<DLLExportAttr>()) ||4171 (CGM.shouldMapVisibilityToDLLExport(RD) &&4172 !llvm::GlobalValue::isLocalLinkage(Linkage) &&4173 llvmVisibility == llvm::GlobalValue::DefaultVisibility))4174 DLLStorageClass = llvm::GlobalValue::DLLExportStorageClass;4175 }4176 return BuildTypeInfo(Ty, Linkage, llvmVisibility, DLLStorageClass);4177}4178 4179llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(4180 QualType Ty,4181 llvm::GlobalVariable::LinkageTypes Linkage,4182 llvm::GlobalValue::VisibilityTypes Visibility,4183 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) {4184 SmallString<256> Name;4185 llvm::raw_svector_ostream Out(Name);4186 CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);4187 llvm::Module &M = CGM.getModule();4188 llvm::GlobalVariable *OldGV = M.getNamedGlobal(Name);4189 // int8 is an arbitrary type to be replaced later with replaceInitializer.4190 llvm::GlobalVariable *GV =4191 new llvm::GlobalVariable(M, CGM.Int8Ty, /*isConstant=*/true, Linkage,4192 /*Initializer=*/nullptr, Name);4193 4194 // Add the vtable pointer.4195 BuildVTablePointer(cast<Type>(Ty), GV);4196 4197 // And the name.4198 llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage);4199 llvm::Constant *TypeNameField;4200 4201 // If we're supposed to demote the visibility, be sure to set a flag4202 // to use a string comparison for type_info comparisons.4203 ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =4204 CXXABI.classifyRTTIUniqueness(Ty, Linkage);4205 if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {4206 // The flag is the sign bit, which on ARM64 is defined to be clear4207 // for global pointers. This is very ARM64-specific.4208 TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.Int64Ty);4209 llvm::Constant *flag =4210 llvm::ConstantInt::get(CGM.Int64Ty, ((uint64_t)1) << 63);4211 TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);4212 TypeNameField =4213 llvm::ConstantExpr::getIntToPtr(TypeNameField, CGM.GlobalsInt8PtrTy);4214 } else {4215 TypeNameField = TypeName;4216 }4217 Fields.push_back(TypeNameField);4218 4219 switch (Ty->getTypeClass()) {4220#define TYPE(Class, Base)4221#define ABSTRACT_TYPE(Class, Base)4222#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:4223#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:4224#define DEPENDENT_TYPE(Class, Base) case Type::Class:4225#include "clang/AST/TypeNodes.inc"4226 llvm_unreachable("Non-canonical and dependent types shouldn't get here");4227 4228 // GCC treats vector types as fundamental types.4229 case Type::Builtin:4230 case Type::Vector:4231 case Type::ExtVector:4232 case Type::ConstantMatrix:4233 case Type::Complex:4234 case Type::BlockPointer:4235 // Itanium C++ ABI 2.9.5p4:4236 // abi::__fundamental_type_info adds no data members to std::type_info.4237 break;4238 4239 case Type::LValueReference:4240 case Type::RValueReference:4241 llvm_unreachable("References shouldn't get here");4242 4243 case Type::Auto:4244 case Type::DeducedTemplateSpecialization:4245 llvm_unreachable("Undeduced type shouldn't get here");4246 4247 case Type::Pipe:4248 break;4249 4250 case Type::BitInt:4251 break;4252 4253 case Type::ConstantArray:4254 case Type::IncompleteArray:4255 case Type::VariableArray:4256 case Type::ArrayParameter:4257 // Itanium C++ ABI 2.9.5p5:4258 // abi::__array_type_info adds no data members to std::type_info.4259 break;4260 4261 case Type::FunctionNoProto:4262 case Type::FunctionProto:4263 // Itanium C++ ABI 2.9.5p5:4264 // abi::__function_type_info adds no data members to std::type_info.4265 break;4266 4267 case Type::Enum:4268 // Itanium C++ ABI 2.9.5p5:4269 // abi::__enum_type_info adds no data members to std::type_info.4270 break;4271 4272 case Type::Record: {4273 const auto *RD = cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl())4274 ->getDefinitionOrSelf();4275 if (!RD->hasDefinition() || !RD->getNumBases()) {4276 // We don't need to emit any fields.4277 break;4278 }4279 4280 if (CanUseSingleInheritance(RD))4281 BuildSIClassTypeInfo(RD);4282 else4283 BuildVMIClassTypeInfo(RD);4284 4285 break;4286 }4287 4288 case Type::ObjCObject:4289 case Type::ObjCInterface:4290 BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));4291 break;4292 4293 case Type::ObjCObjectPointer:4294 BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->getPointeeType());4295 break;4296 4297 case Type::Pointer:4298 BuildPointerTypeInfo(cast<PointerType>(Ty)->getPointeeType());4299 break;4300 4301 case Type::MemberPointer:4302 BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));4303 break;4304 4305 case Type::Atomic:4306 // No fields, at least for the moment.4307 break;4308 4309 case Type::HLSLAttributedResource:4310 case Type::HLSLInlineSpirv:4311 llvm_unreachable("HLSL doesn't support RTTI");4312 }4313 4314 GV->replaceInitializer(llvm::ConstantStruct::getAnon(Fields));4315 4316 // Export the typeinfo in the same circumstances as the vtable is exported.4317 auto GVDLLStorageClass = DLLStorageClass;4318 if (CGM.getTarget().hasPS4DLLImportExport() &&4319 GVDLLStorageClass != llvm::GlobalVariable::DLLExportStorageClass) {4320 if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {4321 const auto *RD =4322 cast<CXXRecordDecl>(RecordTy->getDecl())->getDefinitionOrSelf();4323 if (RD->hasAttr<DLLExportAttr>() ||4324 CXXRecordNonInlineHasAttr<DLLExportAttr>(RD))4325 GVDLLStorageClass = llvm::GlobalVariable::DLLExportStorageClass;4326 }4327 }4328 4329 // If there's already an old global variable, replace it with the new one.4330 if (OldGV) {4331 GV->takeName(OldGV);4332 OldGV->replaceAllUsesWith(GV);4333 OldGV->eraseFromParent();4334 }4335 4336 if (CGM.supportsCOMDAT() && GV->isWeakForLinker())4337 GV->setComdat(M.getOrInsertComdat(GV->getName()));4338 4339 CharUnits Align = CGM.getContext().toCharUnitsFromBits(4340 CGM.getTarget().getPointerAlign(CGM.GetGlobalVarAddressSpace(nullptr)));4341 GV->setAlignment(Align.getAsAlign());4342 4343 // The Itanium ABI specifies that type_info objects must be globally4344 // unique, with one exception: if the type is an incomplete class4345 // type or a (possibly indirect) pointer to one. That exception4346 // affects the general case of comparing type_info objects produced4347 // by the typeid operator, which is why the comparison operators on4348 // std::type_info generally use the type_info name pointers instead4349 // of the object addresses. However, the language's built-in uses4350 // of RTTI generally require class types to be complete, even when4351 // manipulating pointers to those class types. This allows the4352 // implementation of dynamic_cast to rely on address equality tests,4353 // which is much faster.4354 4355 // All of this is to say that it's important that both the type_info4356 // object and the type_info name be uniqued when weakly emitted.4357 4358 TypeName->setVisibility(Visibility);4359 CGM.setDSOLocal(TypeName);4360 4361 GV->setVisibility(Visibility);4362 CGM.setDSOLocal(GV);4363 4364 TypeName->setDLLStorageClass(DLLStorageClass);4365 GV->setDLLStorageClass(GVDLLStorageClass);4366 4367 TypeName->setPartition(CGM.getCodeGenOpts().SymbolPartition);4368 GV->setPartition(CGM.getCodeGenOpts().SymbolPartition);4369 4370 return GV;4371}4372 4373/// BuildObjCObjectTypeInfo - Build the appropriate kind of type_info4374/// for the given Objective-C object type.4375void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(const ObjCObjectType *OT) {4376 // Drop qualifiers.4377 const Type *T = OT->getBaseType().getTypePtr();4378 assert(isa<BuiltinType>(T) || isa<ObjCInterfaceType>(T));4379 4380 // The builtin types are abi::__class_type_infos and don't require4381 // extra fields.4382 if (isa<BuiltinType>(T)) return;4383 4384 ObjCInterfaceDecl *Class = cast<ObjCInterfaceType>(T)->getDecl();4385 ObjCInterfaceDecl *Super = Class->getSuperClass();4386 4387 // Root classes are also __class_type_info.4388 if (!Super) return;4389 4390 QualType SuperTy = CGM.getContext().getObjCInterfaceType(Super);4391 4392 // Everything else is single inheritance.4393 llvm::Constant *BaseTypeInfo =4394 ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(SuperTy);4395 Fields.push_back(BaseTypeInfo);4396}4397 4398/// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single4399/// inheritance, according to the Itanium C++ ABI, 2.95p6b.4400void ItaniumRTTIBuilder::BuildSIClassTypeInfo(const CXXRecordDecl *RD) {4401 // Itanium C++ ABI 2.9.5p6b:4402 // It adds to abi::__class_type_info a single member pointing to the4403 // type_info structure for the base type,4404 llvm::Constant *BaseTypeInfo =4405 ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(RD->bases_begin()->getType());4406 Fields.push_back(BaseTypeInfo);4407}4408 4409namespace {4410 /// SeenBases - Contains virtual and non-virtual bases seen when traversing4411 /// a class hierarchy.4412 struct SeenBases {4413 llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;4414 llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;4415 };4416}4417 4418/// ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in4419/// abi::__vmi_class_type_info.4420///4421static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base,4422 SeenBases &Bases) {4423 4424 unsigned Flags = 0;4425 4426 auto *BaseDecl = Base->getType()->castAsCXXRecordDecl();4427 if (Base->isVirtual()) {4428 // Mark the virtual base as seen.4429 if (!Bases.VirtualBases.insert(BaseDecl).second) {4430 // If this virtual base has been seen before, then the class is diamond4431 // shaped.4432 Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;4433 } else {4434 if (Bases.NonVirtualBases.count(BaseDecl))4435 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;4436 }4437 } else {4438 // Mark the non-virtual base as seen.4439 if (!Bases.NonVirtualBases.insert(BaseDecl).second) {4440 // If this non-virtual base has been seen before, then the class has non-4441 // diamond shaped repeated inheritance.4442 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;4443 } else {4444 if (Bases.VirtualBases.count(BaseDecl))4445 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;4446 }4447 }4448 4449 // Walk all bases.4450 for (const auto &I : BaseDecl->bases())4451 Flags |= ComputeVMIClassTypeInfoFlags(&I, Bases);4452 4453 return Flags;4454}4455 4456static unsigned ComputeVMIClassTypeInfoFlags(const CXXRecordDecl *RD) {4457 unsigned Flags = 0;4458 SeenBases Bases;4459 4460 // Walk all bases.4461 for (const auto &I : RD->bases())4462 Flags |= ComputeVMIClassTypeInfoFlags(&I, Bases);4463 4464 return Flags;4465}4466 4467/// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for4468/// classes with bases that do not satisfy the abi::__si_class_type_info4469/// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.4470void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) {4471 llvm::Type *UnsignedIntLTy =4472 CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);4473 4474 // Itanium C++ ABI 2.9.5p6c:4475 // __flags is a word with flags describing details about the class4476 // structure, which may be referenced by using the __flags_masks4477 // enumeration. These flags refer to both direct and indirect bases.4478 unsigned Flags = ComputeVMIClassTypeInfoFlags(RD);4479 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));4480 4481 // Itanium C++ ABI 2.9.5p6c:4482 // __base_count is a word with the number of direct proper base class4483 // descriptions that follow.4484 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->getNumBases()));4485 4486 if (!RD->getNumBases())4487 return;4488 4489 // Now add the base class descriptions.4490 4491 // Itanium C++ ABI 2.9.5p6c:4492 // __base_info[] is an array of base class descriptions -- one for every4493 // direct proper base. Each description is of the type:4494 //4495 // struct abi::__base_class_type_info {4496 // public:4497 // const __class_type_info *__base_type;4498 // long __offset_flags;4499 //4500 // enum __offset_flags_masks {4501 // __virtual_mask = 0x1,4502 // __public_mask = 0x2,4503 // __offset_shift = 84504 // };4505 // };4506 4507 // If we're in mingw and 'long' isn't wide enough for a pointer, use 'long4508 // long' instead of 'long' for __offset_flags. libstdc++abi uses long long on4509 // LLP64 platforms.4510 // FIXME: Consider updating libc++abi to match, and extend this logic to all4511 // LLP64 platforms.4512 QualType OffsetFlagsTy = CGM.getContext().LongTy;4513 const TargetInfo &TI = CGM.getContext().getTargetInfo();4514 if (TI.getTriple().isOSCygMing() &&4515 TI.getPointerWidth(LangAS::Default) > TI.getLongWidth())4516 OffsetFlagsTy = CGM.getContext().LongLongTy;4517 llvm::Type *OffsetFlagsLTy =4518 CGM.getTypes().ConvertType(OffsetFlagsTy);4519 4520 for (const auto &Base : RD->bases()) {4521 // The __base_type member points to the RTTI for the base type.4522 Fields.push_back(ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(Base.getType()));4523 4524 auto *BaseDecl = Base.getType()->castAsCXXRecordDecl();4525 int64_t OffsetFlags = 0;4526 4527 // All but the lower 8 bits of __offset_flags are a signed offset.4528 // For a non-virtual base, this is the offset in the object of the base4529 // subobject. For a virtual base, this is the offset in the virtual table of4530 // the virtual base offset for the virtual base referenced (negative).4531 CharUnits Offset;4532 if (Base.isVirtual())4533 Offset =4534 CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(RD, BaseDecl);4535 else {4536 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);4537 Offset = Layout.getBaseClassOffset(BaseDecl);4538 };4539 4540 OffsetFlags = uint64_t(Offset.getQuantity()) << 8;4541 4542 // The low-order byte of __offset_flags contains flags, as given by the4543 // masks from the enumeration __offset_flags_masks.4544 if (Base.isVirtual())4545 OffsetFlags |= BCTI_Virtual;4546 if (Base.getAccessSpecifier() == AS_public)4547 OffsetFlags |= BCTI_Public;4548 4549 Fields.push_back(llvm::ConstantInt::get(OffsetFlagsLTy, OffsetFlags));4550 }4551}4552 4553/// Compute the flags for a __pbase_type_info, and remove the corresponding4554/// pieces from \p Type.4555static unsigned extractPBaseFlags(ASTContext &Ctx, QualType &Type) {4556 unsigned Flags = 0;4557 4558 if (Type.isConstQualified())4559 Flags |= ItaniumRTTIBuilder::PTI_Const;4560 if (Type.isVolatileQualified())4561 Flags |= ItaniumRTTIBuilder::PTI_Volatile;4562 if (Type.isRestrictQualified())4563 Flags |= ItaniumRTTIBuilder::PTI_Restrict;4564 Type = Type.getUnqualifiedType();4565 4566 // Itanium C++ ABI 2.9.5p7:4567 // When the abi::__pbase_type_info is for a direct or indirect pointer to an4568 // incomplete class type, the incomplete target type flag is set.4569 if (ContainsIncompleteClassType(Type))4570 Flags |= ItaniumRTTIBuilder::PTI_Incomplete;4571 4572 if (auto *Proto = Type->getAs<FunctionProtoType>()) {4573 if (Proto->isNothrow()) {4574 Flags |= ItaniumRTTIBuilder::PTI_Noexcept;4575 Type = Ctx.getFunctionTypeWithExceptionSpec(Type, EST_None);4576 }4577 }4578 4579 return Flags;4580}4581 4582/// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct,4583/// used for pointer types.4584void ItaniumRTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) {4585 // Itanium C++ ABI 2.9.5p7:4586 // __flags is a flag word describing the cv-qualification and other4587 // attributes of the type pointed to4588 unsigned Flags = extractPBaseFlags(CGM.getContext(), PointeeTy);4589 4590 llvm::Type *UnsignedIntLTy =4591 CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);4592 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));4593 4594 // Itanium C++ ABI 2.9.5p7:4595 // __pointee is a pointer to the std::type_info derivation for the4596 // unqualified type being pointed to.4597 llvm::Constant *PointeeTypeInfo =4598 ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(PointeeTy);4599 Fields.push_back(PointeeTypeInfo);4600}4601 4602/// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info4603/// struct, used for member pointer types.4604void4605ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {4606 QualType PointeeTy = Ty->getPointeeType();4607 4608 // Itanium C++ ABI 2.9.5p7:4609 // __flags is a flag word describing the cv-qualification and other4610 // attributes of the type pointed to.4611 unsigned Flags = extractPBaseFlags(CGM.getContext(), PointeeTy);4612 4613 const auto *RD = Ty->getMostRecentCXXRecordDecl();4614 if (!RD->hasDefinition())4615 Flags |= PTI_ContainingClassIncomplete;4616 4617 llvm::Type *UnsignedIntLTy =4618 CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);4619 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));4620 4621 // Itanium C++ ABI 2.9.5p7:4622 // __pointee is a pointer to the std::type_info derivation for the4623 // unqualified type being pointed to.4624 llvm::Constant *PointeeTypeInfo =4625 ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(PointeeTy);4626 Fields.push_back(PointeeTypeInfo);4627 4628 // Itanium C++ ABI 2.9.5p9:4629 // __context is a pointer to an abi::__class_type_info corresponding to the4630 // class type containing the member pointed to4631 // (e.g., the "A" in "int A::*").4632 CanQualType T = CGM.getContext().getCanonicalTagType(RD);4633 Fields.push_back(ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(T));4634}4635 4636llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(QualType Ty) {4637 return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);4638}4639 4640void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(const CXXRecordDecl *RD) {4641 // Types added here must also be added to TypeInfoIsInStandardLibrary.4642 QualType FundamentalTypes[] = {4643 getContext().VoidTy, getContext().NullPtrTy,4644 getContext().BoolTy, getContext().WCharTy,4645 getContext().CharTy, getContext().UnsignedCharTy,4646 getContext().SignedCharTy, getContext().ShortTy,4647 getContext().UnsignedShortTy, getContext().IntTy,4648 getContext().UnsignedIntTy, getContext().LongTy,4649 getContext().UnsignedLongTy, getContext().LongLongTy,4650 getContext().UnsignedLongLongTy, getContext().Int128Ty,4651 getContext().UnsignedInt128Ty, getContext().HalfTy,4652 getContext().FloatTy, getContext().DoubleTy,4653 getContext().LongDoubleTy, getContext().Float128Ty,4654 getContext().Char8Ty, getContext().Char16Ty,4655 getContext().Char32Ty4656 };4657 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =4658 RD->hasAttr<DLLExportAttr>() || CGM.shouldMapVisibilityToDLLExport(RD)4659 ? llvm::GlobalValue::DLLExportStorageClass4660 : llvm::GlobalValue::DefaultStorageClass;4661 llvm::GlobalValue::VisibilityTypes Visibility =4662 CodeGenModule::GetLLVMVisibility(RD->getVisibility());4663 for (const QualType &FundamentalType : FundamentalTypes) {4664 QualType PointerType = getContext().getPointerType(FundamentalType);4665 QualType PointerTypeConst = getContext().getPointerType(4666 FundamentalType.withConst());4667 for (QualType Type : {FundamentalType, PointerType, PointerTypeConst})4668 ItaniumRTTIBuilder(*this).BuildTypeInfo(4669 Type, llvm::GlobalValue::ExternalLinkage,4670 Visibility, DLLStorageClass);4671 }4672}4673 4674/// What sort of uniqueness rules should we use for the RTTI for the4675/// given type?4676ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(4677 QualType CanTy, llvm::GlobalValue::LinkageTypes Linkage) const {4678 if (shouldRTTIBeUnique())4679 return RUK_Unique;4680 4681 // It's only necessary for linkonce_odr or weak_odr linkage.4682 if (Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&4683 Linkage != llvm::GlobalValue::WeakODRLinkage)4684 return RUK_Unique;4685 4686 // It's only necessary with default visibility.4687 if (CanTy->getVisibility() != DefaultVisibility)4688 return RUK_Unique;4689 4690 // If we're not required to publish this symbol, hide it.4691 if (Linkage == llvm::GlobalValue::LinkOnceODRLinkage)4692 return RUK_NonUniqueHidden;4693 4694 // If we're required to publish this symbol, as we might be under an4695 // explicit instantiation, leave it with default visibility but4696 // enable string-comparisons.4697 assert(Linkage == llvm::GlobalValue::WeakODRLinkage);4698 return RUK_NonUniqueVisible;4699}4700 4701// Find out how to codegen the complete destructor and constructor4702namespace {4703enum class StructorCodegen { Emit, RAUW, Alias, COMDAT };4704}4705static StructorCodegen getCodegenToUse(CodeGenModule &CGM,4706 const CXXMethodDecl *MD) {4707 if (!CGM.getCodeGenOpts().CXXCtorDtorAliases)4708 return StructorCodegen::Emit;4709 4710 // The complete and base structors are not equivalent if there are any virtual4711 // bases, so emit separate functions.4712 if (MD->getParent()->getNumVBases())4713 return StructorCodegen::Emit;4714 4715 GlobalDecl AliasDecl;4716 if (const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {4717 AliasDecl = GlobalDecl(DD, Dtor_Complete);4718 } else {4719 const auto *CD = cast<CXXConstructorDecl>(MD);4720 AliasDecl = GlobalDecl(CD, Ctor_Complete);4721 }4722 llvm::GlobalValue::LinkageTypes Linkage = CGM.getFunctionLinkage(AliasDecl);4723 4724 if (llvm::GlobalValue::isDiscardableIfUnused(Linkage))4725 return StructorCodegen::RAUW;4726 4727 // FIXME: Should we allow available_externally aliases?4728 if (!llvm::GlobalAlias::isValidLinkage(Linkage))4729 return StructorCodegen::RAUW;4730 4731 if (llvm::GlobalValue::isWeakForLinker(Linkage)) {4732 // Only ELF and wasm support COMDATs with arbitrary names (C5/D5).4733 if (CGM.getTarget().getTriple().isOSBinFormatELF() ||4734 CGM.getTarget().getTriple().isOSBinFormatWasm())4735 return StructorCodegen::COMDAT;4736 return StructorCodegen::Emit;4737 }4738 4739 return StructorCodegen::Alias;4740}4741 4742static void emitConstructorDestructorAlias(CodeGenModule &CGM,4743 GlobalDecl AliasDecl,4744 GlobalDecl TargetDecl) {4745 llvm::GlobalValue::LinkageTypes Linkage = CGM.getFunctionLinkage(AliasDecl);4746 4747 StringRef MangledName = CGM.getMangledName(AliasDecl);4748 llvm::GlobalValue *Entry = CGM.GetGlobalValue(MangledName);4749 if (Entry && !Entry->isDeclaration())4750 return;4751 4752 auto *Aliasee = cast<llvm::GlobalValue>(CGM.GetAddrOfGlobal(TargetDecl));4753 4754 // Create the alias with no name.4755 auto *Alias = llvm::GlobalAlias::create(Linkage, "", Aliasee);4756 4757 // Constructors and destructors are always unnamed_addr.4758 Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);4759 4760 // Switch any previous uses to the alias.4761 if (Entry) {4762 assert(Entry->getType() == Aliasee->getType() &&4763 "declaration exists with different type");4764 Alias->takeName(Entry);4765 Entry->replaceAllUsesWith(Alias);4766 Entry->eraseFromParent();4767 } else {4768 Alias->setName(MangledName);4769 }4770 4771 // Finally, set up the alias with its proper name and attributes.4772 CGM.SetCommonAttributes(AliasDecl, Alias);4773}4774 4775void ItaniumCXXABI::emitCXXStructor(GlobalDecl GD) {4776 auto *MD = cast<CXXMethodDecl>(GD.getDecl());4777 auto *CD = dyn_cast<CXXConstructorDecl>(MD);4778 const CXXDestructorDecl *DD = CD ? nullptr : cast<CXXDestructorDecl>(MD);4779 4780 StructorCodegen CGType = getCodegenToUse(CGM, MD);4781 4782 if (CD ? GD.getCtorType() == Ctor_Complete4783 : GD.getDtorType() == Dtor_Complete) {4784 GlobalDecl BaseDecl;4785 if (CD)4786 BaseDecl = GD.getWithCtorType(Ctor_Base);4787 else4788 BaseDecl = GD.getWithDtorType(Dtor_Base);4789 4790 if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {4791 emitConstructorDestructorAlias(CGM, GD, BaseDecl);4792 return;4793 }4794 4795 if (CGType == StructorCodegen::RAUW) {4796 StringRef MangledName = CGM.getMangledName(GD);4797 auto *Aliasee = CGM.GetAddrOfGlobal(BaseDecl);4798 CGM.addReplacement(MangledName, Aliasee);4799 return;4800 }4801 }4802 4803 // The base destructor is equivalent to the base destructor of its4804 // base class if there is exactly one non-virtual base class with a4805 // non-trivial destructor, there are no fields with a non-trivial4806 // destructor, and the body of the destructor is trivial.4807 if (DD && GD.getDtorType() == Dtor_Base &&4808 CGType != StructorCodegen::COMDAT &&4809 !CGM.TryEmitBaseDestructorAsAlias(DD))4810 return;4811 4812 // FIXME: The deleting destructor is equivalent to the selected operator4813 // delete if:4814 // * either the delete is a destroying operator delete or the destructor4815 // would be trivial if it weren't virtual,4816 // * the conversion from the 'this' parameter to the first parameter of the4817 // destructor is equivalent to a bitcast,4818 // * the destructor does not have an implicit "this" return, and4819 // * the operator delete has the same calling convention and IR function type4820 // as the destructor.4821 // In such cases we should try to emit the deleting dtor as an alias to the4822 // selected 'operator delete'.4823 4824 llvm::Function *Fn = CGM.codegenCXXStructor(GD);4825 4826 if (CGType == StructorCodegen::COMDAT) {4827 SmallString<256> Buffer;4828 llvm::raw_svector_ostream Out(Buffer);4829 if (DD)4830 getMangleContext().mangleCXXDtorComdat(DD, Out);4831 else4832 getMangleContext().mangleCXXCtorComdat(CD, Out);4833 llvm::Comdat *C = CGM.getModule().getOrInsertComdat(Out.str());4834 Fn->setComdat(C);4835 } else {4836 CGM.maybeSetTrivialComdat(*MD, *Fn);4837 }4838}4839 4840static llvm::FunctionCallee getBeginCatchFn(CodeGenModule &CGM) {4841 // void *__cxa_begin_catch(void*);4842 llvm::FunctionType *FTy = llvm::FunctionType::get(4843 CGM.Int8PtrTy, CGM.Int8PtrTy, /*isVarArg=*/false);4844 4845 return CGM.CreateRuntimeFunction(FTy, "__cxa_begin_catch");4846}4847 4848static llvm::FunctionCallee getEndCatchFn(CodeGenModule &CGM) {4849 // void __cxa_end_catch();4850 llvm::FunctionType *FTy =4851 llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);4852 4853 return CGM.CreateRuntimeFunction(FTy, "__cxa_end_catch");4854}4855 4856static llvm::FunctionCallee getGetExceptionPtrFn(CodeGenModule &CGM) {4857 // void *__cxa_get_exception_ptr(void*);4858 llvm::FunctionType *FTy = llvm::FunctionType::get(4859 CGM.Int8PtrTy, CGM.Int8PtrTy, /*isVarArg=*/false);4860 4861 return CGM.CreateRuntimeFunction(FTy, "__cxa_get_exception_ptr");4862}4863 4864namespace {4865 /// A cleanup to call __cxa_end_catch. In many cases, the caught4866 /// exception type lets us state definitively that the thrown exception4867 /// type does not have a destructor. In particular:4868 /// - Catch-alls tell us nothing, so we have to conservatively4869 /// assume that the thrown exception might have a destructor.4870 /// - Catches by reference behave according to their base types.4871 /// - Catches of non-record types will only trigger for exceptions4872 /// of non-record types, which never have destructors.4873 /// - Catches of record types can trigger for arbitrary subclasses4874 /// of the caught type, so we have to assume the actual thrown4875 /// exception type might have a throwing destructor, even if the4876 /// caught type's destructor is trivial or nothrow.4877 struct CallEndCatch final : EHScopeStack::Cleanup {4878 CallEndCatch(bool MightThrow) : MightThrow(MightThrow) {}4879 bool MightThrow;4880 4881 void Emit(CodeGenFunction &CGF, Flags flags) override {4882 if (!MightThrow) {4883 CGF.EmitNounwindRuntimeCall(getEndCatchFn(CGF.CGM));4884 return;4885 }4886 4887 CGF.EmitRuntimeCallOrInvoke(getEndCatchFn(CGF.CGM));4888 }4889 };4890}4891 4892/// Emits a call to __cxa_begin_catch and enters a cleanup to call4893/// __cxa_end_catch. If -fassume-nothrow-exception-dtor is specified, we assume4894/// that the exception object's dtor is nothrow, therefore the __cxa_end_catch4895/// call can be marked as nounwind even if EndMightThrow is true.4896///4897/// \param EndMightThrow - true if __cxa_end_catch might throw4898static llvm::Value *CallBeginCatch(CodeGenFunction &CGF,4899 llvm::Value *Exn,4900 bool EndMightThrow) {4901 llvm::CallInst *call =4902 CGF.EmitNounwindRuntimeCall(getBeginCatchFn(CGF.CGM), Exn);4903 4904 CGF.EHStack.pushCleanup<CallEndCatch>(4905 NormalAndEHCleanup,4906 EndMightThrow && !CGF.CGM.getLangOpts().AssumeNothrowExceptionDtor);4907 4908 return call;4909}4910 4911/// A "special initializer" callback for initializing a catch4912/// parameter during catch initialization.4913static void InitCatchParam(CodeGenFunction &CGF,4914 const VarDecl &CatchParam,4915 Address ParamAddr,4916 SourceLocation Loc) {4917 // Load the exception from where the landing pad saved it.4918 llvm::Value *Exn = CGF.getExceptionFromSlot();4919 4920 CanQualType CatchType =4921 CGF.CGM.getContext().getCanonicalType(CatchParam.getType());4922 llvm::Type *LLVMCatchTy = CGF.ConvertTypeForMem(CatchType);4923 4924 // If we're catching by reference, we can just cast the object4925 // pointer to the appropriate pointer.4926 if (isa<ReferenceType>(CatchType)) {4927 QualType CaughtType = cast<ReferenceType>(CatchType)->getPointeeType();4928 bool EndCatchMightThrow = CaughtType->isRecordType();4929 4930 // __cxa_begin_catch returns the adjusted object pointer.4931 llvm::Value *AdjustedExn = CallBeginCatch(CGF, Exn, EndCatchMightThrow);4932 4933 // We have no way to tell the personality function that we're4934 // catching by reference, so if we're catching a pointer,4935 // __cxa_begin_catch will actually return that pointer by value.4936 if (const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {4937 QualType PointeeType = PT->getPointeeType();4938 4939 // When catching by reference, generally we should just ignore4940 // this by-value pointer and use the exception object instead.4941 if (!PointeeType->isRecordType()) {4942 4943 // Exn points to the struct _Unwind_Exception header, which4944 // we have to skip past in order to reach the exception data.4945 unsigned HeaderSize =4946 CGF.CGM.getTargetCodeGenInfo().getSizeOfUnwindException();4947 AdjustedExn =4948 CGF.Builder.CreateConstGEP1_32(CGF.Int8Ty, Exn, HeaderSize);4949 4950 // However, if we're catching a pointer-to-record type that won't4951 // work, because the personality function might have adjusted4952 // the pointer. There's actually no way for us to fully satisfy4953 // the language/ABI contract here: we can't use Exn because it4954 // might have the wrong adjustment, but we can't use the by-value4955 // pointer because it's off by a level of abstraction.4956 //4957 // The current solution is to dump the adjusted pointer into an4958 // alloca, which breaks language semantics (because changing the4959 // pointer doesn't change the exception) but at least works.4960 // The better solution would be to filter out non-exact matches4961 // and rethrow them, but this is tricky because the rethrow4962 // really needs to be catchable by other sites at this landing4963 // pad. The best solution is to fix the personality function.4964 } else {4965 // Pull the pointer for the reference type off.4966 llvm::Type *PtrTy = CGF.ConvertTypeForMem(CaughtType);4967 4968 // Create the temporary and write the adjusted pointer into it.4969 Address ExnPtrTmp =4970 CGF.CreateTempAlloca(PtrTy, CGF.getPointerAlign(), "exn.byref.tmp");4971 llvm::Value *Casted = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy);4972 CGF.Builder.CreateStore(Casted, ExnPtrTmp);4973 4974 // Bind the reference to the temporary.4975 AdjustedExn = ExnPtrTmp.emitRawPointer(CGF);4976 }4977 }4978 4979 llvm::Value *ExnCast =4980 CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.byref");4981 CGF.Builder.CreateStore(ExnCast, ParamAddr);4982 return;4983 }4984 4985 // Scalars and complexes.4986 TypeEvaluationKind TEK = CGF.getEvaluationKind(CatchType);4987 if (TEK != TEK_Aggregate) {4988 llvm::Value *AdjustedExn = CallBeginCatch(CGF, Exn, false);4989 4990 // If the catch type is a pointer type, __cxa_begin_catch returns4991 // the pointer by value.4992 if (CatchType->hasPointerRepresentation()) {4993 llvm::Value *CastExn =4994 CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.casted");4995 4996 switch (CatchType.getQualifiers().getObjCLifetime()) {4997 case Qualifiers::OCL_Strong:4998 CastExn = CGF.EmitARCRetainNonBlock(CastExn);4999 [[fallthrough]];5000 5001 case Qualifiers::OCL_None:5002 case Qualifiers::OCL_ExplicitNone:5003 case Qualifiers::OCL_Autoreleasing:5004 CGF.Builder.CreateStore(CastExn, ParamAddr);5005 return;5006 5007 case Qualifiers::OCL_Weak:5008 CGF.EmitARCInitWeak(ParamAddr, CastExn);5009 return;5010 }5011 llvm_unreachable("bad ownership qualifier!");5012 }5013 5014 // Otherwise, it returns a pointer into the exception object.5015 5016 LValue srcLV = CGF.MakeNaturalAlignAddrLValue(AdjustedExn, CatchType);5017 LValue destLV = CGF.MakeAddrLValue(ParamAddr, CatchType);5018 switch (TEK) {5019 case TEK_Complex:5020 CGF.EmitStoreOfComplex(CGF.EmitLoadOfComplex(srcLV, Loc), destLV,5021 /*init*/ true);5022 return;5023 case TEK_Scalar: {5024 llvm::Value *ExnLoad = CGF.EmitLoadOfScalar(srcLV, Loc);5025 CGF.EmitStoreOfScalar(ExnLoad, destLV, /*init*/ true);5026 return;5027 }5028 case TEK_Aggregate:5029 llvm_unreachable("evaluation kind filtered out!");5030 }5031 llvm_unreachable("bad evaluation kind");5032 }5033 5034 assert(isa<RecordType>(CatchType) && "unexpected catch type!");5035 auto catchRD = CatchType->getAsCXXRecordDecl();5036 CharUnits caughtExnAlignment = CGF.CGM.getClassPointerAlignment(catchRD);5037 5038 llvm::Type *PtrTy = CGF.DefaultPtrTy;5039 5040 // Check for a copy expression. If we don't have a copy expression,5041 // that means a trivial copy is okay.5042 const Expr *copyExpr = CatchParam.getInit();5043 if (!copyExpr) {5044 llvm::Value *rawAdjustedExn = CallBeginCatch(CGF, Exn, true);5045 Address adjustedExn(CGF.Builder.CreateBitCast(rawAdjustedExn, PtrTy),5046 LLVMCatchTy, caughtExnAlignment);5047 LValue Dest = CGF.MakeAddrLValue(ParamAddr, CatchType);5048 LValue Src = CGF.MakeAddrLValue(adjustedExn, CatchType);5049 CGF.EmitAggregateCopy(Dest, Src, CatchType, AggValueSlot::DoesNotOverlap);5050 return;5051 }5052 5053 // We have to call __cxa_get_exception_ptr to get the adjusted5054 // pointer before copying.5055 llvm::CallInst *rawAdjustedExn =5056 CGF.EmitNounwindRuntimeCall(getGetExceptionPtrFn(CGF.CGM), Exn);5057 5058 // Cast that to the appropriate type.5059 Address adjustedExn(CGF.Builder.CreateBitCast(rawAdjustedExn, PtrTy),5060 LLVMCatchTy, caughtExnAlignment);5061 5062 // The copy expression is defined in terms of an OpaqueValueExpr.5063 // Find it and map it to the adjusted expression.5064 CodeGenFunction::OpaqueValueMapping5065 opaque(CGF, OpaqueValueExpr::findInCopyConstruct(copyExpr),5066 CGF.MakeAddrLValue(adjustedExn, CatchParam.getType()));5067 5068 // Call the copy ctor in a terminate scope.5069 CGF.EHStack.pushTerminate();5070 5071 // Perform the copy construction.5072 CGF.EmitAggExpr(copyExpr,5073 AggValueSlot::forAddr(ParamAddr, Qualifiers(),5074 AggValueSlot::IsNotDestructed,5075 AggValueSlot::DoesNotNeedGCBarriers,5076 AggValueSlot::IsNotAliased,5077 AggValueSlot::DoesNotOverlap));5078 5079 // Leave the terminate scope.5080 CGF.EHStack.popTerminate();5081 5082 // Undo the opaque value mapping.5083 opaque.pop();5084 5085 // Finally we can call __cxa_begin_catch.5086 CallBeginCatch(CGF, Exn, true);5087}5088 5089/// Begins a catch statement by initializing the catch variable and5090/// calling __cxa_begin_catch.5091void ItaniumCXXABI::emitBeginCatch(CodeGenFunction &CGF,5092 const CXXCatchStmt *S) {5093 // We have to be very careful with the ordering of cleanups here:5094 // C++ [except.throw]p4:5095 // The destruction [of the exception temporary] occurs5096 // immediately after the destruction of the object declared in5097 // the exception-declaration in the handler.5098 //5099 // So the precise ordering is:5100 // 1. Construct catch variable.5101 // 2. __cxa_begin_catch5102 // 3. Enter __cxa_end_catch cleanup5103 // 4. Enter dtor cleanup5104 //5105 // We do this by using a slightly abnormal initialization process.5106 // Delegation sequence:5107 // - ExitCXXTryStmt opens a RunCleanupsScope5108 // - EmitAutoVarAlloca creates the variable and debug info5109 // - InitCatchParam initializes the variable from the exception5110 // - CallBeginCatch calls __cxa_begin_catch5111 // - CallBeginCatch enters the __cxa_end_catch cleanup5112 // - EmitAutoVarCleanups enters the variable destructor cleanup5113 // - EmitCXXTryStmt emits the code for the catch body5114 // - EmitCXXTryStmt close the RunCleanupsScope5115 5116 VarDecl *CatchParam = S->getExceptionDecl();5117 if (!CatchParam) {5118 llvm::Value *Exn = CGF.getExceptionFromSlot();5119 CallBeginCatch(CGF, Exn, true);5120 return;5121 }5122 5123 // Emit the local.5124 CodeGenFunction::AutoVarEmission var = CGF.EmitAutoVarAlloca(*CatchParam);5125 {5126 ApplyAtomGroup Grp(CGF.getDebugInfo());5127 InitCatchParam(CGF, *CatchParam, var.getObjectAddress(CGF),5128 S->getBeginLoc());5129 }5130 CGF.EmitAutoVarCleanups(var);5131}5132 5133/// Get or define the following function:5134/// void @__clang_call_terminate(i8* %exn) nounwind noreturn5135/// This code is used only in C++.5136static llvm::FunctionCallee getClangCallTerminateFn(CodeGenModule &CGM) {5137 ASTContext &C = CGM.getContext();5138 const CGFunctionInfo &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(5139 C.VoidTy, {C.getPointerType(C.CharTy)});5140 llvm::FunctionType *fnTy = CGM.getTypes().GetFunctionType(FI);5141 llvm::FunctionCallee fnRef = CGM.CreateRuntimeFunction(5142 fnTy, "__clang_call_terminate", llvm::AttributeList(), /*Local=*/true);5143 llvm::Function *fn =5144 cast<llvm::Function>(fnRef.getCallee()->stripPointerCasts());5145 if (fn->empty()) {5146 CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, fn, /*IsThunk=*/false);5147 CGM.SetLLVMFunctionAttributesForDefinition(nullptr, fn);5148 fn->setDoesNotThrow();5149 fn->setDoesNotReturn();5150 5151 // What we really want is to massively penalize inlining without5152 // forbidding it completely. The difference between that and5153 // 'noinline' is negligible.5154 fn->addFnAttr(llvm::Attribute::NoInline);5155 5156 // Allow this function to be shared across translation units, but5157 // we don't want it to turn into an exported symbol.5158 fn->setLinkage(llvm::Function::LinkOnceODRLinkage);5159 fn->setVisibility(llvm::Function::HiddenVisibility);5160 if (CGM.supportsCOMDAT())5161 fn->setComdat(CGM.getModule().getOrInsertComdat(fn->getName()));5162 5163 // Set up the function.5164 llvm::BasicBlock *entry =5165 llvm::BasicBlock::Create(CGM.getLLVMContext(), "", fn);5166 CGBuilderTy builder(CGM, entry);5167 5168 // Pull the exception pointer out of the parameter list.5169 llvm::Value *exn = &*fn->arg_begin();5170 5171 // Call __cxa_begin_catch(exn).5172 llvm::CallInst *catchCall = builder.CreateCall(getBeginCatchFn(CGM), exn);5173 catchCall->setDoesNotThrow();5174 catchCall->setCallingConv(CGM.getRuntimeCC());5175 5176 // Call std::terminate().5177 llvm::CallInst *termCall = builder.CreateCall(CGM.getTerminateFn());5178 termCall->setDoesNotThrow();5179 termCall->setDoesNotReturn();5180 termCall->setCallingConv(CGM.getRuntimeCC());5181 5182 // std::terminate cannot return.5183 builder.CreateUnreachable();5184 }5185 return fnRef;5186}5187 5188llvm::CallInst *5189ItaniumCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,5190 llvm::Value *Exn) {5191 // In C++, we want to call __cxa_begin_catch() before terminating.5192 if (Exn) {5193 assert(CGF.CGM.getLangOpts().CPlusPlus);5194 return CGF.EmitNounwindRuntimeCall(getClangCallTerminateFn(CGF.CGM), Exn);5195 }5196 return CGF.EmitNounwindRuntimeCall(CGF.CGM.getTerminateFn());5197}5198 5199std::pair<llvm::Value *, const CXXRecordDecl *>5200ItaniumCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,5201 const CXXRecordDecl *RD) {5202 return {CGF.GetVTablePtr(This, CGM.Int8PtrTy, RD), RD};5203}5204 5205llvm::Constant *5206ItaniumCXXABI::getSignedVirtualMemberFunctionPointer(const CXXMethodDecl *MD) {5207 const CXXMethodDecl *origMD =5208 cast<CXXMethodDecl>(CGM.getItaniumVTableContext()5209 .findOriginalMethod(MD->getCanonicalDecl())5210 .getDecl());5211 llvm::Constant *thunk = getOrCreateVirtualFunctionPointerThunk(origMD);5212 QualType funcType = CGM.getContext().getMemberPointerType(5213 MD->getType(), /*Qualifier=*/std::nullopt, MD->getParent());5214 return CGM.getMemberFunctionPointer(thunk, funcType);5215}5216 5217void WebAssemblyCXXABI::emitBeginCatch(CodeGenFunction &CGF,5218 const CXXCatchStmt *C) {5219 if (CGF.getTarget().hasFeature("exception-handling"))5220 CGF.EHStack.pushCleanup<CatchRetScope>(5221 NormalCleanup, cast<llvm::CatchPadInst>(CGF.CurrentFuncletPad));5222 ItaniumCXXABI::emitBeginCatch(CGF, C);5223}5224 5225llvm::CallInst *5226WebAssemblyCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,5227 llvm::Value *Exn) {5228 // Itanium ABI calls __clang_call_terminate(), which __cxa_begin_catch() on5229 // the violating exception to mark it handled, but it is currently hard to do5230 // with wasm EH instruction structure with catch/catch_all, we just call5231 // std::terminate and ignore the violating exception as in CGCXXABI in Wasm EH5232 // and call __clang_call_terminate only in Emscripten EH.5233 // TODO Consider code transformation that makes calling __clang_call_terminate5234 // in Wasm EH possible.5235 if (Exn && !EHPersonality::get(CGF).isWasmPersonality()) {5236 assert(CGF.CGM.getLangOpts().CPlusPlus);5237 return CGF.EmitNounwindRuntimeCall(getClangCallTerminateFn(CGF.CGM), Exn);5238 }5239 return CGCXXABI::emitTerminateForUnexpectedException(CGF, Exn);5240}5241 5242/// Register a global destructor as best as we know how.5243void XLCXXABI::registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,5244 llvm::FunctionCallee Dtor,5245 llvm::Constant *Addr) {5246 if (D.getTLSKind() != VarDecl::TLS_None) {5247 llvm::PointerType *PtrTy = CGF.DefaultPtrTy;5248 5249 // extern "C" int __pt_atexit_np(int flags, int(*)(int,...), ...);5250 llvm::FunctionType *AtExitTy =5251 llvm::FunctionType::get(CGM.IntTy, {CGM.IntTy, PtrTy}, true);5252 5253 // Fetch the actual function.5254 llvm::FunctionCallee AtExit =5255 CGM.CreateRuntimeFunction(AtExitTy, "__pt_atexit_np");5256 5257 // Create __dtor function for the var decl.5258 llvm::Function *DtorStub = CGF.createTLSAtExitStub(D, Dtor, Addr, AtExit);5259 5260 // Register above __dtor with atexit().5261 // First param is flags and must be 0, second param is function ptr5262 llvm::Value *NV = llvm::Constant::getNullValue(CGM.IntTy);5263 CGF.EmitNounwindRuntimeCall(AtExit, {NV, DtorStub});5264 5265 // Cannot unregister TLS __dtor so done5266 return;5267 }5268 5269 // Create __dtor function for the var decl.5270 llvm::Function *DtorStub =5271 cast<llvm::Function>(CGF.createAtExitStub(D, Dtor, Addr));5272 5273 // Register above __dtor with atexit().5274 CGF.registerGlobalDtorWithAtExit(DtorStub);5275 5276 // Emit __finalize function to unregister __dtor and (as appropriate) call5277 // __dtor.5278 emitCXXStermFinalizer(D, DtorStub, Addr);5279}5280 5281void XLCXXABI::emitCXXStermFinalizer(const VarDecl &D, llvm::Function *dtorStub,5282 llvm::Constant *addr) {5283 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, false);5284 SmallString<256> FnName;5285 {5286 llvm::raw_svector_ostream Out(FnName);5287 getMangleContext().mangleDynamicStermFinalizer(&D, Out);5288 }5289 5290 // Create the finalization action associated with a variable.5291 const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();5292 llvm::Function *StermFinalizer = CGM.CreateGlobalInitOrCleanUpFunction(5293 FTy, FnName.str(), FI, D.getLocation());5294 5295 CodeGenFunction CGF(CGM);5296 5297 CGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, StermFinalizer, FI,5298 FunctionArgList(), D.getLocation(),5299 D.getInit()->getExprLoc());5300 5301 // The unatexit subroutine unregisters __dtor functions that were previously5302 // registered by the atexit subroutine. If the referenced function is found,5303 // the unatexit returns a value of 0, meaning that the cleanup is still5304 // pending (and we should call the __dtor function).5305 llvm::Value *V = CGF.unregisterGlobalDtorWithUnAtExit(dtorStub);5306 5307 llvm::Value *NeedsDestruct = CGF.Builder.CreateIsNull(V, "needs_destruct");5308 5309 llvm::BasicBlock *DestructCallBlock = CGF.createBasicBlock("destruct.call");5310 llvm::BasicBlock *EndBlock = CGF.createBasicBlock("destruct.end");5311 5312 // Check if unatexit returns a value of 0. If it does, jump to5313 // DestructCallBlock, otherwise jump to EndBlock directly.5314 CGF.Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);5315 5316 CGF.EmitBlock(DestructCallBlock);5317 5318 // Emit the call to dtorStub.5319 llvm::CallInst *CI = CGF.Builder.CreateCall(dtorStub);5320 5321 // Make sure the call and the callee agree on calling convention.5322 CI->setCallingConv(dtorStub->getCallingConv());5323 5324 CGF.EmitBlock(EndBlock);5325 5326 CGF.FinishFunction();5327 5328 if (auto *IPA = D.getAttr<InitPriorityAttr>()) {5329 CGM.AddCXXPrioritizedStermFinalizerEntry(StermFinalizer,5330 IPA->getPriority());5331 } else if (isTemplateInstantiation(D.getTemplateSpecializationKind()) ||5332 getContext().GetGVALinkageForVariable(&D) == GVA_DiscardableODR) {5333 // According to C++ [basic.start.init]p2, class template static data5334 // members (i.e., implicitly or explicitly instantiated specializations)5335 // have unordered initialization. As a consequence, we can put them into5336 // their own llvm.global_dtors entry.5337 CGM.AddCXXStermFinalizerToGlobalDtor(StermFinalizer, 65535);5338 } else {5339 CGM.AddCXXStermFinalizerEntry(StermFinalizer);5340 }5341}5342