23#include "llvm/IR/IntrinsicInst.h"
24#include "llvm/Transforms/Utils/Cloning.h"
30using namespace CodeGen;
33 : CGM(CGM), VTContext(CGM.getContext().getVTableContext()) {}
37 return GetOrCreateLLVMFunction(Name, FnTy, GD,
true,
42 llvm::Function *ThunkFn,
bool ForVTable,
52 ThunkFn->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
53 ThunkFn->setDSOLocal(
true);
57 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
65 (isa<PointerType>(typeL) && isa<PointerType>(typeR)) ||
66 (isa<ReferenceType>(typeL) && isa<ReferenceType>(typeR))));
76 llvm::BasicBlock *AdjustNull =
nullptr;
77 llvm::BasicBlock *AdjustNotNull =
nullptr;
78 llvm::BasicBlock *AdjustEnd =
nullptr;
100 if (NullCheckValue) {
101 CGF.
Builder.CreateBr(AdjustEnd);
103 CGF.
Builder.CreateBr(AdjustEnd);
106 llvm::PHINode *PHI = CGF.
Builder.CreatePHI(ReturnValue->getType(), 2);
107 PHI->addIncoming(ReturnValue, AdjustNotNull);
108 PHI->addIncoming(llvm::Constant::getNullValue(ReturnValue->getType()),
122 llvm::ValueToValueMapTy &VMap) {
124 auto *DIS = Fn->getSubprogram();
127 auto *NewDIS = llvm::MDNode::replaceWithDistinct(DIS->clone());
128 VMap.MD()[DIS].reset(NewDIS);
132 for (
auto &BB : *Fn) {
134 for (llvm::DbgVariableRecord &DVR :
135 llvm::filterDbgVars(I.getDbgRecordRange())) {
136 auto *DILocal = DVR.getVariable();
137 if (!DILocal->isResolved())
140 if (
auto *DII = dyn_cast<llvm::DbgVariableIntrinsic>(&I)) {
141 auto *DILocal = DII->getVariable();
142 if (!DILocal->isResolved())
177 llvm::Function *BaseFn = cast<llvm::Function>(Callee);
186 assert(!BaseFn->isDeclaration() &&
"cannot clone undefined variadic method");
189 llvm::ValueToValueMapTy VMap;
194 llvm::Function *NewFn = llvm::CloneFunction(BaseFn, VMap);
195 Fn->replaceAllUsesWith(NewFn);
197 Fn->eraseFromParent();
204 llvm::Function::arg_iterator AI = Fn->arg_begin();
213 llvm::BasicBlock *EntryBB = &Fn->front();
214 llvm::BasicBlock::iterator ThisStore =
215 llvm::find_if(*EntryBB, [&](llvm::Instruction &I) {
216 return isa<llvm::StoreInst>(I) && I.getOperand(0) == &*AI;
218 assert(ThisStore != EntryBB->end() &&
219 "Store of this should be in entry block?");
221 Builder.SetInsertPoint(&*ThisStore);
225 *
this, ThisPtr, ThisValueClass, Thunk);
226 AdjustedThisPtr =
Builder.CreateBitCast(AdjustedThisPtr,
227 ThisStore->getOperand(0)->getType());
228 ThisStore->setOperand(0, AdjustedThisPtr);
232 for (llvm::BasicBlock &BB : *Fn) {
233 llvm::Instruction *
T = BB.getTerminator();
234 if (isa<llvm::ReturnInst>(
T)) {
236 T->eraseFromParent();
250 bool IsUnprototyped) {
262 ResultType = ThisType;
273 if (!IsUnprototyped) {
276 if (isa<CXXDestructorDecl>(MD))
290 CXXThisValue = CXXABIThisValue;
306 bool IsUnprototyped) {
308 "Please use a new CGF for this thunk");
317 llvm::Value *AdjustedThisPtr =
319 ThisValueClass, *Thunk)
329 MD,
"return-adjusting thunk with incomplete parameter type");
331 llvm_unreachable(
"shouldn't try to emit musttail return-adjusting "
332 "thunks for variadic functions");
335 MD,
"non-trivial argument copy for return-adjusting thunk");
346 if (isa<CXXDestructorDecl>(MD))
350 unsigned PrefixArgs = CallArgs.size() - 1;
364 assert(isa<CXXDestructorDecl>(MD) ||
365 similar(CallFnInfo.getReturnInfo(), CallFnInfo.getReturnType(),
369 assert(
similar(CallFnInfo.arg_begin()[i].info,
370 CallFnInfo.arg_begin()[i].type,
389 llvm::CallBase *CallOrInvoke;
391 CallArgs, &CallOrInvoke);
396 else if (llvm::CallInst*
Call = dyn_cast<llvm::CallInst>(CallOrInvoke))
397 Call->setTailCallKind(llvm::CallInst::TCK_Tail);
410 llvm::Value *AdjustedThisPtr,
411 llvm::FunctionCallee Callee) {
423 llvm::Type *ThisType = Args[ThisArgNo]->getType();
424 if (ThisType != AdjustedThisPtr->getType())
425 AdjustedThisPtr =
Builder.CreateBitCast(AdjustedThisPtr, ThisType);
426 Args[ThisArgNo] = AdjustedThisPtr;
428 assert(ThisAI.
isInAlloca() &&
"this is passed directly or inalloca");
431 if (ThisType != AdjustedThisPtr->getType())
432 AdjustedThisPtr =
Builder.CreateBitCast(AdjustedThisPtr, ThisType);
438 llvm::CallInst *
Call =
Builder.CreateCall(Callee, Args);
439 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
443 llvm::AttributeList Attrs;
447 Call->setAttributes(Attrs);
450 if (
Call->getType()->isVoidTy())
465 bool IsUnprototyped) {
482 &Thunk, IsUnprototyped);
486 bool IsUnprototyped,
bool ForVTable) {
503llvm::Constant *CodeGenVTables::maybeEmitThunk(
GlobalDecl GD,
513 llvm::raw_svector_ostream Out(Name);
531 llvm::Constant *Thunk = CGM.
GetAddrOfThunk(Name, ThunkVTableTy, GD);
548 llvm::Function *ThunkFn = cast<llvm::Function>(Thunk->stripPointerCasts());
549 if (ThunkFn->getFunctionType() != ThunkFnTy) {
550 llvm::GlobalValue *OldThunkFn = ThunkFn;
552 assert(OldThunkFn->isDeclaration() &&
"Shouldn't replace non-declaration");
555 OldThunkFn->setName(StringRef());
556 ThunkFn = llvm::Function::Create(ThunkFnTy, llvm::Function::ExternalLinkage,
560 if (!OldThunkFn->use_empty()) {
561 OldThunkFn->replaceAllUsesWith(ThunkFn);
565 OldThunkFn->eraseFromParent();
569 bool UseAvailableExternallyLinkage = ForVTable && ABIHasKeyFunctions;
571 if (!ThunkFn->isDeclaration()) {
572 if (!ABIHasKeyFunctions || UseAvailableExternallyLinkage) {
586 ThunkFn->addFnAttr(
"thunk");
595 bool ShouldCloneVarArgs =
false;
596 if (!IsUnprototyped && ThunkFn->isVarArg()) {
597 ShouldCloneVarArgs =
true;
600 case llvm::Triple::x86_64:
601 case llvm::Triple::x86:
602 case llvm::Triple::aarch64:
603 ShouldCloneVarArgs =
false;
611 if (ShouldCloneVarArgs) {
612 if (UseAvailableExternallyLinkage)
636 if (!ThunkInfoVector)
639 for (
const ThunkInfo& Thunk : *ThunkInfoVector)
640 maybeEmitThunk(GD, Thunk,
false);
644 llvm::Constant *component,
645 unsigned vtableAddressPoint,
646 bool vtableHasLocalLinkage,
647 bool isCompleteDtor)
const {
649 if (component->isNullValue())
650 return builder.add(llvm::ConstantInt::get(CGM.
Int32Ty, 0));
653 cast<llvm::GlobalValue>(component->stripPointerCastsAndAliases());
667 auto stubLinkage = vtableHasLocalLinkage
668 ? llvm::GlobalValue::InternalLinkage
669 : llvm::GlobalValue::LinkOnceODRLinkage;
671 llvm::Constant *target;
672 if (
auto *func = dyn_cast<llvm::Function>(globalVal)) {
673 target = llvm::DSOLocalEquivalent::get(func);
676 rttiProxyName.append(
".rtti_proxy");
682 llvm::GlobalVariable *proxy = module.getNamedGlobal(rttiProxyName);
684 proxy =
new llvm::GlobalVariable(module, globalVal->getType(),
686 globalVal, rttiProxyName);
687 proxy->setDSOLocal(
true);
688 proxy->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
689 if (!proxy->hasLocalLinkage()) {
690 proxy->setVisibility(llvm::GlobalValue::HiddenVisibility);
691 proxy->setComdat(module.getOrInsertComdat(rttiProxyName));
703 builder.addRelativeOffsetToPosition(CGM.
Int32Ty, target,
729 builder.add(llvm::ConstantExpr::getIntToPtr(
742 unsigned componentIndex,
743 llvm::Constant *rtti,
744 unsigned &nextVTableThunkIndex,
745 unsigned vtableAddressPoint,
746 bool vtableHasLocalLinkage) {
749 auto addOffsetConstant =
752 switch (component.getKind()) {
754 return addOffsetConstant(CGM, builder, component.getVCallOffset());
757 return addOffsetConstant(CGM, builder, component.getVBaseOffset());
760 return addOffsetConstant(CGM, builder, component.getOffsetToTop());
764 return addRelativeComponent(builder, rtti, vtableAddressPoint,
765 vtableHasLocalLinkage,
768 return builder.add(rtti);
777 layout.
vtable_thunks()[nextVTableThunkIndex].first == componentIndex;
788 ? MD->
hasAttr<CUDADeviceAttr>()
789 : (MD->
hasAttr<CUDAHostAttr>() || !MD->
hasAttr<CUDADeviceAttr>());
790 if (!CanEmitMethod) {
792 nextVTableThunkIndex++;
799 auto getSpecialVirtualFn = [&](StringRef
name) -> llvm::Constant * {
815 llvm::FunctionType *fnTy =
816 llvm::FunctionType::get(CGM.
VoidTy,
false);
817 llvm::Constant *fn = cast<llvm::Constant>(
819 if (
auto f = dyn_cast<llvm::Function>(fn))
820 f->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
824 llvm::Constant *fnPtr;
827 if (cast<CXXMethodDecl>(GD.
getDecl())->isPureVirtual()) {
831 fnPtr = PureVirtualFn;
834 }
else if (cast<CXXMethodDecl>(GD.
getDecl())->isDeleted()) {
835 if (!DeletedVirtualFn)
838 fnPtr = DeletedVirtualFn;
841 }
else if (IsThunk) {
842 auto &thunkInfo = layout.
vtable_thunks()[nextVTableThunkIndex].second;
844 nextVTableThunkIndex++;
845 fnPtr = maybeEmitThunk(GD, thunkInfo,
true);
847 assert(thunkInfo.Method &&
"Method not set");
860 return addRelativeComponent(
861 builder, fnPtr, vtableAddressPoint, vtableHasLocalLinkage,
868 unsigned FnAS = fnPtr->getType()->getPointerAddressSpace();
874 if (
const auto &Schema =
876 return builder.addSignedPointer(fnPtr, Schema, GD,
QualType());
877 return builder.add(fnPtr);
883 return builder.add(llvm::ConstantExpr::getNullValue(CGM.
Int32Ty));
888 llvm_unreachable(
"Unexpected vtable component kind");
894 for (
unsigned i = 0, e = layout.
getNumVTables(); i != e; ++i)
895 tys.push_back(llvm::ArrayType::get(componentType, layout.
getVTableSize(i)));
902 llvm::Constant *rtti,
903 bool vtableHasLocalLinkage) {
907 unsigned nextVTableThunkIndex = 0;
908 for (
unsigned vtableIndex = 0, endIndex = layout.
getNumVTables();
909 vtableIndex != endIndex; ++vtableIndex) {
910 auto vtableElem = builder.
beginArray(componentType);
913 size_t vtableEnd = vtableStart + layout.
getVTableSize(vtableIndex);
914 for (
size_t componentIndex = vtableStart; componentIndex < vtableEnd;
916 addVTableComponent(vtableElem, layout, componentIndex, rtti,
917 nextVTableThunkIndex, addressPoints[vtableIndex],
918 vtableHasLocalLinkage);
920 vtableElem.finishAndAddTo(builder);
926 llvm::GlobalVariable::LinkageTypes
Linkage,
927 VTableAddressPointsMapTy &AddressPoints) {
929 DI->completeClassData(
Base.getBase());
931 std::unique_ptr<VTableLayout> VTLayout(
933 Base.getBase(),
Base.getBaseOffset(), BaseIsVirtual, RD));
936 AddressPoints = VTLayout->getAddressPoints();
940 llvm::raw_svector_ostream Out(OutName);
942 .mangleCXXCtorVTable(RD,
Base.getBaseOffset().getQuantity(),
943 Base.getBase(), Out);
947 bool VTableAliasExists =
948 UsingRelativeLayout && CGM.
getModule().getNamedAlias(Name);
949 if (VTableAliasExists) {
951 Name.append(
".local");
961 if (
Linkage == llvm::GlobalVariable::AvailableExternallyLinkage)
962 Linkage = llvm::GlobalVariable::InternalLinkage;
964 llvm::Align Align = CGM.
getDataLayout().getABITypeAlign(VTType);
967 llvm::GlobalVariable *VTable =
971 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
980 VTable->hasLocalLinkage());
981 components.finishAndSetAsInitializer(VTable);
985 assert(!VTable->isDeclaration() &&
"Shouldn't set properties on declaration");
990 if (UsingRelativeLayout) {
992 if (!VTable->isDSOLocal())
1009 llvm::GlobalValue::SanitizerMetadata Meta;
1010 if (GV->hasSanitizerMetadata())
1011 Meta = GV->getSanitizerMetadata();
1012 Meta.NoHWAddress =
true;
1013 GV->setSanitizerMetadata(Meta);
1024 llvm::StringRef AliasNameRef) {
1026 "Can only use this if the relative vtable ABI is used");
1027 assert(!VTable->isDSOLocal() &&
"This should be called only if the vtable is "
1028 "not guaranteed to be dso_local");
1033 if (VTable->hasAvailableExternallyLinkage())
1040 VTable->setName(AliasName +
".local");
1042 auto Linkage = VTable->getLinkage();
1043 assert(llvm::GlobalAlias::isValidLinkage(
Linkage) &&
1044 "Invalid vtable alias linkage");
1046 llvm::GlobalAlias *VTableAlias = CGM.
getModule().getNamedAlias(AliasName);
1048 VTableAlias = llvm::GlobalAlias::create(VTable->getValueType(),
1049 VTable->getAddressSpace(),
Linkage,
1052 assert(VTableAlias->getValueType() == VTable->getValueType());
1053 assert(VTableAlias->getLinkage() ==
Linkage);
1055 VTableAlias->setVisibility(VTable->getVisibility());
1056 VTableAlias->setUnnamedAddr(VTable->getUnnamedAddr());
1059 if (!VTable->hasComdat()) {
1060 VTable->setLinkage(llvm::GlobalValue::InternalLinkage);
1070 VTable->setVisibility(llvm::GlobalValue::HiddenVisibility);
1073 VTableAlias->setAliasee(VTable);
1085llvm::GlobalVariable::LinkageTypes
1088 return llvm::GlobalVariable::InternalLinkage;
1098 if (IsInNamedModule || (keyFunction && !RD->
hasAttr<DLLImportAttr>())) {
1102 if (keyFunction && keyFunction->
hasBody(def))
1103 keyFunction = cast<CXXMethodDecl>(def);
1105 bool IsExternalDefinition =
1116 (IsInNamedModule || def || CodeGenOpts.OptimizationLevel > 0 ||
1117 CodeGenOpts.getDebugInfo() != llvm::codegenoptions::NoDebugInfo) &&
1118 "Shouldn't query vtable linkage without the class in module units, "
1119 "key function, optimizations, or debug info");
1120 if (IsExternalDefinition && CodeGenOpts.OptimizationLevel > 0)
1121 return llvm::GlobalVariable::AvailableExternallyLinkage;
1123 if (keyFunction && keyFunction->
isInlined())
1125 ? llvm::GlobalVariable::LinkOnceODRLinkage
1126 : llvm::Function::InternalLinkage;
1128 return llvm::GlobalVariable::ExternalLinkage;
1132 llvm::GlobalVariable::LinkOnceODRLinkage :
1133 llvm::Function::InternalLinkage;
1137 llvm::GlobalVariable::WeakODRLinkage :
1138 llvm::Function::InternalLinkage;
1141 return IsExternalDefinition
1142 ? llvm::GlobalVariable::AvailableExternallyLinkage
1143 : llvm::GlobalVariable::ExternalLinkage;
1150 return llvm::Function::InternalLinkage;
1152 llvm::GlobalVariable::LinkageTypes DiscardableODRLinkage =
1153 llvm::GlobalValue::LinkOnceODRLinkage;
1154 llvm::GlobalVariable::LinkageTypes NonDiscardableODRLinkage =
1155 llvm::GlobalValue::WeakODRLinkage;
1156 if (RD->
hasAttr<DLLExportAttr>()) {
1158 DiscardableODRLinkage = NonDiscardableODRLinkage;
1159 }
else if (RD->
hasAttr<DLLImportAttr>()) {
1161 DiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;
1162 NonDiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;
1169 return DiscardableODRLinkage;
1175 return DiscardableODRLinkage;
1177 ? llvm::GlobalVariable::AvailableExternallyLinkage
1178 : llvm::GlobalVariable::ExternalLinkage;
1181 return NonDiscardableODRLinkage;
1184 llvm_unreachable(
"Invalid TemplateSpecializationKind!");
1200 DI->completeClassData(RD);
1219 assert(RD->
isDynamicClass() &&
"Non-dynamic classes have no VTable.");
1251 return !keyFunction->
hasBody();
1270void CodeGenModule::EmitDeferredVTables() {
1274 size_t savedSize = DeferredVTables.size();
1280 else if (shouldOpportunisticallyEmitVTables())
1281 OpportunisticVTables.push_back(RD);
1283 assert(savedSize == DeferredVTables.size() &&
1284 "deferred extra vtables during vtable emission?");
1285 DeferredVTables.clear();
1289 if (RD->
hasAttr<LTOVisibilityPublicAttr>() || RD->
hasAttr<UuidAttr>() ||
1298 auto *
D = cast<Decl>(DC);
1301 if (
auto *ND = dyn_cast<NamespaceDecl>(
D))
1303 if (II->isStr(
"std") || II->isStr(
"stdext"))
1331 if (!
Visited.insert(RD).second)
1332 return llvm::GlobalObject::VCallVisibilityTranslationUnit;
1335 llvm::GlobalObject::VCallVisibility TypeVis;
1337 TypeVis = llvm::GlobalObject::VCallVisibilityTranslationUnit;
1339 TypeVis = llvm::GlobalObject::VCallVisibilityLinkageUnit;
1341 TypeVis = llvm::GlobalObject::VCallVisibilityPublic;
1343 for (
const auto &B : RD->
bases())
1344 if (B.getType()->getAsCXXRecordDecl()->isDynamicClass())
1349 for (
const auto &B : RD->
vbases())
1350 if (B.getType()->getAsCXXRecordDecl()->isDynamicClass())
1359 llvm::GlobalVariable *VTable,
1369 struct AddressPoint {
1373 bool operator<(
const AddressPoint &RHS)
const {
1375 return D < 0 || (
D == 0 && Offset < RHS.Offset);
1378 std::vector<AddressPoint> AddressPoints;
1380 AddressPoint N{AP.first.getBase(),
1382 AP.second.AddressPointIndex,
1384 llvm::raw_string_ostream Stream(N.TypeName);
1387 AddressPoints.push_back(std::move(N));
1391 llvm::sort(AddressPoints);
1394 for (
auto AP : AddressPoints) {
1402 for (
unsigned I = 0; I != Comps.size(); ++I) {
1407 std::nullopt, AP.Base));
1408 VTable->addTypeMetadata((ComponentWidth * I).getQuantity(), MD);
1414 llvm::DenseSet<const CXXRecordDecl *>
Visited;
1415 llvm::GlobalObject::VCallVisibility TypeVis =
1417 if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic)
1418 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)
llvm::DenseSet< const void * > Visited
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
bool useAbbreviatedThunkName(GlobalDecl VirtualMethodDecl, StringRef MangledName)
QualType getMemberPointerType(QualType T, NestedNameSpecifier Qualifier, const CXXRecordDecl *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
CanQualType getCanonicalTagType(const TagDecl *TD) 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.
QualType getFunctionObjectParameterType() const
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.
PointerAuthOptions PointerAuth
Configuration for pointer-signing.
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
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Type * getElementType() const
Return the type of the values stored in this address.
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)
llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")
virtual bool hasMostDerivedReturn(GlobalDecl GD) const
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 llvm::Value * performThisAdjustment(CodeGenFunction &CGF, Address This, const CXXRecordDecl *UnadjustedClass, const ThunkInfo &TI)=0
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 llvm::Value * performReturnAdjustment(CodeGenFunction &CGF, Address Ret, const CXXRecordDecl *UnadjustedClass, const ReturnAdjustment &RA)=0
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
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...
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
void EmitMustTailThunk(GlobalDecl GD, llvm::Value *AdjustedThisPtr, llvm::FunctionCallee Callee)
Emit a musttail call for a thunk with a potentially adjusted this pointer.
Address LoadCXXThisAddress()
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
void EmitDelegateCallArg(CallArgList &args, const VarDecl *param, SourceLocation loc)
EmitDelegateCallArg - We are performing a delegate call; that is, the current function is delegating ...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
Address makeNaturalAddressForPointer(llvm::Value *Ptr, QualType T, CharUnits Alignment=CharUnits::Zero(), bool ForPointeeType=false, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
Construct an address with the natural alignment of T.
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
void EmitCallAndReturnForThunk(llvm::FunctionCallee Callee, const ThunkInfo *Thunk, bool IsUnprototyped)
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.
llvm::Function * GenerateVarArgsThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo, GlobalDecl GD, const ThunkInfo &Thunk)
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
bool AutoreleaseResult
In ARC, whether we should autorelease the return value.
llvm::Type * ConvertTypeForMem(QualType T)
void generateThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo, GlobalDecl GD, const ThunkInfo &Thunk, bool IsUnprototyped)
Generate a thunk for the given method.
void StartThunk(llvm::Function *Fn, GlobalDecl GD, const CGFunctionInfo &FnInfo, bool IsUnprototyped)
static bool hasAggregateEvaluationKind(QualType T)
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
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 EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
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 useRelativeLayout() const
Return true if the relative vtable layout is used.
llvm::Type * getVTableComponentType() const
Return the type used as components for a vtable.
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 ...
bool isInNamedModule() const
Whether this declaration comes from a named module.
SourceLocation getLocation() const
bool shouldEmitInExternalSource() const
Whether the definition of the declaration should be emitted in external sources.
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.
GlobalDecl getWithDecl(const Decl *D)
CXXDtorType getDtorType() const
const Decl * getDecl() const
One of these records is kept for each identifier that is lexed.
bool isRelativeLayout() const
GlobalDecl findOriginalMethod(GlobalDecl GD)
Return the method that added the v-table slot that will be used to call the given method.
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 mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, const ThunkInfo &Thunk, bool ElideOverrideInfo, raw_ostream &)=0
virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, bool ElideOverrideInfo, raw_ostream &)=0
virtual void mangleCanonicalTypeName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
Generates a unique string for an externally visible type for use with TBAA or type uniquing.
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.
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
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
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
The JSON file list parser is used to communicate input to InstallAPI.
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
@ Dtor_Base
Base object dtor.
const FunctionProtoType * T
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::PointerType * GlobalsInt8PtrTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * PtrDiffTy
PointerAuthSchema CXXVirtualFunctionPointers
The ABI for most C++ virtual function pointers, i.e. v-table entries.
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.
ReturnAdjustment Return
The return adjustment.