19#include "mlir/Dialect/OpenMP/OpenMPOffloadUtils.h"
20#include "mlir/IR/SymbolTable.h"
23#include "clang/AST/Attrs.inc"
37#include "llvm/ADT/StringExtras.h"
38#include "llvm/ADT/StringRef.h"
42#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
43#include "mlir/IR/Attributes.h"
44#include "mlir/IR/BuiltinOps.h"
45#include "mlir/IR/Location.h"
46#include "mlir/IR/MLIRContext.h"
47#include "mlir/IR/Operation.h"
48#include "mlir/IR/Verifier.h"
57 case TargetCXXABI::GenericItanium:
58 case TargetCXXABI::GenericAArch64:
59 case TargetCXXABI::AppleARM64:
60 case TargetCXXABI::GenericARM:
63 case TargetCXXABI::Fuchsia:
64 case TargetCXXABI::iOS:
65 case TargetCXXABI::WatchOS:
66 case TargetCXXABI::GenericMIPS:
67 case TargetCXXABI::WebAssembly:
68 case TargetCXXABI::XL:
69 case TargetCXXABI::Microsoft:
70 cgm.
errorNYI(
"createCXXABI: C++ ABI kind");
74 llvm_unreachable(
"invalid C++ ABI kind");
77CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
81 : builder(mlirContext, *this), astContext(astContext),
82 langOpts(astContext.
getLangOpts()), codeGenOpts(cgo),
83 theModule{
mlir::ModuleOp::create(
mlir::UnknownLoc::get(&mlirContext))},
84 diags(diags), target(astContext.getTargetInfo()),
85 abi(
createCXXABI(*this)), genTypes(*this), vtables(*this) {
113 .toCharUnitsFromBits(
117 const unsigned charSize = astContext.getTargetInfo().getCharWidth();
121 const unsigned sizeTypeSize =
122 astContext.getTypeSize(astContext.getSignedSizeType());
123 SizeSizeInBytes = astContext.toCharUnitsFromBits(sizeTypeSize).getQuantity();
130 std::optional<cir::SourceLanguage> sourceLanguage = getCIRSourceLanguage();
133 cir::CIRDialect::getSourceLanguageAttrName(),
134 cir::SourceLanguageAttr::get(&mlirContext, *sourceLanguage));
135 theModule->setAttr(cir::CIRDialect::getTripleAttrName(),
136 builder.getStringAttr(
getTriple().str()));
138 if (cgo.OptimizationLevel > 0 || cgo.OptimizeSize > 0)
139 theModule->setAttr(cir::CIRDialect::getOptInfoAttrName(),
140 cir::OptInfoAttr::get(&mlirContext,
141 cgo.OptimizationLevel,
144 if (langOpts.OpenMP) {
145 mlir::omp::OffloadModuleOpts ompOpts(
146 langOpts.OpenMPTargetDebug, langOpts.OpenMPTeamSubscription,
147 langOpts.OpenMPThreadSubscription, langOpts.OpenMPNoThreadState,
148 langOpts.OpenMPNoNestedParallelism, langOpts.OpenMPIsTargetDevice,
149 getTriple().isGPU(), langOpts.OpenMPForceUSM, langOpts.OpenMP,
150 langOpts.OMPHostIRFile, langOpts.OMPTargetTriples, langOpts.NoGPULib);
151 mlir::omp::setOffloadModuleInterfaceAttributes(theModule, ompOpts);
157 createOpenMPRuntime();
162 FileID mainFileId = astContext.getSourceManager().getMainFileID();
164 *astContext.getSourceManager().getFileEntryForID(mainFileId);
167 theModule.setSymName(path);
168 theModule->setLoc(mlir::FileLineColLoc::get(&mlirContext, path,
175 llvm::StringRef cudaBinaryName = codeGenOpts.CudaGpuBinaryFileName;
176 if (!cudaBinaryName.empty()) {
177 theModule->setAttr(cir::CIRDialect::getCUDABinaryHandleAttrName(),
178 cir::CUDABinaryHandleAttr::get(
179 &mlirContext, mlir::StringAttr::get(
180 &mlirContext, cudaBinaryName)));
187void CIRGenModule::createCUDARuntime() {
191void CIRGenModule::createOpenMPRuntime() {
192 openMPRuntime = std::make_unique<CIRGenOpenMPRuntime>(*
this);
203 auto &layout = astContext.getASTRecordLayout(rd);
208 return layout.getAlignment();
211 return layout.getNonVirtualAlignment();
216 bool forPointeeType) {
226 if (
unsigned align = tt->getDecl()->getMaxAlignment()) {
229 return astContext.toCharUnitsFromBits(align);
237 t = astContext.getBaseElementType(t);
258 }
else if (forPointeeType && !alignForArray &&
262 alignment = astContext.getTypeAlignInChars(t);
267 if (
unsigned maxAlign = astContext.getLangOpts().MaxTypeAlign) {
269 !astContext.isAlignmentRequired(t))
283 if (theTargetCIRGenInfo)
284 return *theTargetCIRGenInfo;
287 switch (triple.getArch()) {
294 case llvm::Triple::x86_64: {
295 switch (triple.getOS()) {
302 case llvm::Triple::Linux:
304 return *theTargetCIRGenInfo;
307 case llvm::Triple::nvptx:
308 case llvm::Triple::nvptx64:
310 return *theTargetCIRGenInfo;
311 case llvm::Triple::amdgcn: {
313 return *theTargetCIRGenInfo;
319 assert(cLoc.
isValid() &&
"expected valid source location");
323 return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
328 assert(cRange.
isValid() &&
"expected a valid source range");
331 mlir::Attribute metadata;
332 return mlir::FusedLoc::get({begin, end}, metadata, builder.getContext());
341 false, isForDefinition);
375 assert(op &&
"expected a valid global op");
383 mlir::Operation *globalValueOp = op;
384 if (
auto gv = dyn_cast<cir::GetGlobalOp>(op)) {
386 assert(globalValueOp &&
"expected a valid global op");
389 if (
auto cirGlobalValue =
390 dyn_cast<cir::CIRGlobalValueInterface>(globalValueOp))
391 if (!cirGlobalValue.isDeclaration())
412 assert(deferredVTables.empty());
422 std::vector<GlobalDecl> curDeclsToEmit;
441 if (
auto *
attr =
decl->getAttr<AttrT>())
442 return attr->isImplicit();
443 return decl->isImplicit();
448 assert(langOpts.CUDA &&
"Should not be called by non-CUDA languages");
453 return !langOpts.CUDAIsDevice || global->
hasAttr<CUDADeviceAttr>() ||
454 global->
hasAttr<CUDAConstantAttr>() ||
455 global->
hasAttr<CUDASharedAttr>() ||
461 if (
const auto *cd = dyn_cast<clang::OpenACCConstructDecl>(gd.
getDecl())) {
469 if (global->hasAttr<WeakRefAttr>())
474 if (global->hasAttr<AliasAttr>()) {
487 "Expected Variable or Function");
488 if (
const auto *
varDecl = dyn_cast<VarDecl>(global)) {
492 }
else if (langOpts.CUDAIsDevice) {
493 const auto *
functionDecl = dyn_cast<FunctionDecl>(global);
494 if ((!global->hasAttr<CUDADeviceAttr>() ||
495 (langOpts.OffloadImplicitHostDeviceTemplates &&
500 !
getASTContext().CUDAImplicitHostDeviceFunUsedByDevice.count(
502 !global->hasAttr<CUDAGlobalAttr>() &&
504 !global->hasAttr<CUDAHostAttr>()))
507 }
else if (!global->hasAttr<CUDAHostAttr>() &&
508 global->hasAttr<CUDADeviceAttr>())
512 if (langOpts.OpenMP) {
514 if (openMPRuntime && openMPRuntime->emitTargetGlobal(gd))
516 if (
auto *drd = dyn_cast<OMPDeclareReductionDecl>(global)) {
521 if (
auto *dmd = dyn_cast<OMPDeclareMapperDecl>(global)) {
528 if (
const auto *fd = dyn_cast<FunctionDecl>(global)) {
531 if (fd->hasAttr<AnnotateAttr>()) {
534 deferredAnnotations[mangledName] = fd;
536 if (!fd->doesThisDeclarationHaveABody()) {
537 if (!fd->doesDeclarationForceExternallyVisibleDefinition())
541 "function declaration that forces code gen");
546 assert(vd->isFileVarDecl() &&
"Cannot emit local var decl as global.");
548 !astContext.isMSStaticDataMemberInlineDefinition(vd)) {
552 if (astContext.getInlineVariableDefinitionKind(vd) ==
591 mlir::Operation *op) {
595 cir::FuncOp funcOp = dyn_cast_if_present<cir::FuncOp>(op);
596 if (!funcOp || funcOp.getFunctionType() != funcType) {
602 if (!funcOp.isDeclaration())
614 mlir::OpBuilder::InsertionGuard guard(builder);
619 setNonAliasAttributes(gd, funcOp);
622 auto getPriority = [
this](
const auto *
attr) ->
int {
626 return attr->DefaultPriority;
629 if (
const ConstructorAttr *ca = funcDecl->getAttr<ConstructorAttr>())
631 if (
const DestructorAttr *da = funcDecl->getAttr<DestructorAttr>())
634 if (funcDecl->getAttr<AnnotateAttr>())
637 if (
getLangOpts().OpenMP && funcDecl->hasAttr<OMPDeclareTargetDeclAttr>())
643 std::optional<int> priority) {
652 ctor.setGlobalCtorPriority(priority);
657 std::optional<int> priority) {
658 if (codeGenOpts.RegisterGlobalDtorsWithAtExit &&
660 errorNYI(dtor.getLoc(),
"registerGlobalDtorsWithAtExit");
663 dtor.setGlobalDtorPriority(priority);
688 mlir::ptr::MemorySpaceAttrInterface addrSpace,
689 mlir::Operation *insertPoint) {
694 mlir::OpBuilder::InsertionGuard guard(builder);
700 builder.setInsertionPoint(insertPoint);
706 builder.setInsertionPointToStart(
getModule().getBody());
709 g = cir::GlobalOp::create(builder, loc, name, t, isConstant, addrSpace);
715 mlir::SymbolTable::setSymbolVisibility(
716 g, mlir::SymbolTable::Visibility::Private);
724 if (isa_and_nonnull<NamedDecl>(d))
728 if (
auto gvi = mlir::dyn_cast<cir::CIRGlobalValueInterface>(gv)) {
729 if (d && d->
hasAttr<UsedAttr>())
732 if (
const auto *vd = dyn_cast_if_present<VarDecl>(d);
733 vd && ((codeGenOpts.KeepPersistentStorageVariables &&
734 (vd->getStorageDuration() ==
SD_Static ||
735 vd->getStorageDuration() ==
SD_Thread)) ||
736 (codeGenOpts.KeepStaticConsts &&
738 vd->getType().isConstQualified())))
744static std::vector<std::string>
746 llvm::StringMap<bool> &featureMap) {
747 llvm::StringMap<bool> defaultFeatureMap;
751 std::vector<std::string> delta;
752 for (
const auto &[k, v] : featureMap) {
753 auto defaultIt = defaultFeatureMap.find(k);
754 if (defaultIt == defaultFeatureMap.end() || defaultIt->getValue() != v)
755 delta.push_back((v ?
"+" :
"-") + k.str());
761bool CIRGenModule::getCPUAndFeaturesAttributes(
762 GlobalDecl gd, llvm::StringMap<std::string> &attrs,
763 bool setTargetFeatures) {
769 std::vector<std::string> features;
773 const auto *fd = dyn_cast_or_null<FunctionDecl>(gd.
getDecl());
774 fd = fd ? fd->getMostRecentDecl() : fd;
775 const auto *td = fd ? fd->getAttr<TargetAttr>() :
nullptr;
776 const auto *tv = fd ? fd->getAttr<TargetVersionAttr>() :
nullptr;
777 assert((!td || !tv) &&
"both target_version and target specified");
778 const auto *sd = fd ? fd->getAttr<CPUSpecificAttr>() :
nullptr;
779 const auto *tc = fd ? fd->getAttr<TargetClonesAttr>() :
nullptr;
780 bool addedAttr =
false;
781 if (td || tv || sd || tc) {
786 llvm::StringMap<bool> featureMap;
788 astContext.getFunctionFeatureMap(featureMap, gd);
799 if (!targetCPU.empty()) {
800 attrs[
"cir.target-cpu"] = targetCPU.str();
803 if (!tuneCPU.empty()) {
804 attrs[
"cir.tune-cpu"] = tuneCPU.str();
807 if (!features.empty() && setTargetFeatures) {
808 llvm::erase_if(features, [&](
const std::string &f) {
809 assert(!f.empty() && (f[0] ==
'+' || f[0] ==
'-') &&
810 "feature string must start with '+' or '-'");
813 llvm::sort(features);
814 attrs[
"cir.target-features"] = llvm::join(features,
",");
822void CIRGenModule::setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op) {
827 if (
auto gvi = mlir::dyn_cast<cir::CIRGlobalValueInterface>(op)) {
828 if (
const auto *sa = d->
getAttr<SectionAttr>())
829 gvi.setSection(builder.getStringAttr(sa->getName()));
833 if (
auto func = dyn_cast<cir::FuncOp>(op)) {
834 llvm::StringMap<std::string> attrs;
835 if (getCPUAndFeaturesAttributes(gd, attrs)) {
839 for (
const auto &[key, val] : attrs)
840 func->setAttr(key, builder.getStringAttr(val));
850std::optional<cir::SourceLanguage> CIRGenModule::getCIRSourceLanguage()
const {
851 using ClangStd = clang::LangStandard;
852 using CIRLang = cir::SourceLanguage;
857 if (opts.C99 || opts.C11 || opts.C17 || opts.C23 || opts.C2y ||
858 opts.LangStd == ClangStd::lang_c89 ||
859 opts.LangStd == ClangStd::lang_gnu89)
864 errorNYI(
"CIR does not yet support the given source language");
868LangAS CIRGenModule::getGlobalVarAddressSpace(
const VarDecl *d) {
869 if (langOpts.OpenCL) {
877 if (langOpts.SYCLIsDevice &&
879 errorNYI(
"SYCL global address space");
881 if (langOpts.CUDA && langOpts.CUDAIsDevice) {
883 if (d->
hasAttr<CUDAConstantAttr>())
885 if (d->
hasAttr<CUDASharedAttr>())
887 if (d->
hasAttr<CUDADeviceAttr>())
896 errorNYI(
"OpenMP global address space");
909 gv.
setLinkage(cir::GlobalLinkageKind::ExternalWeakLinkage);
914 for (mlir::Attribute i : indexes) {
915 auto ind = mlir::cast<mlir::IntegerAttr>(i);
916 inds.push_back(ind.getValue().getSExtValue());
922 return view.getSymbol().getValue() == glob.getSymName();
926 cir::GlobalOp newGlob,
927 cir::GlobalViewAttr
attr,
938 mlir::Type newTy = newGlob.getSymType();
943 cir::PointerType newPtrTy;
946 newPtrTy = cir::PointerType::get(newTy);
955 cgm.
errorNYI(
"Unhandled type in createNewGlobalView");
961 mlir::Attribute oldInit) {
962 if (
auto oldView = mlir::dyn_cast<cir::GlobalViewAttr>(oldInit))
965 auto getNewInitElements =
966 [&](mlir::ArrayAttr oldElements) -> mlir::ArrayAttr {
968 for (mlir::Attribute elt : oldElements) {
969 if (
auto view = mlir::dyn_cast<cir::GlobalViewAttr>(elt))
971 else if (mlir::isa<cir::ConstArrayAttr, cir::ConstRecordAttr>(elt))
974 newElements.push_back(elt);
976 return mlir::ArrayAttr::get(cgm.
getBuilder().getContext(), newElements);
979 if (
auto oldArray = mlir::dyn_cast<cir::ConstArrayAttr>(oldInit)) {
980 mlir::Attribute newElements =
981 getNewInitElements(mlir::cast<mlir::ArrayAttr>(oldArray.getElts()));
983 newElements, mlir::cast<cir::ArrayType>(oldArray.getType()));
985 if (
auto oldRecord = mlir::dyn_cast<cir::ConstRecordAttr>(oldInit)) {
986 mlir::ArrayAttr newMembers = getNewInitElements(oldRecord.getMembers());
987 auto recordTy = mlir::cast<cir::RecordType>(oldRecord.getType());
989 newMembers, recordTy.getPacked(), recordTy.getPadded(), recordTy);
994 cgm.
errorNYI(
"Unhandled type in getNewInitValue");
1002 assert(oldGV.getSymName() == newGV.getSymName() &&
"symbol names must match");
1004 mlir::Type oldTy = oldGV.getSymType();
1005 mlir::Type newTy = newGV.getSymType();
1010 assert(oldTy != newTy &&
"expected type change in replaceGlobal");
1013 std::optional<mlir::SymbolTable::UseRange> oldSymUses =
1014 oldGV.getSymbolUses(theModule);
1015 for (mlir::SymbolTable::SymbolUse use : *oldSymUses) {
1016 mlir::Operation *userOp = use.getUser();
1018 (mlir::isa<cir::GetGlobalOp, cir::GlobalOp, cir::ConstantOp>(userOp)) &&
1019 "Unexpected user for global op");
1021 if (
auto getGlobalOp = dyn_cast<cir::GetGlobalOp>(use.getUser())) {
1022 mlir::Value useOpResultValue = getGlobalOp.getAddr();
1023 useOpResultValue.setType(cir::PointerType::get(newTy));
1025 mlir::OpBuilder::InsertionGuard guard(builder);
1026 builder.setInsertionPointAfter(getGlobalOp);
1027 mlir::Type ptrTy = builder.getPointerTo(oldTy);
1029 builder.createBitcast(getGlobalOp->getLoc(), useOpResultValue, ptrTy);
1030 useOpResultValue.replaceAllUsesExcept(
cast,
cast.getDefiningOp());
1031 }
else if (
auto glob = dyn_cast<cir::GlobalOp>(userOp)) {
1032 if (
auto init = glob.getInitialValue()) {
1033 mlir::Attribute nw =
getNewInitValue(*
this, newGV, oldTy, init.value());
1034 glob.setInitialValueAttr(nw);
1036 }
else if (
auto c = dyn_cast<cir::ConstantOp>(userOp)) {
1038 auto typedAttr = mlir::cast<mlir::TypedAttr>(init);
1039 mlir::OpBuilder::InsertionGuard guard(builder);
1040 builder.setInsertionPointAfter(
c);
1041 auto newUser = cir::ConstantOp::create(builder,
c.getLoc(), typedAttr);
1042 c.replaceAllUsesWith(newUser.getOperation());
1076 cir::GlobalOp entry;
1080 "getOrCreateCIRGlobal: global with non-GlobalOp type");
1085 mlir::ptr::MemorySpaceAttrInterface entryCIRAS = entry.getAddrSpaceAttr();
1091 if (entry.getSymType() == ty &&
1101 if (isForDefinition && !entry.isDeclaration()) {
1103 "getOrCreateCIRGlobal: global with conflicting type");
1111 if (!isForDefinition)
1120 bool isConstant =
false;
1125 astContext,
true, !needsDtor);
1128 mlir::ptr::MemorySpaceAttrInterface declCIRAS =
1133 cir::GlobalOp gv =
createGlobalOp(loc, mangledName, ty, isConstant, declCIRAS,
1134 entry.getOperation());
1154 if (langOpts.OpenMP && !langOpts.OpenMPSimd)
1156 "getOrCreateCIRGlobal: OpenMP target global variable");
1158 gv.setAlignmentAttr(
getSize(astContext.getDeclAlign(d)));
1169 if (astContext.isMSStaticDataMemberInlineDefinition(d))
1171 "getOrCreateCIRGlobal: MS static data member inline definition");
1175 if (
const SectionAttr *sa = d->
getAttr<SectionAttr>())
1176 gv.setSectionAttr(builder.getStringAttr(sa->getName()));
1181 if (
getTriple().getArch() == llvm::Triple::xcore)
1183 "getOrCreateCIRGlobal: XCore specific ABI requirements");
1193 "getOrCreateCIRGlobal: external const declaration with initializer");
1205 "getOrCreateCIRGlobal: HIP managed attribute");
1240 mlir::Type ptrTy = builder.getPointerTo(g.getSymType(), g.getAddrSpaceAttr());
1241 return cir::GetGlobalOp::create(
1244 g.getStaticLocalGuard().has_value());
1252 cir::PointerType ptrTy =
1253 builder.getPointerTo(globalOp.getSymType(), globalOp.getAddrSpaceAttr());
1254 return builder.getGlobalViewAttr(ptrTy, globalOp);
1258 assert((mlir::isa<cir::FuncOp>(gv.getOperation()) ||
1259 !gv.isDeclarationForLinker()) &&
1260 "Only globals with definition can force usage.");
1265 assert(!gv.isDeclarationForLinker() &&
1266 "Only globals with definition can force usage.");
1271 cir::CIRGlobalValueInterface gv) {
1272 assert((mlir::isa<cir::FuncOp>(gv.getOperation()) ||
1273 !gv.isDeclarationForLinker()) &&
1274 "Only globals with definition can force usage.");
1282 std::vector<cir::CIRGlobalValueInterface> &list) {
1287 mlir::Location loc = builder.getUnknownLoc();
1289 usedArray.resize(list.size());
1290 for (
auto [i, op] : llvm::enumerate(list)) {
1291 usedArray[i] = cir::GlobalViewAttr::get(
1292 cgm.
voidPtrTy, mlir::FlatSymbolRefAttr::get(op.getNameAttr()));
1295 cir::ArrayType arrayTy = cir::ArrayType::get(cgm.
voidPtrTy, usedArray.size());
1297 cir::ConstArrayAttr initAttr = cir::ConstArrayAttr::get(
1298 arrayTy, mlir::ArrayAttr::get(&cgm.
getMLIRContext(), usedArray));
1302 gv.setLinkage(cir::GlobalLinkageKind::AppendingLinkage);
1303 gv.setInitialValueAttr(initAttr);
1304 gv.setSectionAttr(builder.getStringAttr(
"llvm.metadata"));
1316 "emitGlobalVarDefinition: emit OpenCL/OpenMP global variable");
1323 bool isDefinitionAvailableExternally =
1328 if (isDefinitionAvailableExternally &&
1336 mlir::Attribute init;
1337 bool needsGlobalCtor =
false;
1338 bool needsGlobalDtor =
1339 !isDefinitionAvailableExternally &&
1344 std::optional<ConstantEmitter> emitter;
1349 bool isCUDASharedVar =
1354 bool isCUDAShadowVar =
1356 (vd->
hasAttr<CUDAConstantAttr>() || vd->
hasAttr<CUDADeviceAttr>() ||
1357 vd->
hasAttr<CUDASharedAttr>());
1358 bool isCUDADeviceShadowVar =
1364 (isCUDASharedVar || isCUDAShadowVar || isCUDADeviceShadowVar)) {
1366 }
else if (vd->
hasAttr<LoaderUninitializedAttr>()) {
1368 "emitGlobalVarDefinition: loader uninitialized attribute");
1369 }
else if (!initExpr) {
1382 emitter.emplace(*
this);
1383 mlir::Attribute initializer = emitter->tryEmitForInitializer(*initDecl);
1392 "emitGlobalVarDefinition: flexible array initializer");
1394 if (!isDefinitionAvailableExternally)
1395 needsGlobalCtor =
true;
1398 "emitGlobalVarDefinition: static initializer");
1409 mlir::Type initType;
1410 if (mlir::isa<mlir::SymbolRefAttr>(init)) {
1413 "emitGlobalVarDefinition: global initializer is a symbol reference");
1416 assert(mlir::isa<mlir::TypedAttr>(init) &&
"This should have a type");
1417 auto typedInitAttr = mlir::cast<mlir::TypedAttr>(init);
1418 initType = typedInitAttr.getType();
1420 assert(!mlir::isa<mlir::NoneType>(initType) &&
"Should have a type by now");
1426 if (!gv || gv.getSymType() != initType) {
1428 "emitGlobalVarDefinition: global initializer with type mismatch");
1434 if (vd->
hasAttr<AnnotateAttr>())
1447 if (langOpts.CUDA) {
1448 if (langOpts.CUDAIsDevice) {
1451 if (linkage != cir::GlobalLinkageKind::InternalLinkage &&
1453 (vd->
hasAttr<CUDADeviceAttr>() || vd->
hasAttr<CUDAConstantAttr>() ||
1456 gv->setAttr(cir::CUDAExternallyInitializedAttr::getMnemonic(),
1472 emitter->finalize(gv);
1476 gv.setConstant((vd->
hasAttr<CUDAConstantAttr>() && langOpts.CUDAIsDevice) ||
1477 (!needsGlobalCtor && !needsGlobalDtor &&
1482 if (
const SectionAttr *sa = vd->
getAttr<SectionAttr>()) {
1485 gv.setConstant(
true);
1489 gv.setLinkage(linkage);
1493 if (linkage == cir::GlobalLinkageKind::CommonLinkage) {
1495 gv.setConstant(
false);
1500 std::optional<mlir::Attribute> initializer = gv.getInitialValue();
1501 if (initializer && !
getBuilder().isNullValue(*initializer))
1502 gv.setLinkage(cir::GlobalLinkageKind::WeakAnyLinkage);
1505 setNonAliasAttributes(vd, gv);
1513 if (needsGlobalCtor || needsGlobalDtor)
1518 mlir::Operation *op) {
1520 if (
const auto *fd = dyn_cast<FunctionDecl>(
decl)) {
1524 if (
const auto *method = dyn_cast<CXXMethodDecl>(
decl)) {
1528 abi->emitCXXStructor(gd);
1529 else if (fd->isMultiVersion())
1530 errorNYI(method->getSourceRange(),
"multiversion functions");
1534 if (method->isVirtual())
1540 if (fd->isMultiVersion())
1541 errorNYI(fd->getSourceRange(),
"multiversion functions");
1546 if (
const auto *vd = dyn_cast<VarDecl>(
decl))
1549 llvm_unreachable(
"Invalid argument to CIRGenModule::emitGlobalDefinition");
1563 astContext.getAsConstantArrayType(e->
getType());
1564 uint64_t finalSize = cat->getZExtSize();
1565 str.resize(finalSize);
1567 mlir::Type eltTy =
convertType(cat->getElementType());
1568 return builder.getString(str, eltTy, finalSize,
false);
1573 auto arrayEltTy = mlir::cast<cir::IntType>(arrayTy.getElementType());
1575 uint64_t arraySize = arrayTy.getSize();
1577 assert(arraySize == literalSize + 1 &&
1578 "wide string literal array size must be literal length plus null "
1583 bool isAllZero =
true;
1584 for (
unsigned i = 0; i < literalSize; ++i) {
1592 return cir::ZeroAttr::get(arrayTy);
1596 elements.reserve(arraySize);
1597 for (
unsigned i = 0; i < literalSize; ++i)
1598 elements.push_back(cir::IntAttr::get(arrayEltTy, e->
getCodeUnit(i)));
1600 elements.push_back(cir::IntAttr::get(arrayEltTy, 0));
1602 auto elementsAttr = mlir::ArrayAttr::get(&
getMLIRContext(), elements);
1603 return builder.getConstArray(elementsAttr, arrayTy);
1614 if (d.
hasAttr<SelectAnyAttr>())
1618 if (
auto *vd = dyn_cast<VarDecl>(&d))
1633 llvm_unreachable(
"No such linkage");
1639 if (
auto globalOp = dyn_cast_or_null<cir::GlobalOp>(op)) {
1640 globalOp.setComdat(
true);
1643 funcOp.setComdat(
true);
1649 genTypes.updateCompletedType(td);
1653 replacements[name] = op;
1658 mlir::SymbolUserMap &userMap) {
1659 for (mlir::Operation *user : userMap.getUsers(oldF)) {
1660 auto call = mlir::dyn_cast<cir::CallOp>(user);
1664 for (
auto [argOp, fnArgType] :
1665 llvm::zip(call.getArgs(), newF.getFunctionType().getInputs())) {
1666 if (argOp.getType() != fnArgType)
1675void CIRGenModule::applyReplacements() {
1676 if (replacements.empty())
1682 mlir::SymbolTableCollection symbolTableCollection;
1683 mlir::SymbolUserMap userMap(symbolTableCollection, theModule);
1685 for (
auto &i : replacements) {
1686 StringRef mangledName = i.first;
1687 mlir::Operation *replacement = i.second;
1693 auto newF = dyn_cast<cir::FuncOp>(replacement);
1696 errorNYI(replacement->getLoc(),
"replacement is not a function");
1701 "call argument types do not match replacement function");
1705 userMap.replaceAllUsesWith(oldF, newF.getSymNameAttr());
1706 newF->moveBefore(oldF);
1713 mlir::Location loc, StringRef name, mlir::Type ty,
1715 auto gv = mlir::dyn_cast_or_null<cir::GlobalOp>(
getGlobalValue(name));
1719 if (gv.getSymType() == ty)
1725 assert(gv.isDeclaration() &&
"Declaration has wrong type!");
1727 errorNYI(loc,
"createOrReplaceCXXRuntimeVariable: declaration exists with "
1738 mlir::SymbolTable::setSymbolVisibility(gv,
1742 !gv.hasAvailableExternallyLinkage()) {
1746 gv.setAlignmentAttr(
getSize(alignment));
1757 if ((noCommon || vd->
hasAttr<NoCommonAttr>()) && !vd->
hasAttr<CommonAttr>())
1768 if (vd->
hasAttr<SectionAttr>())
1774 if (vd->
hasAttr<PragmaClangBSSSectionAttr>() ||
1775 vd->
hasAttr<PragmaClangDataSectionAttr>() ||
1776 vd->
hasAttr<PragmaClangRelroSectionAttr>() ||
1777 vd->
hasAttr<PragmaClangRodataSectionAttr>())
1785 if (vd->
hasAttr<WeakImportAttr>())
1795 if (vd->
hasAttr<AlignedAttr>())
1802 for (
const FieldDecl *fd : rd->fields()) {
1803 if (fd->isBitField())
1805 if (fd->hasAttr<AlignedAttr>())
1827cir::GlobalLinkageKind
1831 return cir::GlobalLinkageKind::InternalLinkage;
1834 return cir::GlobalLinkageKind::WeakAnyLinkage;
1838 return cir::GlobalLinkageKind::LinkOnceAnyLinkage;
1843 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
1857 return !astContext.getLangOpts().AppleKext
1858 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
1859 : cir::GlobalLinkageKind::InternalLinkage;
1873 return cir::GlobalLinkageKind::ExternalLinkage;
1876 return dd->
hasAttr<CUDAGlobalAttr>()
1877 ? cir::GlobalLinkageKind::ExternalLinkage
1878 : cir::GlobalLinkageKind::InternalLinkage;
1879 return cir::GlobalLinkageKind::WeakODRLinkage;
1887 return cir::GlobalLinkageKind::CommonLinkage;
1893 if (dd->
hasAttr<SelectAnyAttr>())
1894 return cir::GlobalLinkageKind::WeakODRLinkage;
1898 return cir::GlobalLinkageKind::ExternalLinkage;
1910 mlir::Operation *old, cir::FuncOp newFn) {
1912 auto oldFn = mlir::dyn_cast<cir::FuncOp>(old);
1920 if (oldFn->getAttrs().size() <= 1)
1922 "replaceUsesOfNonProtoTypeWithRealFunction: Attribute forwarding");
1925 newFn.setNoProto(oldFn.getNoProto());
1928 std::optional<mlir::SymbolTable::UseRange> symUses =
1929 oldFn.getSymbolUses(oldFn->getParentOp());
1930 for (
const mlir::SymbolTable::SymbolUse &use : symUses.value()) {
1931 mlir::OpBuilder::InsertionGuard guard(builder);
1933 if (
auto noProtoCallOp = mlir::dyn_cast<cir::CallOp>(use.getUser())) {
1934 builder.setInsertionPoint(noProtoCallOp);
1937 cir::FuncType newFnType = newFn.getFunctionType();
1938 mlir::OperandRange callOperands = noProtoCallOp.getOperands();
1939 bool returnTypeMatches =
1940 newFnType.hasVoidReturn()
1941 ? noProtoCallOp.getNumResults() == 0
1942 : noProtoCallOp.getNumResults() == 1 &&
1943 noProtoCallOp.getResultTypes().front() ==
1944 newFnType.getReturnType();
1945 bool typesMatch = !newFn.getNoProto() && returnTypeMatches &&
1946 callOperands.size() == newFnType.getNumInputs();
1947 for (
unsigned i = 0, e = newFnType.getNumInputs(); typesMatch && i != e;
1949 if (callOperands[i].
getType() != newFnType.getInput(i))
1953 cir::CallOp realCallOp;
1957 builder.createCallOp(noProtoCallOp.getLoc(), newFn, callOperands);
1961 cir::FuncType origFnType = oldFn.getFunctionType();
1962 cir::FuncType callFnType =
1963 origFnType.isVarArg()
1964 ? cir::FuncType::get(origFnType.getInputs(),
1965 origFnType.getReturnType(),
1968 mlir::Value addr = cir::GetGlobalOp::create(
1969 builder, noProtoCallOp.getLoc(), cir::PointerType::get(newFnType),
1970 newFn.getSymName());
1971 mlir::Value casted =
1972 builder.createBitcast(addr, cir::PointerType::get(callFnType));
1973 realCallOp = builder.createIndirectCallOp(
1974 noProtoCallOp.getLoc(), casted, callFnType, callOperands);
1978 noProtoCallOp.replaceAllUsesWith(realCallOp);
1979 noProtoCallOp.erase();
1980 }
else if (
auto getGlobalOp =
1981 mlir::dyn_cast<cir::GetGlobalOp>(use.getUser())) {
1988 mlir::Value res = getGlobalOp.getAddr();
1989 const mlir::Type oldResTy = res.getType();
1990 const auto newPtrTy = cir::PointerType::get(newFn.getFunctionType());
1991 if (oldResTy != newPtrTy) {
1992 res.setType(newPtrTy);
1993 builder.setInsertionPointAfter(getGlobalOp.getOperation());
1994 mlir::Value castRes =
1995 cir::CastOp::create(builder, getGlobalOp.getLoc(), oldResTy,
1996 cir::CastKind::bitcast, res);
1997 res.replaceAllUsesExcept(castRes, castRes.getDefiningOp());
1999 }
else if (mlir::isa<cir::GlobalOp>(use.getUser())) {
2005 "replaceUsesOfNonProtoTypeWithRealFunction: unexpected use type");
2010cir::GlobalLinkageKind
2012 GVALinkage linkage = astContext.GetGVALinkageForVariable(vd);
2019 GVALinkage linkage = astContext.GetGVALinkageForFunction(d);
2021 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(d))
2030 StringRef globalName,
CharUnits alignment) {
2039 gv.setAlignmentAttr(cgm.
getSize(alignment));
2041 cir::GlobalLinkageKindAttr::get(cgm.
getBuilder().getContext(), lt));
2045 if (gv.isWeakForLinker()) {
2046 assert(cgm.
supportsCOMDAT() &&
"Only COFF uses weak string literals");
2049 cgm.
setDSOLocal(
static_cast<mlir::Operation *
>(gv));
2070 std::string result =
2081 astContext.getAlignOfGlobalVarInChars(
s->getType(),
nullptr);
2089 if (!gv.getAlignment() ||
2090 uint64_t(alignment.
getQuantity()) > *gv.getAlignment())
2091 gv.setAlignmentAttr(
getSize(alignment));
2096 if (
getCXXABI().getMangleContext().shouldMangleStringLiteral(
s) &&
2099 "getGlobalForStringLiteral: mangle string literals");
2107 mlir::Location loc =
s->getBeginLoc().isValid()
2109 : builder.getUnknownLoc();
2110 auto typedC = llvm::cast<mlir::TypedAttr>(
c);
2112 cir::GlobalLinkageKind::PrivateLinkage, *
this,
2113 uniqueName, alignment);
2127 auto arrayTy = mlir::dyn_cast<cir::ArrayType>(gv.getSymType());
2128 assert(arrayTy &&
"String literal must be array");
2132 return builder.getGlobalViewAttr(ptrTy, gv);
2148 errorNYI(
"SYCL or OpenMP temp address space");
2158 "emitExplicitCastExprType");
2164 auto ty = mlir::cast<cir::MethodType>(
convertType(destTy));
2165 return builder.getNullMethodAttr(ty);
2168 auto ty = mlir::cast<cir::DataMemberType>(
convertType(destTy));
2169 return builder.getNullDataMemberAttr(ty);
2180 if (
const auto *methodDecl = dyn_cast<CXXMethodDecl>(
decl)) {
2182 if (methodDecl->isVirtual())
2183 return cir::ConstantOp::create(
2184 builder, loc,
getCXXABI().buildVirtualMethodAttr(ty, methodDecl));
2190 return cir::ConstantOp::create(builder, loc,
2191 builder.getMethodAttr(ty, methodFuncOp));
2197 return cir::ConstantOp::create(
2198 builder, loc, builder.getDataMemberAttr(ty,
fieldDecl->getFieldIndex()));
2208 if (
auto *oid = dyn_cast<ObjCImplDecl>(
decl))
2209 errorNYI(oid->getSourceRange(),
"emitDeclConext: ObjCImplDecl");
2219 if (
decl->isTemplated())
2222 switch (
decl->getKind()) {
2225 decl->getDeclKindName());
2228 case Decl::CXXConversion:
2229 case Decl::CXXMethod:
2230 case Decl::Function: {
2233 if (!fd->isConsteval())
2242 case Decl::Decomposition:
2243 case Decl::VarTemplateSpecialization: {
2245 if (
auto *decomp = dyn_cast<DecompositionDecl>(
decl))
2246 for (
auto *binding : decomp->flat_bindings())
2247 if (
auto *holdingVar = binding->getHoldingVar())
2251 case Decl::OpenACCRoutine:
2254 case Decl::OpenACCDeclare:
2257 case Decl::OMPThreadPrivate:
2260 case Decl::OMPGroupPrivate:
2263 case Decl::OMPAllocate:
2266 case Decl::OMPCapturedExpr:
2269 case Decl::OMPDeclareReduction:
2272 case Decl::OMPDeclareMapper:
2275 case Decl::OMPRequires:
2280 case Decl::UsingDirective:
2281 case Decl::UsingEnum:
2282 case Decl::NamespaceAlias:
2284 case Decl::TypeAlias:
2290 case Decl::ClassTemplate:
2292 case Decl::CXXDeductionGuide:
2294 case Decl::ExplicitInstantiation:
2295 case Decl::FunctionTemplate:
2296 case Decl::StaticAssert:
2297 case Decl::TypeAliasTemplate:
2298 case Decl::UsingShadow:
2299 case Decl::VarTemplate:
2300 case Decl::VarTemplatePartialSpecialization:
2303 case Decl::CXXConstructor:
2306 case Decl::CXXDestructor:
2311 case Decl::LinkageSpec:
2312 case Decl::Namespace:
2316 case Decl::ClassTemplateSpecialization:
2317 case Decl::CXXRecord: {
2320 for (
auto *childDecl : crd->
decls())
2326 case Decl::FileScopeAsm:
2328 if (langOpts.CUDA && langOpts.CUDAIsDevice)
2331 if (langOpts.OpenMPIsTargetDevice)
2334 if (langOpts.SYCLIsDevice)
2337 std::string line = file_asm->getAsmString();
2338 globalScopeAsm.push_back(builder.getStringAttr(line));
2345 op.setInitialValueAttr(value);
2359 md->getParent()->getNumVBases() == 0)
2361 "getAddrAndTypeOfCXXStructor: MS ABI complete destructor");
2372 false, isForDefinition);
2374 return {fnType, fn};
2378 mlir::Type funcType,
bool forVTable,
2382 "consteval function should never be emitted");
2392 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(gd.
getDecl())) {
2395 dd->getParent()->getNumVBases() == 0)
2397 "getAddrOfFunction: MS ABI complete destructor");
2403 false, isForDefinition);
2405 if (langOpts.CUDA && !langOpts.CUDAIsDevice &&
2411 bool isHIPHandle = mlir::isa<cir::GlobalOp>(*handle);
2412 if (isForDefinition || isHIPHandle)
2414 return mlir::dyn_cast<cir::FuncOp>(*handle);
2423 llvm::raw_svector_ostream
out(buffer);
2432 assert(ii &&
"Attempt to mangle unnamed decl.");
2434 const auto *fd = dyn_cast<FunctionDecl>(nd);
2438 }
else if (fd && fd->hasAttr<CUDAGlobalAttr>() &&
2442 DeviceKernelAttr::isOpenCLSpelling(
2443 fd->getAttr<DeviceKernelAttr>()) &&
2460 if (
const auto *fd = dyn_cast<FunctionDecl>(nd)) {
2461 if (fd->isMultiVersion()) {
2463 "getMangledName: multi-version functions");
2468 "getMangledName: GPU relocatable device code");
2471 return std::string(
out.str());
2474static FunctionDecl *
2489 if (
auto *methodDecl = dyn_cast<CXXMethodDecl>(protoFunc);
2490 methodDecl && methodDecl->isImplicitObjectMemberFunction()) {
2492 paramTypes.insert(paramTypes.begin(), methodDecl->getThisType());
2495 fpt->getExtProtoInfo());
2506 params.reserve(fpt->getNumParams());
2509 for (
unsigned i = 0, e = fpt->getNumParams(); i != e; ++i) {
2513 nullptr, fpt->getParamType(i),
nullptr,
2516 params.push_back(parm);
2519 tempFunc->setParams(params);
2544 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(canonicalGd.
getDecl())) {
2547 "getMangledName: C++ constructor without variants");
2556 auto result = manglings.insert(std::make_pair(mangledName, gd));
2557 return mangledDeclNames[canonicalGd] = result.first->first();
2561 assert(!d->
getInit() &&
"Cannot emit definite definitions here!");
2569 if (gv && !mlir::cast<cir::GlobalOp>(gv).isDeclaration())
2585 if (langOpts.EmitAllDecls)
2588 const auto *vd = dyn_cast<VarDecl>(global);
2590 ((codeGenOpts.KeepPersistentStorageVariables &&
2591 (vd->getStorageDuration() ==
SD_Static ||
2592 vd->getStorageDuration() ==
SD_Thread)) ||
2593 (codeGenOpts.KeepStaticConsts && vd->getStorageDuration() ==
SD_Static &&
2594 vd->getType().isConstQualified())))
2607 if (langOpts.OpenMP >= 50 && !langOpts.OpenMPSimd) {
2608 std::optional<OMPDeclareTargetDeclAttr *> activeAttr =
2609 OMPDeclareTargetDeclAttr::getActiveAttr(global);
2610 if (!activeAttr || (*activeAttr)->getLevel() != (
unsigned)-1)
2614 const auto *fd = dyn_cast<FunctionDecl>(global);
2621 if (fd->hasAttr<TargetVersionAttr>() && !fd->isMultiVersion())
2623 if (langOpts.SYCLIsDevice) {
2624 errorNYI(fd->getSourceRange(),
"mayBeEmittedEagerly: SYCL");
2628 const auto *vd = dyn_cast<VarDecl>(global);
2630 if (astContext.getInlineVariableDefinitionKind(vd) ==
2638 if (langOpts.OpenMP && langOpts.OpenMPUseTLS &&
2639 astContext.getTargetInfo().isTLSSupported() &&
isa<VarDecl>(global) &&
2641 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(global))
2644 assert((fd || vd) &&
2645 "Only FunctionDecl and VarDecl should hit this path so far.");
2650 cir::CIRGlobalValueInterface gv) {
2651 if (gv.hasLocalLinkage())
2654 if (!gv.hasDefaultVisibility() && !gv.hasExternalWeakLinkage())
2662 const llvm::Triple &tt = cgm.
getTriple();
2664 if (tt.isOSCygMing()) {
2673 cgm.
errorNYI(
"shouldAssumeDSOLocal: MinGW");
2679 if (tt.isOSBinFormatCOFF() && gv.hasExternalWeakLinkage())
2687 if (tt.isOSBinFormatCOFF() || (tt.isOSWindows() && tt.isOSBinFormatMachO()))
2691 if (!tt.isOSBinFormatELF())
2696 if (rm != llvm::Reloc::Static && !lOpts.PIE) {
2704 return !(lOpts.SemanticInterposition || lOpts.HalfNoSemanticInterposition);
2708 if (!gv.isDeclarationForLinker())
2714 if (rm == llvm::Reloc::PIC_ && gv.hasExternalWeakLinkage())
2721 if (cgOpts.DirectAccessExternalData) {
2727 if (
auto globalOp = dyn_cast<cir::GlobalOp>(gv.getOperation())) {
2760 if (
auto globalValue = dyn_cast<cir::CIRGlobalValueInterface>(op))
2779 auto res = manglings.find(mangledName);
2780 if (res == manglings.end())
2782 result = res->getValue();
2789 return cir::TLS_Model::GeneralDynamic;
2791 return cir::TLS_Model::LocalDynamic;
2793 return cir::TLS_Model::InitialExec;
2795 return cir::TLS_Model::LocalExec;
2797 llvm_unreachable(
"Invalid TLS model!");
2801 assert(d.
getTLSKind() &&
"setting TLS mode on non-TLS var!");
2806 if (d.
getAttr<TLSModelAttr>())
2810 global.setTlsModel(tlm);
2814 if (d.
isStaticLocal() || tlm != cir::TLS_Model::GeneralDynamic)
2822 cir::FuncOp func,
bool isThunk) {
2824 cir::CallingConv callingConv;
2825 cir::SideEffect sideEffect;
2832 mlir::NamedAttrList pal{};
2833 std::vector<mlir::NamedAttrList> argAttrs(info.
arguments().size());
2834 mlir::NamedAttrList retAttrs{};
2836 retAttrs, callingConv, sideEffect,
2839 for (mlir::NamedAttribute
attr : pal)
2840 func->setAttr(
attr.getName(),
attr.getValue());
2842 llvm::for_each(llvm::enumerate(argAttrs), [func](
auto idx_arg_pair) {
2843 mlir::function_interface_impl::setArgAttrs(func, idx_arg_pair.index(),
2844 idx_arg_pair.value());
2846 if (!retAttrs.empty())
2847 mlir::function_interface_impl::setResultAttrs(func, 0, retAttrs);
2860 bool isIncompleteFunction,
2868 if (!isIncompleteFunction)
2870 getTypes().arrangeGlobalDeclaration(globalDecl),
2873 if (!isIncompleteFunction && func.isDeclaration())
2886 if (funcDecl->isInlineBuiltinDeclaration()) {
2888 bool hasBody = funcDecl->
hasBody(fdBody);
2890 assert(hasBody &&
"Inline builtin declarations should always have an "
2895 if (funcDecl->isReplaceableGlobalAllocationFunction()) {
2898 func->setAttr(cir::CIRDialect::getNoBuiltinAttrName(),
2910 if (!langOpts.Exceptions)
2913 if (langOpts.CXXExceptions)
2916 if (langOpts.ObjCExceptions)
2927 f->setAttr(cir::CIRDialect::getNoThrowAttrName(),
2930 std::optional<cir::InlineKind> existingInlineKind = f.getInlineKind();
2932 existingInlineKind && *existingInlineKind == cir::InlineKind::NoInline;
2933 bool isAlwaysInline = existingInlineKind &&
2934 *existingInlineKind == cir::InlineKind::AlwaysInline;
2938 if (!isAlwaysInline &&
2943 f.setInlineKind(cir::InlineKind::NoInline);
2958 if (
decl->hasAttr<NoInlineAttr>() && !isAlwaysInline) {
2960 f.setInlineKind(cir::InlineKind::NoInline);
2961 }
else if (
decl->hasAttr<AlwaysInlineAttr>() && !isNoInline) {
2964 f.setInlineKind(cir::InlineKind::AlwaysInline);
2968 if (!isAlwaysInline)
2969 f.setInlineKind(cir::InlineKind::NoInline);
2974 if (
auto *fd = dyn_cast<FunctionDecl>(
decl)) {
2979 auto checkRedeclForInline = [](
const FunctionDecl *redecl) {
2980 return redecl->isInlineSpecified();
2982 if (any_of(
decl->redecls(), checkRedeclForInline))
2987 return any_of(pattern->
redecls(), checkRedeclForInline);
2989 if (checkForInline(fd)) {
2990 f.setInlineKind(cir::InlineKind::InlineHint);
2991 }
else if (codeGenOpts.getInlining() ==
2993 !fd->isInlined() && !isAlwaysInline) {
2994 f.setInlineKind(cir::InlineKind::NoInline);
3003 StringRef mangledName, mlir::Type funcType,
GlobalDecl gd,
bool forVTable,
3005 mlir::NamedAttrList extraAttrs) {
3008 if (
const auto *fd = cast_or_null<FunctionDecl>(d)) {
3010 if (
getLangOpts().OpenMPIsTargetDevice && openMPRuntime &&
3012 !dontDefer && !isForDefinition) {
3015 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(fdDef))
3017 else if (
const auto *dd = dyn_cast<CXXDestructorDecl>(fdDef))
3027 if (fd->isMultiVersion())
3028 errorNYI(fd->getSourceRange(),
"getOrCreateCIRFunction: multi-version");
3034 assert(mlir::isa<cir::FuncOp>(entry));
3039 if (d && !d->
hasAttr<DLLImportAttr>() && !d->
hasAttr<DLLExportAttr>()) {
3047 if (isForDefinition && fn && !fn.isDeclaration()) {
3054 diagnosedConflictingDefinitions.insert(gd).second) {
3058 diag::note_previous_definition);
3062 if (fn && fn.getFunctionType() == funcType) {
3066 if (!isForDefinition) {
3074 auto *funcDecl = llvm::cast_or_null<FunctionDecl>(gd.
getDecl());
3075 bool invalidLoc = !funcDecl ||
3076 funcDecl->getSourceRange().getBegin().isInvalid() ||
3077 funcDecl->getSourceRange().getEnd().isInvalid();
3079 invalidLoc ? theModule->getLoc() :
getLoc(funcDecl->getSourceRange()),
3080 mangledName, mlir::cast<cir::FuncType>(funcType), funcDecl);
3082 if (funcDecl && funcDecl->hasAttr<AnnotateAttr>())
3083 deferredAnnotations[mangledName] = funcDecl;
3094 auto symbolOp = mlir::cast<mlir::SymbolOpInterface>(entry);
3102 if (symbolOp.getSymbolUses(symbolOp->getParentOp()))
3112 if (!extraAttrs.empty()) {
3113 extraAttrs.append(funcOp->getAttrs());
3114 funcOp->setAttrs(extraAttrs);
3121 assert(funcOp.getFunctionType() == funcType);
3128 if (isa_and_nonnull<CXXDestructorDecl>(d) &&
3158 fd = fd->getPreviousDecl()) {
3160 if (fd->doesThisDeclarationHaveABody()) {
3173 cir::FuncType funcType,
3177 mlir::OpBuilder::InsertionGuard guard(builder);
3185 builder.setInsertionPoint(cgf->
curFn);
3187 func = cir::FuncOp::create(builder, loc, name, funcType);
3194 func.setNoProto(
true);
3196 assert(func.isDeclaration() &&
"expected empty body");
3200 func.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
3202 mlir::SymbolTable::setSymbolVisibility(
3203 func, mlir::SymbolTable::Visibility::Private);
3211 theModule.push_back(func);
3216 for (
const auto *
attr :
3230 fnOp.setBuiltin(
true);
3236 return cir::CtorKind::Default;
3238 return cir::CtorKind::Copy;
3240 return cir::CtorKind::Move;
3241 return cir::CtorKind::Custom;
3246 return cir::AssignKind::Copy;
3248 return cir::AssignKind::Move;
3249 llvm_unreachable(
"not a copy or move assignment operator");
3257 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(funcDecl)) {
3258 auto cxxDtor = cir::CXXDtorAttr::get(
3261 funcOp.setCxxSpecialMemberAttr(cxxDtor);
3265 if (
const auto *ctor = dyn_cast<CXXConstructorDecl>(funcDecl)) {
3267 auto cxxCtor = cir::CXXCtorAttr::get(
3269 kind, ctor->isTrivial());
3270 funcOp.setCxxSpecialMemberAttr(cxxCtor);
3274 const auto *method = dyn_cast<CXXMethodDecl>(funcDecl);
3275 if (method && (method->isCopyAssignmentOperator() ||
3276 method->isMoveAssignmentOperator())) {
3278 auto cxxAssign = cir::CXXAssignAttr::get(
3280 assignKind, method->isTrivial());
3281 funcOp.setCxxSpecialMemberAttr(cxxAssign);
3287 cir::FuncOp funcOp, StringRef name) {
3303 mlir::NamedAttrList extraAttrs,
3305 bool assumeConvergent) {
3306 if (assumeConvergent)
3307 errorNYI(
"createRuntimeFunction: assumeConvergent");
3317 entry.setDSOLocal(
true);
3323mlir::SymbolTable::Visibility
3327 if (op.isDeclaration())
3328 return mlir::SymbolTable::Visibility::Private;
3332mlir::SymbolTable::Visibility
3335 case cir::GlobalLinkageKind::InternalLinkage:
3336 case cir::GlobalLinkageKind::PrivateLinkage:
3337 return mlir::SymbolTable::Visibility::Private;
3338 case cir::GlobalLinkageKind::ExternalLinkage:
3339 case cir::GlobalLinkageKind::ExternalWeakLinkage:
3340 case cir::GlobalLinkageKind::LinkOnceODRLinkage:
3341 case cir::GlobalLinkageKind::AvailableExternallyLinkage:
3342 case cir::GlobalLinkageKind::CommonLinkage:
3343 case cir::GlobalLinkageKind::WeakAnyLinkage:
3344 case cir::GlobalLinkageKind::WeakODRLinkage:
3345 return mlir::SymbolTable::Visibility::Public;
3347 llvm::errs() <<
"visibility not implemented for '"
3348 << stringifyGlobalLinkageKind(glk) <<
"'\n";
3349 assert(0 &&
"not implemented");
3352 llvm_unreachable(
"linkage should be handled above!");
3356 clang::VisibilityAttr::VisibilityType visibility) {
3357 switch (visibility) {
3358 case clang::VisibilityAttr::VisibilityType::Default:
3359 return cir::VisibilityKind::Default;
3360 case clang::VisibilityAttr::VisibilityType::Hidden:
3361 return cir::VisibilityKind::Hidden;
3362 case clang::VisibilityAttr::VisibilityType::Protected:
3363 return cir::VisibilityKind::Protected;
3365 llvm_unreachable(
"unexpected visibility value");
3370 const clang::VisibilityAttr *va =
decl->getAttr<clang::VisibilityAttr>();
3371 cir::VisibilityAttr cirVisibility =
3374 cirVisibility = cir::VisibilityAttr::get(
3378 return cirVisibility;
3384 applyReplacements();
3386 theModule->setAttr(cir::CIRDialect::getModuleLevelAsmAttrName(),
3387 builder.getArrayAttr(globalScopeAsm));
3389 emitGlobalAnnotations();
3391 if (!recordLayoutEntries.empty())
3393 cir::CIRDialect::getRecordLayoutsAttrName(),
3394 mlir::DictionaryAttr::get(&
getMLIRContext(), recordLayoutEntries));
3403 std::string cuidName =
3406 auto loc = builder.getUnknownLoc();
3407 mlir::ptr::MemorySpaceAttrInterface addrSpace =
3409 getGlobalVarAddressSpace(
nullptr));
3413 gv.setLinkage(cir::GlobalLinkageKind::ExternalLinkage);
3415 auto zeroAttr = cir::IntAttr::get(int8Ty, 0);
3416 gv.setInitialValueAttr(zeroAttr);
3418 mlir::SymbolTable::setSymbolVisibility(
3419 gv, mlir::SymbolTable::Visibility::Public);
3436 const AliasAttr *aa = d->
getAttr<AliasAttr>();
3437 assert(aa &&
"Not an alias?");
3441 if (aa->getAliasee() == mangledName) {
3442 diags.Report(aa->getLocation(), diag::err_cyclic_alias) << 0;
3450 auto entryGV = mlir::dyn_cast<cir::CIRGlobalValueInterface>(entry);
3451 if (entryGV && entryGV.isDefinition())
3464 cir::GlobalLinkageKind linkage;
3477 linkage = cir::GlobalLinkageKind::WeakAnyLinkage;
3489 mlir::SymbolTable::Visibility visibility =
3493 cir::CIRGlobalValueInterface alias =
3494 isFunction ? mlir::cast<cir::CIRGlobalValueInterface>(
3496 mlir::cast<cir::FuncType>(declTy),
3499 : mlir::cast<cir::CIRGlobalValueInterface>(
3501 alias.setAliasee(aa->getAliasee());
3502 alias.setLinkage(linkage);
3503 mlir::SymbolTable::setSymbolVisibility(alias, visibility);
3511 cir::FuncOp aliasee,
3512 cir::GlobalLinkageKind linkage) {
3514 auto *aliasFD = dyn_cast<FunctionDecl>(aliasGD.
getDecl());
3515 assert(aliasFD &&
"expected FunctionDecl");
3526 mangledName, fnType, aliasFD);
3527 alias.setAliasee(aliasee.getName());
3528 alias.setLinkage(linkage);
3532 mlir::SymbolTable::setSymbolVisibility(
3533 alias, mlir::SymbolTable::Visibility::Private);
3545 "declaration exists with different type");
3557 return genTypes.convertType(
type);
3564 return mlir::verify(theModule).succeeded();
3573 return builder.getConstNullPtrAttr(builder.getUInt8PtrTy());
3576 langOpts.ObjCRuntime.isGNUFamily()) {
3577 errorNYI(loc,
"getAddrOfRTTIDescriptor: Objc PtrType & Objc RT GUN");
3587 llvm::iterator_range<CastExpr::path_const_iterator> path) {
3594 assert(!base->isVirtual() &&
"Should not see virtual bases here!");
3599 const auto *baseDecl = base->getType()->castAsCXXRecordDecl();
3611 llvm::StringRef feature) {
3612 unsigned diagID = diags.getCustomDiagID(
3614 return diags.Report(loc, diagID) << feature;
3618 llvm::StringRef feature) {
3630 "cannot compile this %0 yet");
3631 diags.Report(astContext.getFullLoc(
s->getBeginLoc()), diagId)
3632 <<
type <<
s->getSourceRange();
3638 "cannot compile this %0 yet");
3639 diags.Report(astContext.getFullLoc(d->
getLocation()), diagId) <<
type;
3643 cir::LabelOp label) {
3644 [[maybe_unused]]
auto result =
3646 assert(result.second &&
3647 "attempting to map a blockaddress info that is already mapped");
3652 assert(result.second &&
3653 "attempting to map a blockaddress operation that is already mapped");
3657 cir::LabelOp label) {
3659 assert(result.second &&
3660 "attempting to map a blockaddress operation that is already mapped");
3664 cir::LabelOp newLabel) {
3667 "trying to update a blockaddress not previously mapped");
3668 assert(!it->second &&
"blockaddress already has a resolved label");
3670 it->second = newLabel;
3683 "not a global temporary");
3695 materializedType = mte->
getType();
3704 llvm::raw_svector_ostream
out(name);
3708 auto insertResult = materializedGlobalTemporaryMap.insert({mte,
nullptr});
3709 if (!insertResult.second) {
3713 if (!insertResult.first->second) {
3716 insertResult.first->second =
3719 return insertResult.first->second;
3736 value = &evalResult.
Val;
3740 std::optional<ConstantEmitter> emitter;
3741 mlir::Attribute initialValue =
nullptr;
3742 bool isConstant =
false;
3746 emitter.emplace(*
this);
3747 initialValue = emitter->emitForInitializer(*value, materializedType);
3752 type = mlir::cast<mlir::TypedAttr>(initialValue).getType();
3761 if (linkage == cir::GlobalLinkageKind::ExternalLinkage) {
3763 if (
varDecl->isStaticDataMember() &&
varDecl->getAnyInitializer(initVD) &&
3771 linkage = cir::GlobalLinkageKind::InternalLinkage;
3775 gv.setInitialValueAttr(initialValue);
3778 emitter->finalize(gv);
3780 if (!gv.hasLocalLinkage()) {
3785 gv.setAlignment(align.getAsAlign().value());
3788 "Global temporary with comdat/weak linkage");
3791 "Global temporary with thread local storage");
3792 mlir::Operation *cv = gv;
3801 mlir::Operation *&entry = materializedGlobalTemporaryMap[mte];
3803 entry->replaceAllUsesWith(cv);
3818 return *globalOpEntry;
3825 "emitForInitializer should take gcd->getType().getAddressSpace()");
3827 auto typedInit = dyn_cast<mlir::TypedAttr>(init);
3831 "getAddrOfUnnamedGlobalConstantDecl: non-typed initializer");
3840 std::string name = numEntries == 0
3842 : (Twine(
".constant.") + Twine(numEntries)).str();
3844 typedInit.getType(),
true);
3845 globalOp.setLinkage(cir::GlobalLinkageKind::PrivateLinkage);
3848 globalOp.setAlignment(alignment.
getAsAlign().value());
3852 *globalOpEntry = globalOp;
3867 "emitForInitializer should take tpo->getType().getAddressSpace()");
3868 mlir::Attribute init =
3878 cir::GlobalLinkageKind linkage =
3880 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
3881 : cir::GlobalLinkageKind::InternalLinkage;
3885 typedInit.getType(),
true);
3886 globalOp.setLinkage(linkage);
3887 globalOp.setAlignment(alignment.
getAsAlign().value());
3889 linkage == cir::GlobalLinkageKind::LinkOnceODRLinkage);
3904CIRGenModule::getOrCreateAnnotationArgs(
const AnnotateAttr *
attr) {
3911 llvm::FoldingSetNodeID id;
3912 for (
Expr *e : exprs)
3915 mlir::ArrayAttr &lookup = annotationArgs[
id.ComputeHash()];
3920 args.reserve(exprs.size());
3921 for (
Expr *e : exprs) {
3922 if (
auto *strE = dyn_cast<clang::StringLiteral>(e->IgnoreParenCasts())) {
3923 args.push_back(builder.getStringAttr(strE->getString()));
3924 }
else if (
auto *intE =
3925 dyn_cast<clang::IntegerLiteral>(e->IgnoreParenCasts())) {
3926 auto intTy = builder.getIntegerType(intE->getValue().getBitWidth());
3927 args.push_back(builder.getIntegerAttr(intTy, intE->getValue()));
3929 errorNYI(e->getExprLoc(),
"annotation argument expression");
3933 return lookup = builder.getArrayAttr(args);
3936cir::AnnotationAttr CIRGenModule::emitAnnotateAttr(
const AnnotateAttr *aa) {
3937 mlir::StringAttr annoGV = builder.getStringAttr(aa->getAnnotation());
3938 mlir::ArrayAttr args = getOrCreateAnnotationArgs(aa);
3939 return cir::AnnotationAttr::get(&
getMLIRContext(), annoGV, args);
3943 mlir::Operation *gv) {
3944 assert(d->
hasAttr<AnnotateAttr>() &&
"no annotate attribute");
3946 "annotation only on globals");
3949 annotations.push_back(emitAnnotateAttr(i));
3950 if (
auto global = dyn_cast<cir::GlobalOp>(gv))
3951 global.setAnnotationsAttr(builder.getArrayAttr(annotations));
3952 else if (
auto func = dyn_cast<cir::FuncOp>(gv))
3953 func.setAnnotationsAttr(builder.getArrayAttr(annotations));
3956void CIRGenModule::emitGlobalAnnotations() {
3957 for (
const auto &[mangledName, vd] : deferredAnnotations) {
3962 deferredAnnotations.clear();
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
static bool shouldAssumeDSOLocal(const CIRGenModule &cgm, cir::CIRGlobalValueInterface gv)
static cir::AssignKind getAssignKindFromDecl(const CXXMethodDecl *method)
static FunctionDecl * createOpenACCBindTempFunction(ASTContext &ctx, const IdentifierInfo *bindName, const FunctionDecl *protoFunc)
static bool shouldBeInCOMDAT(CIRGenModule &cgm, const Decl &d)
static mlir::Attribute getNewInitValue(CIRGenModule &cgm, cir::GlobalOp newGlob, mlir::Type oldTy, mlir::Attribute oldInit)
static bool hasUnwindExceptions(const LangOptions &langOpts)
Determines whether the language options require us to model unwind exceptions.
static void setWindowsItaniumDLLImport(CIRGenModule &cgm, bool isLocal, cir::FuncOp funcOp, StringRef name)
static std::string getMangledNameImpl(CIRGenModule &cgm, GlobalDecl gd, const NamedDecl *nd)
static llvm::SmallVector< int64_t > indexesOfArrayAttr(mlir::ArrayAttr indexes)
static bool isViewOnGlobal(cir::GlobalOp glob, cir::GlobalViewAttr view)
static cir::GlobalOp generateStringLiteral(mlir::Location loc, mlir::TypedAttr c, cir::GlobalLinkageKind lt, CIRGenModule &cgm, StringRef globalName, CharUnits alignment)
static bool hasImplicitAttr(const ValueDecl *decl)
static std::vector< std::string > getFeatureDeltaFromDefault(const CIRGenModule &cgm, llvm::StringRef targetCPU, llvm::StringMap< bool > &featureMap)
Get the feature delta from the default feature map for the given target CPU.
static CIRGenCXXABI * createCXXABI(CIRGenModule &cgm)
static bool isVarDeclStrongDefinition(const ASTContext &astContext, CIRGenModule &cgm, const VarDecl *vd, bool noCommon)
static void setLinkageForGV(cir::GlobalOp &gv, const NamedDecl *nd)
static 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.
__device__ __2f16 float __ockl_bool s
__device__ __2f16 float c
cir::GlobalViewAttr getGlobalViewAttr(cir::GlobalOp globalOp, mlir::ArrayAttr indices={})
Get constant address of a global variable as an MLIR attribute.
cir::PointerType getPointerTo(mlir::Type ty)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
@ Strong
Strong definition.
@ WeakUnknown
Weak for now, might become strong later in this TU.
bool DeclMustBeEmitted(const Decl *D)
Determines if the decl can be CodeGen'ed or deserialized from PCH lazily, only when used; this is onl...
StringRef getCUIDHash() const
void Deallocate(void *Ptr) const
GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const
bool isAlignmentRequired(const Type *T) const
Determine if the alignment the type has was required using an alignment attribute.
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
GVALinkage GetGVALinkageForVariable(const VarDecl *VD) const
unsigned getTypeAlignIfKnown(QualType T, bool NeedsPreferredAlignment=false) const
Return the alignment of a type, in bits, or 0 if the type is incomplete and we cannot determine the a...
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
DiagnosticsEngine & getDiagnostics() const
const TargetInfo & getTargetInfo() const
TargetCXXABI::Kind getCXXABIKind() const
Return the C++ ABI kind that should be used.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
mlir::Attribute getConstRecordOrZeroAttr(mlir::ArrayAttr arrayAttr, bool packed=false, bool padded=false, mlir::Type type={})
uint64_t computeOffsetFromGlobalViewIndices(const cir::CIRDataLayout &layout, mlir::Type ty, llvm::ArrayRef< int64_t > indices)
void computeGlobalViewIndicesFromFlatOffset(int64_t offset, mlir::Type ty, cir::CIRDataLayout layout, llvm::SmallVectorImpl< int64_t > &indices)
cir::ConstArrayAttr getConstArray(mlir::Attribute attrs, cir::ArrayType arrayTy) const
virtual mlir::Operation * getKernelHandle(cir::FuncOp fn, GlobalDecl gd)=0
Implements C++ ABI-specific code generation functions.
virtual mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty)=0
virtual void emitCXXConstructors(const clang::CXXConstructorDecl *d)=0
Emit constructor variants required by this ABI.
virtual void emitCXXDestructors(const clang::CXXDestructorDecl *d)=0
Emit dtor variants required by this ABI.
clang::MangleContext & getMangleContext()
Gets the mangle context.
virtual cir::GlobalLinkageKind getCXXDestructorLinkage(GVALinkage linkage, const CXXDestructorDecl *dtor, CXXDtorType dt) const
llvm::ArrayRef< CanQualType > arguments() const
cir::FuncOp generateCode(clang::GlobalDecl gd, cir::FuncOp fn, cir::FuncType funcType)
void emitVariablyModifiedType(QualType ty)
mlir::Operation * curFn
The current function or global initializer that is generated code for.
This class organizes the cross-function state that is used while generating CIR code.
cir::GlobalOp getAddrOfUnnamedGlobalConstantDecl(const UnnamedGlobalConstantDecl *gcd)
void updateResolvedBlockAddress(cir::BlockAddressOp op, cir::LabelOp newLabel)
void addUsedOrCompilerUsedGlobal(cir::CIRGlobalValueInterface gv)
Add a global to a list to be added to the llvm.compiler.used metadata.
void replaceUsesOfNonProtoTypeWithRealFunction(mlir::Operation *old, cir::FuncOp newFn)
This function is called when we implement a function with no prototype, e.g.
llvm::StringRef getMangledName(clang::GlobalDecl gd)
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *derivedClass, llvm::iterator_range< CastExpr::path_const_iterator > path)
void setGlobalVisibility(mlir::Operation *op, const NamedDecl *d) const
Set the visibility for the given global.
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
void emitDeferred()
Emit any needed decls for which code generation was deferred.
cir::GlobalLinkageKind getCIRLinkageVarDefinition(const VarDecl *vd)
clang::ASTContext & getASTContext() const
void insertGlobalSymbol(mlir::Operation *op)
cir::FuncOp getAddrOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
CIRGenCUDARuntime & getCUDARuntime()
llvm::DenseMap< cir::BlockAddrInfoAttr, cir::LabelOp > blockAddressInfoToLabel
Map BlockAddrInfoAttr (function name, label name) to the corresponding CIR LabelOp.
void emitTopLevelDecl(clang::Decl *decl)
void emitOMPDeclareMapper(const OMPDeclareMapperDecl *d)
void addReplacement(llvm::StringRef name, mlir::Operation *op)
mlir::Type convertType(clang::QualType type)
bool shouldEmitRTTI(bool forEH=false)
cir::GlobalOp getGlobalForStringLiteral(const StringLiteral *s, llvm::StringRef name=".str")
Return a global symbol reference to a constant array for the given string literal.
std::vector< cir::CIRGlobalValueInterface > llvmUsed
List of global values which are required to be present in the object file; This is used for forcing v...
void emitOMPCapturedExpr(const OMPCapturedExprDecl *d)
void mapUnresolvedBlockAddress(cir::BlockAddressOp op)
bool mustBeEmitted(const clang::ValueDecl *d)
Determine whether the definition must be emitted; if this returns false, the definition can be emitte...
void emitGlobalOpenACCDeclareDecl(const clang::OpenACCDeclareDecl *cd)
mlir::IntegerAttr getSize(CharUnits size)
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)
void mapResolvedBlockAddress(cir::BlockAddressOp op, cir::LabelOp)
clang::DiagnosticsEngine & getDiags() const
cir::GlobalLinkageKind getCIRLinkageForDeclarator(const DeclaratorDecl *dd, GVALinkage linkage)
mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty, bool forEH=false)
Get the address of the RTTI descriptor for the given type.
void setFunctionAttributes(GlobalDecl gd, cir::FuncOp f, bool isIncompleteFunction, bool isThunk)
Set function attributes for a function declaration.
static mlir::SymbolTable::Visibility getMLIRVisibilityFromCIRLinkage(cir::GlobalLinkageKind GLK)
const clang::TargetInfo & getTarget() const
void setCIRFunctionAttributes(GlobalDecl gd, const CIRGenFunctionInfo &info, cir::FuncOp func, bool isThunk)
Set the CIR function attributes (Sext, zext, etc).
const llvm::Triple & getTriple() const
static mlir::SymbolTable::Visibility getMLIRVisibility(Visibility v)
void emitTentativeDefinition(const VarDecl *d)
void 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)
void setTLSMode(mlir::Operation *op, const VarDecl &d)
Set TLS mode for the given operation based on the given variable declaration.
cir::FuncOp getAddrOfFunction(clang::GlobalDecl gd, mlir::Type funcType=nullptr, bool forVTable=false, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
Return the address of the given function.
void emitAliasForGlobal(llvm::StringRef mangledName, mlir::Operation *op, GlobalDecl aliasGD, cir::FuncOp aliasee, cir::GlobalLinkageKind linkage)
void emitLLVMUsed()
Emit llvm.used and llvm.compiler.used globals.
mlir::Value emitMemberPointerConstant(const UnaryOperator *e)
void emitGlobalOpenACCDecl(const clang::OpenACCConstructDecl *cd)
bool verifyModule() const
void emitExplicitCastExprType(const ExplicitCastExpr *e, CIRGenFunction *cgf=nullptr)
Emit type info if type of an expression is a variably modified type.
const cir::CIRDataLayout getDataLayout() const
void eraseGlobalSymbol(mlir::Operation *op)
mlir::Operation * getAddrOfGlobalTemporary(const MaterializeTemporaryExpr *mte, const Expr *init)
Returns a pointer to a global variable representing a temporary with static or thread storage duratio...
std::map< llvm::StringRef, clang::GlobalDecl > deferredDecls
This contains all the decls which have definitions but which are deferred for emission and therefore ...
void errorUnsupported(const Stmt *s, llvm::StringRef type)
Print out an error that codegen doesn't support the specified stmt yet.
mlir::Value getAddrOfGlobalVar(const VarDecl *d, mlir::Type ty={}, ForDefinition_t isForDefinition=NotForDefinition)
Return the mlir::Value for the address of the given global variable.
llvm::StringMap< mlir::Operation * > symbolLookupCache
Cache for O(1) symbol lookups by name, replacing the O(N) linear scan in SymbolTable::lookupSymbolIn ...
static void setInitializer(cir::GlobalOp &op, mlir::Attribute value)
cir::GlobalViewAttr getAddrOfGlobalVarAttr(const VarDecl *d)
Return the mlir::GlobalViewAttr for the address of the given global.
void addGlobalCtor(cir::FuncOp ctor, std::optional< int > priority=std::nullopt)
Add a global constructor or destructor to the module.
cir::GlobalLinkageKind getFunctionLinkage(GlobalDecl gd)
void updateCompletedType(const clang::TagDecl *td)
const clang::CodeGenOptions & getCodeGenOpts() const
void emitDeferredVTables()
Emit any vtables which we deferred and still have a use for.
const clang::LangOptions & getLangOpts() const
void constructAttributeList(llvm::StringRef name, const CIRGenFunctionInfo &info, CIRGenCalleeInfo calleeInfo, mlir::NamedAttrList &attrs, llvm::MutableArrayRef< mlir::NamedAttrList > argAttrs, mlir::NamedAttrList &retAttrs, cir::CallingConv &callingConv, cir::SideEffect &sideEffect, bool attrOnCallSite, bool isThunk)
Get the CIR attributes and calling convention to use for a particular function type.
cir::FuncOp getOrCreateCIRFunction(llvm::StringRef mangledName, mlir::Type funcType, clang::GlobalDecl gd, bool forVTable, bool dontDefer=false, bool isThunk=false, ForDefinition_t isForDefinition=NotForDefinition, mlir::NamedAttrList extraAttrs={})
void emitOpenACCRoutineDecl(const clang::FunctionDecl *funcDecl, cir::FuncOp func, SourceLocation pragmaLoc, ArrayRef< const OpenACCClause * > clauses)
void emitVTablesOpportunistically()
Try to emit external vtables as available_externally if they have emitted all inlined virtual functio...
cir::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)
void setGVPropertiesAux(mlir::Operation *op, const NamedDecl *d) const
LangAS getLangTempAllocaAddressSpace() const
Returns the address space for temporary allocations in the language.
llvm::DenseSet< cir::BlockAddressOp > unresolvedBlockAddressToLabel
Track CIR BlockAddressOps that cannot be resolved immediately because their LabelOp has not yet been ...
mlir::Location getLoc(clang::SourceLocation cLoc)
Helpers to convert the presumed location of Clang's SourceLocation to an MLIR Location.
llvm::DenseMap< mlir::Attribute, cir::GlobalOp > constantStringMap
mlir::Operation * lastGlobalOp
void replaceGlobal(cir::GlobalOp oldGV, cir::GlobalOp newGV)
Replace all uses of the old global with the new global, updating types and references as needed.
static cir::VisibilityKind getGlobalVisibilityKindFromClangVisibility(clang::VisibilityAttr::VisibilityType visibility)
llvm::StringMap< unsigned > cgGlobalNames
void setCXXSpecialMemberAttr(cir::FuncOp funcOp, const clang::FunctionDecl *funcDecl)
Mark the function as a special member (e.g. constructor, destructor)
mlir::TypedAttr emitNullMemberAttr(QualType t, const MemberPointerType *mpt)
Returns a null attribute to represent either a null method or null data member, depending on the type...
mlir::Operation * getGlobalValue(llvm::StringRef ref)
void emitOMPDeclareReduction(const OMPDeclareReductionDecl *d)
mlir::ModuleOp getModule() const
bool supportsCOMDAT() const
void addCompilerUsedGlobal(cir::CIRGlobalValueInterface gv)
Add a global value to the llvmCompilerUsed list.
clang::CharUnits getNaturalTypeAlignment(clang::QualType t, LValueBaseInfo *baseInfo=nullptr, bool forPointeeType=false)
FIXME: this could likely be a common helper and not necessarily related with codegen.
mlir::MLIRContext & getMLIRContext()
mlir::Operation * getAddrOfGlobal(clang::GlobalDecl gd, ForDefinition_t isForDefinition=NotForDefinition)
void maybeSetTrivialComdat(const clang::Decl &d, mlir::Operation *op)
CIRGenCXXABI & getCXXABI() const
cir::GlobalViewAttr getAddrOfConstantStringFromLiteral(const StringLiteral *s, llvm::StringRef name=".str")
Return a global symbol reference to a constant array for the given string literal.
llvm::MapVector< cir::BlockAddressOp, cir::LabelOp > blockAddressToLabel
Map CIR BlockAddressOps directly to their resolved LabelOps.
bool lookupRepresentativeDecl(llvm::StringRef mangledName, clang::GlobalDecl &gd) const
void emitDeclContext(const DeclContext *dc)
clang::CharUnits getNaturalPointeeTypeAlignment(clang::QualType t, LValueBaseInfo *baseInfo=nullptr)
void emitGlobal(clang::GlobalDecl gd)
Emit code for a single global function or variable declaration.
cir::LabelOp lookupBlockAddressInfo(cir::BlockAddrInfoAttr blockInfo)
bool mayBeEmittedEagerly(const clang::ValueDecl *d)
Determine whether the definition can be emitted eagerly, or should be delayed until the end of the tr...
void mapBlockAddress(cir::BlockAddrInfoAttr blockInfo, cir::LabelOp label)
void addGlobalAnnotations(const clang::ValueDecl *d, mlir::Operation *gv)
Add global annotations for a global value (GlobalOp or FuncOp).
void setCIRFunctionAttributesForDefinition(const clang::FunctionDecl *fd, cir::FuncOp f)
Set extra attributes (inline, etc.) for a function.
std::string getOpenACCBindMangledName(const IdentifierInfo *bindName, const FunctionDecl *attachedFunction)
void emitGlobalFunctionDefinition(clang::GlobalDecl gd, mlir::Operation *op)
CIRGenVTables & getVTables()
void setFunctionLinkage(GlobalDecl gd, cir::FuncOp f)
std::vector< clang::GlobalDecl > deferredDeclsToEmit
void emitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *d)
CIRGenOpenMPRuntime & getOpenMPRuntime()
void emitAMDGPUMetadata()
Emits AMDGPU specific Metadata.
void emitOMPGroupPrivateDecl(const OMPGroupPrivateDecl *d)
mlir::Attribute getConstantArrayFromStringLiteral(const StringLiteral *e)
Return a constant array for the given string.
cir::VisibilityAttr getGlobalVisibilityAttrFromDecl(const Decl *decl)
void setCommonAttributes(GlobalDecl gd, mlir::Operation *op)
Set attributes which are common to any form of a global definition (alias, Objective-C method,...
void emitDeclareTargetFunction(const FunctionDecl *fd, cir::FuncOp funcOp)
If the function has an OMPDeclareTargetDeclAttr, set the corresponding omp.declare_target attribute o...
const CIRGenFunctionInfo & arrangeGlobalDeclaration(GlobalDecl gd)
const CIRGenFunctionInfo & arrangeCXXMethodDeclaration(const clang::CXXMethodDecl *md)
C++ methods have some special rules and also have implicit parameters.
const CIRGenFunctionInfo & arrangeCXXStructorDeclaration(clang::GlobalDecl gd)
cir::FuncType getFunctionType(const CIRGenFunctionInfo &info)
Get the CIR function type for.
mlir::Type convertTypeForMem(clang::QualType, bool forBitField=false)
Convert type T into an mlir::Type.
void emitThunks(GlobalDecl gd)
Emit the associated thunks for the given global decl.
void finalize(cir::GlobalOp gv)
mlir::Attribute emitForInitializer(const APValue &value, QualType destType)
virtual clang::LangAS getGlobalVarAddressSpace(CIRGenModule &cgm, const clang::VarDecl *d) const
Get target favored AST address space of a global variable for languages other than OpenCL and CUDA.
virtual mlir::ptr::MemorySpaceAttrInterface getCIRAllocaAddressSpace() const
Get the address space for alloca.
virtual void setTargetAttributes(const clang::Decl *decl, mlir::Operation *global, CIRGenModule &module) const
Provides a convenient hook to handle extra target-specific attributes for the given global.
Represents a base class of a C++ class.
Represents a C++ constructor within a class.
bool isMoveConstructor(unsigned &TypeQuals) const
Determine whether this constructor is a move constructor (C++11 [class.copy]p3), which can be used to...
bool isCopyConstructor(unsigned &TypeQuals) const
Whether this constructor is a copy constructor (C++ [class.copy]p2, which can be used to copy the cla...
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
Represents a static or instance method of a struct/union/class.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
Represents a C++ struct/union/class.
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
bool hasDefinition() const
CharUnits - This is an opaque type for sizes expressed in character units.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
llvm::Reloc::Model RelocationModel
The name of the relocation model to use.
Represents the canonical version of C arrays with a specified constant size.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Decl - This represents one declaration (or definition), e.g.
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
static DeclContext * castToDeclContext(const Decl *)
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Represents a ValueDecl that came out of a declarator.
A little helper class used to produce diagnostics.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
ExplicitCastExpr - An explicit cast written in the source code.
This represents one expression.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Represents a member of a struct/union/class.
Cached information about one file (either on disk or in the virtual file system).
StringRef tryGetRealPathName() const
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Represents a function declaration or definition.
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin=false, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=ConstexprSpecKind::Unspecified, const AssociatedConstraint &TrailingRequiresClause={})
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
FunctionDecl * getDefinition()
Get the definition for this declaration.
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
FunctionType - C99 6.7.5.3 - Function Declarators.
CallingConv getCallConv() const
GlobalDecl - represents a global declaration.
CXXCtorType getCtorType() const
GlobalDecl getCanonicalDecl() const
KernelReferenceKind getKernelReferenceKind() const
GlobalDecl getWithDecl(const Decl *D)
CXXDtorType getDtorType() const
const Decl * getDecl() const
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
void setLinkage(Linkage L)
Linkage getLinkage() const
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
bool shouldMangleDeclName(const NamedDecl *D)
void mangleName(GlobalDecl GD, raw_ostream &)
virtual void mangleReferenceTemporary(const VarDecl *D, unsigned ManglingNumber, raw_ostream &)=0
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
APValue * getOrCreateValue(bool MayCreate) const
Get the storage for the constant value of a materialized temporary of static storage duration.
ValueDecl * getExtendingDecl()
Get the declaration which triggered the lifetime-extension of this temporary, if any.
unsigned getManglingNumber() const
A pointer to member type per C++ 8.3.3 - Pointers to members.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
LinkageInfo getLinkageAndVisibility() const
Determines the linkage and visibility of this entity.
bool hasUnwindExceptions() const
Does this runtime use zero-cost exceptions?
Represents a parameter to a function.
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
A (possibly-)qualified type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
bool isConstQualified() const
Determine whether this type is const-qualified.
bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor, bool ExcludeDtor)
bool hasUnaligned() const
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
StringLiteral - This represents a string literal expression, e.g.
unsigned getLength() const
uint32_t getCodeUnit(size_t i) const
StringRef getString() const
unsigned getCharByteWidth() const
Represents the declaration of a struct/union/class/enum.
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
TargetOptions & getTargetOpts() const
Retrieve the target options.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
bool isReadOnlyFeature(StringRef Feature) const
Determine whether the given target feature is read only.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
virtual bool initFeatureMap(llvm::StringMap< bool > &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector< std::string > &FeatureVec) const
Initialize the map with the default set of target features for the CPU this should include all legal ...
std::vector< std::string > Features
The list of target specific features to enable or disable – this should be a list of strings starting...
std::string TuneCPU
If given, the name of the target CPU to tune code for.
std::string CPU
If given, the name of the target CPU to generate code for.
A template parameter object.
const APValue & getValue() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() const
bool isReferenceType() const
bool isCUDADeviceBuiltinSurfaceType() const
Check if the type is the CUDA device builtin surface type.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isCUDADeviceBuiltinTextureType() const
Check if the type is the CUDA device builtin texture type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isObjCObjectPointerType() const
bool isMemberFunctionPointerType() const
const T * getAs() const
Member-template getAs<specific type>'.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
An artificial decl, representing a global anonymous constant value which is uniquified by value withi...
const APValue & getValue() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
TLSKind getTLSKind() const
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool hasFlexibleArrayInit(const ASTContext &Ctx) const
Whether this variable has a flexible array member initialized with one or more elements.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
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)
CIRGenCUDARuntime * createNVCUDARuntime(CIRGenModule &cgm)
const internal::VariadicDynCastAllOfMatcher< Decl, VarDecl > varDecl
Matches variable declarations.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, FieldDecl > fieldDecl
Matches field declarations.
const internal::VariadicDynCastAllOfMatcher< Decl, FunctionDecl > functionDecl
Matches function declarations.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
GVALinkage
A more specific kind of linkage than enum Linkage.
@ GVA_AvailableExternally
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ SD_Thread
Thread storage duration.
@ SD_Static
Static storage duration.
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Dtor_Complete
Complete object dtor.
LangAS
Defines the address space values used by the address space qualifier of QualType.
@ FirstTargetAddressSpace
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
U cast(CodeGen::Address addr)
bool isExternallyVisible(Linkage L)
static bool globalCtorLexOrder()
static bool opFuncArmNewAttr()
static bool getRuntimeFunctionDecl()
static bool weakRefReference()
static bool opFuncOptNoneAttr()
static bool addressSpace()
static bool opFuncMinSizeAttr()
static bool opGlobalUnnamedAddr()
static bool opGlobalThreadLocal()
static bool opFuncMultiVersioning()
static bool sourceLanguageCases()
static bool 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.