19#include "mlir/Dialect/OpenMP/Utils/Utils.h"
20#include "mlir/IR/SymbolTable.h"
23#include "clang/AST/Attrs.inc"
37#include "llvm/ADT/STLExtras.h"
38#include "llvm/ADT/StringExtras.h"
39#include "llvm/ADT/StringRef.h"
40#include "llvm/ADT/StringSwitch.h"
41#include "llvm/Support/raw_ostream.h"
45#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
46#include "mlir/IR/Attributes.h"
47#include "mlir/IR/BuiltinOps.h"
48#include "mlir/IR/Location.h"
49#include "mlir/IR/MLIRContext.h"
50#include "mlir/IR/Operation.h"
51#include "mlir/IR/Verifier.h"
60 case TargetCXXABI::GenericItanium:
61 case TargetCXXABI::GenericAArch64:
62 case TargetCXXABI::AppleARM64:
63 case TargetCXXABI::GenericARM:
66 case TargetCXXABI::Fuchsia:
67 case TargetCXXABI::iOS:
68 case TargetCXXABI::WatchOS:
69 case TargetCXXABI::GenericMIPS:
70 case TargetCXXABI::WebAssembly:
71 case TargetCXXABI::XL:
72 case TargetCXXABI::Microsoft:
73 cgm.
errorNYI(
"createCXXABI: C++ ABI kind");
77 llvm_unreachable(
"invalid C++ ABI kind");
80CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
84 : builder(mlirContext, *this), astContext(astContext),
85 langOpts(astContext.
getLangOpts()), codeGenOpts(cgo),
86 theModule{
mlir::ModuleOp::create(
mlir::UnknownLoc::get(&mlirContext))},
87 diags(diags), target(astContext.getTargetInfo()),
88 abi(
createCXXABI(*this)), genTypes(*this), vtables(*this) {
116 .toCharUnitsFromBits(
120 const unsigned charSize = astContext.getTargetInfo().getCharWidth();
124 const unsigned sizeTypeSize =
125 astContext.getTypeSize(astContext.getSignedSizeType());
126 SizeSizeInBytes = astContext.toCharUnitsFromBits(sizeTypeSize).getQuantity();
133 std::optional<cir::SourceLanguage> sourceLanguage = getCIRSourceLanguage();
136 cir::CIRDialect::getSourceLanguageAttrName(),
137 cir::SourceLanguageAttr::get(&mlirContext, *sourceLanguage));
138 theModule->setAttr(cir::CIRDialect::getTripleAttrName(),
139 builder.getStringAttr(
getTriple().str()));
141 if (cgo.OptimizationLevel > 0 || cgo.OptimizeSize > 0)
142 theModule->setAttr(cir::CIRDialect::getOptInfoAttrName(),
143 cir::OptInfoAttr::get(&mlirContext,
144 cgo.OptimizationLevel,
148 cir::CIRDialect::getDefaultTlsModelAttrName(),
151 if (langOpts.OpenMP) {
152 mlir::omp::OffloadModuleOpts ompOpts(
153 langOpts.OpenMPTargetDebug, langOpts.OpenMPTeamSubscription,
154 langOpts.OpenMPThreadSubscription, langOpts.OpenMPNoThreadState,
155 langOpts.OpenMPNoNestedParallelism, langOpts.OpenMPIsTargetDevice,
156 getTriple().isGPU(), langOpts.OpenMPForceUSM, langOpts.OpenMP,
157 langOpts.OMPHostIRFile, langOpts.OMPTargetTriples, langOpts.NoGPULib);
158 mlir::omp::setOffloadModuleInterfaceAttributes(theModule, ompOpts);
159 mlir::omp::setOpenMPVersionAttribute(theModule, langOpts.OpenMP);
165 createOpenMPRuntime();
170 FileID mainFileId = astContext.getSourceManager().getMainFileID();
172 *astContext.getSourceManager().getFileEntryForID(mainFileId);
175 theModule.setSymName(path);
176 theModule->setLoc(mlir::FileLineColLoc::get(&mlirContext, path,
183 llvm::StringRef cudaBinaryName = codeGenOpts.OffloadBinaryToEmbedFile;
184 if (!cudaBinaryName.empty()) {
185 theModule->setAttr(cir::CIRDialect::getCUDABinaryHandleAttrName(),
186 cir::CUDABinaryHandleAttr::get(
187 &mlirContext, mlir::StringAttr::get(
188 &mlirContext, cudaBinaryName)));
195void CIRGenModule::createCUDARuntime() {
199void CIRGenModule::createOpenMPRuntime() {
200 openMPRuntime = std::make_unique<CIRGenOpenMPRuntime>(*
this);
211 auto &layout = astContext.getASTRecordLayout(rd);
216 return layout.getAlignment();
219 return layout.getNonVirtualAlignment();
224 bool forPointeeType) {
234 if (
unsigned align = tt->getDecl()->getMaxAlignment()) {
237 return astContext.toCharUnitsFromBits(align);
245 t = astContext.getBaseElementType(t);
266 }
else if (forPointeeType && !alignForArray &&
270 alignment = astContext.getTypeAlignInChars(t);
275 if (
unsigned maxAlign = astContext.getLangOpts().MaxTypeAlign) {
277 !astContext.isAlignmentRequired(t))
291 if (theTargetCIRGenInfo)
292 return *theTargetCIRGenInfo;
295 switch (triple.getArch()) {
302 case llvm::Triple::x86_64: {
303 switch (triple.getOS()) {
310 case llvm::Triple::Linux:
312 return *theTargetCIRGenInfo;
315 case llvm::Triple::aarch64:
316 case llvm::Triple::aarch64_32:
317 case llvm::Triple::aarch64_be: {
319 return *theTargetCIRGenInfo;
321 case llvm::Triple::nvptx:
322 case llvm::Triple::nvptx64:
324 return *theTargetCIRGenInfo;
325 case llvm::Triple::amdgpu: {
327 return *theTargetCIRGenInfo;
329 case llvm::Triple::spirv:
330 case llvm::Triple::spirv32:
331 case llvm::Triple::spirv64:
333 return *theTargetCIRGenInfo;
338 assert(cLoc.
isValid() &&
"expected valid source location");
342 return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
347 assert(cRange.
isValid() &&
"expected a valid source range");
350 mlir::Attribute metadata;
351 return mlir::FusedLoc::get({begin, end}, metadata, builder.getContext());
360 false, isForDefinition);
394 assert(op &&
"expected a valid global op");
402 mlir::Operation *globalValueOp = op;
403 if (
auto gv = dyn_cast<cir::GetGlobalOp>(op)) {
405 assert(globalValueOp &&
"expected a valid global op");
408 if (
auto cirGlobalValue =
409 dyn_cast<cir::CIRGlobalValueInterface>(globalValueOp))
410 if (!cirGlobalValue.isDeclaration())
431 assert(deferredVTables.empty());
441 std::vector<GlobalDecl> curDeclsToEmit;
449 if (
const auto *fd = d.getDecl()->getAsFunction()) {
450 if (langOpts.SYCLIsDevice && fd->hasAttr<SYCLKernelEntryPointAttr>() &&
454 if (!fd->getAttr<SYCLKernelEntryPointAttr>()->isInvalidAttr()) {
481 if (
auto *
attr =
decl->getAttr<AttrT>())
482 return attr->isImplicit();
483 return decl->isImplicit();
488 assert(langOpts.CUDA &&
"Should not be called by non-CUDA languages");
493 return !langOpts.CUDAIsDevice || global->
hasAttr<CUDADeviceAttr>() ||
494 global->
hasAttr<CUDAConstantAttr>() ||
495 global->
hasAttr<CUDASharedAttr>() ||
505 os << (isa<VarDecl>(d) ?
".static." :
".intern.");
507 os << (isa<VarDecl>(d) ?
"__static__" :
"__intern__");
514 "printPostfixForExternalizedDecl: CUID is not specified");
521 if (
const auto *cd = dyn_cast<clang::OpenACCConstructDecl>(gd.
getDecl())) {
529 if (global->hasAttr<WeakRefAttr>())
534 if (global->hasAttr<AliasAttr>()) {
547 "Expected Variable or Function");
548 if (
const auto *
varDecl = dyn_cast<VarDecl>(global)) {
552 }
else if (langOpts.CUDAIsDevice) {
553 const auto *
functionDecl = dyn_cast<FunctionDecl>(global);
554 if ((!global->hasAttr<CUDADeviceAttr>() ||
555 (langOpts.OffloadImplicitHostDeviceTemplates &&
560 !
getASTContext().CUDAImplicitHostDeviceFunUsedByDevice.count(
562 !global->hasAttr<CUDAGlobalAttr>() &&
564 !global->hasAttr<CUDAHostAttr>()))
567 }
else if (!global->hasAttr<CUDAHostAttr>() &&
568 global->hasAttr<CUDADeviceAttr>())
572 if (langOpts.OpenMP) {
574 if (openMPRuntime && openMPRuntime->emitTargetGlobal(gd))
576 if (
auto *drd = dyn_cast<OMPDeclareReductionDecl>(global)) {
581 if (
auto *dmd = dyn_cast<OMPDeclareMapperDecl>(global)) {
588 if (
const auto *fd = dyn_cast<FunctionDecl>(global)) {
591 if (fd->hasAttr<AnnotateAttr>()) {
594 deferredAnnotations[mangledName] = fd;
596 if (!fd->doesThisDeclarationHaveABody()) {
597 if (!fd->doesDeclarationForceExternallyVisibleDefinition() &&
608 assert(vd->isFileVarDecl() &&
"Cannot emit local var decl as global.");
610 !astContext.isMSStaticDataMemberInlineDefinition(vd)) {
614 if (astContext.getInlineVariableDefinitionKind(vd) ==
653 mlir::Operation *op) {
657 cir::FuncOp funcOp = dyn_cast_if_present<cir::FuncOp>(op);
658 if (!funcOp || funcOp.getFunctionType() != funcType) {
664 if (!funcOp.isDeclaration())
676 mlir::OpBuilder::InsertionGuard guard(builder);
681 setNonAliasAttributes(gd, funcOp);
684 auto getPriority = [
this](
const auto *
attr) ->
int {
688 return attr->DefaultPriority;
691 if (
const ConstructorAttr *ca = funcDecl->getAttr<ConstructorAttr>())
693 if (
const DestructorAttr *da = funcDecl->getAttr<DestructorAttr>())
696 if (funcDecl->getAttr<AnnotateAttr>())
699 if (
getLangOpts().OpenMP && funcDecl->hasAttr<OMPDeclareTargetDeclAttr>())
705 std::optional<int> priority) {
714 ctor.setGlobalCtorPriority(priority);
719 std::optional<int> priority) {
720 if (codeGenOpts.RegisterGlobalDtorsWithAtExit &&
722 errorNYI(dtor.getLoc(),
"registerGlobalDtorsWithAtExit");
725 dtor.setGlobalDtorPriority(priority);
750 mlir::ptr::MemorySpaceAttrInterface addrSpace,
751 mlir::Operation *insertPoint) {
756 mlir::OpBuilder::InsertionGuard guard(builder);
762 builder.setInsertionPoint(insertPoint);
768 builder.setInsertionPointToStart(
getModule().getBody());
771 g = cir::GlobalOp::create(builder, loc, name, t, isConstant, addrSpace);
777 mlir::SymbolTable::setSymbolVisibility(
778 g, mlir::SymbolTable::Visibility::Private);
786 if (isa_and_nonnull<NamedDecl>(d))
790 if (
auto gvi = mlir::dyn_cast<cir::CIRGlobalValueInterface>(gv)) {
791 if (d && d->
hasAttr<UsedAttr>())
794 if (
const auto *vd = dyn_cast_if_present<VarDecl>(d);
795 vd && ((codeGenOpts.KeepPersistentStorageVariables &&
796 (vd->getStorageDuration() ==
SD_Static ||
797 vd->getStorageDuration() ==
SD_Thread)) ||
798 (codeGenOpts.KeepStaticConsts &&
800 vd->getType().isConstQualified())))
806static std::vector<std::string>
808 llvm::StringMap<bool> &featureMap) {
809 llvm::StringMap<bool> defaultFeatureMap;
813 std::vector<std::string> delta;
814 for (
const auto &[k, v] : featureMap) {
815 auto defaultIt = defaultFeatureMap.find(k);
816 if (defaultIt == defaultFeatureMap.end() || defaultIt->getValue() != v)
817 delta.push_back((v ?
"+" :
"-") + k.str());
823bool CIRGenModule::getCPUAndFeaturesAttributes(
824 GlobalDecl gd, llvm::StringMap<std::string> &attrs,
825 bool setTargetFeatures) {
831 std::vector<std::string> features;
835 const auto *fd = dyn_cast_or_null<FunctionDecl>(gd.
getDecl());
836 fd = fd ? fd->getMostRecentDecl() : fd;
837 const auto *td = fd ? fd->getAttr<TargetAttr>() :
nullptr;
838 const auto *tv = fd ? fd->getAttr<TargetVersionAttr>() :
nullptr;
839 assert((!td || !tv) &&
"both target_version and target specified");
840 const auto *sd = fd ? fd->getAttr<CPUSpecificAttr>() :
nullptr;
841 const auto *tc = fd ? fd->getAttr<TargetClonesAttr>() :
nullptr;
842 bool addedAttr =
false;
843 if (td || tv || sd || tc) {
844 llvm::StringMap<bool> featureMap;
845 astContext.getFunctionFeatureMap(featureMap, gd);
851 llvm::StringRef featureStr = td ? td->getFeaturesStr() : llvm::StringRef();
854 if (!featureStr.empty()) {
855 clang::ParsedTargetAttr parsedAttr =
857 if (!parsedAttr.
CPU.empty() &&
859 targetCPU = parsedAttr.
CPU;
862 if (!parsedAttr.
Tune.empty() &&
864 tuneCPU = parsedAttr.
Tune;
880 features.reserve(features.size() + featureMap.size());
881 for (
const auto &entry : featureMap)
882 features.push_back((entry.getValue() ?
"+" :
"-") +
883 entry.getKey().str());
888 llvm::StringMap<bool> featureMap;
890 astContext.getFunctionFeatureMap(featureMap, gd);
901 if (!targetCPU.empty()) {
902 attrs[cir::CIRDialect::getTargetCPUAttrName()] = targetCPU.str();
905 if (!tuneCPU.empty()) {
906 attrs[cir::CIRDialect::getTuneCPUAttrName()] = tuneCPU.str();
909 if (!features.empty() && setTargetFeatures) {
910 llvm::erase_if(features, [&](
const std::string &f) {
911 assert(!f.empty() && (f[0] ==
'+' || f[0] ==
'-') &&
912 "feature string must start with '+' or '-'");
915 llvm::sort(features);
916 attrs[cir::CIRDialect::getTargetFeaturesAttrName()] =
917 llvm::join(features,
",");
925void CIRGenModule::setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op) {
930 if (
auto gvi = mlir::dyn_cast<cir::CIRGlobalValueInterface>(op)) {
931 if (
const auto *sa = d->
getAttr<SectionAttr>())
932 gvi.setSection(builder.getStringAttr(sa->getName()));
936 if (
auto func = dyn_cast<cir::FuncOp>(op)) {
937 llvm::StringMap<std::string> attrs;
938 if (getCPUAndFeaturesAttributes(gd, attrs)) {
945 for (llvm::StringRef name :
946 {cir::CIRDialect::getTargetCPUAttrName(),
947 cir::CIRDialect::getTuneCPUAttrName(),
948 cir::CIRDialect::getTargetFeaturesAttrName()})
949 func->removeAttr(name);
950 for (
const auto &[key, val] : attrs)
951 func->setAttr(key, builder.getStringAttr(val));
961std::optional<cir::SourceLanguage> CIRGenModule::getCIRSourceLanguage()
const {
962 using ClangStd = clang::LangStandard;
963 using CIRLang = cir::SourceLanguage;
968 if (opts.C99 || opts.C11 || opts.C17 || opts.C23 || opts.C2y ||
969 opts.LangStd == ClangStd::lang_c89 ||
970 opts.LangStd == ClangStd::lang_gnu89)
975 errorNYI(
"CIR does not yet support the given source language");
979LangAS CIRGenModule::getGlobalVarAddressSpace(
const VarDecl *d) {
980 if (langOpts.OpenCL) {
988 if (langOpts.SYCLIsDevice &&
990 errorNYI(
"SYCL global address space");
992 if (langOpts.CUDA && langOpts.CUDAIsDevice) {
994 if (d->
hasAttr<CUDAConstantAttr>())
996 if (d->
hasAttr<CUDASharedAttr>())
998 if (d->
hasAttr<CUDADeviceAttr>())
1006 if (langOpts.OpenMP)
1007 errorNYI(
"OpenMP global address space");
1020 gv.
setLinkage(cir::GlobalLinkageKind::ExternalWeakLinkage);
1029 auto linkage = cir::GlobalLinkageKind::ExternalWeakLinkage;
1030 func.setLinkage(linkage);
1031 func.setLinkageAttr(
1032 cir::GlobalLinkageKindAttr::get(&cgm.
getMLIRContext(), linkage));
1034 if (!func.isDeclaration())
1035 mlir::SymbolTable::setSymbolVisibility(
1042 for (mlir::Attribute i : indexes) {
1043 auto ind = mlir::cast<mlir::IntegerAttr>(i);
1044 inds.push_back(ind.getValue().getSExtValue());
1050 return view.getSymbol().getValue() == glob.getSymName();
1054 cir::GlobalOp newGlob,
1055 cir::GlobalViewAttr
attr,
1066 mlir::Type newTy = newGlob.getSymType();
1071 cir::PointerType newPtrTy;
1074 newPtrTy = cir::PointerType::get(newTy);
1083 cgm.
errorNYI(
"Unhandled type in createNewGlobalView");
1089 mlir::Attribute oldInit) {
1090 if (
auto oldView = mlir::dyn_cast<cir::GlobalViewAttr>(oldInit))
1093 auto getNewInitElements =
1094 [&](mlir::ArrayAttr oldElements) -> mlir::ArrayAttr {
1096 for (mlir::Attribute elt : oldElements) {
1097 if (
auto view = mlir::dyn_cast<cir::GlobalViewAttr>(elt))
1099 else if (mlir::isa<cir::ConstArrayAttr, cir::ConstRecordAttr>(elt))
1102 newElements.push_back(elt);
1104 return mlir::ArrayAttr::get(cgm.
getBuilder().getContext(), newElements);
1107 if (
auto oldArray = mlir::dyn_cast<cir::ConstArrayAttr>(oldInit)) {
1113 mlir::Attribute oldElts = oldArray.getElts();
1114 if (mlir::isa<mlir::StringAttr>(oldElts))
1116 mlir::Attribute newElements =
1117 getNewInitElements(mlir::cast<mlir::ArrayAttr>(oldElts));
1119 newElements, mlir::cast<cir::ArrayType>(oldArray.getType()));
1121 if (
auto oldRecord = mlir::dyn_cast<cir::ConstRecordAttr>(oldInit)) {
1122 mlir::ArrayAttr newMembers = getNewInitElements(oldRecord.getMembers());
1123 auto recordTy = mlir::cast<cir::RecordType>(oldRecord.getType());
1129 cgm.
errorNYI(
"Unhandled type in getNewInitValue");
1137 assert(oldGV.getSymName() == newGV.getSymName() &&
"symbol names must match");
1139 mlir::Type oldTy = oldGV.getSymType();
1140 mlir::Type newTy = newGV.getSymType();
1145 assert(oldTy != newTy &&
"expected type change in replaceGlobal");
1148 std::optional<mlir::SymbolTable::UseRange> oldSymUses =
1149 oldGV.getSymbolUses(theModule);
1150 for (mlir::SymbolTable::SymbolUse use : *oldSymUses) {
1151 mlir::Operation *userOp = use.getUser();
1153 (mlir::isa<cir::GetGlobalOp, cir::GlobalOp, cir::ConstantOp>(userOp)) &&
1154 "Unexpected user for global op");
1156 if (
auto getGlobalOp = dyn_cast<cir::GetGlobalOp>(use.getUser())) {
1157 mlir::Value useOpResultValue = getGlobalOp.getAddr();
1158 useOpResultValue.setType(cir::PointerType::get(newTy));
1160 mlir::OpBuilder::InsertionGuard guard(builder);
1161 builder.setInsertionPointAfter(getGlobalOp);
1162 mlir::Type ptrTy = builder.getPointerTo(oldTy);
1164 builder.createBitcast(getGlobalOp->getLoc(), useOpResultValue, ptrTy);
1165 useOpResultValue.replaceAllUsesExcept(
cast,
cast.getDefiningOp());
1166 }
else if (
auto glob = dyn_cast<cir::GlobalOp>(userOp)) {
1167 if (
auto init = glob.getInitialValue()) {
1168 mlir::Attribute nw =
getNewInitValue(*
this, newGV, oldTy, init.value());
1169 glob.setInitialValueAttr(nw);
1171 }
else if (
auto c = dyn_cast<cir::ConstantOp>(userOp)) {
1172 mlir::Attribute init =
getNewInitValue(*
this, newGV, oldTy, c.getValue());
1173 auto typedAttr = mlir::cast<mlir::TypedAttr>(init);
1174 mlir::OpBuilder::InsertionGuard guard(builder);
1175 builder.setInsertionPointAfter(c);
1176 auto newUser = cir::ConstantOp::create(builder, c.getLoc(), typedAttr);
1177 c.replaceAllUsesWith(newUser.getOperation());
1213 cir::GlobalOp entry;
1217 "getOrCreateCIRGlobal: global with non-GlobalOp type");
1222 mlir::ptr::MemorySpaceAttrInterface entryCIRAS = entry.getAddrSpaceAttr();
1228 if (entry.getSymType() == ty &&
1238 if (isForDefinition && !entry.isDeclaration()) {
1240 "getOrCreateCIRGlobal: global with conflicting type");
1248 if (!isForDefinition)
1257 bool isConstant =
false;
1265 mlir::ptr::MemorySpaceAttrInterface declCIRAS =
1270 cir::GlobalOp gv =
createGlobalOp(loc, mangledName, ty, isConstant, declCIRAS,
1271 entry.getOperation());
1291 if (langOpts.OpenMP && !langOpts.OpenMPSimd)
1293 "getOrCreateCIRGlobal: OpenMP target global variable");
1295 gv.setAlignmentAttr(
getSize(astContext.getDeclAlign(d)));
1306 if (astContext.isMSStaticDataMemberInlineDefinition(d))
1308 "getOrCreateCIRGlobal: MS static data member inline definition");
1312 if (
const SectionAttr *sa = d->
getAttr<SectionAttr>())
1313 gv.setSectionAttr(builder.getStringAttr(sa->getName()));
1317 if (
getTriple().getArch() == llvm::Triple::xcore)
1319 "getOrCreateCIRGlobal: XCore specific ABI requirements");
1329 "getOrCreateCIRGlobal: external const declaration with initializer");
1341 "getOrCreateCIRGlobal: HIP managed attribute");
1376 mlir::Type ptrTy = builder.getPointerTo(g.getSymType(), g.getAddrSpaceAttr());
1377 return cir::GetGlobalOp::create(
1380 g.getStaticLocalGuard().has_value());
1388 cir::PointerType ptrTy =
1389 builder.getPointerTo(globalOp.getSymType(), globalOp.getAddrSpaceAttr());
1390 return builder.getGlobalViewAttr(ptrTy, globalOp);
1394 assert((mlir::isa<cir::FuncOp>(gv.getOperation()) ||
1395 !gv.isDeclarationForLinker()) &&
1396 "Only globals with definition can force usage.");
1401 assert(!gv.isDeclarationForLinker() &&
1402 "Only globals with definition can force usage.");
1407 cir::CIRGlobalValueInterface gv) {
1408 assert((mlir::isa<cir::FuncOp>(gv.getOperation()) ||
1409 !gv.isDeclarationForLinker()) &&
1410 "Only globals with definition can force usage.");
1418 std::vector<cir::CIRGlobalValueInterface> &list) {
1423 mlir::Location loc = builder.getUnknownLoc();
1425 usedArray.resize(list.size());
1426 for (
auto [i, op] : llvm::enumerate(list)) {
1427 usedArray[i] = cir::GlobalViewAttr::get(
1428 cgm.
voidPtrTy, mlir::FlatSymbolRefAttr::get(op.getNameAttr()));
1431 cir::ArrayType arrayTy = cir::ArrayType::get(cgm.
voidPtrTy, usedArray.size());
1433 cir::ConstArrayAttr initAttr = cir::ConstArrayAttr::get(
1434 arrayTy, mlir::ArrayAttr::get(&cgm.
getMLIRContext(), usedArray));
1438 gv.setLinkage(cir::GlobalLinkageKind::AppendingLinkage);
1439 gv.setInitialValueAttr(initAttr);
1440 gv.setSectionAttr(builder.getStringAttr(
"llvm.metadata"));
1452 "emitGlobalVarDefinition: emit OpenCL/OpenMP global variable");
1459 bool isDefinitionAvailableExternally =
1464 if (isDefinitionAvailableExternally &&
1472 mlir::Attribute init;
1473 bool needsGlobalCtor =
false;
1474 bool needsGlobalDtor =
1475 !isDefinitionAvailableExternally &&
1480 std::optional<ConstantEmitter> emitter;
1485 bool isCUDASharedVar =
1490 bool isCUDAShadowVar =
1492 (vd->
hasAttr<CUDAConstantAttr>() || vd->
hasAttr<CUDADeviceAttr>() ||
1493 vd->
hasAttr<CUDASharedAttr>());
1494 bool isCUDADeviceShadowVar =
1500 (isCUDASharedVar || isCUDAShadowVar || isCUDADeviceShadowVar)) {
1502 }
else if (vd->
hasAttr<LoaderUninitializedAttr>()) {
1504 "emitGlobalVarDefinition: loader uninitialized attribute");
1505 }
else if (!initExpr) {
1518 emitter.emplace(*
this);
1519 mlir::Attribute initializer = emitter->tryEmitForInitializer(*initDecl);
1528 "emitGlobalVarDefinition: flexible array initializer");
1530 if (!isDefinitionAvailableExternally)
1531 needsGlobalCtor =
true;
1534 "emitGlobalVarDefinition: static initializer");
1545 mlir::Type initType;
1546 if (mlir::isa<mlir::SymbolRefAttr>(init)) {
1549 "emitGlobalVarDefinition: global initializer is a symbol reference");
1552 assert(mlir::isa<mlir::TypedAttr>(init) &&
"This should have a type");
1553 auto typedInitAttr = mlir::cast<mlir::TypedAttr>(init);
1554 initType = typedInitAttr.getType();
1556 assert(!mlir::isa<mlir::NoneType>(initType) &&
"Should have a type by now");
1562 if (!gv || gv.getSymType() != initType) {
1564 "emitGlobalVarDefinition: global initializer with type mismatch");
1570 if (vd->
hasAttr<AnnotateAttr>())
1583 if (langOpts.CUDA) {
1584 if (langOpts.CUDAIsDevice) {
1587 if (linkage != cir::GlobalLinkageKind::InternalLinkage &&
1589 (vd->
hasAttr<CUDADeviceAttr>() || vd->
hasAttr<CUDAConstantAttr>() ||
1592 gv->setAttr(cir::CUDAExternallyInitializedAttr::getMnemonic(),
1605 emitter->finalize(gv);
1609 gv.setConstant((vd->
hasAttr<CUDAConstantAttr>() && langOpts.CUDAIsDevice) ||
1610 (!needsGlobalCtor && !needsGlobalDtor &&
1615 if (
const SectionAttr *sa = vd->
getAttr<SectionAttr>()) {
1618 gv.setConstant(
true);
1622 gv.setLinkage(linkage);
1626 if (linkage == cir::GlobalLinkageKind::CommonLinkage) {
1628 gv.setConstant(
false);
1633 std::optional<mlir::Attribute> initializer = gv.getInitialValue();
1634 if (initializer && !
getBuilder().isNullValue(*initializer))
1635 gv.setLinkage(cir::GlobalLinkageKind::WeakAnyLinkage);
1638 setNonAliasAttributes(vd, gv);
1646 if (needsGlobalCtor || needsGlobalDtor)
1652 cir::GlobalLinkageKind::AvailableExternallyLinkage)
1658 if (fd->isInlineBuiltinDeclaration())
1669 mlir::Operation *op) {
1671 if (
const auto *fd = dyn_cast<FunctionDecl>(
decl)) {
1675 if (
const auto *method = dyn_cast<CXXMethodDecl>(
decl)) {
1679 abi->emitCXXStructor(gd);
1680 else if (fd->isMultiVersion())
1681 errorNYI(method->getSourceRange(),
"multiversion functions");
1685 if (method->isVirtual())
1691 if (fd->isMultiVersion())
1692 errorNYI(fd->getSourceRange(),
"multiversion functions");
1697 if (
const auto *vd = dyn_cast<VarDecl>(
decl))
1700 llvm_unreachable(
"Invalid argument to CIRGenModule::emitGlobalDefinition");
1714 astContext.getAsConstantArrayType(e->
getType());
1715 uint64_t finalSize = cat->getZExtSize();
1716 str.resize(finalSize);
1718 mlir::Type eltTy =
convertType(cat->getElementType());
1719 return builder.getString(str, eltTy, finalSize,
false);
1724 auto arrayEltTy = mlir::cast<cir::IntType>(arrayTy.getElementType());
1726 uint64_t arraySize = arrayTy.getSize();
1728 assert(arraySize > literalSize &&
1729 "wide string literal array size must have room for null terminator?");
1733 bool isAllZero =
true;
1734 for (
unsigned i = 0; i < literalSize; ++i) {
1742 return cir::ZeroAttr::get(arrayTy);
1746 elements.reserve(arraySize);
1747 for (
unsigned i = 0; i < literalSize; ++i)
1748 elements.push_back(cir::IntAttr::get(arrayEltTy, e->
getCodeUnit(i)));
1750 auto elementsAttr = mlir::ArrayAttr::get(&
getMLIRContext(), elements);
1751 return builder.getConstArray(elementsAttr, arrayTy);
1762 if (d.
hasAttr<SelectAnyAttr>())
1766 if (
auto *vd = dyn_cast<VarDecl>(&d))
1781 llvm_unreachable(
"No such linkage");
1787 if (
auto globalOp = dyn_cast_or_null<cir::GlobalOp>(op)) {
1788 globalOp.setComdat(
true);
1791 funcOp.setComdat(
true);
1797 genTypes.updateCompletedType(td);
1801 replacements[name] = op;
1806 mlir::SymbolUserMap &userMap) {
1807 for (mlir::Operation *user : userMap.getUsers(oldF)) {
1808 auto call = mlir::dyn_cast<cir::CallOp>(user);
1812 for (
auto [argOp, fnArgType] :
1813 llvm::zip(call.getArgs(), newF.getFunctionType().getInputs())) {
1814 if (argOp.getType() != fnArgType)
1823void CIRGenModule::applyReplacements() {
1824 if (replacements.empty())
1830 mlir::SymbolTableCollection symbolTableCollection;
1831 mlir::SymbolUserMap userMap(symbolTableCollection, theModule);
1833 for (
auto &i : replacements) {
1834 StringRef mangledName = i.first;
1835 mlir::Operation *replacement = i.second;
1841 auto newF = dyn_cast<cir::FuncOp>(replacement);
1844 errorNYI(replacement->getLoc(),
"replacement is not a function");
1849 "call argument types do not match replacement function");
1853 userMap.replaceAllUsesWith(oldF, newF.getSymNameAttr());
1854 newF->moveBefore(oldF);
1861 mlir::Location loc, StringRef name, mlir::Type ty,
1863 auto gv = mlir::dyn_cast_or_null<cir::GlobalOp>(
getGlobalValue(name));
1867 if (gv.getSymType() == ty)
1873 assert(gv.isDeclaration() &&
"Declaration has wrong type!");
1875 errorNYI(loc,
"createOrReplaceCXXRuntimeVariable: declaration exists with "
1886 mlir::SymbolTable::setSymbolVisibility(gv,
1890 !gv.hasAvailableExternallyLinkage()) {
1894 gv.setAlignmentAttr(
getSize(alignment));
1905 if ((noCommon || vd->
hasAttr<NoCommonAttr>()) && !vd->
hasAttr<CommonAttr>())
1916 if (vd->
hasAttr<SectionAttr>())
1922 if (vd->
hasAttr<PragmaClangBSSSectionAttr>() ||
1923 vd->
hasAttr<PragmaClangDataSectionAttr>() ||
1924 vd->
hasAttr<PragmaClangRelroSectionAttr>() ||
1925 vd->
hasAttr<PragmaClangRodataSectionAttr>())
1933 if (vd->
hasAttr<WeakImportAttr>())
1943 if (vd->
hasAttr<AlignedAttr>())
1950 for (
const FieldDecl *fd : rd->fields()) {
1951 if (fd->isBitField())
1953 if (fd->hasAttr<AlignedAttr>())
1975cir::GlobalLinkageKind
1979 return cir::GlobalLinkageKind::InternalLinkage;
1982 return cir::GlobalLinkageKind::WeakAnyLinkage;
1986 return cir::GlobalLinkageKind::LinkOnceAnyLinkage;
1991 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
2005 return !astContext.getLangOpts().AppleKext
2006 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
2007 : cir::GlobalLinkageKind::InternalLinkage;
2021 return cir::GlobalLinkageKind::ExternalLinkage;
2024 return dd->
hasAttr<CUDAGlobalAttr>()
2025 ? cir::GlobalLinkageKind::ExternalLinkage
2026 : cir::GlobalLinkageKind::InternalLinkage;
2027 return cir::GlobalLinkageKind::WeakODRLinkage;
2035 return cir::GlobalLinkageKind::CommonLinkage;
2041 if (dd->
hasAttr<SelectAnyAttr>())
2042 return cir::GlobalLinkageKind::WeakODRLinkage;
2046 return cir::GlobalLinkageKind::ExternalLinkage;
2058 mlir::Operation *old, cir::FuncOp newFn) {
2060 auto oldFn = mlir::dyn_cast<cir::FuncOp>(old);
2068 if (oldFn->getAttrs().size() <= 1)
2070 "replaceUsesOfNonProtoTypeWithRealFunction: Attribute forwarding");
2073 newFn.setNoProto(oldFn.getNoProto());
2076 std::optional<mlir::SymbolTable::UseRange> symUses =
2077 oldFn.getSymbolUses(oldFn->getParentOp());
2082 for (
const mlir::SymbolTable::SymbolUse &use : symUses.value()) {
2083 mlir::OpBuilder::InsertionGuard guard(builder);
2085 if (
auto noProtoCallOp = mlir::dyn_cast<cir::CallOp>(use.getUser())) {
2086 builder.setInsertionPoint(noProtoCallOp);
2089 cir::FuncType newFnType = newFn.getFunctionType();
2090 mlir::OperandRange callOperands = noProtoCallOp.getOperands();
2091 bool returnTypeMatches =
2092 newFnType.hasVoidReturn()
2093 ? noProtoCallOp.getNumResults() == 0
2094 : noProtoCallOp.getNumResults() == 1 &&
2095 noProtoCallOp.getResultTypes().front() ==
2096 newFnType.getReturnType();
2097 bool typesMatch = !newFn.getNoProto() && returnTypeMatches &&
2098 callOperands.size() == newFnType.getNumInputs();
2099 for (
unsigned i = 0, e = newFnType.getNumInputs(); typesMatch && i != e;
2101 if (callOperands[i].
getType() != newFnType.getInput(i))
2105 cir::CallOp realCallOp;
2109 builder.createCallOp(noProtoCallOp.getLoc(), newFn, callOperands);
2113 cir::FuncType origFnType = oldFn.getFunctionType();
2114 cir::FuncType callFnType =
2115 origFnType.isVarArg()
2116 ? cir::FuncType::get(origFnType.getInputs(),
2117 origFnType.getReturnType(),
2120 mlir::Value addr = cir::GetGlobalOp::create(
2121 builder, noProtoCallOp.getLoc(), cir::PointerType::get(newFnType),
2122 newFn.getSymName());
2123 mlir::Value casted =
2124 builder.createBitcast(addr, cir::PointerType::get(callFnType));
2125 realCallOp = builder.createIndirectCallOp(
2126 noProtoCallOp.getLoc(), casted, callFnType, callOperands);
2130 noProtoCallOp.replaceAllUsesWith(realCallOp);
2131 noProtoCallOp.erase();
2132 }
else if (
auto getGlobalOp =
2133 mlir::dyn_cast<cir::GetGlobalOp>(use.getUser())) {
2140 mlir::Value res = getGlobalOp.getAddr();
2141 const mlir::Type oldResTy = res.getType();
2142 const auto newPtrTy = cir::PointerType::get(newFn.getFunctionType());
2143 if (oldResTy != newPtrTy) {
2144 res.setType(newPtrTy);
2145 builder.setInsertionPointAfter(getGlobalOp.getOperation());
2146 mlir::Value castRes =
2147 cir::CastOp::create(builder, getGlobalOp.getLoc(), oldResTy,
2148 cir::CastKind::bitcast, res);
2149 res.replaceAllUsesExcept(castRes, castRes.getDefiningOp());
2151 }
else if (mlir::isa<cir::GlobalOp>(use.getUser())) {
2157 "replaceUsesOfNonProtoTypeWithRealFunction: unexpected use type");
2162cir::GlobalLinkageKind
2164 GVALinkage linkage = astContext.GetGVALinkageForVariable(vd);
2171 GVALinkage linkage = astContext.GetGVALinkageForFunction(d);
2173 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(d))
2182 StringRef globalName,
CharUnits alignment) {
2187 cir::GlobalOp gv = cgm.
createGlobalOp(loc, globalName, c.getType(),
2191 gv.setAlignmentAttr(cgm.
getSize(alignment));
2193 cir::GlobalLinkageKindAttr::get(cgm.
getBuilder().getContext(), lt));
2197 if (gv.isWeakForLinker()) {
2198 assert(cgm.
supportsCOMDAT() &&
"Only COFF uses weak string literals");
2201 cgm.
setDSOLocal(
static_cast<mlir::Operation *
>(gv));
2222 std::string result =
2233 astContext.getAlignOfGlobalVarInChars(s->
getType(),
nullptr);
2241 if (!gv.getAlignment() ||
2242 uint64_t(alignment.
getQuantity()) > *gv.getAlignment())
2243 gv.setAlignmentAttr(
getSize(alignment));
2248 if (
getCXXABI().getMangleContext().shouldMangleStringLiteral(s) &&
2251 "getGlobalForStringLiteral: mangle string literals");
2261 : builder.getUnknownLoc();
2262 auto typedC = llvm::cast<mlir::TypedAttr>(c);
2264 cir::GlobalLinkageKind::PrivateLinkage, *
this,
2265 uniqueName, alignment);
2279 auto arrayTy = mlir::dyn_cast<cir::ArrayType>(gv.getSymType());
2280 assert(arrayTy &&
"String literal must be array");
2284 return builder.getGlobalViewAttr(ptrTy, gv);
2301 errorNYI(
"SYCL temp address space");
2312 "emitExplicitCastExprType");
2318 auto ty = mlir::cast<cir::MethodType>(
convertType(destTy));
2319 return builder.getNullMethodAttr(ty);
2322 auto ty = mlir::cast<cir::DataMemberType>(
convertType(destTy));
2323 return builder.getNullDataMemberAttr(ty);
2334 if (
const auto *methodDecl = dyn_cast<CXXMethodDecl>(
decl)) {
2336 if (methodDecl->isVirtual())
2337 return cir::ConstantOp::create(
2338 builder, loc,
getCXXABI().buildVirtualMethodAttr(ty, methodDecl));
2344 return cir::ConstantOp::create(builder, loc,
2345 builder.getMethodAttr(ty, methodFuncOp));
2360 assert(
fieldDecl->getParent() == destClass &&
2361 "scalar member pointer should be relative to the declaring class");
2363 astContext.toCharUnitsFromBits(astContext.getFieldOffset(
fieldDecl))
2365 return cir::ConstantOp::create(builder, loc,
2366 cir::DataMemberOffsetAttr::get(ty, offset));
2369 std::optional<llvm::SmallVector<int32_t>> path =
2373 return cir::ConstantOp::create(builder, loc,
2374 builder.getDataMemberAttr(ty, *path));
2377std::optional<llvm::SmallVector<int32_t>>
2381 if (!findFieldMemberPath(destClass, field, path))
2382 return std::nullopt;
2386bool CIRGenModule::findFieldMemberPath(
const CXXRecordDecl *currentClass,
2395 if (currentClass->
isUnion()) {
2401 "data member pointer for non-zero-initializable union");
2408 path.push_back(fieldIdx);
2416 for (
const CXXBaseSpecifier &base : currentClass->
bases()) {
2417 const auto *baseDecl =
2420 if (base.isVirtual()) {
2425 llvm::SmallVector<int32_t> discardedPath;
2426 if (findFieldMemberPath(baseDecl, field, discardedPath)) {
2428 "data member pointer through virtual base");
2441 path.push_back(baseFieldIdx);
2442 if (findFieldMemberPath(baseDecl, field, path))
2461 if (
auto *oid = dyn_cast<ObjCImplDecl>(
decl))
2462 errorNYI(oid->getSourceRange(),
"emitDeclConext: ObjCImplDecl");
2472 if (
decl->isTemplated())
2475 switch (
decl->getKind()) {
2478 decl->getDeclKindName());
2481 case Decl::CXXConversion:
2482 case Decl::CXXMethod:
2483 case Decl::Function: {
2486 if (!fd->isConsteval())
2495 case Decl::Decomposition:
2496 case Decl::VarTemplateSpecialization: {
2498 if (
auto *decomp = dyn_cast<DecompositionDecl>(
decl))
2499 for (
auto *binding : decomp->flat_bindings())
2500 if (
auto *holdingVar = binding->getHoldingVar())
2504 case Decl::OpenACCRoutine:
2507 case Decl::OpenACCDeclare:
2510 case Decl::OMPThreadPrivate:
2513 case Decl::OMPGroupPrivate:
2516 case Decl::OMPAllocate:
2519 case Decl::OMPCapturedExpr:
2522 case Decl::OMPDeclareReduction:
2525 case Decl::OMPDeclareMapper:
2528 case Decl::OMPRequires:
2533 case Decl::UsingDirective:
2534 case Decl::UsingEnum:
2535 case Decl::NamespaceAlias:
2537 case Decl::TypeAlias:
2543 case Decl::ClassTemplate:
2545 case Decl::CXXDeductionGuide:
2547 case Decl::ExplicitInstantiation:
2548 case Decl::FunctionTemplate:
2549 case Decl::StaticAssert:
2550 case Decl::TypeAliasTemplate:
2551 case Decl::UsingShadow:
2552 case Decl::VarTemplate:
2553 case Decl::VarTemplatePartialSpecialization:
2556 case Decl::CXXConstructor:
2559 case Decl::CXXDestructor:
2564 case Decl::LinkageSpec:
2565 case Decl::Namespace:
2569 case Decl::ClassTemplateSpecialization:
2570 case Decl::CXXRecord: {
2573 for (
auto *childDecl : crd->
decls())
2579 case Decl::FileScopeAsm:
2581 if (langOpts.CUDA && langOpts.CUDAIsDevice)
2584 if (langOpts.OpenMPIsTargetDevice)
2587 if (langOpts.SYCLIsDevice)
2590 std::string line = file_asm->getAsmString();
2591 globalScopeAsm.push_back(builder.getStringAttr(line));
2598 op.setInitialValueAttr(value);
2612 md->getParent()->getNumVBases() == 0)
2614 "getAddrAndTypeOfCXXStructor: MS ABI complete destructor");
2625 false, isForDefinition);
2627 return {fnType, fn};
2631 mlir::Type funcType,
bool forVTable,
2635 "consteval function should never be emitted");
2645 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(gd.
getDecl())) {
2648 dd->getParent()->getNumVBases() == 0)
2650 "getAddrOfFunction: MS ABI complete destructor");
2656 false, isForDefinition);
2658 if (langOpts.CUDA && !langOpts.CUDAIsDevice &&
2664 bool isHIPHandle = mlir::isa<cir::GlobalOp>(*handle);
2665 if (isForDefinition || isHIPHandle)
2667 return mlir::dyn_cast<cir::FuncOp>(*handle);
2676 llvm::raw_svector_ostream
out(buffer);
2685 assert(ii &&
"Attempt to mangle unnamed decl.");
2687 const auto *fd = dyn_cast<FunctionDecl>(nd);
2691 }
else if (fd && fd->hasAttr<CUDAGlobalAttr>() &&
2695 DeviceKernelAttr::isOpenCLSpelling(
2696 fd->getAttr<DeviceKernelAttr>()) &&
2713 if (
const auto *fd = dyn_cast<FunctionDecl>(nd)) {
2714 if (fd->isMultiVersion()) {
2716 "getMangledName: multi-version functions");
2721 "getMangledName: GPU relocatable device code");
2724 return std::string(
out.str());
2727static FunctionDecl *
2742 if (
auto *methodDecl = dyn_cast<CXXMethodDecl>(protoFunc);
2743 methodDecl && methodDecl->isImplicitObjectMemberFunction()) {
2745 paramTypes.insert(paramTypes.begin(), methodDecl->getThisType());
2748 fpt->getExtProtoInfo());
2759 params.reserve(fpt->getNumParams());
2762 for (
unsigned i = 0, e = fpt->getNumParams(); i != e; ++i) {
2766 nullptr, fpt->getParamType(i),
nullptr,
2769 params.push_back(parm);
2772 tempFunc->setParams(params);
2797 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(canonicalGd.
getDecl())) {
2800 "getMangledName: C++ constructor without variants");
2809 if (!langOpts.CUDAIsDevice || !astContext.mayExternalize(gd.
getDecl())) {
2810 auto foundName = mangledDeclNames.find(canonicalGd);
2811 if (foundName != mangledDeclNames.end())
2812 return foundName->second;
2819 auto result = manglings.insert(std::make_pair(mangledName, gd));
2820 return mangledDeclNames[canonicalGd] = result.first->first();
2824 assert(!d->
getInit() &&
"Cannot emit definite definitions here!");
2832 if (gv && !mlir::cast<cir::GlobalOp>(gv).isDeclaration())
2848 if (langOpts.EmitAllDecls)
2851 const auto *vd = dyn_cast<VarDecl>(global);
2853 ((codeGenOpts.KeepPersistentStorageVariables &&
2854 (vd->getStorageDuration() ==
SD_Static ||
2855 vd->getStorageDuration() ==
SD_Thread)) ||
2856 (codeGenOpts.KeepStaticConsts && vd->getStorageDuration() ==
SD_Static &&
2857 vd->getType().isConstQualified())))
2870 if (langOpts.OpenMP >= 50 && !langOpts.OpenMPSimd) {
2871 std::optional<OMPDeclareTargetDeclAttr *> activeAttr =
2872 OMPDeclareTargetDeclAttr::getActiveAttr(global);
2873 if (!activeAttr || (*activeAttr)->getLevel() != (
unsigned)-1)
2877 const auto *fd = dyn_cast<FunctionDecl>(global);
2884 if (fd->hasAttr<TargetVersionAttr>() && !fd->isMultiVersion())
2886 if (langOpts.SYCLIsDevice) {
2887 errorNYI(fd->getSourceRange(),
"mayBeEmittedEagerly: SYCL");
2891 const auto *vd = dyn_cast<VarDecl>(global);
2893 if (astContext.getInlineVariableDefinitionKind(vd) ==
2901 if (langOpts.OpenMP && langOpts.OpenMPUseTLS &&
2902 astContext.getTargetInfo().isTLSSupported() &&
isa<VarDecl>(global) &&
2904 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(global))
2907 assert((fd || vd) &&
2908 "Only FunctionDecl and VarDecl should hit this path so far.");
2913 cir::CIRGlobalValueInterface gv) {
2914 if (gv.hasLocalLinkage())
2917 if (!gv.hasDefaultVisibility() && !gv.hasExternalWeakLinkage())
2925 const llvm::Triple &tt = cgm.
getTriple();
2927 if (tt.isOSCygMing()) {
2936 cgm.
errorNYI(
"shouldAssumeDSOLocal: MinGW");
2942 if (tt.isOSBinFormatCOFF() && gv.hasExternalWeakLinkage())
2950 if (tt.isOSBinFormatCOFF() || (tt.isOSWindows() && tt.isOSBinFormatMachO()))
2954 if (!tt.isOSBinFormatELF())
2959 if (rm != llvm::Reloc::Static && !lOpts.PIE) {
2967 return !(lOpts.SemanticInterposition || lOpts.HalfNoSemanticInterposition);
2971 if (!gv.isDeclarationForLinker())
2977 if (rm == llvm::Reloc::PIC_ && gv.hasExternalWeakLinkage())
2984 if (cgOpts.DirectAccessExternalData) {
2990 if (
auto globalOp = dyn_cast<cir::GlobalOp>(gv.getOperation())) {
3016 if (gv.hasLocalLinkage()) {
3017 gv.setGlobalVisibility(cir::VisibilityKind::Default);
3032 d->
hasAttr<OMPDeclareTargetDeclAttr>() &&
3033 d->
getAttr<OMPDeclareTargetDeclAttr>()->getDevType() !=
3034 OMPDeclareTargetDeclAttr::DT_NoHost &&
3036 llvm_unreachable(
"setGlobalVisibility: OpenMP is NYI");
3045 !d->
hasAttr<OMPDeclareTargetDeclAttr>()) {
3046 bool needsProtected =
false;
3050 }
else if (
const auto *vd = dyn_cast<VarDecl>(d)) {
3051 needsProtected = vd->hasAttr<CUDADeviceAttr>() ||
3052 vd->hasAttr<CUDAConstantAttr>() ||
3053 vd->getType()->isCUDADeviceBuiltinSurfaceType() ||
3054 vd->getType()->isCUDADeviceBuiltinTextureType();
3056 if (needsProtected) {
3057 gv.setGlobalVisibility(cir::VisibilityKind::Protected);
3063 gv.setGlobalVisibility(cir::VisibilityKind::Hidden);
3070 !gv.isDeclarationForLinker())
3079 if (
auto globalValue = dyn_cast<cir::CIRGlobalValueInterface>(op))
3098 auto res = manglings.find(mangledName);
3099 if (res == manglings.end())
3101 result = res->getValue();
3106 return llvm::StringSwitch<cir::TLSModel>(S)
3107 .Case(
"global-dynamic", cir::TLSModel::GeneralDynamic)
3108 .Case(
"local-dynamic", cir::TLSModel::LocalDynamic)
3109 .Case(
"initial-exec", cir::TLSModel::InitialExec)
3110 .Case(
"local-exec", cir::TLSModel::LocalExec);
3116 return cir::TLSModel::GeneralDynamic;
3118 return cir::TLSModel::LocalDynamic;
3120 return cir::TLSModel::InitialExec;
3122 return cir::TLSModel::LocalExec;
3124 llvm_unreachable(
"Invalid TLS model!");
3128 bool isExtendingDecl) {
3129 assert(d.
getTLSKind() &&
"setting TLS mode on non-TLS var!");
3138 global.setTlsModel(tlm);
3148 if (isExtendingDecl)
3156 cir::FuncOp func,
bool isThunk) {
3158 cir::CallingConv callingConv;
3159 cir::SideEffect sideEffect;
3166 mlir::NamedAttrList pal{};
3167 std::vector<mlir::NamedAttrList> argAttrs(info.arguments().size());
3168 mlir::NamedAttrList retAttrs{};
3170 retAttrs, callingConv, sideEffect,
3173 for (mlir::NamedAttribute
attr : pal)
3174 func->setAttr(
attr.getName(),
attr.getValue());
3176 llvm::for_each(llvm::enumerate(argAttrs), [func](
auto idx_arg_pair) {
3177 mlir::function_interface_impl::setArgAttrs(func, idx_arg_pair.index(),
3178 idx_arg_pair.value());
3180 if (!retAttrs.empty())
3181 mlir::function_interface_impl::setResultAttrs(func, 0, retAttrs);
3194 bool isIncompleteFunction,
3202 if (!isIncompleteFunction)
3204 getTypes().arrangeGlobalDeclaration(globalDecl),
3207 if (!isIncompleteFunction && func.isDeclaration())
3214 if (funcDecl->isInlineBuiltinDeclaration()) {
3216 bool hasBody = funcDecl->
hasBody(fdBody);
3218 assert(hasBody &&
"Inline builtin declarations should always have an "
3223 if (funcDecl->isReplaceableGlobalAllocationFunction()) {
3226 func->setAttr(cir::CIRDialect::getNoBuiltinAttrName(),
3238 if (!langOpts.Exceptions)
3241 if (langOpts.CXXExceptions)
3244 if (langOpts.ObjCExceptions)
3255 f->setAttr(cir::CIRDialect::getNoThrowAttrName(),
3258 std::optional<cir::InlineKind> existingInlineKind = f.getInlineKind();
3260 existingInlineKind && *existingInlineKind == cir::InlineKind::NoInline;
3261 bool isAlwaysInline = existingInlineKind &&
3262 *existingInlineKind == cir::InlineKind::AlwaysInline;
3266 if (!isAlwaysInline &&
3271 f.setInlineKind(cir::InlineKind::NoInline);
3286 if (
decl->hasAttr<NoInlineAttr>() && !isAlwaysInline) {
3288 f.setInlineKind(cir::InlineKind::NoInline);
3289 }
else if (
decl->hasAttr<AlwaysInlineAttr>() && !isNoInline) {
3292 f.setInlineKind(cir::InlineKind::AlwaysInline);
3296 if (!isAlwaysInline)
3297 f.setInlineKind(cir::InlineKind::NoInline);
3302 if (
auto *fd = dyn_cast<FunctionDecl>(
decl)) {
3307 auto checkRedeclForInline = [](
const FunctionDecl *redecl) {
3308 return redecl->isInlineSpecified();
3310 if (any_of(
decl->redecls(), checkRedeclForInline))
3315 return any_of(pattern->
redecls(), checkRedeclForInline);
3317 if (checkForInline(fd)) {
3318 f.setInlineKind(cir::InlineKind::InlineHint);
3319 }
else if (codeGenOpts.getInlining() ==
3321 !fd->isInlined() && !isAlwaysInline) {
3322 f.setInlineKind(cir::InlineKind::NoInline);
3334static cir::LangAddressSpace
3336 switch (addressSpace) {
3338 return cir::LangAddressSpace::OffloadGlobal;
3340 return cir::LangAddressSpace::OffloadConstant;
3342 return cir::LangAddressSpace::OffloadLocal;
3344 return cir::LangAddressSpace::OffloadGeneric;
3346 return cir::LangAddressSpace::OffloadGlobalDevice;
3348 return cir::LangAddressSpace::OffloadGlobalHost;
3352 return cir::LangAddressSpace::Default;
3358 assert(fd &&
"expected a kernel function declaration");
3371 argNames.push_back(builder.getStringAttr(param->getName()));
3374 std::string typeQuals;
3376 if (
type->isImageType() ||
type->isPipeType()) {
3378 "OpenCL kernel argument metadata for image and pipe types");
3382 accessQuals.push_back(builder.getStringAttr(
"none"));
3384 auto getTypeSpelling = [&](
QualType paramType) {
3385 std::string typeName = paramType.getUnqualifiedType().getAsString(policy);
3387 if (paramType.isCanonical()) {
3388 StringRef typeNameRef = typeName;
3389 if (typeNameRef.consume_front(
"unsigned "))
3390 return std::string(
"u") + typeNameRef.str();
3391 if (typeNameRef.consume_front(
"signed "))
3392 return typeNameRef.str();
3400 if (
type->isPointerType()) {
3402 addressQuals.push_back(cir::LangAddressSpaceAttr::get(
3406 argTypeNames.push_back(
3407 builder.getStringAttr(getTypeSpelling(pointeeType) +
"*"));
3408 argBaseTypeNames.push_back(builder.getStringAttr(
3411 if (
type.isRestrictQualified())
3412 typeQuals =
"restrict";
3415 typeQuals += typeQuals.empty() ?
"const" :
" const";
3417 typeQuals += typeQuals.empty() ?
"volatile" :
" volatile";
3419 addressQuals.push_back(cir::LangAddressSpaceAttr::get(
3422 argTypeNames.push_back(builder.getStringAttr(getTypeSpelling(
type)));
3423 argBaseTypeNames.push_back(
3424 builder.getStringAttr(getTypeSpelling(
type.getCanonicalType())));
3427 argTypeQuals.push_back(builder.getStringAttr(typeQuals));
3430 mlir::ArrayAttr names;
3432 names = builder.getArrayAttr(argNames);
3434 mlir::Attribute metadata = cir::OpenCLKernelArgMetadataAttr::get(
3435 func.getContext(), builder.getArrayAttr(addressQuals),
3436 builder.getArrayAttr(accessQuals), builder.getArrayAttr(argTypeNames),
3437 builder.getArrayAttr(argBaseTypeNames),
3438 builder.getArrayAttr(argTypeQuals), names);
3439 func->setAttr(cir::CIRDialect::getOpenCLKernelArgMetadataAttrName(),
3444 StringRef mangledName, mlir::Type funcType,
GlobalDecl gd,
bool forVTable,
3446 mlir::NamedAttrList extraAttrs) {
3449 if (
const auto *fd = cast_or_null<FunctionDecl>(d)) {
3451 if (
getLangOpts().OpenMPIsTargetDevice && openMPRuntime &&
3453 !dontDefer && !isForDefinition) {
3456 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(fdDef))
3458 else if (
const auto *dd = dyn_cast<CXXDestructorDecl>(fdDef))
3468 if (fd->isMultiVersion())
3469 errorNYI(fd->getSourceRange(),
"getOrCreateCIRFunction: multi-version");
3475 assert(mlir::isa<cir::FuncOp>(entry));
3480 if (d && !d->
hasAttr<DLLImportAttr>() && !d->
hasAttr<DLLExportAttr>()) {
3488 if (isForDefinition && fn && !fn.isDeclaration()) {
3495 diagnosedConflictingDefinitions.insert(gd).second) {
3499 diag::note_previous_definition);
3503 if (fn && fn.getFunctionType() == funcType) {
3507 if (!isForDefinition) {
3515 auto *funcDecl = llvm::cast_or_null<FunctionDecl>(gd.
getDecl());
3516 bool invalidLoc = !funcDecl ||
3517 funcDecl->getSourceRange().getBegin().isInvalid() ||
3518 funcDecl->getSourceRange().getEnd().isInvalid();
3520 invalidLoc ? theModule->getLoc() :
getLoc(funcDecl->getSourceRange()),
3521 mangledName, mlir::cast<cir::FuncType>(funcType), funcDecl);
3523 if (funcDecl && funcDecl->hasAttr<AnnotateAttr>())
3524 deferredAnnotations[mangledName] = funcDecl;
3535 auto symbolOp = mlir::cast<mlir::SymbolOpInterface>(entry);
3543 if (symbolOp.getSymbolUses(symbolOp->getParentOp()))
3553 if (!extraAttrs.empty()) {
3554 extraAttrs.append(funcOp->getAttrs());
3555 funcOp->setAttrs(extraAttrs);
3562 assert(funcOp.getFunctionType() == funcType);
3569 if (isa_and_nonnull<CXXDestructorDecl>(d) &&
3599 fd = fd->getPreviousDecl()) {
3601 if (fd->doesThisDeclarationHaveABody()) {
3614 cir::FuncType funcType,
3618 mlir::OpBuilder::InsertionGuard guard(builder);
3623 builder.setInsertionPointToEnd(theModule.getBody());
3625 func = cir::FuncOp::create(builder, loc, name, funcType);
3632 func.setNoProto(
true);
3634 assert(func.isDeclaration() &&
"expected empty body");
3638 func.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
3640 mlir::SymbolTable::setSymbolVisibility(
3641 func, mlir::SymbolTable::Visibility::Private);
3652 for (
const auto *
attr :
3666 fnOp.setBuiltin(
true);
3672 return cir::CtorKind::Default;
3674 return cir::CtorKind::Copy;
3676 return cir::CtorKind::Move;
3677 return cir::CtorKind::Custom;
3682 return cir::AssignKind::Copy;
3684 return cir::AssignKind::Move;
3685 llvm_unreachable(
"not a copy or move assignment operator");
3693 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(funcDecl)) {
3694 auto cxxDtor = cir::CXXDtorAttr::get(
3697 funcOp.setFuncInfoAttr(cxxDtor);
3701 if (
const auto *ctor = dyn_cast<CXXConstructorDecl>(funcDecl)) {
3703 auto cxxCtor = cir::CXXCtorAttr::get(
3705 kind, ctor->isTrivial());
3706 funcOp.setFuncInfoAttr(cxxCtor);
3710 const auto *method = dyn_cast<CXXMethodDecl>(funcDecl);
3711 if (method && (method->isCopyAssignmentOperator() ||
3712 method->isMoveAssignmentOperator())) {
3714 auto cxxAssign = cir::CXXAssignAttr::get(
3716 assignKind, method->isTrivial());
3717 funcOp.setFuncInfoAttr(cxxAssign);
3727 bool inStdNamespace = method ? method->getParent()->isInStdNamespace()
3729 if (!inStdNamespace)
3735 std::optional<cir::KnownFuncKind>
kind;
3737 kind = llvm::StringSwitch<std::optional<cir::KnownFuncKind>>(
3739 .Case(cir::StdFindOp::getFunctionName(),
3740 cir::StdFindOp::getFuncKind())
3741 .Default(std::nullopt);
3750 cir::FuncOp funcOp, StringRef name) {
3766 mlir::NamedAttrList extraAttrs,
3768 bool assumeConvergent) {
3769 if (assumeConvergent)
3770 errorNYI(
"createRuntimeFunction: assumeConvergent");
3780 entry.setDSOLocal(
true);
3786mlir::SymbolTable::Visibility
3790 if (op.isDeclaration())
3791 return mlir::SymbolTable::Visibility::Private;
3795mlir::SymbolTable::Visibility
3798 case cir::GlobalLinkageKind::InternalLinkage:
3799 case cir::GlobalLinkageKind::PrivateLinkage:
3800 return mlir::SymbolTable::Visibility::Private;
3801 case cir::GlobalLinkageKind::ExternalLinkage:
3802 case cir::GlobalLinkageKind::ExternalWeakLinkage:
3803 case cir::GlobalLinkageKind::LinkOnceODRLinkage:
3804 case cir::GlobalLinkageKind::AvailableExternallyLinkage:
3805 case cir::GlobalLinkageKind::CommonLinkage:
3806 case cir::GlobalLinkageKind::WeakAnyLinkage:
3807 case cir::GlobalLinkageKind::WeakODRLinkage:
3808 return mlir::SymbolTable::Visibility::Public;
3810 llvm::errs() <<
"visibility not implemented for '"
3811 << stringifyGlobalLinkageKind(glk) <<
"'\n";
3812 assert(0 &&
"not implemented");
3815 llvm_unreachable(
"linkage should be handled above!");
3819 clang::VisibilityAttr::VisibilityType visibility) {
3820 switch (visibility) {
3821 case clang::VisibilityAttr::VisibilityType::Default:
3822 return cir::VisibilityKind::Default;
3823 case clang::VisibilityAttr::VisibilityType::Hidden:
3824 return cir::VisibilityKind::Hidden;
3825 case clang::VisibilityAttr::VisibilityType::Protected:
3826 return cir::VisibilityKind::Protected;
3828 llvm_unreachable(
"unexpected visibility value");
3833 const clang::VisibilityAttr *va =
decl->getAttr<clang::VisibilityAttr>();
3834 cir::VisibilityAttr cirVisibility =
3837 cirVisibility = cir::VisibilityAttr::get(
3841 return cirVisibility;
3847 applyReplacements();
3849 theModule->setAttr(cir::CIRDialect::getModuleLevelAsmAttrName(),
3850 builder.getArrayAttr(globalScopeAsm));
3852 emitGlobalAnnotations();
3854 if (!recordLayoutEntries.empty())
3856 cir::CIRDialect::getRecordLayoutsAttrName(),
3857 mlir::DictionaryAttr::get(&
getMLIRContext(), recordLayoutEntries));
3866 std::string cuidName =
3869 auto loc = builder.getUnknownLoc();
3870 mlir::ptr::MemorySpaceAttrInterface addrSpace =
3872 getGlobalVarAddressSpace(
nullptr));
3876 gv.setLinkage(cir::GlobalLinkageKind::ExternalLinkage);
3878 auto zeroAttr = cir::IntAttr::get(int8Ty, 0);
3879 gv.setInitialValueAttr(zeroAttr);
3881 mlir::SymbolTable::setSymbolVisibility(
3882 gv, mlir::SymbolTable::Visibility::Public);
3887 if (astContext.getLangOpts().CUDA && cudaRuntime)
3902 const AliasAttr *aa = d->
getAttr<AliasAttr>();
3903 assert(aa &&
"Not an alias?");
3907 if (aa->getAliasee() == mangledName) {
3908 diags.Report(aa->getLocation(), diag::err_cyclic_alias) << 0;
3916 auto entryGV = mlir::dyn_cast<cir::CIRGlobalValueInterface>(entry);
3917 if (entryGV && entryGV.isDefinition())
3930 cir::GlobalLinkageKind linkage;
3942 cir::CIRGlobalValueInterface alias =
3943 isFunction ? mlir::cast<cir::CIRGlobalValueInterface>(
3945 mlir::cast<cir::FuncType>(declTy),
3948 : mlir::cast<cir::CIRGlobalValueInterface>(
3959 entry, mlir::cast<cir::FuncOp>(alias.getOperation()));
3967 linkage = cir::GlobalLinkageKind::WeakAnyLinkage;
3971 mlir::SymbolTable::Visibility visibility =
3974 alias.setAliasee(aa->getAliasee());
3975 alias.setLinkage(linkage);
3976 mlir::SymbolTable::setSymbolVisibility(alias, visibility);
3984 cir::FuncOp aliasee,
3985 cir::GlobalLinkageKind linkage) {
3987 auto *aliasFD = dyn_cast<FunctionDecl>(aliasGD.
getDecl());
3988 assert(aliasFD &&
"expected FunctionDecl");
3999 mangledName, fnType, aliasFD);
4000 alias.setAliasee(aliasee.getName());
4001 alias.setLinkage(linkage);
4005 mlir::SymbolTable::setSymbolVisibility(
4006 alias, mlir::SymbolTable::Visibility::Private);
4018 "declaration exists with different type");
4030 return genTypes.convertType(
type);
4037 return mlir::verify(theModule).succeeded();
4046 return builder.getConstNullPtrAttr(builder.getUInt8PtrTy());
4049 langOpts.ObjCRuntime.isGNUFamily()) {
4050 errorNYI(loc,
"getAddrOfRTTIDescriptor: Objc PtrType & Objc RT GUN");
4060 llvm::iterator_range<CastExpr::path_const_iterator> path) {
4067 assert(!base->isVirtual() &&
"Should not see virtual bases here!");
4072 const auto *baseDecl = base->getType()->castAsCXXRecordDecl();
4084 llvm::StringRef feature) {
4085 unsigned diagID = diags.getCustomDiagID(
4087 return diags.Report(loc, diagID) << feature;
4091 llvm::StringRef feature) {
4103 "cannot compile this %0 yet");
4104 diags.Report(astContext.getFullLoc(s->
getBeginLoc()), diagId)
4111 "cannot compile this %0 yet");
4112 diags.Report(astContext.getFullLoc(d->
getLocation()), diagId) <<
type;
4120 "not a global temporary");
4132 materializedType = mte->
getType();
4141 llvm::raw_svector_ostream
out(name);
4145 auto insertResult = materializedGlobalTemporaryMap.insert({mte,
nullptr});
4146 if (!insertResult.second) {
4150 if (!insertResult.first->second) {
4153 insertResult.first->second =
4156 return insertResult.first->second;
4173 value = &evalResult.
Val;
4177 std::optional<ConstantEmitter> emitter;
4178 mlir::Attribute initialValue =
nullptr;
4179 bool isConstant =
false;
4183 emitter.emplace(*
this);
4184 initialValue = emitter->emitForInitializer(*value, materializedType);
4189 type = mlir::cast<mlir::TypedAttr>(initialValue).getType();
4198 if (linkage == cir::GlobalLinkageKind::ExternalLinkage) {
4200 if (
varDecl->isStaticDataMember() &&
varDecl->getAnyInitializer(initVD) &&
4208 linkage = cir::GlobalLinkageKind::InternalLinkage;
4212 gv.setInitialValueAttr(initialValue);
4213 gv.setLinkage(linkage);
4217 emitter->finalize(gv);
4219 if (!gv.hasLocalLinkage()) {
4224 gv.setAlignment(align.getAsAlign().value());
4229 mlir::Operation *cv = gv;
4238 mlir::Operation *&entry = materializedGlobalTemporaryMap[mte];
4240 entry->replaceAllUsesWith(cv);
4255 return *globalOpEntry;
4262 "emitForInitializer should take gcd->getType().getAddressSpace()");
4264 auto typedInit = dyn_cast<mlir::TypedAttr>(init);
4268 "getAddrOfUnnamedGlobalConstantDecl: non-typed initializer");
4277 std::string name = numEntries == 0
4279 : (Twine(
".constant.") + Twine(numEntries)).str();
4281 typedInit.getType(),
true);
4282 globalOp.setLinkage(cir::GlobalLinkageKind::PrivateLinkage);
4285 globalOp.setAlignment(alignment.
getAsAlign().value());
4289 *globalOpEntry = globalOp;
4304 "emitForInitializer should take tpo->getType().getAddressSpace()");
4305 mlir::Attribute init =
4315 cir::GlobalLinkageKind linkage =
4317 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
4318 : cir::GlobalLinkageKind::InternalLinkage;
4322 typedInit.getType(),
true);
4323 globalOp.setLinkage(linkage);
4324 globalOp.setAlignment(alignment.
getAsAlign().value());
4326 linkage == cir::GlobalLinkageKind::LinkOnceODRLinkage);
4341CIRGenModule::getOrCreateAnnotationArgs(
const AnnotateAttr *
attr) {
4348 llvm::FoldingSetNodeID id;
4349 for (
Expr *e : exprs)
4352 mlir::ArrayAttr &lookup = annotationArgs[
id.ComputeHash()];
4357 args.reserve(exprs.size());
4358 for (
Expr *e : exprs) {
4359 if (
auto *strE = dyn_cast<clang::StringLiteral>(e->IgnoreParenCasts())) {
4360 args.push_back(builder.getStringAttr(strE->getString()));
4361 }
else if (
auto *intE =
4362 dyn_cast<clang::IntegerLiteral>(e->IgnoreParenCasts())) {
4363 auto intTy = builder.getIntegerType(intE->getValue().getBitWidth());
4364 args.push_back(builder.getIntegerAttr(intTy, intE->getValue()));
4366 errorNYI(e->getExprLoc(),
"annotation argument expression");
4370 return lookup = builder.getArrayAttr(args);
4373cir::AnnotationAttr CIRGenModule::emitAnnotateAttr(
const AnnotateAttr *aa) {
4374 mlir::StringAttr annoGV = builder.getStringAttr(aa->getAnnotation());
4375 mlir::ArrayAttr args = getOrCreateAnnotationArgs(aa);
4376 return cir::AnnotationAttr::get(&
getMLIRContext(), annoGV, args);
4380 mlir::Operation *gv) {
4381 assert(d->
hasAttr<AnnotateAttr>() &&
"no annotate attribute");
4383 "annotation only on globals");
4386 annotations.push_back(emitAnnotateAttr(i));
4387 if (
auto global = dyn_cast<cir::GlobalOp>(gv))
4388 global.setAnnotationsAttr(builder.getArrayAttr(annotations));
4389 else if (
auto func = dyn_cast<cir::FuncOp>(gv))
4390 func.setAnnotationsAttr(builder.getArrayAttr(annotations));
4393void CIRGenModule::emitGlobalAnnotations() {
4394 for (
const auto &[mangledName, vd] : deferredAnnotations) {
4399 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 cir::LangAddressSpace getOpenCLKernelArgAddressSpace(LangAS addressSpace)
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::TLSModel getCIRTLSModel(StringRef S)
static cir::GlobalViewAttr createNewGlobalView(CIRGenModule &cgm, cir::GlobalOp newGlob, cir::GlobalViewAttr attr, mlir::Type oldTy)
This file defines OpenACC nodes for declarative directives.
static constexpr bool needsDtor()
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
Defines the SourceManager interface.
This file defines OpenMP AST classes for executable directives and clauses.
cir::GlobalViewAttr getGlobalViewAttr(cir::GlobalOp globalOp, mlir::ArrayAttr indices={})
Get constant address of a global variable as an MLIR attribute.
cir::PointerType getPointerTo(mlir::Type ty)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
@ Strong
Strong definition.
@ WeakUnknown
Weak for now, might become strong later in this TU.
bool DeclMustBeEmitted(const Decl *D)
Determines if the decl can be CodeGen'ed or deserialized from PCH lazily, only when used; this is onl...
StringRef getCUIDHash() const
void Deallocate(void *Ptr) const
GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const
bool isSameEntity(const NamedDecl *X, const NamedDecl *Y) const
Determine whether the two declarations refer to the same entity.
bool isAlignmentRequired(const Type *T) const
Determine if the alignment the type has was required using an alignment attribute.
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
const clang::PrintingPolicy & getPrintingPolicy() const
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, cir::RecordType recordTy)
uint64_t computeOffsetFromGlobalViewIndices(const cir::CIRDataLayout &layout, mlir::Type ty, llvm::ArrayRef< int64_t > indices)
void computeGlobalViewIndicesFromFlatOffset(int64_t offset, mlir::Type ty, cir::CIRDataLayout layout, llvm::SmallVectorImpl< int64_t > &indices)
cir::ConstArrayAttr getConstArray(mlir::Attribute attrs, cir::ArrayType arrayTy) const
virtual void handleGlobalReplace(cir::GlobalOp oldGV, cir::GlobalOp newGV)
virtual mlir::Operation * getKernelHandle(cir::FuncOp fn, GlobalDecl gd)=0
virtual void finalizeModule()
Perform module finalization: on device side, mark ODR-used device variables as compiler-used.
virtual void internalizeDeviceSideVar(const VarDecl *d, cir::GlobalLinkageKind &linkage)=0
Adjust linkage of shadow variables in host compilation.
virtual void handleVarRegistration(const VarDecl *vd, cir::GlobalOp var)=0
Check whether a variable is a device variable and register it if true.
Implements C++ ABI-specific code generation functions.
virtual mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty)=0
virtual void emitCXXConstructors(const clang::CXXConstructorDecl *d)=0
Emit constructor variants required by this ABI.
virtual void emitCXXDestructors(const clang::CXXDestructorDecl *d)=0
Emit dtor variants required by this ABI.
clang::MangleContext & getMangleContext()
Gets the mangle context.
virtual cir::GlobalLinkageKind getCXXDestructorLinkage(GVALinkage linkage, const CXXDestructorDecl *dtor, CXXDtorType dt) const
cir::FuncOp generateCode(clang::GlobalDecl gd, cir::FuncOp fn, cir::FuncType funcType)
void emitVariablyModifiedType(QualType ty)
This class organizes the cross-function state that is used while generating CIR code.
cir::GlobalOp getAddrOfUnnamedGlobalConstantDecl(const UnnamedGlobalConstantDecl *gcd)
void setGlobalVisibility(cir::CIRGlobalValueInterface gv, const NamedDecl *d) const
Set the visibility for the given global.
void addUsedOrCompilerUsedGlobal(cir::CIRGlobalValueInterface gv)
Add a global to a list to be added to the llvm.compiler.used metadata.
void setFuncInfoAttr(cir::FuncOp funcOp, const clang::FunctionDecl *funcDecl)
Record the func_info tag for a function, either a C++ special member form (constructor,...
void replaceUsesOfNonProtoTypeWithRealFunction(mlir::Operation *old, cir::FuncOp newFn)
This function is called when we implement a function with no prototype, e.g.
bool shouldEmitFunction(clang::GlobalDecl gd)
Check if fd ends up calling itself directly through asm label or builtin-pointer-to-self trickery (e....
llvm::StringRef getMangledName(clang::GlobalDecl gd)
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *derivedClass, llvm::iterator_range< CastExpr::path_const_iterator > path)
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
void emitDeferred()
Emit any needed decls for which code generation was deferred.
cir::GlobalLinkageKind getCIRLinkageVarDefinition(const VarDecl *vd)
clang::ASTContext & getASTContext() const
void insertGlobalSymbol(mlir::Operation *op)
cir::FuncOp getAddrOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
CIRGenCUDARuntime & getCUDARuntime()
void emitTopLevelDecl(clang::Decl *decl)
void emitOMPDeclareMapper(const OMPDeclareMapperDecl *d)
void addReplacement(llvm::StringRef name, mlir::Operation *op)
mlir::Type convertType(clang::QualType type)
bool shouldEmitRTTI(bool forEH=false)
cir::GlobalOp getGlobalForStringLiteral(const StringLiteral *s, llvm::StringRef name=".str")
Return a global symbol reference to a constant array for the given string literal.
std::vector< cir::CIRGlobalValueInterface > llvmUsed
List of global values which are required to be present in the object file; This is used for forcing v...
void emitOMPCapturedExpr(const OMPCapturedExprDecl *d)
bool mustBeEmitted(const clang::ValueDecl *d)
Determine whether the definition must be emitted; if this returns false, the definition can be emitte...
void emitGlobalOpenACCDeclareDecl(const clang::OpenACCDeclareDecl *cd)
mlir::IntegerAttr getSize(CharUnits size)
cir::TLSModel getDefaultCIRTLSModel() const
Get TLS mode from CodeGenOptions.
void setGlobalTlsReferences(const VarDecl &vd, cir::GlobalOp globalOp)
void emitOpenCLKernelArgMetadata(cir::FuncOp func, const clang::FunctionDecl *fd)
Generate OpenCL kernel argument metadata for a kernel function.
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)
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()
void emitSYCLKernelCaller(const clang::FunctionDecl *kernelEntryPointFn, clang::ASTContext &ctx)
Emit the SYCL kernel caller offload entry point function generated for a function declared with the s...
mlir::Operation * getAddrOfGlobal(clang::GlobalDecl gd, ForDefinition_t isForDefinition=NotForDefinition)
void maybeSetTrivialComdat(const clang::Decl &d, mlir::Operation *op)
bool isEmptyFieldForMemberPointer(const FieldDecl *field)
Returns true if field is an empty field that isn't laid out in the CIR record (e.g.
CIRGenCXXABI & getCXXABI() const
cir::GlobalViewAttr getAddrOfConstantStringFromLiteral(const StringLiteral *s, llvm::StringRef name=".str")
Return a global symbol reference to a constant array for the given string literal.
bool lookupRepresentativeDecl(llvm::StringRef mangledName, clang::GlobalDecl &gd) const
void emitDeclContext(const DeclContext *dc)
clang::CharUnits getNaturalPointeeTypeAlignment(clang::QualType t, LValueBaseInfo *baseInfo=nullptr)
void emitGlobal(clang::GlobalDecl gd)
Emit code for a single global function or variable declaration.
bool mayBeEmittedEagerly(const clang::ValueDecl *d)
Determine whether the definition can be emitted eagerly, or should be delayed until the end of the tr...
void addGlobalAnnotations(const clang::ValueDecl *d, mlir::Operation *gv)
Add global annotations for a global value (GlobalOp or FuncOp).
void setCIRFunctionAttributesForDefinition(const clang::FunctionDecl *fd, cir::FuncOp f)
Set extra attributes (inline, etc.) for a function.
std::string getOpenACCBindMangledName(const IdentifierInfo *bindName, const FunctionDecl *attachedFunction)
void emitGlobalFunctionDefinition(clang::GlobalDecl gd, mlir::Operation *op)
CIRGenVTables & getVTables()
void setFunctionLinkage(GlobalDecl gd, cir::FuncOp f)
std::vector< clang::GlobalDecl > deferredDeclsToEmit
void emitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *d)
CIRGenOpenMPRuntime & getOpenMPRuntime()
void emitAMDGPUMetadata()
Emits AMDGPU specific Metadata.
void emitOMPGroupPrivateDecl(const OMPGroupPrivateDecl *d)
mlir::Attribute getConstantArrayFromStringLiteral(const StringLiteral *e)
Return a constant array for the given string.
cir::VisibilityAttr getGlobalVisibilityAttrFromDecl(const Decl *decl)
void setCommonAttributes(GlobalDecl gd, mlir::Operation *op)
Set attributes which are common to any form of a global definition (alias, Objective-C method,...
void emitDeclareTargetFunction(const FunctionDecl *fd, cir::FuncOp funcOp)
If the function has an OMPDeclareTargetDeclAttr, set the corresponding omp.declare_target attribute o...
This class handles record and union layout info while lowering AST types to CIR types.
bool hasNonVirtualBaseCIRField(const CXXRecordDecl *rd) const
unsigned getCIRFieldNo(const clang::FieldDecl *fd) const
Return cir::RecordType element number that corresponds to the field FD.
bool isZeroInitializable() const
Check whether this struct can be C++ zero-initialized with a zeroinitializer.
unsigned getNonVirtualBaseCIRFieldNo(const CXXRecordDecl *rd) const
const CIRGenFunctionInfo & arrangeGlobalDeclaration(GlobalDecl gd)
const CIRGenFunctionInfo & arrangeCXXMethodDeclaration(const clang::CXXMethodDecl *md)
C++ methods have some special rules and also have implicit parameters.
const CIRGenFunctionInfo & arrangeCXXStructorDeclaration(clang::GlobalDecl gd)
cir::FuncType getFunctionType(const CIRGenFunctionInfo &info)
Get the CIR function type for.
const CIRGenRecordLayout & getCIRGenRecordLayout(const clang::RecordDecl *rd)
Return record layout info for the given record decl.
mlir::Type convertTypeForMem(clang::QualType, bool forBitField=false)
Convert type T into an mlir::Type.
void emitThunks(GlobalDecl gd)
Emit the associated thunks for the given global decl.
void finalize(cir::GlobalOp gv)
mlir::Attribute emitForInitializer(const APValue &value, QualType destType)
virtual clang::LangAS getGlobalVarAddressSpace(CIRGenModule &cgm, const clang::VarDecl *d) const
Get target favored AST address space of a global variable for languages other than OpenCL and CUDA.
virtual mlir::ptr::MemorySpaceAttrInterface getCIRAllocaAddressSpace() const
Get the address space for alloca.
virtual void setTargetAttributes(const clang::Decl *decl, mlir::Operation *global, CIRGenModule &module) const
Provides a convenient hook to handle extra target-specific attributes for the given global.
Represents a base class of a C++ class.
Represents a C++ constructor within a class.
bool isMoveConstructor(unsigned &TypeQuals) const
Determine whether this constructor is a move constructor (C++11 [class.copy]p3), which can be used to...
bool isCopyConstructor(unsigned &TypeQuals) const
Whether this constructor is a copy constructor (C++ [class.copy]p2, which can be used to copy the cla...
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
Represents a static or instance method of a struct/union/class.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
Represents a C++ struct/union/class.
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
bool hasDefinition() const
CharUnits - This is an opaque type for sizes expressed in character units.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
llvm::Reloc::Model RelocationModel
The name of the relocation model to use.
Represents the canonical version of C arrays with a specified constant size.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
bool isInExportDeclContext() const
Whether this declaration was exported in a lexical context.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
static DeclContext * castToDeclContext(const Decl *)
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Represents a ValueDecl that came out of a declarator.
A little helper class used to produce diagnostics.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
ExplicitCastExpr - An explicit cast written in the source code.
This represents one expression.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Represents a member of a struct/union/class.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
bool isPotentiallyOverlapping() const
Determine if this field is of potentially-overlapping class type, that is, subobject with the [[no_un...
Cached information about one file (either on disk or in the virtual file system).
StringRef tryGetRealPathName() const
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Represents a function declaration or definition.
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin=false, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=ConstexprSpecKind::Unspecified, const AssociatedConstraint &TrailingRequiresClause={})
ArrayRef< ParmVarDecl * > parameters() const
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.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getCanonicalType() const
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...
std::unique_ptr< TargetCIRGenInfo > createAArch64TargetCIRGenInfo(CIRGenTypes &cgt)
CIRGenCUDARuntime * createNVCUDARuntime(CIRGenModule &cgm)
const internal::VariadicDynCastAllOfMatcher< Decl, VarDecl > varDecl
Matches variable declarations.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, FieldDecl > fieldDecl
Matches field declarations.
const internal::VariadicDynCastAllOfMatcher< Decl, FunctionDecl > functionDecl
Matches function declarations.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
Top level wrappers for InstallAPI frontend operations.
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.
Describes how types, statements, expressions, and declarations should be printed.