22#include "llvm/IR/IntrinsicInst.h"
23#include "llvm/Support/Format.h"
24#include "llvm/Transforms/Utils/Cloning.h"
29using namespace CodeGen;
32 : CGM(CGM), VTContext(CGM.getContext().getVTableContext()) {}
36 return GetOrCreateLLVMFunction(Name, FnTy, GD,
true,
41 llvm::Function *ThunkFn,
bool ForVTable,
51 ThunkFn->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
52 ThunkFn->setDSOLocal(
true);
56 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
64 (isa<PointerType>(typeL) && isa<PointerType>(typeR)) ||
65 (isa<ReferenceType>(typeL) && isa<ReferenceType>(typeR))));
75 llvm::BasicBlock *AdjustNull =
nullptr;
76 llvm::BasicBlock *AdjustNotNull =
nullptr;
77 llvm::BasicBlock *AdjustEnd =
nullptr;
100 CGF.
Builder.CreateBr(AdjustEnd);
102 CGF.
Builder.CreateBr(AdjustEnd);
105 llvm::PHINode *PHI = CGF.
Builder.CreatePHI(ReturnValue->getType(), 2);
106 PHI->addIncoming(ReturnValue, AdjustNotNull);
107 PHI->addIncoming(llvm::Constant::getNullValue(ReturnValue->getType()),
121 llvm::ValueToValueMapTy &VMap) {
123 auto *DIS = Fn->getSubprogram();
126 auto *NewDIS = DIS->replaceWithDistinct(DIS->clone());
127 VMap.MD()[DIS].reset(NewDIS);
131 for (
auto &BB : *Fn) {
133 if (
auto *DII = dyn_cast<llvm::DbgVariableIntrinsic>(&I)) {
134 auto *DILocal = DII->getVariable();
135 if (!DILocal->isResolved())
170 llvm::Function *BaseFn = cast<llvm::Function>(Callee);
179 assert(!BaseFn->isDeclaration() &&
"cannot clone undefined variadic method");
182 llvm::ValueToValueMapTy VMap;
187 llvm::Function *NewFn = llvm::CloneFunction(BaseFn, VMap);
188 Fn->replaceAllUsesWith(NewFn);
190 Fn->eraseFromParent();
197 llvm::Function::arg_iterator AI = Fn->arg_begin();
206 llvm::BasicBlock *EntryBB = &Fn->front();
207 llvm::BasicBlock::iterator ThisStore =
208 llvm::find_if(*EntryBB, [&](llvm::Instruction &I) {
209 return isa<llvm::StoreInst>(I) &&
212 assert(ThisStore != EntryBB->end() &&
213 "Store of this should be in entry block?");
215 Builder.SetInsertPoint(&*ThisStore);
216 llvm::Value *AdjustedThisPtr =
218 AdjustedThisPtr =
Builder.CreateBitCast(AdjustedThisPtr,
219 ThisStore->getOperand(0)->getType());
220 ThisStore->setOperand(0, AdjustedThisPtr);
224 for (llvm::BasicBlock &BB : *Fn) {
225 llvm::Instruction *T = BB.getTerminator();
226 if (isa<llvm::ReturnInst>(T)) {
228 T->eraseFromParent();
242 bool IsUnprototyped) {
254 ResultType = ThisType;
265 if (!IsUnprototyped) {
268 if (isa<CXXDestructorDecl>(MD))
282 CXXThisValue = CXXABIThisValue;
298 bool IsUnprototyped) {
300 "Please use a new CGF for this thunk");
304 llvm::Value *AdjustedThisPtr =
316 MD,
"return-adjusting thunk with incomplete parameter type");
318 llvm_unreachable(
"shouldn't try to emit musttail return-adjusting "
319 "thunks for variadic functions");
322 MD,
"non-trivial argument copy for return-adjusting thunk");
333 if (isa<CXXDestructorDecl>(MD))
337 unsigned PrefixArgs = CallArgs.size() - 1;
351 assert(isa<CXXDestructorDecl>(MD) ||
352 similar(CallFnInfo.getReturnInfo(), CallFnInfo.getReturnType(),
356 assert(
similar(CallFnInfo.arg_begin()[i].info,
357 CallFnInfo.arg_begin()[i].type,
376 llvm::CallBase *CallOrInvoke;
378 CallArgs, &CallOrInvoke);
383 else if (llvm::CallInst* Call = dyn_cast<llvm::CallInst>(CallOrInvoke))
384 Call->setTailCallKind(llvm::CallInst::TCK_Tail);
397 llvm::Value *AdjustedThisPtr,
398 llvm::FunctionCallee Callee) {
410 llvm::Type *ThisType = Args[ThisArgNo]->getType();
411 if (ThisType != AdjustedThisPtr->getType())
412 AdjustedThisPtr =
Builder.CreateBitCast(AdjustedThisPtr, ThisType);
413 Args[ThisArgNo] = AdjustedThisPtr;
415 assert(ThisAI.
isInAlloca() &&
"this is passed directly or inalloca");
418 if (ThisType != AdjustedThisPtr->getType())
419 AdjustedThisPtr =
Builder.CreateBitCast(AdjustedThisPtr, ThisType);
425 llvm::CallInst *
Call =
Builder.CreateCall(Callee, Args);
426 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
430 llvm::AttributeList Attrs;
434 Call->setAttributes(Attrs);
437 if (
Call->getType()->isVoidTy())
452 bool IsUnprototyped) {
469 Callee = llvm::ConstantExpr::getBitCast(Callee, Fn->getType());
473 &Thunk, IsUnprototyped);
477 bool IsUnprototyped,
bool ForVTable) {
494llvm::Constant *CodeGenVTables::maybeEmitThunk(
GlobalDecl GD,
504 llvm::raw_svector_ostream Out(Name);
510 llvm::Constant *Thunk = CGM.
GetAddrOfThunk(Name, ThunkVTableTy, GD);
527 llvm::Function *ThunkFn = cast<llvm::Function>(Thunk->stripPointerCasts());
528 if (ThunkFn->getFunctionType() != ThunkFnTy) {
529 llvm::GlobalValue *OldThunkFn = ThunkFn;
531 assert(OldThunkFn->isDeclaration() &&
"Shouldn't replace non-declaration");
534 OldThunkFn->setName(StringRef());
535 ThunkFn = llvm::Function::Create(ThunkFnTy, llvm::Function::ExternalLinkage,
540 if (!OldThunkFn->use_empty()) {
541 llvm::Constant *NewPtrForOldDecl =
542 llvm::ConstantExpr::getBitCast(ThunkFn, OldThunkFn->getType());
543 OldThunkFn->replaceAllUsesWith(NewPtrForOldDecl);
547 OldThunkFn->eraseFromParent();
551 bool UseAvailableExternallyLinkage = ForVTable && ABIHasKeyFunctions;
553 if (!ThunkFn->isDeclaration()) {
554 if (!ABIHasKeyFunctions || UseAvailableExternallyLinkage) {
568 ThunkFn->addFnAttr(
"thunk");
577 bool ShouldCloneVarArgs =
false;
578 if (!IsUnprototyped && ThunkFn->isVarArg()) {
579 ShouldCloneVarArgs =
true;
582 case llvm::Triple::x86_64:
583 case llvm::Triple::x86:
584 case llvm::Triple::aarch64:
585 ShouldCloneVarArgs =
false;
593 if (ShouldCloneVarArgs) {
594 if (UseAvailableExternallyLinkage)
618 if (!ThunkInfoVector)
621 for (
const ThunkInfo& Thunk : *ThunkInfoVector)
622 maybeEmitThunk(GD, Thunk,
false);
626 llvm::Constant *component,
627 unsigned vtableAddressPoint,
628 bool vtableHasLocalLinkage,
629 bool isCompleteDtor)
const {
631 if (component->isNullValue())
632 return builder.add(llvm::ConstantInt::get(CGM.
Int32Ty, 0));
635 cast<llvm::GlobalValue>(component->stripPointerCastsAndAliases());
642 auto stubLinkage = vtableHasLocalLinkage ? llvm::GlobalValue::InternalLinkage
643 : llvm::GlobalValue::ExternalLinkage;
645 llvm::Constant *target;
646 if (
auto *func = dyn_cast<llvm::Function>(globalVal)) {
647 target = llvm::DSOLocalEquivalent::get(func);
650 rttiProxyName.append(
".rtti_proxy");
656 llvm::GlobalVariable *proxy = module.getNamedGlobal(rttiProxyName);
658 proxy =
new llvm::GlobalVariable(module, globalVal->getType(),
660 globalVal, rttiProxyName);
661 proxy->setDSOLocal(
true);
662 proxy->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
663 if (!proxy->hasLocalLinkage()) {
664 proxy->setVisibility(llvm::GlobalValue::HiddenVisibility);
665 proxy->setComdat(module.getOrInsertComdat(rttiProxyName));
677 builder.addRelativeOffsetToPosition(CGM.
Int32Ty, target,
686bool CodeGenVTables::useRelativeLayout()
const {
696llvm::Type *CodeGenVTables::getVTableComponentType()
const {
703 builder.add(llvm::ConstantExpr::getIntToPtr(
716 unsigned componentIndex,
717 llvm::Constant *rtti,
718 unsigned &nextVTableThunkIndex,
719 unsigned vtableAddressPoint,
720 bool vtableHasLocalLinkage) {
723 auto addOffsetConstant =
726 switch (component.getKind()) {
728 return addOffsetConstant(CGM, builder, component.getVCallOffset());
731 return addOffsetConstant(CGM, builder, component.getVBaseOffset());
734 return addOffsetConstant(CGM, builder, component.getOffsetToTop());
737 if (useRelativeLayout())
738 return addRelativeComponent(builder, rtti, vtableAddressPoint,
739 vtableHasLocalLinkage,
742 return builder.add(llvm::ConstantExpr::getBitCast(rtti, CGM.
Int8PtrTy));
758 ? MD->
hasAttr<CUDADeviceAttr>()
759 : (MD->
hasAttr<CUDAHostAttr>() || !MD->
hasAttr<CUDADeviceAttr>());
761 return builder.add(llvm::ConstantExpr::getNullValue(CGM.
Int8PtrTy));
765 auto getSpecialVirtualFn = [&](StringRef
name) -> llvm::Constant * {
773 if (useRelativeLayout())
774 return llvm::ConstantPointerNull::get(CGM.
Int8PtrTy);
780 return llvm::ConstantPointerNull::get(CGM.
Int8PtrTy);
781 llvm::FunctionType *fnTy =
782 llvm::FunctionType::get(CGM.
VoidTy,
false);
783 llvm::Constant *fn = cast<llvm::Constant>(
785 if (
auto f = dyn_cast<llvm::Function>(fn))
786 f->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
787 return llvm::ConstantExpr::getBitCast(fn, CGM.
Int8PtrTy);
790 llvm::Constant *fnPtr;
793 if (cast<CXXMethodDecl>(GD.
getDecl())->isPure()) {
797 fnPtr = PureVirtualFn;
800 }
else if (cast<CXXMethodDecl>(GD.
getDecl())->isDeleted()) {
801 if (!DeletedVirtualFn)
804 fnPtr = DeletedVirtualFn;
807 }
else if (nextVTableThunkIndex < layout.
vtable_thunks().size() &&
810 auto &thunkInfo = layout.
vtable_thunks()[nextVTableThunkIndex].second;
812 nextVTableThunkIndex++;
813 fnPtr = maybeEmitThunk(GD, thunkInfo,
true);
821 if (useRelativeLayout()) {
822 return addRelativeComponent(
823 builder, fnPtr, vtableAddressPoint, vtableHasLocalLinkage,
826 return builder.add(llvm::ConstantExpr::getBitCast(fnPtr, CGM.
Int8PtrTy));
830 if (useRelativeLayout())
831 return builder.add(llvm::ConstantExpr::getNullValue(CGM.
Int32Ty));
833 return builder.addNullPointer(CGM.
Int8PtrTy);
836 llvm_unreachable(
"Unexpected vtable component kind");
841 llvm::Type *componentType = getVTableComponentType();
842 for (
unsigned i = 0, e = layout.
getNumVTables(); i != e; ++i)
843 tys.push_back(llvm::ArrayType::get(componentType, layout.
getVTableSize(i)));
850 llvm::Constant *rtti,
851 bool vtableHasLocalLinkage) {
852 llvm::Type *componentType = getVTableComponentType();
855 unsigned nextVTableThunkIndex = 0;
856 for (
unsigned vtableIndex = 0, endIndex = layout.
getNumVTables();
857 vtableIndex != endIndex; ++vtableIndex) {
858 auto vtableElem = builder.
beginArray(componentType);
861 size_t vtableEnd = vtableStart + layout.
getVTableSize(vtableIndex);
862 for (
size_t componentIndex = vtableStart; componentIndex < vtableEnd;
864 addVTableComponent(vtableElem, layout, componentIndex, rtti,
865 nextVTableThunkIndex, addressPoints[vtableIndex],
866 vtableHasLocalLinkage);
868 vtableElem.finishAndAddTo(builder);
874 llvm::GlobalVariable::LinkageTypes
Linkage,
875 VTableAddressPointsMapTy &AddressPoints) {
877 DI->completeClassData(
Base.getBase());
879 std::unique_ptr<VTableLayout> VTLayout(
881 Base.getBase(),
Base.getBaseOffset(), BaseIsVirtual, RD));
884 AddressPoints = VTLayout->getAddressPoints();
888 llvm::raw_svector_ostream Out(OutName);
890 .mangleCXXCtorVTable(RD,
Base.getBaseOffset().getQuantity(),
891 Base.getBase(), Out);
895 bool VTableAliasExists =
896 UsingRelativeLayout && CGM.
getModule().getNamedAlias(Name);
897 if (VTableAliasExists) {
899 Name.append(
".local");
909 if (
Linkage == llvm::GlobalVariable::AvailableExternallyLinkage)
910 Linkage = llvm::GlobalVariable::InternalLinkage;
912 llvm::Align Align = CGM.
getDataLayout().getABITypeAlign(VTType);
915 llvm::GlobalVariable *VTable =
919 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
928 VTable->hasLocalLinkage());
929 components.finishAndSetAsInitializer(VTable);
933 assert(!VTable->isDeclaration() &&
"Shouldn't set properties on declaration");
938 if (UsingRelativeLayout) {
940 if (!VTable->isDSOLocal())
957 llvm::GlobalValue::SanitizerMetadata Meta;
958 if (GV->hasSanitizerMetadata())
959 Meta = GV->getSanitizerMetadata();
960 Meta.NoHWAddress =
true;
961 GV->setSanitizerMetadata(Meta);
972 llvm::StringRef AliasNameRef) {
974 "Can only use this if the relative vtable ABI is used");
975 assert(!VTable->isDSOLocal() &&
"This should be called only if the vtable is "
976 "not guaranteed to be dso_local");
981 if (VTable->hasAvailableExternallyLinkage())
988 VTable->setName(AliasName +
".local");
990 auto Linkage = VTable->getLinkage();
991 assert(llvm::GlobalAlias::isValidLinkage(
Linkage) &&
992 "Invalid vtable alias linkage");
994 llvm::GlobalAlias *VTableAlias = CGM.
getModule().getNamedAlias(AliasName);
996 VTableAlias = llvm::GlobalAlias::create(VTable->getValueType(),
997 VTable->getAddressSpace(),
Linkage,
1000 assert(VTableAlias->getValueType() == VTable->getValueType());
1001 assert(VTableAlias->getLinkage() ==
Linkage);
1003 VTableAlias->setVisibility(VTable->getVisibility());
1004 VTableAlias->setUnnamedAddr(VTable->getUnnamedAddr());
1007 if (!VTable->hasComdat()) {
1012 VTable->setLinkage(llvm::GlobalValue::PrivateLinkage);
1015 VTable->setVisibility(llvm::GlobalValue::HiddenVisibility);
1018 VTableAlias->setAliasee(VTable);
1030llvm::GlobalVariable::LinkageTypes
1033 return llvm::GlobalVariable::InternalLinkage;
1038 if (keyFunction && !RD->
hasAttr<DLLImportAttr>()) {
1042 if (keyFunction->
hasBody(def))
1043 keyFunction = cast<CXXMethodDecl>(def);
1048 assert((def || CodeGenOpts.OptimizationLevel > 0 ||
1050 "Shouldn't query vtable linkage without key function, "
1051 "optimizations, or debug info");
1052 if (!def && CodeGenOpts.OptimizationLevel > 0)
1053 return llvm::GlobalVariable::AvailableExternallyLinkage;
1057 llvm::GlobalVariable::LinkOnceODRLinkage :
1058 llvm::Function::InternalLinkage;
1060 return llvm::GlobalVariable::ExternalLinkage;
1064 llvm::GlobalVariable::LinkOnceODRLinkage :
1065 llvm::Function::InternalLinkage;
1069 llvm::GlobalVariable::WeakODRLinkage :
1070 llvm::Function::InternalLinkage;
1073 llvm_unreachable(
"Should not have been asked to emit this");
1080 return llvm::Function::InternalLinkage;
1082 llvm::GlobalVariable::LinkageTypes DiscardableODRLinkage =
1083 llvm::GlobalValue::LinkOnceODRLinkage;
1084 llvm::GlobalVariable::LinkageTypes NonDiscardableODRLinkage =
1085 llvm::GlobalValue::WeakODRLinkage;
1086 if (RD->
hasAttr<DLLExportAttr>()) {
1088 DiscardableODRLinkage = NonDiscardableODRLinkage;
1089 }
else if (RD->
hasAttr<DLLImportAttr>()) {
1091 DiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;
1092 NonDiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;
1099 return DiscardableODRLinkage;
1105 return DiscardableODRLinkage;
1107 ? llvm::GlobalVariable::AvailableExternallyLinkage
1108 : llvm::GlobalVariable::ExternalLinkage;
1111 return NonDiscardableODRLinkage;
1114 llvm_unreachable(
"Invalid TemplateSpecializationKind!");
1130 DI->completeClassData(RD);
1149 assert(RD->
isDynamicClass() &&
"Non-dynamic classes have no VTable.");
1176 return !keyFunction->
hasBody();
1195void CodeGenModule::EmitDeferredVTables() {
1199 size_t savedSize = DeferredVTables.size();
1205 else if (shouldOpportunisticallyEmitVTables())
1206 OpportunisticVTables.push_back(RD);
1208 assert(savedSize == DeferredVTables.size() &&
1209 "deferred extra vtables during vtable emission?");
1210 DeferredVTables.clear();
1214 if (RD->
hasAttr<LTOVisibilityPublicAttr>() || RD->
hasAttr<UuidAttr>())
1222 auto *D = cast<Decl>(DC);
1225 if (
auto *ND = dyn_cast<NamespaceDecl>(D))
1227 if (II->isStr(
"std") || II->isStr(
"stdext"))
1242 if (RD->
hasAttr<DLLExportAttr>() || RD->
hasAttr<DLLImportAttr>())
1259 if (!Visited.insert(RD).second)
1260 return llvm::GlobalObject::VCallVisibilityTranslationUnit;
1263 llvm::GlobalObject::VCallVisibility TypeVis;
1265 TypeVis = llvm::GlobalObject::VCallVisibilityTranslationUnit;
1267 TypeVis = llvm::GlobalObject::VCallVisibilityLinkageUnit;
1269 TypeVis = llvm::GlobalObject::VCallVisibilityPublic;
1271 for (
auto B : RD->
bases())
1272 if (B.getType()->getAsCXXRecordDecl()->isDynamicClass())
1277 for (
auto B : RD->
vbases())
1278 if (B.getType()->getAsCXXRecordDecl()->isDynamicClass())
1287 llvm::GlobalVariable *VTable,
1294 typedef std::pair<const CXXRecordDecl *, unsigned> AddressPoint;
1295 std::vector<AddressPoint> AddressPoints;
1297 AddressPoints.push_back(std::make_pair(
1299 AP.second.AddressPointIndex));
1302 llvm::sort(AddressPoints, [
this](
const AddressPoint &AP1,
1303 const AddressPoint &AP2) {
1308 llvm::raw_string_ostream O1(S1);
1310 QualType(AP1.first->getTypeForDecl(), 0), O1);
1314 llvm::raw_string_ostream O2(S2);
1316 QualType(AP2.first->getTypeForDecl(), 0), O2);
1324 return AP1.second < AP2.second;
1328 for (
auto AP : AddressPoints) {
1336 for (
unsigned I = 0; I != Comps.size(); ++I) {
1341 Comps[I].getFunctionDecl()->getType(),
1343 VTable->addTypeMetadata((ComponentWidth * I).getQuantity(), MD);
1350 llvm::GlobalObject::VCallVisibility TypeVis =
1352 if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic)
1353 VTable->setVCallVisibilityMetadata(TypeVis);
static RValue PerformReturnAdjustment(CodeGenFunction &CGF, QualType ResultType, RValue RV, const ThunkInfo &Thunk)
static void setThunkProperties(CodeGenModule &CGM, const ThunkInfo &Thunk, llvm::Function *ThunkFn, bool ForVTable, GlobalDecl GD)
static bool shouldEmitVTableThunk(CodeGenModule &CGM, const CXXMethodDecl *MD, bool IsUnprototyped, bool ForVTable)
static void resolveTopLevelMetadata(llvm::Function *Fn, llvm::ValueToValueMapTy &VMap)
This function clones a function's DISubprogram node and enters it into a value map with the intent th...
static bool shouldEmitAvailableExternallyVTable(const CodeGenModule &CGM, const CXXRecordDecl *RD)
static bool shouldEmitVTableAtEndOfTranslationUnit(CodeGenModule &CGM, const CXXRecordDecl *RD)
Given that we're currently at the end of the translation unit, and we've emitted a reference to the v...
static void AddRelativeLayoutOffset(const CodeGenModule &CGM, ConstantArrayBuilder &builder, CharUnits offset)
static void AddPointerLayoutOffset(const CodeGenModule &CGM, ConstantArrayBuilder &builder, CharUnits offset)
static bool similar(const ABIArgInfo &infoL, CanQualType typeL, const ABIArgInfo &infoR, CanQualType typeR)
static bool UseRelativeLayout(const CodeGenModule &CGM)
static Decl::Kind getKind(const Decl *D)
QualType getTagDeclType(const TagDecl *Decl) const
Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl.
QualType getMemberPointerType(QualType T, const Type *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
QualType getRecordType(const RecordDecl *Decl) const
const CXXMethodDecl * getCurrentKeyFunction(const CXXRecordDecl *RD)
Get our current best idea for the key function of the given record decl, or nullptr if there isn't on...
const LangOptions & getLangOpts() const
Represents a C++ destructor within a class.
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
QualType getThisType() const
Return the type of the this pointer.
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Represents a C++ struct/union/class.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
base_class_range vbases()
bool isDynamicClass() const
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
@ Indirect
Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...
bool isSRetAfterThis() const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
llvm::Value * getPointer() const
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
virtual bool hasMostDerivedReturn(GlobalDecl GD) const
virtual llvm::Value * performReturnAdjustment(CodeGenFunction &CGF, Address Ret, const ReturnAdjustment &RA)=0
virtual bool HasThisReturn(GlobalDecl GD) const
Returns true if the given constructor or destructor is one of the kinds that the ABI says returns 'th...
virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF)=0
Emit the ABI-specific prolog for the function.
virtual StringRef GetPureVirtualCallName()=0
Gets the pure virtual member call function.
virtual void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV, QualType ResultType)
virtual bool canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const =0
Determine whether it's possible to emit a vtable for RD, even though we do not know that the vtable h...
virtual StringRef GetDeletedVirtualCallName()=0
Gets the deleted virtual member call name.
void buildThisParam(CodeGenFunction &CGF, FunctionArgList &Params)
Build a parameter variable suitable for 'this'.
virtual void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy, FunctionArgList &Params)=0
Insert any ABI-specific implicit parameters into the parameter list for a function.
virtual void setThunkLinkage(llvm::Function *Thunk, bool ForVTable, GlobalDecl GD, bool ReturnAdjustment)=0
virtual void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, GlobalDecl GD, CallArgList &CallArgs)
virtual void emitVirtualInheritanceTables(const CXXRecordDecl *RD)=0
Emit any tables needed to implement virtual inheritance.
virtual void emitVTableDefinitions(CodeGenVTables &CGVT, const CXXRecordDecl *RD)=0
Emits the VTable definitions required for the given record type.
virtual bool exportThunk()=0
virtual llvm::Value * performThisAdjustment(CodeGenFunction &CGF, Address This, const ThisAdjustment &TA)=0
MangleContext & getMangleContext()
Gets the mangle context.
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
CGFunctionInfo - Class to encapsulate the information about a function definition.
bool usesInAlloca() const
Return true if this function uses inalloca arguments.
ABIArgInfo & getReturnInfo()
unsigned getCallingConvention() const
getCallingConvention - Return the user specified calling convention, which has been translated into a...
const_arg_iterator arg_begin() const
unsigned getRegParm() const
CanQualType getReturnType() const
unsigned arg_size() const
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
void EmitCallAndReturnForThunk(llvm::FunctionCallee Callee, const ThunkInfo *Thunk, bool IsUnprototyped)
llvm::Function * GenerateVarArgsThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo, GlobalDecl GD, const ThunkInfo &Thunk)
void generateThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo, GlobalDecl GD, const ThunkInfo &Thunk, bool IsUnprototyped)
Generate a thunk for the given method.
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **callOrInvoke, bool IsMustTail, SourceLocation Loc)
EmitCall - Generate a call of the given function, expecting the given result type,...
llvm::Type * ConvertTypeForMem(QualType T)
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
void EmitDelegateCallArg(CallArgList &args, const VarDecl *param, SourceLocation loc)
EmitDelegateCallArg - We are performing a delegate call; that is, the current function is delegating ...
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
void StartThunk(llvm::Function *Fn, GlobalDecl GD, const CGFunctionInfo &FnInfo, bool IsUnprototyped)
bool AutoreleaseResult
In ARC, whether we should autorelease the return value.
Address LoadCXXThisAddress()
static bool hasAggregateEvaluationKind(QualType T)
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
const CGFunctionInfo * CurFnInfo
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
llvm::LLVMContext & getLLVMContext()
void EmitMustTailThunk(GlobalDecl GD, llvm::Value *AdjustedThisPtr, llvm::FunctionCallee Callee)
Emit a musttail call for a thunk with a potentially adjusted this pointer.
This class organizes the cross-function state that is used while generating LLVM code.
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
void AddVTableTypeMetadata(llvm::GlobalVariable *VTable, CharUnits Offset, const CXXRecordDecl *RD)
Create and attach type metadata for the given vtable.
llvm::GlobalObject::VCallVisibility GetVCallVisibilityLevel(const CXXRecordDecl *RD, llvm::DenseSet< const CXXRecordDecl * > &Visited)
Returns the vcall visibility of the given type.
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
CGDebugInfo * getModuleDebugInfo()
CodeGenVTables & getVTables()
CharUnits GetTargetTypeStoreSize(llvm::Type *Ty) const
Return the store size, in character units, of the given LLVM type.
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
llvm::Constant * GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty=nullptr, bool ForVTable=false, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the given function.
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn't support the specified stmt yet.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
void EmitVTableTypeMetadata(const CXXRecordDecl *RD, llvm::GlobalVariable *VTable, const VTableLayout &VTLayout)
Emit type metadata for the given vtable using the given layout.
bool HasHiddenLTOVisibility(const CXXRecordDecl *RD)
Returns whether the given record has hidden LTO visibility and therefore may participate in (single-m...
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
CharUnits getClassPointerAlignment(const CXXRecordDecl *CD)
Returns the assumed alignment of an opaque pointer to the given class.
const llvm::Triple & getTriple() const
bool AlwaysHasLTOVisibilityPublic(const CXXRecordDecl *RD)
Returns whether the given record has public LTO visibility (regardless of -lto-whole-program-visibili...
void EmitVTable(CXXRecordDecl *Class)
This is a callback from Sema to tell us that a particular vtable is required to be emitted in this tr...
void ConstructAttributeList(StringRef Name, const CGFunctionInfo &Info, CGCalleeInfo CalleeInfo, llvm::AttributeList &Attrs, unsigned &CallingConv, bool AttrOnCallSite, bool IsThunk)
Get the LLVM attributes and calling convention to use for a particular function type.
void setFunctionLinkage(GlobalDecl GD, llvm::Function *F)
ItaniumVTableContext & getItaniumVTableContext()
ASTContext & getContext() const
llvm::Type * getVTableComponentType() const
bool supportsCOMDAT() const
bool ReturnTypeUsesSRet(const CGFunctionInfo &FI)
Return true iff the given type uses 'sret' when used as a return type.
const CodeGenOptions & getCodeGenOpts() const
llvm::GlobalVariable * CreateOrReplaceCXXRuntimeVariable(StringRef Name, llvm::Type *Ty, llvm::GlobalValue::LinkageTypes Linkage, llvm::Align Alignment)
Will return a global variable of the given type.
llvm::LLVMContext & getLLVMContext()
llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F, bool IsThunk)
Set the LLVM function attributes (sext, zext, etc).
void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)
Set the LLVM function attributes which only apply to a function definition.
llvm::Metadata * CreateMetadataIdentifierForVirtualMemPtrType(QualType T)
Create a metadata identifier that is intended to be used to check virtual calls via a member function...
llvm::Constant * GetAddrOfThunk(StringRef Name, llvm::Type *FnTy, GlobalDecl GD)
Get the address of the thunk for the given global decl.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
bool isFuncTypeConvertible(const FunctionType *FT)
isFuncTypeConvertible - Utility to check whether a function type can be converted to an LLVM type (i....
const CGFunctionInfo & arrangeGlobalDeclaration(GlobalDecl GD)
const CGFunctionInfo & arrangeUnprototypedMustTailThunk(const CXXMethodDecl *MD)
Arrange a thunk that takes 'this' as the first parameter followed by varargs.
const CGFunctionInfo & arrangeCXXMethodCall(const CallArgList &args, const FunctionProtoType *type, RequiredArgs required, unsigned numPrefixArgs)
Arrange a call to a C++ method, passing the given arguments.
llvm::Type * GetFunctionTypeForVTable(GlobalDecl GD)
GetFunctionTypeForVTable - Get the LLVM function type for use in a vtable, given a CXXMethodDecl.
void createVTableInitializer(ConstantStructBuilder &builder, const VTableLayout &layout, llvm::Constant *rtti, bool vtableHasLocalLinkage)
Add vtable components for the given vtable layout to the given global initializer.
void GenerateClassData(const CXXRecordDecl *RD)
GenerateClassData - Generate all the class data required to be generated upon definition of a KeyFunc...
void GenerateRelativeVTableAlias(llvm::GlobalVariable *VTable, llvm::StringRef AliasNameRef)
Generate a public facing alias for the vtable and make the vtable either hidden or private.
ItaniumVTableContext & getItaniumVTableContext()
CodeGenVTables(CodeGenModule &CGM)
llvm::GlobalVariable * GenerateConstructionVTable(const CXXRecordDecl *RD, const BaseSubobject &Base, bool BaseIsVirtual, llvm::GlobalVariable::LinkageTypes Linkage, VTableAddressPointsMapTy &AddressPoints)
GenerateConstructionVTable - Generate a construction vtable for the given base subobject.
llvm::Type * getVTableType(const VTableLayout &layout)
Returns the type of a vtable with the given layout.
bool isVTableExternal(const CXXRecordDecl *RD)
At this point in the translation unit, does it appear that can we rely on the vtable being defined el...
void RemoveHwasanMetadata(llvm::GlobalValue *GV) const
Specify a global should not be instrumented with hwasan.
void EmitThunks(GlobalDecl GD)
EmitThunks - Emit the associated thunks for the given global decl.
ArrayBuilder beginArray(llvm::Type *eltTy=nullptr)
A helper class of ConstantInitBuilder, used for building constant array initializers.
StructBuilder beginStruct(llvm::StructType *structTy=nullptr)
The standard implementation of ConstantInitBuilder used in Clang.
A helper class of ConstantInitBuilder, used for building constant struct initializers.
FunctionArgList - Type for representing both the decl and type of parameters to a function.
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, unsigned additional)
Compute the arguments required by the given formal prototype, given that there may be some additional...
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
SourceLocation getLocation() const
Represents a function declaration or definition.
param_iterator param_end()
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
ArrayRef< ParmVarDecl * > parameters() const
param_iterator param_begin()
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template instantiation this function represents.
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
bool isDefined(const FunctionDecl *&Definition, bool CheckForPendingFriendDefinition=false) const
Returns true if the function has a definition that does not need to be instantiated.
Represents a prototype with parameter type info, e.g.
FunctionType - C99 6.7.5.3 - Function Declarators.
QualType getReturnType() const
GlobalDecl - represents a global declaration.
CXXDtorType getDtorType() const
const Decl * getDecl() const
One of these records is kept for each identifier that is lexed.
bool isRelativeLayout() const
SanitizerSet Sanitize
Set of enabled sanitizers.
Visibility getVisibility() const
Linkage getLinkage() const
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
virtual void mangleTypeName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
Generates a unique string for an externally visible type for use with TBAA or type uniquing.
virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, const ThisAdjustment &ThisAdjustment, raw_ostream &)=0
virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, raw_ostream &)=0
LinkageInfo getLinkageAndVisibility() const
Determines the linkage and visibility of this entity.
bool isExternallyVisible() const
Represents a parameter to a function.
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Encodes a location in the source.
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
bool isItaniumFamily() const
Does this ABI generally fall into the Itanium family of ABIs?
bool hasKeyFunctions() const
Does this ABI use key functions? If so, class data such as the vtable is emitted with strong linkage ...
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
@ CK_DeletingDtorPointer
A pointer to the deleting destructor.
@ CK_UnusedFunctionPointer
An entry that is never used.
@ CK_CompleteDtorPointer
A pointer to the complete destructor.
virtual const ThunkInfoVectorTy * getThunkInfo(GlobalDecl GD)
const AddressPointsIndexMapTy & getAddressPointIndices() const
size_t getVTableOffset(size_t i) const
ArrayRef< VTableComponent > vtable_components() const
size_t getNumVTables() const
ArrayRef< VTableThunkTy > vtable_thunks() const
const AddressPointsMapTy & getAddressPoints() const
size_t getVTableSize(size_t i) const
@ NoDebugInfo
Don't generate debug info.
bool Call(InterpState &S, CodePtr &PC, const Function *Func)
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
@ Dtor_Base
Base object dtor.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
CallingConv
CallingConv - Specifies the calling convention that a function uses.
bool isExternallyVisible(Linkage L)
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
llvm::IntegerType * Int32Ty
llvm::PointerType * Int8PtrTy
llvm::IntegerType * PtrDiffTy
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
The this pointer adjustment as well as an optional return adjustment for a thunk.
ThisAdjustment This
The this pointer adjustment.
ReturnAdjustment Return
The return adjustment.