31#include "mlir/IR/BuiltinOps.h"
32#include "mlir/IR/Location.h"
33#include "mlir/IR/MLIRContext.h"
34#include "mlir/IR/Verifier.h"
43 case TargetCXXABI::GenericItanium:
44 case TargetCXXABI::GenericAArch64:
45 case TargetCXXABI::AppleARM64:
48 case TargetCXXABI::Fuchsia:
49 case TargetCXXABI::GenericARM:
50 case TargetCXXABI::iOS:
51 case TargetCXXABI::WatchOS:
52 case TargetCXXABI::GenericMIPS:
53 case TargetCXXABI::WebAssembly:
54 case TargetCXXABI::XL:
55 case TargetCXXABI::Microsoft:
56 cgm.
errorNYI(
"C++ ABI kind not yet implemented");
60 llvm_unreachable(
"invalid C++ ABI kind");
63CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
67 : builder(mlirContext, *this), astContext(astContext),
68 langOpts(astContext.
getLangOpts()), codeGenOpts(cgo),
69 theModule{
mlir::ModuleOp::create(
mlir::UnknownLoc::get(&mlirContext))},
70 diags(diags), target(astContext.getTargetInfo()),
71 abi(
createCXXABI(*this)), genTypes(*this), vtables(*this) {
103 const unsigned charSize = astContext.getTargetInfo().getCharWidth();
107 const unsigned sizeTypeSize =
108 astContext.getTypeSize(astContext.getSignedSizeType());
109 SizeSizeInBytes = astContext.toCharUnitsFromBits(sizeTypeSize).getQuantity();
116 std::optional<cir::SourceLanguage> sourceLanguage = getCIRSourceLanguage();
119 cir::CIRDialect::getSourceLanguageAttrName(),
120 cir::SourceLanguageAttr::get(&mlirContext, *sourceLanguage));
121 theModule->setAttr(cir::CIRDialect::getTripleAttrName(),
122 builder.getStringAttr(
getTriple().str()));
124 if (cgo.OptimizationLevel > 0 || cgo.OptimizeSize > 0)
125 theModule->setAttr(cir::CIRDialect::getOptInfoAttrName(),
126 cir::OptInfoAttr::get(&mlirContext,
127 cgo.OptimizationLevel,
132 FileID mainFileId = astContext.getSourceManager().getMainFileID();
134 *astContext.getSourceManager().getFileEntryForID(mainFileId);
137 theModule.setSymName(path);
138 theModule->setLoc(mlir::FileLineColLoc::get(&mlirContext, path,
154 auto &layout = astContext.getASTRecordLayout(rd);
159 return layout.getAlignment();
162 return layout.getNonVirtualAlignment();
176 if (
unsigned align = tt->getDecl()->getMaxAlignment()) {
179 return astContext.toCharUnitsFromBits(align);
185 t = astContext.getBaseElementType(t);
207 alignment = astContext.getTypeAlignInChars(t);
212 if (
unsigned maxAlign = astContext.getLangOpts().MaxTypeAlign) {
214 !astContext.isAlignmentRequired(t))
221 if (theTargetCIRGenInfo)
222 return *theTargetCIRGenInfo;
225 switch (triple.getArch()) {
232 case llvm::Triple::x86_64: {
233 switch (triple.getOS()) {
240 case llvm::Triple::Linux:
242 return *theTargetCIRGenInfo;
249 assert(cLoc.
isValid() &&
"expected valid source location");
253 return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
258 assert(cRange.
isValid() &&
"expected a valid source range");
261 mlir::Attribute metadata;
262 return mlir::FusedLoc::get({begin, end}, metadata, builder.getContext());
271 false, isForDefinition);
305 assert(op &&
"expected a valid global op");
313 mlir::Operation *globalValueOp = op;
314 if (
auto gv = dyn_cast<cir::GetGlobalOp>(op))
316 mlir::SymbolTable::lookupSymbolIn(
getModule(), gv.getNameAttr());
318 if (
auto cirGlobalValue =
319 dyn_cast<cir::CIRGlobalValueInterface>(globalValueOp))
320 if (!cirGlobalValue.isDeclaration())
345 std::vector<GlobalDecl> curDeclsToEmit;
362 if (
const auto *cd = dyn_cast<clang::OpenACCConstructDecl>(gd.
getDecl())) {
375 if (
const auto *fd = dyn_cast<FunctionDecl>(global)) {
378 if (fd->hasAttr<AnnotateAttr>())
379 errorNYI(fd->getSourceRange(),
"deferredAnnotations");
380 if (!fd->doesThisDeclarationHaveABody()) {
381 if (!fd->doesDeclarationForceExternallyVisibleDefinition())
385 "function declaration that forces code gen");
390 assert(vd->isFileVarDecl() &&
"Cannot emit local var decl as global.");
392 !astContext.isMSStaticDataMemberInlineDefinition(vd)) {
396 if (astContext.getInlineVariableDefinitionKind(vd) ==
435 mlir::Operation *op) {
439 cir::FuncOp funcOp = dyn_cast_if_present<cir::FuncOp>(op);
440 if (!funcOp || funcOp.getFunctionType() != funcType) {
446 if (!funcOp.isDeclaration())
458 mlir::OpBuilder::InsertionGuard guard(builder);
463 setNonAliasAttributes(gd, funcOp);
466 auto getPriority = [
this](
const auto *
attr) ->
int {
470 return attr->DefaultPriority;
473 if (
const ConstructorAttr *ca = funcDecl->getAttr<ConstructorAttr>())
475 if (
const DestructorAttr *da = funcDecl->getAttr<DestructorAttr>())
478 if (funcDecl->getAttr<AnnotateAttr>())
479 errorNYI(funcDecl->getSourceRange(),
"deferredAnnotations");
484 std::optional<int> priority) {
493 ctor.setGlobalCtorPriority(priority);
498 std::optional<int> priority) {
499 if (codeGenOpts.RegisterGlobalDtorsWithAtExit &&
501 errorNYI(dtor.getLoc(),
"registerGlobalDtorsWithAtExit");
504 dtor.setGlobalDtorPriority(priority);
522 return mlir::SymbolTable::lookupSymbolIn(theModule, name);
526 mlir::Location loc, StringRef name,
527 mlir::Type t,
bool isConstant,
528 mlir::Operation *insertPoint) {
533 mlir::OpBuilder::InsertionGuard guard(builder);
539 builder.setInsertionPoint(insertPoint);
545 builder.setInsertionPointToStart(cgm.
getModule().getBody());
548 g = cir::GlobalOp::create(builder, loc, name, t, isConstant);
554 mlir::SymbolTable::setSymbolVisibility(
555 g, mlir::SymbolTable::Visibility::Private);
562 if (isa_and_nonnull<NamedDecl>(d))
568void CIRGenModule::setNonAliasAttributes(
GlobalDecl gd, mlir::Operation *op) {
579std::optional<cir::SourceLanguage> CIRGenModule::getCIRSourceLanguage()
const {
581 using CIRLang = cir::SourceLanguage;
586 if (opts.C99 || opts.C11 || opts.C17 || opts.C23 || opts.C2y ||
587 opts.LangStd == ClangStd::lang_c89 ||
588 opts.LangStd == ClangStd::lang_gnu89)
593 errorNYI(
"CIR does not yet support the given source language");
605 gv.
setLinkage(cir::GlobalLinkageKind::ExternalWeakLinkage);
624 LangAS langAS,
const VarDecl *d,
641 if (entry.getSymType() == ty)
650 if (isForDefinition && !entry.isDeclaration()) {
659 if (!isForDefinition)
668 bool isConstant =
false;
673 astContext,
true, !needsDtor);
680 entry.getOperation());
695 if (langOpts.OpenMP && !langOpts.OpenMPSimd)
698 gv.setAlignmentAttr(
getSize(astContext.getDeclAlign(d)));
712 if (astContext.isMSStaticDataMemberInlineDefinition(d))
719 if (
getTriple().getArch() == llvm::Triple::xcore)
729 "external const declaration with initializer");
763 mlir::Type ptrTy = builder.getPointerTo(g.getSymType());
765 g.getSymNameAttr(), tlsAccess);
774 cir::PointerType ptrTy = builder.getPointerTo(globalOp.getSymType());
775 return builder.getGlobalViewAttr(ptrTy, globalOp);
788 bool isDefinitionAvailableExternally =
793 if (isDefinitionAvailableExternally &&
801 mlir::Attribute init;
802 bool needsGlobalCtor =
false;
803 bool needsGlobalDtor =
804 !isDefinitionAvailableExternally &&
809 std::optional<ConstantEmitter> emitter;
813 if (vd->
hasAttr<LoaderUninitializedAttr>()) {
816 }
else if (!initExpr) {
829 emitter.emplace(*
this);
830 mlir::Attribute initializer = emitter->tryEmitForInitializer(*initDecl);
840 if (!isDefinitionAvailableExternally)
841 needsGlobalCtor =
true;
855 if (mlir::isa<mlir::SymbolRefAttr>(init)) {
859 assert(mlir::isa<mlir::TypedAttr>(init) &&
"This should have a type");
860 auto typedInitAttr = mlir::cast<mlir::TypedAttr>(init);
861 initType = typedInitAttr.getType();
863 assert(!mlir::isa<mlir::NoneType>(initType) &&
"Should have a type by now");
869 if (!gv || gv.getSymType() != initType) {
876 if (vd->
hasAttr<AnnotateAttr>()) {
887 emitter->finalize(gv);
891 gv.setConstant((vd->
hasAttr<CUDAConstantAttr>() && langOpts.CUDAIsDevice) ||
892 (!needsGlobalCtor && !needsGlobalDtor &&
899 cir::GlobalLinkageKind linkage =
903 gv.setLinkage(linkage);
907 if (linkage == cir::GlobalLinkageKind::CommonLinkage) {
909 gv.setConstant(
false);
914 std::optional<mlir::Attribute> initializer = gv.getInitialValue();
915 if (initializer && !
getBuilder().isNullValue(*initializer))
916 gv.setLinkage(cir::GlobalLinkageKind::WeakAnyLinkage);
919 setNonAliasAttributes(vd, gv);
926 if (needsGlobalCtor || needsGlobalDtor)
931 mlir::Operation *op) {
933 if (
const auto *fd = dyn_cast<FunctionDecl>(
decl)) {
937 if (
const auto *method = dyn_cast<CXXMethodDecl>(
decl)) {
941 abi->emitCXXStructor(gd);
942 else if (fd->isMultiVersion())
943 errorNYI(method->getSourceRange(),
"multiversion functions");
947 if (method->isVirtual())
953 if (fd->isMultiVersion())
954 errorNYI(fd->getSourceRange(),
"multiversion functions");
959 if (
const auto *vd = dyn_cast<VarDecl>(
decl))
962 llvm_unreachable(
"Invalid argument to CIRGenModule::emitGlobalDefinition");
976 astContext.getAsConstantArrayType(e->
getType());
977 uint64_t finalSize = cat->getZExtSize();
978 str.resize(finalSize);
980 mlir::Type eltTy =
convertType(cat->getElementType());
981 return builder.getString(str, eltTy, finalSize);
986 auto arrayEltTy = mlir::cast<cir::IntType>(arrayTy.getElementType());
988 uint64_t arraySize = arrayTy.getSize();
990 assert(arraySize == literalSize + 1 &&
991 "wide string literal array size must be literal length plus null "
996 bool isAllZero =
true;
997 for (
unsigned i = 0; i < literalSize; ++i) {
1005 return cir::ZeroAttr::get(arrayTy);
1009 elements.reserve(arraySize);
1010 for (
unsigned i = 0; i < literalSize; ++i)
1011 elements.push_back(cir::IntAttr::get(arrayEltTy, e->
getCodeUnit(i)));
1013 elements.push_back(cir::IntAttr::get(arrayEltTy, 0));
1015 auto elementsAttr = mlir::ArrayAttr::get(&
getMLIRContext(), elements);
1016 return builder.getConstArray(elementsAttr, arrayTy);
1027 if (d.
hasAttr<SelectAnyAttr>())
1031 if (
auto *vd = dyn_cast<VarDecl>(&d))
1046 llvm_unreachable(
"No such linkage");
1052 if (
auto globalOp = dyn_cast_or_null<cir::GlobalOp>(op)) {
1053 globalOp.setComdat(
true);
1056 funcOp.setComdat(
true);
1062 genTypes.updateCompletedType(td);
1066 replacements[name] = op;
1069void CIRGenModule::replacePointerTypeArgs(cir::FuncOp oldF, cir::FuncOp newF) {
1070 std::optional<mlir::SymbolTable::UseRange> optionalUseRange =
1071 oldF.getSymbolUses(theModule);
1072 if (!optionalUseRange)
1075 for (
const mlir::SymbolTable::SymbolUse &u : *optionalUseRange) {
1077 auto call = mlir::dyn_cast<cir::CallOp>(u.getUser());
1081 for (
const auto [argOp, fnArgType] :
1082 llvm::zip(call.getArgs(), newF.getFunctionType().getInputs())) {
1083 if (argOp.getType() == fnArgType)
1089 errorNYI(call.getLoc(),
"replace call with mismatched types");
1094void CIRGenModule::applyReplacements() {
1095 for (
auto &i : replacements) {
1096 StringRef mangledName = i.first();
1097 mlir::Operation *replacement = i.second;
1103 auto newF = dyn_cast<cir::FuncOp>(replacement);
1106 errorNYI(replacement->getLoc(),
"replacement is not a function");
1112 replacePointerTypeArgs(oldF, newF);
1115 if (oldF.replaceAllSymbolUses(newF.getSymNameAttr(), theModule).failed())
1116 llvm_unreachable(
"internal error, cannot RAUW symbol");
1118 newF->moveBefore(oldF);
1125 mlir::Location loc, StringRef name, mlir::Type ty,
1127 auto gv = mlir::dyn_cast_or_null<cir::GlobalOp>(
1128 mlir::SymbolTable::lookupSymbolIn(theModule, name));
1132 if (gv.getSymType() == ty)
1138 assert(gv.isDeclaration() &&
"Declaration has wrong type!");
1140 errorNYI(loc,
"createOrReplaceCXXRuntimeVariable: declaration exists with "
1151 mlir::SymbolTable::setSymbolVisibility(gv,
1155 !gv.hasAvailableExternallyLinkage()) {
1159 gv.setAlignmentAttr(
getSize(alignment));
1170 if ((noCommon || vd->
hasAttr<NoCommonAttr>()) && !vd->
hasAttr<CommonAttr>())
1181 if (vd->
hasAttr<SectionAttr>())
1187 if (vd->
hasAttr<PragmaClangBSSSectionAttr>() ||
1188 vd->
hasAttr<PragmaClangDataSectionAttr>() ||
1189 vd->
hasAttr<PragmaClangRelroSectionAttr>() ||
1190 vd->
hasAttr<PragmaClangRodataSectionAttr>())
1198 if (vd->
hasAttr<WeakImportAttr>())
1208 if (vd->
hasAttr<AlignedAttr>())
1215 for (
const FieldDecl *fd : rd->fields()) {
1216 if (fd->isBitField())
1218 if (fd->hasAttr<AlignedAttr>())
1243 return cir::GlobalLinkageKind::InternalLinkage;
1245 if (dd->
hasAttr<WeakAttr>()) {
1246 if (isConstantVariable)
1247 return cir::GlobalLinkageKind::WeakODRLinkage;
1248 return cir::GlobalLinkageKind::WeakAnyLinkage;
1253 return cir::GlobalLinkageKind::LinkOnceAnyLinkage;
1258 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
1272 return !astContext.getLangOpts().AppleKext
1273 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
1274 : cir::GlobalLinkageKind::InternalLinkage;
1288 return cir::GlobalLinkageKind::ExternalLinkage;
1291 return dd->
hasAttr<CUDAGlobalAttr>()
1292 ? cir::GlobalLinkageKind::ExternalLinkage
1293 : cir::GlobalLinkageKind::InternalLinkage;
1294 return cir::GlobalLinkageKind::WeakODRLinkage;
1302 return cir::GlobalLinkageKind::CommonLinkage;
1308 if (dd->
hasAttr<SelectAnyAttr>())
1309 return cir::GlobalLinkageKind::WeakODRLinkage;
1313 return cir::GlobalLinkageKind::ExternalLinkage;
1325 mlir::Operation *old, cir::FuncOp newFn) {
1327 auto oldFn = mlir::dyn_cast<cir::FuncOp>(old);
1335 if (oldFn->getAttrs().size() <= 1)
1337 "replaceUsesOfNonProtoTypeWithRealFunction: Attribute forwarding");
1340 newFn.setNoProto(oldFn.getNoProto());
1343 std::optional<mlir::SymbolTable::UseRange> symUses =
1344 oldFn.getSymbolUses(oldFn->getParentOp());
1345 for (
const mlir::SymbolTable::SymbolUse &use : symUses.value()) {
1346 mlir::OpBuilder::InsertionGuard guard(builder);
1348 if (
auto noProtoCallOp = mlir::dyn_cast<cir::CallOp>(use.getUser())) {
1349 builder.setInsertionPoint(noProtoCallOp);
1352 cir::CallOp realCallOp = builder.createCallOp(
1353 noProtoCallOp.getLoc(), newFn, noProtoCallOp.getOperands());
1356 noProtoCallOp.replaceAllUsesWith(realCallOp);
1357 noProtoCallOp.erase();
1358 }
else if (
auto getGlobalOp =
1359 mlir::dyn_cast<cir::GetGlobalOp>(use.getUser())) {
1361 getGlobalOp.getAddr().setType(
1362 cir::PointerType::get(newFn.getFunctionType()));
1365 "replaceUsesOfNonProtoTypeWithRealFunction: unexpected use");
1370cir::GlobalLinkageKind
1372 assert(!isConstant &&
"constant variables NYI");
1373 GVALinkage linkage = astContext.GetGVALinkageForVariable(vd);
1380 GVALinkage linkage = astContext.GetGVALinkageForFunction(d);
1382 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(d))
1391 StringRef globalName,
CharUnits alignment) {
1397 cgm, loc, globalName,
c.getType(), !cgm.
getLangOpts().WritableStrings);
1400 gv.setAlignmentAttr(cgm.
getSize(alignment));
1402 cir::GlobalLinkageKindAttr::get(cgm.
getBuilder().getContext(), lt));
1406 if (gv.isWeakForLinker()) {
1407 assert(cgm.
supportsCOMDAT() &&
"Only COFF uses weak string literals");
1410 cgm.
setDSOLocal(
static_cast<mlir::Operation *
>(gv));
1431 std::string result =
1434 assert(!mlir::SymbolTable::lookupSymbolIn(theModule, result));
1442 astContext.getAlignOfGlobalVarInChars(
s->getType(),
nullptr);
1450 if (!gv.getAlignment() ||
1451 uint64_t(alignment.
getQuantity()) > *gv.getAlignment())
1452 gv.setAlignmentAttr(
getSize(alignment));
1457 if (
getCXXABI().getMangleContext().shouldMangleStringLiteral(
s) &&
1460 "getGlobalForStringLiteral: mangle string literals");
1468 mlir::Location loc =
s->getBeginLoc().isValid()
1470 : builder.getUnknownLoc();
1471 auto typedC = llvm::cast<mlir::TypedAttr>(
c);
1473 cir::GlobalLinkageKind::PrivateLinkage, *
this,
1474 uniqueName, alignment);
1488 auto arrayTy = mlir::dyn_cast<cir::ArrayType>(gv.getSymType());
1489 assert(arrayTy &&
"String literal must be array");
1493 return builder.getGlobalViewAttr(ptrTy, gv);
1509 errorNYI(
"SYCL or OpenMP temp address space");
1519 "emitExplicitCastExprType");
1530 if (
const auto *methodDecl = dyn_cast<CXXMethodDecl>(
decl)) {
1532 if (methodDecl->isVirtual()) {
1535 "emitMemberPointerConstant: virtual method pointer");
1540 return cir::ConstantOp::create(builder, loc,
1541 builder.getMethodAttr(ty, methodFuncOp));
1547 return cir::ConstantOp::create(
1548 builder, loc, builder.getDataMemberAttr(ty,
fieldDecl->getFieldIndex()));
1558 if (
auto *oid = dyn_cast<ObjCImplDecl>(
decl))
1559 errorNYI(oid->getSourceRange(),
"emitDeclConext: ObjCImplDecl");
1569 if (
decl->isTemplated())
1572 switch (
decl->getKind()) {
1575 decl->getDeclKindName());
1578 case Decl::CXXConversion:
1579 case Decl::CXXMethod:
1580 case Decl::Function: {
1583 if (!fd->isConsteval())
1589 case Decl::Decomposition:
1590 case Decl::VarTemplateSpecialization: {
1593 errorNYI(
decl->getSourceRange(),
"global variable decompositions");
1599 case Decl::OpenACCRoutine:
1602 case Decl::OpenACCDeclare:
1605 case Decl::OMPThreadPrivate:
1608 case Decl::OMPGroupPrivate:
1611 case Decl::OMPAllocate:
1614 case Decl::OMPCapturedExpr:
1617 case Decl::OMPDeclareReduction:
1620 case Decl::OMPDeclareMapper:
1623 case Decl::OMPRequires:
1628 case Decl::UsingDirective:
1629 case Decl::UsingEnum:
1630 case Decl::NamespaceAlias:
1632 case Decl::TypeAlias:
1638 case Decl::ClassTemplate:
1640 case Decl::CXXDeductionGuide:
1642 case Decl::FunctionTemplate:
1643 case Decl::StaticAssert:
1644 case Decl::TypeAliasTemplate:
1645 case Decl::UsingShadow:
1646 case Decl::VarTemplate:
1647 case Decl::VarTemplatePartialSpecialization:
1650 case Decl::CXXConstructor:
1653 case Decl::CXXDestructor:
1658 case Decl::LinkageSpec:
1659 case Decl::Namespace:
1663 case Decl::ClassTemplateSpecialization:
1664 case Decl::CXXRecord: {
1667 for (
auto *childDecl : crd->
decls())
1673 case Decl::FileScopeAsm:
1675 if (langOpts.CUDA && langOpts.CUDAIsDevice)
1678 if (langOpts.OpenMPIsTargetDevice)
1681 if (langOpts.SYCLIsDevice)
1684 std::string line = file_asm->getAsmString();
1685 globalScopeAsm.push_back(builder.getStringAttr(line));
1692 op.setInitialValueAttr(value);
1706 md->getParent()->getNumVBases() == 0)
1708 "getAddrAndTypeOfCXXStructor: MS ABI complete destructor");
1719 false, isForDefinition);
1721 return {fnType, fn};
1725 mlir::Type funcType,
bool forVTable,
1729 "consteval function should never be emitted");
1739 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(gd.
getDecl())) {
1742 dd->getParent()->getNumVBases() == 0)
1744 "getAddrOfFunction: MS ABI complete destructor");
1750 false, isForDefinition);
1758 llvm::raw_svector_ostream
out(buffer);
1767 assert(ii &&
"Attempt to mangle unnamed decl.");
1769 const auto *fd = dyn_cast<FunctionDecl>(nd);
1773 }
else if (fd && fd->hasAttr<CUDAGlobalAttr>() &&
1789 if (
const auto *fd = dyn_cast<FunctionDecl>(nd)) {
1790 if (fd->isMultiVersion()) {
1792 "getMangledName: multi-version functions");
1797 "getMangledName: GPU relocatable device code");
1800 return std::string(
out.str());
1803static FunctionDecl *
1818 if (
auto *methodDecl = dyn_cast<CXXMethodDecl>(protoFunc);
1819 methodDecl && methodDecl->isImplicitObjectMemberFunction()) {
1821 paramTypes.insert(paramTypes.begin(), methodDecl->getThisType());
1824 fpt->getExtProtoInfo());
1835 params.reserve(fpt->getNumParams());
1838 for (
unsigned i = 0, e = fpt->getNumParams(); i != e; ++i) {
1842 nullptr, fpt->getParamType(i),
nullptr,
1845 params.push_back(parm);
1848 tempFunc->setParams(params);
1873 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(canonicalGd.
getDecl())) {
1876 "getMangledName: C++ constructor without variants");
1885 auto result = manglings.insert(std::make_pair(mangledName, gd));
1886 return mangledDeclNames[canonicalGd] = result.first->first();
1890 assert(!d->
getInit() &&
"Cannot emit definite definitions here!");
1898 if (gv && !mlir::cast<cir::GlobalOp>(gv).isDeclaration())
1914 if (langOpts.EmitAllDecls)
1917 const auto *vd = dyn_cast<VarDecl>(global);
1919 ((codeGenOpts.KeepPersistentStorageVariables &&
1920 (vd->getStorageDuration() ==
SD_Static ||
1921 vd->getStorageDuration() ==
SD_Thread)) ||
1922 (codeGenOpts.KeepStaticConsts && vd->getStorageDuration() ==
SD_Static &&
1923 vd->getType().isConstQualified())))
1936 if (langOpts.OpenMP >= 50 && !langOpts.OpenMPSimd) {
1937 std::optional<OMPDeclareTargetDeclAttr *> activeAttr =
1938 OMPDeclareTargetDeclAttr::getActiveAttr(global);
1939 if (!activeAttr || (*activeAttr)->getLevel() != (
unsigned)-1)
1943 const auto *fd = dyn_cast<FunctionDecl>(global);
1950 if (fd->hasAttr<TargetVersionAttr>() && !fd->isMultiVersion())
1952 if (langOpts.SYCLIsDevice) {
1953 errorNYI(fd->getSourceRange(),
"mayBeEmittedEagerly: SYCL");
1957 const auto *vd = dyn_cast<VarDecl>(global);
1959 if (astContext.getInlineVariableDefinitionKind(vd) ==
1967 if (langOpts.OpenMP && langOpts.OpenMPUseTLS &&
1968 astContext.getTargetInfo().isTLSSupported() &&
isa<VarDecl>(global) &&
1970 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(global))
1973 assert((fd || vd) &&
1974 "Only FunctionDecl and VarDecl should hit this path so far.");
1979 cir::CIRGlobalValueInterface gv) {
1980 if (gv.hasLocalLinkage())
1983 if (!gv.hasDefaultVisibility() && !gv.hasExternalWeakLinkage())
1991 const llvm::Triple &tt = cgm.
getTriple();
1993 if (tt.isOSCygMing()) {
2002 cgm.
errorNYI(
"shouldAssumeDSOLocal: MinGW");
2008 if (tt.isOSBinFormatCOFF() && gv.hasExternalWeakLinkage())
2016 if (tt.isOSBinFormatCOFF() || (tt.isOSWindows() && tt.isOSBinFormatMachO()))
2020 if (!tt.isOSBinFormatELF())
2025 if (rm != llvm::Reloc::Static && !lOpts.PIE) {
2033 return !(lOpts.SemanticInterposition || lOpts.HalfNoSemanticInterposition);
2037 if (!gv.isDeclarationForLinker())
2043 if (rm == llvm::Reloc::PIC_ && gv.hasExternalWeakLinkage())
2050 if (cgOpts.DirectAccessExternalData) {
2056 if (
auto globalOp = dyn_cast<cir::GlobalOp>(gv.getOperation())) {
2089 if (
auto globalValue = dyn_cast<cir::CIRGlobalValueInterface>(op))
2109 return cir::TLS_Model::GeneralDynamic;
2111 return cir::TLS_Model::LocalDynamic;
2113 return cir::TLS_Model::InitialExec;
2115 return cir::TLS_Model::LocalExec;
2117 llvm_unreachable(
"Invalid TLS model!");
2121 assert(d.
getTLSKind() &&
"setting TLS mode on non-TLS var!");
2126 if (d.
getAttr<TLSModelAttr>())
2130 global.setTlsModel(tlm);
2135 cir::FuncOp func,
bool isThunk) {
2137 cir::CallingConv callingConv;
2138 cir::SideEffect sideEffect;
2145 mlir::NamedAttrList pal{};
2163 bool isIncompleteFunction,
2169 if (!isIncompleteFunction)
2171 getTypes().arrangeGlobalDeclaration(globalDecl),
2187 if (fd->isInlineBuiltinDeclaration()) {
2189 bool hasBody = fd->
hasBody(fdBody);
2191 assert(hasBody &&
"Inline builtin declarations should always have an "
2202 std::optional<cir::InlineKind> existingInlineKind = f.getInlineKind();
2204 existingInlineKind && *existingInlineKind == cir::InlineKind::NoInline;
2205 bool isAlwaysInline = existingInlineKind &&
2206 *existingInlineKind == cir::InlineKind::AlwaysInline;
2210 if (!isAlwaysInline &&
2215 f.setInlineKind(cir::InlineKind::NoInline);
2230 if (
decl->hasAttr<NoInlineAttr>() && !isAlwaysInline) {
2232 f.setInlineKind(cir::InlineKind::NoInline);
2233 }
else if (
decl->hasAttr<AlwaysInlineAttr>() && !isNoInline) {
2236 f.setInlineKind(cir::InlineKind::AlwaysInline);
2240 if (!isAlwaysInline) {
2241 f.setInlineKind(cir::InlineKind::NoInline);
2247 if (
auto *fd = dyn_cast<FunctionDecl>(
decl)) {
2252 auto checkRedeclForInline = [](
const FunctionDecl *redecl) {
2253 return redecl->isInlineSpecified();
2255 if (any_of(
decl->redecls(), checkRedeclForInline))
2260 return any_of(pattern->
redecls(), checkRedeclForInline);
2262 if (checkForInline(fd)) {
2263 f.setInlineKind(cir::InlineKind::InlineHint);
2264 }
else if (codeGenOpts.getInlining() ==
2266 !fd->isInlined() && !isAlwaysInline) {
2267 f.setInlineKind(cir::InlineKind::NoInline);
2276 StringRef mangledName, mlir::Type funcType,
GlobalDecl gd,
bool forVTable,
2278 mlir::ArrayAttr extraAttrs) {
2287 if (
const auto *fd = cast_or_null<FunctionDecl>(d)) {
2289 if (
getLangOpts().OpenMPIsTargetDevice && fd->isDefined() && !dontDefer &&
2292 "getOrCreateCIRFunction: OpenMP target function");
2296 if (fd->isMultiVersion())
2297 errorNYI(fd->getSourceRange(),
"getOrCreateCIRFunction: multi-version");
2303 assert(mlir::isa<cir::FuncOp>(entry));
2308 if (d && !d->
hasAttr<DLLImportAttr>() && !d->
hasAttr<DLLExportAttr>()) {
2316 if (isForDefinition && fn && !fn.isDeclaration()) {
2319 if (fn && fn.getFunctionType() == funcType) {
2323 if (!isForDefinition) {
2331 auto *funcDecl = llvm::cast_or_null<FunctionDecl>(gd.
getDecl());
2332 bool invalidLoc = !funcDecl ||
2333 funcDecl->getSourceRange().getBegin().isInvalid() ||
2334 funcDecl->getSourceRange().getEnd().isInvalid();
2336 invalidLoc ? theModule->getLoc() :
getLoc(funcDecl->getSourceRange()),
2337 mangledName, mlir::cast<cir::FuncType>(funcType), funcDecl);
2348 auto symbolOp = mlir::cast<mlir::SymbolOpInterface>(entry);
2356 if (symbolOp.getSymbolUses(symbolOp->getParentOp()))
2370 assert(funcOp.getFunctionType() == funcType);
2377 if (isa_and_nonnull<CXXDestructorDecl>(d) &&
2407 fd = fd->getPreviousDecl()) {
2409 if (fd->doesThisDeclarationHaveABody()) {
2422 cir::FuncType funcType,
2426 mlir::OpBuilder::InsertionGuard guard(builder);
2434 builder.setInsertionPoint(cgf->
curFn);
2436 func = cir::FuncOp::create(builder, loc, name, funcType);
2441 func.setNoProto(
true);
2443 assert(func.isDeclaration() &&
"expected empty body");
2447 func.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
2449 mlir::SymbolTable::setSymbolVisibility(
2450 func, mlir::SymbolTable::Visibility::Private);
2458 theModule.push_back(func);
2463 for (
const auto *
attr :
2477 fnOp.setBuiltin(
true);
2483 return cir::CtorKind::Default;
2485 return cir::CtorKind::Copy;
2487 return cir::CtorKind::Move;
2488 return cir::CtorKind::Custom;
2493 return cir::AssignKind::Copy;
2495 return cir::AssignKind::Move;
2496 llvm_unreachable(
"not a copy or move assignment operator");
2504 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(funcDecl)) {
2505 auto cxxDtor = cir::CXXDtorAttr::get(
2508 funcOp.setCxxSpecialMemberAttr(cxxDtor);
2512 if (
const auto *ctor = dyn_cast<CXXConstructorDecl>(funcDecl)) {
2514 auto cxxCtor = cir::CXXCtorAttr::get(
2516 kind, ctor->isTrivial());
2517 funcOp.setCxxSpecialMemberAttr(cxxCtor);
2521 const auto *method = dyn_cast<CXXMethodDecl>(funcDecl);
2522 if (method && (method->isCopyAssignmentOperator() ||
2523 method->isMoveAssignmentOperator())) {
2525 auto cxxAssign = cir::CXXAssignAttr::get(
2527 assignKind, method->isTrivial());
2528 funcOp.setCxxSpecialMemberAttr(cxxAssign);
2534 cir::FuncOp funcOp, StringRef name) {
2549 StringRef name, mlir::ArrayAttr,
2551 bool assumeConvergent) {
2552 if (assumeConvergent)
2553 errorNYI(
"createRuntimeFunction: assumeConvergent");
2563 entry.setDSOLocal(
true);
2569mlir::SymbolTable::Visibility
2573 if (op.isDeclaration())
2574 return mlir::SymbolTable::Visibility::Private;
2578mlir::SymbolTable::Visibility
2581 case cir::GlobalLinkageKind::InternalLinkage:
2582 case cir::GlobalLinkageKind::PrivateLinkage:
2583 return mlir::SymbolTable::Visibility::Private;
2584 case cir::GlobalLinkageKind::ExternalLinkage:
2585 case cir::GlobalLinkageKind::ExternalWeakLinkage:
2586 case cir::GlobalLinkageKind::LinkOnceODRLinkage:
2587 case cir::GlobalLinkageKind::AvailableExternallyLinkage:
2588 case cir::GlobalLinkageKind::CommonLinkage:
2589 case cir::GlobalLinkageKind::WeakAnyLinkage:
2590 case cir::GlobalLinkageKind::WeakODRLinkage:
2591 return mlir::SymbolTable::Visibility::Public;
2593 llvm::errs() <<
"visibility not implemented for '"
2594 << stringifyGlobalLinkageKind(glk) <<
"'\n";
2595 assert(0 &&
"not implemented");
2598 llvm_unreachable(
"linkage should be handled above!");
2602 clang::VisibilityAttr::VisibilityType visibility) {
2603 switch (visibility) {
2604 case clang::VisibilityAttr::VisibilityType::Default:
2605 return cir::VisibilityKind::Default;
2606 case clang::VisibilityAttr::VisibilityType::Hidden:
2607 return cir::VisibilityKind::Hidden;
2608 case clang::VisibilityAttr::VisibilityType::Protected:
2609 return cir::VisibilityKind::Protected;
2611 llvm_unreachable(
"unexpected visibility value");
2616 const clang::VisibilityAttr *va =
decl->getAttr<clang::VisibilityAttr>();
2617 cir::VisibilityAttr cirVisibility =
2620 cirVisibility = cir::VisibilityAttr::get(
2624 return cirVisibility;
2629 applyReplacements();
2631 theModule->setAttr(cir::CIRDialect::getModuleLevelAsmAttrName(),
2632 builder.getArrayAttr(globalScopeAsm));
2640 cir::FuncOp aliasee,
2641 cir::GlobalLinkageKind linkage) {
2643 auto *aliasFD = dyn_cast<FunctionDecl>(aliasGD.
getDecl());
2644 assert(aliasFD &&
"expected FunctionDecl");
2655 mangledName, fnType, aliasFD);
2656 alias.setAliasee(aliasee.getName());
2657 alias.setLinkage(linkage);
2661 mlir::SymbolTable::setSymbolVisibility(
2662 alias, mlir::SymbolTable::Visibility::Private);
2669 errorNYI(aliasFD->getSourceRange(),
"emitAliasForGlobal: previous uses");
2679 return genTypes.convertType(
type);
2686 return mlir::verify(theModule).succeeded();
2695 return builder.getConstNullPtrAttr(builder.getUInt8PtrTy());
2698 langOpts.ObjCRuntime.isGNUFamily()) {
2699 errorNYI(loc,
"getAddrOfRTTIDescriptor: Objc PtrType & Objc RT GUN");
2709 llvm::iterator_range<CastExpr::path_const_iterator> path) {
2716 assert(!base->isVirtual() &&
"Should not see virtual bases here!");
2721 const auto *baseDecl = base->getType()->castAsCXXRecordDecl();
2733 llvm::StringRef feature) {
2734 unsigned diagID = diags.getCustomDiagID(
2736 return diags.Report(loc, diagID) << feature;
2740 llvm::StringRef feature) {
2752 "cannot compile this %0 yet");
2753 diags.Report(astContext.getFullLoc(
s->getBeginLoc()), diagId)
2754 <<
type <<
s->getSourceRange();
2760 "cannot compile this %0 yet");
2761 diags.Report(astContext.getFullLoc(d->
getLocation()), diagId) <<
type;
2765 cir::LabelOp label) {
2766 [[maybe_unused]]
auto result =
2768 assert(result.second &&
2769 "attempting to map a blockaddress info that is already mapped");
2774 assert(result.second &&
2775 "attempting to map a blockaddress operation that is already mapped");
2779 cir::LabelOp label) {
2781 assert(result.second &&
2782 "attempting to map a blockaddress operation that is already mapped");
2786 cir::LabelOp newLabel) {
2789 "trying to update a blockaddress not previously mapped");
2790 assert(!it->second &&
"blockaddress already has a resolved label");
2792 it->second = newLabel;
Defines the clang::ASTContext interface.
static bool shouldAssumeDSOLocal(const CIRGenModule &cgm, cir::CIRGlobalValueInterface gv)
static cir::AssignKind getAssignKindFromDecl(const CXXMethodDecl *method)
static FunctionDecl * createOpenACCBindTempFunction(ASTContext &ctx, const IdentifierInfo *bindName, const FunctionDecl *protoFunc)
static bool shouldBeInCOMDAT(CIRGenModule &cgm, const Decl &d)
static void setWindowsItaniumDLLImport(CIRGenModule &cgm, bool isLocal, cir::FuncOp funcOp, StringRef name)
static std::string getMangledNameImpl(CIRGenModule &cgm, GlobalDecl gd, const NamedDecl *nd)
static cir::GlobalOp generateStringLiteral(mlir::Location loc, mlir::TypedAttr c, cir::GlobalLinkageKind lt, CIRGenModule &cgm, StringRef globalName, CharUnits alignment)
static CIRGenCXXABI * createCXXABI(CIRGenModule &cgm)
static bool isVarDeclStrongDefinition(const ASTContext &astContext, CIRGenModule &cgm, const VarDecl *vd, bool noCommon)
static void setLinkageForGV(cir::GlobalOp &gv, const NamedDecl *nd)
static cir::CtorKind getCtorKindFromDecl(const CXXConstructorDecl *ctor)
This file defines OpenACC nodes for declarative directives.
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
Defines the SourceManager interface.
__device__ __2f16 float __ockl_bool s
__device__ __2f16 float c
cir::PointerType getPointerTo(mlir::Type ty)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
@ Strong
Strong definition.
@ WeakUnknown
Weak for now, might become strong later in this TU.
bool DeclMustBeEmitted(const Decl *D)
Determines if the decl can be CodeGen'ed or deserialized from PCH lazily, only when used; this is onl...
void Deallocate(void *Ptr) const
GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const
bool isAlignmentRequired(const Type *T) const
Determine if the alignment the type has was required using an alignment attribute.
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
GVALinkage GetGVALinkageForVariable(const VarDecl *VD) const
unsigned getTypeAlignIfKnown(QualType T, bool NeedsPreferredAlignment=false) const
Return the alignment of a type, in bits, or 0 if the type is incomplete and we cannot determine the a...
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
const TargetInfo & getTargetInfo() const
TargetCXXABI::Kind getCXXABIKind() const
Return the C++ ABI kind that should be used.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Implements C++ ABI-specific code generation functions.
virtual mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty)=0
virtual void emitCXXConstructors(const clang::CXXConstructorDecl *d)=0
Emit constructor variants required by this ABI.
virtual void emitCXXDestructors(const clang::CXXDestructorDecl *d)=0
Emit dtor variants required by this ABI.
clang::MangleContext & getMangleContext()
Gets the mangle context.
virtual cir::GlobalLinkageKind getCXXDestructorLinkage(GVALinkage linkage, const CXXDestructorDecl *dtor, CXXDtorType dt) const
cir::FuncOp generateCode(clang::GlobalDecl gd, cir::FuncOp fn, cir::FuncType funcType)
void emitVariablyModifiedType(QualType ty)
mlir::Operation * curFn
The current function or global initializer that is generated code for.
This class organizes the cross-function state that is used while generating CIR code.
void updateResolvedBlockAddress(cir::BlockAddressOp op, cir::LabelOp newLabel)
void replaceUsesOfNonProtoTypeWithRealFunction(mlir::Operation *old, cir::FuncOp newFn)
This function is called when we implement a function with no prototype, e.g.
llvm::StringRef getMangledName(clang::GlobalDecl gd)
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *derivedClass, llvm::iterator_range< CastExpr::path_const_iterator > path)
void setGlobalVisibility(mlir::Operation *op, const NamedDecl *d) const
Set the visibility for the given global.
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
void emitDeferred()
Emit any needed decls for which code generation was deferred.
clang::ASTContext & getASTContext() const
cir::FuncOp getAddrOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
cir::FuncOp createRuntimeFunction(cir::FuncType ty, llvm::StringRef name, mlir::ArrayAttr={}, bool isLocal=false, bool assumeConvergent=false)
llvm::DenseMap< cir::BlockAddrInfoAttr, cir::LabelOp > blockAddressInfoToLabel
Map BlockAddrInfoAttr (function name, label name) to the corresponding CIR LabelOp.
void emitTopLevelDecl(clang::Decl *decl)
void emitOMPDeclareMapper(const OMPDeclareMapperDecl *d)
void addReplacement(llvm::StringRef name, mlir::Operation *op)
mlir::Type convertType(clang::QualType type)
bool shouldEmitRTTI(bool forEH=false)
cir::GlobalOp getGlobalForStringLiteral(const StringLiteral *s, llvm::StringRef name=".str")
Return a global symbol reference to a constant array for the given string literal.
void emitOMPCapturedExpr(const OMPCapturedExprDecl *d)
void mapUnresolvedBlockAddress(cir::BlockAddressOp op)
bool mustBeEmitted(const clang::ValueDecl *d)
Determine whether the definition must be emitted; if this returns false, the definition can be emitte...
void emitGlobalOpenACCDeclareDecl(const clang::OpenACCDeclareDecl *cd)
mlir::IntegerAttr getSize(CharUnits size)
CIRGenBuilderTy & getBuilder()
void setDSOLocal(mlir::Operation *op) const
std::string getUniqueGlobalName(const std::string &baseName)
std::pair< cir::FuncType, cir::FuncOp > getAddrAndTypeOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
void setGVProperties(mlir::Operation *op, const NamedDecl *d) const
Set visibility, dllimport/dllexport and dso_local.
cir::GlobalOp getOrCreateCIRGlobal(llvm::StringRef mangledName, mlir::Type ty, LangAS langAS, const VarDecl *d, ForDefinition_t isForDefinition)
If the specified mangled name is not in the module, create and return an mlir::GlobalOp value.
cir::FuncOp createCIRBuiltinFunction(mlir::Location loc, llvm::StringRef name, cir::FuncType ty, const clang::FunctionDecl *fd)
Create a CIR function with builtin attribute set.
void emitGlobalOpenACCRoutineDecl(const clang::OpenACCRoutineDecl *cd)
clang::CharUnits getClassPointerAlignment(const clang::CXXRecordDecl *rd)
Return the best known alignment for an unknown pointer to a particular class.
void handleCXXStaticMemberVarInstantiation(VarDecl *vd)
Tell the consumer that this variable has been instantiated.
void emitOMPRequiresDecl(const OMPRequiresDecl *d)
void emitGlobalDefinition(clang::GlobalDecl gd, mlir::Operation *op=nullptr)
void mapResolvedBlockAddress(cir::BlockAddressOp op, cir::LabelOp)
clang::DiagnosticsEngine & getDiags() const
mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty, bool forEH=false)
Get the address of the RTTI descriptor for the given type.
clang::CharUnits getNaturalTypeAlignment(clang::QualType t, LValueBaseInfo *baseInfo)
FIXME: this could likely be a common helper and not necessarily related with codegen.
void setFunctionAttributes(GlobalDecl gd, cir::FuncOp f, bool isIncompleteFunction, bool isThunk)
Set function attributes for a function declaration.
static mlir::SymbolTable::Visibility getMLIRVisibilityFromCIRLinkage(cir::GlobalLinkageKind GLK)
const clang::TargetInfo & getTarget() const
void setCIRFunctionAttributes(GlobalDecl gd, const CIRGenFunctionInfo &info, cir::FuncOp func, bool isThunk)
Set the CIR function attributes (Sext, zext, etc).
const llvm::Triple & getTriple() const
static mlir::SymbolTable::Visibility getMLIRVisibility(Visibility v)
void emitTentativeDefinition(const VarDecl *d)
cir::GlobalOp createOrReplaceCXXRuntimeVariable(mlir::Location loc, llvm::StringRef name, mlir::Type ty, cir::GlobalLinkageKind linkage, clang::CharUnits alignment)
Will return a global variable of the given type.
void emitOMPAllocateDecl(const OMPAllocateDecl *d)
void error(SourceLocation loc, llvm::StringRef error)
Emit a general error that something can't be done.
void emitGlobalDecl(const clang::GlobalDecl &d)
Helper for emitDeferred to apply actual codegen.
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::ArrayAttr extraAttrs={})
void emitGlobalVarDefinition(const clang::VarDecl *vd, bool isTentative=false)
void setTLSMode(mlir::Operation *op, const VarDecl &d)
Set TLS mode for the given operation based on the given variable declaration.
cir::FuncOp getAddrOfFunction(clang::GlobalDecl gd, mlir::Type funcType=nullptr, bool forVTable=false, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
Return the address of the given function.
void emitAliasForGlobal(llvm::StringRef mangledName, mlir::Operation *op, GlobalDecl aliasGD, cir::FuncOp aliasee, cir::GlobalLinkageKind linkage)
mlir::Value emitMemberPointerConstant(const UnaryOperator *e)
void emitGlobalOpenACCDecl(const clang::OpenACCConstructDecl *cd)
bool verifyModule() const
void emitExplicitCastExprType(const ExplicitCastExpr *e, CIRGenFunction *cgf=nullptr)
Emit type info if type of an expression is a variably modified type.
std::map< llvm::StringRef, clang::GlobalDecl > deferredDecls
This contains all the decls which have definitions but which are deferred for emission and therefore ...
void errorUnsupported(const Stmt *s, llvm::StringRef type)
Print out an error that codegen doesn't support the specified stmt yet.
mlir::Value getAddrOfGlobalVar(const VarDecl *d, mlir::Type ty={}, ForDefinition_t isForDefinition=NotForDefinition)
Return the mlir::Value for the address of the given global variable.
static void setInitializer(cir::GlobalOp &op, mlir::Attribute value)
cir::GlobalViewAttr getAddrOfGlobalVarAttr(const VarDecl *d)
Return the mlir::GlobalViewAttr for the address of the given global.
void addGlobalCtor(cir::FuncOp ctor, std::optional< int > priority=std::nullopt)
Add a global constructor or destructor to the module.
cir::GlobalLinkageKind getFunctionLinkage(GlobalDecl gd)
void updateCompletedType(const clang::TagDecl *td)
const clang::CodeGenOptions & getCodeGenOpts() const
const clang::LangOptions & getLangOpts() const
void emitOpenACCRoutineDecl(const clang::FunctionDecl *funcDecl, cir::FuncOp func, SourceLocation pragmaLoc, ArrayRef< const OpenACCClause * > clauses)
cir::TLS_Model getDefaultCIRTLSModel() const
Get TLS mode from CodeGenOptions.
void addGlobalDtor(cir::FuncOp dtor, std::optional< int > priority=std::nullopt)
Add a function to the list that will be called when the module is unloaded.
void addDeferredDeclToEmit(clang::GlobalDecl GD)
cir::FuncOp createCIRFunction(mlir::Location loc, llvm::StringRef name, cir::FuncType funcType, const clang::FunctionDecl *funcDecl)
const TargetCIRGenInfo & getTargetCIRGenInfo()
void emitCXXGlobalVarDeclInitFunc(const VarDecl *vd, cir::GlobalOp addr, bool performInit)
void setGVPropertiesAux(mlir::Operation *op, const NamedDecl *d) const
LangAS getLangTempAllocaAddressSpace() const
Returns the address space for temporary allocations in the language.
llvm::DenseSet< cir::BlockAddressOp > unresolvedBlockAddressToLabel
Track CIR BlockAddressOps that cannot be resolved immediately because their LabelOp has not yet been ...
mlir::Location getLoc(clang::SourceLocation cLoc)
Helpers to convert the presumed location of Clang's SourceLocation to an MLIR Location.
llvm::DenseMap< mlir::Attribute, cir::GlobalOp > constantStringMap
mlir::Operation * lastGlobalOp
static cir::VisibilityKind getGlobalVisibilityKindFromClangVisibility(clang::VisibilityAttr::VisibilityType visibility)
llvm::StringMap< unsigned > cgGlobalNames
void setCXXSpecialMemberAttr(cir::FuncOp funcOp, const clang::FunctionDecl *funcDecl)
Mark the function as a special member (e.g. constructor, destructor)
mlir::Operation * getGlobalValue(llvm::StringRef ref)
void emitOMPDeclareReduction(const OMPDeclareReductionDecl *d)
mlir::ModuleOp getModule() const
bool supportsCOMDAT() const
cir::GlobalLinkageKind getCIRLinkageForDeclarator(const DeclaratorDecl *dd, GVALinkage linkage, bool isConstantVariable)
mlir::MLIRContext & getMLIRContext()
mlir::Operation * getAddrOfGlobal(clang::GlobalDecl gd, ForDefinition_t isForDefinition=NotForDefinition)
static cir::GlobalOp createGlobalOp(CIRGenModule &cgm, mlir::Location loc, llvm::StringRef name, mlir::Type t, bool isConstant=false, mlir::Operation *insertPoint=nullptr)
void maybeSetTrivialComdat(const clang::Decl &d, mlir::Operation *op)
CIRGenCXXABI & getCXXABI() const
cir::GlobalViewAttr getAddrOfConstantStringFromLiteral(const StringLiteral *s, llvm::StringRef name=".str")
Return a global symbol reference to a constant array for the given string literal.
llvm::MapVector< cir::BlockAddressOp, cir::LabelOp > blockAddressToLabel
Map CIR BlockAddressOps directly to their resolved LabelOps.
void emitDeclContext(const DeclContext *dc)
void emitGlobal(clang::GlobalDecl gd)
Emit code for a single global function or variable declaration.
cir::LabelOp lookupBlockAddressInfo(cir::BlockAddrInfoAttr blockInfo)
bool mayBeEmittedEagerly(const clang::ValueDecl *d)
Determine whether the definition can be emitted eagerly, or should be delayed until the end of the tr...
cir::GlobalLinkageKind getCIRLinkageVarDefinition(const VarDecl *vd, bool isConstant)
void mapBlockAddress(cir::BlockAddrInfoAttr blockInfo, cir::LabelOp label)
void setCIRFunctionAttributesForDefinition(const clang::FunctionDecl *fd, cir::FuncOp f)
Set extra attributes (inline, etc.) for a function.
std::string getOpenACCBindMangledName(const IdentifierInfo *bindName, const FunctionDecl *attachedFunction)
void emitGlobalFunctionDefinition(clang::GlobalDecl gd, mlir::Operation *op)
CIRGenVTables & getVTables()
void setFunctionLinkage(GlobalDecl gd, cir::FuncOp f)
void constructAttributeList(llvm::StringRef name, const CIRGenFunctionInfo &info, CIRGenCalleeInfo calleeInfo, mlir::NamedAttrList &attrs, cir::CallingConv &callingConv, cir::SideEffect &sideEffect, bool attrOnCallSite, bool isThunk)
Get the CIR attributes and calling convention to use for a particular function type.
std::vector< clang::GlobalDecl > deferredDeclsToEmit
void emitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *d)
void emitOMPGroupPrivateDecl(const OMPGroupPrivateDecl *d)
mlir::Attribute getConstantArrayFromStringLiteral(const StringLiteral *e)
Return a constant array for the given string.
cir::VisibilityAttr getGlobalVisibilityAttrFromDecl(const Decl *decl)
void setCommonAttributes(GlobalDecl gd, mlir::Operation *op)
Set attributes which are common to any form of a global definition (alias, Objective-C method,...
const CIRGenFunctionInfo & arrangeGlobalDeclaration(GlobalDecl gd)
const CIRGenFunctionInfo & arrangeCXXMethodDeclaration(const clang::CXXMethodDecl *md)
C++ methods have some special rules and also have implicit parameters.
const CIRGenFunctionInfo & arrangeCXXStructorDeclaration(clang::GlobalDecl gd)
cir::FuncType getFunctionType(const CIRGenFunctionInfo &info)
Get the CIR function type for.
mlir::Type convertTypeForMem(clang::QualType, bool forBitField=false)
Convert type T into an mlir::Type.
void emitThunks(GlobalDecl gd)
Emit the associated thunks for the given global decl.
virtual cir::TargetAddressSpaceAttr getCIRAllocaAddressSpace() const
Get the address space for alloca.
Represents a base class of a C++ class.
Represents a C++ constructor within a class.
bool isMoveConstructor(unsigned &TypeQuals) const
Determine whether this constructor is a move constructor (C++11 [class.copy]p3), which can be used to...
bool isCopyConstructor(unsigned &TypeQuals) const
Whether this constructor is a copy constructor (C++ [class.copy]p2, which can be used to copy the cla...
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
Represents a static or instance method of a struct/union/class.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
Represents a C++ struct/union/class.
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
bool hasDefinition() const
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
llvm::Reloc::Model RelocationModel
The name of the relocation model to use.
Represents the canonical version of C arrays with a specified constant size.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Decl - This represents one declaration (or definition), e.g.
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
static DeclContext * castToDeclContext(const Decl *)
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Represents a ValueDecl that came out of a declarator.
A little helper class used to produce diagnostics.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
ExplicitCastExpr - An explicit cast written in the source code.
This represents one expression.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Represents a member of a struct/union/class.
Cached information about one file (either on disk or in the virtual file system).
StringRef tryGetRealPathName() const
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Represents a function declaration or definition.
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin=false, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=ConstexprSpecKind::Unspecified, const AssociatedConstraint &TrailingRequiresClause={})
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
FunctionType - C99 6.7.5.3 - Function Declarators.
CallingConv getCallConv() const
GlobalDecl - represents a global declaration.
GlobalDecl getCanonicalDecl() const
KernelReferenceKind getKernelReferenceKind() const
GlobalDecl getWithDecl(const Decl *D)
CXXDtorType getDtorType() const
const Decl * getDecl() const
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
void setLinkage(Linkage L)
Linkage getLinkage() const
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
bool shouldMangleDeclName(const NamedDecl *D)
void mangleName(GlobalDecl GD, raw_ostream &)
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
LinkageInfo getLinkageAndVisibility() const
Determines the linkage and visibility of this entity.
Represents a parameter to a function.
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
A (possibly-)qualified type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
bool isConstQualified() const
Determine whether this type is const-qualified.
bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor, bool ExcludeDtor)
bool hasUnaligned() const
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
StringLiteral - This represents a string literal expression, e.g.
unsigned getLength() const
uint32_t getCodeUnit(size_t i) const
StringRef getString() const
unsigned getCharByteWidth() const
Represents the declaration of a struct/union/class/enum.
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() const
bool isReferenceType() const
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isObjCObjectPointerType() const
const T * getAs() const
Member-template getAs<specific type>'.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
TLSKind getTLSKind() const
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool hasFlexibleArrayInit(const ASTContext &Ctx) const
Whether this variable has a flexible array member initialized with one or more elements.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const
Would the destruction of this variable have any effect, and if so, what kind?
const Expr * getInit() const
bool hasExternalStorage() const
Returns true if a variable has extern or private_extern storage.
@ TLS_Dynamic
TLS with a dynamic initializer.
@ TLS_None
Not a TLS variable.
@ Definition
This declaration is definitely a definition.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
TemplateSpecializationKind getTemplateSpecializationKind() const
If this variable is an instantiation of a variable template or a static data member of a class templa...
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
static bool isWeakForLinker(GlobalLinkageKind linkage)
Whether the definition of this global may be replaced at link time.
@ AttributedType
The l-value was considered opaque, so the alignment was determined from a type, but that type was an ...
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
CIRGenCXXABI * CreateCIRGenItaniumCXXABI(CIRGenModule &cgm)
Creates and Itanium-family ABI.
std::unique_ptr< TargetCIRGenInfo > createX8664TargetCIRGenInfo(CIRGenTypes &cgt)
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, FieldDecl > fieldDecl
Matches field declarations.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
GVALinkage
A more specific kind of linkage than enum Linkage.
@ GVA_AvailableExternally
@ SD_Thread
Thread storage duration.
@ SD_Static
Static storage duration.
@ Dtor_Complete
Complete object dtor.
LangAS
Defines the address space values used by the address space qualifier of QualType.
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_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
U cast(CodeGen::Address addr)
bool isExternallyVisible(Linkage L)
static bool globalCtorLexOrder()
static bool alignCXXRecordDecl()
static bool opFuncArmNewAttr()
static bool getRuntimeFunctionDecl()
static bool weakRefReference()
static bool opFuncOptNoneAttr()
static bool opGlobalSection()
static bool addressSpace()
static bool opFuncMinSizeAttr()
static bool opGlobalUnnamedAddr()
static bool opGlobalThreadLocal()
static bool sourceLanguageCases()
static bool opFuncAstDeclAttr()
static bool opFuncNoDuplicateAttr()
static bool opGlobalUsedOrCompilerUsed()
static bool virtualMethodAttr()
static bool stackProtector()
static bool moduleNameHash()
static bool opGlobalVisibility()
static bool setDLLStorageClass()
static bool opFuncUnwindTablesAttr()
static bool opFuncParameterAttributes()
static bool targetCIRGenInfoArch()
static bool opFuncExtraAttrs()
static bool opFuncNakedAttr()
static bool opFuncSection()
static bool attributeNoBuiltin()
static bool opGlobalDLLImportExport()
static bool opGlobalPartition()
static bool opGlobalWeakRef()
static bool setTargetAttributes()
static bool deferredCXXGlobalInit()
static bool opFuncOperandBundles()
static bool opFuncCallingConv()
static bool globalCtorAssociatedData()
static bool defaultVisibility()
static bool opFuncColdHotAttr()
static bool opFuncExceptions()
static bool opFuncArmStreamingAttr()
static bool deferredVtables()
static bool cudaSupport()
static bool opFuncMaybeHandleStaticInExternC()
static bool generateDebugInfo()
static bool targetCIRGenInfoOS()
static bool opFuncCPUAndFeaturesAttributes()
static bool maybeHandleStaticInExternC()
static bool setLLVMFunctionFEnvAttributes()
cir::TargetAddressSpaceAttr cirAllocaAddressSpace
mlir::Type uCharTy
ClangIR char.
unsigned char SizeSizeInBytes
unsigned char PointerAlignInBytes
cir::PointerType allocaInt8PtrTy
void* in alloca address space
cir::PointerType uInt8PtrTy
cir::PointerType voidPtrTy
void* in address space 0
LangStandard - Information about the properties of a particular language standard.