19#include "mlir/Dialect/OpenMP/OpenMPUtils.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;
450 if (
auto *
attr =
decl->getAttr<AttrT>())
451 return attr->isImplicit();
452 return decl->isImplicit();
457 assert(langOpts.CUDA &&
"Should not be called by non-CUDA languages");
462 return !langOpts.CUDAIsDevice || global->
hasAttr<CUDADeviceAttr>() ||
463 global->
hasAttr<CUDAConstantAttr>() ||
464 global->
hasAttr<CUDASharedAttr>() ||
474 os << (isa<VarDecl>(d) ?
".static." :
".intern.");
476 os << (isa<VarDecl>(d) ?
"__static__" :
"__intern__");
483 "printPostfixForExternalizedDecl: CUID is not specified");
490 if (
const auto *cd = dyn_cast<clang::OpenACCConstructDecl>(gd.
getDecl())) {
498 if (global->hasAttr<WeakRefAttr>())
503 if (global->hasAttr<AliasAttr>()) {
516 "Expected Variable or Function");
517 if (
const auto *
varDecl = dyn_cast<VarDecl>(global)) {
521 }
else if (langOpts.CUDAIsDevice) {
522 const auto *
functionDecl = dyn_cast<FunctionDecl>(global);
523 if ((!global->hasAttr<CUDADeviceAttr>() ||
524 (langOpts.OffloadImplicitHostDeviceTemplates &&
529 !
getASTContext().CUDAImplicitHostDeviceFunUsedByDevice.count(
531 !global->hasAttr<CUDAGlobalAttr>() &&
533 !global->hasAttr<CUDAHostAttr>()))
536 }
else if (!global->hasAttr<CUDAHostAttr>() &&
537 global->hasAttr<CUDADeviceAttr>())
541 if (langOpts.OpenMP) {
543 if (openMPRuntime && openMPRuntime->emitTargetGlobal(gd))
545 if (
auto *drd = dyn_cast<OMPDeclareReductionDecl>(global)) {
550 if (
auto *dmd = dyn_cast<OMPDeclareMapperDecl>(global)) {
557 if (
const auto *fd = dyn_cast<FunctionDecl>(global)) {
560 if (fd->hasAttr<AnnotateAttr>()) {
563 deferredAnnotations[mangledName] = fd;
565 if (!fd->doesThisDeclarationHaveABody()) {
566 if (!fd->doesDeclarationForceExternallyVisibleDefinition() &&
577 assert(vd->isFileVarDecl() &&
"Cannot emit local var decl as global.");
579 !astContext.isMSStaticDataMemberInlineDefinition(vd)) {
583 if (astContext.getInlineVariableDefinitionKind(vd) ==
622 mlir::Operation *op) {
626 cir::FuncOp funcOp = dyn_cast_if_present<cir::FuncOp>(op);
627 if (!funcOp || funcOp.getFunctionType() != funcType) {
633 if (!funcOp.isDeclaration())
645 mlir::OpBuilder::InsertionGuard guard(builder);
650 setNonAliasAttributes(gd, funcOp);
653 auto getPriority = [
this](
const auto *
attr) ->
int {
657 return attr->DefaultPriority;
660 if (
const ConstructorAttr *ca = funcDecl->getAttr<ConstructorAttr>())
662 if (
const DestructorAttr *da = funcDecl->getAttr<DestructorAttr>())
665 if (funcDecl->getAttr<AnnotateAttr>())
668 if (
getLangOpts().OpenMP && funcDecl->hasAttr<OMPDeclareTargetDeclAttr>())
674 std::optional<int> priority) {
683 ctor.setGlobalCtorPriority(priority);
688 std::optional<int> priority) {
689 if (codeGenOpts.RegisterGlobalDtorsWithAtExit &&
691 errorNYI(dtor.getLoc(),
"registerGlobalDtorsWithAtExit");
694 dtor.setGlobalDtorPriority(priority);
719 mlir::ptr::MemorySpaceAttrInterface addrSpace,
720 mlir::Operation *insertPoint) {
725 mlir::OpBuilder::InsertionGuard guard(builder);
731 builder.setInsertionPoint(insertPoint);
737 builder.setInsertionPointToStart(
getModule().getBody());
740 g = cir::GlobalOp::create(builder, loc, name, t, isConstant, addrSpace);
746 mlir::SymbolTable::setSymbolVisibility(
747 g, mlir::SymbolTable::Visibility::Private);
755 if (isa_and_nonnull<NamedDecl>(d))
759 if (
auto gvi = mlir::dyn_cast<cir::CIRGlobalValueInterface>(gv)) {
760 if (d && d->
hasAttr<UsedAttr>())
763 if (
const auto *vd = dyn_cast_if_present<VarDecl>(d);
764 vd && ((codeGenOpts.KeepPersistentStorageVariables &&
765 (vd->getStorageDuration() ==
SD_Static ||
766 vd->getStorageDuration() ==
SD_Thread)) ||
767 (codeGenOpts.KeepStaticConsts &&
769 vd->getType().isConstQualified())))
775static std::vector<std::string>
777 llvm::StringMap<bool> &featureMap) {
778 llvm::StringMap<bool> defaultFeatureMap;
782 std::vector<std::string> delta;
783 for (
const auto &[k, v] : featureMap) {
784 auto defaultIt = defaultFeatureMap.find(k);
785 if (defaultIt == defaultFeatureMap.end() || defaultIt->getValue() != v)
786 delta.push_back((v ?
"+" :
"-") + k.str());
792bool CIRGenModule::getCPUAndFeaturesAttributes(
793 GlobalDecl gd, llvm::StringMap<std::string> &attrs,
794 bool setTargetFeatures) {
800 std::vector<std::string> features;
804 const auto *fd = dyn_cast_or_null<FunctionDecl>(gd.
getDecl());
805 fd = fd ? fd->getMostRecentDecl() : fd;
806 const auto *td = fd ? fd->getAttr<TargetAttr>() :
nullptr;
807 const auto *tv = fd ? fd->getAttr<TargetVersionAttr>() :
nullptr;
808 assert((!td || !tv) &&
"both target_version and target specified");
809 const auto *sd = fd ? fd->getAttr<CPUSpecificAttr>() :
nullptr;
810 const auto *tc = fd ? fd->getAttr<TargetClonesAttr>() :
nullptr;
811 bool addedAttr =
false;
812 if (td || tv || sd || tc) {
813 llvm::StringMap<bool> featureMap;
814 astContext.getFunctionFeatureMap(featureMap, gd);
820 llvm::StringRef featureStr = td ? td->getFeaturesStr() : llvm::StringRef();
823 if (!featureStr.empty()) {
824 clang::ParsedTargetAttr parsedAttr =
826 if (!parsedAttr.
CPU.empty() &&
828 targetCPU = parsedAttr.
CPU;
831 if (!parsedAttr.
Tune.empty() &&
833 tuneCPU = parsedAttr.
Tune;
849 features.reserve(features.size() + featureMap.size());
850 for (
const auto &entry : featureMap)
851 features.push_back((entry.getValue() ?
"+" :
"-") +
852 entry.getKey().str());
857 llvm::StringMap<bool> featureMap;
859 astContext.getFunctionFeatureMap(featureMap, gd);
870 if (!targetCPU.empty()) {
871 attrs[
"cir.target-cpu"] = targetCPU.str();
874 if (!tuneCPU.empty()) {
875 attrs[
"cir.tune-cpu"] = tuneCPU.str();
878 if (!features.empty() && setTargetFeatures) {
879 llvm::erase_if(features, [&](
const std::string &f) {
880 assert(!f.empty() && (f[0] ==
'+' || f[0] ==
'-') &&
881 "feature string must start with '+' or '-'");
884 llvm::sort(features);
885 attrs[
"cir.target-features"] = llvm::join(features,
",");
893void CIRGenModule::setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op) {
898 if (
auto gvi = mlir::dyn_cast<cir::CIRGlobalValueInterface>(op)) {
899 if (
const auto *sa = d->
getAttr<SectionAttr>())
900 gvi.setSection(builder.getStringAttr(sa->getName()));
904 if (
auto func = dyn_cast<cir::FuncOp>(op)) {
905 llvm::StringMap<std::string> attrs;
906 if (getCPUAndFeaturesAttributes(gd, attrs)) {
910 for (
const auto &[key, val] : attrs)
911 func->setAttr(key, builder.getStringAttr(val));
921std::optional<cir::SourceLanguage> CIRGenModule::getCIRSourceLanguage()
const {
922 using ClangStd = clang::LangStandard;
923 using CIRLang = cir::SourceLanguage;
928 if (opts.C99 || opts.C11 || opts.C17 || opts.C23 || opts.C2y ||
929 opts.LangStd == ClangStd::lang_c89 ||
930 opts.LangStd == ClangStd::lang_gnu89)
935 errorNYI(
"CIR does not yet support the given source language");
939LangAS CIRGenModule::getGlobalVarAddressSpace(
const VarDecl *d) {
940 if (langOpts.OpenCL) {
948 if (langOpts.SYCLIsDevice &&
950 errorNYI(
"SYCL global address space");
952 if (langOpts.CUDA && langOpts.CUDAIsDevice) {
954 if (d->
hasAttr<CUDAConstantAttr>())
956 if (d->
hasAttr<CUDASharedAttr>())
958 if (d->
hasAttr<CUDADeviceAttr>())
967 errorNYI(
"OpenMP global address space");
980 gv.
setLinkage(cir::GlobalLinkageKind::ExternalWeakLinkage);
989 auto linkage = cir::GlobalLinkageKind::ExternalWeakLinkage;
990 func.setLinkage(linkage);
994 if (!func.isDeclaration())
995 mlir::SymbolTable::setSymbolVisibility(
1002 for (mlir::Attribute i : indexes) {
1003 auto ind = mlir::cast<mlir::IntegerAttr>(i);
1004 inds.push_back(ind.getValue().getSExtValue());
1010 return view.getSymbol().getValue() == glob.getSymName();
1014 cir::GlobalOp newGlob,
1015 cir::GlobalViewAttr
attr,
1026 mlir::Type newTy = newGlob.getSymType();
1031 cir::PointerType newPtrTy;
1034 newPtrTy = cir::PointerType::get(newTy);
1043 cgm.
errorNYI(
"Unhandled type in createNewGlobalView");
1049 mlir::Attribute oldInit) {
1050 if (
auto oldView = mlir::dyn_cast<cir::GlobalViewAttr>(oldInit))
1053 auto getNewInitElements =
1054 [&](mlir::ArrayAttr oldElements) -> mlir::ArrayAttr {
1056 for (mlir::Attribute elt : oldElements) {
1057 if (
auto view = mlir::dyn_cast<cir::GlobalViewAttr>(elt))
1059 else if (mlir::isa<cir::ConstArrayAttr, cir::ConstRecordAttr>(elt))
1062 newElements.push_back(elt);
1064 return mlir::ArrayAttr::get(cgm.
getBuilder().getContext(), newElements);
1067 if (
auto oldArray = mlir::dyn_cast<cir::ConstArrayAttr>(oldInit)) {
1073 mlir::Attribute oldElts = oldArray.getElts();
1074 if (mlir::isa<mlir::StringAttr>(oldElts))
1076 mlir::Attribute newElements =
1077 getNewInitElements(mlir::cast<mlir::ArrayAttr>(oldElts));
1079 newElements, mlir::cast<cir::ArrayType>(oldArray.getType()));
1081 if (
auto oldRecord = mlir::dyn_cast<cir::ConstRecordAttr>(oldInit)) {
1082 mlir::ArrayAttr newMembers = getNewInitElements(oldRecord.getMembers());
1083 auto recordTy = mlir::cast<cir::RecordType>(oldRecord.getType());
1085 newMembers, recordTy.getPacked(), recordTy.getPadded(), recordTy);
1090 cgm.
errorNYI(
"Unhandled type in getNewInitValue");
1098 assert(oldGV.getSymName() == newGV.getSymName() &&
"symbol names must match");
1100 mlir::Type oldTy = oldGV.getSymType();
1101 mlir::Type newTy = newGV.getSymType();
1106 assert(oldTy != newTy &&
"expected type change in replaceGlobal");
1109 std::optional<mlir::SymbolTable::UseRange> oldSymUses =
1110 oldGV.getSymbolUses(theModule);
1111 for (mlir::SymbolTable::SymbolUse use : *oldSymUses) {
1112 mlir::Operation *userOp = use.getUser();
1114 (mlir::isa<cir::GetGlobalOp, cir::GlobalOp, cir::ConstantOp>(userOp)) &&
1115 "Unexpected user for global op");
1117 if (
auto getGlobalOp = dyn_cast<cir::GetGlobalOp>(use.getUser())) {
1118 mlir::Value useOpResultValue = getGlobalOp.getAddr();
1119 useOpResultValue.setType(cir::PointerType::get(newTy));
1121 mlir::OpBuilder::InsertionGuard guard(builder);
1122 builder.setInsertionPointAfter(getGlobalOp);
1123 mlir::Type ptrTy = builder.getPointerTo(oldTy);
1125 builder.createBitcast(getGlobalOp->getLoc(), useOpResultValue, ptrTy);
1126 useOpResultValue.replaceAllUsesExcept(
cast,
cast.getDefiningOp());
1127 }
else if (
auto glob = dyn_cast<cir::GlobalOp>(userOp)) {
1128 if (
auto init = glob.getInitialValue()) {
1129 mlir::Attribute nw =
getNewInitValue(*
this, newGV, oldTy, init.value());
1130 glob.setInitialValueAttr(nw);
1132 }
else if (
auto c = dyn_cast<cir::ConstantOp>(userOp)) {
1133 mlir::Attribute init =
getNewInitValue(*
this, newGV, oldTy, c.getValue());
1134 auto typedAttr = mlir::cast<mlir::TypedAttr>(init);
1135 mlir::OpBuilder::InsertionGuard guard(builder);
1136 builder.setInsertionPointAfter(c);
1137 auto newUser = cir::ConstantOp::create(builder, c.getLoc(), typedAttr);
1138 c.replaceAllUsesWith(newUser.getOperation());
1174 cir::GlobalOp entry;
1178 "getOrCreateCIRGlobal: global with non-GlobalOp type");
1183 mlir::ptr::MemorySpaceAttrInterface entryCIRAS = entry.getAddrSpaceAttr();
1189 if (entry.getSymType() == ty &&
1199 if (isForDefinition && !entry.isDeclaration()) {
1201 "getOrCreateCIRGlobal: global with conflicting type");
1209 if (!isForDefinition)
1218 bool isConstant =
false;
1223 astContext,
true, !needsDtor);
1226 mlir::ptr::MemorySpaceAttrInterface declCIRAS =
1231 cir::GlobalOp gv =
createGlobalOp(loc, mangledName, ty, isConstant, declCIRAS,
1232 entry.getOperation());
1252 if (langOpts.OpenMP && !langOpts.OpenMPSimd)
1254 "getOrCreateCIRGlobal: OpenMP target global variable");
1256 gv.setAlignmentAttr(
getSize(astContext.getDeclAlign(d)));
1267 if (astContext.isMSStaticDataMemberInlineDefinition(d))
1269 "getOrCreateCIRGlobal: MS static data member inline definition");
1273 if (
const SectionAttr *sa = d->
getAttr<SectionAttr>())
1274 gv.setSectionAttr(builder.getStringAttr(sa->getName()));
1278 if (
getTriple().getArch() == llvm::Triple::xcore)
1280 "getOrCreateCIRGlobal: XCore specific ABI requirements");
1290 "getOrCreateCIRGlobal: external const declaration with initializer");
1302 "getOrCreateCIRGlobal: HIP managed attribute");
1337 mlir::Type ptrTy = builder.getPointerTo(g.getSymType(), g.getAddrSpaceAttr());
1338 return cir::GetGlobalOp::create(
1341 g.getStaticLocalGuard().has_value());
1349 cir::PointerType ptrTy =
1350 builder.getPointerTo(globalOp.getSymType(), globalOp.getAddrSpaceAttr());
1351 return builder.getGlobalViewAttr(ptrTy, globalOp);
1355 assert((mlir::isa<cir::FuncOp>(gv.getOperation()) ||
1356 !gv.isDeclarationForLinker()) &&
1357 "Only globals with definition can force usage.");
1362 assert(!gv.isDeclarationForLinker() &&
1363 "Only globals with definition can force usage.");
1368 cir::CIRGlobalValueInterface gv) {
1369 assert((mlir::isa<cir::FuncOp>(gv.getOperation()) ||
1370 !gv.isDeclarationForLinker()) &&
1371 "Only globals with definition can force usage.");
1379 std::vector<cir::CIRGlobalValueInterface> &list) {
1384 mlir::Location loc = builder.getUnknownLoc();
1386 usedArray.resize(list.size());
1387 for (
auto [i, op] : llvm::enumerate(list)) {
1388 usedArray[i] = cir::GlobalViewAttr::get(
1389 cgm.
voidPtrTy, mlir::FlatSymbolRefAttr::get(op.getNameAttr()));
1392 cir::ArrayType arrayTy = cir::ArrayType::get(cgm.
voidPtrTy, usedArray.size());
1394 cir::ConstArrayAttr initAttr = cir::ConstArrayAttr::get(
1395 arrayTy, mlir::ArrayAttr::get(&cgm.
getMLIRContext(), usedArray));
1399 gv.setLinkage(cir::GlobalLinkageKind::AppendingLinkage);
1400 gv.setInitialValueAttr(initAttr);
1401 gv.setSectionAttr(builder.getStringAttr(
"llvm.metadata"));
1413 "emitGlobalVarDefinition: emit OpenCL/OpenMP global variable");
1420 bool isDefinitionAvailableExternally =
1425 if (isDefinitionAvailableExternally &&
1433 mlir::Attribute init;
1434 bool needsGlobalCtor =
false;
1435 bool needsGlobalDtor =
1436 !isDefinitionAvailableExternally &&
1441 std::optional<ConstantEmitter> emitter;
1446 bool isCUDASharedVar =
1451 bool isCUDAShadowVar =
1453 (vd->
hasAttr<CUDAConstantAttr>() || vd->
hasAttr<CUDADeviceAttr>() ||
1454 vd->
hasAttr<CUDASharedAttr>());
1455 bool isCUDADeviceShadowVar =
1461 (isCUDASharedVar || isCUDAShadowVar || isCUDADeviceShadowVar)) {
1463 }
else if (vd->
hasAttr<LoaderUninitializedAttr>()) {
1465 "emitGlobalVarDefinition: loader uninitialized attribute");
1466 }
else if (!initExpr) {
1479 emitter.emplace(*
this);
1480 mlir::Attribute initializer = emitter->tryEmitForInitializer(*initDecl);
1489 "emitGlobalVarDefinition: flexible array initializer");
1491 if (!isDefinitionAvailableExternally)
1492 needsGlobalCtor =
true;
1495 "emitGlobalVarDefinition: static initializer");
1506 mlir::Type initType;
1507 if (mlir::isa<mlir::SymbolRefAttr>(init)) {
1510 "emitGlobalVarDefinition: global initializer is a symbol reference");
1513 assert(mlir::isa<mlir::TypedAttr>(init) &&
"This should have a type");
1514 auto typedInitAttr = mlir::cast<mlir::TypedAttr>(init);
1515 initType = typedInitAttr.getType();
1517 assert(!mlir::isa<mlir::NoneType>(initType) &&
"Should have a type by now");
1523 if (!gv || gv.getSymType() != initType) {
1525 "emitGlobalVarDefinition: global initializer with type mismatch");
1531 if (vd->
hasAttr<AnnotateAttr>())
1544 if (langOpts.CUDA) {
1545 if (langOpts.CUDAIsDevice) {
1548 if (linkage != cir::GlobalLinkageKind::InternalLinkage &&
1550 (vd->
hasAttr<CUDADeviceAttr>() || vd->
hasAttr<CUDAConstantAttr>() ||
1553 gv->setAttr(cir::CUDAExternallyInitializedAttr::getMnemonic(),
1566 emitter->finalize(gv);
1570 gv.setConstant((vd->
hasAttr<CUDAConstantAttr>() && langOpts.CUDAIsDevice) ||
1571 (!needsGlobalCtor && !needsGlobalDtor &&
1576 if (
const SectionAttr *sa = vd->
getAttr<SectionAttr>()) {
1579 gv.setConstant(
true);
1583 gv.setLinkage(linkage);
1587 if (linkage == cir::GlobalLinkageKind::CommonLinkage) {
1589 gv.setConstant(
false);
1594 std::optional<mlir::Attribute> initializer = gv.getInitialValue();
1595 if (initializer && !
getBuilder().isNullValue(*initializer))
1596 gv.setLinkage(cir::GlobalLinkageKind::WeakAnyLinkage);
1599 setNonAliasAttributes(vd, gv);
1607 if (needsGlobalCtor || needsGlobalDtor)
1613 cir::GlobalLinkageKind::AvailableExternallyLinkage)
1619 if (fd->isInlineBuiltinDeclaration())
1630 mlir::Operation *op) {
1632 if (
const auto *fd = dyn_cast<FunctionDecl>(
decl)) {
1636 if (
const auto *method = dyn_cast<CXXMethodDecl>(
decl)) {
1640 abi->emitCXXStructor(gd);
1641 else if (fd->isMultiVersion())
1642 errorNYI(method->getSourceRange(),
"multiversion functions");
1646 if (method->isVirtual())
1652 if (fd->isMultiVersion())
1653 errorNYI(fd->getSourceRange(),
"multiversion functions");
1658 if (
const auto *vd = dyn_cast<VarDecl>(
decl))
1661 llvm_unreachable(
"Invalid argument to CIRGenModule::emitGlobalDefinition");
1675 astContext.getAsConstantArrayType(e->
getType());
1676 uint64_t finalSize = cat->getZExtSize();
1677 str.resize(finalSize);
1679 mlir::Type eltTy =
convertType(cat->getElementType());
1680 return builder.getString(str, eltTy, finalSize,
false);
1685 auto arrayEltTy = mlir::cast<cir::IntType>(arrayTy.getElementType());
1687 uint64_t arraySize = arrayTy.getSize();
1689 assert(arraySize > literalSize &&
1690 "wide string literal array size must have room for null terminator?");
1694 bool isAllZero =
true;
1695 for (
unsigned i = 0; i < literalSize; ++i) {
1703 return cir::ZeroAttr::get(arrayTy);
1707 elements.reserve(arraySize);
1708 for (
unsigned i = 0; i < literalSize; ++i)
1709 elements.push_back(cir::IntAttr::get(arrayEltTy, e->
getCodeUnit(i)));
1711 auto elementsAttr = mlir::ArrayAttr::get(&
getMLIRContext(), elements);
1712 return builder.getConstArray(elementsAttr, arrayTy);
1723 if (d.
hasAttr<SelectAnyAttr>())
1727 if (
auto *vd = dyn_cast<VarDecl>(&d))
1742 llvm_unreachable(
"No such linkage");
1748 if (
auto globalOp = dyn_cast_or_null<cir::GlobalOp>(op)) {
1749 globalOp.setComdat(
true);
1752 funcOp.setComdat(
true);
1758 genTypes.updateCompletedType(td);
1762 replacements[name] = op;
1767 mlir::SymbolUserMap &userMap) {
1768 for (mlir::Operation *user : userMap.getUsers(oldF)) {
1769 auto call = mlir::dyn_cast<cir::CallOp>(user);
1773 for (
auto [argOp, fnArgType] :
1774 llvm::zip(call.getArgs(), newF.getFunctionType().getInputs())) {
1775 if (argOp.getType() != fnArgType)
1784void CIRGenModule::applyReplacements() {
1785 if (replacements.empty())
1791 mlir::SymbolTableCollection symbolTableCollection;
1792 mlir::SymbolUserMap userMap(symbolTableCollection, theModule);
1794 for (
auto &i : replacements) {
1795 StringRef mangledName = i.first;
1796 mlir::Operation *replacement = i.second;
1802 auto newF = dyn_cast<cir::FuncOp>(replacement);
1805 errorNYI(replacement->getLoc(),
"replacement is not a function");
1810 "call argument types do not match replacement function");
1814 userMap.replaceAllUsesWith(oldF, newF.getSymNameAttr());
1815 newF->moveBefore(oldF);
1822 mlir::Location loc, StringRef name, mlir::Type ty,
1824 auto gv = mlir::dyn_cast_or_null<cir::GlobalOp>(
getGlobalValue(name));
1828 if (gv.getSymType() == ty)
1834 assert(gv.isDeclaration() &&
"Declaration has wrong type!");
1836 errorNYI(loc,
"createOrReplaceCXXRuntimeVariable: declaration exists with "
1847 mlir::SymbolTable::setSymbolVisibility(gv,
1851 !gv.hasAvailableExternallyLinkage()) {
1855 gv.setAlignmentAttr(
getSize(alignment));
1866 if ((noCommon || vd->
hasAttr<NoCommonAttr>()) && !vd->
hasAttr<CommonAttr>())
1877 if (vd->
hasAttr<SectionAttr>())
1883 if (vd->
hasAttr<PragmaClangBSSSectionAttr>() ||
1884 vd->
hasAttr<PragmaClangDataSectionAttr>() ||
1885 vd->
hasAttr<PragmaClangRelroSectionAttr>() ||
1886 vd->
hasAttr<PragmaClangRodataSectionAttr>())
1894 if (vd->
hasAttr<WeakImportAttr>())
1904 if (vd->
hasAttr<AlignedAttr>())
1911 for (
const FieldDecl *fd : rd->fields()) {
1912 if (fd->isBitField())
1914 if (fd->hasAttr<AlignedAttr>())
1936cir::GlobalLinkageKind
1940 return cir::GlobalLinkageKind::InternalLinkage;
1943 return cir::GlobalLinkageKind::WeakAnyLinkage;
1947 return cir::GlobalLinkageKind::LinkOnceAnyLinkage;
1952 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
1966 return !astContext.getLangOpts().AppleKext
1967 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
1968 : cir::GlobalLinkageKind::InternalLinkage;
1982 return cir::GlobalLinkageKind::ExternalLinkage;
1985 return dd->
hasAttr<CUDAGlobalAttr>()
1986 ? cir::GlobalLinkageKind::ExternalLinkage
1987 : cir::GlobalLinkageKind::InternalLinkage;
1988 return cir::GlobalLinkageKind::WeakODRLinkage;
1996 return cir::GlobalLinkageKind::CommonLinkage;
2002 if (dd->
hasAttr<SelectAnyAttr>())
2003 return cir::GlobalLinkageKind::WeakODRLinkage;
2007 return cir::GlobalLinkageKind::ExternalLinkage;
2019 mlir::Operation *old, cir::FuncOp newFn) {
2021 auto oldFn = mlir::dyn_cast<cir::FuncOp>(old);
2029 if (oldFn->getAttrs().size() <= 1)
2031 "replaceUsesOfNonProtoTypeWithRealFunction: Attribute forwarding");
2034 newFn.setNoProto(oldFn.getNoProto());
2037 std::optional<mlir::SymbolTable::UseRange> symUses =
2038 oldFn.getSymbolUses(oldFn->getParentOp());
2039 for (
const mlir::SymbolTable::SymbolUse &use : symUses.value()) {
2040 mlir::OpBuilder::InsertionGuard guard(builder);
2042 if (
auto noProtoCallOp = mlir::dyn_cast<cir::CallOp>(use.getUser())) {
2043 builder.setInsertionPoint(noProtoCallOp);
2046 cir::FuncType newFnType = newFn.getFunctionType();
2047 mlir::OperandRange callOperands = noProtoCallOp.getOperands();
2048 bool returnTypeMatches =
2049 newFnType.hasVoidReturn()
2050 ? noProtoCallOp.getNumResults() == 0
2051 : noProtoCallOp.getNumResults() == 1 &&
2052 noProtoCallOp.getResultTypes().front() ==
2053 newFnType.getReturnType();
2054 bool typesMatch = !newFn.getNoProto() && returnTypeMatches &&
2055 callOperands.size() == newFnType.getNumInputs();
2056 for (
unsigned i = 0, e = newFnType.getNumInputs(); typesMatch && i != e;
2058 if (callOperands[i].
getType() != newFnType.getInput(i))
2062 cir::CallOp realCallOp;
2066 builder.createCallOp(noProtoCallOp.getLoc(), newFn, callOperands);
2070 cir::FuncType origFnType = oldFn.getFunctionType();
2071 cir::FuncType callFnType =
2072 origFnType.isVarArg()
2073 ? cir::FuncType::get(origFnType.getInputs(),
2074 origFnType.getReturnType(),
2077 mlir::Value addr = cir::GetGlobalOp::create(
2078 builder, noProtoCallOp.getLoc(), cir::PointerType::get(newFnType),
2079 newFn.getSymName());
2080 mlir::Value casted =
2081 builder.createBitcast(addr, cir::PointerType::get(callFnType));
2082 realCallOp = builder.createIndirectCallOp(
2083 noProtoCallOp.getLoc(), casted, callFnType, callOperands);
2087 noProtoCallOp.replaceAllUsesWith(realCallOp);
2088 noProtoCallOp.erase();
2089 }
else if (
auto getGlobalOp =
2090 mlir::dyn_cast<cir::GetGlobalOp>(use.getUser())) {
2097 mlir::Value res = getGlobalOp.getAddr();
2098 const mlir::Type oldResTy = res.getType();
2099 const auto newPtrTy = cir::PointerType::get(newFn.getFunctionType());
2100 if (oldResTy != newPtrTy) {
2101 res.setType(newPtrTy);
2102 builder.setInsertionPointAfter(getGlobalOp.getOperation());
2103 mlir::Value castRes =
2104 cir::CastOp::create(builder, getGlobalOp.getLoc(), oldResTy,
2105 cir::CastKind::bitcast, res);
2106 res.replaceAllUsesExcept(castRes, castRes.getDefiningOp());
2108 }
else if (mlir::isa<cir::GlobalOp>(use.getUser())) {
2114 "replaceUsesOfNonProtoTypeWithRealFunction: unexpected use type");
2119cir::GlobalLinkageKind
2121 GVALinkage linkage = astContext.GetGVALinkageForVariable(vd);
2128 GVALinkage linkage = astContext.GetGVALinkageForFunction(d);
2130 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(d))
2139 StringRef globalName,
CharUnits alignment) {
2144 cir::GlobalOp gv = cgm.
createGlobalOp(loc, globalName, c.getType(),
2148 gv.setAlignmentAttr(cgm.
getSize(alignment));
2150 cir::GlobalLinkageKindAttr::get(cgm.
getBuilder().getContext(), lt));
2154 if (gv.isWeakForLinker()) {
2155 assert(cgm.
supportsCOMDAT() &&
"Only COFF uses weak string literals");
2158 cgm.
setDSOLocal(
static_cast<mlir::Operation *
>(gv));
2179 std::string result =
2190 astContext.getAlignOfGlobalVarInChars(s->
getType(),
nullptr);
2198 if (!gv.getAlignment() ||
2199 uint64_t(alignment.
getQuantity()) > *gv.getAlignment())
2200 gv.setAlignmentAttr(
getSize(alignment));
2205 if (
getCXXABI().getMangleContext().shouldMangleStringLiteral(s) &&
2208 "getGlobalForStringLiteral: mangle string literals");
2218 : builder.getUnknownLoc();
2219 auto typedC = llvm::cast<mlir::TypedAttr>(c);
2221 cir::GlobalLinkageKind::PrivateLinkage, *
this,
2222 uniqueName, alignment);
2236 auto arrayTy = mlir::dyn_cast<cir::ArrayType>(gv.getSymType());
2237 assert(arrayTy &&
"String literal must be array");
2241 return builder.getGlobalViewAttr(ptrTy, gv);
2258 errorNYI(
"SYCL temp address space");
2269 "emitExplicitCastExprType");
2275 auto ty = mlir::cast<cir::MethodType>(
convertType(destTy));
2276 return builder.getNullMethodAttr(ty);
2279 auto ty = mlir::cast<cir::DataMemberType>(
convertType(destTy));
2280 return builder.getNullDataMemberAttr(ty);
2291 if (
const auto *methodDecl = dyn_cast<CXXMethodDecl>(
decl)) {
2293 if (methodDecl->isVirtual())
2294 return cir::ConstantOp::create(
2295 builder, loc,
getCXXABI().buildVirtualMethodAttr(ty, methodDecl));
2301 return cir::ConstantOp::create(builder, loc,
2302 builder.getMethodAttr(ty, methodFuncOp));
2317 assert(
fieldDecl->getParent() == destClass &&
2318 "scalar member pointer should be relative to the declaring class");
2320 astContext.toCharUnitsFromBits(astContext.getFieldOffset(
fieldDecl))
2322 return cir::ConstantOp::create(builder, loc,
2323 cir::DataMemberOffsetAttr::get(ty, offset));
2326 std::optional<llvm::SmallVector<int32_t>> path =
2330 return cir::ConstantOp::create(builder, loc,
2331 builder.getDataMemberAttr(ty, *path));
2334std::optional<llvm::SmallVector<int32_t>>
2338 if (!findFieldMemberPath(destClass, field, path))
2339 return std::nullopt;
2343bool CIRGenModule::findFieldMemberPath(
const CXXRecordDecl *currentClass,
2350 if (field->
getParent() == currentClass) {
2352 if (currentClass->
isUnion()) {
2358 "data member pointer for non-zero-initializable union");
2365 path.push_back(fieldIdx);
2373 for (
const CXXBaseSpecifier &base : currentClass->
bases()) {
2374 const auto *baseDecl =
2377 if (base.isVirtual()) {
2382 llvm::SmallVector<int32_t> discardedPath;
2383 if (findFieldMemberPath(baseDecl, field, discardedPath)) {
2385 "data member pointer through virtual base");
2398 path.push_back(baseFieldIdx);
2399 if (findFieldMemberPath(baseDecl, field, path))
2418 if (
auto *oid = dyn_cast<ObjCImplDecl>(
decl))
2419 errorNYI(oid->getSourceRange(),
"emitDeclConext: ObjCImplDecl");
2429 if (
decl->isTemplated())
2432 switch (
decl->getKind()) {
2435 decl->getDeclKindName());
2438 case Decl::CXXConversion:
2439 case Decl::CXXMethod:
2440 case Decl::Function: {
2443 if (!fd->isConsteval())
2452 case Decl::Decomposition:
2453 case Decl::VarTemplateSpecialization: {
2455 if (
auto *decomp = dyn_cast<DecompositionDecl>(
decl))
2456 for (
auto *binding : decomp->flat_bindings())
2457 if (
auto *holdingVar = binding->getHoldingVar())
2461 case Decl::OpenACCRoutine:
2464 case Decl::OpenACCDeclare:
2467 case Decl::OMPThreadPrivate:
2470 case Decl::OMPGroupPrivate:
2473 case Decl::OMPAllocate:
2476 case Decl::OMPCapturedExpr:
2479 case Decl::OMPDeclareReduction:
2482 case Decl::OMPDeclareMapper:
2485 case Decl::OMPRequires:
2490 case Decl::UsingDirective:
2491 case Decl::UsingEnum:
2492 case Decl::NamespaceAlias:
2494 case Decl::TypeAlias:
2500 case Decl::ClassTemplate:
2502 case Decl::CXXDeductionGuide:
2504 case Decl::ExplicitInstantiation:
2505 case Decl::FunctionTemplate:
2506 case Decl::StaticAssert:
2507 case Decl::TypeAliasTemplate:
2508 case Decl::UsingShadow:
2509 case Decl::VarTemplate:
2510 case Decl::VarTemplatePartialSpecialization:
2513 case Decl::CXXConstructor:
2516 case Decl::CXXDestructor:
2521 case Decl::LinkageSpec:
2522 case Decl::Namespace:
2526 case Decl::ClassTemplateSpecialization:
2527 case Decl::CXXRecord: {
2530 for (
auto *childDecl : crd->
decls())
2536 case Decl::FileScopeAsm:
2538 if (langOpts.CUDA && langOpts.CUDAIsDevice)
2541 if (langOpts.OpenMPIsTargetDevice)
2544 if (langOpts.SYCLIsDevice)
2547 std::string line = file_asm->getAsmString();
2548 globalScopeAsm.push_back(builder.getStringAttr(line));
2555 op.setInitialValueAttr(value);
2569 md->getParent()->getNumVBases() == 0)
2571 "getAddrAndTypeOfCXXStructor: MS ABI complete destructor");
2582 false, isForDefinition);
2584 return {fnType, fn};
2588 mlir::Type funcType,
bool forVTable,
2592 "consteval function should never be emitted");
2602 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(gd.
getDecl())) {
2605 dd->getParent()->getNumVBases() == 0)
2607 "getAddrOfFunction: MS ABI complete destructor");
2613 false, isForDefinition);
2615 if (langOpts.CUDA && !langOpts.CUDAIsDevice &&
2621 bool isHIPHandle = mlir::isa<cir::GlobalOp>(*handle);
2622 if (isForDefinition || isHIPHandle)
2624 return mlir::dyn_cast<cir::FuncOp>(*handle);
2633 llvm::raw_svector_ostream
out(buffer);
2642 assert(ii &&
"Attempt to mangle unnamed decl.");
2644 const auto *fd = dyn_cast<FunctionDecl>(nd);
2648 }
else if (fd && fd->hasAttr<CUDAGlobalAttr>() &&
2652 DeviceKernelAttr::isOpenCLSpelling(
2653 fd->getAttr<DeviceKernelAttr>()) &&
2670 if (
const auto *fd = dyn_cast<FunctionDecl>(nd)) {
2671 if (fd->isMultiVersion()) {
2673 "getMangledName: multi-version functions");
2678 "getMangledName: GPU relocatable device code");
2681 return std::string(
out.str());
2684static FunctionDecl *
2699 if (
auto *methodDecl = dyn_cast<CXXMethodDecl>(protoFunc);
2700 methodDecl && methodDecl->isImplicitObjectMemberFunction()) {
2702 paramTypes.insert(paramTypes.begin(), methodDecl->getThisType());
2705 fpt->getExtProtoInfo());
2716 params.reserve(fpt->getNumParams());
2719 for (
unsigned i = 0, e = fpt->getNumParams(); i != e; ++i) {
2723 nullptr, fpt->getParamType(i),
nullptr,
2726 params.push_back(parm);
2729 tempFunc->setParams(params);
2754 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(canonicalGd.
getDecl())) {
2757 "getMangledName: C++ constructor without variants");
2766 auto result = manglings.insert(std::make_pair(mangledName, gd));
2767 return mangledDeclNames[canonicalGd] = result.first->first();
2771 assert(!d->
getInit() &&
"Cannot emit definite definitions here!");
2779 if (gv && !mlir::cast<cir::GlobalOp>(gv).isDeclaration())
2795 if (langOpts.EmitAllDecls)
2798 const auto *vd = dyn_cast<VarDecl>(global);
2800 ((codeGenOpts.KeepPersistentStorageVariables &&
2801 (vd->getStorageDuration() ==
SD_Static ||
2802 vd->getStorageDuration() ==
SD_Thread)) ||
2803 (codeGenOpts.KeepStaticConsts && vd->getStorageDuration() ==
SD_Static &&
2804 vd->getType().isConstQualified())))
2817 if (langOpts.OpenMP >= 50 && !langOpts.OpenMPSimd) {
2818 std::optional<OMPDeclareTargetDeclAttr *> activeAttr =
2819 OMPDeclareTargetDeclAttr::getActiveAttr(global);
2820 if (!activeAttr || (*activeAttr)->getLevel() != (
unsigned)-1)
2824 const auto *fd = dyn_cast<FunctionDecl>(global);
2831 if (fd->hasAttr<TargetVersionAttr>() && !fd->isMultiVersion())
2833 if (langOpts.SYCLIsDevice) {
2834 errorNYI(fd->getSourceRange(),
"mayBeEmittedEagerly: SYCL");
2838 const auto *vd = dyn_cast<VarDecl>(global);
2840 if (astContext.getInlineVariableDefinitionKind(vd) ==
2848 if (langOpts.OpenMP && langOpts.OpenMPUseTLS &&
2849 astContext.getTargetInfo().isTLSSupported() &&
isa<VarDecl>(global) &&
2851 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(global))
2854 assert((fd || vd) &&
2855 "Only FunctionDecl and VarDecl should hit this path so far.");
2860 cir::CIRGlobalValueInterface gv) {
2861 if (gv.hasLocalLinkage())
2864 if (!gv.hasDefaultVisibility() && !gv.hasExternalWeakLinkage())
2872 const llvm::Triple &tt = cgm.
getTriple();
2874 if (tt.isOSCygMing()) {
2883 cgm.
errorNYI(
"shouldAssumeDSOLocal: MinGW");
2889 if (tt.isOSBinFormatCOFF() && gv.hasExternalWeakLinkage())
2897 if (tt.isOSBinFormatCOFF() || (tt.isOSWindows() && tt.isOSBinFormatMachO()))
2901 if (!tt.isOSBinFormatELF())
2906 if (rm != llvm::Reloc::Static && !lOpts.PIE) {
2914 return !(lOpts.SemanticInterposition || lOpts.HalfNoSemanticInterposition);
2918 if (!gv.isDeclarationForLinker())
2924 if (rm == llvm::Reloc::PIC_ && gv.hasExternalWeakLinkage())
2931 if (cgOpts.DirectAccessExternalData) {
2937 if (
auto globalOp = dyn_cast<cir::GlobalOp>(gv.getOperation())) {
2963 if (gv.hasLocalLinkage()) {
2964 gv.setGlobalVisibility(cir::VisibilityKind::Default);
2979 d->
hasAttr<OMPDeclareTargetDeclAttr>() &&
2980 d->
getAttr<OMPDeclareTargetDeclAttr>()->getDevType() !=
2981 OMPDeclareTargetDeclAttr::DT_NoHost &&
2983 llvm_unreachable(
"setGlobalVisibility: OpenMP is NYI");
2992 !d->
hasAttr<OMPDeclareTargetDeclAttr>()) {
2993 bool needsProtected =
false;
2997 }
else if (
const auto *vd = dyn_cast<VarDecl>(d)) {
2998 needsProtected = vd->hasAttr<CUDADeviceAttr>() ||
2999 vd->hasAttr<CUDAConstantAttr>() ||
3000 vd->getType()->isCUDADeviceBuiltinSurfaceType() ||
3001 vd->getType()->isCUDADeviceBuiltinTextureType();
3003 if (needsProtected) {
3004 gv.setGlobalVisibility(cir::VisibilityKind::Protected);
3010 gv.setGlobalVisibility(cir::VisibilityKind::Hidden);
3017 !gv.isDeclarationForLinker())
3026 if (
auto globalValue = dyn_cast<cir::CIRGlobalValueInterface>(op))
3045 auto res = manglings.find(mangledName);
3046 if (res == manglings.end())
3048 result = res->getValue();
3055 return cir::TLS_Model::GeneralDynamic;
3057 return cir::TLS_Model::LocalDynamic;
3059 return cir::TLS_Model::InitialExec;
3061 return cir::TLS_Model::LocalExec;
3063 llvm_unreachable(
"Invalid TLS model!");
3067 bool isExtendingDecl) {
3068 assert(d.
getTLSKind() &&
"setting TLS mode on non-TLS var!");
3073 if (d.
getAttr<TLSModelAttr>())
3077 global.setTlsModel(tlm);
3081 if (d.
isStaticLocal() || tlm != cir::TLS_Model::GeneralDynamic)
3087 if (isExtendingDecl)
3095 cir::FuncOp func,
bool isThunk) {
3097 cir::CallingConv callingConv;
3098 cir::SideEffect sideEffect;
3105 mlir::NamedAttrList pal{};
3106 std::vector<mlir::NamedAttrList> argAttrs(info.
arguments().size());
3107 mlir::NamedAttrList retAttrs{};
3109 retAttrs, callingConv, sideEffect,
3112 for (mlir::NamedAttribute
attr : pal)
3113 func->setAttr(
attr.getName(),
attr.getValue());
3115 llvm::for_each(llvm::enumerate(argAttrs), [func](
auto idx_arg_pair) {
3116 mlir::function_interface_impl::setArgAttrs(func, idx_arg_pair.index(),
3117 idx_arg_pair.value());
3119 if (!retAttrs.empty())
3120 mlir::function_interface_impl::setResultAttrs(func, 0, retAttrs);
3133 bool isIncompleteFunction,
3141 if (!isIncompleteFunction)
3143 getTypes().arrangeGlobalDeclaration(globalDecl),
3146 if (!isIncompleteFunction && func.isDeclaration())
3153 if (funcDecl->isInlineBuiltinDeclaration()) {
3155 bool hasBody = funcDecl->
hasBody(fdBody);
3157 assert(hasBody &&
"Inline builtin declarations should always have an "
3162 if (funcDecl->isReplaceableGlobalAllocationFunction()) {
3165 func->setAttr(cir::CIRDialect::getNoBuiltinAttrName(),
3177 if (!langOpts.Exceptions)
3180 if (langOpts.CXXExceptions)
3183 if (langOpts.ObjCExceptions)
3194 f->setAttr(cir::CIRDialect::getNoThrowAttrName(),
3197 std::optional<cir::InlineKind> existingInlineKind = f.getInlineKind();
3199 existingInlineKind && *existingInlineKind == cir::InlineKind::NoInline;
3200 bool isAlwaysInline = existingInlineKind &&
3201 *existingInlineKind == cir::InlineKind::AlwaysInline;
3205 if (!isAlwaysInline &&
3210 f.setInlineKind(cir::InlineKind::NoInline);
3225 if (
decl->hasAttr<NoInlineAttr>() && !isAlwaysInline) {
3227 f.setInlineKind(cir::InlineKind::NoInline);
3228 }
else if (
decl->hasAttr<AlwaysInlineAttr>() && !isNoInline) {
3231 f.setInlineKind(cir::InlineKind::AlwaysInline);
3235 if (!isAlwaysInline)
3236 f.setInlineKind(cir::InlineKind::NoInline);
3241 if (
auto *fd = dyn_cast<FunctionDecl>(
decl)) {
3246 auto checkRedeclForInline = [](
const FunctionDecl *redecl) {
3247 return redecl->isInlineSpecified();
3249 if (any_of(
decl->redecls(), checkRedeclForInline))
3254 return any_of(pattern->
redecls(), checkRedeclForInline);
3256 if (checkForInline(fd)) {
3257 f.setInlineKind(cir::InlineKind::InlineHint);
3258 }
else if (codeGenOpts.getInlining() ==
3260 !fd->isInlined() && !isAlwaysInline) {
3261 f.setInlineKind(cir::InlineKind::NoInline);
3270 StringRef mangledName, mlir::Type funcType,
GlobalDecl gd,
bool forVTable,
3272 mlir::NamedAttrList extraAttrs) {
3275 if (
const auto *fd = cast_or_null<FunctionDecl>(d)) {
3277 if (
getLangOpts().OpenMPIsTargetDevice && openMPRuntime &&
3279 !dontDefer && !isForDefinition) {
3282 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(fdDef))
3284 else if (
const auto *dd = dyn_cast<CXXDestructorDecl>(fdDef))
3294 if (fd->isMultiVersion())
3295 errorNYI(fd->getSourceRange(),
"getOrCreateCIRFunction: multi-version");
3301 assert(mlir::isa<cir::FuncOp>(entry));
3306 if (d && !d->
hasAttr<DLLImportAttr>() && !d->
hasAttr<DLLExportAttr>()) {
3314 if (isForDefinition && fn && !fn.isDeclaration()) {
3321 diagnosedConflictingDefinitions.insert(gd).second) {
3325 diag::note_previous_definition);
3329 if (fn && fn.getFunctionType() == funcType) {
3333 if (!isForDefinition) {
3341 auto *funcDecl = llvm::cast_or_null<FunctionDecl>(gd.
getDecl());
3342 bool invalidLoc = !funcDecl ||
3343 funcDecl->getSourceRange().getBegin().isInvalid() ||
3344 funcDecl->getSourceRange().getEnd().isInvalid();
3346 invalidLoc ? theModule->getLoc() :
getLoc(funcDecl->getSourceRange()),
3347 mangledName, mlir::cast<cir::FuncType>(funcType), funcDecl);
3349 if (funcDecl && funcDecl->hasAttr<AnnotateAttr>())
3350 deferredAnnotations[mangledName] = funcDecl;
3361 auto symbolOp = mlir::cast<mlir::SymbolOpInterface>(entry);
3369 if (symbolOp.getSymbolUses(symbolOp->getParentOp()))
3379 if (!extraAttrs.empty()) {
3380 extraAttrs.append(funcOp->getAttrs());
3381 funcOp->setAttrs(extraAttrs);
3388 assert(funcOp.getFunctionType() == funcType);
3395 if (isa_and_nonnull<CXXDestructorDecl>(d) &&
3425 fd = fd->getPreviousDecl()) {
3427 if (fd->doesThisDeclarationHaveABody()) {
3440 cir::FuncType funcType,
3444 mlir::OpBuilder::InsertionGuard guard(builder);
3452 builder.setInsertionPoint(cgf->
curFn);
3454 func = cir::FuncOp::create(builder, loc, name, funcType);
3461 func.setNoProto(
true);
3463 assert(func.isDeclaration() &&
"expected empty body");
3467 func.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
3469 mlir::SymbolTable::setSymbolVisibility(
3470 func, mlir::SymbolTable::Visibility::Private);
3479 theModule.push_back(func);
3484 for (
const auto *
attr :
3498 fnOp.setBuiltin(
true);
3504 return cir::CtorKind::Default;
3506 return cir::CtorKind::Copy;
3508 return cir::CtorKind::Move;
3509 return cir::CtorKind::Custom;
3514 return cir::AssignKind::Copy;
3516 return cir::AssignKind::Move;
3517 llvm_unreachable(
"not a copy or move assignment operator");
3525 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(funcDecl)) {
3526 auto cxxDtor = cir::CXXDtorAttr::get(
3529 funcOp.setFuncInfoAttr(cxxDtor);
3533 if (
const auto *ctor = dyn_cast<CXXConstructorDecl>(funcDecl)) {
3535 auto cxxCtor = cir::CXXCtorAttr::get(
3537 kind, ctor->isTrivial());
3538 funcOp.setFuncInfoAttr(cxxCtor);
3542 const auto *method = dyn_cast<CXXMethodDecl>(funcDecl);
3543 if (method && (method->isCopyAssignmentOperator() ||
3544 method->isMoveAssignmentOperator())) {
3546 auto cxxAssign = cir::CXXAssignAttr::get(
3548 assignKind, method->isTrivial());
3549 funcOp.setFuncInfoAttr(cxxAssign);
3559 bool inStdNamespace = method ? method->getParent()->isInStdNamespace()
3561 if (!inStdNamespace)
3567 std::optional<cir::KnownFuncKind>
kind;
3569 kind = llvm::StringSwitch<std::optional<cir::KnownFuncKind>>(
3571 .Case(cir::StdFindOp::getFunctionName(),
3572 cir::StdFindOp::getFuncKind())
3573 .Default(std::nullopt);
3582 cir::FuncOp funcOp, StringRef name) {
3598 mlir::NamedAttrList extraAttrs,
3600 bool assumeConvergent) {
3601 if (assumeConvergent)
3602 errorNYI(
"createRuntimeFunction: assumeConvergent");
3612 entry.setDSOLocal(
true);
3618mlir::SymbolTable::Visibility
3622 if (op.isDeclaration())
3623 return mlir::SymbolTable::Visibility::Private;
3627mlir::SymbolTable::Visibility
3630 case cir::GlobalLinkageKind::InternalLinkage:
3631 case cir::GlobalLinkageKind::PrivateLinkage:
3632 return mlir::SymbolTable::Visibility::Private;
3633 case cir::GlobalLinkageKind::ExternalLinkage:
3634 case cir::GlobalLinkageKind::ExternalWeakLinkage:
3635 case cir::GlobalLinkageKind::LinkOnceODRLinkage:
3636 case cir::GlobalLinkageKind::AvailableExternallyLinkage:
3637 case cir::GlobalLinkageKind::CommonLinkage:
3638 case cir::GlobalLinkageKind::WeakAnyLinkage:
3639 case cir::GlobalLinkageKind::WeakODRLinkage:
3640 return mlir::SymbolTable::Visibility::Public;
3642 llvm::errs() <<
"visibility not implemented for '"
3643 << stringifyGlobalLinkageKind(glk) <<
"'\n";
3644 assert(0 &&
"not implemented");
3647 llvm_unreachable(
"linkage should be handled above!");
3651 clang::VisibilityAttr::VisibilityType visibility) {
3652 switch (visibility) {
3653 case clang::VisibilityAttr::VisibilityType::Default:
3654 return cir::VisibilityKind::Default;
3655 case clang::VisibilityAttr::VisibilityType::Hidden:
3656 return cir::VisibilityKind::Hidden;
3657 case clang::VisibilityAttr::VisibilityType::Protected:
3658 return cir::VisibilityKind::Protected;
3660 llvm_unreachable(
"unexpected visibility value");
3665 const clang::VisibilityAttr *va =
decl->getAttr<clang::VisibilityAttr>();
3666 cir::VisibilityAttr cirVisibility =
3669 cirVisibility = cir::VisibilityAttr::get(
3673 return cirVisibility;
3679 applyReplacements();
3681 theModule->setAttr(cir::CIRDialect::getModuleLevelAsmAttrName(),
3682 builder.getArrayAttr(globalScopeAsm));
3684 emitGlobalAnnotations();
3686 if (!recordLayoutEntries.empty())
3688 cir::CIRDialect::getRecordLayoutsAttrName(),
3689 mlir::DictionaryAttr::get(&
getMLIRContext(), recordLayoutEntries));
3698 std::string cuidName =
3701 auto loc = builder.getUnknownLoc();
3702 mlir::ptr::MemorySpaceAttrInterface addrSpace =
3704 getGlobalVarAddressSpace(
nullptr));
3708 gv.setLinkage(cir::GlobalLinkageKind::ExternalLinkage);
3710 auto zeroAttr = cir::IntAttr::get(int8Ty, 0);
3711 gv.setInitialValueAttr(zeroAttr);
3713 mlir::SymbolTable::setSymbolVisibility(
3714 gv, mlir::SymbolTable::Visibility::Public);
3719 if (astContext.getLangOpts().CUDA && cudaRuntime)
3734 const AliasAttr *aa = d->
getAttr<AliasAttr>();
3735 assert(aa &&
"Not an alias?");
3739 if (aa->getAliasee() == mangledName) {
3740 diags.Report(aa->getLocation(), diag::err_cyclic_alias) << 0;
3748 auto entryGV = mlir::dyn_cast<cir::CIRGlobalValueInterface>(entry);
3749 if (entryGV && entryGV.isDefinition())
3762 cir::GlobalLinkageKind linkage;
3775 linkage = cir::GlobalLinkageKind::WeakAnyLinkage;
3787 mlir::SymbolTable::Visibility visibility =
3791 cir::CIRGlobalValueInterface alias =
3792 isFunction ? mlir::cast<cir::CIRGlobalValueInterface>(
3794 mlir::cast<cir::FuncType>(declTy),
3797 : mlir::cast<cir::CIRGlobalValueInterface>(
3799 alias.setAliasee(aa->getAliasee());
3800 alias.setLinkage(linkage);
3801 mlir::SymbolTable::setSymbolVisibility(alias, visibility);
3809 cir::FuncOp aliasee,
3810 cir::GlobalLinkageKind linkage) {
3812 auto *aliasFD = dyn_cast<FunctionDecl>(aliasGD.
getDecl());
3813 assert(aliasFD &&
"expected FunctionDecl");
3824 mangledName, fnType, aliasFD);
3825 alias.setAliasee(aliasee.getName());
3826 alias.setLinkage(linkage);
3830 mlir::SymbolTable::setSymbolVisibility(
3831 alias, mlir::SymbolTable::Visibility::Private);
3843 "declaration exists with different type");
3855 return genTypes.convertType(
type);
3862 return mlir::verify(theModule).succeeded();
3871 return builder.getConstNullPtrAttr(builder.getUInt8PtrTy());
3874 langOpts.ObjCRuntime.isGNUFamily()) {
3875 errorNYI(loc,
"getAddrOfRTTIDescriptor: Objc PtrType & Objc RT GUN");
3885 llvm::iterator_range<CastExpr::path_const_iterator> path) {
3892 assert(!base->isVirtual() &&
"Should not see virtual bases here!");
3897 const auto *baseDecl = base->getType()->castAsCXXRecordDecl();
3909 llvm::StringRef feature) {
3910 unsigned diagID = diags.getCustomDiagID(
3912 return diags.Report(loc, diagID) << feature;
3916 llvm::StringRef feature) {
3928 "cannot compile this %0 yet");
3929 diags.Report(astContext.getFullLoc(s->
getBeginLoc()), diagId)
3936 "cannot compile this %0 yet");
3937 diags.Report(astContext.getFullLoc(d->
getLocation()), diagId) <<
type;
3941 cir::LabelOp label) {
3942 [[maybe_unused]]
auto result =
3944 assert(result.second &&
3945 "attempting to map a blockaddress info that is already mapped");
3958 "not a global temporary");
3970 materializedType = mte->
getType();
3979 llvm::raw_svector_ostream
out(name);
3983 auto insertResult = materializedGlobalTemporaryMap.insert({mte,
nullptr});
3984 if (!insertResult.second) {
3988 if (!insertResult.first->second) {
3991 insertResult.first->second =
3994 return insertResult.first->second;
4011 value = &evalResult.
Val;
4015 std::optional<ConstantEmitter> emitter;
4016 mlir::Attribute initialValue =
nullptr;
4017 bool isConstant =
false;
4021 emitter.emplace(*
this);
4022 initialValue = emitter->emitForInitializer(*value, materializedType);
4027 type = mlir::cast<mlir::TypedAttr>(initialValue).getType();
4036 if (linkage == cir::GlobalLinkageKind::ExternalLinkage) {
4038 if (
varDecl->isStaticDataMember() &&
varDecl->getAnyInitializer(initVD) &&
4046 linkage = cir::GlobalLinkageKind::InternalLinkage;
4050 gv.setInitialValueAttr(initialValue);
4051 gv.setLinkage(linkage);
4055 emitter->finalize(gv);
4057 if (!gv.hasLocalLinkage()) {
4062 gv.setAlignment(align.getAsAlign().value());
4067 mlir::Operation *cv = gv;
4076 mlir::Operation *&entry = materializedGlobalTemporaryMap[mte];
4078 entry->replaceAllUsesWith(cv);
4093 return *globalOpEntry;
4100 "emitForInitializer should take gcd->getType().getAddressSpace()");
4102 auto typedInit = dyn_cast<mlir::TypedAttr>(init);
4106 "getAddrOfUnnamedGlobalConstantDecl: non-typed initializer");
4115 std::string name = numEntries == 0
4117 : (Twine(
".constant.") + Twine(numEntries)).str();
4119 typedInit.getType(),
true);
4120 globalOp.setLinkage(cir::GlobalLinkageKind::PrivateLinkage);
4123 globalOp.setAlignment(alignment.
getAsAlign().value());
4127 *globalOpEntry = globalOp;
4142 "emitForInitializer should take tpo->getType().getAddressSpace()");
4143 mlir::Attribute init =
4153 cir::GlobalLinkageKind linkage =
4155 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
4156 : cir::GlobalLinkageKind::InternalLinkage;
4160 typedInit.getType(),
true);
4161 globalOp.setLinkage(linkage);
4162 globalOp.setAlignment(alignment.
getAsAlign().value());
4164 linkage == cir::GlobalLinkageKind::LinkOnceODRLinkage);
4179CIRGenModule::getOrCreateAnnotationArgs(
const AnnotateAttr *
attr) {
4186 llvm::FoldingSetNodeID id;
4187 for (
Expr *e : exprs)
4190 mlir::ArrayAttr &lookup = annotationArgs[
id.ComputeHash()];
4195 args.reserve(exprs.size());
4196 for (
Expr *e : exprs) {
4197 if (
auto *strE = dyn_cast<clang::StringLiteral>(e->IgnoreParenCasts())) {
4198 args.push_back(builder.getStringAttr(strE->getString()));
4199 }
else if (
auto *intE =
4200 dyn_cast<clang::IntegerLiteral>(e->IgnoreParenCasts())) {
4201 auto intTy = builder.getIntegerType(intE->getValue().getBitWidth());
4202 args.push_back(builder.getIntegerAttr(intTy, intE->getValue()));
4204 errorNYI(e->getExprLoc(),
"annotation argument expression");
4208 return lookup = builder.getArrayAttr(args);
4211cir::AnnotationAttr CIRGenModule::emitAnnotateAttr(
const AnnotateAttr *aa) {
4212 mlir::StringAttr annoGV = builder.getStringAttr(aa->getAnnotation());
4213 mlir::ArrayAttr args = getOrCreateAnnotationArgs(aa);
4214 return cir::AnnotationAttr::get(&
getMLIRContext(), annoGV, args);
4218 mlir::Operation *gv) {
4219 assert(d->
hasAttr<AnnotateAttr>() &&
"no annotate attribute");
4221 "annotation only on globals");
4224 annotations.push_back(emitAnnotateAttr(i));
4225 if (
auto global = dyn_cast<cir::GlobalOp>(gv))
4226 global.setAnnotationsAttr(builder.getArrayAttr(annotations));
4227 else if (
auto func = dyn_cast<cir::FuncOp>(gv))
4228 func.setAnnotationsAttr(builder.getArrayAttr(annotations));
4231void CIRGenModule::emitGlobalAnnotations() {
4232 for (
const auto &[mangledName, vd] : deferredAnnotations) {
4237 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 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 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
llvm::ArrayRef< CanQualType > arguments() const
cir::FuncOp generateCode(clang::GlobalDecl gd, cir::FuncOp fn, cir::FuncType funcType)
void emitVariablyModifiedType(QualType ty)
mlir::Operation * curFn
The current function or global initializer that is generated code for.
This class organizes the cross-function state that is used while generating CIR code.
cir::GlobalOp getAddrOfUnnamedGlobalConstantDecl(const UnnamedGlobalConstantDecl *gcd)
void 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()
llvm::DenseMap< cir::BlockAddrInfoAttr, cir::LabelOp > blockAddressInfoToLabel
Map BlockAddrInfoAttr (function name, label name) to the corresponding CIR LabelOp.
void emitTopLevelDecl(clang::Decl *decl)
void emitOMPDeclareMapper(const OMPDeclareMapperDecl *d)
void addReplacement(llvm::StringRef name, mlir::Operation *op)
mlir::Type convertType(clang::QualType type)
bool shouldEmitRTTI(bool forEH=false)
cir::GlobalOp getGlobalForStringLiteral(const StringLiteral *s, llvm::StringRef name=".str")
Return a global symbol reference to a constant array for the given string literal.
std::vector< cir::CIRGlobalValueInterface > llvmUsed
List of global values which are required to be present in the object file; This is used for forcing v...
void emitOMPCapturedExpr(const OMPCapturedExprDecl *d)
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.
cir::LabelOp lookupBlockAddressInfo(cir::BlockAddrInfoAttr blockInfo)
bool mayBeEmittedEagerly(const clang::ValueDecl *d)
Determine whether the definition can be emitted eagerly, or should be delayed until the end of the tr...
void mapBlockAddress(cir::BlockAddrInfoAttr blockInfo, cir::LabelOp label)
void addGlobalAnnotations(const clang::ValueDecl *d, mlir::Operation *gv)
Add global annotations for a global value (GlobalOp or FuncOp).
void setCIRFunctionAttributesForDefinition(const clang::FunctionDecl *fd, cir::FuncOp f)
Set extra attributes (inline, etc.) for a function.
std::string getOpenACCBindMangledName(const IdentifierInfo *bindName, const FunctionDecl *attachedFunction)
void emitGlobalFunctionDefinition(clang::GlobalDecl gd, mlir::Operation *op)
CIRGenVTables & getVTables()
void setFunctionLinkage(GlobalDecl gd, cir::FuncOp f)
std::vector< clang::GlobalDecl > deferredDeclsToEmit
void emitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *d)
CIRGenOpenMPRuntime & getOpenMPRuntime()
void emitAMDGPUMetadata()
Emits AMDGPU specific Metadata.
void emitOMPGroupPrivateDecl(const OMPGroupPrivateDecl *d)
mlir::Attribute getConstantArrayFromStringLiteral(const StringLiteral *e)
Return a constant array for the given string.
cir::VisibilityAttr getGlobalVisibilityAttrFromDecl(const Decl *decl)
void setCommonAttributes(GlobalDecl gd, mlir::Operation *op)
Set attributes which are common to any form of a global definition (alias, Objective-C method,...
void emitDeclareTargetFunction(const FunctionDecl *fd, cir::FuncOp funcOp)
If the function has an OMPDeclareTargetDeclAttr, set the corresponding omp.declare_target attribute o...
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.