29#include "mlir/IR/BuiltinOps.h"
30#include "mlir/IR/Location.h"
31#include "mlir/IR/MLIRContext.h"
32#include "mlir/IR/Verifier.h"
39 case TargetCXXABI::GenericItanium:
40 case TargetCXXABI::GenericAArch64:
41 case TargetCXXABI::AppleARM64:
44 case TargetCXXABI::Fuchsia:
45 case TargetCXXABI::GenericARM:
46 case TargetCXXABI::iOS:
47 case TargetCXXABI::WatchOS:
48 case TargetCXXABI::GenericMIPS:
49 case TargetCXXABI::WebAssembly:
50 case TargetCXXABI::XL:
51 case TargetCXXABI::Microsoft:
52 cgm.
errorNYI(
"C++ ABI kind not yet implemented");
56 llvm_unreachable(
"invalid C++ ABI kind");
59CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
63 : builder(mlirContext, *this), astContext(astContext),
64 langOpts(astContext.
getLangOpts()), codeGenOpts(cgo),
65 theModule{
mlir::ModuleOp::create(
mlir::UnknownLoc::get(&mlirContext))},
66 diags(diags), target(astContext.getTargetInfo()),
67 abi(
createCXXABI(*this)), genTypes(*this), vtables(*this) {
99 const unsigned charSize = astContext.getTargetInfo().getCharWidth();
103 const unsigned sizeTypeSize =
104 astContext.getTypeSize(astContext.getSignedSizeType());
105 SizeSizeInBytes = astContext.toCharUnitsFromBits(sizeTypeSize).getQuantity();
112 std::optional<cir::SourceLanguage> sourceLanguage = getCIRSourceLanguage();
115 cir::CIRDialect::getSourceLanguageAttrName(),
116 cir::SourceLanguageAttr::get(&mlirContext, *sourceLanguage));
117 theModule->setAttr(cir::CIRDialect::getTripleAttrName(),
118 builder.getStringAttr(
getTriple().str()));
120 if (cgo.OptimizationLevel > 0 || cgo.OptimizeSize > 0)
121 theModule->setAttr(cir::CIRDialect::getOptInfoAttrName(),
122 cir::OptInfoAttr::get(&mlirContext,
123 cgo.OptimizationLevel,
128 FileID mainFileId = astContext.getSourceManager().getMainFileID();
130 *astContext.getSourceManager().getFileEntryForID(mainFileId);
133 theModule.setSymName(path);
134 theModule->setLoc(mlir::FileLineColLoc::get(&mlirContext, path,
150 auto &layout = astContext.getASTRecordLayout(rd);
155 return layout.getAlignment();
158 return layout.getNonVirtualAlignment();
172 if (
unsigned align = tt->getDecl()->getMaxAlignment()) {
175 return astContext.toCharUnitsFromBits(align);
181 t = astContext.getBaseElementType(t);
203 alignment = astContext.getTypeAlignInChars(t);
208 if (
unsigned maxAlign = astContext.getLangOpts().MaxTypeAlign) {
210 !astContext.isAlignmentRequired(t))
217 if (theTargetCIRGenInfo)
218 return *theTargetCIRGenInfo;
221 switch (triple.getArch()) {
228 case llvm::Triple::x86_64: {
229 switch (triple.getOS()) {
236 case llvm::Triple::Linux:
238 return *theTargetCIRGenInfo;
245 assert(cLoc.
isValid() &&
"expected valid source location");
249 return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
254 assert(cRange.
isValid() &&
"expected a valid source range");
257 mlir::Attribute metadata;
258 return mlir::FusedLoc::get({begin, end}, metadata, builder.getContext());
267 false, isForDefinition);
301 assert(op &&
"expected a valid global op");
309 mlir::Operation *globalValueOp = op;
310 if (
auto gv = dyn_cast<cir::GetGlobalOp>(op))
312 mlir::SymbolTable::lookupSymbolIn(
getModule(), gv.getNameAttr());
314 if (
auto cirGlobalValue =
315 dyn_cast<cir::CIRGlobalValueInterface>(globalValueOp))
316 if (!cirGlobalValue.isDeclaration())
341 std::vector<GlobalDecl> curDeclsToEmit;
358 if (
const auto *cd = dyn_cast<clang::OpenACCConstructDecl>(gd.
getDecl())) {
365 if (
const auto *fd = dyn_cast<FunctionDecl>(global)) {
368 if (fd->hasAttr<AnnotateAttr>())
369 errorNYI(fd->getSourceRange(),
"deferredAnnotations");
370 if (!fd->doesThisDeclarationHaveABody()) {
371 if (!fd->doesDeclarationForceExternallyVisibleDefinition())
375 "function declaration that forces code gen");
380 assert(vd->isFileVarDecl() &&
"Cannot emit local var decl as global.");
382 !astContext.isMSStaticDataMemberInlineDefinition(vd)) {
386 if (astContext.getInlineVariableDefinitionKind(vd) ==
425 mlir::Operation *op) {
429 cir::FuncOp funcOp = dyn_cast_if_present<cir::FuncOp>(op);
430 if (!funcOp || funcOp.getFunctionType() != funcType) {
436 if (!funcOp.isDeclaration())
448 mlir::OpBuilder::InsertionGuard guard(builder);
453 setNonAliasAttributes(gd, funcOp);
456 auto getPriority = [
this](
const auto *
attr) ->
int {
460 return attr->DefaultPriority;
463 if (
const ConstructorAttr *ca = funcDecl->getAttr<ConstructorAttr>())
465 if (
const DestructorAttr *da = funcDecl->getAttr<DestructorAttr>())
468 if (funcDecl->getAttr<AnnotateAttr>())
469 errorNYI(funcDecl->getSourceRange(),
"deferredAnnotations");
474 std::optional<int> priority) {
483 ctor.setGlobalCtorPriority(priority);
488 std::optional<int> priority) {
489 if (codeGenOpts.RegisterGlobalDtorsWithAtExit &&
491 errorNYI(dtor.getLoc(),
"registerGlobalDtorsWithAtExit");
494 dtor.setGlobalDtorPriority(priority);
512 return mlir::SymbolTable::lookupSymbolIn(theModule, name);
516 mlir::Location loc, StringRef name,
517 mlir::Type t,
bool isConstant,
518 mlir::Operation *insertPoint) {
523 mlir::OpBuilder::InsertionGuard guard(builder);
529 builder.setInsertionPoint(insertPoint);
535 builder.setInsertionPointToStart(cgm.
getModule().getBody());
538 g = cir::GlobalOp::create(builder, loc, name, t, isConstant);
544 mlir::SymbolTable::setSymbolVisibility(
545 g, mlir::SymbolTable::Visibility::Private);
552 if (isa_and_nonnull<NamedDecl>(d))
558void CIRGenModule::setNonAliasAttributes(
GlobalDecl gd, mlir::Operation *op) {
569std::optional<cir::SourceLanguage> CIRGenModule::getCIRSourceLanguage()
const {
571 using CIRLang = cir::SourceLanguage;
576 if (opts.C99 || opts.C11 || opts.C17 || opts.C23 || opts.C2y ||
577 opts.LangStd == ClangStd::lang_c89 ||
578 opts.LangStd == ClangStd::lang_gnu89)
583 errorNYI(
"CIR does not yet support the given source language");
595 gv.
setLinkage(cir::GlobalLinkageKind::ExternalWeakLinkage);
614 LangAS langAS,
const VarDecl *d,
631 if (entry.getSymType() == ty)
640 if (isForDefinition && !entry.isDeclaration()) {
649 if (!isForDefinition)
659 entry.getOperation());
674 if (langOpts.OpenMP && !langOpts.OpenMPSimd)
677 gv.setAlignmentAttr(
getSize(astContext.getDeclAlign(d)));
681 astContext,
false,
false));
695 if (astContext.isMSStaticDataMemberInlineDefinition(d))
702 if (
getTriple().getArch() == llvm::Triple::xcore)
712 "external const declaration with initializer");
746 mlir::Type ptrTy = builder.getPointerTo(g.getSymType());
748 g.getSymNameAttr(), tlsAccess);
757 cir::PointerType ptrTy = builder.getPointerTo(globalOp.getSymType());
758 return builder.getGlobalViewAttr(ptrTy, globalOp);
771 bool isDefinitionAvailableExternally =
776 if (isDefinitionAvailableExternally &&
784 mlir::Attribute init;
785 bool needsGlobalCtor =
false;
786 bool needsGlobalDtor =
787 !isDefinitionAvailableExternally &&
792 std::optional<ConstantEmitter> emitter;
796 if (vd->
hasAttr<LoaderUninitializedAttr>()) {
799 }
else if (!initExpr) {
812 emitter.emplace(*
this);
813 mlir::Attribute initializer = emitter->tryEmitForInitializer(*initDecl);
823 if (!isDefinitionAvailableExternally)
824 needsGlobalCtor =
true;
838 if (mlir::isa<mlir::SymbolRefAttr>(init)) {
842 assert(mlir::isa<mlir::TypedAttr>(init) &&
"This should have a type");
843 auto typedInitAttr = mlir::cast<mlir::TypedAttr>(init);
844 initType = typedInitAttr.getType();
846 assert(!mlir::isa<mlir::NoneType>(initType) &&
"Should have a type by now");
852 if (!gv || gv.getSymType() != initType) {
859 if (vd->
hasAttr<AnnotateAttr>()) {
870 emitter->finalize(gv);
873 gv.setConstant((vd->
hasAttr<CUDAConstantAttr>() && langOpts.CUDAIsDevice) ||
874 (!needsGlobalCtor && !needsGlobalDtor &&
876 astContext,
true,
true)));
880 cir::GlobalLinkageKind linkage =
884 gv.setLinkage(linkage);
888 if (linkage == cir::GlobalLinkageKind::CommonLinkage) {
890 gv.setConstant(
false);
895 std::optional<mlir::Attribute> initializer = gv.getInitialValue();
896 if (initializer && !
getBuilder().isNullValue(*initializer))
897 gv.setLinkage(cir::GlobalLinkageKind::WeakAnyLinkage);
900 setNonAliasAttributes(vd, gv);
907 if (needsGlobalCtor || needsGlobalDtor)
912 mlir::Operation *op) {
914 if (
const auto *fd = dyn_cast<FunctionDecl>(
decl)) {
918 if (
const auto *method = dyn_cast<CXXMethodDecl>(
decl)) {
922 abi->emitCXXStructor(gd);
923 else if (fd->isMultiVersion())
924 errorNYI(method->getSourceRange(),
"multiversion functions");
928 if (method->isVirtual())
934 if (fd->isMultiVersion())
935 errorNYI(fd->getSourceRange(),
"multiversion functions");
940 if (
const auto *vd = dyn_cast<VarDecl>(
decl))
943 llvm_unreachable(
"Invalid argument to CIRGenModule::emitGlobalDefinition");
957 astContext.getAsConstantArrayType(e->
getType());
958 uint64_t finalSize = cat->getZExtSize();
959 str.resize(finalSize);
961 mlir::Type eltTy =
convertType(cat->getElementType());
962 return builder.getString(str, eltTy, finalSize);
966 "getConstantArrayFromStringLiteral: wide characters");
967 return mlir::Attribute();
978 if (d.
hasAttr<SelectAnyAttr>())
982 if (
auto *vd = dyn_cast<VarDecl>(&d))
997 llvm_unreachable(
"No such linkage");
1003 if (
auto globalOp = dyn_cast_or_null<cir::GlobalOp>(op)) {
1004 globalOp.setComdat(
true);
1007 funcOp.setComdat(
true);
1013 genTypes.updateCompletedType(td);
1017 replacements[name] = op;
1020void CIRGenModule::replacePointerTypeArgs(cir::FuncOp oldF, cir::FuncOp newF) {
1021 std::optional<mlir::SymbolTable::UseRange> optionalUseRange =
1022 oldF.getSymbolUses(theModule);
1023 if (!optionalUseRange)
1026 for (
const mlir::SymbolTable::SymbolUse &u : *optionalUseRange) {
1028 auto call = mlir::dyn_cast<cir::CallOp>(u.getUser());
1032 for (
const auto [argOp, fnArgType] :
1033 llvm::zip(call.getArgs(), newF.getFunctionType().getInputs())) {
1034 if (argOp.getType() == fnArgType)
1040 errorNYI(call.getLoc(),
"replace call with mismatched types");
1045void CIRGenModule::applyReplacements() {
1046 for (
auto &i : replacements) {
1047 StringRef mangledName = i.first();
1048 mlir::Operation *replacement = i.second;
1054 auto newF = dyn_cast<cir::FuncOp>(replacement);
1057 errorNYI(replacement->getLoc(),
"replacement is not a function");
1063 replacePointerTypeArgs(oldF, newF);
1066 if (oldF.replaceAllSymbolUses(newF.getSymNameAttr(), theModule).failed())
1067 llvm_unreachable(
"internal error, cannot RAUW symbol");
1069 newF->moveBefore(oldF);
1076 mlir::Location loc, StringRef name, mlir::Type ty,
1078 auto gv = mlir::dyn_cast_or_null<cir::GlobalOp>(
1079 mlir::SymbolTable::lookupSymbolIn(theModule, name));
1083 if (gv.getSymType() == ty)
1089 assert(gv.isDeclaration() &&
"Declaration has wrong type!");
1091 errorNYI(loc,
"createOrReplaceCXXRuntimeVariable: declaration exists with "
1102 mlir::SymbolTable::setSymbolVisibility(gv,
1106 !gv.hasAvailableExternallyLinkage()) {
1110 gv.setAlignmentAttr(
getSize(alignment));
1121 if ((noCommon || vd->
hasAttr<NoCommonAttr>()) && !vd->
hasAttr<CommonAttr>())
1132 if (vd->
hasAttr<SectionAttr>())
1138 if (vd->
hasAttr<PragmaClangBSSSectionAttr>() ||
1139 vd->
hasAttr<PragmaClangDataSectionAttr>() ||
1140 vd->
hasAttr<PragmaClangRelroSectionAttr>() ||
1141 vd->
hasAttr<PragmaClangRodataSectionAttr>())
1149 if (vd->
hasAttr<WeakImportAttr>())
1159 if (vd->
hasAttr<AlignedAttr>())
1166 for (
const FieldDecl *fd : rd->fields()) {
1167 if (fd->isBitField())
1169 if (fd->hasAttr<AlignedAttr>())
1194 return cir::GlobalLinkageKind::InternalLinkage;
1196 if (dd->
hasAttr<WeakAttr>()) {
1197 if (isConstantVariable)
1198 return cir::GlobalLinkageKind::WeakODRLinkage;
1199 return cir::GlobalLinkageKind::WeakAnyLinkage;
1204 return cir::GlobalLinkageKind::LinkOnceAnyLinkage;
1209 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
1223 return !astContext.getLangOpts().AppleKext
1224 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
1225 : cir::GlobalLinkageKind::InternalLinkage;
1239 return cir::GlobalLinkageKind::ExternalLinkage;
1242 return dd->
hasAttr<CUDAGlobalAttr>()
1243 ? cir::GlobalLinkageKind::ExternalLinkage
1244 : cir::GlobalLinkageKind::InternalLinkage;
1245 return cir::GlobalLinkageKind::WeakODRLinkage;
1253 return cir::GlobalLinkageKind::CommonLinkage;
1259 if (dd->
hasAttr<SelectAnyAttr>())
1260 return cir::GlobalLinkageKind::WeakODRLinkage;
1264 return cir::GlobalLinkageKind::ExternalLinkage;
1276 mlir::Operation *old, cir::FuncOp newFn) {
1278 auto oldFn = mlir::dyn_cast<cir::FuncOp>(old);
1286 if (oldFn->getAttrs().size() <= 1)
1288 "replaceUsesOfNonProtoTypeWithRealFunction: Attribute forwarding");
1291 newFn.setNoProto(oldFn.getNoProto());
1294 std::optional<mlir::SymbolTable::UseRange> symUses =
1295 oldFn.getSymbolUses(oldFn->getParentOp());
1296 for (
const mlir::SymbolTable::SymbolUse &use : symUses.value()) {
1297 mlir::OpBuilder::InsertionGuard guard(builder);
1299 if (
auto noProtoCallOp = mlir::dyn_cast<cir::CallOp>(use.getUser())) {
1300 builder.setInsertionPoint(noProtoCallOp);
1303 cir::CallOp realCallOp = builder.createCallOp(
1304 noProtoCallOp.getLoc(), newFn, noProtoCallOp.getOperands());
1307 noProtoCallOp.replaceAllUsesWith(realCallOp);
1308 noProtoCallOp.erase();
1309 }
else if (
auto getGlobalOp =
1310 mlir::dyn_cast<cir::GetGlobalOp>(use.getUser())) {
1312 getGlobalOp.getAddr().setType(
1313 cir::PointerType::get(newFn.getFunctionType()));
1316 "replaceUsesOfNonProtoTypeWithRealFunction: unexpected use");
1321cir::GlobalLinkageKind
1323 assert(!isConstant &&
"constant variables NYI");
1324 GVALinkage linkage = astContext.GetGVALinkageForVariable(vd);
1331 GVALinkage linkage = astContext.GetGVALinkageForFunction(d);
1333 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(d))
1342 StringRef globalName,
CharUnits alignment) {
1348 cgm, loc, globalName,
c.getType(), !cgm.
getLangOpts().WritableStrings);
1351 gv.setAlignmentAttr(cgm.
getSize(alignment));
1353 cir::GlobalLinkageKindAttr::get(cgm.
getBuilder().getContext(), lt));
1357 if (gv.isWeakForLinker()) {
1358 assert(cgm.
supportsCOMDAT() &&
"Only COFF uses weak string literals");
1361 cgm.
setDSOLocal(
static_cast<mlir::Operation *
>(gv));
1382 std::string result =
1385 assert(!mlir::SymbolTable::lookupSymbolIn(theModule, result));
1393 astContext.getAlignOfGlobalVarInChars(
s->getType(),
nullptr);
1401 if (!gv.getAlignment() ||
1402 uint64_t(alignment.
getQuantity()) > *gv.getAlignment())
1403 gv.setAlignmentAttr(
getSize(alignment));
1408 if (
getCXXABI().getMangleContext().shouldMangleStringLiteral(
s) &&
1411 "getGlobalForStringLiteral: mangle string literals");
1417 mlir::Location loc =
getLoc(
s->getSourceRange());
1418 auto typedC = llvm::cast<mlir::TypedAttr>(
c);
1420 cir::GlobalLinkageKind::PrivateLinkage, *
this,
1421 uniqueName, alignment);
1435 auto arrayTy = mlir::dyn_cast<cir::ArrayType>(gv.getSymType());
1436 assert(arrayTy &&
"String literal must be array");
1440 return builder.getGlobalViewAttr(ptrTy, gv);
1456 errorNYI(
"SYCL or OpenMP temp address space");
1466 "emitExplicitCastExprType");
1485 return cir::ConstantOp::create(
1486 builder, loc, builder.getDataMemberAttr(ty,
fieldDecl->getFieldIndex()));
1496 if (
auto *oid = dyn_cast<ObjCImplDecl>(
decl))
1497 errorNYI(oid->getSourceRange(),
"emitDeclConext: ObjCImplDecl");
1507 if (
decl->isTemplated())
1510 switch (
decl->getKind()) {
1513 decl->getDeclKindName());
1516 case Decl::CXXConversion:
1517 case Decl::CXXMethod:
1518 case Decl::Function: {
1521 if (!fd->isConsteval())
1527 case Decl::Decomposition:
1528 case Decl::VarTemplateSpecialization: {
1531 errorNYI(
decl->getSourceRange(),
"global variable decompositions");
1537 case Decl::OpenACCRoutine:
1540 case Decl::OpenACCDeclare:
1545 case Decl::UsingDirective:
1546 case Decl::UsingEnum:
1547 case Decl::NamespaceAlias:
1549 case Decl::TypeAlias:
1555 case Decl::ClassTemplate:
1557 case Decl::CXXDeductionGuide:
1559 case Decl::FunctionTemplate:
1560 case Decl::StaticAssert:
1561 case Decl::TypeAliasTemplate:
1562 case Decl::UsingShadow:
1563 case Decl::VarTemplate:
1564 case Decl::VarTemplatePartialSpecialization:
1567 case Decl::CXXConstructor:
1570 case Decl::CXXDestructor:
1575 case Decl::LinkageSpec:
1576 case Decl::Namespace:
1580 case Decl::ClassTemplateSpecialization:
1581 case Decl::CXXRecord: {
1584 for (
auto *childDecl : crd->
decls())
1590 case Decl::FileScopeAsm:
1592 if (langOpts.CUDA && langOpts.CUDAIsDevice)
1595 if (langOpts.OpenMPIsTargetDevice)
1598 if (langOpts.SYCLIsDevice)
1601 std::string line = file_asm->getAsmString();
1602 globalScopeAsm.push_back(builder.getStringAttr(line));
1609 op.setInitialValueAttr(value);
1623 md->getParent()->getNumVBases() == 0)
1625 "getAddrAndTypeOfCXXStructor: MS ABI complete destructor");
1636 false, isForDefinition);
1638 return {fnType, fn};
1642 mlir::Type funcType,
bool forVTable,
1646 "consteval function should never be emitted");
1656 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(gd.
getDecl())) {
1659 dd->getParent()->getNumVBases() == 0)
1661 "getAddrOfFunction: MS ABI complete destructor");
1667 false, isForDefinition);
1675 llvm::raw_svector_ostream
out(buffer);
1684 assert(ii &&
"Attempt to mangle unnamed decl.");
1686 const auto *fd = dyn_cast<FunctionDecl>(nd);
1690 }
else if (fd && fd->hasAttr<CUDAGlobalAttr>() &&
1706 if (
const auto *fd = dyn_cast<FunctionDecl>(nd)) {
1707 if (fd->isMultiVersion()) {
1709 "getMangledName: multi-version functions");
1714 "getMangledName: GPU relocatable device code");
1717 return std::string(
out.str());
1725 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(canonicalGd.
getDecl())) {
1728 "getMangledName: C++ constructor without variants");
1737 auto result = manglings.insert(std::make_pair(mangledName, gd));
1738 return mangledDeclNames[canonicalGd] = result.first->first();
1742 assert(!d->
getInit() &&
"Cannot emit definite definitions here!");
1750 if (gv && !mlir::cast<cir::GlobalOp>(gv).isDeclaration())
1766 if (langOpts.EmitAllDecls)
1769 const auto *vd = dyn_cast<VarDecl>(global);
1771 ((codeGenOpts.KeepPersistentStorageVariables &&
1772 (vd->getStorageDuration() ==
SD_Static ||
1773 vd->getStorageDuration() ==
SD_Thread)) ||
1774 (codeGenOpts.KeepStaticConsts && vd->getStorageDuration() ==
SD_Static &&
1775 vd->getType().isConstQualified())))
1788 if (langOpts.OpenMP >= 50 && !langOpts.OpenMPSimd) {
1789 std::optional<OMPDeclareTargetDeclAttr *> activeAttr =
1790 OMPDeclareTargetDeclAttr::getActiveAttr(global);
1791 if (!activeAttr || (*activeAttr)->getLevel() != (
unsigned)-1)
1795 const auto *fd = dyn_cast<FunctionDecl>(global);
1802 if (fd->hasAttr<TargetVersionAttr>() && !fd->isMultiVersion())
1804 if (langOpts.SYCLIsDevice) {
1805 errorNYI(fd->getSourceRange(),
"mayBeEmittedEagerly: SYCL");
1809 const auto *vd = dyn_cast<VarDecl>(global);
1811 if (astContext.getInlineVariableDefinitionKind(vd) ==
1819 if (langOpts.OpenMP && langOpts.OpenMPUseTLS &&
1820 astContext.getTargetInfo().isTLSSupported() &&
isa<VarDecl>(global) &&
1822 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(global))
1825 assert((fd || vd) &&
1826 "Only FunctionDecl and VarDecl should hit this path so far.");
1831 cir::CIRGlobalValueInterface gv) {
1832 if (gv.hasLocalLinkage())
1835 if (!gv.hasDefaultVisibility() && !gv.hasExternalWeakLinkage())
1843 const llvm::Triple &tt = cgm.
getTriple();
1845 if (tt.isOSCygMing()) {
1854 cgm.
errorNYI(
"shouldAssumeDSOLocal: MinGW");
1860 if (tt.isOSBinFormatCOFF() && gv.hasExternalWeakLinkage())
1868 if (tt.isOSBinFormatCOFF() || (tt.isOSWindows() && tt.isOSBinFormatMachO()))
1872 if (!tt.isOSBinFormatELF())
1877 if (rm != llvm::Reloc::Static && !lOpts.PIE) {
1885 return !(lOpts.SemanticInterposition || lOpts.HalfNoSemanticInterposition);
1889 if (!gv.isDeclarationForLinker())
1895 if (rm == llvm::Reloc::PIC_ && gv.hasExternalWeakLinkage())
1902 if (cgOpts.DirectAccessExternalData) {
1908 if (
auto globalOp = dyn_cast<cir::GlobalOp>(gv.getOperation())) {
1941 if (
auto globalValue = dyn_cast<cir::CIRGlobalValueInterface>(op))
1961 return cir::TLS_Model::GeneralDynamic;
1963 return cir::TLS_Model::LocalDynamic;
1965 return cir::TLS_Model::InitialExec;
1967 return cir::TLS_Model::LocalExec;
1969 llvm_unreachable(
"Invalid TLS model!");
1973 assert(d.
getTLSKind() &&
"setting TLS mode on non-TLS var!");
1978 if (d.
getAttr<TLSModelAttr>())
1982 global.setTlsModel(tlm);
1987 bool isIncompleteFunction,
2007 if (fd->isInlineBuiltinDeclaration()) {
2009 bool hasBody = fd->
hasBody(fdBody);
2011 assert(hasBody &&
"Inline builtin declarations should always have an "
2022 std::optional<cir::InlineKind> existingInlineKind = f.getInlineKind();
2024 existingInlineKind && *existingInlineKind == cir::InlineKind::NoInline;
2025 bool isAlwaysInline = existingInlineKind &&
2026 *existingInlineKind == cir::InlineKind::AlwaysInline;
2030 if (!isAlwaysInline &&
2035 f.setInlineKind(cir::InlineKind::NoInline);
2050 if (
decl->hasAttr<NoInlineAttr>() && !isAlwaysInline) {
2052 f.setInlineKind(cir::InlineKind::NoInline);
2053 }
else if (
decl->hasAttr<AlwaysInlineAttr>() && !isNoInline) {
2056 f.setInlineKind(cir::InlineKind::AlwaysInline);
2060 if (!isAlwaysInline) {
2061 f.setInlineKind(cir::InlineKind::NoInline);
2067 if (
auto *fd = dyn_cast<FunctionDecl>(
decl)) {
2072 auto checkRedeclForInline = [](
const FunctionDecl *redecl) {
2073 return redecl->isInlineSpecified();
2075 if (any_of(
decl->redecls(), checkRedeclForInline))
2080 return any_of(pattern->
redecls(), checkRedeclForInline);
2082 if (checkForInline(fd)) {
2083 f.setInlineKind(cir::InlineKind::InlineHint);
2084 }
else if (codeGenOpts.getInlining() ==
2086 !fd->isInlined() && !isAlwaysInline) {
2087 f.setInlineKind(cir::InlineKind::NoInline);
2096 StringRef mangledName, mlir::Type funcType,
GlobalDecl gd,
bool forVTable,
2098 mlir::ArrayAttr extraAttrs) {
2107 if (
const auto *fd = cast_or_null<FunctionDecl>(d)) {
2109 if (
getLangOpts().OpenMPIsTargetDevice && fd->isDefined() && !dontDefer &&
2112 "getOrCreateCIRFunction: OpenMP target function");
2116 if (fd->isMultiVersion())
2117 errorNYI(fd->getSourceRange(),
"getOrCreateCIRFunction: multi-version");
2123 assert(mlir::isa<cir::FuncOp>(entry));
2128 if (d && !d->
hasAttr<DLLImportAttr>() && !d->
hasAttr<DLLExportAttr>()) {
2136 if (isForDefinition && fn && !fn.isDeclaration()) {
2139 if (fn && fn.getFunctionType() == funcType) {
2143 if (!isForDefinition) {
2151 auto *funcDecl = llvm::cast_or_null<FunctionDecl>(gd.
getDecl());
2152 bool invalidLoc = !funcDecl ||
2153 funcDecl->getSourceRange().getBegin().isInvalid() ||
2154 funcDecl->getSourceRange().getEnd().isInvalid();
2156 invalidLoc ? theModule->getLoc() :
getLoc(funcDecl->getSourceRange()),
2157 mangledName, mlir::cast<cir::FuncType>(funcType), funcDecl);
2168 auto symbolOp = mlir::cast<mlir::SymbolOpInterface>(entry);
2176 if (symbolOp.getSymbolUses(symbolOp->getParentOp()))
2190 assert(funcOp.getFunctionType() == funcType);
2197 if (isa_and_nonnull<CXXDestructorDecl>(d) &&
2227 fd = fd->getPreviousDecl()) {
2229 if (fd->doesThisDeclarationHaveABody()) {
2242 cir::FuncType funcType,
2246 mlir::OpBuilder::InsertionGuard guard(builder);
2254 builder.setInsertionPoint(cgf->
curFn);
2256 func = cir::FuncOp::create(builder, loc, name, funcType);
2261 func.setNoProto(
true);
2263 assert(func.isDeclaration() &&
"expected empty body");
2267 func.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
2269 mlir::SymbolTable::setSymbolVisibility(
2270 func, mlir::SymbolTable::Visibility::Private);
2278 theModule.push_back(func);
2283 for (
const auto *
attr :
2297 fnOp.setBuiltin(
true);
2303 return cir::CtorKind::Default;
2305 return cir::CtorKind::Copy;
2307 return cir::CtorKind::Move;
2308 return cir::CtorKind::Custom;
2313 return cir::AssignKind::Copy;
2315 return cir::AssignKind::Move;
2316 llvm_unreachable(
"not a copy or move assignment operator");
2324 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(funcDecl)) {
2325 auto cxxDtor = cir::CXXDtorAttr::get(
2328 funcOp.setCxxSpecialMemberAttr(cxxDtor);
2332 if (
const auto *ctor = dyn_cast<CXXConstructorDecl>(funcDecl)) {
2334 auto cxxCtor = cir::CXXCtorAttr::get(
2336 kind, ctor->isTrivial());
2337 funcOp.setCxxSpecialMemberAttr(cxxCtor);
2341 const auto *method = dyn_cast<CXXMethodDecl>(funcDecl);
2342 if (method && (method->isCopyAssignmentOperator() ||
2343 method->isMoveAssignmentOperator())) {
2345 auto cxxAssign = cir::CXXAssignAttr::get(
2347 assignKind, method->isTrivial());
2348 funcOp.setCxxSpecialMemberAttr(cxxAssign);
2354 StringRef name, mlir::ArrayAttr,
2355 [[maybe_unused]]
bool isLocal,
2356 bool assumeConvergent) {
2357 if (assumeConvergent)
2358 errorNYI(
"createRuntimeFunction: assumeConvergent");
2360 errorNYI(
"createRuntimeFunction: local");
2370 entry.setDSOLocal(
true);
2376mlir::SymbolTable::Visibility
2380 if (op.isDeclaration())
2381 return mlir::SymbolTable::Visibility::Private;
2385mlir::SymbolTable::Visibility
2388 case cir::GlobalLinkageKind::InternalLinkage:
2389 case cir::GlobalLinkageKind::PrivateLinkage:
2390 return mlir::SymbolTable::Visibility::Private;
2391 case cir::GlobalLinkageKind::ExternalLinkage:
2392 case cir::GlobalLinkageKind::ExternalWeakLinkage:
2393 case cir::GlobalLinkageKind::LinkOnceODRLinkage:
2394 case cir::GlobalLinkageKind::AvailableExternallyLinkage:
2395 case cir::GlobalLinkageKind::CommonLinkage:
2396 case cir::GlobalLinkageKind::WeakAnyLinkage:
2397 case cir::GlobalLinkageKind::WeakODRLinkage:
2398 return mlir::SymbolTable::Visibility::Public;
2400 llvm::errs() <<
"visibility not implemented for '"
2401 << stringifyGlobalLinkageKind(glk) <<
"'\n";
2402 assert(0 &&
"not implemented");
2405 llvm_unreachable(
"linkage should be handled above!");
2409 clang::VisibilityAttr::VisibilityType visibility) {
2410 switch (visibility) {
2411 case clang::VisibilityAttr::VisibilityType::Default:
2412 return cir::VisibilityKind::Default;
2413 case clang::VisibilityAttr::VisibilityType::Hidden:
2414 return cir::VisibilityKind::Hidden;
2415 case clang::VisibilityAttr::VisibilityType::Protected:
2416 return cir::VisibilityKind::Protected;
2418 llvm_unreachable(
"unexpected visibility value");
2423 const clang::VisibilityAttr *va =
decl->getAttr<clang::VisibilityAttr>();
2424 cir::VisibilityAttr cirVisibility =
2427 cirVisibility = cir::VisibilityAttr::get(
2431 return cirVisibility;
2436 applyReplacements();
2438 theModule->setAttr(cir::CIRDialect::getModuleLevelAsmAttrName(),
2439 builder.getArrayAttr(globalScopeAsm));
2447 cir::FuncOp aliasee,
2448 cir::GlobalLinkageKind linkage) {
2450 auto *aliasFD = dyn_cast<FunctionDecl>(aliasGD.
getDecl());
2451 assert(aliasFD &&
"expected FunctionDecl");
2462 mangledName, fnType, aliasFD);
2463 alias.setAliasee(aliasee.getName());
2464 alias.setLinkage(linkage);
2468 mlir::SymbolTable::setSymbolVisibility(
2469 alias, mlir::SymbolTable::Visibility::Private);
2476 errorNYI(aliasFD->getSourceRange(),
"emitAliasForGlobal: previous uses");
2486 return genTypes.convertType(
type);
2493 return mlir::verify(theModule).succeeded();
2502 return builder.getConstNullPtrAttr(builder.getUInt8PtrTy());
2505 langOpts.ObjCRuntime.isGNUFamily()) {
2506 errorNYI(loc,
"getAddrOfRTTIDescriptor: Objc PtrType & Objc RT GUN");
2516 llvm::iterator_range<CastExpr::path_const_iterator> path) {
2523 assert(!base->isVirtual() &&
"Should not see virtual bases here!");
2528 const auto *baseDecl = base->getType()->castAsCXXRecordDecl();
2540 llvm::StringRef feature) {
2541 unsigned diagID = diags.getCustomDiagID(
2543 return diags.Report(loc, diagID) << feature;
2547 llvm::StringRef feature) {
2552 cir::LabelOp label) {
2553 [[maybe_unused]]
auto result =
2555 assert(result.second &&
2556 "attempting to map a blockaddress info that is already mapped");
2561 assert(result.second &&
2562 "attempting to map a blockaddress operation that is already mapped");
2566 cir::LabelOp label) {
2568 assert(result.second &&
2569 "attempting to map a blockaddress operation that is already mapped");
2573 cir::LabelOp newLabel) {
2576 "trying to update a blockaddress not previously mapped");
2577 assert(!it->second &&
"blockaddress already has a resolved label");
2579 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 bool shouldBeInCOMDAT(CIRGenModule &cgm, const Decl &d)
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.
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 ...
@ 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...
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...
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 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 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 emitGlobalDefinition(clang::GlobalDecl gd, mlir::Operation *op=nullptr)
void mapResolvedBlockAddress(cir::BlockAddressOp op, cir::LabelOp)
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
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 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 ...
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)
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.
void emitGlobalFunctionDefinition(clang::GlobalDecl gd, mlir::Operation *op)
CIRGenVTables & getVTables()
void setFunctionLinkage(GlobalDecl gd, cir::FuncOp f)
std::vector< clang::GlobalDecl > deferredDeclsToEmit
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
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.
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.
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 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
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.
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 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 stackProtector()
static bool moduleNameHash()
static bool opGlobalVisibility()
static bool setFunctionAttributes()
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.