19#include "mlir/Dialect/OpenMP/OpenMPOffloadUtils.h"
22#include "clang/AST/Attrs.inc"
36#include "llvm/ADT/StringExtras.h"
37#include "llvm/ADT/StringRef.h"
41#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
42#include "mlir/IR/Attributes.h"
43#include "mlir/IR/BuiltinOps.h"
44#include "mlir/IR/Location.h"
45#include "mlir/IR/MLIRContext.h"
46#include "mlir/IR/Operation.h"
47#include "mlir/IR/Verifier.h"
56 case TargetCXXABI::GenericItanium:
57 case TargetCXXABI::GenericAArch64:
58 case TargetCXXABI::AppleARM64:
61 case TargetCXXABI::Fuchsia:
62 case TargetCXXABI::GenericARM:
63 case TargetCXXABI::iOS:
64 case TargetCXXABI::WatchOS:
65 case TargetCXXABI::GenericMIPS:
66 case TargetCXXABI::WebAssembly:
67 case TargetCXXABI::XL:
68 case TargetCXXABI::Microsoft:
69 cgm.
errorNYI(
"createCXXABI: C++ ABI kind");
73 llvm_unreachable(
"invalid C++ ABI kind");
76CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
80 : builder(mlirContext, *this), astContext(astContext),
81 langOpts(astContext.
getLangOpts()), codeGenOpts(cgo),
82 theModule{
mlir::ModuleOp::create(
mlir::UnknownLoc::get(&mlirContext))},
83 diags(diags), target(astContext.getTargetInfo()),
84 abi(
createCXXABI(*this)), genTypes(*this), vtables(*this) {
112 .toCharUnitsFromBits(
116 const unsigned charSize = astContext.getTargetInfo().getCharWidth();
120 const unsigned sizeTypeSize =
121 astContext.getTypeSize(astContext.getSignedSizeType());
122 SizeSizeInBytes = astContext.toCharUnitsFromBits(sizeTypeSize).getQuantity();
129 std::optional<cir::SourceLanguage> sourceLanguage = getCIRSourceLanguage();
132 cir::CIRDialect::getSourceLanguageAttrName(),
133 cir::SourceLanguageAttr::get(&mlirContext, *sourceLanguage));
134 theModule->setAttr(cir::CIRDialect::getTripleAttrName(),
135 builder.getStringAttr(
getTriple().str()));
137 if (cgo.OptimizationLevel > 0 || cgo.OptimizeSize > 0)
138 theModule->setAttr(cir::CIRDialect::getOptInfoAttrName(),
139 cir::OptInfoAttr::get(&mlirContext,
140 cgo.OptimizationLevel,
143 if (langOpts.OpenMP) {
144 mlir::omp::OffloadModuleOpts ompOpts(
145 langOpts.OpenMPTargetDebug, langOpts.OpenMPTeamSubscription,
146 langOpts.OpenMPThreadSubscription, langOpts.OpenMPNoThreadState,
147 langOpts.OpenMPNoNestedParallelism, langOpts.OpenMPIsTargetDevice,
148 getTriple().isGPU(), langOpts.OpenMPForceUSM, langOpts.OpenMP,
149 langOpts.OMPHostIRFile, langOpts.OMPTargetTriples, langOpts.NoGPULib);
150 mlir::omp::setOffloadModuleInterfaceAttributes(theModule, ompOpts);
156 createOpenMPRuntime();
161 FileID mainFileId = astContext.getSourceManager().getMainFileID();
163 *astContext.getSourceManager().getFileEntryForID(mainFileId);
166 theModule.setSymName(path);
167 theModule->setLoc(mlir::FileLineColLoc::get(&mlirContext, path,
174 llvm::StringRef cudaBinaryName = codeGenOpts.CudaGpuBinaryFileName;
175 if (!cudaBinaryName.empty()) {
176 theModule->setAttr(cir::CIRDialect::getCUDABinaryHandleAttrName(),
177 cir::CUDABinaryHandleAttr::get(
178 &mlirContext, mlir::StringAttr::get(
179 &mlirContext, cudaBinaryName)));
186void CIRGenModule::createCUDARuntime() {
190void CIRGenModule::createOpenMPRuntime() {
191 openMPRuntime = std::make_unique<CIRGenOpenMPRuntime>(*
this);
202 auto &layout = astContext.getASTRecordLayout(rd);
207 return layout.getAlignment();
210 return layout.getNonVirtualAlignment();
215 bool forPointeeType) {
225 if (
unsigned align = tt->getDecl()->getMaxAlignment()) {
228 return astContext.toCharUnitsFromBits(align);
236 t = astContext.getBaseElementType(t);
257 }
else if (forPointeeType && !alignForArray &&
261 alignment = astContext.getTypeAlignInChars(t);
266 if (
unsigned maxAlign = astContext.getLangOpts().MaxTypeAlign) {
268 !astContext.isAlignmentRequired(t))
282 if (theTargetCIRGenInfo)
283 return *theTargetCIRGenInfo;
286 switch (triple.getArch()) {
293 case llvm::Triple::x86_64: {
294 switch (triple.getOS()) {
301 case llvm::Triple::Linux:
303 return *theTargetCIRGenInfo;
306 case llvm::Triple::nvptx:
307 case llvm::Triple::nvptx64:
309 return *theTargetCIRGenInfo;
310 case llvm::Triple::amdgcn: {
312 return *theTargetCIRGenInfo;
318 assert(cLoc.
isValid() &&
"expected valid source location");
322 return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
327 assert(cRange.
isValid() &&
"expected a valid source range");
330 mlir::Attribute metadata;
331 return mlir::FusedLoc::get({begin, end}, metadata, builder.getContext());
340 false, isForDefinition);
374 assert(op &&
"expected a valid global op");
382 mlir::Operation *globalValueOp = op;
383 if (
auto gv = dyn_cast<cir::GetGlobalOp>(op)) {
385 assert(globalValueOp &&
"expected a valid global op");
388 if (
auto cirGlobalValue =
389 dyn_cast<cir::CIRGlobalValueInterface>(globalValueOp))
390 if (!cirGlobalValue.isDeclaration())
411 assert(deferredVTables.empty());
421 std::vector<GlobalDecl> curDeclsToEmit;
440 if (
auto *
attr =
decl->getAttr<AttrT>())
441 return attr->isImplicit();
442 return decl->isImplicit();
447 assert(langOpts.CUDA &&
"Should not be called by non-CUDA languages");
452 return !langOpts.CUDAIsDevice || global->
hasAttr<CUDADeviceAttr>() ||
453 global->
hasAttr<CUDAConstantAttr>() ||
454 global->
hasAttr<CUDASharedAttr>() ||
460 if (
const auto *cd = dyn_cast<clang::OpenACCConstructDecl>(gd.
getDecl())) {
467 if (global->hasAttr<WeakRefAttr>())
468 errorNYI(global->getSourceRange(),
"emitGlobal: WeakRefAttr");
470 if (global->hasAttr<AliasAttr>())
471 errorNYI(global->getSourceRange(),
"emitGlobal: AliasAttr");
478 "Expected Variable or Function");
479 if (
const auto *
varDecl = dyn_cast<VarDecl>(global)) {
483 }
else if (langOpts.CUDAIsDevice) {
484 const auto *
functionDecl = dyn_cast<FunctionDecl>(global);
485 if ((!global->hasAttr<CUDADeviceAttr>() ||
486 (langOpts.OffloadImplicitHostDeviceTemplates &&
491 !
getASTContext().CUDAImplicitHostDeviceFunUsedByDevice.count(
493 !global->hasAttr<CUDAGlobalAttr>() &&
495 !global->hasAttr<CUDAHostAttr>()))
498 }
else if (!global->hasAttr<CUDAHostAttr>() &&
499 global->hasAttr<CUDADeviceAttr>())
503 if (langOpts.OpenMP) {
505 if (openMPRuntime && openMPRuntime->emitTargetGlobal(gd))
507 if (
auto *drd = dyn_cast<OMPDeclareReductionDecl>(global)) {
512 if (
auto *dmd = dyn_cast<OMPDeclareMapperDecl>(global)) {
519 if (
const auto *fd = dyn_cast<FunctionDecl>(global)) {
522 if (fd->hasAttr<AnnotateAttr>()) {
525 deferredAnnotations[mangledName] = fd;
527 if (!fd->doesThisDeclarationHaveABody()) {
528 if (!fd->doesDeclarationForceExternallyVisibleDefinition())
532 "function declaration that forces code gen");
537 assert(vd->isFileVarDecl() &&
"Cannot emit local var decl as global.");
539 !astContext.isMSStaticDataMemberInlineDefinition(vd)) {
543 if (astContext.getInlineVariableDefinitionKind(vd) ==
582 mlir::Operation *op) {
586 cir::FuncOp funcOp = dyn_cast_if_present<cir::FuncOp>(op);
587 if (!funcOp || funcOp.getFunctionType() != funcType) {
593 if (!funcOp.isDeclaration())
605 mlir::OpBuilder::InsertionGuard guard(builder);
610 setNonAliasAttributes(gd, funcOp);
613 auto getPriority = [
this](
const auto *
attr) ->
int {
617 return attr->DefaultPriority;
620 if (
const ConstructorAttr *ca = funcDecl->getAttr<ConstructorAttr>())
622 if (
const DestructorAttr *da = funcDecl->getAttr<DestructorAttr>())
625 if (funcDecl->getAttr<AnnotateAttr>())
628 if (
getLangOpts().OpenMP && funcDecl->hasAttr<OMPDeclareTargetDeclAttr>())
634 std::optional<int> priority) {
643 ctor.setGlobalCtorPriority(priority);
648 std::optional<int> priority) {
649 if (codeGenOpts.RegisterGlobalDtorsWithAtExit &&
651 errorNYI(dtor.getLoc(),
"registerGlobalDtorsWithAtExit");
654 dtor.setGlobalDtorPriority(priority);
678 StringRef name, mlir::Type t,
bool isConstant,
679 mlir::ptr::MemorySpaceAttrInterface addrSpace,
680 mlir::Operation *insertPoint) {
685 mlir::OpBuilder::InsertionGuard guard(builder);
691 builder.setInsertionPoint(insertPoint);
697 builder.setInsertionPointToStart(cgm.
getModule().getBody());
700 g = cir::GlobalOp::create(builder, loc, name, t, isConstant, addrSpace);
706 mlir::SymbolTable::setSymbolVisibility(
707 g, mlir::SymbolTable::Visibility::Private);
715 if (isa_and_nonnull<NamedDecl>(d))
719 if (
auto gvi = mlir::dyn_cast<cir::CIRGlobalValueInterface>(gv)) {
720 if (d && d->
hasAttr<UsedAttr>())
723 if (
const auto *vd = dyn_cast_if_present<VarDecl>(d);
724 vd && ((codeGenOpts.KeepPersistentStorageVariables &&
725 (vd->getStorageDuration() ==
SD_Static ||
726 vd->getStorageDuration() ==
SD_Thread)) ||
727 (codeGenOpts.KeepStaticConsts &&
729 vd->getType().isConstQualified())))
735static std::vector<std::string>
737 llvm::StringMap<bool> &featureMap) {
738 llvm::StringMap<bool> defaultFeatureMap;
742 std::vector<std::string> delta;
743 for (
const auto &[k, v] : featureMap) {
744 auto defaultIt = defaultFeatureMap.find(k);
745 if (defaultIt == defaultFeatureMap.end() || defaultIt->getValue() != v)
746 delta.push_back((v ?
"+" :
"-") + k.str());
752bool CIRGenModule::getCPUAndFeaturesAttributes(
753 GlobalDecl gd, llvm::StringMap<std::string> &attrs,
754 bool setTargetFeatures) {
760 std::vector<std::string> features;
764 const auto *fd = dyn_cast_or_null<FunctionDecl>(gd.
getDecl());
765 fd = fd ? fd->getMostRecentDecl() : fd;
766 const auto *td = fd ? fd->getAttr<TargetAttr>() :
nullptr;
767 const auto *tv = fd ? fd->getAttr<TargetVersionAttr>() :
nullptr;
768 assert((!td || !tv) &&
"both target_version and target specified");
769 const auto *sd = fd ? fd->getAttr<CPUSpecificAttr>() :
nullptr;
770 const auto *tc = fd ? fd->getAttr<TargetClonesAttr>() :
nullptr;
771 bool addedAttr =
false;
772 if (td || tv || sd || tc) {
777 llvm::StringMap<bool> featureMap;
779 astContext.getFunctionFeatureMap(featureMap, gd);
790 if (!targetCPU.empty()) {
791 attrs[
"cir.target-cpu"] = targetCPU.str();
794 if (!tuneCPU.empty()) {
795 attrs[
"cir.tune-cpu"] = tuneCPU.str();
798 if (!features.empty() && setTargetFeatures) {
799 llvm::erase_if(features, [&](
const std::string &f) {
800 assert(!f.empty() && (f[0] ==
'+' || f[0] ==
'-') &&
801 "feature string must start with '+' or '-'");
804 llvm::sort(features);
805 attrs[
"cir.target-features"] = llvm::join(features,
",");
813void CIRGenModule::setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op) {
818 if (
auto gvi = mlir::dyn_cast<cir::CIRGlobalValueInterface>(op)) {
819 if (
const auto *sa = d->
getAttr<SectionAttr>())
820 gvi.setSection(builder.getStringAttr(sa->getName()));
824 if (
auto func = dyn_cast<cir::FuncOp>(op)) {
825 llvm::StringMap<std::string> attrs;
826 if (getCPUAndFeaturesAttributes(gd, attrs)) {
830 for (
const auto &[key, val] : attrs)
831 func->setAttr(key, builder.getStringAttr(val));
841std::optional<cir::SourceLanguage> CIRGenModule::getCIRSourceLanguage()
const {
842 using ClangStd = clang::LangStandard;
843 using CIRLang = cir::SourceLanguage;
848 if (opts.C99 || opts.C11 || opts.C17 || opts.C23 || opts.C2y ||
849 opts.LangStd == ClangStd::lang_c89 ||
850 opts.LangStd == ClangStd::lang_gnu89)
855 errorNYI(
"CIR does not yet support the given source language");
859LangAS CIRGenModule::getGlobalVarAddressSpace(
const VarDecl *d) {
860 if (langOpts.OpenCL) {
868 if (langOpts.SYCLIsDevice &&
870 errorNYI(
"SYCL global address space");
872 if (langOpts.CUDA && langOpts.CUDAIsDevice) {
874 if (d->
hasAttr<CUDAConstantAttr>())
876 if (d->
hasAttr<CUDASharedAttr>())
878 if (d->
hasAttr<CUDADeviceAttr>())
887 errorNYI(
"OpenMP global address space");
900 gv.
setLinkage(cir::GlobalLinkageKind::ExternalWeakLinkage);
905 for (mlir::Attribute i : indexes) {
906 auto ind = mlir::cast<mlir::IntegerAttr>(i);
907 inds.push_back(ind.getValue().getSExtValue());
913 return view.getSymbol().getValue() == glob.getSymName();
917 cir::GlobalOp newGlob,
918 cir::GlobalViewAttr
attr,
929 mlir::Type newTy = newGlob.getSymType();
934 cir::PointerType newPtrTy;
937 newPtrTy = cir::PointerType::get(newTy);
946 cgm.
errorNYI(
"Unhandled type in createNewGlobalView");
952 mlir::Attribute oldInit) {
953 if (
auto oldView = mlir::dyn_cast<cir::GlobalViewAttr>(oldInit))
956 auto getNewInitElements =
957 [&](mlir::ArrayAttr oldElements) -> mlir::ArrayAttr {
959 for (mlir::Attribute elt : oldElements) {
960 if (
auto view = mlir::dyn_cast<cir::GlobalViewAttr>(elt))
962 else if (mlir::isa<cir::ConstArrayAttr, cir::ConstRecordAttr>(elt))
965 newElements.push_back(elt);
967 return mlir::ArrayAttr::get(cgm.
getBuilder().getContext(), newElements);
970 if (
auto oldArray = mlir::dyn_cast<cir::ConstArrayAttr>(oldInit)) {
971 mlir::Attribute newElements =
972 getNewInitElements(mlir::cast<mlir::ArrayAttr>(oldArray.getElts()));
974 newElements, mlir::cast<cir::ArrayType>(oldArray.getType()));
976 if (
auto oldRecord = mlir::dyn_cast<cir::ConstRecordAttr>(oldInit)) {
977 mlir::ArrayAttr newMembers = getNewInitElements(oldRecord.getMembers());
978 auto recordTy = mlir::cast<cir::RecordType>(oldRecord.getType());
980 newMembers, recordTy.getPacked(), recordTy.getPadded(), recordTy);
985 cgm.
errorNYI(
"Unhandled type in getNewInitValue");
993 assert(oldGV.getSymName() == newGV.getSymName() &&
"symbol names must match");
995 mlir::Type oldTy = oldGV.getSymType();
996 mlir::Type newTy = newGV.getSymType();
1001 assert(oldTy != newTy &&
"expected type change in replaceGlobal");
1004 std::optional<mlir::SymbolTable::UseRange> oldSymUses =
1005 oldGV.getSymbolUses(theModule);
1006 for (mlir::SymbolTable::SymbolUse use : *oldSymUses) {
1007 mlir::Operation *userOp = use.getUser();
1009 (mlir::isa<cir::GetGlobalOp, cir::GlobalOp, cir::ConstantOp>(userOp)) &&
1010 "Unexpected user for global op");
1012 if (
auto getGlobalOp = dyn_cast<cir::GetGlobalOp>(use.getUser())) {
1013 mlir::Value useOpResultValue = getGlobalOp.getAddr();
1014 useOpResultValue.setType(cir::PointerType::get(newTy));
1016 mlir::OpBuilder::InsertionGuard guard(builder);
1017 builder.setInsertionPointAfter(getGlobalOp);
1018 mlir::Type ptrTy = builder.getPointerTo(oldTy);
1020 builder.createBitcast(getGlobalOp->getLoc(), useOpResultValue, ptrTy);
1021 useOpResultValue.replaceAllUsesExcept(
cast,
cast.getDefiningOp());
1022 }
else if (
auto glob = dyn_cast<cir::GlobalOp>(userOp)) {
1023 if (
auto init = glob.getInitialValue()) {
1024 mlir::Attribute nw =
getNewInitValue(*
this, newGV, oldTy, init.value());
1025 glob.setInitialValueAttr(nw);
1027 }
else if (
auto c = dyn_cast<cir::ConstantOp>(userOp)) {
1029 auto typedAttr = mlir::cast<mlir::TypedAttr>(init);
1030 mlir::OpBuilder::InsertionGuard guard(builder);
1031 builder.setInsertionPointAfter(
c);
1032 auto newUser = cir::ConstantOp::create(builder,
c.getLoc(), typedAttr);
1033 c.replaceAllUsesWith(newUser.getOperation());
1067 cir::GlobalOp entry;
1071 "getOrCreateCIRGlobal: global with non-GlobalOp type");
1076 mlir::ptr::MemorySpaceAttrInterface entryCIRAS = entry.getAddrSpaceAttr();
1082 if (entry.getSymType() == ty &&
1092 if (isForDefinition && !entry.isDeclaration()) {
1094 "getOrCreateCIRGlobal: global with conflicting type");
1102 if (!isForDefinition)
1111 bool isConstant =
false;
1116 astContext,
true, !needsDtor);
1119 mlir::ptr::MemorySpaceAttrInterface declCIRAS =
1125 *
this, loc, mangledName, ty, isConstant, declCIRAS,
1126 entry.getOperation());
1146 if (langOpts.OpenMP && !langOpts.OpenMPSimd)
1148 "getOrCreateCIRGlobal: OpenMP target global variable");
1150 gv.setAlignmentAttr(
getSize(astContext.getDeclAlign(d)));
1164 if (astContext.isMSStaticDataMemberInlineDefinition(d))
1166 "getOrCreateCIRGlobal: MS static data member inline definition");
1170 if (
const SectionAttr *sa = d->
getAttr<SectionAttr>())
1171 gv.setSectionAttr(builder.getStringAttr(sa->getName()));
1176 if (
getTriple().getArch() == llvm::Triple::xcore)
1178 "getOrCreateCIRGlobal: XCore specific ABI requirements");
1188 "getOrCreateCIRGlobal: external const declaration with initializer");
1200 "getOrCreateCIRGlobal: HIP managed attribute");
1235 mlir::Type ptrTy = builder.getPointerTo(g.getSymType(), g.getAddrSpaceAttr());
1236 return cir::GetGlobalOp::create(
1239 g.getStaticLocalGuard().has_value());
1247 cir::PointerType ptrTy =
1248 builder.getPointerTo(globalOp.getSymType(), globalOp.getAddrSpaceAttr());
1249 return builder.getGlobalViewAttr(ptrTy, globalOp);
1253 assert((mlir::isa<cir::FuncOp>(gv.getOperation()) ||
1254 !gv.isDeclarationForLinker()) &&
1255 "Only globals with definition can force usage.");
1260 assert(!gv.isDeclarationForLinker() &&
1261 "Only globals with definition can force usage.");
1266 cir::CIRGlobalValueInterface gv) {
1267 assert((mlir::isa<cir::FuncOp>(gv.getOperation()) ||
1268 !gv.isDeclarationForLinker()) &&
1269 "Only globals with definition can force usage.");
1277 std::vector<cir::CIRGlobalValueInterface> &list) {
1282 mlir::Location loc = builder.getUnknownLoc();
1284 usedArray.resize(list.size());
1285 for (
auto [i, op] : llvm::enumerate(list)) {
1286 usedArray[i] = cir::GlobalViewAttr::get(
1287 cgm.
voidPtrTy, mlir::FlatSymbolRefAttr::get(op.getNameAttr()));
1290 cir::ArrayType arrayTy = cir::ArrayType::get(cgm.
voidPtrTy, usedArray.size());
1292 cir::ConstArrayAttr initAttr = cir::ConstArrayAttr::get(
1293 arrayTy, mlir::ArrayAttr::get(&cgm.
getMLIRContext(), usedArray));
1297 gv.setLinkage(cir::GlobalLinkageKind::AppendingLinkage);
1298 gv.setInitialValueAttr(initAttr);
1299 gv.setSectionAttr(builder.getStringAttr(
"llvm.metadata"));
1311 "emitGlobalVarDefinition: emit OpenCL/OpenMP global variable");
1318 bool isDefinitionAvailableExternally =
1323 if (isDefinitionAvailableExternally &&
1331 mlir::Attribute init;
1332 bool needsGlobalCtor =
false;
1333 bool needsGlobalDtor =
1334 !isDefinitionAvailableExternally &&
1339 std::optional<ConstantEmitter> emitter;
1344 bool isCUDASharedVar =
1349 bool isCUDAShadowVar =
1351 (vd->
hasAttr<CUDAConstantAttr>() || vd->
hasAttr<CUDADeviceAttr>() ||
1352 vd->
hasAttr<CUDASharedAttr>());
1353 bool isCUDADeviceShadowVar =
1359 (isCUDASharedVar || isCUDAShadowVar || isCUDADeviceShadowVar)) {
1361 }
else if (vd->
hasAttr<LoaderUninitializedAttr>()) {
1363 "emitGlobalVarDefinition: loader uninitialized attribute");
1364 }
else if (!initExpr) {
1377 emitter.emplace(*
this);
1378 mlir::Attribute initializer = emitter->tryEmitForInitializer(*initDecl);
1387 "emitGlobalVarDefinition: flexible array initializer");
1389 if (!isDefinitionAvailableExternally)
1390 needsGlobalCtor =
true;
1393 "emitGlobalVarDefinition: static initializer");
1404 mlir::Type initType;
1405 if (mlir::isa<mlir::SymbolRefAttr>(init)) {
1408 "emitGlobalVarDefinition: global initializer is a symbol reference");
1411 assert(mlir::isa<mlir::TypedAttr>(init) &&
"This should have a type");
1412 auto typedInitAttr = mlir::cast<mlir::TypedAttr>(init);
1413 initType = typedInitAttr.getType();
1415 assert(!mlir::isa<mlir::NoneType>(initType) &&
"Should have a type by now");
1421 if (!gv || gv.getSymType() != initType) {
1423 "emitGlobalVarDefinition: global initializer with type mismatch");
1429 if (vd->
hasAttr<AnnotateAttr>())
1442 if (langOpts.CUDA) {
1443 if (langOpts.CUDAIsDevice) {
1446 if (linkage != cir::GlobalLinkageKind::InternalLinkage &&
1448 (vd->
hasAttr<CUDADeviceAttr>() || vd->
hasAttr<CUDAConstantAttr>() ||
1451 gv->setAttr(cir::CUDAExternallyInitializedAttr::getMnemonic(),
1467 emitter->finalize(gv);
1471 gv.setConstant((vd->
hasAttr<CUDAConstantAttr>() && langOpts.CUDAIsDevice) ||
1472 (!needsGlobalCtor && !needsGlobalDtor &&
1477 if (
const SectionAttr *sa = vd->
getAttr<SectionAttr>()) {
1480 gv.setConstant(
true);
1484 gv.setLinkage(linkage);
1488 if (linkage == cir::GlobalLinkageKind::CommonLinkage) {
1490 gv.setConstant(
false);
1495 std::optional<mlir::Attribute> initializer = gv.getInitialValue();
1496 if (initializer && !
getBuilder().isNullValue(*initializer))
1497 gv.setLinkage(cir::GlobalLinkageKind::WeakAnyLinkage);
1500 setNonAliasAttributes(vd, gv);
1507 if (needsGlobalCtor || needsGlobalDtor)
1512 mlir::Operation *op) {
1514 if (
const auto *fd = dyn_cast<FunctionDecl>(
decl)) {
1518 if (
const auto *method = dyn_cast<CXXMethodDecl>(
decl)) {
1522 abi->emitCXXStructor(gd);
1523 else if (fd->isMultiVersion())
1524 errorNYI(method->getSourceRange(),
"multiversion functions");
1528 if (method->isVirtual())
1534 if (fd->isMultiVersion())
1535 errorNYI(fd->getSourceRange(),
"multiversion functions");
1540 if (
const auto *vd = dyn_cast<VarDecl>(
decl))
1543 llvm_unreachable(
"Invalid argument to CIRGenModule::emitGlobalDefinition");
1557 astContext.getAsConstantArrayType(e->
getType());
1558 uint64_t finalSize = cat->getZExtSize();
1559 str.resize(finalSize);
1561 mlir::Type eltTy =
convertType(cat->getElementType());
1562 return builder.getString(str, eltTy, finalSize,
false);
1567 auto arrayEltTy = mlir::cast<cir::IntType>(arrayTy.getElementType());
1569 uint64_t arraySize = arrayTy.getSize();
1571 assert(arraySize == literalSize + 1 &&
1572 "wide string literal array size must be literal length plus null "
1577 bool isAllZero =
true;
1578 for (
unsigned i = 0; i < literalSize; ++i) {
1586 return cir::ZeroAttr::get(arrayTy);
1590 elements.reserve(arraySize);
1591 for (
unsigned i = 0; i < literalSize; ++i)
1592 elements.push_back(cir::IntAttr::get(arrayEltTy, e->
getCodeUnit(i)));
1594 elements.push_back(cir::IntAttr::get(arrayEltTy, 0));
1596 auto elementsAttr = mlir::ArrayAttr::get(&
getMLIRContext(), elements);
1597 return builder.getConstArray(elementsAttr, arrayTy);
1608 if (d.
hasAttr<SelectAnyAttr>())
1612 if (
auto *vd = dyn_cast<VarDecl>(&d))
1627 llvm_unreachable(
"No such linkage");
1633 if (
auto globalOp = dyn_cast_or_null<cir::GlobalOp>(op)) {
1634 globalOp.setComdat(
true);
1637 funcOp.setComdat(
true);
1643 genTypes.updateCompletedType(td);
1647 replacements[name] = op;
1653 std::optional<mlir::SymbolTable::UseRange> optionalUseRange =
1654 oldF.getSymbolUses(modOp);
1655 if (!optionalUseRange)
1658 for (
const mlir::SymbolTable::SymbolUse &u : *optionalUseRange) {
1659 auto call = mlir::dyn_cast<cir::CallOp>(u.getUser());
1663 for (
auto [argOp, fnArgType] :
1664 llvm::zip(call.getArgs(), newF.getFunctionType().getInputs())) {
1665 if (argOp.getType() != fnArgType)
1674void CIRGenModule::applyReplacements() {
1675 for (
auto &i : replacements) {
1676 StringRef mangledName = i.first;
1677 mlir::Operation *replacement = i.second;
1683 auto newF = dyn_cast<cir::FuncOp>(replacement);
1686 errorNYI(replacement->getLoc(),
"replacement is not a function");
1691 "call argument types do not match replacement function");
1694 if (oldF.replaceAllSymbolUses(newF.getSymNameAttr(), theModule).failed())
1695 llvm_unreachable(
"internal error, cannot RAUW symbol");
1697 newF->moveBefore(oldF);
1705 mlir::Location loc, StringRef name, mlir::Type ty,
1707 auto gv = mlir::dyn_cast_or_null<cir::GlobalOp>(
getGlobalValue(name));
1711 if (gv.getSymType() == ty)
1717 assert(gv.isDeclaration() &&
"Declaration has wrong type!");
1719 errorNYI(loc,
"createOrReplaceCXXRuntimeVariable: declaration exists with "
1730 mlir::SymbolTable::setSymbolVisibility(gv,
1734 !gv.hasAvailableExternallyLinkage()) {
1738 gv.setAlignmentAttr(
getSize(alignment));
1749 if ((noCommon || vd->
hasAttr<NoCommonAttr>()) && !vd->
hasAttr<CommonAttr>())
1760 if (vd->
hasAttr<SectionAttr>())
1766 if (vd->
hasAttr<PragmaClangBSSSectionAttr>() ||
1767 vd->
hasAttr<PragmaClangDataSectionAttr>() ||
1768 vd->
hasAttr<PragmaClangRelroSectionAttr>() ||
1769 vd->
hasAttr<PragmaClangRodataSectionAttr>())
1777 if (vd->
hasAttr<WeakImportAttr>())
1787 if (vd->
hasAttr<AlignedAttr>())
1794 for (
const FieldDecl *fd : rd->fields()) {
1795 if (fd->isBitField())
1797 if (fd->hasAttr<AlignedAttr>())
1819cir::GlobalLinkageKind
1823 return cir::GlobalLinkageKind::InternalLinkage;
1826 return cir::GlobalLinkageKind::WeakAnyLinkage;
1830 return cir::GlobalLinkageKind::LinkOnceAnyLinkage;
1835 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
1849 return !astContext.getLangOpts().AppleKext
1850 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
1851 : cir::GlobalLinkageKind::InternalLinkage;
1865 return cir::GlobalLinkageKind::ExternalLinkage;
1868 return dd->
hasAttr<CUDAGlobalAttr>()
1869 ? cir::GlobalLinkageKind::ExternalLinkage
1870 : cir::GlobalLinkageKind::InternalLinkage;
1871 return cir::GlobalLinkageKind::WeakODRLinkage;
1879 return cir::GlobalLinkageKind::CommonLinkage;
1885 if (dd->
hasAttr<SelectAnyAttr>())
1886 return cir::GlobalLinkageKind::WeakODRLinkage;
1890 return cir::GlobalLinkageKind::ExternalLinkage;
1902 mlir::Operation *old, cir::FuncOp newFn) {
1904 auto oldFn = mlir::dyn_cast<cir::FuncOp>(old);
1912 if (oldFn->getAttrs().size() <= 1)
1914 "replaceUsesOfNonProtoTypeWithRealFunction: Attribute forwarding");
1917 newFn.setNoProto(oldFn.getNoProto());
1920 std::optional<mlir::SymbolTable::UseRange> symUses =
1921 oldFn.getSymbolUses(oldFn->getParentOp());
1922 for (
const mlir::SymbolTable::SymbolUse &use : symUses.value()) {
1923 mlir::OpBuilder::InsertionGuard guard(builder);
1925 if (
auto noProtoCallOp = mlir::dyn_cast<cir::CallOp>(use.getUser())) {
1926 builder.setInsertionPoint(noProtoCallOp);
1929 cir::CallOp realCallOp = builder.createCallOp(
1930 noProtoCallOp.getLoc(), newFn, noProtoCallOp.getOperands());
1933 noProtoCallOp.replaceAllUsesWith(realCallOp);
1934 noProtoCallOp.erase();
1935 }
else if (
auto getGlobalOp =
1936 mlir::dyn_cast<cir::GetGlobalOp>(use.getUser())) {
1943 mlir::Value res = getGlobalOp.getAddr();
1944 const mlir::Type oldResTy = res.getType();
1945 const auto newPtrTy = cir::PointerType::get(newFn.getFunctionType());
1946 if (oldResTy != newPtrTy) {
1947 res.setType(newPtrTy);
1948 builder.setInsertionPointAfter(getGlobalOp.getOperation());
1949 mlir::Value castRes =
1950 cir::CastOp::create(builder, getGlobalOp.getLoc(), oldResTy,
1951 cir::CastKind::bitcast, res);
1952 res.replaceAllUsesExcept(castRes, castRes.getDefiningOp());
1954 }
else if (mlir::isa<cir::GlobalOp>(use.getUser())) {
1960 "replaceUsesOfNonProtoTypeWithRealFunction: unexpected use type");
1965cir::GlobalLinkageKind
1967 GVALinkage linkage = astContext.GetGVALinkageForVariable(vd);
1974 GVALinkage linkage = astContext.GetGVALinkageForFunction(d);
1976 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(d))
1985 StringRef globalName,
CharUnits alignment) {
1991 cgm, loc, globalName,
c.getType(), !cgm.
getLangOpts().WritableStrings);
1994 gv.setAlignmentAttr(cgm.
getSize(alignment));
1996 cir::GlobalLinkageKindAttr::get(cgm.
getBuilder().getContext(), lt));
2000 if (gv.isWeakForLinker()) {
2001 assert(cgm.
supportsCOMDAT() &&
"Only COFF uses weak string literals");
2004 cgm.
setDSOLocal(
static_cast<mlir::Operation *
>(gv));
2025 std::string result =
2036 astContext.getAlignOfGlobalVarInChars(
s->getType(),
nullptr);
2044 if (!gv.getAlignment() ||
2045 uint64_t(alignment.
getQuantity()) > *gv.getAlignment())
2046 gv.setAlignmentAttr(
getSize(alignment));
2051 if (
getCXXABI().getMangleContext().shouldMangleStringLiteral(
s) &&
2054 "getGlobalForStringLiteral: mangle string literals");
2062 mlir::Location loc =
s->getBeginLoc().isValid()
2064 : builder.getUnknownLoc();
2065 auto typedC = llvm::cast<mlir::TypedAttr>(
c);
2067 cir::GlobalLinkageKind::PrivateLinkage, *
this,
2068 uniqueName, alignment);
2082 auto arrayTy = mlir::dyn_cast<cir::ArrayType>(gv.getSymType());
2083 assert(arrayTy &&
"String literal must be array");
2087 return builder.getGlobalViewAttr(ptrTy, gv);
2103 errorNYI(
"SYCL or OpenMP temp address space");
2113 "emitExplicitCastExprType");
2119 auto ty = mlir::cast<cir::MethodType>(
convertType(destTy));
2120 return builder.getNullMethodAttr(ty);
2123 auto ty = mlir::cast<cir::DataMemberType>(
convertType(destTy));
2124 return builder.getNullDataMemberAttr(ty);
2135 if (
const auto *methodDecl = dyn_cast<CXXMethodDecl>(
decl)) {
2137 if (methodDecl->isVirtual())
2138 return cir::ConstantOp::create(
2139 builder, loc,
getCXXABI().buildVirtualMethodAttr(ty, methodDecl));
2145 return cir::ConstantOp::create(builder, loc,
2146 builder.getMethodAttr(ty, methodFuncOp));
2152 return cir::ConstantOp::create(
2153 builder, loc, builder.getDataMemberAttr(ty,
fieldDecl->getFieldIndex()));
2163 if (
auto *oid = dyn_cast<ObjCImplDecl>(
decl))
2164 errorNYI(oid->getSourceRange(),
"emitDeclConext: ObjCImplDecl");
2174 if (
decl->isTemplated())
2177 switch (
decl->getKind()) {
2180 decl->getDeclKindName());
2183 case Decl::CXXConversion:
2184 case Decl::CXXMethod:
2185 case Decl::Function: {
2188 if (!fd->isConsteval())
2197 case Decl::Decomposition:
2198 case Decl::VarTemplateSpecialization: {
2200 if (
auto *decomp = dyn_cast<DecompositionDecl>(
decl))
2201 for (
auto *binding : decomp->flat_bindings())
2202 if (
auto *holdingVar = binding->getHoldingVar())
2206 case Decl::OpenACCRoutine:
2209 case Decl::OpenACCDeclare:
2212 case Decl::OMPThreadPrivate:
2215 case Decl::OMPGroupPrivate:
2218 case Decl::OMPAllocate:
2221 case Decl::OMPCapturedExpr:
2224 case Decl::OMPDeclareReduction:
2227 case Decl::OMPDeclareMapper:
2230 case Decl::OMPRequires:
2235 case Decl::UsingDirective:
2236 case Decl::UsingEnum:
2237 case Decl::NamespaceAlias:
2239 case Decl::TypeAlias:
2245 case Decl::ClassTemplate:
2247 case Decl::CXXDeductionGuide:
2249 case Decl::ExplicitInstantiation:
2250 case Decl::FunctionTemplate:
2251 case Decl::StaticAssert:
2252 case Decl::TypeAliasTemplate:
2253 case Decl::UsingShadow:
2254 case Decl::VarTemplate:
2255 case Decl::VarTemplatePartialSpecialization:
2258 case Decl::CXXConstructor:
2261 case Decl::CXXDestructor:
2266 case Decl::LinkageSpec:
2267 case Decl::Namespace:
2271 case Decl::ClassTemplateSpecialization:
2272 case Decl::CXXRecord: {
2275 for (
auto *childDecl : crd->
decls())
2281 case Decl::FileScopeAsm:
2283 if (langOpts.CUDA && langOpts.CUDAIsDevice)
2286 if (langOpts.OpenMPIsTargetDevice)
2289 if (langOpts.SYCLIsDevice)
2292 std::string line = file_asm->getAsmString();
2293 globalScopeAsm.push_back(builder.getStringAttr(line));
2300 op.setInitialValueAttr(value);
2314 md->getParent()->getNumVBases() == 0)
2316 "getAddrAndTypeOfCXXStructor: MS ABI complete destructor");
2327 false, isForDefinition);
2329 return {fnType, fn};
2333 mlir::Type funcType,
bool forVTable,
2337 "consteval function should never be emitted");
2347 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(gd.
getDecl())) {
2350 dd->getParent()->getNumVBases() == 0)
2352 "getAddrOfFunction: MS ABI complete destructor");
2358 false, isForDefinition);
2360 if (langOpts.CUDA && !langOpts.CUDAIsDevice &&
2366 bool isHIPHandle = mlir::isa<cir::GlobalOp>(*handle);
2367 if (isForDefinition || isHIPHandle)
2369 return mlir::dyn_cast<cir::FuncOp>(*handle);
2378 llvm::raw_svector_ostream
out(buffer);
2387 assert(ii &&
"Attempt to mangle unnamed decl.");
2389 const auto *fd = dyn_cast<FunctionDecl>(nd);
2393 }
else if (fd && fd->hasAttr<CUDAGlobalAttr>() &&
2397 DeviceKernelAttr::isOpenCLSpelling(
2398 fd->getAttr<DeviceKernelAttr>()) &&
2415 if (
const auto *fd = dyn_cast<FunctionDecl>(nd)) {
2416 if (fd->isMultiVersion()) {
2418 "getMangledName: multi-version functions");
2423 "getMangledName: GPU relocatable device code");
2426 return std::string(
out.str());
2429static FunctionDecl *
2444 if (
auto *methodDecl = dyn_cast<CXXMethodDecl>(protoFunc);
2445 methodDecl && methodDecl->isImplicitObjectMemberFunction()) {
2447 paramTypes.insert(paramTypes.begin(), methodDecl->getThisType());
2450 fpt->getExtProtoInfo());
2461 params.reserve(fpt->getNumParams());
2464 for (
unsigned i = 0, e = fpt->getNumParams(); i != e; ++i) {
2468 nullptr, fpt->getParamType(i),
nullptr,
2471 params.push_back(parm);
2474 tempFunc->setParams(params);
2499 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(canonicalGd.
getDecl())) {
2502 "getMangledName: C++ constructor without variants");
2511 auto result = manglings.insert(std::make_pair(mangledName, gd));
2512 return mangledDeclNames[canonicalGd] = result.first->first();
2516 assert(!d->
getInit() &&
"Cannot emit definite definitions here!");
2524 if (gv && !mlir::cast<cir::GlobalOp>(gv).isDeclaration())
2540 if (langOpts.EmitAllDecls)
2543 const auto *vd = dyn_cast<VarDecl>(global);
2545 ((codeGenOpts.KeepPersistentStorageVariables &&
2546 (vd->getStorageDuration() ==
SD_Static ||
2547 vd->getStorageDuration() ==
SD_Thread)) ||
2548 (codeGenOpts.KeepStaticConsts && vd->getStorageDuration() ==
SD_Static &&
2549 vd->getType().isConstQualified())))
2562 if (langOpts.OpenMP >= 50 && !langOpts.OpenMPSimd) {
2563 std::optional<OMPDeclareTargetDeclAttr *> activeAttr =
2564 OMPDeclareTargetDeclAttr::getActiveAttr(global);
2565 if (!activeAttr || (*activeAttr)->getLevel() != (
unsigned)-1)
2569 const auto *fd = dyn_cast<FunctionDecl>(global);
2576 if (fd->hasAttr<TargetVersionAttr>() && !fd->isMultiVersion())
2578 if (langOpts.SYCLIsDevice) {
2579 errorNYI(fd->getSourceRange(),
"mayBeEmittedEagerly: SYCL");
2583 const auto *vd = dyn_cast<VarDecl>(global);
2585 if (astContext.getInlineVariableDefinitionKind(vd) ==
2593 if (langOpts.OpenMP && langOpts.OpenMPUseTLS &&
2594 astContext.getTargetInfo().isTLSSupported() &&
isa<VarDecl>(global) &&
2596 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(global))
2599 assert((fd || vd) &&
2600 "Only FunctionDecl and VarDecl should hit this path so far.");
2605 cir::CIRGlobalValueInterface gv) {
2606 if (gv.hasLocalLinkage())
2609 if (!gv.hasDefaultVisibility() && !gv.hasExternalWeakLinkage())
2617 const llvm::Triple &tt = cgm.
getTriple();
2619 if (tt.isOSCygMing()) {
2628 cgm.
errorNYI(
"shouldAssumeDSOLocal: MinGW");
2634 if (tt.isOSBinFormatCOFF() && gv.hasExternalWeakLinkage())
2642 if (tt.isOSBinFormatCOFF() || (tt.isOSWindows() && tt.isOSBinFormatMachO()))
2646 if (!tt.isOSBinFormatELF())
2651 if (rm != llvm::Reloc::Static && !lOpts.PIE) {
2659 return !(lOpts.SemanticInterposition || lOpts.HalfNoSemanticInterposition);
2663 if (!gv.isDeclarationForLinker())
2669 if (rm == llvm::Reloc::PIC_ && gv.hasExternalWeakLinkage())
2676 if (cgOpts.DirectAccessExternalData) {
2682 if (
auto globalOp = dyn_cast<cir::GlobalOp>(gv.getOperation())) {
2715 if (
auto globalValue = dyn_cast<cir::CIRGlobalValueInterface>(op))
2734 auto res = manglings.find(mangledName);
2735 if (res == manglings.end())
2737 result = res->getValue();
2744 return cir::TLS_Model::GeneralDynamic;
2746 return cir::TLS_Model::LocalDynamic;
2748 return cir::TLS_Model::InitialExec;
2750 return cir::TLS_Model::LocalExec;
2752 llvm_unreachable(
"Invalid TLS model!");
2756 assert(d.
getTLSKind() &&
"setting TLS mode on non-TLS var!");
2761 if (d.
getAttr<TLSModelAttr>())
2765 global.setTlsModel(tlm);
2770 cir::FuncOp func,
bool isThunk) {
2772 cir::CallingConv callingConv;
2773 cir::SideEffect sideEffect;
2780 mlir::NamedAttrList pal{};
2781 std::vector<mlir::NamedAttrList> argAttrs(info.
arguments().size());
2782 mlir::NamedAttrList retAttrs{};
2784 retAttrs, callingConv, sideEffect,
2787 for (mlir::NamedAttribute
attr : pal)
2788 func->setAttr(
attr.getName(),
attr.getValue());
2790 llvm::for_each(llvm::enumerate(argAttrs), [func](
auto idx_arg_pair) {
2791 mlir::function_interface_impl::setArgAttrs(func, idx_arg_pair.index(),
2792 idx_arg_pair.value());
2794 if (!retAttrs.empty())
2795 mlir::function_interface_impl::setResultAttrs(func, 0, retAttrs);
2808 bool isIncompleteFunction,
2816 if (!isIncompleteFunction)
2818 getTypes().arrangeGlobalDeclaration(globalDecl),
2821 if (!isIncompleteFunction && func.isDeclaration())
2834 if (funcDecl->isInlineBuiltinDeclaration()) {
2836 bool hasBody = funcDecl->
hasBody(fdBody);
2838 assert(hasBody &&
"Inline builtin declarations should always have an "
2843 if (funcDecl->isReplaceableGlobalAllocationFunction()) {
2846 func->setAttr(cir::CIRDialect::getNoBuiltinAttrName(),
2858 if (!langOpts.Exceptions)
2861 if (langOpts.CXXExceptions)
2864 if (langOpts.ObjCExceptions)
2875 f->setAttr(cir::CIRDialect::getNoThrowAttrName(),
2878 std::optional<cir::InlineKind> existingInlineKind = f.getInlineKind();
2880 existingInlineKind && *existingInlineKind == cir::InlineKind::NoInline;
2881 bool isAlwaysInline = existingInlineKind &&
2882 *existingInlineKind == cir::InlineKind::AlwaysInline;
2886 if (!isAlwaysInline &&
2891 f.setInlineKind(cir::InlineKind::NoInline);
2906 if (
decl->hasAttr<NoInlineAttr>() && !isAlwaysInline) {
2908 f.setInlineKind(cir::InlineKind::NoInline);
2909 }
else if (
decl->hasAttr<AlwaysInlineAttr>() && !isNoInline) {
2912 f.setInlineKind(cir::InlineKind::AlwaysInline);
2916 if (!isAlwaysInline)
2917 f.setInlineKind(cir::InlineKind::NoInline);
2922 if (
auto *fd = dyn_cast<FunctionDecl>(
decl)) {
2927 auto checkRedeclForInline = [](
const FunctionDecl *redecl) {
2928 return redecl->isInlineSpecified();
2930 if (any_of(
decl->redecls(), checkRedeclForInline))
2935 return any_of(pattern->
redecls(), checkRedeclForInline);
2937 if (checkForInline(fd)) {
2938 f.setInlineKind(cir::InlineKind::InlineHint);
2939 }
else if (codeGenOpts.getInlining() ==
2941 !fd->isInlined() && !isAlwaysInline) {
2942 f.setInlineKind(cir::InlineKind::NoInline);
2951 StringRef mangledName, mlir::Type funcType,
GlobalDecl gd,
bool forVTable,
2953 mlir::NamedAttrList extraAttrs) {
2956 if (
const auto *fd = cast_or_null<FunctionDecl>(d)) {
2958 if (
getLangOpts().OpenMPIsTargetDevice && openMPRuntime &&
2960 !dontDefer && !isForDefinition) {
2963 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(fdDef))
2965 else if (
const auto *dd = dyn_cast<CXXDestructorDecl>(fdDef))
2975 if (fd->isMultiVersion())
2976 errorNYI(fd->getSourceRange(),
"getOrCreateCIRFunction: multi-version");
2982 assert(mlir::isa<cir::FuncOp>(entry));
2987 if (d && !d->
hasAttr<DLLImportAttr>() && !d->
hasAttr<DLLExportAttr>()) {
2995 if (isForDefinition && fn && !fn.isDeclaration()) {
3002 diagnosedConflictingDefinitions.insert(gd).second) {
3006 diag::note_previous_definition);
3010 if (fn && fn.getFunctionType() == funcType) {
3014 if (!isForDefinition) {
3022 auto *funcDecl = llvm::cast_or_null<FunctionDecl>(gd.
getDecl());
3023 bool invalidLoc = !funcDecl ||
3024 funcDecl->getSourceRange().getBegin().isInvalid() ||
3025 funcDecl->getSourceRange().getEnd().isInvalid();
3027 invalidLoc ? theModule->getLoc() :
getLoc(funcDecl->getSourceRange()),
3028 mangledName, mlir::cast<cir::FuncType>(funcType), funcDecl);
3030 if (funcDecl && funcDecl->hasAttr<AnnotateAttr>())
3031 deferredAnnotations[mangledName] = funcDecl;
3042 auto symbolOp = mlir::cast<mlir::SymbolOpInterface>(entry);
3050 if (symbolOp.getSymbolUses(symbolOp->getParentOp()))
3060 if (!extraAttrs.empty()) {
3061 extraAttrs.append(funcOp->getAttrs());
3062 funcOp->setAttrs(extraAttrs);
3069 assert(funcOp.getFunctionType() == funcType);
3076 if (isa_and_nonnull<CXXDestructorDecl>(d) &&
3106 fd = fd->getPreviousDecl()) {
3108 if (fd->doesThisDeclarationHaveABody()) {
3121 cir::FuncType funcType,
3125 mlir::OpBuilder::InsertionGuard guard(builder);
3133 builder.setInsertionPoint(cgf->
curFn);
3135 func = cir::FuncOp::create(builder, loc, name, funcType);
3142 func.setNoProto(
true);
3144 assert(func.isDeclaration() &&
"expected empty body");
3148 func.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
3150 mlir::SymbolTable::setSymbolVisibility(
3151 func, mlir::SymbolTable::Visibility::Private);
3159 theModule.push_back(func);
3164 for (
const auto *
attr :
3178 fnOp.setBuiltin(
true);
3184 return cir::CtorKind::Default;
3186 return cir::CtorKind::Copy;
3188 return cir::CtorKind::Move;
3189 return cir::CtorKind::Custom;
3194 return cir::AssignKind::Copy;
3196 return cir::AssignKind::Move;
3197 llvm_unreachable(
"not a copy or move assignment operator");
3205 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(funcDecl)) {
3206 auto cxxDtor = cir::CXXDtorAttr::get(
3209 funcOp.setCxxSpecialMemberAttr(cxxDtor);
3213 if (
const auto *ctor = dyn_cast<CXXConstructorDecl>(funcDecl)) {
3215 auto cxxCtor = cir::CXXCtorAttr::get(
3217 kind, ctor->isTrivial());
3218 funcOp.setCxxSpecialMemberAttr(cxxCtor);
3222 const auto *method = dyn_cast<CXXMethodDecl>(funcDecl);
3223 if (method && (method->isCopyAssignmentOperator() ||
3224 method->isMoveAssignmentOperator())) {
3226 auto cxxAssign = cir::CXXAssignAttr::get(
3228 assignKind, method->isTrivial());
3229 funcOp.setCxxSpecialMemberAttr(cxxAssign);
3235 cir::FuncOp funcOp, StringRef name) {
3251 mlir::NamedAttrList extraAttrs,
3253 bool assumeConvergent) {
3254 if (assumeConvergent)
3255 errorNYI(
"createRuntimeFunction: assumeConvergent");
3265 entry.setDSOLocal(
true);
3271mlir::SymbolTable::Visibility
3275 if (op.isDeclaration())
3276 return mlir::SymbolTable::Visibility::Private;
3280mlir::SymbolTable::Visibility
3283 case cir::GlobalLinkageKind::InternalLinkage:
3284 case cir::GlobalLinkageKind::PrivateLinkage:
3285 return mlir::SymbolTable::Visibility::Private;
3286 case cir::GlobalLinkageKind::ExternalLinkage:
3287 case cir::GlobalLinkageKind::ExternalWeakLinkage:
3288 case cir::GlobalLinkageKind::LinkOnceODRLinkage:
3289 case cir::GlobalLinkageKind::AvailableExternallyLinkage:
3290 case cir::GlobalLinkageKind::CommonLinkage:
3291 case cir::GlobalLinkageKind::WeakAnyLinkage:
3292 case cir::GlobalLinkageKind::WeakODRLinkage:
3293 return mlir::SymbolTable::Visibility::Public;
3295 llvm::errs() <<
"visibility not implemented for '"
3296 << stringifyGlobalLinkageKind(glk) <<
"'\n";
3297 assert(0 &&
"not implemented");
3300 llvm_unreachable(
"linkage should be handled above!");
3304 clang::VisibilityAttr::VisibilityType visibility) {
3305 switch (visibility) {
3306 case clang::VisibilityAttr::VisibilityType::Default:
3307 return cir::VisibilityKind::Default;
3308 case clang::VisibilityAttr::VisibilityType::Hidden:
3309 return cir::VisibilityKind::Hidden;
3310 case clang::VisibilityAttr::VisibilityType::Protected:
3311 return cir::VisibilityKind::Protected;
3313 llvm_unreachable(
"unexpected visibility value");
3318 const clang::VisibilityAttr *va =
decl->getAttr<clang::VisibilityAttr>();
3319 cir::VisibilityAttr cirVisibility =
3322 cirVisibility = cir::VisibilityAttr::get(
3326 return cirVisibility;
3332 applyReplacements();
3334 theModule->setAttr(cir::CIRDialect::getModuleLevelAsmAttrName(),
3335 builder.getArrayAttr(globalScopeAsm));
3337 emitGlobalAnnotations();
3339 if (!recordLayoutEntries.empty())
3341 cir::CIRDialect::getRecordLayoutsAttrName(),
3342 mlir::DictionaryAttr::get(&
getMLIRContext(), recordLayoutEntries));
3351 std::string cuidName =
3354 auto loc = builder.getUnknownLoc();
3355 mlir::ptr::MemorySpaceAttrInterface addrSpace =
3357 getGlobalVarAddressSpace(
nullptr));
3361 gv.setLinkage(cir::GlobalLinkageKind::ExternalLinkage);
3363 auto zeroAttr = cir::IntAttr::get(int8Ty, 0);
3364 gv.setInitialValueAttr(zeroAttr);
3366 mlir::SymbolTable::setSymbolVisibility(
3367 gv, mlir::SymbolTable::Visibility::Public);
3380 cir::FuncOp aliasee,
3381 cir::GlobalLinkageKind linkage) {
3383 auto *aliasFD = dyn_cast<FunctionDecl>(aliasGD.
getDecl());
3384 assert(aliasFD &&
"expected FunctionDecl");
3395 mangledName, fnType, aliasFD);
3396 alias.setAliasee(aliasee.getName());
3397 alias.setLinkage(linkage);
3401 mlir::SymbolTable::setSymbolVisibility(
3402 alias, mlir::SymbolTable::Visibility::Private);
3414 "declaration exists with different type");
3426 return genTypes.convertType(
type);
3433 return mlir::verify(theModule).succeeded();
3442 return builder.getConstNullPtrAttr(builder.getUInt8PtrTy());
3445 langOpts.ObjCRuntime.isGNUFamily()) {
3446 errorNYI(loc,
"getAddrOfRTTIDescriptor: Objc PtrType & Objc RT GUN");
3456 llvm::iterator_range<CastExpr::path_const_iterator> path) {
3463 assert(!base->isVirtual() &&
"Should not see virtual bases here!");
3468 const auto *baseDecl = base->getType()->castAsCXXRecordDecl();
3480 llvm::StringRef feature) {
3481 unsigned diagID = diags.getCustomDiagID(
3483 return diags.Report(loc, diagID) << feature;
3487 llvm::StringRef feature) {
3499 "cannot compile this %0 yet");
3500 diags.Report(astContext.getFullLoc(
s->getBeginLoc()), diagId)
3501 <<
type <<
s->getSourceRange();
3507 "cannot compile this %0 yet");
3508 diags.Report(astContext.getFullLoc(d->
getLocation()), diagId) <<
type;
3512 cir::LabelOp label) {
3513 [[maybe_unused]]
auto result =
3515 assert(result.second &&
3516 "attempting to map a blockaddress info that is already mapped");
3521 assert(result.second &&
3522 "attempting to map a blockaddress operation that is already mapped");
3526 cir::LabelOp label) {
3528 assert(result.second &&
3529 "attempting to map a blockaddress operation that is already mapped");
3533 cir::LabelOp newLabel) {
3536 "trying to update a blockaddress not previously mapped");
3537 assert(!it->second &&
"blockaddress already has a resolved label");
3539 it->second = newLabel;
3552 "not a global temporary");
3564 materializedType = mte->
getType();
3568 auto insertResult = materializedGlobalTemporaryMap.insert({mte,
nullptr});
3569 if (!insertResult.second)
3576 llvm::raw_svector_ostream
out(name);
3594 value = &evalResult.
Val;
3598 std::optional<ConstantEmitter> emitter;
3599 mlir::Attribute initialValue =
nullptr;
3600 bool isConstant =
false;
3604 emitter.emplace(*
this);
3605 initialValue = emitter->emitForInitializer(*value, materializedType);
3610 type = mlir::cast<mlir::TypedAttr>(initialValue).getType();
3619 if (linkage == cir::GlobalLinkageKind::ExternalLinkage) {
3621 if (
varDecl->isStaticDataMember() &&
varDecl->getAnyInitializer(initVD) &&
3629 linkage = cir::GlobalLinkageKind::InternalLinkage;
3634 gv.setInitialValueAttr(initialValue);
3637 emitter->finalize(gv);
3639 if (!gv.hasLocalLinkage()) {
3644 gv.setAlignment(align.getAsAlign().value());
3647 "Global temporary with comdat/weak linkage");
3650 "Global temporary with thread local storage");
3651 mlir::Operation *cv = gv;
3657 mlir::Operation *&entry = materializedGlobalTemporaryMap[mte];
3659 entry->replaceAllUsesWith(cv);
3674 return *globalOpEntry;
3681 "emitForInitializer should take gcd->getType().getAddressSpace()");
3683 auto typedInit = dyn_cast<mlir::TypedAttr>(init);
3687 "getAddrOfUnnamedGlobalConstantDecl: non-typed initializer");
3696 std::string name = numEntries == 0
3698 : (Twine(
".constant.") + Twine(numEntries)).str();
3699 auto globalOp =
createGlobalOp(*
this, builder.getUnknownLoc(), name,
3700 typedInit.getType(),
true);
3701 globalOp.setLinkage(cir::GlobalLinkageKind::PrivateLinkage);
3704 globalOp.setAlignment(alignment.
getAsAlign().value());
3708 *globalOpEntry = globalOp;
3723 "emitForInitializer should take tpo->getType().getAddressSpace()");
3724 mlir::Attribute init =
3734 cir::GlobalLinkageKind linkage =
3736 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
3737 : cir::GlobalLinkageKind::InternalLinkage;
3740 auto globalOp =
createGlobalOp(*
this, builder.getUnknownLoc(), name,
3741 typedInit.getType(),
true);
3742 globalOp.setLinkage(linkage);
3743 globalOp.setAlignment(alignment.
getAsAlign().value());
3745 linkage == cir::GlobalLinkageKind::LinkOnceODRLinkage);
3760CIRGenModule::getOrCreateAnnotationArgs(
const AnnotateAttr *
attr) {
3767 llvm::FoldingSetNodeID id;
3768 for (
Expr *e : exprs)
3771 mlir::ArrayAttr &lookup = annotationArgs[
id.ComputeHash()];
3776 args.reserve(exprs.size());
3777 for (
Expr *e : exprs) {
3778 if (
auto *strE = dyn_cast<clang::StringLiteral>(e->IgnoreParenCasts())) {
3779 args.push_back(builder.getStringAttr(strE->getString()));
3780 }
else if (
auto *intE =
3781 dyn_cast<clang::IntegerLiteral>(e->IgnoreParenCasts())) {
3782 auto intTy = builder.getIntegerType(intE->getValue().getBitWidth());
3783 args.push_back(builder.getIntegerAttr(intTy, intE->getValue()));
3785 errorNYI(e->getExprLoc(),
"annotation argument expression");
3789 return lookup = builder.getArrayAttr(args);
3792cir::AnnotationAttr CIRGenModule::emitAnnotateAttr(
const AnnotateAttr *aa) {
3793 mlir::StringAttr annoGV = builder.getStringAttr(aa->getAnnotation());
3794 mlir::ArrayAttr args = getOrCreateAnnotationArgs(aa);
3795 return cir::AnnotationAttr::get(&
getMLIRContext(), annoGV, args);
3799 mlir::Operation *gv) {
3800 assert(d->
hasAttr<AnnotateAttr>() &&
"no annotate attribute");
3802 "annotation only on globals");
3805 annotations.push_back(emitAnnotateAttr(i));
3806 if (
auto global = dyn_cast<cir::GlobalOp>(gv))
3807 global.setAnnotationsAttr(builder.getArrayAttr(annotations));
3808 else if (
auto func = dyn_cast<cir::FuncOp>(gv))
3809 func.setAnnotationsAttr(builder.getArrayAttr(annotations));
3812void CIRGenModule::emitGlobalAnnotations() {
3813 for (
const auto &[mangledName, vd] : deferredAnnotations) {
3818 deferredAnnotations.clear();
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
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 mlir::Attribute getNewInitValue(CIRGenModule &cgm, cir::GlobalOp newGlob, mlir::Type oldTy, mlir::Attribute oldInit)
static bool hasUnwindExceptions(const LangOptions &langOpts)
Determines whether the language options require us to model unwind exceptions.
static void setWindowsItaniumDLLImport(CIRGenModule &cgm, bool isLocal, cir::FuncOp funcOp, StringRef name)
static std::string getMangledNameImpl(CIRGenModule &cgm, GlobalDecl gd, const NamedDecl *nd)
static llvm::SmallVector< int64_t > indexesOfArrayAttr(mlir::ArrayAttr indexes)
static bool isViewOnGlobal(cir::GlobalOp glob, cir::GlobalViewAttr view)
static cir::GlobalOp generateStringLiteral(mlir::Location loc, mlir::TypedAttr c, cir::GlobalLinkageKind lt, CIRGenModule &cgm, StringRef globalName, CharUnits alignment)
static bool hasImplicitAttr(const ValueDecl *decl)
static std::vector< std::string > getFeatureDeltaFromDefault(const CIRGenModule &cgm, llvm::StringRef targetCPU, llvm::StringMap< bool > &featureMap)
Get the feature delta from the default feature map for the given target CPU.
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)
static void emitUsed(CIRGenModule &cgm, StringRef name, std::vector< cir::CIRGlobalValueInterface > &list)
static bool verifyPointerTypeArgs(mlir::ModuleOp modOp, cir::FuncOp oldF, cir::FuncOp newF)
static cir::GlobalViewAttr createNewGlobalView(CIRGenModule &cgm, cir::GlobalOp newGlob, cir::GlobalViewAttr attr, mlir::Type oldTy)
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.
This file defines OpenMP AST classes for executable directives and clauses.
__device__ __2f16 float __ockl_bool s
__device__ __2f16 float c
cir::GlobalViewAttr getGlobalViewAttr(cir::GlobalOp globalOp, mlir::ArrayAttr indices={})
Get constant address of a global variable as an MLIR attribute.
cir::PointerType getPointerTo(mlir::Type ty)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
@ 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...
StringRef getCUIDHash() const
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.
DiagnosticsEngine & getDiagnostics() const
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.
mlir::Attribute getConstRecordOrZeroAttr(mlir::ArrayAttr arrayAttr, bool packed=false, bool padded=false, mlir::Type type={})
uint64_t computeOffsetFromGlobalViewIndices(const cir::CIRDataLayout &layout, mlir::Type ty, llvm::ArrayRef< int64_t > indices)
void computeGlobalViewIndicesFromFlatOffset(int64_t offset, mlir::Type ty, cir::CIRDataLayout layout, llvm::SmallVectorImpl< int64_t > &indices)
cir::ConstArrayAttr getConstArray(mlir::Attribute attrs, cir::ArrayType arrayTy) const
virtual mlir::Operation * getKernelHandle(cir::FuncOp fn, GlobalDecl gd)=0
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
llvm::ArrayRef< CanQualType > arguments() 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.
cir::GlobalOp getAddrOfUnnamedGlobalConstantDecl(const UnnamedGlobalConstantDecl *gcd)
void updateResolvedBlockAddress(cir::BlockAddressOp op, cir::LabelOp newLabel)
void addUsedOrCompilerUsedGlobal(cir::CIRGlobalValueInterface gv)
Add a global to a list to be added to the llvm.compiler.used metadata.
void replaceUsesOfNonProtoTypeWithRealFunction(mlir::Operation *old, cir::FuncOp newFn)
This function is called when we implement a function with no prototype, e.g.
static cir::GlobalOp createGlobalOp(CIRGenModule &cgm, mlir::Location loc, llvm::StringRef name, mlir::Type t, bool isConstant=false, mlir::ptr::MemorySpaceAttrInterface addrSpace={}, mlir::Operation *insertPoint=nullptr)
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.
cir::GlobalLinkageKind getCIRLinkageVarDefinition(const VarDecl *vd)
clang::ASTContext & getASTContext() const
void insertGlobalSymbol(mlir::Operation *op)
cir::FuncOp getAddrOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
CIRGenCUDARuntime & getCUDARuntime()
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.
std::vector< cir::CIRGlobalValueInterface > llvmUsed
List of global values which are required to be present in the object file; This is used for forcing v...
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.
cir::GlobalOp getAddrOfTemplateParamObject(const TemplateParamObjectDecl *tpo)
Get the GlobalOp of a template parameter object.
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.
llvm::DenseMap< const UnnamedGlobalConstantDecl *, cir::GlobalOp > unnamedGlobalConstantDeclMap
std::vector< cir::CIRGlobalValueInterface > llvmCompilerUsed
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
cir::GlobalLinkageKind getCIRLinkageForDeclarator(const DeclaratorDecl *dd, GVALinkage linkage)
mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty, bool forEH=false)
Get the address of the RTTI descriptor for the given type.
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)
void addUsedGlobal(cir::CIRGlobalValueInterface gv)
Add a global value to the llvmUsed list.
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.
void emitGlobalVarDefinition(const clang::VarDecl *vd, bool isTentative=false)
cir::FuncOp createRuntimeFunction(cir::FuncType ty, llvm::StringRef name, mlir::NamedAttrList extraAttrs={}, bool isLocal=false, bool assumeConvergent=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)
void emitLLVMUsed()
Emit llvm.used and llvm.compiler.used globals.
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.
const cir::CIRDataLayout getDataLayout() const
void eraseGlobalSymbol(mlir::Operation *op)
mlir::Operation * getAddrOfGlobalTemporary(const MaterializeTemporaryExpr *mte, const Expr *init)
Returns a pointer to a global variable representing a temporary with static or thread storage duratio...
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.
llvm::StringMap< mlir::Operation * > symbolLookupCache
Cache for O(1) symbol lookups by name, replacing the O(N) linear scan in SymbolTable::lookupSymbolIn ...
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
void emitDeferredVTables()
Emit any vtables which we deferred and still have a use for.
const clang::LangOptions & getLangOpts() const
void constructAttributeList(llvm::StringRef name, const CIRGenFunctionInfo &info, CIRGenCalleeInfo calleeInfo, mlir::NamedAttrList &attrs, llvm::MutableArrayRef< mlir::NamedAttrList > argAttrs, mlir::NamedAttrList &retAttrs, cir::CallingConv &callingConv, cir::SideEffect &sideEffect, bool attrOnCallSite, bool isThunk)
Get the CIR attributes and calling convention to use for a particular function type.
cir::FuncOp getOrCreateCIRFunction(llvm::StringRef mangledName, mlir::Type funcType, clang::GlobalDecl gd, bool forVTable, bool dontDefer=false, bool isThunk=false, ForDefinition_t isForDefinition=NotForDefinition, mlir::NamedAttrList extraAttrs={})
void emitOpenACCRoutineDecl(const clang::FunctionDecl *funcDecl, cir::FuncOp func, SourceLocation pragmaLoc, ArrayRef< const OpenACCClause * > clauses)
void emitVTablesOpportunistically()
Try to emit external vtables as available_externally if they have emitted all inlined virtual functio...
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)
bool shouldEmitCUDAGlobalVar(const VarDecl *global) const
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
void replaceGlobal(cir::GlobalOp oldGV, cir::GlobalOp newGV)
Replace all uses of the old global with the new global, updating types and references as needed.
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::TypedAttr emitNullMemberAttr(QualType t, const MemberPointerType *mpt)
Returns a null attribute to represent either a null method or null data member, depending on the type...
mlir::Operation * getGlobalValue(llvm::StringRef ref)
void emitOMPDeclareReduction(const OMPDeclareReductionDecl *d)
mlir::ModuleOp getModule() const
bool supportsCOMDAT() const
void addCompilerUsedGlobal(cir::CIRGlobalValueInterface gv)
Add a global value to the llvmCompilerUsed list.
clang::CharUnits getNaturalTypeAlignment(clang::QualType t, LValueBaseInfo *baseInfo=nullptr, bool forPointeeType=false)
FIXME: this could likely be a common helper and not necessarily related with codegen.
mlir::MLIRContext & getMLIRContext()
mlir::Operation * getAddrOfGlobal(clang::GlobalDecl gd, ForDefinition_t isForDefinition=NotForDefinition)
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.
bool lookupRepresentativeDecl(llvm::StringRef mangledName, clang::GlobalDecl &gd) const
void emitDeclContext(const DeclContext *dc)
clang::CharUnits getNaturalPointeeTypeAlignment(clang::QualType t, LValueBaseInfo *baseInfo=nullptr)
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...
void mapBlockAddress(cir::BlockAddrInfoAttr blockInfo, cir::LabelOp label)
void addGlobalAnnotations(const clang::ValueDecl *d, mlir::Operation *gv)
Add global annotations for a global value (GlobalOp or FuncOp).
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)
std::vector< clang::GlobalDecl > deferredDeclsToEmit
void emitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *d)
CIRGenOpenMPRuntime & getOpenMPRuntime()
void emitAMDGPUMetadata()
Emits AMDGPU specific Metadata.
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,...
void emitDeclareTargetFunction(const FunctionDecl *fd, cir::FuncOp funcOp)
If the function has an OMPDeclareTargetDeclAttr, set the corresponding omp.declare_target attribute o...
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.
void finalize(cir::GlobalOp gv)
mlir::Attribute emitForInitializer(const APValue &value, QualType destType)
virtual clang::LangAS getGlobalVarAddressSpace(CIRGenModule &cgm, const clang::VarDecl *d) const
Get target favored AST address space of a global variable for languages other than OpenCL and CUDA.
virtual mlir::ptr::MemorySpaceAttrInterface getCIRAllocaAddressSpace() const
Get the address space for alloca.
virtual void setTargetAttributes(const clang::Decl *decl, mlir::Operation *global, CIRGenModule &module) const
Provides a convenient hook to handle extra target-specific attributes for the given global.
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.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
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
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
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.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
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.
FunctionDecl * getDefinition()
Get the definition for this declaration.
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.
CXXCtorType getCtorType() const
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...
clang::ObjCRuntime ObjCRuntime
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 &)
virtual void mangleReferenceTemporary(const VarDecl *D, unsigned ManglingNumber, raw_ostream &)=0
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
APValue * getOrCreateValue(bool MayCreate) const
Get the storage for the constant value of a materialized temporary of static storage duration.
ValueDecl * getExtendingDecl()
Get the declaration which triggered the lifetime-extension of this temporary, if any.
unsigned getManglingNumber() const
A pointer to member type per C++ 8.3.3 - Pointers to members.
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.
bool hasUnwindExceptions() const
Does this runtime use zero-cost exceptions?
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?
TargetOptions & getTargetOpts() const
Retrieve the target options.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
bool isReadOnlyFeature(StringRef Feature) const
Determine whether the given target feature is read only.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
virtual bool initFeatureMap(llvm::StringMap< bool > &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector< std::string > &FeatureVec) const
Initialize the map with the default set of target features for the CPU this should include all legal ...
std::vector< std::string > Features
The list of target specific features to enable or disable – this should be a list of strings starting...
std::string TuneCPU
If given, the name of the target CPU to tune code for.
std::string CPU
If given, the name of the target CPU to generate code for.
A template parameter object.
const APValue & getValue() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() const
bool isReferenceType() const
bool isCUDADeviceBuiltinSurfaceType() const
Check if the type is the CUDA device builtin surface type.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isCUDADeviceBuiltinTextureType() const
Check if the type is the CUDA device builtin texture type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isObjCObjectPointerType() const
bool isMemberFunctionPointerType() const
const T * getAs() const
Member-template getAs<specific type>'.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
An artificial decl, representing a global anonymous constant value which is uniquified by value withi...
const APValue & getValue() 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.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
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.
@ DeclarationOnly
This declaration is only a declaration.
@ 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.
bool isMatchingAddressSpace(mlir::ptr::MemorySpaceAttrInterface cirAS, clang::LangAS as)
mlir::ptr::MemorySpaceAttrInterface toCIRAddressSpaceAttr(mlir::MLIRContext &ctx, clang::LangAS langAS)
Convert an AST LangAS to the appropriate CIR address space attribute interface.
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 ...
std::unique_ptr< TargetCIRGenInfo > createAMDGPUTargetCIRGenInfo(CIRGenTypes &cgt)
std::unique_ptr< TargetCIRGenInfo > createNVPTXTargetCIRGenInfo(CIRGenTypes &cgt)
CIRGenCXXABI * CreateCIRGenItaniumCXXABI(CIRGenModule &cgm)
Creates and Itanium-family ABI.
std::unique_ptr< TargetCIRGenInfo > createX8664TargetCIRGenInfo(CIRGenTypes &cgt)
CIRGenCUDARuntime * createNVCUDARuntime(CIRGenModule &cgm)
const internal::VariadicDynCastAllOfMatcher< Decl, VarDecl > varDecl
Matches variable declarations.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, FieldDecl > fieldDecl
Matches field declarations.
const internal::VariadicDynCastAllOfMatcher< Decl, FunctionDecl > functionDecl
Matches function 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
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ SD_Thread
Thread storage duration.
@ SD_Static
Static storage duration.
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Dtor_Complete
Complete object dtor.
LangAS
Defines the address space values used by the address space qualifier of QualType.
@ FirstTargetAddressSpace
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 opFuncArmNewAttr()
static bool getRuntimeFunctionDecl()
static bool weakRefReference()
static bool opFuncOptNoneAttr()
static bool addressSpace()
static bool opFuncMinSizeAttr()
static bool opGlobalUnnamedAddr()
static bool opGlobalThreadLocal()
static bool opFuncMultiVersioning()
static bool sourceLanguageCases()
static bool opFuncAstDeclAttr()
static bool opFuncNoDuplicateAttr()
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 attributeNoBuiltin()
static bool opGlobalDLLImportExport()
static bool opGlobalPartition()
static bool opGlobalPragmaClangSection()
static bool opGlobalWeakRef()
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 cudaSupport()
static bool opFuncMaybeHandleStaticInExternC()
static bool generateDebugInfo()
static bool targetCIRGenInfoOS()
static bool maybeHandleStaticInExternC()
static bool setLLVMFunctionFEnvAttributes()
mlir::Type uCharTy
ClangIR char.
unsigned char SizeSizeInBytes
unsigned char PointerAlignInBytes
cir::PointerType allocaInt8PtrTy
void* in alloca address space
cir::PointerType uInt8PtrTy
mlir::ptr::MemorySpaceAttrInterface cirAllocaAddressSpace
cir::PointerType voidPtrTy
void* in address space 0
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
bool hasSideEffects() const
Return true if the evaluated expression has side effects.