19#include "mlir/Dialect/OpenMP/OpenMPOffloadUtils.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/Support/raw_ostream.h"
44#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
45#include "mlir/IR/Attributes.h"
46#include "mlir/IR/BuiltinOps.h"
47#include "mlir/IR/Location.h"
48#include "mlir/IR/MLIRContext.h"
49#include "mlir/IR/Operation.h"
50#include "mlir/IR/Verifier.h"
59 case TargetCXXABI::GenericItanium:
60 case TargetCXXABI::GenericAArch64:
61 case TargetCXXABI::AppleARM64:
62 case TargetCXXABI::GenericARM:
65 case TargetCXXABI::Fuchsia:
66 case TargetCXXABI::iOS:
67 case TargetCXXABI::WatchOS:
68 case TargetCXXABI::GenericMIPS:
69 case TargetCXXABI::WebAssembly:
70 case TargetCXXABI::XL:
71 case TargetCXXABI::Microsoft:
72 cgm.
errorNYI(
"createCXXABI: C++ ABI kind");
76 llvm_unreachable(
"invalid C++ ABI kind");
79CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
83 : builder(mlirContext, *this), astContext(astContext),
84 langOpts(astContext.
getLangOpts()), codeGenOpts(cgo),
85 theModule{
mlir::ModuleOp::create(
mlir::UnknownLoc::get(&mlirContext))},
86 diags(diags), target(astContext.getTargetInfo()),
87 abi(
createCXXABI(*this)), genTypes(*this), vtables(*this) {
115 .toCharUnitsFromBits(
119 const unsigned charSize = astContext.getTargetInfo().getCharWidth();
123 const unsigned sizeTypeSize =
124 astContext.getTypeSize(astContext.getSignedSizeType());
125 SizeSizeInBytes = astContext.toCharUnitsFromBits(sizeTypeSize).getQuantity();
132 std::optional<cir::SourceLanguage> sourceLanguage = getCIRSourceLanguage();
135 cir::CIRDialect::getSourceLanguageAttrName(),
136 cir::SourceLanguageAttr::get(&mlirContext, *sourceLanguage));
137 theModule->setAttr(cir::CIRDialect::getTripleAttrName(),
138 builder.getStringAttr(
getTriple().str()));
140 if (cgo.OptimizationLevel > 0 || cgo.OptimizeSize > 0)
141 theModule->setAttr(cir::CIRDialect::getOptInfoAttrName(),
142 cir::OptInfoAttr::get(&mlirContext,
143 cgo.OptimizationLevel,
146 if (langOpts.OpenMP) {
147 mlir::omp::OffloadModuleOpts ompOpts(
148 langOpts.OpenMPTargetDebug, langOpts.OpenMPTeamSubscription,
149 langOpts.OpenMPThreadSubscription, langOpts.OpenMPNoThreadState,
150 langOpts.OpenMPNoNestedParallelism, langOpts.OpenMPIsTargetDevice,
151 getTriple().isGPU(), langOpts.OpenMPForceUSM, langOpts.OpenMP,
152 langOpts.OMPHostIRFile, langOpts.OMPTargetTriples, langOpts.NoGPULib);
153 mlir::omp::setOffloadModuleInterfaceAttributes(theModule, ompOpts);
159 createOpenMPRuntime();
164 FileID mainFileId = astContext.getSourceManager().getMainFileID();
166 *astContext.getSourceManager().getFileEntryForID(mainFileId);
169 theModule.setSymName(path);
170 theModule->setLoc(mlir::FileLineColLoc::get(&mlirContext, path,
177 llvm::StringRef cudaBinaryName = codeGenOpts.CudaGpuBinaryFileName;
178 if (!cudaBinaryName.empty()) {
179 theModule->setAttr(cir::CIRDialect::getCUDABinaryHandleAttrName(),
180 cir::CUDABinaryHandleAttr::get(
181 &mlirContext, mlir::StringAttr::get(
182 &mlirContext, cudaBinaryName)));
189void CIRGenModule::createCUDARuntime() {
193void CIRGenModule::createOpenMPRuntime() {
194 openMPRuntime = std::make_unique<CIRGenOpenMPRuntime>(*
this);
205 auto &layout = astContext.getASTRecordLayout(rd);
210 return layout.getAlignment();
213 return layout.getNonVirtualAlignment();
218 bool forPointeeType) {
228 if (
unsigned align = tt->getDecl()->getMaxAlignment()) {
231 return astContext.toCharUnitsFromBits(align);
239 t = astContext.getBaseElementType(t);
260 }
else if (forPointeeType && !alignForArray &&
264 alignment = astContext.getTypeAlignInChars(t);
269 if (
unsigned maxAlign = astContext.getLangOpts().MaxTypeAlign) {
271 !astContext.isAlignmentRequired(t))
285 if (theTargetCIRGenInfo)
286 return *theTargetCIRGenInfo;
289 switch (triple.getArch()) {
296 case llvm::Triple::x86_64: {
297 switch (triple.getOS()) {
304 case llvm::Triple::Linux:
306 return *theTargetCIRGenInfo;
309 case llvm::Triple::nvptx:
310 case llvm::Triple::nvptx64:
312 return *theTargetCIRGenInfo;
313 case llvm::Triple::amdgpu: {
315 return *theTargetCIRGenInfo;
317 case llvm::Triple::spirv:
318 case llvm::Triple::spirv32:
319 case llvm::Triple::spirv64:
321 return *theTargetCIRGenInfo;
326 assert(cLoc.
isValid() &&
"expected valid source location");
330 return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
335 assert(cRange.
isValid() &&
"expected a valid source range");
338 mlir::Attribute metadata;
339 return mlir::FusedLoc::get({begin, end}, metadata, builder.getContext());
348 false, isForDefinition);
382 assert(op &&
"expected a valid global op");
390 mlir::Operation *globalValueOp = op;
391 if (
auto gv = dyn_cast<cir::GetGlobalOp>(op)) {
393 assert(globalValueOp &&
"expected a valid global op");
396 if (
auto cirGlobalValue =
397 dyn_cast<cir::CIRGlobalValueInterface>(globalValueOp))
398 if (!cirGlobalValue.isDeclaration())
419 assert(deferredVTables.empty());
429 std::vector<GlobalDecl> curDeclsToEmit;
448 if (
auto *
attr =
decl->getAttr<AttrT>())
449 return attr->isImplicit();
450 return decl->isImplicit();
455 assert(langOpts.CUDA &&
"Should not be called by non-CUDA languages");
460 return !langOpts.CUDAIsDevice || global->
hasAttr<CUDADeviceAttr>() ||
461 global->
hasAttr<CUDAConstantAttr>() ||
462 global->
hasAttr<CUDASharedAttr>() ||
472 os << (isa<VarDecl>(d) ?
".static." :
".intern.");
474 os << (isa<VarDecl>(d) ?
"__static__" :
"__intern__");
481 "printPostfixForExternalizedDecl: CUID is not specified");
488 if (
const auto *cd = dyn_cast<clang::OpenACCConstructDecl>(gd.
getDecl())) {
496 if (global->hasAttr<WeakRefAttr>())
501 if (global->hasAttr<AliasAttr>()) {
514 "Expected Variable or Function");
515 if (
const auto *
varDecl = dyn_cast<VarDecl>(global)) {
519 }
else if (langOpts.CUDAIsDevice) {
520 const auto *
functionDecl = dyn_cast<FunctionDecl>(global);
521 if ((!global->hasAttr<CUDADeviceAttr>() ||
522 (langOpts.OffloadImplicitHostDeviceTemplates &&
527 !
getASTContext().CUDAImplicitHostDeviceFunUsedByDevice.count(
529 !global->hasAttr<CUDAGlobalAttr>() &&
531 !global->hasAttr<CUDAHostAttr>()))
534 }
else if (!global->hasAttr<CUDAHostAttr>() &&
535 global->hasAttr<CUDADeviceAttr>())
539 if (langOpts.OpenMP) {
541 if (openMPRuntime && openMPRuntime->emitTargetGlobal(gd))
543 if (
auto *drd = dyn_cast<OMPDeclareReductionDecl>(global)) {
548 if (
auto *dmd = dyn_cast<OMPDeclareMapperDecl>(global)) {
555 if (
const auto *fd = dyn_cast<FunctionDecl>(global)) {
558 if (fd->hasAttr<AnnotateAttr>()) {
561 deferredAnnotations[mangledName] = fd;
563 if (!fd->doesThisDeclarationHaveABody()) {
564 if (!fd->doesDeclarationForceExternallyVisibleDefinition() &&
575 assert(vd->isFileVarDecl() &&
"Cannot emit local var decl as global.");
577 !astContext.isMSStaticDataMemberInlineDefinition(vd)) {
581 if (astContext.getInlineVariableDefinitionKind(vd) ==
620 mlir::Operation *op) {
624 cir::FuncOp funcOp = dyn_cast_if_present<cir::FuncOp>(op);
625 if (!funcOp || funcOp.getFunctionType() != funcType) {
631 if (!funcOp.isDeclaration())
643 mlir::OpBuilder::InsertionGuard guard(builder);
648 setNonAliasAttributes(gd, funcOp);
651 auto getPriority = [
this](
const auto *
attr) ->
int {
655 return attr->DefaultPriority;
658 if (
const ConstructorAttr *ca = funcDecl->getAttr<ConstructorAttr>())
660 if (
const DestructorAttr *da = funcDecl->getAttr<DestructorAttr>())
663 if (funcDecl->getAttr<AnnotateAttr>())
666 if (
getLangOpts().OpenMP && funcDecl->hasAttr<OMPDeclareTargetDeclAttr>())
672 std::optional<int> priority) {
681 ctor.setGlobalCtorPriority(priority);
686 std::optional<int> priority) {
687 if (codeGenOpts.RegisterGlobalDtorsWithAtExit &&
689 errorNYI(dtor.getLoc(),
"registerGlobalDtorsWithAtExit");
692 dtor.setGlobalDtorPriority(priority);
717 mlir::ptr::MemorySpaceAttrInterface addrSpace,
718 mlir::Operation *insertPoint) {
723 mlir::OpBuilder::InsertionGuard guard(builder);
729 builder.setInsertionPoint(insertPoint);
735 builder.setInsertionPointToStart(
getModule().getBody());
738 g = cir::GlobalOp::create(builder, loc, name, t, isConstant, addrSpace);
744 mlir::SymbolTable::setSymbolVisibility(
745 g, mlir::SymbolTable::Visibility::Private);
753 if (isa_and_nonnull<NamedDecl>(d))
757 if (
auto gvi = mlir::dyn_cast<cir::CIRGlobalValueInterface>(gv)) {
758 if (d && d->
hasAttr<UsedAttr>())
761 if (
const auto *vd = dyn_cast_if_present<VarDecl>(d);
762 vd && ((codeGenOpts.KeepPersistentStorageVariables &&
763 (vd->getStorageDuration() ==
SD_Static ||
764 vd->getStorageDuration() ==
SD_Thread)) ||
765 (codeGenOpts.KeepStaticConsts &&
767 vd->getType().isConstQualified())))
773static std::vector<std::string>
775 llvm::StringMap<bool> &featureMap) {
776 llvm::StringMap<bool> defaultFeatureMap;
780 std::vector<std::string> delta;
781 for (
const auto &[k, v] : featureMap) {
782 auto defaultIt = defaultFeatureMap.find(k);
783 if (defaultIt == defaultFeatureMap.end() || defaultIt->getValue() != v)
784 delta.push_back((v ?
"+" :
"-") + k.str());
790bool CIRGenModule::getCPUAndFeaturesAttributes(
791 GlobalDecl gd, llvm::StringMap<std::string> &attrs,
792 bool setTargetFeatures) {
798 std::vector<std::string> features;
802 const auto *fd = dyn_cast_or_null<FunctionDecl>(gd.
getDecl());
803 fd = fd ? fd->getMostRecentDecl() : fd;
804 const auto *td = fd ? fd->getAttr<TargetAttr>() :
nullptr;
805 const auto *tv = fd ? fd->getAttr<TargetVersionAttr>() :
nullptr;
806 assert((!td || !tv) &&
"both target_version and target specified");
807 const auto *sd = fd ? fd->getAttr<CPUSpecificAttr>() :
nullptr;
808 const auto *tc = fd ? fd->getAttr<TargetClonesAttr>() :
nullptr;
809 bool addedAttr =
false;
810 if (td || tv || sd || tc) {
811 llvm::StringMap<bool> featureMap;
812 astContext.getFunctionFeatureMap(featureMap, gd);
818 llvm::StringRef featureStr = td ? td->getFeaturesStr() : llvm::StringRef();
821 if (!featureStr.empty()) {
822 clang::ParsedTargetAttr parsedAttr =
824 if (!parsedAttr.
CPU.empty() &&
826 targetCPU = parsedAttr.
CPU;
829 if (!parsedAttr.
Tune.empty() &&
831 tuneCPU = parsedAttr.
Tune;
847 features.reserve(features.size() + featureMap.size());
848 for (
const auto &entry : featureMap)
849 features.push_back((entry.getValue() ?
"+" :
"-") +
850 entry.getKey().str());
855 llvm::StringMap<bool> featureMap;
857 astContext.getFunctionFeatureMap(featureMap, gd);
868 if (!targetCPU.empty()) {
869 attrs[
"cir.target-cpu"] = targetCPU.str();
872 if (!tuneCPU.empty()) {
873 attrs[
"cir.tune-cpu"] = tuneCPU.str();
876 if (!features.empty() && setTargetFeatures) {
877 llvm::erase_if(features, [&](
const std::string &f) {
878 assert(!f.empty() && (f[0] ==
'+' || f[0] ==
'-') &&
879 "feature string must start with '+' or '-'");
882 llvm::sort(features);
883 attrs[
"cir.target-features"] = llvm::join(features,
",");
891void CIRGenModule::setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op) {
896 if (
auto gvi = mlir::dyn_cast<cir::CIRGlobalValueInterface>(op)) {
897 if (
const auto *sa = d->
getAttr<SectionAttr>())
898 gvi.setSection(builder.getStringAttr(sa->getName()));
902 if (
auto func = dyn_cast<cir::FuncOp>(op)) {
903 llvm::StringMap<std::string> attrs;
904 if (getCPUAndFeaturesAttributes(gd, attrs)) {
908 for (
const auto &[key, val] : attrs)
909 func->setAttr(key, builder.getStringAttr(val));
919std::optional<cir::SourceLanguage> CIRGenModule::getCIRSourceLanguage()
const {
920 using ClangStd = clang::LangStandard;
921 using CIRLang = cir::SourceLanguage;
926 if (opts.C99 || opts.C11 || opts.C17 || opts.C23 || opts.C2y ||
927 opts.LangStd == ClangStd::lang_c89 ||
928 opts.LangStd == ClangStd::lang_gnu89)
933 errorNYI(
"CIR does not yet support the given source language");
937LangAS CIRGenModule::getGlobalVarAddressSpace(
const VarDecl *d) {
938 if (langOpts.OpenCL) {
946 if (langOpts.SYCLIsDevice &&
948 errorNYI(
"SYCL global address space");
950 if (langOpts.CUDA && langOpts.CUDAIsDevice) {
952 if (d->
hasAttr<CUDAConstantAttr>())
954 if (d->
hasAttr<CUDASharedAttr>())
956 if (d->
hasAttr<CUDADeviceAttr>())
965 errorNYI(
"OpenMP global address space");
978 gv.
setLinkage(cir::GlobalLinkageKind::ExternalWeakLinkage);
987 auto linkage = cir::GlobalLinkageKind::ExternalWeakLinkage;
988 func.setLinkage(linkage);
992 if (!func.isDeclaration())
993 mlir::SymbolTable::setSymbolVisibility(
1000 for (mlir::Attribute i : indexes) {
1001 auto ind = mlir::cast<mlir::IntegerAttr>(i);
1002 inds.push_back(ind.getValue().getSExtValue());
1008 return view.getSymbol().getValue() == glob.getSymName();
1012 cir::GlobalOp newGlob,
1013 cir::GlobalViewAttr
attr,
1024 mlir::Type newTy = newGlob.getSymType();
1029 cir::PointerType newPtrTy;
1032 newPtrTy = cir::PointerType::get(newTy);
1041 cgm.
errorNYI(
"Unhandled type in createNewGlobalView");
1047 mlir::Attribute oldInit) {
1048 if (
auto oldView = mlir::dyn_cast<cir::GlobalViewAttr>(oldInit))
1051 auto getNewInitElements =
1052 [&](mlir::ArrayAttr oldElements) -> mlir::ArrayAttr {
1054 for (mlir::Attribute elt : oldElements) {
1055 if (
auto view = mlir::dyn_cast<cir::GlobalViewAttr>(elt))
1057 else if (mlir::isa<cir::ConstArrayAttr, cir::ConstRecordAttr>(elt))
1060 newElements.push_back(elt);
1062 return mlir::ArrayAttr::get(cgm.
getBuilder().getContext(), newElements);
1065 if (
auto oldArray = mlir::dyn_cast<cir::ConstArrayAttr>(oldInit)) {
1071 mlir::Attribute oldElts = oldArray.getElts();
1072 if (mlir::isa<mlir::StringAttr>(oldElts))
1074 mlir::Attribute newElements =
1075 getNewInitElements(mlir::cast<mlir::ArrayAttr>(oldElts));
1077 newElements, mlir::cast<cir::ArrayType>(oldArray.getType()));
1079 if (
auto oldRecord = mlir::dyn_cast<cir::ConstRecordAttr>(oldInit)) {
1080 mlir::ArrayAttr newMembers = getNewInitElements(oldRecord.getMembers());
1081 auto recordTy = mlir::cast<cir::RecordType>(oldRecord.getType());
1083 newMembers, recordTy.getPacked(), recordTy.getPadded(), recordTy);
1088 cgm.
errorNYI(
"Unhandled type in getNewInitValue");
1096 assert(oldGV.getSymName() == newGV.getSymName() &&
"symbol names must match");
1098 mlir::Type oldTy = oldGV.getSymType();
1099 mlir::Type newTy = newGV.getSymType();
1104 assert(oldTy != newTy &&
"expected type change in replaceGlobal");
1107 std::optional<mlir::SymbolTable::UseRange> oldSymUses =
1108 oldGV.getSymbolUses(theModule);
1109 for (mlir::SymbolTable::SymbolUse use : *oldSymUses) {
1110 mlir::Operation *userOp = use.getUser();
1112 (mlir::isa<cir::GetGlobalOp, cir::GlobalOp, cir::ConstantOp>(userOp)) &&
1113 "Unexpected user for global op");
1115 if (
auto getGlobalOp = dyn_cast<cir::GetGlobalOp>(use.getUser())) {
1116 mlir::Value useOpResultValue = getGlobalOp.getAddr();
1117 useOpResultValue.setType(cir::PointerType::get(newTy));
1119 mlir::OpBuilder::InsertionGuard guard(builder);
1120 builder.setInsertionPointAfter(getGlobalOp);
1121 mlir::Type ptrTy = builder.getPointerTo(oldTy);
1123 builder.createBitcast(getGlobalOp->getLoc(), useOpResultValue, ptrTy);
1124 useOpResultValue.replaceAllUsesExcept(
cast,
cast.getDefiningOp());
1125 }
else if (
auto glob = dyn_cast<cir::GlobalOp>(userOp)) {
1126 if (
auto init = glob.getInitialValue()) {
1127 mlir::Attribute nw =
getNewInitValue(*
this, newGV, oldTy, init.value());
1128 glob.setInitialValueAttr(nw);
1130 }
else if (
auto c = dyn_cast<cir::ConstantOp>(userOp)) {
1131 mlir::Attribute init =
getNewInitValue(*
this, newGV, oldTy, c.getValue());
1132 auto typedAttr = mlir::cast<mlir::TypedAttr>(init);
1133 mlir::OpBuilder::InsertionGuard guard(builder);
1134 builder.setInsertionPointAfter(c);
1135 auto newUser = cir::ConstantOp::create(builder, c.getLoc(), typedAttr);
1136 c.replaceAllUsesWith(newUser.getOperation());
1172 cir::GlobalOp entry;
1176 "getOrCreateCIRGlobal: global with non-GlobalOp type");
1181 mlir::ptr::MemorySpaceAttrInterface entryCIRAS = entry.getAddrSpaceAttr();
1187 if (entry.getSymType() == ty &&
1197 if (isForDefinition && !entry.isDeclaration()) {
1199 "getOrCreateCIRGlobal: global with conflicting type");
1207 if (!isForDefinition)
1216 bool isConstant =
false;
1221 astContext,
true, !needsDtor);
1224 mlir::ptr::MemorySpaceAttrInterface declCIRAS =
1229 cir::GlobalOp gv =
createGlobalOp(loc, mangledName, ty, isConstant, declCIRAS,
1230 entry.getOperation());
1250 if (langOpts.OpenMP && !langOpts.OpenMPSimd)
1252 "getOrCreateCIRGlobal: OpenMP target global variable");
1254 gv.setAlignmentAttr(
getSize(astContext.getDeclAlign(d)));
1265 if (astContext.isMSStaticDataMemberInlineDefinition(d))
1267 "getOrCreateCIRGlobal: MS static data member inline definition");
1271 if (
const SectionAttr *sa = d->
getAttr<SectionAttr>())
1272 gv.setSectionAttr(builder.getStringAttr(sa->getName()));
1276 if (
getTriple().getArch() == llvm::Triple::xcore)
1278 "getOrCreateCIRGlobal: XCore specific ABI requirements");
1288 "getOrCreateCIRGlobal: external const declaration with initializer");
1300 "getOrCreateCIRGlobal: HIP managed attribute");
1335 mlir::Type ptrTy = builder.getPointerTo(g.getSymType(), g.getAddrSpaceAttr());
1336 return cir::GetGlobalOp::create(
1339 g.getStaticLocalGuard().has_value());
1347 cir::PointerType ptrTy =
1348 builder.getPointerTo(globalOp.getSymType(), globalOp.getAddrSpaceAttr());
1349 return builder.getGlobalViewAttr(ptrTy, globalOp);
1353 assert((mlir::isa<cir::FuncOp>(gv.getOperation()) ||
1354 !gv.isDeclarationForLinker()) &&
1355 "Only globals with definition can force usage.");
1360 assert(!gv.isDeclarationForLinker() &&
1361 "Only globals with definition can force usage.");
1366 cir::CIRGlobalValueInterface gv) {
1367 assert((mlir::isa<cir::FuncOp>(gv.getOperation()) ||
1368 !gv.isDeclarationForLinker()) &&
1369 "Only globals with definition can force usage.");
1377 std::vector<cir::CIRGlobalValueInterface> &list) {
1382 mlir::Location loc = builder.getUnknownLoc();
1384 usedArray.resize(list.size());
1385 for (
auto [i, op] : llvm::enumerate(list)) {
1386 usedArray[i] = cir::GlobalViewAttr::get(
1387 cgm.
voidPtrTy, mlir::FlatSymbolRefAttr::get(op.getNameAttr()));
1390 cir::ArrayType arrayTy = cir::ArrayType::get(cgm.
voidPtrTy, usedArray.size());
1392 cir::ConstArrayAttr initAttr = cir::ConstArrayAttr::get(
1393 arrayTy, mlir::ArrayAttr::get(&cgm.
getMLIRContext(), usedArray));
1397 gv.setLinkage(cir::GlobalLinkageKind::AppendingLinkage);
1398 gv.setInitialValueAttr(initAttr);
1399 gv.setSectionAttr(builder.getStringAttr(
"llvm.metadata"));
1411 "emitGlobalVarDefinition: emit OpenCL/OpenMP global variable");
1418 bool isDefinitionAvailableExternally =
1423 if (isDefinitionAvailableExternally &&
1431 mlir::Attribute init;
1432 bool needsGlobalCtor =
false;
1433 bool needsGlobalDtor =
1434 !isDefinitionAvailableExternally &&
1439 std::optional<ConstantEmitter> emitter;
1444 bool isCUDASharedVar =
1449 bool isCUDAShadowVar =
1451 (vd->
hasAttr<CUDAConstantAttr>() || vd->
hasAttr<CUDADeviceAttr>() ||
1452 vd->
hasAttr<CUDASharedAttr>());
1453 bool isCUDADeviceShadowVar =
1459 (isCUDASharedVar || isCUDAShadowVar || isCUDADeviceShadowVar)) {
1461 }
else if (vd->
hasAttr<LoaderUninitializedAttr>()) {
1463 "emitGlobalVarDefinition: loader uninitialized attribute");
1464 }
else if (!initExpr) {
1477 emitter.emplace(*
this);
1478 mlir::Attribute initializer = emitter->tryEmitForInitializer(*initDecl);
1487 "emitGlobalVarDefinition: flexible array initializer");
1489 if (!isDefinitionAvailableExternally)
1490 needsGlobalCtor =
true;
1493 "emitGlobalVarDefinition: static initializer");
1504 mlir::Type initType;
1505 if (mlir::isa<mlir::SymbolRefAttr>(init)) {
1508 "emitGlobalVarDefinition: global initializer is a symbol reference");
1511 assert(mlir::isa<mlir::TypedAttr>(init) &&
"This should have a type");
1512 auto typedInitAttr = mlir::cast<mlir::TypedAttr>(init);
1513 initType = typedInitAttr.getType();
1515 assert(!mlir::isa<mlir::NoneType>(initType) &&
"Should have a type by now");
1521 if (!gv || gv.getSymType() != initType) {
1523 "emitGlobalVarDefinition: global initializer with type mismatch");
1529 if (vd->
hasAttr<AnnotateAttr>())
1542 if (langOpts.CUDA) {
1543 if (langOpts.CUDAIsDevice) {
1546 if (linkage != cir::GlobalLinkageKind::InternalLinkage &&
1548 (vd->
hasAttr<CUDADeviceAttr>() || vd->
hasAttr<CUDAConstantAttr>() ||
1551 gv->setAttr(cir::CUDAExternallyInitializedAttr::getMnemonic(),
1564 emitter->finalize(gv);
1568 gv.setConstant((vd->
hasAttr<CUDAConstantAttr>() && langOpts.CUDAIsDevice) ||
1569 (!needsGlobalCtor && !needsGlobalDtor &&
1574 if (
const SectionAttr *sa = vd->
getAttr<SectionAttr>()) {
1577 gv.setConstant(
true);
1581 gv.setLinkage(linkage);
1585 if (linkage == cir::GlobalLinkageKind::CommonLinkage) {
1587 gv.setConstant(
false);
1592 std::optional<mlir::Attribute> initializer = gv.getInitialValue();
1593 if (initializer && !
getBuilder().isNullValue(*initializer))
1594 gv.setLinkage(cir::GlobalLinkageKind::WeakAnyLinkage);
1597 setNonAliasAttributes(vd, gv);
1605 if (needsGlobalCtor || needsGlobalDtor)
1611 cir::GlobalLinkageKind::AvailableExternallyLinkage)
1617 if (fd->isInlineBuiltinDeclaration())
1628 mlir::Operation *op) {
1630 if (
const auto *fd = dyn_cast<FunctionDecl>(
decl)) {
1634 if (
const auto *method = dyn_cast<CXXMethodDecl>(
decl)) {
1638 abi->emitCXXStructor(gd);
1639 else if (fd->isMultiVersion())
1640 errorNYI(method->getSourceRange(),
"multiversion functions");
1644 if (method->isVirtual())
1650 if (fd->isMultiVersion())
1651 errorNYI(fd->getSourceRange(),
"multiversion functions");
1656 if (
const auto *vd = dyn_cast<VarDecl>(
decl))
1659 llvm_unreachable(
"Invalid argument to CIRGenModule::emitGlobalDefinition");
1673 astContext.getAsConstantArrayType(e->
getType());
1674 uint64_t finalSize = cat->getZExtSize();
1675 str.resize(finalSize);
1677 mlir::Type eltTy =
convertType(cat->getElementType());
1678 return builder.getString(str, eltTy, finalSize,
false);
1683 auto arrayEltTy = mlir::cast<cir::IntType>(arrayTy.getElementType());
1685 uint64_t arraySize = arrayTy.getSize();
1687 assert(arraySize > literalSize &&
1688 "wide string literal array size must have room for null terminator?");
1692 bool isAllZero =
true;
1693 for (
unsigned i = 0; i < literalSize; ++i) {
1701 return cir::ZeroAttr::get(arrayTy);
1705 elements.reserve(arraySize);
1706 for (
unsigned i = 0; i < literalSize; ++i)
1707 elements.push_back(cir::IntAttr::get(arrayEltTy, e->
getCodeUnit(i)));
1709 auto elementsAttr = mlir::ArrayAttr::get(&
getMLIRContext(), elements);
1710 return builder.getConstArray(elementsAttr, arrayTy);
1721 if (d.
hasAttr<SelectAnyAttr>())
1725 if (
auto *vd = dyn_cast<VarDecl>(&d))
1740 llvm_unreachable(
"No such linkage");
1746 if (
auto globalOp = dyn_cast_or_null<cir::GlobalOp>(op)) {
1747 globalOp.setComdat(
true);
1750 funcOp.setComdat(
true);
1756 genTypes.updateCompletedType(td);
1760 replacements[name] = op;
1765 mlir::SymbolUserMap &userMap) {
1766 for (mlir::Operation *user : userMap.getUsers(oldF)) {
1767 auto call = mlir::dyn_cast<cir::CallOp>(user);
1771 for (
auto [argOp, fnArgType] :
1772 llvm::zip(call.getArgs(), newF.getFunctionType().getInputs())) {
1773 if (argOp.getType() != fnArgType)
1782void CIRGenModule::applyReplacements() {
1783 if (replacements.empty())
1789 mlir::SymbolTableCollection symbolTableCollection;
1790 mlir::SymbolUserMap userMap(symbolTableCollection, theModule);
1792 for (
auto &i : replacements) {
1793 StringRef mangledName = i.first;
1794 mlir::Operation *replacement = i.second;
1800 auto newF = dyn_cast<cir::FuncOp>(replacement);
1803 errorNYI(replacement->getLoc(),
"replacement is not a function");
1808 "call argument types do not match replacement function");
1812 userMap.replaceAllUsesWith(oldF, newF.getSymNameAttr());
1813 newF->moveBefore(oldF);
1820 mlir::Location loc, StringRef name, mlir::Type ty,
1822 auto gv = mlir::dyn_cast_or_null<cir::GlobalOp>(
getGlobalValue(name));
1826 if (gv.getSymType() == ty)
1832 assert(gv.isDeclaration() &&
"Declaration has wrong type!");
1834 errorNYI(loc,
"createOrReplaceCXXRuntimeVariable: declaration exists with "
1845 mlir::SymbolTable::setSymbolVisibility(gv,
1849 !gv.hasAvailableExternallyLinkage()) {
1853 gv.setAlignmentAttr(
getSize(alignment));
1864 if ((noCommon || vd->
hasAttr<NoCommonAttr>()) && !vd->
hasAttr<CommonAttr>())
1875 if (vd->
hasAttr<SectionAttr>())
1881 if (vd->
hasAttr<PragmaClangBSSSectionAttr>() ||
1882 vd->
hasAttr<PragmaClangDataSectionAttr>() ||
1883 vd->
hasAttr<PragmaClangRelroSectionAttr>() ||
1884 vd->
hasAttr<PragmaClangRodataSectionAttr>())
1892 if (vd->
hasAttr<WeakImportAttr>())
1902 if (vd->
hasAttr<AlignedAttr>())
1909 for (
const FieldDecl *fd : rd->fields()) {
1910 if (fd->isBitField())
1912 if (fd->hasAttr<AlignedAttr>())
1934cir::GlobalLinkageKind
1938 return cir::GlobalLinkageKind::InternalLinkage;
1941 return cir::GlobalLinkageKind::WeakAnyLinkage;
1945 return cir::GlobalLinkageKind::LinkOnceAnyLinkage;
1950 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
1964 return !astContext.getLangOpts().AppleKext
1965 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
1966 : cir::GlobalLinkageKind::InternalLinkage;
1980 return cir::GlobalLinkageKind::ExternalLinkage;
1983 return dd->
hasAttr<CUDAGlobalAttr>()
1984 ? cir::GlobalLinkageKind::ExternalLinkage
1985 : cir::GlobalLinkageKind::InternalLinkage;
1986 return cir::GlobalLinkageKind::WeakODRLinkage;
1994 return cir::GlobalLinkageKind::CommonLinkage;
2000 if (dd->
hasAttr<SelectAnyAttr>())
2001 return cir::GlobalLinkageKind::WeakODRLinkage;
2005 return cir::GlobalLinkageKind::ExternalLinkage;
2017 mlir::Operation *old, cir::FuncOp newFn) {
2019 auto oldFn = mlir::dyn_cast<cir::FuncOp>(old);
2027 if (oldFn->getAttrs().size() <= 1)
2029 "replaceUsesOfNonProtoTypeWithRealFunction: Attribute forwarding");
2032 newFn.setNoProto(oldFn.getNoProto());
2035 std::optional<mlir::SymbolTable::UseRange> symUses =
2036 oldFn.getSymbolUses(oldFn->getParentOp());
2037 for (
const mlir::SymbolTable::SymbolUse &use : symUses.value()) {
2038 mlir::OpBuilder::InsertionGuard guard(builder);
2040 if (
auto noProtoCallOp = mlir::dyn_cast<cir::CallOp>(use.getUser())) {
2041 builder.setInsertionPoint(noProtoCallOp);
2044 cir::FuncType newFnType = newFn.getFunctionType();
2045 mlir::OperandRange callOperands = noProtoCallOp.getOperands();
2046 bool returnTypeMatches =
2047 newFnType.hasVoidReturn()
2048 ? noProtoCallOp.getNumResults() == 0
2049 : noProtoCallOp.getNumResults() == 1 &&
2050 noProtoCallOp.getResultTypes().front() ==
2051 newFnType.getReturnType();
2052 bool typesMatch = !newFn.getNoProto() && returnTypeMatches &&
2053 callOperands.size() == newFnType.getNumInputs();
2054 for (
unsigned i = 0, e = newFnType.getNumInputs(); typesMatch && i != e;
2056 if (callOperands[i].
getType() != newFnType.getInput(i))
2060 cir::CallOp realCallOp;
2064 builder.createCallOp(noProtoCallOp.getLoc(), newFn, callOperands);
2068 cir::FuncType origFnType = oldFn.getFunctionType();
2069 cir::FuncType callFnType =
2070 origFnType.isVarArg()
2071 ? cir::FuncType::get(origFnType.getInputs(),
2072 origFnType.getReturnType(),
2075 mlir::Value addr = cir::GetGlobalOp::create(
2076 builder, noProtoCallOp.getLoc(), cir::PointerType::get(newFnType),
2077 newFn.getSymName());
2078 mlir::Value casted =
2079 builder.createBitcast(addr, cir::PointerType::get(callFnType));
2080 realCallOp = builder.createIndirectCallOp(
2081 noProtoCallOp.getLoc(), casted, callFnType, callOperands);
2085 noProtoCallOp.replaceAllUsesWith(realCallOp);
2086 noProtoCallOp.erase();
2087 }
else if (
auto getGlobalOp =
2088 mlir::dyn_cast<cir::GetGlobalOp>(use.getUser())) {
2095 mlir::Value res = getGlobalOp.getAddr();
2096 const mlir::Type oldResTy = res.getType();
2097 const auto newPtrTy = cir::PointerType::get(newFn.getFunctionType());
2098 if (oldResTy != newPtrTy) {
2099 res.setType(newPtrTy);
2100 builder.setInsertionPointAfter(getGlobalOp.getOperation());
2101 mlir::Value castRes =
2102 cir::CastOp::create(builder, getGlobalOp.getLoc(), oldResTy,
2103 cir::CastKind::bitcast, res);
2104 res.replaceAllUsesExcept(castRes, castRes.getDefiningOp());
2106 }
else if (mlir::isa<cir::GlobalOp>(use.getUser())) {
2112 "replaceUsesOfNonProtoTypeWithRealFunction: unexpected use type");
2117cir::GlobalLinkageKind
2119 GVALinkage linkage = astContext.GetGVALinkageForVariable(vd);
2126 GVALinkage linkage = astContext.GetGVALinkageForFunction(d);
2128 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(d))
2137 StringRef globalName,
CharUnits alignment) {
2142 cir::GlobalOp gv = cgm.
createGlobalOp(loc, globalName, c.getType(),
2146 gv.setAlignmentAttr(cgm.
getSize(alignment));
2148 cir::GlobalLinkageKindAttr::get(cgm.
getBuilder().getContext(), lt));
2152 if (gv.isWeakForLinker()) {
2153 assert(cgm.
supportsCOMDAT() &&
"Only COFF uses weak string literals");
2156 cgm.
setDSOLocal(
static_cast<mlir::Operation *
>(gv));
2177 std::string result =
2188 astContext.getAlignOfGlobalVarInChars(s->
getType(),
nullptr);
2196 if (!gv.getAlignment() ||
2197 uint64_t(alignment.
getQuantity()) > *gv.getAlignment())
2198 gv.setAlignmentAttr(
getSize(alignment));
2203 if (
getCXXABI().getMangleContext().shouldMangleStringLiteral(s) &&
2206 "getGlobalForStringLiteral: mangle string literals");
2216 : builder.getUnknownLoc();
2217 auto typedC = llvm::cast<mlir::TypedAttr>(c);
2219 cir::GlobalLinkageKind::PrivateLinkage, *
this,
2220 uniqueName, alignment);
2234 auto arrayTy = mlir::dyn_cast<cir::ArrayType>(gv.getSymType());
2235 assert(arrayTy &&
"String literal must be array");
2239 return builder.getGlobalViewAttr(ptrTy, gv);
2256 errorNYI(
"SYCL temp address space");
2267 "emitExplicitCastExprType");
2273 auto ty = mlir::cast<cir::MethodType>(
convertType(destTy));
2274 return builder.getNullMethodAttr(ty);
2277 auto ty = mlir::cast<cir::DataMemberType>(
convertType(destTy));
2278 return builder.getNullDataMemberAttr(ty);
2289 if (
const auto *methodDecl = dyn_cast<CXXMethodDecl>(
decl)) {
2291 if (methodDecl->isVirtual())
2292 return cir::ConstantOp::create(
2293 builder, loc,
getCXXABI().buildVirtualMethodAttr(ty, methodDecl));
2299 return cir::ConstantOp::create(builder, loc,
2300 builder.getMethodAttr(ty, methodFuncOp));
2309 if (
fieldDecl->hasAttr<NoUniqueAddressAttr>()) {
2312 "emitMemberPointerConstant: no_unique_address field");
2316 std::optional<llvm::SmallVector<int32_t>> path =
2320 return cir::ConstantOp::create(builder, loc,
2321 builder.getDataMemberAttr(ty, *path));
2324std::optional<llvm::SmallVector<int32_t>>
2327 assert(!field->
hasAttr<NoUniqueAddressAttr>());
2330 if (!findFieldMemberPath(destClass, field, path))
2331 return std::nullopt;
2335bool CIRGenModule::findFieldMemberPath(
const CXXRecordDecl *currentClass,
2342 if (field->
getParent() == currentClass) {
2344 if (currentClass->
isUnion()) {
2350 "data member pointer for non-zero-initializable union");
2357 path.push_back(fieldIdx);
2365 for (
const CXXBaseSpecifier &base : currentClass->
bases()) {
2366 const auto *baseDecl =
2369 if (base.isVirtual()) {
2374 llvm::SmallVector<int32_t> discardedPath;
2375 if (findFieldMemberPath(baseDecl, field, discardedPath)) {
2377 "data member pointer through virtual base");
2390 path.push_back(baseFieldIdx);
2391 if (findFieldMemberPath(baseDecl, field, path))
2405 if (
auto *oid = dyn_cast<ObjCImplDecl>(
decl))
2406 errorNYI(oid->getSourceRange(),
"emitDeclConext: ObjCImplDecl");
2416 if (
decl->isTemplated())
2419 switch (
decl->getKind()) {
2422 decl->getDeclKindName());
2425 case Decl::CXXConversion:
2426 case Decl::CXXMethod:
2427 case Decl::Function: {
2430 if (!fd->isConsteval())
2439 case Decl::Decomposition:
2440 case Decl::VarTemplateSpecialization: {
2442 if (
auto *decomp = dyn_cast<DecompositionDecl>(
decl))
2443 for (
auto *binding : decomp->flat_bindings())
2444 if (
auto *holdingVar = binding->getHoldingVar())
2448 case Decl::OpenACCRoutine:
2451 case Decl::OpenACCDeclare:
2454 case Decl::OMPThreadPrivate:
2457 case Decl::OMPGroupPrivate:
2460 case Decl::OMPAllocate:
2463 case Decl::OMPCapturedExpr:
2466 case Decl::OMPDeclareReduction:
2469 case Decl::OMPDeclareMapper:
2472 case Decl::OMPRequires:
2477 case Decl::UsingDirective:
2478 case Decl::UsingEnum:
2479 case Decl::NamespaceAlias:
2481 case Decl::TypeAlias:
2487 case Decl::ClassTemplate:
2489 case Decl::CXXDeductionGuide:
2491 case Decl::ExplicitInstantiation:
2492 case Decl::FunctionTemplate:
2493 case Decl::StaticAssert:
2494 case Decl::TypeAliasTemplate:
2495 case Decl::UsingShadow:
2496 case Decl::VarTemplate:
2497 case Decl::VarTemplatePartialSpecialization:
2500 case Decl::CXXConstructor:
2503 case Decl::CXXDestructor:
2508 case Decl::LinkageSpec:
2509 case Decl::Namespace:
2513 case Decl::ClassTemplateSpecialization:
2514 case Decl::CXXRecord: {
2517 for (
auto *childDecl : crd->
decls())
2523 case Decl::FileScopeAsm:
2525 if (langOpts.CUDA && langOpts.CUDAIsDevice)
2528 if (langOpts.OpenMPIsTargetDevice)
2531 if (langOpts.SYCLIsDevice)
2534 std::string line = file_asm->getAsmString();
2535 globalScopeAsm.push_back(builder.getStringAttr(line));
2542 op.setInitialValueAttr(value);
2556 md->getParent()->getNumVBases() == 0)
2558 "getAddrAndTypeOfCXXStructor: MS ABI complete destructor");
2569 false, isForDefinition);
2571 return {fnType, fn};
2575 mlir::Type funcType,
bool forVTable,
2579 "consteval function should never be emitted");
2589 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(gd.
getDecl())) {
2592 dd->getParent()->getNumVBases() == 0)
2594 "getAddrOfFunction: MS ABI complete destructor");
2600 false, isForDefinition);
2602 if (langOpts.CUDA && !langOpts.CUDAIsDevice &&
2608 bool isHIPHandle = mlir::isa<cir::GlobalOp>(*handle);
2609 if (isForDefinition || isHIPHandle)
2611 return mlir::dyn_cast<cir::FuncOp>(*handle);
2620 llvm::raw_svector_ostream
out(buffer);
2629 assert(ii &&
"Attempt to mangle unnamed decl.");
2631 const auto *fd = dyn_cast<FunctionDecl>(nd);
2635 }
else if (fd && fd->hasAttr<CUDAGlobalAttr>() &&
2639 DeviceKernelAttr::isOpenCLSpelling(
2640 fd->getAttr<DeviceKernelAttr>()) &&
2657 if (
const auto *fd = dyn_cast<FunctionDecl>(nd)) {
2658 if (fd->isMultiVersion()) {
2660 "getMangledName: multi-version functions");
2665 "getMangledName: GPU relocatable device code");
2668 return std::string(
out.str());
2671static FunctionDecl *
2686 if (
auto *methodDecl = dyn_cast<CXXMethodDecl>(protoFunc);
2687 methodDecl && methodDecl->isImplicitObjectMemberFunction()) {
2689 paramTypes.insert(paramTypes.begin(), methodDecl->getThisType());
2692 fpt->getExtProtoInfo());
2703 params.reserve(fpt->getNumParams());
2706 for (
unsigned i = 0, e = fpt->getNumParams(); i != e; ++i) {
2710 nullptr, fpt->getParamType(i),
nullptr,
2713 params.push_back(parm);
2716 tempFunc->setParams(params);
2741 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(canonicalGd.
getDecl())) {
2744 "getMangledName: C++ constructor without variants");
2753 auto result = manglings.insert(std::make_pair(mangledName, gd));
2754 return mangledDeclNames[canonicalGd] = result.first->first();
2758 assert(!d->
getInit() &&
"Cannot emit definite definitions here!");
2766 if (gv && !mlir::cast<cir::GlobalOp>(gv).isDeclaration())
2782 if (langOpts.EmitAllDecls)
2785 const auto *vd = dyn_cast<VarDecl>(global);
2787 ((codeGenOpts.KeepPersistentStorageVariables &&
2788 (vd->getStorageDuration() ==
SD_Static ||
2789 vd->getStorageDuration() ==
SD_Thread)) ||
2790 (codeGenOpts.KeepStaticConsts && vd->getStorageDuration() ==
SD_Static &&
2791 vd->getType().isConstQualified())))
2804 if (langOpts.OpenMP >= 50 && !langOpts.OpenMPSimd) {
2805 std::optional<OMPDeclareTargetDeclAttr *> activeAttr =
2806 OMPDeclareTargetDeclAttr::getActiveAttr(global);
2807 if (!activeAttr || (*activeAttr)->getLevel() != (
unsigned)-1)
2811 const auto *fd = dyn_cast<FunctionDecl>(global);
2818 if (fd->hasAttr<TargetVersionAttr>() && !fd->isMultiVersion())
2820 if (langOpts.SYCLIsDevice) {
2821 errorNYI(fd->getSourceRange(),
"mayBeEmittedEagerly: SYCL");
2825 const auto *vd = dyn_cast<VarDecl>(global);
2827 if (astContext.getInlineVariableDefinitionKind(vd) ==
2835 if (langOpts.OpenMP && langOpts.OpenMPUseTLS &&
2836 astContext.getTargetInfo().isTLSSupported() &&
isa<VarDecl>(global) &&
2838 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(global))
2841 assert((fd || vd) &&
2842 "Only FunctionDecl and VarDecl should hit this path so far.");
2847 cir::CIRGlobalValueInterface gv) {
2848 if (gv.hasLocalLinkage())
2851 if (!gv.hasDefaultVisibility() && !gv.hasExternalWeakLinkage())
2859 const llvm::Triple &tt = cgm.
getTriple();
2861 if (tt.isOSCygMing()) {
2870 cgm.
errorNYI(
"shouldAssumeDSOLocal: MinGW");
2876 if (tt.isOSBinFormatCOFF() && gv.hasExternalWeakLinkage())
2884 if (tt.isOSBinFormatCOFF() || (tt.isOSWindows() && tt.isOSBinFormatMachO()))
2888 if (!tt.isOSBinFormatELF())
2893 if (rm != llvm::Reloc::Static && !lOpts.PIE) {
2901 return !(lOpts.SemanticInterposition || lOpts.HalfNoSemanticInterposition);
2905 if (!gv.isDeclarationForLinker())
2911 if (rm == llvm::Reloc::PIC_ && gv.hasExternalWeakLinkage())
2918 if (cgOpts.DirectAccessExternalData) {
2924 if (
auto globalOp = dyn_cast<cir::GlobalOp>(gv.getOperation())) {
2950 if (gv.hasLocalLinkage()) {
2951 gv.setGlobalVisibility(cir::VisibilityKind::Default);
2966 d->
hasAttr<OMPDeclareTargetDeclAttr>() &&
2967 d->
getAttr<OMPDeclareTargetDeclAttr>()->getDevType() !=
2968 OMPDeclareTargetDeclAttr::DT_NoHost &&
2970 llvm_unreachable(
"setGlobalVisibility: OpenMP is NYI");
2979 !d->
hasAttr<OMPDeclareTargetDeclAttr>()) {
2980 bool needsProtected =
false;
2984 }
else if (
const auto *vd = dyn_cast<VarDecl>(d)) {
2985 needsProtected = vd->hasAttr<CUDADeviceAttr>() ||
2986 vd->hasAttr<CUDAConstantAttr>() ||
2987 vd->getType()->isCUDADeviceBuiltinSurfaceType() ||
2988 vd->getType()->isCUDADeviceBuiltinTextureType();
2990 if (needsProtected) {
2991 gv.setGlobalVisibility(cir::VisibilityKind::Protected);
2997 gv.setGlobalVisibility(cir::VisibilityKind::Hidden);
3004 !gv.isDeclarationForLinker())
3013 if (
auto globalValue = dyn_cast<cir::CIRGlobalValueInterface>(op))
3032 auto res = manglings.find(mangledName);
3033 if (res == manglings.end())
3035 result = res->getValue();
3042 return cir::TLS_Model::GeneralDynamic;
3044 return cir::TLS_Model::LocalDynamic;
3046 return cir::TLS_Model::InitialExec;
3048 return cir::TLS_Model::LocalExec;
3050 llvm_unreachable(
"Invalid TLS model!");
3054 bool isExtendingDecl) {
3055 assert(d.
getTLSKind() &&
"setting TLS mode on non-TLS var!");
3060 if (d.
getAttr<TLSModelAttr>())
3064 global.setTlsModel(tlm);
3068 if (d.
isStaticLocal() || tlm != cir::TLS_Model::GeneralDynamic)
3074 if (isExtendingDecl)
3082 cir::FuncOp func,
bool isThunk) {
3084 cir::CallingConv callingConv;
3085 cir::SideEffect sideEffect;
3092 mlir::NamedAttrList pal{};
3093 std::vector<mlir::NamedAttrList> argAttrs(info.
arguments().size());
3094 mlir::NamedAttrList retAttrs{};
3096 retAttrs, callingConv, sideEffect,
3099 for (mlir::NamedAttribute
attr : pal)
3100 func->setAttr(
attr.getName(),
attr.getValue());
3102 llvm::for_each(llvm::enumerate(argAttrs), [func](
auto idx_arg_pair) {
3103 mlir::function_interface_impl::setArgAttrs(func, idx_arg_pair.index(),
3104 idx_arg_pair.value());
3106 if (!retAttrs.empty())
3107 mlir::function_interface_impl::setResultAttrs(func, 0, retAttrs);
3120 bool isIncompleteFunction,
3128 if (!isIncompleteFunction)
3130 getTypes().arrangeGlobalDeclaration(globalDecl),
3133 if (!isIncompleteFunction && func.isDeclaration())
3140 if (funcDecl->isInlineBuiltinDeclaration()) {
3142 bool hasBody = funcDecl->
hasBody(fdBody);
3144 assert(hasBody &&
"Inline builtin declarations should always have an "
3149 if (funcDecl->isReplaceableGlobalAllocationFunction()) {
3152 func->setAttr(cir::CIRDialect::getNoBuiltinAttrName(),
3164 if (!langOpts.Exceptions)
3167 if (langOpts.CXXExceptions)
3170 if (langOpts.ObjCExceptions)
3181 f->setAttr(cir::CIRDialect::getNoThrowAttrName(),
3184 std::optional<cir::InlineKind> existingInlineKind = f.getInlineKind();
3186 existingInlineKind && *existingInlineKind == cir::InlineKind::NoInline;
3187 bool isAlwaysInline = existingInlineKind &&
3188 *existingInlineKind == cir::InlineKind::AlwaysInline;
3192 if (!isAlwaysInline &&
3197 f.setInlineKind(cir::InlineKind::NoInline);
3212 if (
decl->hasAttr<NoInlineAttr>() && !isAlwaysInline) {
3214 f.setInlineKind(cir::InlineKind::NoInline);
3215 }
else if (
decl->hasAttr<AlwaysInlineAttr>() && !isNoInline) {
3218 f.setInlineKind(cir::InlineKind::AlwaysInline);
3222 if (!isAlwaysInline)
3223 f.setInlineKind(cir::InlineKind::NoInline);
3228 if (
auto *fd = dyn_cast<FunctionDecl>(
decl)) {
3233 auto checkRedeclForInline = [](
const FunctionDecl *redecl) {
3234 return redecl->isInlineSpecified();
3236 if (any_of(
decl->redecls(), checkRedeclForInline))
3241 return any_of(pattern->
redecls(), checkRedeclForInline);
3243 if (checkForInline(fd)) {
3244 f.setInlineKind(cir::InlineKind::InlineHint);
3245 }
else if (codeGenOpts.getInlining() ==
3247 !fd->isInlined() && !isAlwaysInline) {
3248 f.setInlineKind(cir::InlineKind::NoInline);
3257 StringRef mangledName, mlir::Type funcType,
GlobalDecl gd,
bool forVTable,
3259 mlir::NamedAttrList extraAttrs) {
3262 if (
const auto *fd = cast_or_null<FunctionDecl>(d)) {
3264 if (
getLangOpts().OpenMPIsTargetDevice && openMPRuntime &&
3266 !dontDefer && !isForDefinition) {
3269 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(fdDef))
3271 else if (
const auto *dd = dyn_cast<CXXDestructorDecl>(fdDef))
3281 if (fd->isMultiVersion())
3282 errorNYI(fd->getSourceRange(),
"getOrCreateCIRFunction: multi-version");
3288 assert(mlir::isa<cir::FuncOp>(entry));
3293 if (d && !d->
hasAttr<DLLImportAttr>() && !d->
hasAttr<DLLExportAttr>()) {
3301 if (isForDefinition && fn && !fn.isDeclaration()) {
3308 diagnosedConflictingDefinitions.insert(gd).second) {
3312 diag::note_previous_definition);
3316 if (fn && fn.getFunctionType() == funcType) {
3320 if (!isForDefinition) {
3328 auto *funcDecl = llvm::cast_or_null<FunctionDecl>(gd.
getDecl());
3329 bool invalidLoc = !funcDecl ||
3330 funcDecl->getSourceRange().getBegin().isInvalid() ||
3331 funcDecl->getSourceRange().getEnd().isInvalid();
3333 invalidLoc ? theModule->getLoc() :
getLoc(funcDecl->getSourceRange()),
3334 mangledName, mlir::cast<cir::FuncType>(funcType), funcDecl);
3336 if (funcDecl && funcDecl->hasAttr<AnnotateAttr>())
3337 deferredAnnotations[mangledName] = funcDecl;
3348 auto symbolOp = mlir::cast<mlir::SymbolOpInterface>(entry);
3356 if (symbolOp.getSymbolUses(symbolOp->getParentOp()))
3366 if (!extraAttrs.empty()) {
3367 extraAttrs.append(funcOp->getAttrs());
3368 funcOp->setAttrs(extraAttrs);
3375 assert(funcOp.getFunctionType() == funcType);
3382 if (isa_and_nonnull<CXXDestructorDecl>(d) &&
3412 fd = fd->getPreviousDecl()) {
3414 if (fd->doesThisDeclarationHaveABody()) {
3427 cir::FuncType funcType,
3431 mlir::OpBuilder::InsertionGuard guard(builder);
3439 builder.setInsertionPoint(cgf->
curFn);
3441 func = cir::FuncOp::create(builder, loc, name, funcType);
3448 func.setNoProto(
true);
3450 assert(func.isDeclaration() &&
"expected empty body");
3454 func.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
3456 mlir::SymbolTable::setSymbolVisibility(
3457 func, mlir::SymbolTable::Visibility::Private);
3465 theModule.push_back(func);
3470 for (
const auto *
attr :
3484 fnOp.setBuiltin(
true);
3490 return cir::CtorKind::Default;
3492 return cir::CtorKind::Copy;
3494 return cir::CtorKind::Move;
3495 return cir::CtorKind::Custom;
3500 return cir::AssignKind::Copy;
3502 return cir::AssignKind::Move;
3503 llvm_unreachable(
"not a copy or move assignment operator");
3511 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(funcDecl)) {
3512 auto cxxDtor = cir::CXXDtorAttr::get(
3515 funcOp.setFuncInfoAttr(cxxDtor);
3519 if (
const auto *ctor = dyn_cast<CXXConstructorDecl>(funcDecl)) {
3521 auto cxxCtor = cir::CXXCtorAttr::get(
3523 kind, ctor->isTrivial());
3524 funcOp.setFuncInfoAttr(cxxCtor);
3528 const auto *method = dyn_cast<CXXMethodDecl>(funcDecl);
3529 if (method && (method->isCopyAssignmentOperator() ||
3530 method->isMoveAssignmentOperator())) {
3532 auto cxxAssign = cir::CXXAssignAttr::get(
3534 assignKind, method->isTrivial());
3535 funcOp.setFuncInfoAttr(cxxAssign);
3541 cir::FuncOp funcOp, StringRef name) {
3557 mlir::NamedAttrList extraAttrs,
3559 bool assumeConvergent) {
3560 if (assumeConvergent)
3561 errorNYI(
"createRuntimeFunction: assumeConvergent");
3571 entry.setDSOLocal(
true);
3577mlir::SymbolTable::Visibility
3581 if (op.isDeclaration())
3582 return mlir::SymbolTable::Visibility::Private;
3586mlir::SymbolTable::Visibility
3589 case cir::GlobalLinkageKind::InternalLinkage:
3590 case cir::GlobalLinkageKind::PrivateLinkage:
3591 return mlir::SymbolTable::Visibility::Private;
3592 case cir::GlobalLinkageKind::ExternalLinkage:
3593 case cir::GlobalLinkageKind::ExternalWeakLinkage:
3594 case cir::GlobalLinkageKind::LinkOnceODRLinkage:
3595 case cir::GlobalLinkageKind::AvailableExternallyLinkage:
3596 case cir::GlobalLinkageKind::CommonLinkage:
3597 case cir::GlobalLinkageKind::WeakAnyLinkage:
3598 case cir::GlobalLinkageKind::WeakODRLinkage:
3599 return mlir::SymbolTable::Visibility::Public;
3601 llvm::errs() <<
"visibility not implemented for '"
3602 << stringifyGlobalLinkageKind(glk) <<
"'\n";
3603 assert(0 &&
"not implemented");
3606 llvm_unreachable(
"linkage should be handled above!");
3610 clang::VisibilityAttr::VisibilityType visibility) {
3611 switch (visibility) {
3612 case clang::VisibilityAttr::VisibilityType::Default:
3613 return cir::VisibilityKind::Default;
3614 case clang::VisibilityAttr::VisibilityType::Hidden:
3615 return cir::VisibilityKind::Hidden;
3616 case clang::VisibilityAttr::VisibilityType::Protected:
3617 return cir::VisibilityKind::Protected;
3619 llvm_unreachable(
"unexpected visibility value");
3624 const clang::VisibilityAttr *va =
decl->getAttr<clang::VisibilityAttr>();
3625 cir::VisibilityAttr cirVisibility =
3628 cirVisibility = cir::VisibilityAttr::get(
3632 return cirVisibility;
3638 applyReplacements();
3640 theModule->setAttr(cir::CIRDialect::getModuleLevelAsmAttrName(),
3641 builder.getArrayAttr(globalScopeAsm));
3643 emitGlobalAnnotations();
3645 if (!recordLayoutEntries.empty())
3647 cir::CIRDialect::getRecordLayoutsAttrName(),
3648 mlir::DictionaryAttr::get(&
getMLIRContext(), recordLayoutEntries));
3657 std::string cuidName =
3660 auto loc = builder.getUnknownLoc();
3661 mlir::ptr::MemorySpaceAttrInterface addrSpace =
3663 getGlobalVarAddressSpace(
nullptr));
3667 gv.setLinkage(cir::GlobalLinkageKind::ExternalLinkage);
3669 auto zeroAttr = cir::IntAttr::get(int8Ty, 0);
3670 gv.setInitialValueAttr(zeroAttr);
3672 mlir::SymbolTable::setSymbolVisibility(
3673 gv, mlir::SymbolTable::Visibility::Public);
3678 if (astContext.getLangOpts().CUDA && cudaRuntime)
3693 const AliasAttr *aa = d->
getAttr<AliasAttr>();
3694 assert(aa &&
"Not an alias?");
3698 if (aa->getAliasee() == mangledName) {
3699 diags.Report(aa->getLocation(), diag::err_cyclic_alias) << 0;
3707 auto entryGV = mlir::dyn_cast<cir::CIRGlobalValueInterface>(entry);
3708 if (entryGV && entryGV.isDefinition())
3721 cir::GlobalLinkageKind linkage;
3734 linkage = cir::GlobalLinkageKind::WeakAnyLinkage;
3746 mlir::SymbolTable::Visibility visibility =
3750 cir::CIRGlobalValueInterface alias =
3751 isFunction ? mlir::cast<cir::CIRGlobalValueInterface>(
3753 mlir::cast<cir::FuncType>(declTy),
3756 : mlir::cast<cir::CIRGlobalValueInterface>(
3758 alias.setAliasee(aa->getAliasee());
3759 alias.setLinkage(linkage);
3760 mlir::SymbolTable::setSymbolVisibility(alias, visibility);
3768 cir::FuncOp aliasee,
3769 cir::GlobalLinkageKind linkage) {
3771 auto *aliasFD = dyn_cast<FunctionDecl>(aliasGD.
getDecl());
3772 assert(aliasFD &&
"expected FunctionDecl");
3783 mangledName, fnType, aliasFD);
3784 alias.setAliasee(aliasee.getName());
3785 alias.setLinkage(linkage);
3789 mlir::SymbolTable::setSymbolVisibility(
3790 alias, mlir::SymbolTable::Visibility::Private);
3802 "declaration exists with different type");
3814 return genTypes.convertType(
type);
3821 return mlir::verify(theModule).succeeded();
3830 return builder.getConstNullPtrAttr(builder.getUInt8PtrTy());
3833 langOpts.ObjCRuntime.isGNUFamily()) {
3834 errorNYI(loc,
"getAddrOfRTTIDescriptor: Objc PtrType & Objc RT GUN");
3844 llvm::iterator_range<CastExpr::path_const_iterator> path) {
3851 assert(!base->isVirtual() &&
"Should not see virtual bases here!");
3856 const auto *baseDecl = base->getType()->castAsCXXRecordDecl();
3868 llvm::StringRef feature) {
3869 unsigned diagID = diags.getCustomDiagID(
3871 return diags.Report(loc, diagID) << feature;
3875 llvm::StringRef feature) {
3887 "cannot compile this %0 yet");
3888 diags.Report(astContext.getFullLoc(s->
getBeginLoc()), diagId)
3895 "cannot compile this %0 yet");
3896 diags.Report(astContext.getFullLoc(d->
getLocation()), diagId) <<
type;
3900 cir::LabelOp label) {
3901 [[maybe_unused]]
auto result =
3903 assert(result.second &&
3904 "attempting to map a blockaddress info that is already mapped");
3917 "not a global temporary");
3929 materializedType = mte->
getType();
3938 llvm::raw_svector_ostream
out(name);
3942 auto insertResult = materializedGlobalTemporaryMap.insert({mte,
nullptr});
3943 if (!insertResult.second) {
3947 if (!insertResult.first->second) {
3950 insertResult.first->second =
3953 return insertResult.first->second;
3970 value = &evalResult.
Val;
3974 std::optional<ConstantEmitter> emitter;
3975 mlir::Attribute initialValue =
nullptr;
3976 bool isConstant =
false;
3980 emitter.emplace(*
this);
3981 initialValue = emitter->emitForInitializer(*value, materializedType);
3986 type = mlir::cast<mlir::TypedAttr>(initialValue).getType();
3995 if (linkage == cir::GlobalLinkageKind::ExternalLinkage) {
3997 if (
varDecl->isStaticDataMember() &&
varDecl->getAnyInitializer(initVD) &&
4005 linkage = cir::GlobalLinkageKind::InternalLinkage;
4009 gv.setInitialValueAttr(initialValue);
4010 gv.setLinkage(linkage);
4014 emitter->finalize(gv);
4016 if (!gv.hasLocalLinkage()) {
4021 gv.setAlignment(align.getAsAlign().value());
4026 mlir::Operation *cv = gv;
4035 mlir::Operation *&entry = materializedGlobalTemporaryMap[mte];
4037 entry->replaceAllUsesWith(cv);
4052 return *globalOpEntry;
4059 "emitForInitializer should take gcd->getType().getAddressSpace()");
4061 auto typedInit = dyn_cast<mlir::TypedAttr>(init);
4065 "getAddrOfUnnamedGlobalConstantDecl: non-typed initializer");
4074 std::string name = numEntries == 0
4076 : (Twine(
".constant.") + Twine(numEntries)).str();
4078 typedInit.getType(),
true);
4079 globalOp.setLinkage(cir::GlobalLinkageKind::PrivateLinkage);
4082 globalOp.setAlignment(alignment.
getAsAlign().value());
4086 *globalOpEntry = globalOp;
4101 "emitForInitializer should take tpo->getType().getAddressSpace()");
4102 mlir::Attribute init =
4112 cir::GlobalLinkageKind linkage =
4114 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
4115 : cir::GlobalLinkageKind::InternalLinkage;
4119 typedInit.getType(),
true);
4120 globalOp.setLinkage(linkage);
4121 globalOp.setAlignment(alignment.
getAsAlign().value());
4123 linkage == cir::GlobalLinkageKind::LinkOnceODRLinkage);
4138CIRGenModule::getOrCreateAnnotationArgs(
const AnnotateAttr *
attr) {
4145 llvm::FoldingSetNodeID id;
4146 for (
Expr *e : exprs)
4149 mlir::ArrayAttr &lookup = annotationArgs[
id.ComputeHash()];
4154 args.reserve(exprs.size());
4155 for (
Expr *e : exprs) {
4156 if (
auto *strE = dyn_cast<clang::StringLiteral>(e->IgnoreParenCasts())) {
4157 args.push_back(builder.getStringAttr(strE->getString()));
4158 }
else if (
auto *intE =
4159 dyn_cast<clang::IntegerLiteral>(e->IgnoreParenCasts())) {
4160 auto intTy = builder.getIntegerType(intE->getValue().getBitWidth());
4161 args.push_back(builder.getIntegerAttr(intTy, intE->getValue()));
4163 errorNYI(e->getExprLoc(),
"annotation argument expression");
4167 return lookup = builder.getArrayAttr(args);
4170cir::AnnotationAttr CIRGenModule::emitAnnotateAttr(
const AnnotateAttr *aa) {
4171 mlir::StringAttr annoGV = builder.getStringAttr(aa->getAnnotation());
4172 mlir::ArrayAttr args = getOrCreateAnnotationArgs(aa);
4173 return cir::AnnotationAttr::get(&
getMLIRContext(), annoGV, args);
4177 mlir::Operation *gv) {
4178 assert(d->
hasAttr<AnnotateAttr>() &&
"no annotate attribute");
4180 "annotation only on globals");
4183 annotations.push_back(emitAnnotateAttr(i));
4184 if (
auto global = dyn_cast<cir::GlobalOp>(gv))
4185 global.setAnnotationsAttr(builder.getArrayAttr(annotations));
4186 else if (
auto func = dyn_cast<cir::FuncOp>(gv))
4187 func.setAnnotationsAttr(builder.getArrayAttr(annotations));
4190void CIRGenModule::emitGlobalAnnotations() {
4191 for (
const auto &[mangledName, vd] : deferredAnnotations) {
4196 deferredAnnotations.clear();
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
static bool shouldAssumeDSOLocal(const CIRGenModule &cgm, cir::CIRGlobalValueInterface gv)
static cir::AssignKind getAssignKindFromDecl(const CXXMethodDecl *method)
static FunctionDecl * createOpenACCBindTempFunction(ASTContext &ctx, const IdentifierInfo *bindName, const FunctionDecl *protoFunc)
static bool shouldBeInCOMDAT(CIRGenModule &cgm, const Decl &d)
static mlir::Attribute getNewInitValue(CIRGenModule &cgm, cir::GlobalOp newGlob, mlir::Type oldTy, mlir::Attribute oldInit)
static bool hasUnwindExceptions(const LangOptions &langOpts)
Determines whether the language options require us to model unwind exceptions.
static void setWindowsItaniumDLLImport(CIRGenModule &cgm, bool isLocal, cir::FuncOp funcOp, StringRef name)
static std::string getMangledNameImpl(CIRGenModule &cgm, GlobalDecl gd, const NamedDecl *nd)
static llvm::SmallVector< int64_t > indexesOfArrayAttr(mlir::ArrayAttr indexes)
static bool isViewOnGlobal(cir::GlobalOp glob, cir::GlobalViewAttr view)
static void setLinkageForFunction(CIRGenModule &cgm, cir::FuncOp &func, const NamedDecl *nd)
static cir::GlobalOp generateStringLiteral(mlir::Location loc, mlir::TypedAttr c, cir::GlobalLinkageKind lt, CIRGenModule &cgm, StringRef globalName, CharUnits alignment)
static bool hasImplicitAttr(const ValueDecl *decl)
static std::vector< std::string > getFeatureDeltaFromDefault(const CIRGenModule &cgm, llvm::StringRef targetCPU, llvm::StringMap< bool > &featureMap)
Get the feature delta from the default feature map for the given target CPU.
static CIRGenCXXABI * createCXXABI(CIRGenModule &cgm)
static bool isVarDeclStrongDefinition(const ASTContext &astContext, CIRGenModule &cgm, const VarDecl *vd, bool noCommon)
static void setLinkageForGV(cir::GlobalOp &gv, const NamedDecl *nd)
static bool verifyPointerTypeArgs(cir::FuncOp oldF, cir::FuncOp newF, mlir::SymbolUserMap &userMap)
static cir::CtorKind getCtorKindFromDecl(const CXXConstructorDecl *ctor)
static void emitUsed(CIRGenModule &cgm, StringRef name, std::vector< cir::CIRGlobalValueInterface > &list)
static cir::GlobalViewAttr createNewGlobalView(CIRGenModule &cgm, cir::GlobalOp newGlob, cir::GlobalViewAttr attr, mlir::Type oldTy)
This file defines OpenACC nodes for declarative directives.
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
Defines the SourceManager interface.
This file defines OpenMP AST classes for executable directives and clauses.
cir::GlobalViewAttr getGlobalViewAttr(cir::GlobalOp globalOp, mlir::ArrayAttr indices={})
Get constant address of a global variable as an MLIR attribute.
cir::PointerType getPointerTo(mlir::Type ty)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
@ Strong
Strong definition.
@ WeakUnknown
Weak for now, might become strong later in this TU.
bool DeclMustBeEmitted(const Decl *D)
Determines if the decl can be CodeGen'ed or deserialized from PCH lazily, only when used; this is onl...
StringRef getCUIDHash() const
void Deallocate(void *Ptr) const
GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const
bool isAlignmentRequired(const Type *T) const
Determine if the alignment the type has was required using an alignment attribute.
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
GVALinkage GetGVALinkageForVariable(const VarDecl *VD) const
unsigned getTypeAlignIfKnown(QualType T, bool NeedsPreferredAlignment=false) const
Return the alignment of a type, in bits, or 0 if the type is incomplete and we cannot determine the a...
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
DiagnosticsEngine & getDiagnostics() const
const TargetInfo & getTargetInfo() const
TargetCXXABI::Kind getCXXABIKind() const
Return the C++ ABI kind that should be used.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
mlir::Attribute getConstRecordOrZeroAttr(mlir::ArrayAttr arrayAttr, bool packed=false, bool padded=false, mlir::Type type={})
uint64_t computeOffsetFromGlobalViewIndices(const cir::CIRDataLayout &layout, mlir::Type ty, llvm::ArrayRef< int64_t > indices)
void computeGlobalViewIndicesFromFlatOffset(int64_t offset, mlir::Type ty, cir::CIRDataLayout layout, llvm::SmallVectorImpl< int64_t > &indices)
cir::ConstArrayAttr getConstArray(mlir::Attribute attrs, cir::ArrayType arrayTy) const
virtual void handleGlobalReplace(cir::GlobalOp oldGV, cir::GlobalOp newGV)
virtual mlir::Operation * getKernelHandle(cir::FuncOp fn, GlobalDecl gd)=0
virtual void finalizeModule()
Perform module finalization: on device side, mark ODR-used device variables as compiler-used.
virtual void internalizeDeviceSideVar(const VarDecl *d, cir::GlobalLinkageKind &linkage)=0
Adjust linkage of shadow variables in host compilation.
virtual void handleVarRegistration(const VarDecl *vd, cir::GlobalOp var)=0
Check whether a variable is a device variable and register it if true.
Implements C++ ABI-specific code generation functions.
virtual mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty)=0
virtual void emitCXXConstructors(const clang::CXXConstructorDecl *d)=0
Emit constructor variants required by this ABI.
virtual void emitCXXDestructors(const clang::CXXDestructorDecl *d)=0
Emit dtor variants required by this ABI.
clang::MangleContext & getMangleContext()
Gets the mangle context.
virtual cir::GlobalLinkageKind getCXXDestructorLinkage(GVALinkage linkage, const CXXDestructorDecl *dtor, CXXDtorType dt) const
llvm::ArrayRef< CanQualType > arguments() const
cir::FuncOp generateCode(clang::GlobalDecl gd, cir::FuncOp fn, cir::FuncType funcType)
void emitVariablyModifiedType(QualType ty)
mlir::Operation * curFn
The current function or global initializer that is generated code for.
This class organizes the cross-function state that is used while generating CIR code.
cir::GlobalOp getAddrOfUnnamedGlobalConstantDecl(const UnnamedGlobalConstantDecl *gcd)
void setGlobalVisibility(cir::CIRGlobalValueInterface gv, const NamedDecl *d) const
Set the visibility for the given global.
void addUsedOrCompilerUsedGlobal(cir::CIRGlobalValueInterface gv)
Add a global to a list to be added to the llvm.compiler.used metadata.
void replaceUsesOfNonProtoTypeWithRealFunction(mlir::Operation *old, cir::FuncOp newFn)
This function is called when we implement a function with no prototype, e.g.
bool shouldEmitFunction(clang::GlobalDecl gd)
Check if fd ends up calling itself directly through asm label or builtin-pointer-to-self trickery (e....
llvm::StringRef getMangledName(clang::GlobalDecl gd)
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *derivedClass, llvm::iterator_range< CastExpr::path_const_iterator > path)
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
void emitDeferred()
Emit any needed decls for which code generation was deferred.
cir::GlobalLinkageKind getCIRLinkageVarDefinition(const VarDecl *vd)
clang::ASTContext & getASTContext() const
void insertGlobalSymbol(mlir::Operation *op)
cir::FuncOp getAddrOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
CIRGenCUDARuntime & getCUDARuntime()
llvm::DenseMap< cir::BlockAddrInfoAttr, cir::LabelOp > blockAddressInfoToLabel
Map BlockAddrInfoAttr (function name, label name) to the corresponding CIR LabelOp.
void emitTopLevelDecl(clang::Decl *decl)
void emitOMPDeclareMapper(const OMPDeclareMapperDecl *d)
void addReplacement(llvm::StringRef name, mlir::Operation *op)
mlir::Type convertType(clang::QualType type)
bool shouldEmitRTTI(bool forEH=false)
cir::GlobalOp getGlobalForStringLiteral(const StringLiteral *s, llvm::StringRef name=".str")
Return a global symbol reference to a constant array for the given string literal.
std::vector< cir::CIRGlobalValueInterface > llvmUsed
List of global values which are required to be present in the object file; This is used for forcing v...
void emitOMPCapturedExpr(const OMPCapturedExprDecl *d)
bool mustBeEmitted(const clang::ValueDecl *d)
Determine whether the definition must be emitted; if this returns false, the definition can be emitte...
void emitGlobalOpenACCDeclareDecl(const clang::OpenACCDeclareDecl *cd)
mlir::IntegerAttr getSize(CharUnits size)
void setGlobalTlsReferences(const VarDecl &vd, cir::GlobalOp globalOp)
CIRGenBuilderTy & getBuilder()
void setDSOLocal(mlir::Operation *op) const
std::string getUniqueGlobalName(const std::string &baseName)
std::pair< cir::FuncType, cir::FuncOp > getAddrAndTypeOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
void setGVProperties(mlir::Operation *op, const NamedDecl *d) const
Set visibility, dllimport/dllexport and dso_local.
cir::GlobalOp getOrCreateCIRGlobal(llvm::StringRef mangledName, mlir::Type ty, LangAS langAS, const VarDecl *d, ForDefinition_t isForDefinition)
If the specified mangled name is not in the module, create and return an mlir::GlobalOp value.
cir::FuncOp createCIRBuiltinFunction(mlir::Location loc, llvm::StringRef name, cir::FuncType ty, const clang::FunctionDecl *fd)
Create a CIR function with builtin attribute set.
cir::GlobalOp getAddrOfTemplateParamObject(const TemplateParamObjectDecl *tpo)
Get the GlobalOp of a template parameter object.
void emitGlobalOpenACCRoutineDecl(const clang::OpenACCRoutineDecl *cd)
clang::CharUnits getClassPointerAlignment(const clang::CXXRecordDecl *rd)
Return the best known alignment for an unknown pointer to a particular class.
void handleCXXStaticMemberVarInstantiation(VarDecl *vd)
Tell the consumer that this variable has been instantiated.
llvm::DenseMap< const UnnamedGlobalConstantDecl *, cir::GlobalOp > unnamedGlobalConstantDeclMap
std::vector< cir::CIRGlobalValueInterface > llvmCompilerUsed
void emitOMPRequiresDecl(const OMPRequiresDecl *d)
void emitGlobalDefinition(clang::GlobalDecl gd, mlir::Operation *op=nullptr)
clang::DiagnosticsEngine & getDiags() const
cir::GlobalLinkageKind getCIRLinkageForDeclarator(const DeclaratorDecl *dd, GVALinkage linkage)
mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty, bool forEH=false)
Get the address of the RTTI descriptor for the given type.
void setFunctionAttributes(GlobalDecl gd, cir::FuncOp f, bool isIncompleteFunction, bool isThunk)
Set function attributes for a function declaration.
static mlir::SymbolTable::Visibility getMLIRVisibilityFromCIRLinkage(cir::GlobalLinkageKind GLK)
const clang::TargetInfo & getTarget() const
void setCIRFunctionAttributes(GlobalDecl gd, const CIRGenFunctionInfo &info, cir::FuncOp func, bool isThunk)
Set the CIR function attributes (Sext, zext, etc).
const llvm::Triple & getTriple() const
static mlir::SymbolTable::Visibility getMLIRVisibility(Visibility v)
void emitTentativeDefinition(const VarDecl *d)
void emitAliasDefinition(GlobalDecl gd)
Emit a definition for an __attribute__((alias)) declaration.
void addUsedGlobal(cir::CIRGlobalValueInterface gv)
Add a global value to the llvmUsed list.
cir::GlobalOp createOrReplaceCXXRuntimeVariable(mlir::Location loc, llvm::StringRef name, mlir::Type ty, cir::GlobalLinkageKind linkage, clang::CharUnits alignment)
Will return a global variable of the given type.
void emitOMPAllocateDecl(const OMPAllocateDecl *d)
void error(SourceLocation loc, llvm::StringRef error)
Emit a general error that something can't be done.
void emitGlobalDecl(const clang::GlobalDecl &d)
Helper for emitDeferred to apply actual codegen.
void emitGlobalVarDefinition(const clang::VarDecl *vd, bool isTentative=false)
cir::FuncOp createRuntimeFunction(cir::FuncType ty, llvm::StringRef name, mlir::NamedAttrList extraAttrs={}, bool isLocal=false, bool assumeConvergent=false)
cir::FuncOp getAddrOfFunction(clang::GlobalDecl gd, mlir::Type funcType=nullptr, bool forVTable=false, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
Return the address of the given function.
void emitAliasForGlobal(llvm::StringRef mangledName, mlir::Operation *op, GlobalDecl aliasGD, cir::FuncOp aliasee, cir::GlobalLinkageKind linkage)
std::optional< llvm::SmallVector< int32_t > > buildMemberPath(const CXXRecordDecl *destClass, const FieldDecl *field)
Build a GEP-style field-index path from destClass to field.
void emitLLVMUsed()
Emit llvm.used and llvm.compiler.used globals.
mlir::Value emitMemberPointerConstant(const UnaryOperator *e)
void emitGlobalOpenACCDecl(const clang::OpenACCConstructDecl *cd)
bool verifyModule() const
void setTLSMode(mlir::Operation *op, const VarDecl &d, bool isExtendingDecl=false)
Set TLS mode for the given operation based on the given variable declaration.
void emitExplicitCastExprType(const ExplicitCastExpr *e, CIRGenFunction *cgf=nullptr)
Emit type info if type of an expression is a variably modified type.
const cir::CIRDataLayout getDataLayout() const
void eraseGlobalSymbol(mlir::Operation *op)
mlir::Operation * getAddrOfGlobalTemporary(const MaterializeTemporaryExpr *mte, const Expr *init)
Returns a pointer to a global variable representing a temporary with static or thread storage duratio...
std::map< llvm::StringRef, clang::GlobalDecl > deferredDecls
This contains all the decls which have definitions but which are deferred for emission and therefore ...
void errorUnsupported(const Stmt *s, llvm::StringRef type)
Print out an error that codegen doesn't support the specified stmt yet.
mlir::Value getAddrOfGlobalVar(const VarDecl *d, mlir::Type ty={}, ForDefinition_t isForDefinition=NotForDefinition)
Return the mlir::Value for the address of the given global variable.
llvm::StringMap< mlir::Operation * > symbolLookupCache
Cache for O(1) symbol lookups by name, replacing the O(N) linear scan in SymbolTable::lookupSymbolIn ...
static void setInitializer(cir::GlobalOp &op, mlir::Attribute value)
cir::GlobalViewAttr getAddrOfGlobalVarAttr(const VarDecl *d)
Return the mlir::GlobalViewAttr for the address of the given global.
void addGlobalCtor(cir::FuncOp ctor, std::optional< int > priority=std::nullopt)
Add a global constructor or destructor to the module.
cir::GlobalLinkageKind getFunctionLinkage(GlobalDecl gd)
void updateCompletedType(const clang::TagDecl *td)
const clang::CodeGenOptions & getCodeGenOpts() const
void emitDeferredVTables()
Emit any vtables which we deferred and still have a use for.
const clang::LangOptions & getLangOpts() const
void printPostfixForExternalizedDecl(llvm::raw_ostream &os, const Decl *d)
Print the postfix for externalized static variable or kernels for single source offloading languages ...
void constructAttributeList(llvm::StringRef name, const CIRGenFunctionInfo &info, CIRGenCalleeInfo calleeInfo, mlir::NamedAttrList &attrs, llvm::MutableArrayRef< mlir::NamedAttrList > argAttrs, mlir::NamedAttrList &retAttrs, cir::CallingConv &callingConv, cir::SideEffect &sideEffect, bool attrOnCallSite, bool isThunk)
Get the CIR attributes and calling convention to use for a particular function type.
cir::FuncOp getOrCreateCIRFunction(llvm::StringRef mangledName, mlir::Type funcType, clang::GlobalDecl gd, bool forVTable, bool dontDefer=false, bool isThunk=false, ForDefinition_t isForDefinition=NotForDefinition, mlir::NamedAttrList extraAttrs={})
void emitOpenACCRoutineDecl(const clang::FunctionDecl *funcDecl, cir::FuncOp func, SourceLocation pragmaLoc, ArrayRef< const OpenACCClause * > clauses)
void emitVTablesOpportunistically()
Try to emit external vtables as available_externally if they have emitted all inlined virtual functio...
cir::GlobalOp createGlobalOp(mlir::Location loc, llvm::StringRef name, mlir::Type t, bool isConstant=false, mlir::ptr::MemorySpaceAttrInterface addrSpace={}, mlir::Operation *insertPoint=nullptr)
cir::TLS_Model getDefaultCIRTLSModel() const
Get TLS mode from CodeGenOptions.
void addGlobalDtor(cir::FuncOp dtor, std::optional< int > priority=std::nullopt)
Add a function to the list that will be called when the module is unloaded.
void addDeferredDeclToEmit(clang::GlobalDecl GD)
bool shouldEmitCUDAGlobalVar(const VarDecl *global) const
cir::FuncOp createCIRFunction(mlir::Location loc, llvm::StringRef name, cir::FuncType funcType, const clang::FunctionDecl *funcDecl)
const TargetCIRGenInfo & getTargetCIRGenInfo()
void emitCXXGlobalVarDeclInitFunc(const VarDecl *vd, cir::GlobalOp addr, bool performInit)
static cir::VisibilityKind getCIRVisibilityKind(Visibility v)
void setGVPropertiesAux(mlir::Operation *op, const NamedDecl *d) const
LangAS getLangTempAllocaAddressSpace() const
Returns the address space for temporary allocations in the language.
mlir::Location getLoc(clang::SourceLocation cLoc)
Helpers to convert the presumed location of Clang's SourceLocation to an MLIR Location.
llvm::DenseMap< mlir::Attribute, cir::GlobalOp > constantStringMap
mlir::Operation * lastGlobalOp
void replaceGlobal(cir::GlobalOp oldGV, cir::GlobalOp newGV)
Replace all uses of the old global with the new global, updating types and references as needed.
static cir::VisibilityKind getGlobalVisibilityKindFromClangVisibility(clang::VisibilityAttr::VisibilityType visibility)
llvm::StringMap< unsigned > cgGlobalNames
void setCXXSpecialMemberAttr(cir::FuncOp funcOp, const clang::FunctionDecl *funcDecl)
Mark the function as a special member (e.g. constructor, destructor)
mlir::TypedAttr emitNullMemberAttr(QualType t, const MemberPointerType *mpt)
Returns a null attribute to represent either a null method or null data member, depending on the type...
mlir::Operation * getGlobalValue(llvm::StringRef ref)
void emitOMPDeclareReduction(const OMPDeclareReductionDecl *d)
mlir::ModuleOp getModule() const
bool supportsCOMDAT() const
void addCompilerUsedGlobal(cir::CIRGlobalValueInterface gv)
Add a global value to the llvmCompilerUsed list.
clang::CharUnits getNaturalTypeAlignment(clang::QualType t, LValueBaseInfo *baseInfo=nullptr, bool forPointeeType=false)
FIXME: this could likely be a common helper and not necessarily related with codegen.
mlir::MLIRContext & getMLIRContext()
mlir::Operation * getAddrOfGlobal(clang::GlobalDecl gd, ForDefinition_t isForDefinition=NotForDefinition)
void maybeSetTrivialComdat(const clang::Decl &d, mlir::Operation *op)
CIRGenCXXABI & getCXXABI() const
cir::GlobalViewAttr getAddrOfConstantStringFromLiteral(const StringLiteral *s, llvm::StringRef name=".str")
Return a global symbol reference to a constant array for the given string literal.
bool lookupRepresentativeDecl(llvm::StringRef mangledName, clang::GlobalDecl &gd) const
void emitDeclContext(const DeclContext *dc)
clang::CharUnits getNaturalPointeeTypeAlignment(clang::QualType t, LValueBaseInfo *baseInfo=nullptr)
void emitGlobal(clang::GlobalDecl gd)
Emit code for a single global function or variable declaration.
cir::LabelOp lookupBlockAddressInfo(cir::BlockAddrInfoAttr blockInfo)
bool mayBeEmittedEagerly(const clang::ValueDecl *d)
Determine whether the definition can be emitted eagerly, or should be delayed until the end of the tr...
void mapBlockAddress(cir::BlockAddrInfoAttr blockInfo, cir::LabelOp label)
void addGlobalAnnotations(const clang::ValueDecl *d, mlir::Operation *gv)
Add global annotations for a global value (GlobalOp or FuncOp).
void setCIRFunctionAttributesForDefinition(const clang::FunctionDecl *fd, cir::FuncOp f)
Set extra attributes (inline, etc.) for a function.
std::string getOpenACCBindMangledName(const IdentifierInfo *bindName, const FunctionDecl *attachedFunction)
void emitGlobalFunctionDefinition(clang::GlobalDecl gd, mlir::Operation *op)
CIRGenVTables & getVTables()
void setFunctionLinkage(GlobalDecl gd, cir::FuncOp f)
std::vector< clang::GlobalDecl > deferredDeclsToEmit
void emitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *d)
CIRGenOpenMPRuntime & getOpenMPRuntime()
void emitAMDGPUMetadata()
Emits AMDGPU specific Metadata.
void emitOMPGroupPrivateDecl(const OMPGroupPrivateDecl *d)
mlir::Attribute getConstantArrayFromStringLiteral(const StringLiteral *e)
Return a constant array for the given string.
cir::VisibilityAttr getGlobalVisibilityAttrFromDecl(const Decl *decl)
void setCommonAttributes(GlobalDecl gd, mlir::Operation *op)
Set attributes which are common to any form of a global definition (alias, Objective-C method,...
void emitDeclareTargetFunction(const FunctionDecl *fd, cir::FuncOp funcOp)
If the function has an OMPDeclareTargetDeclAttr, set the corresponding omp.declare_target attribute o...
This class handles record and union layout info while lowering AST types to CIR types.
bool hasNonVirtualBaseCIRField(const CXXRecordDecl *rd) const
unsigned getCIRFieldNo(const clang::FieldDecl *fd) const
Return cir::RecordType element number that corresponds to the field FD.
bool isZeroInitializable() const
Check whether this struct can be C++ zero-initialized with a zeroinitializer.
unsigned getNonVirtualBaseCIRFieldNo(const CXXRecordDecl *rd) const
const CIRGenFunctionInfo & arrangeGlobalDeclaration(GlobalDecl gd)
const CIRGenFunctionInfo & arrangeCXXMethodDeclaration(const clang::CXXMethodDecl *md)
C++ methods have some special rules and also have implicit parameters.
const CIRGenFunctionInfo & arrangeCXXStructorDeclaration(clang::GlobalDecl gd)
cir::FuncType getFunctionType(const CIRGenFunctionInfo &info)
Get the CIR function type for.
const CIRGenRecordLayout & getCIRGenRecordLayout(const clang::RecordDecl *rd)
Return record layout info for the given record decl.
mlir::Type convertTypeForMem(clang::QualType, bool forBitField=false)
Convert type T into an mlir::Type.
void emitThunks(GlobalDecl gd)
Emit the associated thunks for the given global decl.
void finalize(cir::GlobalOp gv)
mlir::Attribute emitForInitializer(const APValue &value, QualType destType)
virtual clang::LangAS getGlobalVarAddressSpace(CIRGenModule &cgm, const clang::VarDecl *d) const
Get target favored AST address space of a global variable for languages other than OpenCL and CUDA.
virtual mlir::ptr::MemorySpaceAttrInterface getCIRAllocaAddressSpace() const
Get the address space for alloca.
virtual void setTargetAttributes(const clang::Decl *decl, mlir::Operation *global, CIRGenModule &module) const
Provides a convenient hook to handle extra target-specific attributes for the given global.
Represents a base class of a C++ class.
Represents a C++ constructor within a class.
bool isMoveConstructor(unsigned &TypeQuals) const
Determine whether this constructor is a move constructor (C++11 [class.copy]p3), which can be used to...
bool isCopyConstructor(unsigned &TypeQuals) const
Whether this constructor is a copy constructor (C++ [class.copy]p2, which can be used to copy the cla...
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
Represents a static or instance method of a struct/union/class.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
Represents a C++ struct/union/class.
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
bool hasDefinition() const
CharUnits - This is an opaque type for sizes expressed in character units.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
llvm::Reloc::Model RelocationModel
The name of the relocation model to use.
Represents the canonical version of C arrays with a specified constant size.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Decl - This represents one declaration (or definition), e.g.
bool 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.
Cached information about one file (either on disk or in the virtual file system).
StringRef tryGetRealPathName() const
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Represents a function declaration or definition.
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin=false, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=ConstexprSpecKind::Unspecified, const AssociatedConstraint &TrailingRequiresClause={})
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
FunctionDecl * getDefinition()
Get the definition for this declaration.
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
FunctionType - C99 6.7.5.3 - Function Declarators.
CallingConv getCallConv() const
GlobalDecl - represents a global declaration.
CXXCtorType getCtorType() const
GlobalDecl getCanonicalDecl() const
KernelReferenceKind getKernelReferenceKind() const
GlobalDecl getWithDecl(const Decl *D)
unsigned getMultiVersionIndex() const
CXXDtorType getDtorType() const
const Decl * getDecl() const
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
std::string CUID
The user provided compilation unit ID, if non-empty.
Visibility getVisibility() const
void setLinkage(Linkage L)
Linkage getLinkage() const
bool isVisibilityExplicit() const
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
bool isTriviallyRecursive(const FunctionDecl *FD)
Return true if FD's body contains a direct call back to the symbol it links as, through an asm label ...
bool shouldMangleDeclName(const NamedDecl *D)
void mangleName(GlobalDecl GD, raw_ostream &)
virtual void mangleReferenceTemporary(const VarDecl *D, unsigned ManglingNumber, raw_ostream &)=0
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
APValue * getOrCreateValue(bool MayCreate) const
Get the storage for the constant value of a materialized temporary of static storage duration.
ValueDecl * getExtendingDecl()
Get the declaration which triggered the lifetime-extension of this temporary, if any.
unsigned getManglingNumber() const
A pointer to member type per C++ 8.3.3 - Pointers to members.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
LinkageInfo getLinkageAndVisibility() const
Determines the linkage and visibility of this entity.
bool hasUnwindExceptions() const
Does this runtime use zero-cost exceptions?
Represents a parameter to a function.
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
A (possibly-)qualified type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
bool isConstQualified() const
Determine whether this type is const-qualified.
bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor, bool ExcludeDtor)
bool hasUnaligned() const
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getLength() const
uint32_t getCodeUnit(size_t i) const
StringRef getString() const
unsigned getCharByteWidth() const
Represents the declaration of a struct/union/class/enum.
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
TargetOptions & getTargetOpts() const
Retrieve the target options.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
bool isReadOnlyFeature(StringRef Feature) const
Determine whether the given target feature is read only.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
virtual ParsedTargetAttr parseTargetAttr(StringRef Str) const
virtual bool initFeatureMap(llvm::StringMap< bool > &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector< std::string > &FeatureVec) const
Initialize the map with the default set of target features for the CPU this should include all legal ...
std::vector< std::string > Features
The list of target specific features to enable or disable – this should be a list of strings starting...
std::string TuneCPU
If given, the name of the target CPU to tune code for.
std::string CPU
If given, the name of the target CPU to generate code for.
A template parameter object.
const APValue & getValue() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isCUDADeviceBuiltinSurfaceType() const
Check if the type is the CUDA device builtin surface type.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isCUDADeviceBuiltinTextureType() const
Check if the type is the CUDA device builtin texture type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isObjCObjectPointerType() const
bool isMemberFunctionPointerType() const
const T * getAs() const
Member-template getAs<specific type>'.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
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)
CIRGenCUDARuntime * createNVCUDARuntime(CIRGenModule &cgm)
const internal::VariadicDynCastAllOfMatcher< Decl, VarDecl > varDecl
Matches variable declarations.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, FieldDecl > fieldDecl
Matches field declarations.
const internal::VariadicDynCastAllOfMatcher< Decl, FunctionDecl > functionDecl
Matches function declarations.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
GVALinkage
A more specific kind of linkage than enum Linkage.
@ GVA_AvailableExternally
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ SD_Thread
Thread storage duration.
@ SD_Static
Static storage duration.
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Dtor_Complete
Complete object dtor.
LangAS
Defines the address space values used by the address space qualifier of QualType.
@ FirstTargetAddressSpace
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
U cast(CodeGen::Address addr)
bool isExternallyVisible(Linkage L)
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 int32_t
static bool globalCtorLexOrder()
static bool opFuncArmNewAttr()
static bool getRuntimeFunctionDecl()
static bool weakRefReference()
static bool opFuncOptNoneAttr()
static bool addressSpace()
static bool opFuncMinSizeAttr()
static bool opGlobalUnnamedAddr()
static bool opGlobalThreadLocal()
static bool opFuncMultiVersioning()
static bool sourceLanguageCases()
static bool noUniqueAddressLayout()
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.