10b57cec5SDimitry Andric //===--- CGCXX.cpp - Emit LLVM Code for declarations ----------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This contains code dealing with C++ code generation. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric // We might split this into multiple files if it gets too unwieldy 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #include "CGCXXABI.h" 160b57cec5SDimitry Andric #include "CodeGenFunction.h" 17480093f4SDimitry Andric #include "CodeGenModule.h" 180b57cec5SDimitry Andric #include "clang/AST/ASTContext.h" 19480093f4SDimitry Andric #include "clang/AST/Attr.h" 200b57cec5SDimitry Andric #include "clang/AST/Decl.h" 210b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h" 220b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h" 230b57cec5SDimitry Andric #include "clang/AST/Mangle.h" 240b57cec5SDimitry Andric #include "clang/AST/RecordLayout.h" 250b57cec5SDimitry Andric #include "clang/AST/StmtCXX.h" 260b57cec5SDimitry Andric #include "clang/Basic/CodeGenOptions.h" 270b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h" 280b57cec5SDimitry Andric using namespace clang; 290b57cec5SDimitry Andric using namespace CodeGen; 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric /// Try to emit a base destructor as an alias to its primary 330b57cec5SDimitry Andric /// base-class destructor. 340b57cec5SDimitry Andric bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) { 350b57cec5SDimitry Andric if (!getCodeGenOpts().CXXCtorDtorAliases) 360b57cec5SDimitry Andric return true; 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric // Producing an alias to a base class ctor/dtor can degrade debug quality 390b57cec5SDimitry Andric // as the debugger cannot tell them apart. 400b57cec5SDimitry Andric if (getCodeGenOpts().OptimizationLevel == 0) 410b57cec5SDimitry Andric return true; 420b57cec5SDimitry Andric 437a6dacacSDimitry Andric // Disable this optimization for ARM64EC. FIXME: This probably should work, 447a6dacacSDimitry Andric // but getting the symbol table correct is complicated. 457a6dacacSDimitry Andric if (getTarget().getTriple().isWindowsArm64EC()) 467a6dacacSDimitry Andric return true; 477a6dacacSDimitry Andric 480b57cec5SDimitry Andric // If sanitizing memory to check for use-after-dtor, do not emit as 490b57cec5SDimitry Andric // an alias, unless this class owns no members. 500b57cec5SDimitry Andric if (getCodeGenOpts().SanitizeMemoryUseAfterDtor && 510b57cec5SDimitry Andric !D->getParent()->field_empty()) 520b57cec5SDimitry Andric return true; 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric // If the destructor doesn't have a trivial body, we have to emit it 550b57cec5SDimitry Andric // separately. 560b57cec5SDimitry Andric if (!D->hasTrivialBody()) 570b57cec5SDimitry Andric return true; 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric const CXXRecordDecl *Class = D->getParent(); 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric // We are going to instrument this destructor, so give up even if it is 620b57cec5SDimitry Andric // currently empty. 630b57cec5SDimitry Andric if (Class->mayInsertExtraPadding()) 640b57cec5SDimitry Andric return true; 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric // If we need to manipulate a VTT parameter, give up. 670b57cec5SDimitry Andric if (Class->getNumVBases()) { 680b57cec5SDimitry Andric // Extra Credit: passing extra parameters is perfectly safe 690b57cec5SDimitry Andric // in many calling conventions, so only bail out if the ctor's 700b57cec5SDimitry Andric // calling convention is nonstandard. 710b57cec5SDimitry Andric return true; 720b57cec5SDimitry Andric } 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric // If any field has a non-trivial destructor, we have to emit the 750b57cec5SDimitry Andric // destructor separately. 760b57cec5SDimitry Andric for (const auto *I : Class->fields()) 770b57cec5SDimitry Andric if (I->getType().isDestructedType()) 780b57cec5SDimitry Andric return true; 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric // Try to find a unique base class with a non-trivial destructor. 810b57cec5SDimitry Andric const CXXRecordDecl *UniqueBase = nullptr; 820b57cec5SDimitry Andric for (const auto &I : Class->bases()) { 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric // We're in the base destructor, so skip virtual bases. 850b57cec5SDimitry Andric if (I.isVirtual()) continue; 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric // Skip base classes with trivial destructors. 880b57cec5SDimitry Andric const auto *Base = 89a7dea167SDimitry Andric cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl()); 900b57cec5SDimitry Andric if (Base->hasTrivialDestructor()) continue; 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric // If we've already found a base class with a non-trivial 930b57cec5SDimitry Andric // destructor, give up. 940b57cec5SDimitry Andric if (UniqueBase) return true; 950b57cec5SDimitry Andric UniqueBase = Base; 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric // If we didn't find any bases with a non-trivial destructor, then 990b57cec5SDimitry Andric // the base destructor is actually effectively trivial, which can 1000b57cec5SDimitry Andric // happen if it was needlessly user-defined or if there are virtual 1010b57cec5SDimitry Andric // bases with non-trivial destructors. 1020b57cec5SDimitry Andric if (!UniqueBase) 1030b57cec5SDimitry Andric return true; 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric // If the base is at a non-zero offset, give up. 1060b57cec5SDimitry Andric const ASTRecordLayout &ClassLayout = Context.getASTRecordLayout(Class); 1070b57cec5SDimitry Andric if (!ClassLayout.getBaseClassOffset(UniqueBase).isZero()) 1080b57cec5SDimitry Andric return true; 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric // Give up if the calling conventions don't match. We could update the call, 1110b57cec5SDimitry Andric // but it is probably not worth it. 1120b57cec5SDimitry Andric const CXXDestructorDecl *BaseD = UniqueBase->getDestructor(); 113a7dea167SDimitry Andric if (BaseD->getType()->castAs<FunctionType>()->getCallConv() != 114a7dea167SDimitry Andric D->getType()->castAs<FunctionType>()->getCallConv()) 1150b57cec5SDimitry Andric return true; 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric GlobalDecl AliasDecl(D, Dtor_Base); 1180b57cec5SDimitry Andric GlobalDecl TargetDecl(BaseD, Dtor_Base); 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric // The alias will use the linkage of the referent. If we can't 1210b57cec5SDimitry Andric // support aliases with that linkage, fail. 1220b57cec5SDimitry Andric llvm::GlobalValue::LinkageTypes Linkage = getFunctionLinkage(AliasDecl); 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric // We can't use an alias if the linkage is not valid for one. 1250b57cec5SDimitry Andric if (!llvm::GlobalAlias::isValidLinkage(Linkage)) 1260b57cec5SDimitry Andric return true; 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric llvm::GlobalValue::LinkageTypes TargetLinkage = 1290b57cec5SDimitry Andric getFunctionLinkage(TargetDecl); 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric // Check if we have it already. 1320b57cec5SDimitry Andric StringRef MangledName = getMangledName(AliasDecl); 1330b57cec5SDimitry Andric llvm::GlobalValue *Entry = GetGlobalValue(MangledName); 1340b57cec5SDimitry Andric if (Entry && !Entry->isDeclaration()) 1350b57cec5SDimitry Andric return false; 1360b57cec5SDimitry Andric if (Replacements.count(MangledName)) 1370b57cec5SDimitry Andric return false; 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric llvm::Type *AliasValueType = getTypes().GetFunctionType(AliasDecl); 1400b57cec5SDimitry Andric 14106c3fb27SDimitry Andric // Find the referent. 14206c3fb27SDimitry Andric auto *Aliasee = cast<llvm::GlobalValue>(GetAddrOfGlobal(TargetDecl)); 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric // Instead of creating as alias to a linkonce_odr, replace all of the uses 1450b57cec5SDimitry Andric // of the aliasee. 1460b57cec5SDimitry Andric if (llvm::GlobalValue::isDiscardableIfUnused(Linkage) && 1470b57cec5SDimitry Andric !(TargetLinkage == llvm::GlobalValue::AvailableExternallyLinkage && 1480b57cec5SDimitry Andric TargetDecl.getDecl()->hasAttr<AlwaysInlineAttr>())) { 1490b57cec5SDimitry Andric // FIXME: An extern template instantiation will create functions with 1500b57cec5SDimitry Andric // linkage "AvailableExternally". In libc++, some classes also define 1510b57cec5SDimitry Andric // members with attribute "AlwaysInline" and expect no reference to 1520b57cec5SDimitry Andric // be generated. It is desirable to reenable this optimisation after 1530b57cec5SDimitry Andric // corresponding LLVM changes. 1540b57cec5SDimitry Andric addReplacement(MangledName, Aliasee); 1550b57cec5SDimitry Andric return false; 1560b57cec5SDimitry Andric } 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric // If we have a weak, non-discardable alias (weak, weak_odr), like an extern 1590b57cec5SDimitry Andric // template instantiation or a dllexported class, avoid forming it on COFF. 1600b57cec5SDimitry Andric // A COFF weak external alias cannot satisfy a normal undefined symbol 1610b57cec5SDimitry Andric // reference from another TU. The other TU must also mark the referenced 1620b57cec5SDimitry Andric // symbol as weak, which we cannot rely on. 1630b57cec5SDimitry Andric if (llvm::GlobalValue::isWeakForLinker(Linkage) && 1640b57cec5SDimitry Andric getTriple().isOSBinFormatCOFF()) { 1650b57cec5SDimitry Andric return true; 1660b57cec5SDimitry Andric } 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric // If we don't have a definition for the destructor yet or the definition is 1690b57cec5SDimitry Andric // avaialable_externally, don't emit an alias. We can't emit aliases to 1700b57cec5SDimitry Andric // declarations; that's just not how aliases work. 17106c3fb27SDimitry Andric if (Aliasee->isDeclarationForLinker()) 1720b57cec5SDimitry Andric return true; 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andric // Don't create an alias to a linker weak symbol. This avoids producing 1750b57cec5SDimitry Andric // different COMDATs in different TUs. Another option would be to 1760b57cec5SDimitry Andric // output the alias both for weak_odr and linkonce_odr, but that 1770b57cec5SDimitry Andric // requires explicit comdat support in the IL. 1780b57cec5SDimitry Andric if (llvm::GlobalValue::isWeakForLinker(TargetLinkage)) 1790b57cec5SDimitry Andric return true; 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric // Create the alias with no name. 1820b57cec5SDimitry Andric auto *Alias = llvm::GlobalAlias::create(AliasValueType, 0, Linkage, "", 1830b57cec5SDimitry Andric Aliasee, &getModule()); 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric // Destructors are always unnamed_addr. 1860b57cec5SDimitry Andric Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric // Switch any previous uses to the alias. 1890b57cec5SDimitry Andric if (Entry) { 19006c3fb27SDimitry Andric assert(Entry->getValueType() == AliasValueType && 19106c3fb27SDimitry Andric Entry->getAddressSpace() == Alias->getAddressSpace() && 1920b57cec5SDimitry Andric "declaration exists with different type"); 1930b57cec5SDimitry Andric Alias->takeName(Entry); 1940b57cec5SDimitry Andric Entry->replaceAllUsesWith(Alias); 1950b57cec5SDimitry Andric Entry->eraseFromParent(); 1960b57cec5SDimitry Andric } else { 1970b57cec5SDimitry Andric Alias->setName(MangledName); 1980b57cec5SDimitry Andric } 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric // Finally, set up the alias with its proper name and attributes. 2010b57cec5SDimitry Andric SetCommonAttributes(AliasDecl, Alias); 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric return false; 2040b57cec5SDimitry Andric } 2050b57cec5SDimitry Andric 2060b57cec5SDimitry Andric llvm::Function *CodeGenModule::codegenCXXStructor(GlobalDecl GD) { 2070b57cec5SDimitry Andric const CGFunctionInfo &FnInfo = getTypes().arrangeCXXStructorDeclaration(GD); 2080b57cec5SDimitry Andric auto *Fn = cast<llvm::Function>( 2090b57cec5SDimitry Andric getAddrOfCXXStructor(GD, &FnInfo, /*FnType=*/nullptr, 2100b57cec5SDimitry Andric /*DontDefer=*/true, ForDefinition)); 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric setFunctionLinkage(GD, Fn); 2130b57cec5SDimitry Andric 2140b57cec5SDimitry Andric CodeGenFunction(*this).GenerateCode(GD, Fn, FnInfo); 2150b57cec5SDimitry Andric setNonAliasAttributes(GD, Fn); 2160b57cec5SDimitry Andric SetLLVMFunctionAttributesForDefinition(cast<CXXMethodDecl>(GD.getDecl()), Fn); 2170b57cec5SDimitry Andric return Fn; 2180b57cec5SDimitry Andric } 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric llvm::FunctionCallee CodeGenModule::getAddrAndTypeOfCXXStructor( 2210b57cec5SDimitry Andric GlobalDecl GD, const CGFunctionInfo *FnInfo, llvm::FunctionType *FnType, 2220b57cec5SDimitry Andric bool DontDefer, ForDefinition_t IsForDefinition) { 2230b57cec5SDimitry Andric auto *MD = cast<CXXMethodDecl>(GD.getDecl()); 2240b57cec5SDimitry Andric 2250b57cec5SDimitry Andric if (isa<CXXDestructorDecl>(MD)) { 2260b57cec5SDimitry Andric // Always alias equivalent complete destructors to base destructors in the 2270b57cec5SDimitry Andric // MS ABI. 2280b57cec5SDimitry Andric if (getTarget().getCXXABI().isMicrosoft() && 2290b57cec5SDimitry Andric GD.getDtorType() == Dtor_Complete && 2300b57cec5SDimitry Andric MD->getParent()->getNumVBases() == 0) 2310b57cec5SDimitry Andric GD = GD.getWithDtorType(Dtor_Base); 2320b57cec5SDimitry Andric } 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric if (!FnType) { 2350b57cec5SDimitry Andric if (!FnInfo) 2360b57cec5SDimitry Andric FnInfo = &getTypes().arrangeCXXStructorDeclaration(GD); 2370b57cec5SDimitry Andric FnType = getTypes().GetFunctionType(*FnInfo); 2380b57cec5SDimitry Andric } 2390b57cec5SDimitry Andric 2400b57cec5SDimitry Andric llvm::Constant *Ptr = GetOrCreateLLVMFunction( 2410b57cec5SDimitry Andric getMangledName(GD), FnType, GD, /*ForVTable=*/false, DontDefer, 2420b57cec5SDimitry Andric /*IsThunk=*/false, /*ExtraAttrs=*/llvm::AttributeList(), IsForDefinition); 2430b57cec5SDimitry Andric return {FnType, Ptr}; 2440b57cec5SDimitry Andric } 2450b57cec5SDimitry Andric 2460b57cec5SDimitry Andric static CGCallee BuildAppleKextVirtualCall(CodeGenFunction &CGF, 2470b57cec5SDimitry Andric GlobalDecl GD, 2480b57cec5SDimitry Andric llvm::Type *Ty, 2490b57cec5SDimitry Andric const CXXRecordDecl *RD) { 2500b57cec5SDimitry Andric assert(!CGF.CGM.getTarget().getCXXABI().isMicrosoft() && 2510b57cec5SDimitry Andric "No kext in Microsoft ABI"); 2520b57cec5SDimitry Andric CodeGenModule &CGM = CGF.CGM; 2530b57cec5SDimitry Andric llvm::Value *VTable = CGM.getCXXABI().getAddrOfVTable(RD, CharUnits()); 25406c3fb27SDimitry Andric Ty = llvm::PointerType::getUnqual(CGM.getLLVMContext()); 2550b57cec5SDimitry Andric assert(VTable && "BuildVirtualCall = kext vtbl pointer is null"); 2560b57cec5SDimitry Andric uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD); 2570b57cec5SDimitry Andric const VTableLayout &VTLayout = CGM.getItaniumVTableContext().getVTableLayout(RD); 2580b57cec5SDimitry Andric VTableLayout::AddressPointLocation AddressPoint = 2590b57cec5SDimitry Andric VTLayout.getAddressPoint(BaseSubobject(RD, CharUnits::Zero())); 2600b57cec5SDimitry Andric VTableIndex += VTLayout.getVTableOffset(AddressPoint.VTableIndex) + 2610b57cec5SDimitry Andric AddressPoint.AddressPointIndex; 2620b57cec5SDimitry Andric llvm::Value *VFuncPtr = 263fe6060f1SDimitry Andric CGF.Builder.CreateConstInBoundsGEP1_64(Ty, VTable, VTableIndex, "vfnkxt"); 2645ffd83dbSDimitry Andric llvm::Value *VFunc = CGF.Builder.CreateAlignedLoad( 265fe6060f1SDimitry Andric Ty, VFuncPtr, llvm::Align(CGF.PointerAlignInBytes)); 266*0fca6ea1SDimitry Andric 267*0fca6ea1SDimitry Andric CGPointerAuthInfo PointerAuth; 268*0fca6ea1SDimitry Andric if (auto &Schema = 269*0fca6ea1SDimitry Andric CGM.getCodeGenOpts().PointerAuth.CXXVirtualFunctionPointers) { 270*0fca6ea1SDimitry Andric GlobalDecl OrigMD = 271*0fca6ea1SDimitry Andric CGM.getItaniumVTableContext().findOriginalMethod(GD.getCanonicalDecl()); 272*0fca6ea1SDimitry Andric PointerAuth = CGF.EmitPointerAuthInfo(Schema, VFuncPtr, OrigMD, QualType()); 273*0fca6ea1SDimitry Andric } 274*0fca6ea1SDimitry Andric 275*0fca6ea1SDimitry Andric CGCallee Callee(GD, VFunc, PointerAuth); 2760b57cec5SDimitry Andric return Callee; 2770b57cec5SDimitry Andric } 2780b57cec5SDimitry Andric 2790b57cec5SDimitry Andric /// BuildAppleKextVirtualCall - This routine is to support gcc's kext ABI making 2800b57cec5SDimitry Andric /// indirect call to virtual functions. It makes the call through indexing 2810b57cec5SDimitry Andric /// into the vtable. 2820b57cec5SDimitry Andric CGCallee 2830b57cec5SDimitry Andric CodeGenFunction::BuildAppleKextVirtualCall(const CXXMethodDecl *MD, 2840b57cec5SDimitry Andric NestedNameSpecifier *Qual, 2850b57cec5SDimitry Andric llvm::Type *Ty) { 2860b57cec5SDimitry Andric assert((Qual->getKind() == NestedNameSpecifier::TypeSpec) && 2870b57cec5SDimitry Andric "BuildAppleKextVirtualCall - bad Qual kind"); 2880b57cec5SDimitry Andric 2890b57cec5SDimitry Andric const Type *QTy = Qual->getAsType(); 2900b57cec5SDimitry Andric QualType T = QualType(QTy, 0); 2910b57cec5SDimitry Andric const RecordType *RT = T->getAs<RecordType>(); 2920b57cec5SDimitry Andric assert(RT && "BuildAppleKextVirtualCall - Qual type must be record"); 2930b57cec5SDimitry Andric const auto *RD = cast<CXXRecordDecl>(RT->getDecl()); 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric if (const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) 2960b57cec5SDimitry Andric return BuildAppleKextVirtualDestructorCall(DD, Dtor_Complete, RD); 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric return ::BuildAppleKextVirtualCall(*this, MD, Ty, RD); 2990b57cec5SDimitry Andric } 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric /// BuildVirtualCall - This routine makes indirect vtable call for 3020b57cec5SDimitry Andric /// call to virtual destructors. It returns 0 if it could not do it. 3030b57cec5SDimitry Andric CGCallee 3040b57cec5SDimitry Andric CodeGenFunction::BuildAppleKextVirtualDestructorCall( 3050b57cec5SDimitry Andric const CXXDestructorDecl *DD, 3060b57cec5SDimitry Andric CXXDtorType Type, 3070b57cec5SDimitry Andric const CXXRecordDecl *RD) { 3080b57cec5SDimitry Andric assert(DD->isVirtual() && Type != Dtor_Base); 3090b57cec5SDimitry Andric // Compute the function type we're calling. 3100b57cec5SDimitry Andric const CGFunctionInfo &FInfo = CGM.getTypes().arrangeCXXStructorDeclaration( 3110b57cec5SDimitry Andric GlobalDecl(DD, Dtor_Complete)); 3120b57cec5SDimitry Andric llvm::Type *Ty = CGM.getTypes().GetFunctionType(FInfo); 3130b57cec5SDimitry Andric return ::BuildAppleKextVirtualCall(*this, GlobalDecl(DD, Type), Ty, RD); 3140b57cec5SDimitry Andric } 315