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;
87 CGF.
Builder.CreateCondBr(IsNull, AdjustNull, AdjustNotNull);
94 Address(ReturnValue, ClassAlign),
98 CGF.
Builder.CreateBr(AdjustEnd);
100 CGF.
Builder.CreateBr(AdjustEnd);
103 llvm::PHINode *PHI = CGF.
Builder.CreatePHI(ReturnValue->getType(), 2);
104 PHI->addIncoming(ReturnValue, AdjustNotNull);
105 PHI->addIncoming(llvm::Constant::getNullValue(ReturnValue->getType()),
119 llvm::ValueToValueMapTy &VMap) {
121 auto *DIS = Fn->getSubprogram();
124 auto *NewDIS = DIS->replaceWithDistinct(DIS->clone());
125 VMap.MD()[DIS].reset(NewDIS);
129 for (
auto &BB : Fn->getBasicBlockList()) {
131 if (
auto *DII = dyn_cast<llvm::DbgVariableIntrinsic>(&I)) {
132 auto *DILocal = DII->getVariable();
133 if (!DILocal->isResolved())
162 QualType ResultType = FPT->getReturnType();
168 llvm::Function *BaseFn = cast<llvm::Function>(Callee);
177 assert(!BaseFn->isDeclaration() &&
"cannot clone undefined variadic method");
180 llvm::ValueToValueMapTy VMap;
185 llvm::Function *NewFn = llvm::CloneFunction(BaseFn, VMap);
186 Fn->replaceAllUsesWith(NewFn);
188 Fn->eraseFromParent();
195 llvm::Function::arg_iterator AI = Fn->arg_begin();
202 llvm::BasicBlock *EntryBB = &Fn->front();
203 llvm::BasicBlock::iterator ThisStore =
204 std::find_if(EntryBB->begin(), EntryBB->end(), [&](llvm::Instruction &I) {
205 return isa<llvm::StoreInst>(I) &&
208 assert(ThisStore != EntryBB->end() &&
209 "Store of this should be in entry block?");
211 Builder.SetInsertPoint(&*ThisStore);
214 AdjustedThisPtr = Builder.CreateBitCast(AdjustedThisPtr,
215 ThisStore->getOperand(0)->getType());
216 ThisStore->setOperand(0, AdjustedThisPtr);
220 for (llvm::BasicBlock &BB : *Fn) {
221 llvm::Instruction *T = BB.getTerminator();
222 if (isa<llvm::ReturnInst>(T)) {
224 T->eraseFromParent();
225 Builder.SetInsertPoint(&BB);
238 bool IsUnprototyped) {
239 assert(!CurGD.getDecl() &&
"CurGD was already set!");
241 CurFuncIsThunk =
true;
250 ResultType = ThisType;
261 if (!IsUnprototyped) {
264 if (isa<CXXDestructorDecl>(MD))
271 StartFunction(
GlobalDecl(), ResultType, Fn, FnInfo, FunctionArgs,
278 CXXThisValue = CXXABIThisValue;
286 CurCodeDecl =
nullptr;
287 CurFuncDecl =
nullptr;
294 bool IsUnprototyped) {
295 assert(isa<CXXMethodDecl>(CurGD.getDecl()) &&
296 "Please use a new CGF for this thunk");
297 const CXXMethodDecl *MD = cast<CXXMethodDecl>(CurGD.getDecl());
302 *
this, LoadCXXThisAddress(), Thunk->
This)
308 if (CurFnInfo->usesInAlloca() || CurFnInfo->isVariadic() || IsUnprototyped) {
312 MD,
"return-adjusting thunk with incomplete parameter type");
313 else if (CurFnInfo->isVariadic())
314 llvm_unreachable(
"shouldn't try to emit musttail return-adjusting " 315 "thunks for variadic functions");
318 MD,
"non-trivial argument copy for return-adjusting thunk");
320 EmitMustTailThunk(CurGD, AdjustedThisPtr, Callee);
329 if (isa<CXXDestructorDecl>(MD))
333 unsigned PrefixArgs = CallArgs.size() - 1;
344 assert(CallFnInfo.getRegParm() == CurFnInfo->getRegParm() &&
345 CallFnInfo.isNoReturn() == CurFnInfo->isNoReturn() &&
346 CallFnInfo.getCallingConvention() == CurFnInfo->getCallingConvention());
347 assert(isa<CXXDestructorDecl>(MD) ||
348 similar(CallFnInfo.getReturnInfo(), CallFnInfo.getReturnType(),
349 CurFnInfo->getReturnInfo(), CurFnInfo->getReturnType()));
350 assert(CallFnInfo.arg_size() == CurFnInfo->arg_size());
351 for (
unsigned i = 0, e = CurFnInfo->arg_size(); i != e; ++i)
352 assert(
similar(CallFnInfo.arg_begin()[i].info,
353 CallFnInfo.arg_begin()[i].type,
354 CurFnInfo->arg_begin()[i].info,
355 CurFnInfo->arg_begin()[i].type));
370 llvm::CallBase *CallOrInvoke;
372 CallArgs, &CallOrInvoke);
377 else if (llvm::CallInst* Call = dyn_cast<llvm::CallInst>(CallOrInvoke))
378 Call->setTailCallKind(llvm::CallInst::TCK_Tail);
385 AutoreleaseResult =
false;
392 llvm::FunctionCallee Callee) {
398 for (llvm::Argument &A : CurFn->args())
402 const ABIArgInfo &ThisAI = CurFnInfo->arg_begin()->info;
404 const ABIArgInfo &RetAI = CurFnInfo->getReturnInfo();
406 llvm::Type *ThisType = Args[ThisArgNo]->getType();
407 if (ThisType != AdjustedThisPtr->getType())
408 AdjustedThisPtr = Builder.CreateBitCast(AdjustedThisPtr, ThisType);
409 Args[ThisArgNo] = AdjustedThisPtr;
411 assert(ThisAI.
isInAlloca() &&
"this is passed directly or inalloca");
412 Address ThisAddr = GetAddrOfLocalVar(CXXABIThisDecl);
413 llvm::Type *ThisType = ThisAddr.getElementType();
414 if (ThisType != AdjustedThisPtr->getType())
415 AdjustedThisPtr = Builder.CreateBitCast(AdjustedThisPtr, ThisType);
416 Builder.CreateStore(AdjustedThisPtr, ThisAddr);
421 llvm::CallInst *Call = Builder.CreateCall(Callee, Args);
422 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
426 llvm::AttributeList Attrs;
429 Call->setAttributes(Attrs);
430 Call->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
432 if (Call->getType()->isVoidTy())
433 Builder.CreateRetVoid();
435 Builder.CreateRet(Call);
439 EmitBlock(createBasicBlock());
446 bool IsUnprototyped) {
447 StartThunk(Fn, GD, FnInfo, IsUnprototyped);
455 Ty = llvm::StructType::get(getLLVMContext());
463 Callee = llvm::ConstantExpr::getBitCast(Callee, Fn->getType());
466 EmitCallAndReturnForThunk(llvm::FunctionCallee(Fn->getFunctionType(), Callee),
467 &Thunk, IsUnprototyped);
471 bool IsUnprototyped,
bool ForVTable) {
488 llvm::Constant *CodeGenVTables::maybeEmitThunk(
GlobalDecl GD,
498 llvm::raw_svector_ostream Out(Name);
504 llvm::Constant *Thunk = CGM.
GetAddrOfThunk(Name, ThunkVTableTy, GD);
521 llvm::Function *ThunkFn = cast<llvm::Function>(Thunk->stripPointerCasts());
522 if (ThunkFn->getFunctionType() != ThunkFnTy) {
523 llvm::GlobalValue *OldThunkFn = ThunkFn;
525 assert(OldThunkFn->isDeclaration() &&
"Shouldn't replace non-declaration");
528 OldThunkFn->setName(StringRef());
534 if (!OldThunkFn->use_empty()) {
535 llvm::Constant *NewPtrForOldDecl =
536 llvm::ConstantExpr::getBitCast(ThunkFn, OldThunkFn->getType());
537 OldThunkFn->replaceAllUsesWith(NewPtrForOldDecl);
541 OldThunkFn->eraseFromParent();
545 bool UseAvailableExternallyLinkage = ForVTable && ABIHasKeyFunctions;
547 if (!ThunkFn->isDeclaration()) {
548 if (!ABIHasKeyFunctions || UseAvailableExternallyLinkage) {
562 ThunkFn->addFnAttr(
"thunk");
571 bool ShouldCloneVarArgs =
false;
572 if (!IsUnprototyped && ThunkFn->isVarArg()) {
573 ShouldCloneVarArgs =
true;
576 case llvm::Triple::x86_64:
577 case llvm::Triple::x86:
578 case llvm::Triple::aarch64:
579 ShouldCloneVarArgs =
false;
587 if (ShouldCloneVarArgs) {
588 if (UseAvailableExternallyLinkage)
612 if (!ThunkInfoVector)
615 for (
const ThunkInfo& Thunk : *ThunkInfoVector)
616 maybeEmitThunk(GD, Thunk,
false);
619 void CodeGenVTables::addVTableComponent(
621 unsigned idx, llvm::Constant *rtti,
unsigned &nextVTableThunkIndex) {
624 auto addOffsetConstant = [&](
CharUnits offset) {
625 builder.add(llvm::ConstantExpr::getIntToPtr(
626 llvm::ConstantInt::get(CGM.
PtrDiffTy, offset.getQuantity()),
630 switch (component.getKind()) {
632 return addOffsetConstant(component.getVCallOffset());
635 return addOffsetConstant(component.getVBaseOffset());
638 return addOffsetConstant(component.getOffsetToTop());
641 return builder.add(llvm::ConstantExpr::getBitCast(rtti, CGM.
Int8PtrTy));
649 switch (component.getKind()) {
651 llvm_unreachable(
"Unexpected vtable component kind");
653 GD = component.getFunctionDecl();
672 ? MD->
hasAttr<CUDADeviceAttr>()
673 : (MD->
hasAttr<CUDAHostAttr>() || !MD->
hasAttr<CUDADeviceAttr>());
675 return builder.addNullPointer(CGM.
Int8PtrTy);
679 auto getSpecialVirtualFn = [&](StringRef
name) -> llvm::Constant * {
684 return llvm::ConstantPointerNull::get(CGM.
Int8PtrTy);
685 llvm::FunctionType *fnTy =
686 llvm::FunctionType::get(CGM.
VoidTy,
false);
687 llvm::Constant *fn = cast<llvm::Constant>(
689 if (
auto f = dyn_cast<llvm::Function>(fn))
690 f->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
691 return llvm::ConstantExpr::getBitCast(fn, CGM.
Int8PtrTy);
694 llvm::Constant *fnPtr;
697 if (cast<CXXMethodDecl>(GD.
getDecl())->isPure()) {
701 fnPtr = PureVirtualFn;
704 }
else if (cast<CXXMethodDecl>(GD.
getDecl())->isDeleted()) {
705 if (!DeletedVirtualFn)
708 fnPtr = DeletedVirtualFn;
711 }
else if (nextVTableThunkIndex < layout.
vtable_thunks().size() &&
713 auto &thunkInfo = layout.
vtable_thunks()[nextVTableThunkIndex].second;
715 nextVTableThunkIndex++;
716 fnPtr = maybeEmitThunk(GD, thunkInfo,
true);
724 fnPtr = llvm::ConstantExpr::getBitCast(fnPtr, CGM.
Int8PtrTy);
730 return builder.addNullPointer(CGM.
Int8PtrTy);
733 llvm_unreachable(
"Unexpected vtable component kind");
738 for (
unsigned i = 0, e = layout.
getNumVTables(); i != e; ++i) {
747 llvm::Constant *rtti) {
748 unsigned nextVTableThunkIndex = 0;
749 for (
unsigned i = 0, e = layout.
getNumVTables(); i != e; ++i) {
753 for (
unsigned i = thisIndex; i != nextIndex; ++i) {
754 addVTableComponent(vtableElem, layout, i, rtti, nextVTableThunkIndex);
756 vtableElem.finishAndAddTo(builder);
760 llvm::GlobalVariable *
764 llvm::GlobalVariable::LinkageTypes
Linkage,
765 VTableAddressPointsMapTy& AddressPoints) {
767 DI->completeClassData(Base.
getBase());
769 std::unique_ptr<VTableLayout> VTLayout(
774 AddressPoints = VTLayout->getAddressPoints();
778 llvm::raw_svector_ostream Out(OutName);
782 StringRef Name = OutName.str();
791 if (Linkage == llvm::GlobalVariable::AvailableExternallyLinkage)
794 unsigned Align = CGM.
getDataLayout().getABITypeAlignment(VTType);
797 llvm::GlobalVariable *VTable =
801 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
810 components.finishAndSetAsInitializer(VTable);
814 assert(!VTable->isDeclaration() &&
"Shouldn't set properties on declaration");
831 llvm::GlobalVariable::LinkageTypes
839 if (keyFunction && !RD->
hasAttr<DLLImportAttr>()) {
844 keyFunction = cast<CXXMethodDecl>(def);
849 assert((def || CodeGenOpts.OptimizationLevel > 0 ||
851 "Shouldn't query vtable linkage without key function, " 852 "optimizations, or debug info");
853 if (!def && CodeGenOpts.OptimizationLevel > 0)
854 return llvm::GlobalVariable::AvailableExternallyLinkage;
858 llvm::GlobalVariable::LinkOnceODRLinkage :
865 llvm::GlobalVariable::LinkOnceODRLinkage :
870 llvm::GlobalVariable::WeakODRLinkage :
874 llvm_unreachable(
"Should not have been asked to emit this");
883 llvm::GlobalVariable::LinkageTypes DiscardableODRLinkage =
884 llvm::GlobalValue::LinkOnceODRLinkage;
885 llvm::GlobalVariable::LinkageTypes NonDiscardableODRLinkage =
886 llvm::GlobalValue::WeakODRLinkage;
887 if (RD->
hasAttr<DLLExportAttr>()) {
889 DiscardableODRLinkage = NonDiscardableODRLinkage;
890 }
else if (RD->
hasAttr<DLLImportAttr>()) {
892 DiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;
893 NonDiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;
900 return DiscardableODRLinkage;
905 if (getTarget().getCXXABI().isMicrosoft())
906 return DiscardableODRLinkage;
908 ? llvm::GlobalVariable::AvailableExternallyLinkage
912 return NonDiscardableODRLinkage;
915 llvm_unreachable(
"Invalid TemplateSpecializationKind!");
925 VTables.GenerateClassData(theClass);
931 DI->completeClassData(RD);
950 assert(RD->
isDynamicClass() &&
"Non-dynamic classes have no VTable.");
977 return !keyFunction->
hasBody();
996 void CodeGenModule::EmitDeferredVTables() {
1000 size_t savedSize = DeferredVTables.size();
1005 VTables.GenerateClassData(RD);
1006 else if (shouldOpportunisticallyEmitVTables())
1007 OpportunisticVTables.push_back(RD);
1009 assert(savedSize == DeferredVTables.size() &&
1010 "deferred extra vtables during vtable emission?");
1011 DeferredVTables.clear();
1019 if (RD->
hasAttr<LTOVisibilityPublicAttr>() || RD->
hasAttr<UuidAttr>())
1022 if (getTriple().isOSBinFormatCOFF()) {
1023 if (RD->
hasAttr<DLLExportAttr>() || RD->
hasAttr<DLLImportAttr>())
1030 if (getCodeGenOpts().LTOVisibilityPublicStd) {
1033 auto *D = cast<Decl>(DC);
1035 if (isa<TranslationUnitDecl>(DC->getRedeclContext())) {
1036 if (
auto *ND = dyn_cast<NamespaceDecl>(D))
1038 if (II->isStr(
"std") || II->isStr(
"stdext"))
1048 llvm::GlobalObject::VCallVisibility
1051 llvm::GlobalObject::VCallVisibility TypeVis;
1053 TypeVis = llvm::GlobalObject::VCallVisibilityTranslationUnit;
1054 else if (HasHiddenLTOVisibility(RD))
1055 TypeVis = llvm::GlobalObject::VCallVisibilityLinkageUnit;
1057 TypeVis = llvm::GlobalObject::VCallVisibilityPublic;
1059 for (
auto B : RD->
bases())
1060 if (B.getType()->getAsCXXRecordDecl()->isDynamicClass())
1062 GetVCallVisibilityLevel(B.getType()->getAsCXXRecordDecl()));
1064 for (
auto B : RD->
vbases())
1065 if (B.getType()->getAsCXXRecordDecl()->isDynamicClass())
1067 GetVCallVisibilityLevel(B.getType()->getAsCXXRecordDecl()));
1073 llvm::GlobalVariable *VTable,
1075 if (!getCodeGenOpts().LTOUnit)
1081 typedef std::pair<const CXXRecordDecl *, unsigned> AddressPoint;
1082 std::vector<AddressPoint> AddressPoints;
1084 AddressPoints.push_back(std::make_pair(
1086 AP.second.AddressPointIndex));
1089 llvm::sort(AddressPoints, [
this](
const AddressPoint &AP1,
1090 const AddressPoint &AP2) {
1095 llvm::raw_string_ostream O1(S1);
1096 getCXXABI().getMangleContext().mangleTypeName(
1097 QualType(AP1.first->getTypeForDecl(), 0), O1);
1101 llvm::raw_string_ostream O2(S2);
1102 getCXXABI().getMangleContext().mangleTypeName(
1103 QualType(AP2.first->getTypeForDecl(), 0), O2);
1111 return AP1.second < AP2.second;
1115 for (
auto AP : AddressPoints) {
1117 AddVTableTypeMetadata(VTable, PointerWidth * AP.second, AP.first);
1123 for (
unsigned I = 0; I != Comps.size(); ++I) {
1126 llvm::Metadata *MD = CreateMetadataIdentifierForVirtualMemPtrType(
1128 Comps[I].getFunctionDecl()->getType(),
1130 VTable->addTypeMetadata((PointerWidth * I).getQuantity(), MD);
1134 if (getCodeGenOpts().VirtualFunctionElimination) {
1135 llvm::GlobalObject::VCallVisibility TypeVis = GetVCallVisibilityLevel(RD);
1136 if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic)
1137 VTable->addVCallVisibilityMetadata(TypeVis);
const llvm::DataLayout & getDataLayout() const
size_t getNumVTables() const
ReturnValueSlot - Contains the address where the return value of a function can be stored...
static const Decl * getCanonicalDecl(const Decl *D)
Represents a function declaration or definition.
External linkage, which indicates that the entity can be referred to from other translation units...
void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F)
Set the LLVM function attributes (sext, zext, etc).
A (possibly-)qualified type.
bool ReturnTypeUsesSRet(const CGFunctionInfo &FI)
Return true iff the given type uses 'sret' when used as a return type.
CodeGenTypes & getTypes()
const CodeGenOptions & getCodeGenOpts() const
const AddressPointsMapTy & getAddressPoints() const
virtual void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV, QualType ResultType)
llvm::LLVMContext & getLLVMContext()
CXXDtorType getDtorType() const
virtual void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy, FunctionArgList &Params)=0
Insert any ABI-specific implicit parameters into the parameter list for a function.
The standard implementation of ConstantInitBuilder used in Clang.
CharUnits getClassPointerAlignment(const CXXRecordDecl *CD)
Returns the assumed alignment of an opaque pointer to the given class.
FunctionType - C99 6.7.5.3 - Function Declarators.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
QualType getThisType() const
Return the type of the this pointer.
virtual const ThunkInfoVectorTy * getThunkInfo(GlobalDecl GD)
virtual llvm::Value * performThisAdjustment(CodeGenFunction &CGF, Address This, const ThisAdjustment &TA)=0
void setFunctionLinkage(GlobalDecl GD, llvm::Function *F)
virtual StringRef GetDeletedVirtualCallName()=0
Gets the deleted virtual member call name.
const TargetInfo & getTargetInfo() const
llvm::Function * GenerateVarArgsThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo, GlobalDecl GD, const ThunkInfo &Thunk)
bool isFuncTypeConvertible(const FunctionType *FT)
isFuncTypeConvertible - Utility to check whether a function type can be converted to an LLVM type (i...
bool HasHiddenLTOVisibility(const CXXRecordDecl *RD)
Returns whether the given record has hidden LTO visibility and therefore may participate in (single-m...
bool isDefined(const FunctionDecl *&Definition) const
Returns true if the function has a definition that does not need to be instantiated.
void StartThunk(llvm::Function *Fn, GlobalDecl GD, const CGFunctionInfo &FnInfo, bool IsUnprototyped)
bool ReturnValue(const T &V, APValue &R)
Convers a value to an APValue.
Objects with "hidden" visibility are not seen by the dynamic linker.
Visibility getVisibility() const
CGDebugInfo * getModuleDebugInfo()
bool supportsCOMDAT() const
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
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 ...
llvm::Value * getPointer() const
Don't generate debug info.
Represents a parameter to a function.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have...
void add(RValue rvalue, QualType type)
CharUnits getBaseOffset() const
getBaseOffset - Returns the base class offset.
uint64_t getPointerWidth(unsigned AddrSpace) const
Return the width of pointers on this target, for the specified address space.
One of these records is kept for each identifier that is lexed.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
void generateThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo, GlobalDecl GD, const ThunkInfo &Thunk, bool IsUnprototyped)
Generate a thunk for the given method.
Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
static bool shouldEmitAvailableExternallyVTable(const CodeGenModule &CGM, const CXXRecordDecl *RD)
bool isReferenceType() const
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...
llvm::Type * getVTableType(const VTableLayout &layout)
Returns the type of a vtable with the given layout.
The this pointer adjustment as well as an optional return adjustment for a thunk. ...
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
ArrayRef< ParmVarDecl * > parameters() const
virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF)=0
Emit the ABI-specific prolog for the function.
ArrayRef< VTableComponent > vtable_components() const
virtual void emitVTableDefinitions(CodeGenVTables &CGVT, const CXXRecordDecl *RD)=0
Emits the VTable definitions required for the given record type.
CharUnits - This is an opaque type for sizes expressed in character units.
virtual bool hasMostDerivedReturn(GlobalDecl GD) const
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
void ConstructAttributeList(StringRef Name, const CGFunctionInfo &Info, CGCalleeInfo CalleeInfo, llvm::AttributeList &Attrs, unsigned &CallingConv, bool AttrOnCallSite)
Get the LLVM attributes and calling convention to use for a particular function type.
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
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...
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
ItaniumVTableContext & getItaniumVTableContext()
static bool shouldEmitVTableThunk(CodeGenModule &CGM, const CXXMethodDecl *MD, bool IsUnprototyped, bool ForVTable)
const CGFunctionInfo & arrangeGlobalDeclaration(GlobalDecl GD)
param_iterator param_begin()
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Represents a prototype with parameter type info, e.g.
bool isDynamicClass() const
ArrayBuilder beginArray(llvm::Type *eltTy=nullptr)
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
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...
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 hasKeyFunctions() const
Does this ABI use key functions? If so, class data such as the vtable is emitted with strong linkage ...
static void setThunkProperties(CodeGenModule &CGM, const ThunkInfo &Thunk, llvm::Function *ThunkFn, bool ForVTable, GlobalDecl GD)
static bool similar(const ABIArgInfo &infoL, CanQualType typeL, const ABIArgInfo &infoR, CanQualType typeR)
const T * castAs() const
Member-template castAs<specific type>.
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
Represents a C++ destructor within a class.
virtual bool exportThunk()=0
QualType getTagDeclType(const TagDecl *Decl) const
Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl...
virtual StringRef GetPureVirtualCallName()=0
Gets the pure virtual member call function.
Linkage getLinkage() const
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
const CGFunctionInfo & arrangeUnprototypedMustTailThunk(const CXXMethodDecl *MD)
Arrange a thunk that takes 'this' as the first parameter followed by varargs.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
void EmitCallAndReturnForThunk(llvm::FunctionCallee Callee, const ThunkInfo *Thunk, bool IsUnprototyped)
bool isExternallyVisible(Linkage L)
QualType getRecordType(const RecordDecl *Decl) const
const TargetInfo & getTarget() const
This template specialization was implicitly instantiated from a template.
const LangOptions & getLangOpts() const
ASTContext & getContext() const
virtual void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, GlobalDecl GD, CallArgList &CallArgs)
CallingConv
CallingConv - Specifies the calling convention that a function uses.
GlobalDecl - represents a global declaration.
The l-value was considered opaque, so the alignment was determined from a type.
ArrayRef< VTableThunkTy > vtable_thunks() const
virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, const ThisAdjustment &ThisAdjustment, raw_ostream &)=0
llvm::Constant * GetAddrOfThunk(StringRef Name, llvm::Type *FnTy, GlobalDecl GD)
Get the address of the thunk for the given global decl.
Encodes a location in the source.
QualType getReturnType() const
bool isSRetAfterThis() const
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
const Decl * getDecl() const
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
Represents a static or instance method of a struct/union/class.
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
CodeGenVTables(CodeGenModule &CGM)
void createVTableInitializer(ConstantStructBuilder &builder, const VTableLayout &layout, llvm::Constant *rtti)
Add vtable components for the given vtable layout to the given global initializer.
void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)
Set the LLVM function attributes which only apply to a function definition.
virtual void emitVirtualInheritanceTables(const CXXRecordDecl *RD)=0
Emit any tables needed to implement virtual inheritance.
MangleContext & getMangleContext()
Gets the mangle context.
This template specialization was instantiated from a template due to an explicit instantiation defini...
This template specialization was formed from a template-id but has not yet been declared, defined, or instantiated.
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.
FunctionArgList - Type for representing both the decl and type of parameters to a function...
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn't support the specified stmt yet.
CGFunctionInfo - Class to encapsulate the information about a function definition.
This class organizes the cross-function state that is used while generating LLVM code.
Dataflow Directional Tag Classes.
ThisAdjustment This
The this pointer adjustment.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template instantiation this function represents.
This template specialization was instantiated from a template due to an explicit instantiation declar...
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined...
void buildThisParam(CodeGenFunction &CGF, FunctionArgList &Params)
Build a parameter variable suitable for 'this'.
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. ...
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
llvm::Module & getModule() const
void EmitThunks(GlobalDecl GD)
EmitThunks - Emit the associated thunks for the given global decl.
param_iterator param_end()
llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)
Return the appropriate linkage for the vtable, VTT, and type information of the given class...
static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, unsigned additional)
Compute the arguments required by the given formal prototype, given that there may be some additional...
void EmitVTableTypeMetadata(const CXXRecordDecl *RD, llvm::GlobalVariable *VTable, const VTableLayout &VTLayout)
Emit type metadata for the given vtable using the given layout.
LinkageInfo getLinkageAndVisibility() const
Determines the linkage and visibility of this entity.
StructBuilder beginStruct(llvm::StructType *structTy=nullptr)
This template specialization was declared or defined by an explicit specialization (C++ [temp...
llvm::PointerType * Int8PtrTy
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...
void GenerateClassData(const CXXRecordDecl *RD)
GenerateClassData - Generate all the class data required to be generated upon definition of a KeyFunc...
ReturnAdjustment Return
The return adjustment.
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.
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
llvm::Type * GetFunctionTypeForVTable(GlobalDecl GD)
GetFunctionTypeForVTable - Get the LLVM function type for use in a vtable, given a CXXMethodDecl...
llvm::GlobalObject::VCallVisibility GetVCallVisibilityLevel(const CXXRecordDecl *RD)
Returns the vcall visibility of the given type.
llvm::IntegerType * PtrDiffTy
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
static RValue PerformReturnAdjustment(CodeGenFunction &CGF, QualType ResultType, RValue RV, const ThunkInfo &Thunk)
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...
Represents a C++ struct/union/class.
virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, raw_ostream &)=0
A helper class of ConstantInitBuilder, used for building constant struct initializers.
size_t getVTableSize(size_t i) const
__DEVICE__ int min(int __a, int __b)
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
A pointer to the deleting destructor.
CGCXXABI & getCXXABI() const
llvm::GlobalVariable * CreateOrReplaceCXXRuntimeVariable(StringRef Name, llvm::Type *Ty, llvm::GlobalValue::LinkageTypes Linkage, unsigned Alignment)
Will return a global variable of the given type.
static Decl::Kind getKind(const Decl *D)
static RValue get(llvm::Value *V)
virtual llvm::Value * performReturnAdjustment(CodeGenFunction &CGF, Address Ret, const ReturnAdjustment &RA)=0
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
CodeGenVTables & getVTables()
void EmitMustTailThunk(GlobalDecl GD, llvm::Value *AdjustedThisPtr, llvm::FunctionCallee Callee)
Emit a musttail call for a thunk with a potentially adjusted this pointer.
CallArgList - Type for representing both the value and type of arguments in a call.
const CGFunctionInfo & arrangeCXXMethodCall(const CallArgList &args, const FunctionProtoType *type, RequiredArgs required, unsigned numPrefixArgs)
Arrange a call to a C++ method, passing the given arguments.
const LangOptions & getLangOpts() const
base_class_range vbases()
A pointer to the complete destructor.
A helper class of ConstantInitBuilder, used for building constant array initializers.
size_t getVTableOffset(size_t i) const
An entry that is never used.
virtual void setThunkLinkage(llvm::Function *Thunk, bool ForVTable, GlobalDecl GD, bool ReturnAdjustment)=0
SourceLocation getLocation() const
bool isExternallyVisible() const
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 OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PL, ArrayRef< Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const llvm::Triple & getTriple() const