17#include "mlir/IR/Types.h"
20#include "llvm/ADT/SmallVector.h"
27 : cgm(cgm), vtContext(cgm.getASTContext().getVTableContext()) {}
36 cir::FuncOp thunkFn,
bool forVTable,
47 cgm.
setDSOLocal(
static_cast<mlir::Operation *
>(thunkFn));
51 thunkFn.setSelfComdat();
55 mlir::Type ptrTy = builder.getUInt8PtrTy();
60mlir::Type CIRGenVTables::getVTableComponentType() {
66 mlir::Type componentType = getVTableComponentType();
68 tys.push_back(cir::ArrayType::get(componentType, layout.
getVTableSize(i)));
72 return cgm.getBuilder().getAnonRecordTy(
88 assert(rd->
isDynamicClass() &&
"Non-dynamic classes have no VTable.");
92 if (cgm.getTarget().getCXXABI().isMicrosoft())
116 return !keyFunction->
hasBody();
126 vtables.generateClassData(rd);
133 cgm.getCXXABI().emitVirtualInheritanceTables(rd);
135 cgm.getCXXABI().emitVTableDefinitions(*
this, rd);
138mlir::Attribute CIRGenVTables::getVTableComponent(
139 const VTableLayout &layout,
unsigned componentIndex, mlir::Attribute rtti,
140 unsigned &nextVTableThunkIndex,
unsigned vtableAddressPoint,
141 bool vtableHasLocalLinkage) {
165 assert((mlir::isa<cir::GlobalViewAttr>(rtti) ||
166 mlir::isa<cir::ConstPtrAttr>(rtti)) &&
167 "expected GlobalViewAttr or ConstPtrAttr");
179 layout.
vtable_thunks()[nextVTableThunkIndex].first == componentIndex;
190 ? md->
hasAttr<CUDADeviceAttr>()
191 : (md->
hasAttr<CUDAHostAttr>() || !md->
hasAttr<CUDADeviceAttr>());
192 if (!canEmitMethod) {
194 nextVTableThunkIndex++;
200 auto getSpecialVirtFn = [&](StringRef name) -> cir::FuncOp {
206 "getVTableComponent for OMP Device NVPTX");
210 cir::FuncOp fnPtr = cgm.createRuntimeFunction(fnTy, name);
216 if (!fnPtr.isDeclaration())
221 if (cgm.getLangOpts().isTargetDevice()) {
222 fnPtr.setLinkage(cir::GlobalLinkageKind::WeakAnyLinkage);
223 mlir::SymbolTable::setSymbolVisibility(
224 fnPtr, cgm.getMLIRVisibilityFromCIRLinkage(fnPtr.getLinkage()));
225 mlir::OpBuilder::InsertionGuard guard(builder);
226 builder.setInsertionPointToStart(fnPtr.addEntryBlock());
227 cir::TrapOp::create(builder, fnPtr.getLoc());
237 getSpecialVirtFn(cgm.getCXXABI().getPureVirtualCallName());
238 fnPtr = pureVirtualFn;
240 if (!deletedVirtualFn)
242 getSpecialVirtFn(cgm.getCXXABI().getDeletedVirtualCallName());
243 fnPtr = deletedVirtualFn;
244 }
else if (isThunk) {
245 const ThunkInfo &thunkInfo =
247 nextVTableThunkIndex++;
252 cir::FuncType fnTy = cgm.getTypes().getFunctionType(gd);
253 fnPtr = cgm.getAddrOfFunction(gd, fnTy,
true);
256 return cir::GlobalViewAttr::get(
258 mlir::FlatSymbolRefAttr::get(fnPtr.getSymNameAttr()));
262 llvm_unreachable(
"Unexpected vtable component kind");
267 mlir::Attribute rtti,
268 bool vtableHasLocalLinkage) {
269 mlir::Type componentType = getVTableComponentType();
273 unsigned nextVTableThunkIndex = 0;
275 mlir::MLIRContext *mlirContext = &cgm.getMLIRContext();
278 for (
auto [vtableIndex, addressPoint] : llvm::enumerate(addressPoints)) {
281 size_t vtableEnd = vtableStart + layout.
getVTableSize(vtableIndex);
283 components.reserve(vtableEnd - vtableStart);
284 for (
size_t componentIndex : llvm::seq(vtableStart, vtableEnd))
285 components.push_back(
286 getVTableComponent(layout, componentIndex, rtti, nextVTableThunkIndex,
287 addressPoint, vtableHasLocalLinkage));
289 auto arr = cir::ConstArrayAttr::get(
290 cir::ArrayType::get(componentType, components.size()),
291 mlir::ArrayAttr::get(mlirContext, components));
292 vtables.push_back(arr);
296 const auto members = mlir::ArrayAttr::get(mlirContext, vtables);
297 cir::ConstRecordAttr record = cgm.getBuilder().getAnonConstRecord(members);
300 auto vtableAttr = cir::VTableAttr::get(record.getType(), record.getMembers());
303 cgm.setInitializer(vtableOp, vtableAttr);
308 cir::GlobalLinkageKind linkage, VTableAddressPointsMapTy &addressPoints) {
311 std::unique_ptr<VTableLayout> vtLayout(
316 addressPoints = vtLayout->getAddressPoints();
320 llvm::raw_svector_ostream
out(outName);
335 if (linkage == cir::GlobalLinkageKind::AvailableExternallyLinkage)
336 linkage = cir::GlobalLinkageKind::InternalLinkage;
338 llvm::Align align = cgm.getDataLayout().getABITypeAlign(vtType);
342 cir::GlobalOp vtable = cgm.createOrReplaceCXXRuntimeVariable(
348 mlir::Attribute rtti = cgm.getAddrOfRTTIDescriptor(
349 loc, cgm.getASTContext().getCanonicalTagType(base.
getBase()));
357 assert(!vtable.isDeclaration() &&
"Shouldn't set properties on declaration");
358 cgm.setGVProperties(vtable, rd);
374 return cir::GlobalLinkageKind::InternalLinkage;
378 const CXXMethodDecl *keyFunction = astContext.getCurrentKeyFunction(rd);
379 if (keyFunction && !rd->
hasAttr<DLLImportAttr>()) {
392 (def || codeGenOpts.OptimizationLevel > 0 ||
393 codeGenOpts.getDebugInfo() != llvm::codegenoptions::NoDebugInfo) &&
394 "Shouldn't query vtable linkage without key function, "
395 "optimizations, or debug info");
396 if (!def && codeGenOpts.OptimizationLevel > 0)
397 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
400 return !astContext.getLangOpts().AppleKext
401 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
402 : cir::GlobalLinkageKind::InternalLinkage;
403 return cir::GlobalLinkageKind::ExternalLinkage;
406 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
409 return cir::GlobalLinkageKind::WeakODRLinkage;
412 return !def ? cir::GlobalLinkageKind::AvailableExternallyLinkage
413 : cir::GlobalLinkageKind::ExternalLinkage;
418 if (astContext.getLangOpts().AppleKext)
419 return cir::GlobalLinkageKind::InternalLinkage;
421 auto discardableODRLinkage = cir::GlobalLinkageKind::LinkOnceODRLinkage;
422 auto nonDiscardableODRLinkage = cir::GlobalLinkageKind::WeakODRLinkage;
423 if (rd->
hasAttr<DLLExportAttr>()) {
425 discardableODRLinkage = nonDiscardableODRLinkage;
426 }
else if (rd->
hasAttr<DLLImportAttr>()) {
428 discardableODRLinkage = cir::GlobalLinkageKind::AvailableExternallyLinkage;
429 nonDiscardableODRLinkage =
430 cir::GlobalLinkageKind::AvailableExternallyLinkage;
437 return discardableODRLinkage;
443 return discardableODRLinkage;
445 ? cir::GlobalLinkageKind::AvailableExternallyLinkage
446 : cir::GlobalLinkageKind::ExternalLinkage;
449 return nonDiscardableODRLinkage;
452 llvm_unreachable(
"Invalid TemplateSpecializationKind!");
456 assert(rd->
getNumVBases() &&
"Only classes with virtual bases need a VTT");
459 llvm::raw_svector_ostream
out(outName);
461 .mangleCXXVTT(rd,
out);
462 StringRef name = outName.str();
465 (void)cgm.getCXXABI().getAddrOfVTable(rd,
CharUnits());
467 VTTBuilder builder(cgm.getASTContext(), rd,
false);
469 auto arrayType = cir::ArrayType::get(cgm.getBuilder().getUInt8PtrTy(),
472 cgm.getDataLayout().getABITypeAlign(cgm.getBuilder().getUInt8PtrTy());
473 cir::GlobalOp vtt = cgm.createOrReplaceCXXRuntimeVariable(
476 cgm.setGVProperties(vtt, rd);
483 const VTTVTable &vtable, cir::GlobalLinkageKind linkage,
485 if (vtable.
getBase() == mostDerivedClass) {
487 "Most derived class vtable must have a zero offset!");
498 cir::GlobalLinkageKind linkage,
500 VTTBuilder builder(cgm.getASTContext(), rd,
true);
502 mlir::MLIRContext *mlirContext = &cgm.getMLIRContext();
504 auto arrayType = cir::ArrayType::get(cgm.getBuilder().getUInt8PtrTy(),
510 vtableAddressPoints.push_back(VTableAddressPointsMapTy());
512 vtableAddressPoints.back()));
518 cir::GlobalOp vtable = vtables[vttComponent.VTableIndex];
524 vttComponent.VTableBase);
526 addressPoint = vtableAddressPoints[vttComponent.VTableIndex].lookup(
527 vttComponent.VTableBase);
529 "Did not find ctor vtable address point!");
532 mlir::Attribute indices[2] = {
533 cgm.getBuilder().getI32IntegerAttr(addressPoint.
VTableIndex),
537 auto indicesAttr = mlir::ArrayAttr::get(mlirContext, indices);
542 vttComponents.push_back(init);
545 auto init = cir::ConstArrayAttr::get(
546 arrayType, mlir::ArrayAttr::get(mlirContext, vttComponents));
548 vttOp.setInitialValueAttr(init);
551 vttOp.setLinkage(linkage);
552 mlir::SymbolTable::setSymbolVisibility(
555 if (cgm.supportsCOMDAT() && vttOp.isWeakForLinker())
556 vttOp.setSelfComdat();
561 BaseSubobjectPairTy classSubobjectPair(rd, base);
563 SubVTTIndiciesMapTy::iterator it = subVTTIndicies.find(classSubobjectPair);
564 if (it != subVTTIndicies.end())
567 VTTBuilder builder(cgm.getASTContext(), rd,
false);
571 BaseSubobjectPairTy subclassSubobjectPair(rd, entry.first);
573 subVTTIndicies.insert(std::make_pair(subclassSubobjectPair, entry.second));
576 it = subVTTIndicies.find(classSubobjectPair);
577 assert(it != subVTTIndicies.end() &&
"Did not find index!");
584 auto it = secondaryVirtualPointerIndices.find(std::make_pair(rd, base));
586 if (it != secondaryVirtualPointerIndices.end())
589 VTTBuilder builder(cgm.getASTContext(), rd,
false);
593 std::pair<const CXXRecordDecl *, BaseSubobject> pair =
594 std::make_pair(rd, entry.first);
596 secondaryVirtualPointerIndices.insert(std::make_pair(pair, entry.second));
599 it = secondaryVirtualPointerIndices.find(std::make_pair(rd, base));
600 assert(it != secondaryVirtualPointerIndices.end() &&
"Did not find index!");
610 mlir::Value returnValue = rv.
getValue();
617 mlir::Location loc = returnValue.getLoc();
619 if (!nullCheckValue) {
628 cir::TernaryOp::create(
629 builder, loc, isNotNull,
630 [&](mlir::OpBuilder &, mlir::Location) {
636 [&](mlir::OpBuilder &, mlir::Location) {
637 mlir::Value nullVal =
638 builder.
getNullPtr(returnValue.getType(), loc).getResult();
648 bool isUnprototyped) {
649 assert(!
curGD.getDecl() &&
"curGD was already set!");
658 resultType =
cgm.getASTContext().VoidTy;
659 else if (
cgm.getCXXABI().hasThisReturn(gd))
660 resultType = thisType;
661 else if (
cgm.getCXXABI().hasMostDerivedReturn(gd))
662 resultType =
cgm.getASTContext().VoidPtrTy;
668 cgm.getCXXABI().buildThisParam(*
this, functionArgs);
671 if (!isUnprototyped) {
675 cgm.getCXXABI().addImplicitStructorParams(*
this, resultType,
682 cir::FuncType funcType =
cgm.getTypes().getFunctionType(fnInfo);
690 cgm.getCXXABI().emitInstanceFunctionProlog(md->
getLocation(), *
this);
708 bool isUnprototyped) {
710 "Please use a new CGF for this thunk");
719 mlir::Value adjustedThisPtr =
721 thisValueClass, *thunk)
732 cgm.errorUnsupported(
733 md,
"return-adjusting thunk with incomplete parameter type");
735 llvm_unreachable(
"shouldn't try to emit musttail return-adjusting "
736 "thunks for variadic functions");
738 cgm.errorUnsupported(
739 md,
"non-trivial argument copy for return-adjusting thunk");
748 callArgs.add(
RValue::get(adjustedThisPtr), thisType);
751 cgm.getCXXABI().adjustCallArgsForDestructorThunk(*
this,
curGD, callArgs);
754 unsigned prefixArgs = callArgs.size() - 1;
767 assert(callFnInfo.argTypeSize() ==
curFnInfo->argTypeSize());
772 :
cgm.getCXXABI().hasMostDerivedReturn(
curGD)
773 ?
cgm.getASTContext().VoidPtrTy
784 mlir::Location loc = builder.getUnknownLoc();
786 nullptr,
false, fnLoc);
802 cgm.getCXXABI().emitReturnFromThunk(*
this, rv, resultType);
814 mlir::Value adjustedThisPtr,
815 cir::FuncOp callee) {
820 for (mlir::BlockArgument arg : entryBlock->getArguments())
824 assert(!args.empty() &&
"thunk must have at least 'this' argument");
825 if (adjustedThisPtr.getType() != args[0].getType())
826 adjustedThisPtr = builder.createBitcast(adjustedThisPtr, args[0].
getType());
827 args[0] = adjustedThisPtr;
829 mlir::Location loc =
curFn->getLoc();
830 cir::FuncType calleeTy = callee.getFunctionType();
831 mlir::Type retTy = calleeTy.getReturnType();
835 builder.createCallOp(loc, callee, args, {}, {},
837 call->setAttr(cir::CIRDialect::getMustTailAttrName(),
838 mlir::UnitAttr::get(builder.getContext()));
841 cir::ReturnOp::create(builder, loc);
843 cir::ReturnOp::create(builder, loc, call->getResult(0));
851 bool isUnprototyped) {
854 assert(fn.isDeclaration() &&
"Function already has body?");
855 mlir::Block *entryBb = fn.addEntryBlock();
856 builder.setInsertionPointToStart(entryBb);
876 cgm.errorNYI(
"unprototyped thunk placeholder type");
878 ty =
cgm.getTypes().getFunctionType(fnInfo);
880 cir::FuncOp calleeOp =
cgm.getAddrOfFunction(gd, ty,
true);
887 bool isUnprototyped,
bool forVTable) {
911 llvm::raw_svector_ostream
out(name);
919 if (cgm.getASTContext().useAbbreviatedThunkName(gd, name.str())) {
928 cir::FuncType thunkVTableTy = cgm.getTypes().getFunctionType(gd);
929 cir::FuncOp thunk = cgm.getAddrOfThunk(name, thunkVTableTy, gd);
932 bool isUnprototyped = !cgm.getTypes().isFuncTypeConvertible(
940 isUnprototyped ? (cgm.errorNYI(
"unprototyped must-tail thunk"),
941 cgm.getTypes().arrangeGlobalDeclaration(gd))
942 : cgm.getTypes().arrangeGlobalDeclaration(gd);
943 cir::FuncType thunkFnTy = cgm.getTypes().getFunctionType(fnInfo);
947 cir::FuncOp thunkFn = thunk;
948 if (thunk.getFunctionType() != thunkFnTy) {
949 cir::FuncOp oldThunkFn = thunkFn;
951 assert(oldThunkFn.isDeclaration() &&
"Shouldn't replace non-declaration");
954 cgm.eraseGlobalSymbol(oldThunkFn);
955 oldThunkFn.setName(StringRef());
957 cir::FuncOp::create(cgm.getBuilder(), thunk->getLoc(), name.str(),
958 thunkFnTy, cir::GlobalLinkageKind::ExternalLinkage);
959 cgm.insertGlobalSymbol(thunkFn);
960 cgm.setCIRFunctionAttributes(md, fnInfo, thunkFn,
false);
962 if (!oldThunkFn->use_empty())
963 oldThunkFn->replaceAllUsesWith(thunkFn);
969 bool abiHasKeyFunctions = cgm.getTarget().getCXXABI().hasKeyFunctions();
970 bool useAvailableExternallyLinkage = forVTable && abiHasKeyFunctions;
974 if (!thunkFn.isDeclaration()) {
975 if (!abiHasKeyFunctions || useAvailableExternallyLinkage) {
994 bool shouldCloneVarArgs =
false;
995 if (!isUnprototyped && thunkFn.getFunctionType().isVarArg()) {
996 shouldCloneVarArgs =
true;
998 switch (cgm.getTriple().getArch()) {
999 case llvm::Triple::x86_64:
1000 case llvm::Triple::x86:
1001 case llvm::Triple::aarch64:
1002 shouldCloneVarArgs =
false;
1010 if (shouldCloneVarArgs) {
1011 if (useAvailableExternallyLinkage)
1013 cgm.errorNYI(
"varargs thunk cloning");
1016 mlir::OpBuilder::InsertionGuard guard(cgm.getBuilder());
1019 thunkAdjustments, isUnprototyped);
1035 vtContext->getThunkInfo(gd);
1037 if (!thunkInfoVector)
1040 for (
const ThunkInfo &thunk : *thunkInfoVector)
1070 size_t savedSize = deferredVTables.size();
1074 vtables.generateClassData(rd);
1076 opportunisticVTables.push_back(rd);
1079 assert(savedSize == deferredVTables.size() &&
1080 "deferred extra vtables during vtable emission?");
1081 deferredVTables.clear();
1092 "Only emit opportunistic vtables with optimizations");
1096 "This queue should only contain external vtables");
1097 if (
getCXXABI().canSpeculativelyEmitVTable(rd))
1098 vtables.generateClassData(rd);
1100 opportunisticVTables.clear();
1104 return codeGenOpts.OptimizationLevel > 0;
static RValue performReturnAdjustment(CIRGenFunction &cgf, QualType resultType, RValue rv, const ThunkInfo &thunk)
static cir::GlobalOp getAddrOfVTTVTable(CIRGenVTables &cgvt, CIRGenModule &cgm, const CXXRecordDecl *mostDerivedClass, const VTTVTable &vtable, cir::GlobalLinkageKind linkage, VTableLayout::AddressPointsMapTy &addressPoints)
static bool shouldEmitAvailableExternallyVTable(const CIRGenModule &cgm, const CXXRecordDecl *rd)
static bool shouldEmitVTableAtEndOfTranslationUnit(CIRGenModule &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 setThunkProperties(CIRGenModule &cgm, const ThunkInfo &thunk, cir::FuncOp thunkFn, bool forVTable, GlobalDecl gd)
static bool shouldEmitVTableThunk(CIRGenModule &cgm, const CXXMethodDecl *md, bool isUnprototyped, bool forVTable)
static bool hasAttr(const Decl *D, bool IgnoreImplicitAttr)
mlir::TypedAttr getConstNullPtrAttr(mlir::Type t)
cir::GlobalViewAttr getGlobalViewAttr(cir::GlobalOp globalOp, mlir::ArrayAttr indices={})
Get constant address of a global variable as an MLIR attribute.
cir::ConstantOp getNullPtr(mlir::Type ty, mlir::Location loc)
mlir::Value createPtrIsNotNull(mlir::Value ptr)
mlir::TypedAttr getConstPtrAttr(mlir::Type type, int64_t value)
cir::YieldOp createYield(mlir::Location loc, mlir::ValueRange value={})
Create a yield operation.
C++ view class that accepts both !cir.struct and !cir.union types.
static llvm::SmallVector< RecordMemberKind > getAllDataKinds(llvm::ArrayRef< mlir::Type > members)
One Data kind per member.
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
const TargetInfo & getTargetInfo() const
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
CharUnits getBaseOffset() const
getBaseOffset - Returns the base class offset.
cir::PointerType getUInt8PtrTy()
cir::FuncType getFuncType(llvm::ArrayRef< mlir::Type > params, mlir::Type retTy, bool isVarArg=false)
virtual bool exportThunk()=0
Returns true if the thunk should be exported.
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 cir::GlobalOp getAddrOfVTable(const CXXRecordDecl *rd, CharUnits vptrOffset)=0
Get the address of the vtable for the given record decl which should be used for the vptr at the give...
virtual void setThunkLinkage(cir::FuncOp thunk, bool forVTable, GlobalDecl gd, bool returnAdjustment)=0
Set the linkage and visibility of a thunk function.
virtual mlir::Value performReturnAdjustment(CIRGenFunction &cgf, Address ret, const CXXRecordDecl *unadjustedClass, const ReturnAdjustment &ra)=0
Perform adjustment on a return pointer for a thunk (covariant returns).
static CIRGenCallee forDirect(mlir::Operation *funcPtr, const CIRGenCalleeInfo &abstractInfo=CIRGenCalleeInfo())
clang::GlobalDecl curGD
The GlobalDecl for the current function being compiled or the global variable currently being initial...
bool curFuncIsThunk
In C++, whether we are code generating a thunk.
mlir::Block * getCurFunctionEntryBlock()
mlir::Value loadCXXThis()
Load the value for 'this'.
const clang::Decl * curFuncDecl
Address loadCXXThisAddress()
void emitMustTailThunk(GlobalDecl gd, mlir::Value adjustedThisPtr, cir::FuncOp callee)
Emit a musttail call for a thunk with a potentially different ABI.
llvm::ScopedHashTableScope< const clang::Decl *, mlir::Value > SymTableScopeTy
mlir::Operation * curFn
The current function or global initializer that is generated code for.
void startThunk(cir::FuncOp fn, GlobalDecl gd, const CIRGenFunctionInfo &fnInfo, bool isUnprototyped)
Start generating a thunk function.
mlir::Type convertTypeForMem(QualType t)
Address returnValue
The temporary alloca to hold the return value.
static bool hasAggregateEvaluationKind(clang::QualType type)
void finishFunction(SourceLocation endLoc)
void emitCallAndReturnForThunk(cir::FuncOp callee, SourceRange fnLoc, const ThunkInfo *thunk, bool isUnprototyped)
Emit the call and return for a thunk function.
void emitReturnOfRValue(mlir::Location loc, RValue rv, QualType ty)
const clang::Decl * curCodeDecl
This is the inner-most code context, which includes blocks.
CIRGenBuilderTy & getBuilder()
void startFunction(clang::GlobalDecl gd, clang::QualType returnType, cir::FuncOp fn, cir::FuncType funcType, FunctionArgList args, clang::SourceLocation loc, clang::SourceLocation startLoc)
Emit code for the start of a function.
RValue emitCall(const CIRGenFunctionInfo &funcInfo, const CIRGenCallee &callee, ReturnValueSlot returnValue, const CallArgList &args, cir::CIRCallOpInterface *callOp, bool isMustTail, SourceRange clangLoc)
void emitDelegateCallArg(CallArgList &args, const clang::VarDecl *param, clang::SourceLocation loc)
We are performing a delegate call; that is, the current function is delegating to another one.
const CIRGenFunctionInfo * curFnInfo
mlir::Value cxxabiThisValue
void generateThunk(cir::FuncOp fn, SourceRange fnLoc, const CIRGenFunctionInfo &fnInfo, GlobalDecl gd, const ThunkInfo &thunk, bool isUnprototyped)
Generate code for a thunk function.
void finishThunk()
Finish generating a thunk function.
This class organizes the cross-function state that is used while generating CIR code.
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
clang::ASTContext & getASTContext() const
CIRGenBuilderTy & getBuilder()
void setDSOLocal(mlir::Operation *op) const
void setGVProperties(mlir::Operation *op, const NamedDecl *d) const
Set visibility, dllimport/dllexport and dso_local.
clang::CharUnits getClassPointerAlignment(const clang::CXXRecordDecl *rd)
Return the best known alignment for an unknown pointer to a particular class.
const clang::TargetInfo & getTarget() const
const llvm::Triple & getTriple() const
bool shouldOpportunisticallyEmitVTables()
static mlir::SymbolTable::Visibility getMLIRVisibility(Visibility v)
mlir::Type getVTableComponentType()
cir::FuncOp getAddrOfThunk(StringRef name, mlir::Type fnTy, GlobalDecl gd)
Get or create a thunk function with the given name and type.
const clang::CodeGenOptions & getCodeGenOpts() const
void emitDeferredVTables()
Emit any vtables which we deferred and still have a use for.
const clang::LangOptions & getLangOpts() const
cir::FuncOp getOrCreateCIRFunction(llvm::StringRef mangledName, mlir::Type funcType, clang::GlobalDecl gd, bool forVTable, bool dontDefer=false, bool isThunk=false, ForDefinition_t isForDefinition=NotForDefinition, mlir::NamedAttrList extraAttrs={})
void emitVTablesOpportunistically()
Try to emit external vtables as available_externally if they have emitted all inlined virtual functio...
bool supportsCOMDAT() const
CIRGenCXXABI & getCXXABI() const
CIRGenVTables & getVTables()
void setFunctionLinkage(GlobalDecl gd, cir::FuncOp f)
void emitVTable(const CXXRecordDecl *rd)
This is a callback from Sema to tell us that a particular vtable is required to be emitted in this tr...
cir::GlobalLinkageKind getVTableLinkage(const CXXRecordDecl *rd)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
cir::RecordType getVTableType(const clang::VTableLayout &layout)
Returns the type of a vtable with the given layout.
void createVTableInitializer(cir::GlobalOp &vtable, const clang::VTableLayout &layout, mlir::Attribute rtti, bool vtableHasLocalLinkage)
Add vtable components for the given vtable layout to the given global initializer.
cir::GlobalOp generateConstructionVTable(const CXXRecordDecl *rd, const BaseSubobject &base, bool baseIsVirtual, cir::GlobalLinkageKind linkage, VTableAddressPointsMapTy &addressPoints)
Generate a construction vtable for the given base subobject.
uint64_t getSubVTTIndex(const CXXRecordDecl *rd, BaseSubobject base)
Return the index of the sub-VTT for the base class of the given record decl.
void emitThunks(GlobalDecl gd)
Emit the associated thunks for the given global decl.
void emitVTTDefinition(cir::GlobalOp vttOp, cir::GlobalLinkageKind linkage, const CXXRecordDecl *rd)
Emit the definition of the given vtable.
CIRGenVTables(CIRGenModule &cgm)
cir::FuncOp maybeEmitThunk(GlobalDecl gd, const ThunkInfo &thunkAdjustments, bool forVTable)
Emit a thunk for the given global decl if needed, or return an existing thunk.
void generateClassData(const CXXRecordDecl *rd)
Generate all the class data required to be generated upon definition of a KeyFunction.
cir::GlobalOp getAddrOfVTT(const CXXRecordDecl *rd)
Get the address of the VTT for the given record decl.
clang::ItaniumVTableContext & getItaniumVTableContext()
bool isVTableExternal(const clang::CXXRecordDecl *rd)
At this point in the translation unit, does it appear that can we rely on the vtable being defined el...
uint64_t getSecondaryVirtualPointerIndex(const CXXRecordDecl *rd, BaseSubobject base)
Return the index in the VTT where the virtual pointer for the given subobject is located.
Type for representing both the decl and type of parameters to a function.
This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(mlir::Value v)
mlir::Value getValue() const
Return the value of this scalar value.
static RequiredArgs getFromProtoWithExtraSlots(const clang::FunctionProtoType *prototype, unsigned additional)
Compute the arguments required by the given formal prototype, given that there may be some additional...
Contains the address where the return value of a function can be stored, and whether the address is v...
Represents a C++ destructor within a class.
Represents a static or instance method of a struct/union/class.
QualType getThisType() const
Return the type of the this pointer.
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...
bool isDynamicClass() const
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
This is an opaque type for sizes expressed in character units.
bool isZero() const
Test whether the quantity equals zero.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
ASTContext & getASTContext() const LLVM_READONLY
SourceLocation getLocation() const
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
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()
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
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.
Represents a prototype with parameter type info, e.g.
FunctionType - C99 6.7.5.3 - Function Declarators.
QualType getReturnType() const
GlobalDecl - represents a global declaration.
CXXDtorType getDtorType() const
const Decl * getDecl() const
const VTableLayout & getVTableLayout(const CXXRecordDecl *RD)
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
bool isExternallyVisible() const
Represents a parameter to a function.
A (possibly-)qualified type.
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
virtual bool emitVectorDeletingDtors(const LangOptions &) const
Controls whether to emit MSVC vector deleting destructors.
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.
Class for building VTT layout information.
const llvm::DenseMap< BaseSubobject, uint64_t > & getSecondaryVirtualPointerIndices() const
Returns a reference to the secondary virtual pointer indices.
const llvm::DenseMap< BaseSubobject, uint64_t > & getSubVTTIndices() const
Returns a reference to the sub-VTT indices.
const VTTComponentsVectorTy & getVTTComponents() const
const VTTVTablesVectorTy & getVTTVTables() const
CharUnits getBaseOffset() const
const CXXRecordDecl * getBase() const
BaseSubobject getBaseSubobject() const
Represents a single component in a vtable.
CharUnits getVBaseOffset() const
Kind getKind() const
Get the kind of this vtable component.
@ CK_DeletingDtorPointer
A pointer to the deleting destructor.
@ CK_UnusedFunctionPointer
An entry that is never used.
@ CK_CompleteDtorPointer
A pointer to the complete destructor.
CharUnits getOffsetToTop() const
GlobalDecl getGlobalDecl(bool HasVectorDeletingDtors) const
CharUnits getVCallOffset() const
SmallVector< ThunkInfo, 1 > ThunkInfoVectorTy
const AddressPointsIndexMapTy & getAddressPointIndices() const
size_t getVTableOffset(size_t i) const
llvm::DenseMap< BaseSubobject, AddressPointLocation > AddressPointsMapTy
AddressPointLocation getAddressPoint(BaseSubobject Base) const
ArrayRef< VTableComponent > vtable_components() const
size_t getNumVTables() const
ArrayRef< VTableThunkTy > vtable_thunks() const
size_t getVTableSize(size_t i) const
static bool isLocalLinkage(GlobalLinkageKind linkage)
const AstTypeMatcher< ArrayType > arrayType
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
QualType pointeeType(QualType T)
@ Dtor_Base
Base object dtor.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
U cast(CodeGen::Address addr)
Diagnostic wrappers for TextAPI types for error reporting.
static bool objCLifetime()
static bool opGlobalUnnamedAddr()
static bool vtableEmitMetadata()
static bool opCallThunkTailHint()
static bool setDLLStorageClass()
static bool opCallInAlloca()
static bool pointerAuthentication()
static bool opCallAttrs()
static bool returnValueSlotFeatures()
static bool generateDebugInfo()
static bool vtableRelativeLayout()
Represents a scope, including function bodies, compound statements, and the substatements of if/while...
The this pointer adjustment as well as an optional return adjustment for a thunk.
ReturnAdjustment Return
The return adjustment.
unsigned AddressPointIndex