Go to the documentation of this file.
22 #include "llvm/IR/IntrinsicInst.h"
23 #include "llvm/Support/Format.h"
24 #include "llvm/Transforms/Utils/Cloning.h"
28 using namespace clang;
29 using 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;
86 llvm::Value *IsNull = CGF.
Builder.CreateIsNull(ReturnValue);
87 CGF.
Builder.CreateCondBr(IsNull, AdjustNull, AdjustNotNull);
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->getBasicBlockList()) {
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) {
494 llvm::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());
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());
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()) {
665 proxy->setComdat(module.getOrInsertComdat(rttiProxyName));
671 builder.addRelativeOffsetToPosition(CGM.
Int32Ty, target,
675 bool CodeGenVTables::useRelativeLayout()
const {
680 llvm::Type *CodeGenVTables::getVTableComponentType()
const {
681 if (useRelativeLayout())
689 builder.add(llvm::ConstantExpr::getIntToPtr(
702 unsigned componentIndex,
703 llvm::Constant *rtti,
704 unsigned &nextVTableThunkIndex,
705 unsigned vtableAddressPoint,
706 bool vtableHasLocalLinkage) {
709 auto addOffsetConstant =
712 switch (component.getKind()) {
714 return addOffsetConstant(CGM, builder, component.getVCallOffset());
717 return addOffsetConstant(CGM, builder, component.getVBaseOffset());
720 return addOffsetConstant(CGM, builder, component.getOffsetToTop());
723 if (useRelativeLayout())
724 return addRelativeComponent(builder, rtti, vtableAddressPoint,
725 vtableHasLocalLinkage,
728 return builder.add(llvm::ConstantExpr::getBitCast(rtti, CGM.
Int8PtrTy));
744 ? MD->
hasAttr<CUDADeviceAttr>()
745 : (MD->
hasAttr<CUDAHostAttr>() || !MD->
hasAttr<CUDADeviceAttr>());
747 return builder.add(llvm::ConstantExpr::getNullValue(CGM.
Int8PtrTy));
751 auto getSpecialVirtualFn = [&](StringRef
name) -> llvm::Constant * {
759 if (useRelativeLayout())
760 return llvm::ConstantPointerNull::get(CGM.
Int8PtrTy);
766 return llvm::ConstantPointerNull::get(CGM.
Int8PtrTy);
767 llvm::FunctionType *fnTy =
768 llvm::FunctionType::get(CGM.
VoidTy,
false);
769 llvm::Constant *fn = cast<llvm::Constant>(
771 if (
auto f = dyn_cast<llvm::Function>(fn))
772 f->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
773 return llvm::ConstantExpr::getBitCast(fn, CGM.
Int8PtrTy);
776 llvm::Constant *fnPtr;
779 if (cast<CXXMethodDecl>(GD.
getDecl())->isPure()) {
783 fnPtr = PureVirtualFn;
786 }
else if (cast<CXXMethodDecl>(GD.
getDecl())->isDeleted()) {
787 if (!DeletedVirtualFn)
790 fnPtr = DeletedVirtualFn;
793 }
else if (nextVTableThunkIndex < layout.
vtable_thunks().size() &&
796 auto &thunkInfo = layout.
vtable_thunks()[nextVTableThunkIndex].second;
798 nextVTableThunkIndex++;
799 fnPtr = maybeEmitThunk(GD, thunkInfo,
true);
807 if (useRelativeLayout()) {
808 return addRelativeComponent(
809 builder, fnPtr, vtableAddressPoint, vtableHasLocalLinkage,
812 return builder.add(llvm::ConstantExpr::getBitCast(fnPtr, CGM.
Int8PtrTy));
816 if (useRelativeLayout())
817 return builder.add(llvm::ConstantExpr::getNullValue(CGM.
Int32Ty));
819 return builder.addNullPointer(CGM.
Int8PtrTy);
822 llvm_unreachable(
"Unexpected vtable component kind");
827 llvm::Type *componentType = getVTableComponentType();
828 for (
unsigned i = 0, e = layout.
getNumVTables(); i != e; ++i)
829 tys.push_back(llvm::ArrayType::get(componentType, layout.
getVTableSize(i)));
836 llvm::Constant *rtti,
837 bool vtableHasLocalLinkage) {
838 llvm::Type *componentType = getVTableComponentType();
841 unsigned nextVTableThunkIndex = 0;
842 for (
unsigned vtableIndex = 0, endIndex = layout.
getNumVTables();
843 vtableIndex != endIndex; ++vtableIndex) {
844 auto vtableElem = builder.
beginArray(componentType);
847 size_t vtableEnd = vtableStart + layout.
getVTableSize(vtableIndex);
848 for (
size_t componentIndex = vtableStart; componentIndex < vtableEnd;
850 addVTableComponent(vtableElem, layout, componentIndex, rtti,
851 nextVTableThunkIndex, addressPoints[vtableIndex],
852 vtableHasLocalLinkage);
854 vtableElem.finishAndAddTo(builder);
860 llvm::GlobalVariable::LinkageTypes
Linkage,
861 VTableAddressPointsMapTy &AddressPoints) {
863 DI->completeClassData(
Base.getBase());
865 std::unique_ptr<VTableLayout> VTLayout(
867 Base.getBase(),
Base.getBaseOffset(), BaseIsVirtual, RD));
870 AddressPoints = VTLayout->getAddressPoints();
874 llvm::raw_svector_ostream Out(OutName);
876 .mangleCXXCtorVTable(RD,
Base.getBaseOffset().getQuantity(),
877 Base.getBase(), Out);
881 bool VTableAliasExists =
882 UsingRelativeLayout && CGM.
getModule().getNamedAlias(Name);
883 if (VTableAliasExists) {
885 Name.append(
".local");
895 if (
Linkage == llvm::GlobalVariable::AvailableExternallyLinkage)
898 unsigned Align = CGM.
getDataLayout().getABITypeAlignment(VTType);
901 llvm::GlobalVariable *VTable =
905 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
914 VTable->hasLocalLinkage());
915 components.finishAndSetAsInitializer(VTable);
919 assert(!VTable->isDeclaration() &&
"Shouldn't set properties on declaration");
924 if (UsingRelativeLayout && !VTable->isDSOLocal())
937 llvm::StringRef AliasNameRef) {
939 "Can only use this if the relative vtable ABI is used");
940 assert(!VTable->isDSOLocal() &&
"This should be called only if the vtable is "
941 "not guaranteed to be dso_local");
946 if (VTable->hasAvailableExternallyLinkage())
953 VTable->setName(AliasName +
".local");
955 auto Linkage = VTable->getLinkage();
956 assert(llvm::GlobalAlias::isValidLinkage(
Linkage) &&
957 "Invalid vtable alias linkage");
959 llvm::GlobalAlias *VTableAlias = CGM.
getModule().getNamedAlias(AliasName);
962 VTable->getAddressSpace(),
Linkage,
965 assert(VTableAlias->getValueType() == VTable->getValueType());
966 assert(VTableAlias->getLinkage() ==
Linkage);
968 VTableAlias->setVisibility(VTable->getVisibility());
969 VTableAlias->setUnnamedAddr(VTable->getUnnamedAddr());
972 if (!VTable->hasComdat()) {
977 VTable->setLinkage(llvm::GlobalValue::PrivateLinkage);
983 VTableAlias->setAliasee(VTable);
995 llvm::GlobalVariable::LinkageTypes
1003 if (keyFunction && !RD->
hasAttr<DLLImportAttr>()) {
1007 if (keyFunction->
hasBody(def))
1008 keyFunction = cast<CXXMethodDecl>(def);
1013 assert((def || CodeGenOpts.OptimizationLevel > 0 ||
1015 "Shouldn't query vtable linkage without key function, "
1016 "optimizations, or debug info");
1017 if (!def && CodeGenOpts.OptimizationLevel > 0)
1018 return llvm::GlobalVariable::AvailableExternallyLinkage;
1022 llvm::GlobalVariable::LinkOnceODRLinkage :
1029 llvm::GlobalVariable::LinkOnceODRLinkage :
1034 llvm::GlobalVariable::WeakODRLinkage :
1038 llvm_unreachable(
"Should not have been asked to emit this");
1047 llvm::GlobalVariable::LinkageTypes DiscardableODRLinkage =
1048 llvm::GlobalValue::LinkOnceODRLinkage;
1049 llvm::GlobalVariable::LinkageTypes NonDiscardableODRLinkage =
1050 llvm::GlobalValue::WeakODRLinkage;
1051 if (RD->
hasAttr<DLLExportAttr>()) {
1053 DiscardableODRLinkage = NonDiscardableODRLinkage;
1054 }
else if (RD->
hasAttr<DLLImportAttr>()) {
1056 DiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;
1057 NonDiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;
1064 return DiscardableODRLinkage;
1070 return DiscardableODRLinkage;
1072 ? llvm::GlobalVariable::AvailableExternallyLinkage
1076 return NonDiscardableODRLinkage;
1079 llvm_unreachable(
"Invalid TemplateSpecializationKind!");
1095 DI->completeClassData(RD);
1114 assert(RD->
isDynamicClass() &&
"Non-dynamic classes have no VTable.");
1141 return !keyFunction->
hasBody();
1160 void CodeGenModule::EmitDeferredVTables() {
1164 size_t savedSize = DeferredVTables.size();
1170 else if (shouldOpportunisticallyEmitVTables())
1171 OpportunisticVTables.push_back(RD);
1173 assert(savedSize == DeferredVTables.size() &&
1174 "deferred extra vtables during vtable emission?");
1175 DeferredVTables.clear();
1184 auto *D = cast<Decl>(DC);
1187 if (
auto *ND = dyn_cast<NamespaceDecl>(D))
1189 if (II->isStr(
"std") || II->isStr(
"stdext"))
1203 if (RD->
hasAttr<LTOVisibilityPublicAttr>() || RD->
hasAttr<UuidAttr>())
1207 if (RD->
hasAttr<DLLExportAttr>() || RD->
hasAttr<DLLImportAttr>())
1224 if (!Visited.insert(RD).second)
1225 return llvm::GlobalObject::VCallVisibilityTranslationUnit;
1228 llvm::GlobalObject::VCallVisibility TypeVis;
1230 TypeVis = llvm::GlobalObject::VCallVisibilityTranslationUnit;
1232 TypeVis = llvm::GlobalObject::VCallVisibilityLinkageUnit;
1234 TypeVis = llvm::GlobalObject::VCallVisibilityPublic;
1236 for (
auto B : RD->
bases())
1237 if (B.getType()->getAsCXXRecordDecl()->isDynamicClass())
1242 for (
auto B : RD->
vbases())
1243 if (B.getType()->getAsCXXRecordDecl()->isDynamicClass())
1252 llvm::GlobalVariable *VTable,
1260 typedef std::pair<const CXXRecordDecl *, unsigned> AddressPoint;
1261 std::vector<AddressPoint> AddressPoints;
1263 AddressPoints.push_back(std::make_pair(
1265 AP.second.AddressPointIndex));
1268 llvm::sort(AddressPoints, [
this](
const AddressPoint &AP1,
1269 const AddressPoint &AP2) {
1274 llvm::raw_string_ostream O1(S1);
1276 QualType(AP1.first->getTypeForDecl(), 0), O1);
1280 llvm::raw_string_ostream O2(S2);
1282 QualType(AP2.first->getTypeForDecl(), 0), O2);
1290 return AP1.second < AP2.second;
1294 for (
auto AP : AddressPoints) {
1302 for (
unsigned I = 0; I != Comps.size(); ++I) {
1307 Comps[I].getFunctionDecl()->getType(),
1309 VTable->addTypeMetadata((PointerWidth * I).getQuantity(), MD);
1316 llvm::GlobalObject::VCallVisibility TypeVis =
1318 if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic)
1319 VTable->setVCallVisibilityMetadata(TypeVis);
QualType getThisType() const
Return the type of the this pointer.
@ InternalLinkage
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
llvm::Type * ConvertTypeForMem(QualType T)
CXXDtorType getDtorType() const
@ Dtor_Base
Base object dtor.
unsigned arg_size() const
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
llvm::PointerType * Int8PtrTy
void GenerateRelativeVTableAlias(llvm::GlobalVariable *VTable, llvm::StringRef AliasNameRef)
Generate a public facing alias for the vtable and make the vtable either hidden or private.
void EmitMustTailThunk(GlobalDecl GD, llvm::Value *AdjustedThisPtr, llvm::FunctionCallee Callee)
Emit a musttail call for a thunk with a potentially adjusted this pointer.
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
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.
A helper class of ConstantInitBuilder, used for building constant array initializers.
ItaniumVTableContext & getItaniumVTableContext()
bool AutoreleaseResult
In ARC, whether we should autorelease the return value.
The standard implementation of ConstantInitBuilder used in Clang.
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...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
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,...
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
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...
bool isRelativeLayout() const
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.
bool isExternallyVisible() const
llvm::Function * GenerateVarArgsThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo, GlobalDecl GD, const ThunkInfo &Thunk)
Encodes a location in the source.
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
MangleContext & getMangleContext()
Gets the mangle context.
bool HasHiddenLTOVisibility(const CXXRecordDecl *RD)
Returns whether the given record has hidden LTO visibility and therefore may participate in (single-m...
bool hasKeyFunctions() const
Does this ABI use key functions? If so, class data such as the vtable is emitted with strong linkage ...
size_t getNumVTables() const
virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, raw_ostream &)=0
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
A (possibly-)qualified type.
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.
ASTContext & getContext() const
const_arg_iterator arg_begin() const
bool isSRetAfterThis() const
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
bool isItaniumFamily() const
Does this ABI generally fall into the Itanium family of ABIs?
Represents a parameter to a function.
void generateThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo, GlobalDecl GD, const ThunkInfo &Thunk, bool IsUnprototyped)
Generate a thunk for the given method.
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
ArrayBuilder beginArray(llvm::Type *eltTy=nullptr)
@ NoDebugInfo
Don't generate debug info.
LinkageInfo getLinkageAndVisibility() const
Determines the linkage and visibility of this entity.
CodeGenVTables(CodeGenModule &CGM)
void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F, bool IsThunk)
Set the LLVM function attributes (sext, zext, etc).
const LangOptions & getLangOpts() const
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
A helper class of ConstantInitBuilder, used for building constant struct initializers.
ArrayRef< VTableComponent > vtable_components() 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...
FunctionType - C99 6.7.5.3 - Function Declarators.
static bool shouldEmitAvailableExternallyVTable(const CodeGenModule &CGM, const CXXRecordDecl *RD)
CanQualType getReturnType() const
void add(RValue rvalue, QualType type)
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.
ArrayRef< VTableThunkTy > vtable_thunks() const
void StartThunk(llvm::Function *Fn, GlobalDecl GD, const CGFunctionInfo &FnInfo, bool IsUnprototyped)
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
@ CK_UnusedFunctionPointer
An entry that is never used.
GlobalDecl - represents a global declaration.
size_t getVTableOffset(size_t i) const
virtual const ThunkInfoVectorTy * getThunkInfo(GlobalDecl GD)
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
virtual void emitVirtualInheritanceTables(const CXXRecordDecl *RD)=0
Emit any tables needed to implement virtual inheritance.
unsigned getCallingConvention() const
getCallingConvention - Return the user specified calling convention, which has been translated into a...
void buildThisParam(CodeGenFunction &CGF, FunctionArgList &Params)
Build a parameter variable suitable for 'this'.
bool isReferenceType() const
virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, const ThisAdjustment &ThisAdjustment, raw_ostream &)=0
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)
Set the LLVM function attributes which only apply to a function definition.
__DEVICE__ int min(int __a, int __b)
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
void EmitThunks(GlobalDecl GD)
EmitThunks - Emit the associated thunks for the given global decl.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
param_iterator param_end()
CharUnits getClassPointerAlignment(const CXXRecordDecl *CD)
Returns the assumed alignment of an opaque pointer to the given class.
void GenerateClassData(const CXXRecordDecl *RD)
GenerateClassData - Generate all the class data required to be generated upon definition of a KeyFunc...
bool ReturnTypeUsesSRet(const CGFunctionInfo &FI)
Return true iff the given type uses 'sret' when used as a return type.
const CodeGenOptions & getCodeGenOpts() const
virtual llvm::Value * performReturnAdjustment(CodeGenFunction &CGF, Address Ret, const ReturnAdjustment &RA)=0
@ CK_DeletingDtorPointer
A pointer to the deleting destructor.
void EmitCallAndReturnForThunk(llvm::FunctionCallee Callee, const ThunkInfo *Thunk, bool IsUnprototyped)
const AddressPointsIndexMapTy & getAddressPointIndices() const
bool isExternallyVisible(Linkage L)
llvm::Module & getModule() const
llvm::Type * GetFunctionTypeForVTable(GlobalDecl GD)
GetFunctionTypeForVTable - Get the LLVM function type for use in a vtable, given a CXXMethodDecl.
Represents a C++ destructor within a class.
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
virtual void mangleTypeName(QualType T, raw_ostream &)=0
Generates a unique string for an externally visible type for use with TBAA or type uniquing.
virtual llvm::Value * performThisAdjustment(CodeGenFunction &CGF, Address This, const ThisAdjustment &TA)=0
void setFunctionLinkage(GlobalDecl GD, llvm::Function *F)
QualType getRecordType(const RecordDecl *Decl) const
CallingConv
CallingConv - Specifies the calling convention that a function uses.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
@ CK_CompleteDtorPointer
A pointer to the complete destructor.
CodeGenTypes & getTypes()
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
llvm::LLVMContext & getLLVMContext()
@ Indirect
Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template instantiation this function represents.
ThisAdjustment This
The this pointer adjustment.
static Decl::Kind getKind(const Decl *D)
void EmitVTableTypeMetadata(const CXXRecordDecl *RD, llvm::GlobalVariable *VTable, const VTableLayout &VTLayout)
Emit type metadata for the given vtable using the given layout.
base_class_range vbases()
StructBuilder beginStruct(llvm::StructType *structTy=nullptr)
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.
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
Visibility getVisibility() const
bool isFuncTypeConvertible(const FunctionType *FT)
isFuncTypeConvertible - Utility to check whether a function type can be converted to an LLVM type (i....
const TargetInfo & getTarget() const
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
const AddressPointsMapTy & getAddressPoints() const
llvm::IntegerType * Int32Ty
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...
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
CGDebugInfo * getModuleDebugInfo()
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const llvm::DataLayout & getDataLayout() const
const T * castAs() const
Member-template castAs<specific type>.
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.
ReturnAdjustment Return
The return adjustment.
const CGFunctionInfo & arrangeCXXMethodCall(const CallArgList &args, const FunctionProtoType *type, RequiredArgs required, unsigned numPrefixArgs)
Arrange a call to a C++ method, passing the given arguments.
Represents a C++ struct/union/class.
size_t getVTableSize(size_t i) const
static RValue PerformReturnAdjustment(CodeGenFunction &CGF, QualType ResultType, RValue RV, const ThunkInfo &Thunk)
static void AddRelativeLayoutOffset(const CodeGenModule &CGM, ConstantArrayBuilder &builder, CharUnits offset)
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
void EmitDelegateCallArg(CallArgList &args, const VarDecl *param, SourceLocation loc)
EmitDelegateCallArg - We are performing a delegate call; that is, the current function is delegating ...
virtual void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy, FunctionArgList &Params)=0
Insert any ABI-specific implicit parameters into the parameter list for a function.
const CGFunctionInfo & arrangeUnprototypedMustTailThunk(const CXXMethodDecl *MD)
Arrange a thunk that takes 'this' as the first parameter followed by varargs.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
llvm::Value * getPointer() const
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn't support the specified stmt yet.
llvm::Metadata * CreateMetadataIdentifierForVirtualMemPtrType(QualType T)
Create a metadata identifier that is intended to be used to check virtual calls via a member function...
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
static void AddPointerLayoutOffset(const CodeGenModule &CGM, ConstantArrayBuilder &builder, CharUnits offset)
virtual void setThunkLinkage(llvm::Function *Thunk, bool ForVTable, GlobalDecl GD, bool ReturnAdjustment)=0
llvm::IntegerType * PtrDiffTy
CGCXXABI & getCXXABI() const
QualType getTagDeclType(const TagDecl *Decl) const
Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl.
Represents a prototype with parameter type info, e.g.
bool HasLTOVisibilityPublicStd(const CXXRecordDecl *RD)
Returns whether the given record has public std LTO visibility and therefore may not participate in (...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
This class organizes the cross-function state that is used while generating LLVM code.
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
CodeGenVTables & getVTables()
const llvm::Triple & getTriple() const
The this pointer adjustment as well as an optional return adjustment for a thunk.
bool usesInAlloca() const
Return true if this function uses inalloca arguments.
virtual StringRef GetDeletedVirtualCallName()=0
Gets the deleted virtual member call name.
FunctionArgList - Type for representing both the decl and type of parameters to a function.
ABIArgInfo & getReturnInfo()
Linkage getLinkage() const
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
virtual bool hasMostDerivedReturn(GlobalDecl GD) const
virtual void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV, QualType ResultType)
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...
static bool hasAggregateEvaluationKind(QualType T)
llvm::Type * getElementType() const
Return the type of the values stored in this address.
One of these records is kept for each identifier that is lexed.
llvm::Type * getVTableType(const VTableLayout &layout)
Returns the type of a vtable with the given layout.
const TargetInfo & getTargetInfo() const
bool supportsCOMDAT() const
CGFunctionInfo - Class to encapsulate the information about a function definition.
llvm::GlobalObject::VCallVisibility GetVCallVisibilityLevel(const CXXRecordDecl *RD, llvm::DenseSet< const CXXRecordDecl * > &Visited)
Returns the vcall visibility of the given type.
static bool similar(const ABIArgInfo &infoL, CanQualType typeL, const ABIArgInfo &infoR, CanQualType typeR)
static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, unsigned additional)
Compute the arguments required by the given formal prototype, given that there may be some additional...
const CGFunctionInfo & arrangeGlobalDeclaration(GlobalDecl GD)
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
static RValue get(llvm::Value *V)
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
uint64_t getPointerWidth(unsigned AddrSpace) const
Return the width of pointers on this target, for the specified address space.
@ ExternalLinkage
External linkage, which indicates that the entity can be referred to from other translation units.
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...
QualType getReturnType() const
virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF)=0
Emit the ABI-specific prolog for the function.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
param_iterator param_begin()
virtual void emitVTableDefinitions(CodeGenVTables &CGVT, const CXXRecordDecl *RD)=0
Emits the VTable definitions required for the given record type.
unsigned getRegParm() const
const Decl * getDecl() const
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
bool isDynamicClass() const
CharUnits - This is an opaque type for sizes expressed in character units.
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...
llvm::Constant * GetAddrOfThunk(StringRef Name, llvm::Type *FnTy, GlobalDecl GD)
Get the address of the thunk for the given global decl.
const CGFunctionInfo * CurFnInfo
Address LoadCXXThisAddress()
ItaniumVTableContext & getItaniumVTableContext()
virtual void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, GlobalDecl GD, CallArgList &CallArgs)
llvm::GlobalVariable * CreateOrReplaceCXXRuntimeVariable(StringRef Name, llvm::Type *Ty, llvm::GlobalValue::LinkageTypes Linkage, unsigned Alignment)
Will return a global variable of the given type.
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
virtual bool exportThunk()=0
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
static bool shouldEmitVTableThunk(CodeGenModule &CGM, const CXXMethodDecl *MD, bool IsUnprototyped, bool ForVTable)
virtual StringRef GetPureVirtualCallName()=0
Gets the pure virtual member call function.
ArrayRef< ParmVarDecl * > parameters() const
void AddVTableTypeMetadata(llvm::GlobalVariable *VTable, CharUnits Offset, const CXXRecordDecl *RD)
Create and attach type metadata for the given vtable.
SourceLocation getLocation() const
CallArgList - Type for representing both the value and type of arguments in a call.
Represents a function declaration or definition.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
bool isDefined(const FunctionDecl *&Definition, bool CheckForPendingFriendDefinition=false) const
Returns true if the function has a definition that does not need to be instantiated.
const LangOptions & getLangOpts() const
llvm::LLVMContext & getLLVMContext()
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static void setThunkProperties(CodeGenModule &CGM, const ThunkInfo &Thunk, llvm::Function *ThunkFn, bool ForVTable, GlobalDecl GD)
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 ...
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Represents a static or instance method of a struct/union/class.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.