19#include "mlir/Dialect/OpenMP/Utils/Utils.h"
20#include "mlir/IR/SymbolTable.h"
23#include "clang/AST/Attrs.inc"
37#include "llvm/ADT/STLExtras.h"
38#include "llvm/ADT/StringExtras.h"
39#include "llvm/ADT/StringRef.h"
40#include "llvm/ADT/StringSwitch.h"
41#include "llvm/Support/raw_ostream.h"
45#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
46#include "mlir/IR/Attributes.h"
47#include "mlir/IR/BuiltinOps.h"
48#include "mlir/IR/Location.h"
49#include "mlir/IR/MLIRContext.h"
50#include "mlir/IR/Operation.h"
51#include "mlir/IR/Verifier.h"
60 case TargetCXXABI::GenericItanium:
61 case TargetCXXABI::GenericAArch64:
62 case TargetCXXABI::AppleARM64:
63 case TargetCXXABI::GenericARM:
66 case TargetCXXABI::Fuchsia:
67 case TargetCXXABI::iOS:
68 case TargetCXXABI::WatchOS:
69 case TargetCXXABI::GenericMIPS:
70 case TargetCXXABI::WebAssembly:
71 case TargetCXXABI::XL:
72 case TargetCXXABI::Microsoft:
73 cgm.
errorNYI(
"createCXXABI: C++ ABI kind");
77 llvm_unreachable(
"invalid C++ ABI kind");
80CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
84 : builder(mlirContext, *this), astContext(astContext),
85 langOpts(astContext.
getLangOpts()), codeGenOpts(cgo),
86 theModule{
mlir::ModuleOp::create(
mlir::UnknownLoc::get(&mlirContext))},
87 diags(diags), target(astContext.getTargetInfo()),
88 abi(
createCXXABI(*this)), genTypes(*this), vtables(*this) {
116 .toCharUnitsFromBits(
120 const unsigned charSize = astContext.getTargetInfo().getCharWidth();
124 const unsigned sizeTypeSize =
125 astContext.getTypeSize(astContext.getSignedSizeType());
126 SizeSizeInBytes = astContext.toCharUnitsFromBits(sizeTypeSize).getQuantity();
133 std::optional<cir::SourceLanguage> sourceLanguage = getCIRSourceLanguage();
136 cir::CIRDialect::getSourceLanguageAttrName(),
137 cir::SourceLanguageAttr::get(&mlirContext, *sourceLanguage));
138 theModule->setAttr(cir::CIRDialect::getTripleAttrName(),
139 builder.getStringAttr(
getTriple().str()));
141 if (cgo.OptimizationLevel > 0 || cgo.OptimizeSize > 0)
142 theModule->setAttr(cir::CIRDialect::getOptInfoAttrName(),
143 cir::OptInfoAttr::get(&mlirContext,
144 cgo.OptimizationLevel,
147 if (langOpts.OpenMP) {
148 mlir::omp::OffloadModuleOpts ompOpts(
149 langOpts.OpenMPTargetDebug, langOpts.OpenMPTeamSubscription,
150 langOpts.OpenMPThreadSubscription, langOpts.OpenMPNoThreadState,
151 langOpts.OpenMPNoNestedParallelism, langOpts.OpenMPIsTargetDevice,
152 getTriple().isGPU(), langOpts.OpenMPForceUSM, langOpts.OpenMP,
153 langOpts.OMPHostIRFile, langOpts.OMPTargetTriples, langOpts.NoGPULib);
154 mlir::omp::setOffloadModuleInterfaceAttributes(theModule, ompOpts);
155 mlir::omp::setOpenMPVersionAttribute(theModule, langOpts.OpenMP);
161 createOpenMPRuntime();
166 FileID mainFileId = astContext.getSourceManager().getMainFileID();
168 *astContext.getSourceManager().getFileEntryForID(mainFileId);
171 theModule.setSymName(path);
172 theModule->setLoc(mlir::FileLineColLoc::get(&mlirContext, path,
179 llvm::StringRef cudaBinaryName = codeGenOpts.CudaGpuBinaryFileName;
180 if (!cudaBinaryName.empty()) {
181 theModule->setAttr(cir::CIRDialect::getCUDABinaryHandleAttrName(),
182 cir::CUDABinaryHandleAttr::get(
183 &mlirContext, mlir::StringAttr::get(
184 &mlirContext, cudaBinaryName)));
191void CIRGenModule::createCUDARuntime() {
195void CIRGenModule::createOpenMPRuntime() {
196 openMPRuntime = std::make_unique<CIRGenOpenMPRuntime>(*
this);
207 auto &layout = astContext.getASTRecordLayout(rd);
212 return layout.getAlignment();
215 return layout.getNonVirtualAlignment();
220 bool forPointeeType) {
230 if (
unsigned align = tt->getDecl()->getMaxAlignment()) {
233 return astContext.toCharUnitsFromBits(align);
241 t = astContext.getBaseElementType(t);
262 }
else if (forPointeeType && !alignForArray &&
266 alignment = astContext.getTypeAlignInChars(t);
271 if (
unsigned maxAlign = astContext.getLangOpts().MaxTypeAlign) {
273 !astContext.isAlignmentRequired(t))
287 if (theTargetCIRGenInfo)
288 return *theTargetCIRGenInfo;
291 switch (triple.getArch()) {
298 case llvm::Triple::x86_64: {
299 switch (triple.getOS()) {
306 case llvm::Triple::Linux:
308 return *theTargetCIRGenInfo;
311 case llvm::Triple::nvptx:
312 case llvm::Triple::nvptx64:
314 return *theTargetCIRGenInfo;
315 case llvm::Triple::amdgpu: {
317 return *theTargetCIRGenInfo;
319 case llvm::Triple::spirv:
320 case llvm::Triple::spirv32:
321 case llvm::Triple::spirv64:
323 return *theTargetCIRGenInfo;
328 assert(cLoc.
isValid() &&
"expected valid source location");
332 return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
337 assert(cRange.
isValid() &&
"expected a valid source range");
340 mlir::Attribute metadata;
341 return mlir::FusedLoc::get({begin, end}, metadata, builder.getContext());
350 false, isForDefinition);
384 assert(op &&
"expected a valid global op");
392 mlir::Operation *globalValueOp = op;
393 if (
auto gv = dyn_cast<cir::GetGlobalOp>(op)) {
395 assert(globalValueOp &&
"expected a valid global op");
398 if (
auto cirGlobalValue =
399 dyn_cast<cir::CIRGlobalValueInterface>(globalValueOp))
400 if (!cirGlobalValue.isDeclaration())
421 assert(deferredVTables.empty());
431 std::vector<GlobalDecl> curDeclsToEmit;
439 if (
const auto *fd = d.getDecl()->getAsFunction()) {
440 if (langOpts.SYCLIsDevice && fd->hasAttr<SYCLKernelEntryPointAttr>() &&
444 if (!fd->getAttr<SYCLKernelEntryPointAttr>()->isInvalidAttr())
446 "SYCL kernel caller offload entry point");
467 if (
auto *
attr =
decl->getAttr<AttrT>())
468 return attr->isImplicit();
469 return decl->isImplicit();
474 assert(langOpts.CUDA &&
"Should not be called by non-CUDA languages");
479 return !langOpts.CUDAIsDevice || global->
hasAttr<CUDADeviceAttr>() ||
480 global->
hasAttr<CUDAConstantAttr>() ||
481 global->
hasAttr<CUDASharedAttr>() ||
491 os << (isa<VarDecl>(d) ?
".static." :
".intern.");
493 os << (isa<VarDecl>(d) ?
"__static__" :
"__intern__");
500 "printPostfixForExternalizedDecl: CUID is not specified");
507 if (
const auto *cd = dyn_cast<clang::OpenACCConstructDecl>(gd.
getDecl())) {
515 if (global->hasAttr<WeakRefAttr>())
520 if (global->hasAttr<AliasAttr>()) {
533 "Expected Variable or Function");
534 if (
const auto *
varDecl = dyn_cast<VarDecl>(global)) {
538 }
else if (langOpts.CUDAIsDevice) {
539 const auto *
functionDecl = dyn_cast<FunctionDecl>(global);
540 if ((!global->hasAttr<CUDADeviceAttr>() ||
541 (langOpts.OffloadImplicitHostDeviceTemplates &&
546 !
getASTContext().CUDAImplicitHostDeviceFunUsedByDevice.count(
548 !global->hasAttr<CUDAGlobalAttr>() &&
550 !global->hasAttr<CUDAHostAttr>()))
553 }
else if (!global->hasAttr<CUDAHostAttr>() &&
554 global->hasAttr<CUDADeviceAttr>())
558 if (langOpts.OpenMP) {
560 if (openMPRuntime && openMPRuntime->emitTargetGlobal(gd))
562 if (
auto *drd = dyn_cast<OMPDeclareReductionDecl>(global)) {
567 if (
auto *dmd = dyn_cast<OMPDeclareMapperDecl>(global)) {
574 if (
const auto *fd = dyn_cast<FunctionDecl>(global)) {
577 if (fd->hasAttr<AnnotateAttr>()) {
580 deferredAnnotations[mangledName] = fd;
582 if (!fd->doesThisDeclarationHaveABody()) {
583 if (!fd->doesDeclarationForceExternallyVisibleDefinition() &&
594 assert(vd->isFileVarDecl() &&
"Cannot emit local var decl as global.");
596 !astContext.isMSStaticDataMemberInlineDefinition(vd)) {
600 if (astContext.getInlineVariableDefinitionKind(vd) ==
639 mlir::Operation *op) {
643 cir::FuncOp funcOp = dyn_cast_if_present<cir::FuncOp>(op);
644 if (!funcOp || funcOp.getFunctionType() != funcType) {
650 if (!funcOp.isDeclaration())
662 mlir::OpBuilder::InsertionGuard guard(builder);
667 setNonAliasAttributes(gd, funcOp);
670 auto getPriority = [
this](
const auto *
attr) ->
int {
674 return attr->DefaultPriority;
677 if (
const ConstructorAttr *ca = funcDecl->getAttr<ConstructorAttr>())
679 if (
const DestructorAttr *da = funcDecl->getAttr<DestructorAttr>())
682 if (funcDecl->getAttr<AnnotateAttr>())
685 if (
getLangOpts().OpenMP && funcDecl->hasAttr<OMPDeclareTargetDeclAttr>())
691 std::optional<int> priority) {
700 ctor.setGlobalCtorPriority(priority);
705 std::optional<int> priority) {
706 if (codeGenOpts.RegisterGlobalDtorsWithAtExit &&
708 errorNYI(dtor.getLoc(),
"registerGlobalDtorsWithAtExit");
711 dtor.setGlobalDtorPriority(priority);
736 mlir::ptr::MemorySpaceAttrInterface addrSpace,
737 mlir::Operation *insertPoint) {
742 mlir::OpBuilder::InsertionGuard guard(builder);
748 builder.setInsertionPoint(insertPoint);
754 builder.setInsertionPointToStart(
getModule().getBody());
757 g = cir::GlobalOp::create(builder, loc, name, t, isConstant, addrSpace);
763 mlir::SymbolTable::setSymbolVisibility(
764 g, mlir::SymbolTable::Visibility::Private);
772 if (isa_and_nonnull<NamedDecl>(d))
776 if (
auto gvi = mlir::dyn_cast<cir::CIRGlobalValueInterface>(gv)) {
777 if (d && d->
hasAttr<UsedAttr>())
780 if (
const auto *vd = dyn_cast_if_present<VarDecl>(d);
781 vd && ((codeGenOpts.KeepPersistentStorageVariables &&
782 (vd->getStorageDuration() ==
SD_Static ||
783 vd->getStorageDuration() ==
SD_Thread)) ||
784 (codeGenOpts.KeepStaticConsts &&
786 vd->getType().isConstQualified())))
792static std::vector<std::string>
794 llvm::StringMap<bool> &featureMap) {
795 llvm::StringMap<bool> defaultFeatureMap;
799 std::vector<std::string> delta;
800 for (
const auto &[k, v] : featureMap) {
801 auto defaultIt = defaultFeatureMap.find(k);
802 if (defaultIt == defaultFeatureMap.end() || defaultIt->getValue() != v)
803 delta.push_back((v ?
"+" :
"-") + k.str());
809bool CIRGenModule::getCPUAndFeaturesAttributes(
810 GlobalDecl gd, llvm::StringMap<std::string> &attrs,
811 bool setTargetFeatures) {
817 std::vector<std::string> features;
821 const auto *fd = dyn_cast_or_null<FunctionDecl>(gd.
getDecl());
822 fd = fd ? fd->getMostRecentDecl() : fd;
823 const auto *td = fd ? fd->getAttr<TargetAttr>() :
nullptr;
824 const auto *tv = fd ? fd->getAttr<TargetVersionAttr>() :
nullptr;
825 assert((!td || !tv) &&
"both target_version and target specified");
826 const auto *sd = fd ? fd->getAttr<CPUSpecificAttr>() :
nullptr;
827 const auto *tc = fd ? fd->getAttr<TargetClonesAttr>() :
nullptr;
828 bool addedAttr =
false;
829 if (td || tv || sd || tc) {
830 llvm::StringMap<bool> featureMap;
831 astContext.getFunctionFeatureMap(featureMap, gd);
837 llvm::StringRef featureStr = td ? td->getFeaturesStr() : llvm::StringRef();
840 if (!featureStr.empty()) {
841 clang::ParsedTargetAttr parsedAttr =
843 if (!parsedAttr.
CPU.empty() &&
845 targetCPU = parsedAttr.
CPU;
848 if (!parsedAttr.
Tune.empty() &&
850 tuneCPU = parsedAttr.
Tune;
866 features.reserve(features.size() + featureMap.size());
867 for (
const auto &entry : featureMap)
868 features.push_back((entry.getValue() ?
"+" :
"-") +
869 entry.getKey().str());
874 llvm::StringMap<bool> featureMap;
876 astContext.getFunctionFeatureMap(featureMap, gd);
887 if (!targetCPU.empty()) {
888 attrs[
"cir.target-cpu"] = targetCPU.str();
891 if (!tuneCPU.empty()) {
892 attrs[
"cir.tune-cpu"] = tuneCPU.str();
895 if (!features.empty() && setTargetFeatures) {
896 llvm::erase_if(features, [&](
const std::string &f) {
897 assert(!f.empty() && (f[0] ==
'+' || f[0] ==
'-') &&
898 "feature string must start with '+' or '-'");
901 llvm::sort(features);
902 attrs[
"cir.target-features"] = llvm::join(features,
",");
910void CIRGenModule::setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op) {
915 if (
auto gvi = mlir::dyn_cast<cir::CIRGlobalValueInterface>(op)) {
916 if (
const auto *sa = d->
getAttr<SectionAttr>())
917 gvi.setSection(builder.getStringAttr(sa->getName()));
921 if (
auto func = dyn_cast<cir::FuncOp>(op)) {
922 llvm::StringMap<std::string> attrs;
923 if (getCPUAndFeaturesAttributes(gd, attrs)) {
927 for (
const auto &[key, val] : attrs)
928 func->setAttr(key, builder.getStringAttr(val));
938std::optional<cir::SourceLanguage> CIRGenModule::getCIRSourceLanguage()
const {
939 using ClangStd = clang::LangStandard;
940 using CIRLang = cir::SourceLanguage;
945 if (opts.C99 || opts.C11 || opts.C17 || opts.C23 || opts.C2y ||
946 opts.LangStd == ClangStd::lang_c89 ||
947 opts.LangStd == ClangStd::lang_gnu89)
952 errorNYI(
"CIR does not yet support the given source language");
956LangAS CIRGenModule::getGlobalVarAddressSpace(
const VarDecl *d) {
957 if (langOpts.OpenCL) {
965 if (langOpts.SYCLIsDevice &&
967 errorNYI(
"SYCL global address space");
969 if (langOpts.CUDA && langOpts.CUDAIsDevice) {
971 if (d->
hasAttr<CUDAConstantAttr>())
973 if (d->
hasAttr<CUDASharedAttr>())
975 if (d->
hasAttr<CUDADeviceAttr>())
984 errorNYI(
"OpenMP global address space");
997 gv.
setLinkage(cir::GlobalLinkageKind::ExternalWeakLinkage);
1006 auto linkage = cir::GlobalLinkageKind::ExternalWeakLinkage;
1007 func.setLinkage(linkage);
1008 func.setLinkageAttr(
1009 cir::GlobalLinkageKindAttr::get(&cgm.
getMLIRContext(), linkage));
1011 if (!func.isDeclaration())
1012 mlir::SymbolTable::setSymbolVisibility(
1019 for (mlir::Attribute i : indexes) {
1020 auto ind = mlir::cast<mlir::IntegerAttr>(i);
1021 inds.push_back(ind.getValue().getSExtValue());
1027 return view.getSymbol().getValue() == glob.getSymName();
1031 cir::GlobalOp newGlob,
1032 cir::GlobalViewAttr
attr,
1043 mlir::Type newTy = newGlob.getSymType();
1048 cir::PointerType newPtrTy;
1051 newPtrTy = cir::PointerType::get(newTy);
1060 cgm.
errorNYI(
"Unhandled type in createNewGlobalView");
1066 mlir::Attribute oldInit) {
1067 if (
auto oldView = mlir::dyn_cast<cir::GlobalViewAttr>(oldInit))
1070 auto getNewInitElements =
1071 [&](mlir::ArrayAttr oldElements) -> mlir::ArrayAttr {
1073 for (mlir::Attribute elt : oldElements) {
1074 if (
auto view = mlir::dyn_cast<cir::GlobalViewAttr>(elt))
1076 else if (mlir::isa<cir::ConstArrayAttr, cir::ConstRecordAttr>(elt))
1079 newElements.push_back(elt);
1081 return mlir::ArrayAttr::get(cgm.
getBuilder().getContext(), newElements);
1084 if (
auto oldArray = mlir::dyn_cast<cir::ConstArrayAttr>(oldInit)) {
1090 mlir::Attribute oldElts = oldArray.getElts();
1091 if (mlir::isa<mlir::StringAttr>(oldElts))
1093 mlir::Attribute newElements =
1094 getNewInitElements(mlir::cast<mlir::ArrayAttr>(oldElts));
1096 newElements, mlir::cast<cir::ArrayType>(oldArray.getType()));
1098 if (
auto oldRecord = mlir::dyn_cast<cir::ConstRecordAttr>(oldInit)) {
1099 mlir::ArrayAttr newMembers = getNewInitElements(oldRecord.getMembers());
1100 auto recordTy = mlir::cast<cir::RecordType>(oldRecord.getType());
1102 newMembers, recordTy.getPacked(), recordTy.getPadded(), recordTy);
1107 cgm.
errorNYI(
"Unhandled type in getNewInitValue");
1115 assert(oldGV.getSymName() == newGV.getSymName() &&
"symbol names must match");
1117 mlir::Type oldTy = oldGV.getSymType();
1118 mlir::Type newTy = newGV.getSymType();
1123 assert(oldTy != newTy &&
"expected type change in replaceGlobal");
1126 std::optional<mlir::SymbolTable::UseRange> oldSymUses =
1127 oldGV.getSymbolUses(theModule);
1128 for (mlir::SymbolTable::SymbolUse use : *oldSymUses) {
1129 mlir::Operation *userOp = use.getUser();
1131 (mlir::isa<cir::GetGlobalOp, cir::GlobalOp, cir::ConstantOp>(userOp)) &&
1132 "Unexpected user for global op");
1134 if (
auto getGlobalOp = dyn_cast<cir::GetGlobalOp>(use.getUser())) {
1135 mlir::Value useOpResultValue = getGlobalOp.getAddr();
1136 useOpResultValue.setType(cir::PointerType::get(newTy));
1138 mlir::OpBuilder::InsertionGuard guard(builder);
1139 builder.setInsertionPointAfter(getGlobalOp);
1140 mlir::Type ptrTy = builder.getPointerTo(oldTy);
1142 builder.createBitcast(getGlobalOp->getLoc(), useOpResultValue, ptrTy);
1143 useOpResultValue.replaceAllUsesExcept(
cast,
cast.getDefiningOp());
1144 }
else if (
auto glob = dyn_cast<cir::GlobalOp>(userOp)) {
1145 if (
auto init = glob.getInitialValue()) {
1146 mlir::Attribute nw =
getNewInitValue(*
this, newGV, oldTy, init.value());
1147 glob.setInitialValueAttr(nw);
1149 }
else if (
auto c = dyn_cast<cir::ConstantOp>(userOp)) {
1150 mlir::Attribute init =
getNewInitValue(*
this, newGV, oldTy, c.getValue());
1151 auto typedAttr = mlir::cast<mlir::TypedAttr>(init);
1152 mlir::OpBuilder::InsertionGuard guard(builder);
1153 builder.setInsertionPointAfter(c);
1154 auto newUser = cir::ConstantOp::create(builder, c.getLoc(), typedAttr);
1155 c.replaceAllUsesWith(newUser.getOperation());
1191 cir::GlobalOp entry;
1195 "getOrCreateCIRGlobal: global with non-GlobalOp type");
1200 mlir::ptr::MemorySpaceAttrInterface entryCIRAS = entry.getAddrSpaceAttr();
1206 if (entry.getSymType() == ty &&
1216 if (isForDefinition && !entry.isDeclaration()) {
1218 "getOrCreateCIRGlobal: global with conflicting type");
1226 if (!isForDefinition)
1235 bool isConstant =
false;
1240 astContext,
true, !needsDtor);
1243 mlir::ptr::MemorySpaceAttrInterface declCIRAS =
1248 cir::GlobalOp gv =
createGlobalOp(loc, mangledName, ty, isConstant, declCIRAS,
1249 entry.getOperation());
1269 if (langOpts.OpenMP && !langOpts.OpenMPSimd)
1271 "getOrCreateCIRGlobal: OpenMP target global variable");
1273 gv.setAlignmentAttr(
getSize(astContext.getDeclAlign(d)));
1284 if (astContext.isMSStaticDataMemberInlineDefinition(d))
1286 "getOrCreateCIRGlobal: MS static data member inline definition");
1290 if (
const SectionAttr *sa = d->
getAttr<SectionAttr>())
1291 gv.setSectionAttr(builder.getStringAttr(sa->getName()));
1295 if (
getTriple().getArch() == llvm::Triple::xcore)
1297 "getOrCreateCIRGlobal: XCore specific ABI requirements");
1307 "getOrCreateCIRGlobal: external const declaration with initializer");
1319 "getOrCreateCIRGlobal: HIP managed attribute");
1354 mlir::Type ptrTy = builder.getPointerTo(g.getSymType(), g.getAddrSpaceAttr());
1355 return cir::GetGlobalOp::create(
1358 g.getStaticLocalGuard().has_value());
1366 cir::PointerType ptrTy =
1367 builder.getPointerTo(globalOp.getSymType(), globalOp.getAddrSpaceAttr());
1368 return builder.getGlobalViewAttr(ptrTy, globalOp);
1372 assert((mlir::isa<cir::FuncOp>(gv.getOperation()) ||
1373 !gv.isDeclarationForLinker()) &&
1374 "Only globals with definition can force usage.");
1379 assert(!gv.isDeclarationForLinker() &&
1380 "Only globals with definition can force usage.");
1385 cir::CIRGlobalValueInterface gv) {
1386 assert((mlir::isa<cir::FuncOp>(gv.getOperation()) ||
1387 !gv.isDeclarationForLinker()) &&
1388 "Only globals with definition can force usage.");
1396 std::vector<cir::CIRGlobalValueInterface> &list) {
1401 mlir::Location loc = builder.getUnknownLoc();
1403 usedArray.resize(list.size());
1404 for (
auto [i, op] : llvm::enumerate(list)) {
1405 usedArray[i] = cir::GlobalViewAttr::get(
1406 cgm.
voidPtrTy, mlir::FlatSymbolRefAttr::get(op.getNameAttr()));
1409 cir::ArrayType arrayTy = cir::ArrayType::get(cgm.
voidPtrTy, usedArray.size());
1411 cir::ConstArrayAttr initAttr = cir::ConstArrayAttr::get(
1412 arrayTy, mlir::ArrayAttr::get(&cgm.
getMLIRContext(), usedArray));
1416 gv.setLinkage(cir::GlobalLinkageKind::AppendingLinkage);
1417 gv.setInitialValueAttr(initAttr);
1418 gv.setSectionAttr(builder.getStringAttr(
"llvm.metadata"));
1430 "emitGlobalVarDefinition: emit OpenCL/OpenMP global variable");
1437 bool isDefinitionAvailableExternally =
1442 if (isDefinitionAvailableExternally &&
1450 mlir::Attribute init;
1451 bool needsGlobalCtor =
false;
1452 bool needsGlobalDtor =
1453 !isDefinitionAvailableExternally &&
1458 std::optional<ConstantEmitter> emitter;
1463 bool isCUDASharedVar =
1468 bool isCUDAShadowVar =
1470 (vd->
hasAttr<CUDAConstantAttr>() || vd->
hasAttr<CUDADeviceAttr>() ||
1471 vd->
hasAttr<CUDASharedAttr>());
1472 bool isCUDADeviceShadowVar =
1478 (isCUDASharedVar || isCUDAShadowVar || isCUDADeviceShadowVar)) {
1480 }
else if (vd->
hasAttr<LoaderUninitializedAttr>()) {
1482 "emitGlobalVarDefinition: loader uninitialized attribute");
1483 }
else if (!initExpr) {
1496 emitter.emplace(*
this);
1497 mlir::Attribute initializer = emitter->tryEmitForInitializer(*initDecl);
1506 "emitGlobalVarDefinition: flexible array initializer");
1508 if (!isDefinitionAvailableExternally)
1509 needsGlobalCtor =
true;
1512 "emitGlobalVarDefinition: static initializer");
1523 mlir::Type initType;
1524 if (mlir::isa<mlir::SymbolRefAttr>(init)) {
1527 "emitGlobalVarDefinition: global initializer is a symbol reference");
1530 assert(mlir::isa<mlir::TypedAttr>(init) &&
"This should have a type");
1531 auto typedInitAttr = mlir::cast<mlir::TypedAttr>(init);
1532 initType = typedInitAttr.getType();
1534 assert(!mlir::isa<mlir::NoneType>(initType) &&
"Should have a type by now");
1540 if (!gv || gv.getSymType() != initType) {
1542 "emitGlobalVarDefinition: global initializer with type mismatch");
1548 if (vd->
hasAttr<AnnotateAttr>())
1561 if (langOpts.CUDA) {
1562 if (langOpts.CUDAIsDevice) {
1565 if (linkage != cir::GlobalLinkageKind::InternalLinkage &&
1567 (vd->
hasAttr<CUDADeviceAttr>() || vd->
hasAttr<CUDAConstantAttr>() ||
1570 gv->setAttr(cir::CUDAExternallyInitializedAttr::getMnemonic(),
1583 emitter->finalize(gv);
1587 gv.setConstant((vd->
hasAttr<CUDAConstantAttr>() && langOpts.CUDAIsDevice) ||
1588 (!needsGlobalCtor && !needsGlobalDtor &&
1593 if (
const SectionAttr *sa = vd->
getAttr<SectionAttr>()) {
1596 gv.setConstant(
true);
1600 gv.setLinkage(linkage);
1604 if (linkage == cir::GlobalLinkageKind::CommonLinkage) {
1606 gv.setConstant(
false);
1611 std::optional<mlir::Attribute> initializer = gv.getInitialValue();
1612 if (initializer && !
getBuilder().isNullValue(*initializer))
1613 gv.setLinkage(cir::GlobalLinkageKind::WeakAnyLinkage);
1616 setNonAliasAttributes(vd, gv);
1624 if (needsGlobalCtor || needsGlobalDtor)
1630 cir::GlobalLinkageKind::AvailableExternallyLinkage)
1636 if (fd->isInlineBuiltinDeclaration())
1647 mlir::Operation *op) {
1649 if (
const auto *fd = dyn_cast<FunctionDecl>(
decl)) {
1653 if (
const auto *method = dyn_cast<CXXMethodDecl>(
decl)) {
1657 abi->emitCXXStructor(gd);
1658 else if (fd->isMultiVersion())
1659 errorNYI(method->getSourceRange(),
"multiversion functions");
1663 if (method->isVirtual())
1669 if (fd->isMultiVersion())
1670 errorNYI(fd->getSourceRange(),
"multiversion functions");
1675 if (
const auto *vd = dyn_cast<VarDecl>(
decl))
1678 llvm_unreachable(
"Invalid argument to CIRGenModule::emitGlobalDefinition");
1692 astContext.getAsConstantArrayType(e->
getType());
1693 uint64_t finalSize = cat->getZExtSize();
1694 str.resize(finalSize);
1696 mlir::Type eltTy =
convertType(cat->getElementType());
1697 return builder.getString(str, eltTy, finalSize,
false);
1702 auto arrayEltTy = mlir::cast<cir::IntType>(arrayTy.getElementType());
1704 uint64_t arraySize = arrayTy.getSize();
1706 assert(arraySize > literalSize &&
1707 "wide string literal array size must have room for null terminator?");
1711 bool isAllZero =
true;
1712 for (
unsigned i = 0; i < literalSize; ++i) {
1720 return cir::ZeroAttr::get(arrayTy);
1724 elements.reserve(arraySize);
1725 for (
unsigned i = 0; i < literalSize; ++i)
1726 elements.push_back(cir::IntAttr::get(arrayEltTy, e->
getCodeUnit(i)));
1728 auto elementsAttr = mlir::ArrayAttr::get(&
getMLIRContext(), elements);
1729 return builder.getConstArray(elementsAttr, arrayTy);
1740 if (d.
hasAttr<SelectAnyAttr>())
1744 if (
auto *vd = dyn_cast<VarDecl>(&d))
1759 llvm_unreachable(
"No such linkage");
1765 if (
auto globalOp = dyn_cast_or_null<cir::GlobalOp>(op)) {
1766 globalOp.setComdat(
true);
1769 funcOp.setComdat(
true);
1775 genTypes.updateCompletedType(td);
1779 replacements[name] = op;
1784 mlir::SymbolUserMap &userMap) {
1785 for (mlir::Operation *user : userMap.getUsers(oldF)) {
1786 auto call = mlir::dyn_cast<cir::CallOp>(user);
1790 for (
auto [argOp, fnArgType] :
1791 llvm::zip(call.getArgs(), newF.getFunctionType().getInputs())) {
1792 if (argOp.getType() != fnArgType)
1801void CIRGenModule::applyReplacements() {
1802 if (replacements.empty())
1808 mlir::SymbolTableCollection symbolTableCollection;
1809 mlir::SymbolUserMap userMap(symbolTableCollection, theModule);
1811 for (
auto &i : replacements) {
1812 StringRef mangledName = i.first;
1813 mlir::Operation *replacement = i.second;
1819 auto newF = dyn_cast<cir::FuncOp>(replacement);
1822 errorNYI(replacement->getLoc(),
"replacement is not a function");
1827 "call argument types do not match replacement function");
1831 userMap.replaceAllUsesWith(oldF, newF.getSymNameAttr());
1832 newF->moveBefore(oldF);
1839 mlir::Location loc, StringRef name, mlir::Type ty,
1841 auto gv = mlir::dyn_cast_or_null<cir::GlobalOp>(
getGlobalValue(name));
1845 if (gv.getSymType() == ty)
1851 assert(gv.isDeclaration() &&
"Declaration has wrong type!");
1853 errorNYI(loc,
"createOrReplaceCXXRuntimeVariable: declaration exists with "
1864 mlir::SymbolTable::setSymbolVisibility(gv,
1868 !gv.hasAvailableExternallyLinkage()) {
1872 gv.setAlignmentAttr(
getSize(alignment));
1883 if ((noCommon || vd->
hasAttr<NoCommonAttr>()) && !vd->
hasAttr<CommonAttr>())
1894 if (vd->
hasAttr<SectionAttr>())
1900 if (vd->
hasAttr<PragmaClangBSSSectionAttr>() ||
1901 vd->
hasAttr<PragmaClangDataSectionAttr>() ||
1902 vd->
hasAttr<PragmaClangRelroSectionAttr>() ||
1903 vd->
hasAttr<PragmaClangRodataSectionAttr>())
1911 if (vd->
hasAttr<WeakImportAttr>())
1921 if (vd->
hasAttr<AlignedAttr>())
1928 for (
const FieldDecl *fd : rd->fields()) {
1929 if (fd->isBitField())
1931 if (fd->hasAttr<AlignedAttr>())
1953cir::GlobalLinkageKind
1957 return cir::GlobalLinkageKind::InternalLinkage;
1960 return cir::GlobalLinkageKind::WeakAnyLinkage;
1964 return cir::GlobalLinkageKind::LinkOnceAnyLinkage;
1969 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
1983 return !astContext.getLangOpts().AppleKext
1984 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
1985 : cir::GlobalLinkageKind::InternalLinkage;
1999 return cir::GlobalLinkageKind::ExternalLinkage;
2002 return dd->
hasAttr<CUDAGlobalAttr>()
2003 ? cir::GlobalLinkageKind::ExternalLinkage
2004 : cir::GlobalLinkageKind::InternalLinkage;
2005 return cir::GlobalLinkageKind::WeakODRLinkage;
2013 return cir::GlobalLinkageKind::CommonLinkage;
2019 if (dd->
hasAttr<SelectAnyAttr>())
2020 return cir::GlobalLinkageKind::WeakODRLinkage;
2024 return cir::GlobalLinkageKind::ExternalLinkage;
2036 mlir::Operation *old, cir::FuncOp newFn) {
2038 auto oldFn = mlir::dyn_cast<cir::FuncOp>(old);
2046 if (oldFn->getAttrs().size() <= 1)
2048 "replaceUsesOfNonProtoTypeWithRealFunction: Attribute forwarding");
2051 newFn.setNoProto(oldFn.getNoProto());
2054 std::optional<mlir::SymbolTable::UseRange> symUses =
2055 oldFn.getSymbolUses(oldFn->getParentOp());
2060 for (
const mlir::SymbolTable::SymbolUse &use : symUses.value()) {
2061 mlir::OpBuilder::InsertionGuard guard(builder);
2063 if (
auto noProtoCallOp = mlir::dyn_cast<cir::CallOp>(use.getUser())) {
2064 builder.setInsertionPoint(noProtoCallOp);
2067 cir::FuncType newFnType = newFn.getFunctionType();
2068 mlir::OperandRange callOperands = noProtoCallOp.getOperands();
2069 bool returnTypeMatches =
2070 newFnType.hasVoidReturn()
2071 ? noProtoCallOp.getNumResults() == 0
2072 : noProtoCallOp.getNumResults() == 1 &&
2073 noProtoCallOp.getResultTypes().front() ==
2074 newFnType.getReturnType();
2075 bool typesMatch = !newFn.getNoProto() && returnTypeMatches &&
2076 callOperands.size() == newFnType.getNumInputs();
2077 for (
unsigned i = 0, e = newFnType.getNumInputs(); typesMatch && i != e;
2079 if (callOperands[i].
getType() != newFnType.getInput(i))
2083 cir::CallOp realCallOp;
2087 builder.createCallOp(noProtoCallOp.getLoc(), newFn, callOperands);
2091 cir::FuncType origFnType = oldFn.getFunctionType();
2092 cir::FuncType callFnType =
2093 origFnType.isVarArg()
2094 ? cir::FuncType::get(origFnType.getInputs(),
2095 origFnType.getReturnType(),
2098 mlir::Value addr = cir::GetGlobalOp::create(
2099 builder, noProtoCallOp.getLoc(), cir::PointerType::get(newFnType),
2100 newFn.getSymName());
2101 mlir::Value casted =
2102 builder.createBitcast(addr, cir::PointerType::get(callFnType));
2103 realCallOp = builder.createIndirectCallOp(
2104 noProtoCallOp.getLoc(), casted, callFnType, callOperands);
2108 noProtoCallOp.replaceAllUsesWith(realCallOp);
2109 noProtoCallOp.erase();
2110 }
else if (
auto getGlobalOp =
2111 mlir::dyn_cast<cir::GetGlobalOp>(use.getUser())) {
2118 mlir::Value res = getGlobalOp.getAddr();
2119 const mlir::Type oldResTy = res.getType();
2120 const auto newPtrTy = cir::PointerType::get(newFn.getFunctionType());
2121 if (oldResTy != newPtrTy) {
2122 res.setType(newPtrTy);
2123 builder.setInsertionPointAfter(getGlobalOp.getOperation());
2124 mlir::Value castRes =
2125 cir::CastOp::create(builder, getGlobalOp.getLoc(), oldResTy,
2126 cir::CastKind::bitcast, res);
2127 res.replaceAllUsesExcept(castRes, castRes.getDefiningOp());
2129 }
else if (mlir::isa<cir::GlobalOp>(use.getUser())) {
2135 "replaceUsesOfNonProtoTypeWithRealFunction: unexpected use type");
2140cir::GlobalLinkageKind
2142 GVALinkage linkage = astContext.GetGVALinkageForVariable(vd);
2149 GVALinkage linkage = astContext.GetGVALinkageForFunction(d);
2151 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(d))
2160 StringRef globalName,
CharUnits alignment) {
2165 cir::GlobalOp gv = cgm.
createGlobalOp(loc, globalName, c.getType(),
2169 gv.setAlignmentAttr(cgm.
getSize(alignment));
2171 cir::GlobalLinkageKindAttr::get(cgm.
getBuilder().getContext(), lt));
2175 if (gv.isWeakForLinker()) {
2176 assert(cgm.
supportsCOMDAT() &&
"Only COFF uses weak string literals");
2179 cgm.
setDSOLocal(
static_cast<mlir::Operation *
>(gv));
2200 std::string result =
2211 astContext.getAlignOfGlobalVarInChars(s->
getType(),
nullptr);
2219 if (!gv.getAlignment() ||
2220 uint64_t(alignment.
getQuantity()) > *gv.getAlignment())
2221 gv.setAlignmentAttr(
getSize(alignment));
2226 if (
getCXXABI().getMangleContext().shouldMangleStringLiteral(s) &&
2229 "getGlobalForStringLiteral: mangle string literals");
2239 : builder.getUnknownLoc();
2240 auto typedC = llvm::cast<mlir::TypedAttr>(c);
2242 cir::GlobalLinkageKind::PrivateLinkage, *
this,
2243 uniqueName, alignment);
2257 auto arrayTy = mlir::dyn_cast<cir::ArrayType>(gv.getSymType());
2258 assert(arrayTy &&
"String literal must be array");
2262 return builder.getGlobalViewAttr(ptrTy, gv);
2279 errorNYI(
"SYCL temp address space");
2290 "emitExplicitCastExprType");
2296 auto ty = mlir::cast<cir::MethodType>(
convertType(destTy));
2297 return builder.getNullMethodAttr(ty);
2300 auto ty = mlir::cast<cir::DataMemberType>(
convertType(destTy));
2301 return builder.getNullDataMemberAttr(ty);
2312 if (
const auto *methodDecl = dyn_cast<CXXMethodDecl>(
decl)) {
2314 if (methodDecl->isVirtual())
2315 return cir::ConstantOp::create(
2316 builder, loc,
getCXXABI().buildVirtualMethodAttr(ty, methodDecl));
2322 return cir::ConstantOp::create(builder, loc,
2323 builder.getMethodAttr(ty, methodFuncOp));
2338 assert(
fieldDecl->getParent() == destClass &&
2339 "scalar member pointer should be relative to the declaring class");
2341 astContext.toCharUnitsFromBits(astContext.getFieldOffset(
fieldDecl))
2343 return cir::ConstantOp::create(builder, loc,
2344 cir::DataMemberOffsetAttr::get(ty, offset));
2347 std::optional<llvm::SmallVector<int32_t>> path =
2351 return cir::ConstantOp::create(builder, loc,
2352 builder.getDataMemberAttr(ty, *path));
2355std::optional<llvm::SmallVector<int32_t>>
2359 if (!findFieldMemberPath(destClass, field, path))
2360 return std::nullopt;
2364bool CIRGenModule::findFieldMemberPath(
const CXXRecordDecl *currentClass,
2373 if (currentClass->
isUnion()) {
2379 "data member pointer for non-zero-initializable union");
2386 path.push_back(fieldIdx);
2394 for (
const CXXBaseSpecifier &base : currentClass->
bases()) {
2395 const auto *baseDecl =
2398 if (base.isVirtual()) {
2403 llvm::SmallVector<int32_t> discardedPath;
2404 if (findFieldMemberPath(baseDecl, field, discardedPath)) {
2406 "data member pointer through virtual base");
2419 path.push_back(baseFieldIdx);
2420 if (findFieldMemberPath(baseDecl, field, path))
2439 if (
auto *oid = dyn_cast<ObjCImplDecl>(
decl))
2440 errorNYI(oid->getSourceRange(),
"emitDeclConext: ObjCImplDecl");
2450 if (
decl->isTemplated())
2453 switch (
decl->getKind()) {
2456 decl->getDeclKindName());
2459 case Decl::CXXConversion:
2460 case Decl::CXXMethod:
2461 case Decl::Function: {
2464 if (!fd->isConsteval())
2473 case Decl::Decomposition:
2474 case Decl::VarTemplateSpecialization: {
2476 if (
auto *decomp = dyn_cast<DecompositionDecl>(
decl))
2477 for (
auto *binding : decomp->flat_bindings())
2478 if (
auto *holdingVar = binding->getHoldingVar())
2482 case Decl::OpenACCRoutine:
2485 case Decl::OpenACCDeclare:
2488 case Decl::OMPThreadPrivate:
2491 case Decl::OMPGroupPrivate:
2494 case Decl::OMPAllocate:
2497 case Decl::OMPCapturedExpr:
2500 case Decl::OMPDeclareReduction:
2503 case Decl::OMPDeclareMapper:
2506 case Decl::OMPRequires:
2511 case Decl::UsingDirective:
2512 case Decl::UsingEnum:
2513 case Decl::NamespaceAlias:
2515 case Decl::TypeAlias:
2521 case Decl::ClassTemplate:
2523 case Decl::CXXDeductionGuide:
2525 case Decl::ExplicitInstantiation:
2526 case Decl::FunctionTemplate:
2527 case Decl::StaticAssert:
2528 case Decl::TypeAliasTemplate:
2529 case Decl::UsingShadow:
2530 case Decl::VarTemplate:
2531 case Decl::VarTemplatePartialSpecialization:
2534 case Decl::CXXConstructor:
2537 case Decl::CXXDestructor:
2542 case Decl::LinkageSpec:
2543 case Decl::Namespace:
2547 case Decl::ClassTemplateSpecialization:
2548 case Decl::CXXRecord: {
2551 for (
auto *childDecl : crd->
decls())
2557 case Decl::FileScopeAsm:
2559 if (langOpts.CUDA && langOpts.CUDAIsDevice)
2562 if (langOpts.OpenMPIsTargetDevice)
2565 if (langOpts.SYCLIsDevice)
2568 std::string line = file_asm->getAsmString();
2569 globalScopeAsm.push_back(builder.getStringAttr(line));
2576 op.setInitialValueAttr(value);
2590 md->getParent()->getNumVBases() == 0)
2592 "getAddrAndTypeOfCXXStructor: MS ABI complete destructor");
2603 false, isForDefinition);
2605 return {fnType, fn};
2609 mlir::Type funcType,
bool forVTable,
2613 "consteval function should never be emitted");
2623 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(gd.
getDecl())) {
2626 dd->getParent()->getNumVBases() == 0)
2628 "getAddrOfFunction: MS ABI complete destructor");
2634 false, isForDefinition);
2636 if (langOpts.CUDA && !langOpts.CUDAIsDevice &&
2642 bool isHIPHandle = mlir::isa<cir::GlobalOp>(*handle);
2643 if (isForDefinition || isHIPHandle)
2645 return mlir::dyn_cast<cir::FuncOp>(*handle);
2654 llvm::raw_svector_ostream
out(buffer);
2663 assert(ii &&
"Attempt to mangle unnamed decl.");
2665 const auto *fd = dyn_cast<FunctionDecl>(nd);
2669 }
else if (fd && fd->hasAttr<CUDAGlobalAttr>() &&
2673 DeviceKernelAttr::isOpenCLSpelling(
2674 fd->getAttr<DeviceKernelAttr>()) &&
2691 if (
const auto *fd = dyn_cast<FunctionDecl>(nd)) {
2692 if (fd->isMultiVersion()) {
2694 "getMangledName: multi-version functions");
2699 "getMangledName: GPU relocatable device code");
2702 return std::string(
out.str());
2705static FunctionDecl *
2720 if (
auto *methodDecl = dyn_cast<CXXMethodDecl>(protoFunc);
2721 methodDecl && methodDecl->isImplicitObjectMemberFunction()) {
2723 paramTypes.insert(paramTypes.begin(), methodDecl->getThisType());
2726 fpt->getExtProtoInfo());
2737 params.reserve(fpt->getNumParams());
2740 for (
unsigned i = 0, e = fpt->getNumParams(); i != e; ++i) {
2744 nullptr, fpt->getParamType(i),
nullptr,
2747 params.push_back(parm);
2750 tempFunc->setParams(params);
2775 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(canonicalGd.
getDecl())) {
2778 "getMangledName: C++ constructor without variants");
2787 auto result = manglings.insert(std::make_pair(mangledName, gd));
2788 return mangledDeclNames[canonicalGd] = result.first->first();
2792 assert(!d->
getInit() &&
"Cannot emit definite definitions here!");
2800 if (gv && !mlir::cast<cir::GlobalOp>(gv).isDeclaration())
2816 if (langOpts.EmitAllDecls)
2819 const auto *vd = dyn_cast<VarDecl>(global);
2821 ((codeGenOpts.KeepPersistentStorageVariables &&
2822 (vd->getStorageDuration() ==
SD_Static ||
2823 vd->getStorageDuration() ==
SD_Thread)) ||
2824 (codeGenOpts.KeepStaticConsts && vd->getStorageDuration() ==
SD_Static &&
2825 vd->getType().isConstQualified())))
2838 if (langOpts.OpenMP >= 50 && !langOpts.OpenMPSimd) {
2839 std::optional<OMPDeclareTargetDeclAttr *> activeAttr =
2840 OMPDeclareTargetDeclAttr::getActiveAttr(global);
2841 if (!activeAttr || (*activeAttr)->getLevel() != (
unsigned)-1)
2845 const auto *fd = dyn_cast<FunctionDecl>(global);
2852 if (fd->hasAttr<TargetVersionAttr>() && !fd->isMultiVersion())
2854 if (langOpts.SYCLIsDevice) {
2855 errorNYI(fd->getSourceRange(),
"mayBeEmittedEagerly: SYCL");
2859 const auto *vd = dyn_cast<VarDecl>(global);
2861 if (astContext.getInlineVariableDefinitionKind(vd) ==
2869 if (langOpts.OpenMP && langOpts.OpenMPUseTLS &&
2870 astContext.getTargetInfo().isTLSSupported() &&
isa<VarDecl>(global) &&
2872 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(global))
2875 assert((fd || vd) &&
2876 "Only FunctionDecl and VarDecl should hit this path so far.");
2881 cir::CIRGlobalValueInterface gv) {
2882 if (gv.hasLocalLinkage())
2885 if (!gv.hasDefaultVisibility() && !gv.hasExternalWeakLinkage())
2893 const llvm::Triple &tt = cgm.
getTriple();
2895 if (tt.isOSCygMing()) {
2904 cgm.
errorNYI(
"shouldAssumeDSOLocal: MinGW");
2910 if (tt.isOSBinFormatCOFF() && gv.hasExternalWeakLinkage())
2918 if (tt.isOSBinFormatCOFF() || (tt.isOSWindows() && tt.isOSBinFormatMachO()))
2922 if (!tt.isOSBinFormatELF())
2927 if (rm != llvm::Reloc::Static && !lOpts.PIE) {
2935 return !(lOpts.SemanticInterposition || lOpts.HalfNoSemanticInterposition);
2939 if (!gv.isDeclarationForLinker())
2945 if (rm == llvm::Reloc::PIC_ && gv.hasExternalWeakLinkage())
2952 if (cgOpts.DirectAccessExternalData) {
2958 if (
auto globalOp = dyn_cast<cir::GlobalOp>(gv.getOperation())) {
2984 if (gv.hasLocalLinkage()) {
2985 gv.setGlobalVisibility(cir::VisibilityKind::Default);
3000 d->
hasAttr<OMPDeclareTargetDeclAttr>() &&
3001 d->
getAttr<OMPDeclareTargetDeclAttr>()->getDevType() !=
3002 OMPDeclareTargetDeclAttr::DT_NoHost &&
3004 llvm_unreachable(
"setGlobalVisibility: OpenMP is NYI");
3013 !d->
hasAttr<OMPDeclareTargetDeclAttr>()) {
3014 bool needsProtected =
false;
3018 }
else if (
const auto *vd = dyn_cast<VarDecl>(d)) {
3019 needsProtected = vd->hasAttr<CUDADeviceAttr>() ||
3020 vd->hasAttr<CUDAConstantAttr>() ||
3021 vd->getType()->isCUDADeviceBuiltinSurfaceType() ||
3022 vd->getType()->isCUDADeviceBuiltinTextureType();
3024 if (needsProtected) {
3025 gv.setGlobalVisibility(cir::VisibilityKind::Protected);
3031 gv.setGlobalVisibility(cir::VisibilityKind::Hidden);
3038 !gv.isDeclarationForLinker())
3047 if (
auto globalValue = dyn_cast<cir::CIRGlobalValueInterface>(op))
3066 auto res = manglings.find(mangledName);
3067 if (res == manglings.end())
3069 result = res->getValue();
3074 return llvm::StringSwitch<cir::TLS_Model>(S)
3075 .Case(
"global-dynamic", cir::TLS_Model::GeneralDynamic)
3076 .Case(
"local-dynamic", cir::TLS_Model::LocalDynamic)
3077 .Case(
"initial-exec", cir::TLS_Model::InitialExec)
3078 .Case(
"local-exec", cir::TLS_Model::LocalExec);
3084 return cir::TLS_Model::GeneralDynamic;
3086 return cir::TLS_Model::LocalDynamic;
3088 return cir::TLS_Model::InitialExec;
3090 return cir::TLS_Model::LocalExec;
3092 llvm_unreachable(
"Invalid TLS model!");
3096 bool isExtendingDecl) {
3097 assert(d.
getTLSKind() &&
"setting TLS mode on non-TLS var!");
3106 global.setTlsModel(tlm);
3110 if (d.
isStaticLocal() || tlm != cir::TLS_Model::GeneralDynamic)
3116 if (isExtendingDecl)
3124 cir::FuncOp func,
bool isThunk) {
3126 cir::CallingConv callingConv;
3127 cir::SideEffect sideEffect;
3134 mlir::NamedAttrList pal{};
3135 std::vector<mlir::NamedAttrList> argAttrs(info.arguments().size());
3136 mlir::NamedAttrList retAttrs{};
3138 retAttrs, callingConv, sideEffect,
3141 for (mlir::NamedAttribute
attr : pal)
3142 func->setAttr(
attr.getName(),
attr.getValue());
3144 llvm::for_each(llvm::enumerate(argAttrs), [func](
auto idx_arg_pair) {
3145 mlir::function_interface_impl::setArgAttrs(func, idx_arg_pair.index(),
3146 idx_arg_pair.value());
3148 if (!retAttrs.empty())
3149 mlir::function_interface_impl::setResultAttrs(func, 0, retAttrs);
3162 bool isIncompleteFunction,
3170 if (!isIncompleteFunction)
3172 getTypes().arrangeGlobalDeclaration(globalDecl),
3175 if (!isIncompleteFunction && func.isDeclaration())
3182 if (funcDecl->isInlineBuiltinDeclaration()) {
3184 bool hasBody = funcDecl->
hasBody(fdBody);
3186 assert(hasBody &&
"Inline builtin declarations should always have an "
3191 if (funcDecl->isReplaceableGlobalAllocationFunction()) {
3194 func->setAttr(cir::CIRDialect::getNoBuiltinAttrName(),
3206 if (!langOpts.Exceptions)
3209 if (langOpts.CXXExceptions)
3212 if (langOpts.ObjCExceptions)
3223 f->setAttr(cir::CIRDialect::getNoThrowAttrName(),
3226 std::optional<cir::InlineKind> existingInlineKind = f.getInlineKind();
3228 existingInlineKind && *existingInlineKind == cir::InlineKind::NoInline;
3229 bool isAlwaysInline = existingInlineKind &&
3230 *existingInlineKind == cir::InlineKind::AlwaysInline;
3234 if (!isAlwaysInline &&
3239 f.setInlineKind(cir::InlineKind::NoInline);
3254 if (
decl->hasAttr<NoInlineAttr>() && !isAlwaysInline) {
3256 f.setInlineKind(cir::InlineKind::NoInline);
3257 }
else if (
decl->hasAttr<AlwaysInlineAttr>() && !isNoInline) {
3260 f.setInlineKind(cir::InlineKind::AlwaysInline);
3264 if (!isAlwaysInline)
3265 f.setInlineKind(cir::InlineKind::NoInline);
3270 if (
auto *fd = dyn_cast<FunctionDecl>(
decl)) {
3275 auto checkRedeclForInline = [](
const FunctionDecl *redecl) {
3276 return redecl->isInlineSpecified();
3278 if (any_of(
decl->redecls(), checkRedeclForInline))
3283 return any_of(pattern->
redecls(), checkRedeclForInline);
3285 if (checkForInline(fd)) {
3286 f.setInlineKind(cir::InlineKind::InlineHint);
3287 }
else if (codeGenOpts.getInlining() ==
3289 !fd->isInlined() && !isAlwaysInline) {
3290 f.setInlineKind(cir::InlineKind::NoInline);
3299 StringRef mangledName, mlir::Type funcType,
GlobalDecl gd,
bool forVTable,
3301 mlir::NamedAttrList extraAttrs) {
3304 if (
const auto *fd = cast_or_null<FunctionDecl>(d)) {
3306 if (
getLangOpts().OpenMPIsTargetDevice && openMPRuntime &&
3308 !dontDefer && !isForDefinition) {
3311 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(fdDef))
3313 else if (
const auto *dd = dyn_cast<CXXDestructorDecl>(fdDef))
3323 if (fd->isMultiVersion())
3324 errorNYI(fd->getSourceRange(),
"getOrCreateCIRFunction: multi-version");
3330 assert(mlir::isa<cir::FuncOp>(entry));
3335 if (d && !d->
hasAttr<DLLImportAttr>() && !d->
hasAttr<DLLExportAttr>()) {
3343 if (isForDefinition && fn && !fn.isDeclaration()) {
3350 diagnosedConflictingDefinitions.insert(gd).second) {
3354 diag::note_previous_definition);
3358 if (fn && fn.getFunctionType() == funcType) {
3362 if (!isForDefinition) {
3370 auto *funcDecl = llvm::cast_or_null<FunctionDecl>(gd.
getDecl());
3371 bool invalidLoc = !funcDecl ||
3372 funcDecl->getSourceRange().getBegin().isInvalid() ||
3373 funcDecl->getSourceRange().getEnd().isInvalid();
3375 invalidLoc ? theModule->getLoc() :
getLoc(funcDecl->getSourceRange()),
3376 mangledName, mlir::cast<cir::FuncType>(funcType), funcDecl);
3378 if (funcDecl && funcDecl->hasAttr<AnnotateAttr>())
3379 deferredAnnotations[mangledName] = funcDecl;
3390 auto symbolOp = mlir::cast<mlir::SymbolOpInterface>(entry);
3398 if (symbolOp.getSymbolUses(symbolOp->getParentOp()))
3408 if (!extraAttrs.empty()) {
3409 extraAttrs.append(funcOp->getAttrs());
3410 funcOp->setAttrs(extraAttrs);
3417 assert(funcOp.getFunctionType() == funcType);
3424 if (isa_and_nonnull<CXXDestructorDecl>(d) &&
3454 fd = fd->getPreviousDecl()) {
3456 if (fd->doesThisDeclarationHaveABody()) {
3469 cir::FuncType funcType,
3473 mlir::OpBuilder::InsertionGuard guard(builder);
3481 builder.setInsertionPoint(cgf->
curFn);
3483 func = cir::FuncOp::create(builder, loc, name, funcType);
3490 func.setNoProto(
true);
3492 assert(func.isDeclaration() &&
"expected empty body");
3496 func.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
3498 mlir::SymbolTable::setSymbolVisibility(
3499 func, mlir::SymbolTable::Visibility::Private);
3508 theModule.push_back(func);
3513 for (
const auto *
attr :
3527 fnOp.setBuiltin(
true);
3533 return cir::CtorKind::Default;
3535 return cir::CtorKind::Copy;
3537 return cir::CtorKind::Move;
3538 return cir::CtorKind::Custom;
3543 return cir::AssignKind::Copy;
3545 return cir::AssignKind::Move;
3546 llvm_unreachable(
"not a copy or move assignment operator");
3554 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(funcDecl)) {
3555 auto cxxDtor = cir::CXXDtorAttr::get(
3558 funcOp.setFuncInfoAttr(cxxDtor);
3562 if (
const auto *ctor = dyn_cast<CXXConstructorDecl>(funcDecl)) {
3564 auto cxxCtor = cir::CXXCtorAttr::get(
3566 kind, ctor->isTrivial());
3567 funcOp.setFuncInfoAttr(cxxCtor);
3571 const auto *method = dyn_cast<CXXMethodDecl>(funcDecl);
3572 if (method && (method->isCopyAssignmentOperator() ||
3573 method->isMoveAssignmentOperator())) {
3575 auto cxxAssign = cir::CXXAssignAttr::get(
3577 assignKind, method->isTrivial());
3578 funcOp.setFuncInfoAttr(cxxAssign);
3588 bool inStdNamespace = method ? method->getParent()->isInStdNamespace()
3590 if (!inStdNamespace)
3596 std::optional<cir::KnownFuncKind>
kind;
3598 kind = llvm::StringSwitch<std::optional<cir::KnownFuncKind>>(
3600 .Case(cir::StdFindOp::getFunctionName(),
3601 cir::StdFindOp::getFuncKind())
3602 .Default(std::nullopt);
3611 cir::FuncOp funcOp, StringRef name) {
3627 mlir::NamedAttrList extraAttrs,
3629 bool assumeConvergent) {
3630 if (assumeConvergent)
3631 errorNYI(
"createRuntimeFunction: assumeConvergent");
3641 entry.setDSOLocal(
true);
3647mlir::SymbolTable::Visibility
3651 if (op.isDeclaration())
3652 return mlir::SymbolTable::Visibility::Private;
3656mlir::SymbolTable::Visibility
3659 case cir::GlobalLinkageKind::InternalLinkage:
3660 case cir::GlobalLinkageKind::PrivateLinkage:
3661 return mlir::SymbolTable::Visibility::Private;
3662 case cir::GlobalLinkageKind::ExternalLinkage:
3663 case cir::GlobalLinkageKind::ExternalWeakLinkage:
3664 case cir::GlobalLinkageKind::LinkOnceODRLinkage:
3665 case cir::GlobalLinkageKind::AvailableExternallyLinkage:
3666 case cir::GlobalLinkageKind::CommonLinkage:
3667 case cir::GlobalLinkageKind::WeakAnyLinkage:
3668 case cir::GlobalLinkageKind::WeakODRLinkage:
3669 return mlir::SymbolTable::Visibility::Public;
3671 llvm::errs() <<
"visibility not implemented for '"
3672 << stringifyGlobalLinkageKind(glk) <<
"'\n";
3673 assert(0 &&
"not implemented");
3676 llvm_unreachable(
"linkage should be handled above!");
3680 clang::VisibilityAttr::VisibilityType visibility) {
3681 switch (visibility) {
3682 case clang::VisibilityAttr::VisibilityType::Default:
3683 return cir::VisibilityKind::Default;
3684 case clang::VisibilityAttr::VisibilityType::Hidden:
3685 return cir::VisibilityKind::Hidden;
3686 case clang::VisibilityAttr::VisibilityType::Protected:
3687 return cir::VisibilityKind::Protected;
3689 llvm_unreachable(
"unexpected visibility value");
3694 const clang::VisibilityAttr *va =
decl->getAttr<clang::VisibilityAttr>();
3695 cir::VisibilityAttr cirVisibility =
3698 cirVisibility = cir::VisibilityAttr::get(
3702 return cirVisibility;
3708 applyReplacements();
3710 theModule->setAttr(cir::CIRDialect::getModuleLevelAsmAttrName(),
3711 builder.getArrayAttr(globalScopeAsm));
3713 emitGlobalAnnotations();
3715 if (!recordLayoutEntries.empty())
3717 cir::CIRDialect::getRecordLayoutsAttrName(),
3718 mlir::DictionaryAttr::get(&
getMLIRContext(), recordLayoutEntries));
3727 std::string cuidName =
3730 auto loc = builder.getUnknownLoc();
3731 mlir::ptr::MemorySpaceAttrInterface addrSpace =
3733 getGlobalVarAddressSpace(
nullptr));
3737 gv.setLinkage(cir::GlobalLinkageKind::ExternalLinkage);
3739 auto zeroAttr = cir::IntAttr::get(int8Ty, 0);
3740 gv.setInitialValueAttr(zeroAttr);
3742 mlir::SymbolTable::setSymbolVisibility(
3743 gv, mlir::SymbolTable::Visibility::Public);
3748 if (astContext.getLangOpts().CUDA && cudaRuntime)
3763 const AliasAttr *aa = d->
getAttr<AliasAttr>();
3764 assert(aa &&
"Not an alias?");
3768 if (aa->getAliasee() == mangledName) {
3769 diags.Report(aa->getLocation(), diag::err_cyclic_alias) << 0;
3777 auto entryGV = mlir::dyn_cast<cir::CIRGlobalValueInterface>(entry);
3778 if (entryGV && entryGV.isDefinition())
3791 cir::GlobalLinkageKind linkage;
3803 cir::CIRGlobalValueInterface alias =
3804 isFunction ? mlir::cast<cir::CIRGlobalValueInterface>(
3806 mlir::cast<cir::FuncType>(declTy),
3809 : mlir::cast<cir::CIRGlobalValueInterface>(
3820 entry, mlir::cast<cir::FuncOp>(alias.getOperation()));
3828 linkage = cir::GlobalLinkageKind::WeakAnyLinkage;
3832 mlir::SymbolTable::Visibility visibility =
3835 alias.setAliasee(aa->getAliasee());
3836 alias.setLinkage(linkage);
3837 mlir::SymbolTable::setSymbolVisibility(alias, visibility);
3845 cir::FuncOp aliasee,
3846 cir::GlobalLinkageKind linkage) {
3848 auto *aliasFD = dyn_cast<FunctionDecl>(aliasGD.
getDecl());
3849 assert(aliasFD &&
"expected FunctionDecl");
3860 mangledName, fnType, aliasFD);
3861 alias.setAliasee(aliasee.getName());
3862 alias.setLinkage(linkage);
3866 mlir::SymbolTable::setSymbolVisibility(
3867 alias, mlir::SymbolTable::Visibility::Private);
3879 "declaration exists with different type");
3891 return genTypes.convertType(
type);
3898 return mlir::verify(theModule).succeeded();
3907 return builder.getConstNullPtrAttr(builder.getUInt8PtrTy());
3910 langOpts.ObjCRuntime.isGNUFamily()) {
3911 errorNYI(loc,
"getAddrOfRTTIDescriptor: Objc PtrType & Objc RT GUN");
3921 llvm::iterator_range<CastExpr::path_const_iterator> path) {
3928 assert(!base->isVirtual() &&
"Should not see virtual bases here!");
3933 const auto *baseDecl = base->getType()->castAsCXXRecordDecl();
3945 llvm::StringRef feature) {
3946 unsigned diagID = diags.getCustomDiagID(
3948 return diags.Report(loc, diagID) << feature;
3952 llvm::StringRef feature) {
3964 "cannot compile this %0 yet");
3965 diags.Report(astContext.getFullLoc(s->
getBeginLoc()), diagId)
3972 "cannot compile this %0 yet");
3973 diags.Report(astContext.getFullLoc(d->
getLocation()), diagId) <<
type;
3981 "not a global temporary");
3993 materializedType = mte->
getType();
4002 llvm::raw_svector_ostream
out(name);
4006 auto insertResult = materializedGlobalTemporaryMap.insert({mte,
nullptr});
4007 if (!insertResult.second) {
4011 if (!insertResult.first->second) {
4014 insertResult.first->second =
4017 return insertResult.first->second;
4034 value = &evalResult.
Val;
4038 std::optional<ConstantEmitter> emitter;
4039 mlir::Attribute initialValue =
nullptr;
4040 bool isConstant =
false;
4044 emitter.emplace(*
this);
4045 initialValue = emitter->emitForInitializer(*value, materializedType);
4050 type = mlir::cast<mlir::TypedAttr>(initialValue).getType();
4059 if (linkage == cir::GlobalLinkageKind::ExternalLinkage) {
4061 if (
varDecl->isStaticDataMember() &&
varDecl->getAnyInitializer(initVD) &&
4069 linkage = cir::GlobalLinkageKind::InternalLinkage;
4073 gv.setInitialValueAttr(initialValue);
4074 gv.setLinkage(linkage);
4078 emitter->finalize(gv);
4080 if (!gv.hasLocalLinkage()) {
4085 gv.setAlignment(align.getAsAlign().value());
4090 mlir::Operation *cv = gv;
4099 mlir::Operation *&entry = materializedGlobalTemporaryMap[mte];
4101 entry->replaceAllUsesWith(cv);
4116 return *globalOpEntry;
4123 "emitForInitializer should take gcd->getType().getAddressSpace()");
4125 auto typedInit = dyn_cast<mlir::TypedAttr>(init);
4129 "getAddrOfUnnamedGlobalConstantDecl: non-typed initializer");
4138 std::string name = numEntries == 0
4140 : (Twine(
".constant.") + Twine(numEntries)).str();
4142 typedInit.getType(),
true);
4143 globalOp.setLinkage(cir::GlobalLinkageKind::PrivateLinkage);
4146 globalOp.setAlignment(alignment.
getAsAlign().value());
4150 *globalOpEntry = globalOp;
4165 "emitForInitializer should take tpo->getType().getAddressSpace()");
4166 mlir::Attribute init =
4176 cir::GlobalLinkageKind linkage =
4178 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
4179 : cir::GlobalLinkageKind::InternalLinkage;
4183 typedInit.getType(),
true);
4184 globalOp.setLinkage(linkage);
4185 globalOp.setAlignment(alignment.
getAsAlign().value());
4187 linkage == cir::GlobalLinkageKind::LinkOnceODRLinkage);
4202CIRGenModule::getOrCreateAnnotationArgs(
const AnnotateAttr *
attr) {
4209 llvm::FoldingSetNodeID id;
4210 for (
Expr *e : exprs)
4213 mlir::ArrayAttr &lookup = annotationArgs[
id.ComputeHash()];
4218 args.reserve(exprs.size());
4219 for (
Expr *e : exprs) {
4220 if (
auto *strE = dyn_cast<clang::StringLiteral>(e->IgnoreParenCasts())) {
4221 args.push_back(builder.getStringAttr(strE->getString()));
4222 }
else if (
auto *intE =
4223 dyn_cast<clang::IntegerLiteral>(e->IgnoreParenCasts())) {
4224 auto intTy = builder.getIntegerType(intE->getValue().getBitWidth());
4225 args.push_back(builder.getIntegerAttr(intTy, intE->getValue()));
4227 errorNYI(e->getExprLoc(),
"annotation argument expression");
4231 return lookup = builder.getArrayAttr(args);
4234cir::AnnotationAttr CIRGenModule::emitAnnotateAttr(
const AnnotateAttr *aa) {
4235 mlir::StringAttr annoGV = builder.getStringAttr(aa->getAnnotation());
4236 mlir::ArrayAttr args = getOrCreateAnnotationArgs(aa);
4237 return cir::AnnotationAttr::get(&
getMLIRContext(), annoGV, args);
4241 mlir::Operation *gv) {
4242 assert(d->
hasAttr<AnnotateAttr>() &&
"no annotate attribute");
4244 "annotation only on globals");
4247 annotations.push_back(emitAnnotateAttr(i));
4248 if (
auto global = dyn_cast<cir::GlobalOp>(gv))
4249 global.setAnnotationsAttr(builder.getArrayAttr(annotations));
4250 else if (
auto func = dyn_cast<cir::FuncOp>(gv))
4251 func.setAnnotationsAttr(builder.getArrayAttr(annotations));
4254void CIRGenModule::emitGlobalAnnotations() {
4255 for (
const auto &[mangledName, vd] : deferredAnnotations) {
4260 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 void setLinkageForFunction(CIRGenModule &cgm, cir::FuncOp &func, const NamedDecl *nd)
static cir::GlobalOp generateStringLiteral(mlir::Location loc, mlir::TypedAttr c, cir::GlobalLinkageKind lt, CIRGenModule &cgm, StringRef globalName, CharUnits alignment)
static cir::TLS_Model getCIRTLSModel(StringRef S)
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 bool verifyPointerTypeArgs(cir::FuncOp oldF, cir::FuncOp newF, mlir::SymbolUserMap &userMap)
static cir::CtorKind getCtorKindFromDecl(const CXXConstructorDecl *ctor)
static void emitUsed(CIRGenModule &cgm, StringRef name, std::vector< cir::CIRGlobalValueInterface > &list)
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.
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 isSameEntity(const NamedDecl *X, const NamedDecl *Y) const
Determine whether the two declarations refer to the same entity.
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 void handleGlobalReplace(cir::GlobalOp oldGV, cir::GlobalOp newGV)
virtual mlir::Operation * getKernelHandle(cir::FuncOp fn, GlobalDecl gd)=0
virtual void finalizeModule()
Perform module finalization: on device side, mark ODR-used device variables as compiler-used.
virtual void internalizeDeviceSideVar(const VarDecl *d, cir::GlobalLinkageKind &linkage)=0
Adjust linkage of shadow variables in host compilation.
virtual void handleVarRegistration(const VarDecl *vd, cir::GlobalOp var)=0
Check whether a variable is a device variable and register it if true.
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.
cir::GlobalOp getAddrOfUnnamedGlobalConstantDecl(const UnnamedGlobalConstantDecl *gcd)
void setGlobalVisibility(cir::CIRGlobalValueInterface gv, const NamedDecl *d) const
Set the visibility for the given global.
void addUsedOrCompilerUsedGlobal(cir::CIRGlobalValueInterface gv)
Add a global to a list to be added to the llvm.compiler.used metadata.
void setFuncInfoAttr(cir::FuncOp funcOp, const clang::FunctionDecl *funcDecl)
Record the func_info tag for a function, either a C++ special member form (constructor,...
void replaceUsesOfNonProtoTypeWithRealFunction(mlir::Operation *old, cir::FuncOp newFn)
This function is called when we implement a function with no prototype, e.g.
bool shouldEmitFunction(clang::GlobalDecl gd)
Check if fd ends up calling itself directly through asm label or builtin-pointer-to-self trickery (e....
llvm::StringRef getMangledName(clang::GlobalDecl gd)
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *derivedClass, llvm::iterator_range< CastExpr::path_const_iterator > path)
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()
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)
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)
void setGlobalTlsReferences(const VarDecl &vd, cir::GlobalOp globalOp)
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)
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 emitAliasDefinition(GlobalDecl gd)
Emit a definition for an __attribute__((alias)) declaration.
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)
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)
std::optional< llvm::SmallVector< int32_t > > buildMemberPath(const CXXRecordDecl *destClass, const FieldDecl *field)
Build a GEP-style field-index path from destClass to field.
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 setTLSMode(mlir::Operation *op, const VarDecl &d, bool isExtendingDecl=false)
Set TLS mode for the given operation based on the given variable declaration.
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 printPostfixForExternalizedDecl(llvm::raw_ostream &os, const Decl *d)
Print the postfix for externalized static variable or kernels for single source offloading languages ...
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::GlobalOp createGlobalOp(mlir::Location loc, llvm::StringRef name, mlir::Type t, bool isConstant=false, mlir::ptr::MemorySpaceAttrInterface addrSpace={}, mlir::Operation *insertPoint=nullptr)
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)
static cir::VisibilityKind getCIRVisibilityKind(Visibility v)
void setGVPropertiesAux(mlir::Operation *op, const NamedDecl *d) const
LangAS getLangTempAllocaAddressSpace() const
Returns the address space for temporary allocations in the language.
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
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)
bool isEmptyFieldForMemberPointer(const FieldDecl *field)
Returns true if field is an empty field that isn't laid out in the CIR record (e.g.
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.
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.
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 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...
This class handles record and union layout info while lowering AST types to CIR types.
bool hasNonVirtualBaseCIRField(const CXXRecordDecl *rd) const
unsigned getCIRFieldNo(const clang::FieldDecl *fd) const
Return cir::RecordType element number that corresponds to the field FD.
bool isZeroInitializable() const
Check whether this struct can be C++ zero-initialized with a zeroinitializer.
unsigned getNonVirtualBaseCIRFieldNo(const CXXRecordDecl *rd) const
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.
const CIRGenRecordLayout & getCIRGenRecordLayout(const clang::RecordDecl *rd)
Return record layout info for the given record decl.
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 isInStdNamespace() const
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
bool isInExportDeclContext() const
Whether this declaration was exported in a lexical context.
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.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
bool isPotentiallyOverlapping() const
Determine if this field is of potentially-overlapping class type, that is, subobject with the [[no_un...
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)
unsigned getMultiVersionIndex() const
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
std::string CUID
The user provided compilation unit ID, if non-empty.
Visibility getVisibility() const
void setLinkage(Linkage L)
Linkage getLinkage() const
bool isVisibilityExplicit() const
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
bool isTriviallyRecursive(const FunctionDecl *FD)
Return true if FD's body contains a direct call back to the symbol it links as, through an asm label ...
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.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
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.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
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...
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getBeginLoc() const LLVM_READONLY
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 ParsedTargetAttr parseTargetAttr(StringRef Str) const
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
const T * castAs() const
Member-template castAs<specific type>.
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.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
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_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)
std::unique_ptr< TargetCIRGenInfo > createSPIRVTargetCIRGenInfo(CIRGenTypes &cgt)
bool isEmptyFieldForLayout(const ASTContext &context, const FieldDecl *fd)
isEmptyFieldForLayout - Return true if the field is "empty", that is, either a zero-width bit-field o...
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)
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 int32_t
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 shouldSkipAliasEmission()
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 checkAliases()
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.