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::amdgcn: {
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())
568 "function declaration that forces code gen");
573 assert(vd->isFileVarDecl() &&
"Cannot emit local var decl as global.");
575 !astContext.isMSStaticDataMemberInlineDefinition(vd)) {
579 if (astContext.getInlineVariableDefinitionKind(vd) ==
618 mlir::Operation *op) {
622 cir::FuncOp funcOp = dyn_cast_if_present<cir::FuncOp>(op);
623 if (!funcOp || funcOp.getFunctionType() != funcType) {
629 if (!funcOp.isDeclaration())
641 mlir::OpBuilder::InsertionGuard guard(builder);
646 setNonAliasAttributes(gd, funcOp);
649 auto getPriority = [
this](
const auto *
attr) ->
int {
653 return attr->DefaultPriority;
656 if (
const ConstructorAttr *ca = funcDecl->getAttr<ConstructorAttr>())
658 if (
const DestructorAttr *da = funcDecl->getAttr<DestructorAttr>())
661 if (funcDecl->getAttr<AnnotateAttr>())
664 if (
getLangOpts().OpenMP && funcDecl->hasAttr<OMPDeclareTargetDeclAttr>())
670 std::optional<int> priority) {
679 ctor.setGlobalCtorPriority(priority);
684 std::optional<int> priority) {
685 if (codeGenOpts.RegisterGlobalDtorsWithAtExit &&
687 errorNYI(dtor.getLoc(),
"registerGlobalDtorsWithAtExit");
690 dtor.setGlobalDtorPriority(priority);
715 mlir::ptr::MemorySpaceAttrInterface addrSpace,
716 mlir::Operation *insertPoint) {
721 mlir::OpBuilder::InsertionGuard guard(builder);
727 builder.setInsertionPoint(insertPoint);
733 builder.setInsertionPointToStart(
getModule().getBody());
736 g = cir::GlobalOp::create(builder, loc, name, t, isConstant, addrSpace);
742 mlir::SymbolTable::setSymbolVisibility(
743 g, mlir::SymbolTable::Visibility::Private);
751 if (isa_and_nonnull<NamedDecl>(d))
755 if (
auto gvi = mlir::dyn_cast<cir::CIRGlobalValueInterface>(gv)) {
756 if (d && d->
hasAttr<UsedAttr>())
759 if (
const auto *vd = dyn_cast_if_present<VarDecl>(d);
760 vd && ((codeGenOpts.KeepPersistentStorageVariables &&
761 (vd->getStorageDuration() ==
SD_Static ||
762 vd->getStorageDuration() ==
SD_Thread)) ||
763 (codeGenOpts.KeepStaticConsts &&
765 vd->getType().isConstQualified())))
771static std::vector<std::string>
773 llvm::StringMap<bool> &featureMap) {
774 llvm::StringMap<bool> defaultFeatureMap;
778 std::vector<std::string> delta;
779 for (
const auto &[k, v] : featureMap) {
780 auto defaultIt = defaultFeatureMap.find(k);
781 if (defaultIt == defaultFeatureMap.end() || defaultIt->getValue() != v)
782 delta.push_back((v ?
"+" :
"-") + k.str());
788bool CIRGenModule::getCPUAndFeaturesAttributes(
789 GlobalDecl gd, llvm::StringMap<std::string> &attrs,
790 bool setTargetFeatures) {
796 std::vector<std::string> features;
800 const auto *fd = dyn_cast_or_null<FunctionDecl>(gd.
getDecl());
801 fd = fd ? fd->getMostRecentDecl() : fd;
802 const auto *td = fd ? fd->getAttr<TargetAttr>() :
nullptr;
803 const auto *tv = fd ? fd->getAttr<TargetVersionAttr>() :
nullptr;
804 assert((!td || !tv) &&
"both target_version and target specified");
805 const auto *sd = fd ? fd->getAttr<CPUSpecificAttr>() :
nullptr;
806 const auto *tc = fd ? fd->getAttr<TargetClonesAttr>() :
nullptr;
807 bool addedAttr =
false;
808 if (td || tv || sd || tc) {
809 llvm::StringMap<bool> featureMap;
810 astContext.getFunctionFeatureMap(featureMap, gd);
816 llvm::StringRef featureStr = td ? td->getFeaturesStr() : llvm::StringRef();
819 if (!featureStr.empty()) {
820 clang::ParsedTargetAttr parsedAttr =
822 if (!parsedAttr.
CPU.empty() &&
824 targetCPU = parsedAttr.
CPU;
827 if (!parsedAttr.
Tune.empty() &&
829 tuneCPU = parsedAttr.
Tune;
845 features.reserve(features.size() + featureMap.size());
846 for (
const auto &entry : featureMap)
847 features.push_back((entry.getValue() ?
"+" :
"-") +
848 entry.getKey().str());
853 llvm::StringMap<bool> featureMap;
855 astContext.getFunctionFeatureMap(featureMap, gd);
866 if (!targetCPU.empty()) {
867 attrs[
"cir.target-cpu"] = targetCPU.str();
870 if (!tuneCPU.empty()) {
871 attrs[
"cir.tune-cpu"] = tuneCPU.str();
874 if (!features.empty() && setTargetFeatures) {
875 llvm::erase_if(features, [&](
const std::string &f) {
876 assert(!f.empty() && (f[0] ==
'+' || f[0] ==
'-') &&
877 "feature string must start with '+' or '-'");
880 llvm::sort(features);
881 attrs[
"cir.target-features"] = llvm::join(features,
",");
889void CIRGenModule::setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op) {
894 if (
auto gvi = mlir::dyn_cast<cir::CIRGlobalValueInterface>(op)) {
895 if (
const auto *sa = d->
getAttr<SectionAttr>())
896 gvi.setSection(builder.getStringAttr(sa->getName()));
900 if (
auto func = dyn_cast<cir::FuncOp>(op)) {
901 llvm::StringMap<std::string> attrs;
902 if (getCPUAndFeaturesAttributes(gd, attrs)) {
906 for (
const auto &[key, val] : attrs)
907 func->setAttr(key, builder.getStringAttr(val));
917std::optional<cir::SourceLanguage> CIRGenModule::getCIRSourceLanguage()
const {
918 using ClangStd = clang::LangStandard;
919 using CIRLang = cir::SourceLanguage;
924 if (opts.C99 || opts.C11 || opts.C17 || opts.C23 || opts.C2y ||
925 opts.LangStd == ClangStd::lang_c89 ||
926 opts.LangStd == ClangStd::lang_gnu89)
931 errorNYI(
"CIR does not yet support the given source language");
935LangAS CIRGenModule::getGlobalVarAddressSpace(
const VarDecl *d) {
936 if (langOpts.OpenCL) {
944 if (langOpts.SYCLIsDevice &&
946 errorNYI(
"SYCL global address space");
948 if (langOpts.CUDA && langOpts.CUDAIsDevice) {
950 if (d->
hasAttr<CUDAConstantAttr>())
952 if (d->
hasAttr<CUDASharedAttr>())
954 if (d->
hasAttr<CUDADeviceAttr>())
963 errorNYI(
"OpenMP global address space");
976 gv.
setLinkage(cir::GlobalLinkageKind::ExternalWeakLinkage);
981 for (mlir::Attribute i : indexes) {
982 auto ind = mlir::cast<mlir::IntegerAttr>(i);
983 inds.push_back(ind.getValue().getSExtValue());
989 return view.getSymbol().getValue() == glob.getSymName();
993 cir::GlobalOp newGlob,
994 cir::GlobalViewAttr
attr,
1005 mlir::Type newTy = newGlob.getSymType();
1010 cir::PointerType newPtrTy;
1013 newPtrTy = cir::PointerType::get(newTy);
1022 cgm.
errorNYI(
"Unhandled type in createNewGlobalView");
1028 mlir::Attribute oldInit) {
1029 if (
auto oldView = mlir::dyn_cast<cir::GlobalViewAttr>(oldInit))
1032 auto getNewInitElements =
1033 [&](mlir::ArrayAttr oldElements) -> mlir::ArrayAttr {
1035 for (mlir::Attribute elt : oldElements) {
1036 if (
auto view = mlir::dyn_cast<cir::GlobalViewAttr>(elt))
1038 else if (mlir::isa<cir::ConstArrayAttr, cir::ConstRecordAttr>(elt))
1041 newElements.push_back(elt);
1043 return mlir::ArrayAttr::get(cgm.
getBuilder().getContext(), newElements);
1046 if (
auto oldArray = mlir::dyn_cast<cir::ConstArrayAttr>(oldInit)) {
1047 mlir::Attribute newElements =
1048 getNewInitElements(mlir::cast<mlir::ArrayAttr>(oldArray.getElts()));
1050 newElements, mlir::cast<cir::ArrayType>(oldArray.getType()));
1052 if (
auto oldRecord = mlir::dyn_cast<cir::ConstRecordAttr>(oldInit)) {
1053 mlir::ArrayAttr newMembers = getNewInitElements(oldRecord.getMembers());
1054 auto recordTy = mlir::cast<cir::RecordType>(oldRecord.getType());
1056 newMembers, recordTy.getPacked(), recordTy.getPadded(), recordTy);
1061 cgm.
errorNYI(
"Unhandled type in getNewInitValue");
1069 assert(oldGV.getSymName() == newGV.getSymName() &&
"symbol names must match");
1071 mlir::Type oldTy = oldGV.getSymType();
1072 mlir::Type newTy = newGV.getSymType();
1077 assert(oldTy != newTy &&
"expected type change in replaceGlobal");
1080 std::optional<mlir::SymbolTable::UseRange> oldSymUses =
1081 oldGV.getSymbolUses(theModule);
1082 for (mlir::SymbolTable::SymbolUse use : *oldSymUses) {
1083 mlir::Operation *userOp = use.getUser();
1085 (mlir::isa<cir::GetGlobalOp, cir::GlobalOp, cir::ConstantOp>(userOp)) &&
1086 "Unexpected user for global op");
1088 if (
auto getGlobalOp = dyn_cast<cir::GetGlobalOp>(use.getUser())) {
1089 mlir::Value useOpResultValue = getGlobalOp.getAddr();
1090 useOpResultValue.setType(cir::PointerType::get(newTy));
1092 mlir::OpBuilder::InsertionGuard guard(builder);
1093 builder.setInsertionPointAfter(getGlobalOp);
1094 mlir::Type ptrTy = builder.getPointerTo(oldTy);
1096 builder.createBitcast(getGlobalOp->getLoc(), useOpResultValue, ptrTy);
1097 useOpResultValue.replaceAllUsesExcept(
cast,
cast.getDefiningOp());
1098 }
else if (
auto glob = dyn_cast<cir::GlobalOp>(userOp)) {
1099 if (
auto init = glob.getInitialValue()) {
1100 mlir::Attribute nw =
getNewInitValue(*
this, newGV, oldTy, init.value());
1101 glob.setInitialValueAttr(nw);
1103 }
else if (
auto c = dyn_cast<cir::ConstantOp>(userOp)) {
1105 auto typedAttr = mlir::cast<mlir::TypedAttr>(init);
1106 mlir::OpBuilder::InsertionGuard guard(builder);
1107 builder.setInsertionPointAfter(
c);
1108 auto newUser = cir::ConstantOp::create(builder,
c.getLoc(), typedAttr);
1109 c.replaceAllUsesWith(newUser.getOperation());
1145 cir::GlobalOp entry;
1149 "getOrCreateCIRGlobal: global with non-GlobalOp type");
1154 mlir::ptr::MemorySpaceAttrInterface entryCIRAS = entry.getAddrSpaceAttr();
1160 if (entry.getSymType() == ty &&
1170 if (isForDefinition && !entry.isDeclaration()) {
1172 "getOrCreateCIRGlobal: global with conflicting type");
1180 if (!isForDefinition)
1189 bool isConstant =
false;
1194 astContext,
true, !needsDtor);
1197 mlir::ptr::MemorySpaceAttrInterface declCIRAS =
1202 cir::GlobalOp gv =
createGlobalOp(loc, mangledName, ty, isConstant, declCIRAS,
1203 entry.getOperation());
1223 if (langOpts.OpenMP && !langOpts.OpenMPSimd)
1225 "getOrCreateCIRGlobal: OpenMP target global variable");
1227 gv.setAlignmentAttr(
getSize(astContext.getDeclAlign(d)));
1238 if (astContext.isMSStaticDataMemberInlineDefinition(d))
1240 "getOrCreateCIRGlobal: MS static data member inline definition");
1244 if (
const SectionAttr *sa = d->
getAttr<SectionAttr>())
1245 gv.setSectionAttr(builder.getStringAttr(sa->getName()));
1249 if (
getTriple().getArch() == llvm::Triple::xcore)
1251 "getOrCreateCIRGlobal: XCore specific ABI requirements");
1261 "getOrCreateCIRGlobal: external const declaration with initializer");
1273 "getOrCreateCIRGlobal: HIP managed attribute");
1308 mlir::Type ptrTy = builder.getPointerTo(g.getSymType(), g.getAddrSpaceAttr());
1309 return cir::GetGlobalOp::create(
1312 g.getStaticLocalGuard().has_value());
1320 cir::PointerType ptrTy =
1321 builder.getPointerTo(globalOp.getSymType(), globalOp.getAddrSpaceAttr());
1322 return builder.getGlobalViewAttr(ptrTy, globalOp);
1326 assert((mlir::isa<cir::FuncOp>(gv.getOperation()) ||
1327 !gv.isDeclarationForLinker()) &&
1328 "Only globals with definition can force usage.");
1333 assert(!gv.isDeclarationForLinker() &&
1334 "Only globals with definition can force usage.");
1339 cir::CIRGlobalValueInterface gv) {
1340 assert((mlir::isa<cir::FuncOp>(gv.getOperation()) ||
1341 !gv.isDeclarationForLinker()) &&
1342 "Only globals with definition can force usage.");
1350 std::vector<cir::CIRGlobalValueInterface> &list) {
1355 mlir::Location loc = builder.getUnknownLoc();
1357 usedArray.resize(list.size());
1358 for (
auto [i, op] : llvm::enumerate(list)) {
1359 usedArray[i] = cir::GlobalViewAttr::get(
1360 cgm.
voidPtrTy, mlir::FlatSymbolRefAttr::get(op.getNameAttr()));
1363 cir::ArrayType arrayTy = cir::ArrayType::get(cgm.
voidPtrTy, usedArray.size());
1365 cir::ConstArrayAttr initAttr = cir::ConstArrayAttr::get(
1366 arrayTy, mlir::ArrayAttr::get(&cgm.
getMLIRContext(), usedArray));
1370 gv.setLinkage(cir::GlobalLinkageKind::AppendingLinkage);
1371 gv.setInitialValueAttr(initAttr);
1372 gv.setSectionAttr(builder.getStringAttr(
"llvm.metadata"));
1384 "emitGlobalVarDefinition: emit OpenCL/OpenMP global variable");
1391 bool isDefinitionAvailableExternally =
1396 if (isDefinitionAvailableExternally &&
1404 mlir::Attribute init;
1405 bool needsGlobalCtor =
false;
1406 bool needsGlobalDtor =
1407 !isDefinitionAvailableExternally &&
1412 std::optional<ConstantEmitter> emitter;
1417 bool isCUDASharedVar =
1422 bool isCUDAShadowVar =
1424 (vd->
hasAttr<CUDAConstantAttr>() || vd->
hasAttr<CUDADeviceAttr>() ||
1425 vd->
hasAttr<CUDASharedAttr>());
1426 bool isCUDADeviceShadowVar =
1432 (isCUDASharedVar || isCUDAShadowVar || isCUDADeviceShadowVar)) {
1434 }
else if (vd->
hasAttr<LoaderUninitializedAttr>()) {
1436 "emitGlobalVarDefinition: loader uninitialized attribute");
1437 }
else if (!initExpr) {
1450 emitter.emplace(*
this);
1451 mlir::Attribute initializer = emitter->tryEmitForInitializer(*initDecl);
1460 "emitGlobalVarDefinition: flexible array initializer");
1462 if (!isDefinitionAvailableExternally)
1463 needsGlobalCtor =
true;
1466 "emitGlobalVarDefinition: static initializer");
1477 mlir::Type initType;
1478 if (mlir::isa<mlir::SymbolRefAttr>(init)) {
1481 "emitGlobalVarDefinition: global initializer is a symbol reference");
1484 assert(mlir::isa<mlir::TypedAttr>(init) &&
"This should have a type");
1485 auto typedInitAttr = mlir::cast<mlir::TypedAttr>(init);
1486 initType = typedInitAttr.getType();
1488 assert(!mlir::isa<mlir::NoneType>(initType) &&
"Should have a type by now");
1494 if (!gv || gv.getSymType() != initType) {
1496 "emitGlobalVarDefinition: global initializer with type mismatch");
1502 if (vd->
hasAttr<AnnotateAttr>())
1515 if (langOpts.CUDA) {
1516 if (langOpts.CUDAIsDevice) {
1519 if (linkage != cir::GlobalLinkageKind::InternalLinkage &&
1521 (vd->
hasAttr<CUDADeviceAttr>() || vd->
hasAttr<CUDAConstantAttr>() ||
1524 gv->setAttr(cir::CUDAExternallyInitializedAttr::getMnemonic(),
1537 emitter->finalize(gv);
1541 gv.setConstant((vd->
hasAttr<CUDAConstantAttr>() && langOpts.CUDAIsDevice) ||
1542 (!needsGlobalCtor && !needsGlobalDtor &&
1547 if (
const SectionAttr *sa = vd->
getAttr<SectionAttr>()) {
1550 gv.setConstant(
true);
1554 gv.setLinkage(linkage);
1558 if (linkage == cir::GlobalLinkageKind::CommonLinkage) {
1560 gv.setConstant(
false);
1565 std::optional<mlir::Attribute> initializer = gv.getInitialValue();
1566 if (initializer && !
getBuilder().isNullValue(*initializer))
1567 gv.setLinkage(cir::GlobalLinkageKind::WeakAnyLinkage);
1570 setNonAliasAttributes(vd, gv);
1578 if (needsGlobalCtor || needsGlobalDtor)
1583 mlir::Operation *op) {
1585 if (
const auto *fd = dyn_cast<FunctionDecl>(
decl)) {
1589 if (
const auto *method = dyn_cast<CXXMethodDecl>(
decl)) {
1593 abi->emitCXXStructor(gd);
1594 else if (fd->isMultiVersion())
1595 errorNYI(method->getSourceRange(),
"multiversion functions");
1599 if (method->isVirtual())
1605 if (fd->isMultiVersion())
1606 errorNYI(fd->getSourceRange(),
"multiversion functions");
1611 if (
const auto *vd = dyn_cast<VarDecl>(
decl))
1614 llvm_unreachable(
"Invalid argument to CIRGenModule::emitGlobalDefinition");
1628 astContext.getAsConstantArrayType(e->
getType());
1629 uint64_t finalSize = cat->getZExtSize();
1630 str.resize(finalSize);
1632 mlir::Type eltTy =
convertType(cat->getElementType());
1633 return builder.getString(str, eltTy, finalSize,
false);
1638 auto arrayEltTy = mlir::cast<cir::IntType>(arrayTy.getElementType());
1640 uint64_t arraySize = arrayTy.getSize();
1642 assert(arraySize > literalSize &&
1643 "wide string literal array size must have room for null terminator?");
1647 bool isAllZero =
true;
1648 for (
unsigned i = 0; i < literalSize; ++i) {
1656 return cir::ZeroAttr::get(arrayTy);
1660 elements.reserve(arraySize);
1661 for (
unsigned i = 0; i < literalSize; ++i)
1662 elements.push_back(cir::IntAttr::get(arrayEltTy, e->
getCodeUnit(i)));
1664 auto elementsAttr = mlir::ArrayAttr::get(&
getMLIRContext(), elements);
1665 return builder.getConstArray(elementsAttr, arrayTy);
1676 if (d.
hasAttr<SelectAnyAttr>())
1680 if (
auto *vd = dyn_cast<VarDecl>(&d))
1695 llvm_unreachable(
"No such linkage");
1701 if (
auto globalOp = dyn_cast_or_null<cir::GlobalOp>(op)) {
1702 globalOp.setComdat(
true);
1705 funcOp.setComdat(
true);
1711 genTypes.updateCompletedType(td);
1715 replacements[name] = op;
1720 mlir::SymbolUserMap &userMap) {
1721 for (mlir::Operation *user : userMap.getUsers(oldF)) {
1722 auto call = mlir::dyn_cast<cir::CallOp>(user);
1726 for (
auto [argOp, fnArgType] :
1727 llvm::zip(call.getArgs(), newF.getFunctionType().getInputs())) {
1728 if (argOp.getType() != fnArgType)
1737void CIRGenModule::applyReplacements() {
1738 if (replacements.empty())
1744 mlir::SymbolTableCollection symbolTableCollection;
1745 mlir::SymbolUserMap userMap(symbolTableCollection, theModule);
1747 for (
auto &i : replacements) {
1748 StringRef mangledName = i.first;
1749 mlir::Operation *replacement = i.second;
1755 auto newF = dyn_cast<cir::FuncOp>(replacement);
1758 errorNYI(replacement->getLoc(),
"replacement is not a function");
1763 "call argument types do not match replacement function");
1767 userMap.replaceAllUsesWith(oldF, newF.getSymNameAttr());
1768 newF->moveBefore(oldF);
1775 mlir::Location loc, StringRef name, mlir::Type ty,
1777 auto gv = mlir::dyn_cast_or_null<cir::GlobalOp>(
getGlobalValue(name));
1781 if (gv.getSymType() == ty)
1787 assert(gv.isDeclaration() &&
"Declaration has wrong type!");
1789 errorNYI(loc,
"createOrReplaceCXXRuntimeVariable: declaration exists with "
1800 mlir::SymbolTable::setSymbolVisibility(gv,
1804 !gv.hasAvailableExternallyLinkage()) {
1808 gv.setAlignmentAttr(
getSize(alignment));
1819 if ((noCommon || vd->
hasAttr<NoCommonAttr>()) && !vd->
hasAttr<CommonAttr>())
1830 if (vd->
hasAttr<SectionAttr>())
1836 if (vd->
hasAttr<PragmaClangBSSSectionAttr>() ||
1837 vd->
hasAttr<PragmaClangDataSectionAttr>() ||
1838 vd->
hasAttr<PragmaClangRelroSectionAttr>() ||
1839 vd->
hasAttr<PragmaClangRodataSectionAttr>())
1847 if (vd->
hasAttr<WeakImportAttr>())
1857 if (vd->
hasAttr<AlignedAttr>())
1864 for (
const FieldDecl *fd : rd->fields()) {
1865 if (fd->isBitField())
1867 if (fd->hasAttr<AlignedAttr>())
1889cir::GlobalLinkageKind
1893 return cir::GlobalLinkageKind::InternalLinkage;
1896 return cir::GlobalLinkageKind::WeakAnyLinkage;
1900 return cir::GlobalLinkageKind::LinkOnceAnyLinkage;
1905 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
1919 return !astContext.getLangOpts().AppleKext
1920 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
1921 : cir::GlobalLinkageKind::InternalLinkage;
1935 return cir::GlobalLinkageKind::ExternalLinkage;
1938 return dd->
hasAttr<CUDAGlobalAttr>()
1939 ? cir::GlobalLinkageKind::ExternalLinkage
1940 : cir::GlobalLinkageKind::InternalLinkage;
1941 return cir::GlobalLinkageKind::WeakODRLinkage;
1949 return cir::GlobalLinkageKind::CommonLinkage;
1955 if (dd->
hasAttr<SelectAnyAttr>())
1956 return cir::GlobalLinkageKind::WeakODRLinkage;
1960 return cir::GlobalLinkageKind::ExternalLinkage;
1972 mlir::Operation *old, cir::FuncOp newFn) {
1974 auto oldFn = mlir::dyn_cast<cir::FuncOp>(old);
1982 if (oldFn->getAttrs().size() <= 1)
1984 "replaceUsesOfNonProtoTypeWithRealFunction: Attribute forwarding");
1987 newFn.setNoProto(oldFn.getNoProto());
1990 std::optional<mlir::SymbolTable::UseRange> symUses =
1991 oldFn.getSymbolUses(oldFn->getParentOp());
1992 for (
const mlir::SymbolTable::SymbolUse &use : symUses.value()) {
1993 mlir::OpBuilder::InsertionGuard guard(builder);
1995 if (
auto noProtoCallOp = mlir::dyn_cast<cir::CallOp>(use.getUser())) {
1996 builder.setInsertionPoint(noProtoCallOp);
1999 cir::FuncType newFnType = newFn.getFunctionType();
2000 mlir::OperandRange callOperands = noProtoCallOp.getOperands();
2001 bool returnTypeMatches =
2002 newFnType.hasVoidReturn()
2003 ? noProtoCallOp.getNumResults() == 0
2004 : noProtoCallOp.getNumResults() == 1 &&
2005 noProtoCallOp.getResultTypes().front() ==
2006 newFnType.getReturnType();
2007 bool typesMatch = !newFn.getNoProto() && returnTypeMatches &&
2008 callOperands.size() == newFnType.getNumInputs();
2009 for (
unsigned i = 0, e = newFnType.getNumInputs(); typesMatch && i != e;
2011 if (callOperands[i].
getType() != newFnType.getInput(i))
2015 cir::CallOp realCallOp;
2019 builder.createCallOp(noProtoCallOp.getLoc(), newFn, callOperands);
2023 cir::FuncType origFnType = oldFn.getFunctionType();
2024 cir::FuncType callFnType =
2025 origFnType.isVarArg()
2026 ? cir::FuncType::get(origFnType.getInputs(),
2027 origFnType.getReturnType(),
2030 mlir::Value addr = cir::GetGlobalOp::create(
2031 builder, noProtoCallOp.getLoc(), cir::PointerType::get(newFnType),
2032 newFn.getSymName());
2033 mlir::Value casted =
2034 builder.createBitcast(addr, cir::PointerType::get(callFnType));
2035 realCallOp = builder.createIndirectCallOp(
2036 noProtoCallOp.getLoc(), casted, callFnType, callOperands);
2040 noProtoCallOp.replaceAllUsesWith(realCallOp);
2041 noProtoCallOp.erase();
2042 }
else if (
auto getGlobalOp =
2043 mlir::dyn_cast<cir::GetGlobalOp>(use.getUser())) {
2050 mlir::Value res = getGlobalOp.getAddr();
2051 const mlir::Type oldResTy = res.getType();
2052 const auto newPtrTy = cir::PointerType::get(newFn.getFunctionType());
2053 if (oldResTy != newPtrTy) {
2054 res.setType(newPtrTy);
2055 builder.setInsertionPointAfter(getGlobalOp.getOperation());
2056 mlir::Value castRes =
2057 cir::CastOp::create(builder, getGlobalOp.getLoc(), oldResTy,
2058 cir::CastKind::bitcast, res);
2059 res.replaceAllUsesExcept(castRes, castRes.getDefiningOp());
2061 }
else if (mlir::isa<cir::GlobalOp>(use.getUser())) {
2067 "replaceUsesOfNonProtoTypeWithRealFunction: unexpected use type");
2072cir::GlobalLinkageKind
2074 GVALinkage linkage = astContext.GetGVALinkageForVariable(vd);
2081 GVALinkage linkage = astContext.GetGVALinkageForFunction(d);
2083 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(d))
2092 StringRef globalName,
CharUnits alignment) {
2101 gv.setAlignmentAttr(cgm.
getSize(alignment));
2103 cir::GlobalLinkageKindAttr::get(cgm.
getBuilder().getContext(), lt));
2107 if (gv.isWeakForLinker()) {
2108 assert(cgm.
supportsCOMDAT() &&
"Only COFF uses weak string literals");
2111 cgm.
setDSOLocal(
static_cast<mlir::Operation *
>(gv));
2132 std::string result =
2143 astContext.getAlignOfGlobalVarInChars(
s->getType(),
nullptr);
2151 if (!gv.getAlignment() ||
2152 uint64_t(alignment.
getQuantity()) > *gv.getAlignment())
2153 gv.setAlignmentAttr(
getSize(alignment));
2158 if (
getCXXABI().getMangleContext().shouldMangleStringLiteral(
s) &&
2161 "getGlobalForStringLiteral: mangle string literals");
2169 mlir::Location loc =
s->getBeginLoc().isValid()
2171 : builder.getUnknownLoc();
2172 auto typedC = llvm::cast<mlir::TypedAttr>(
c);
2174 cir::GlobalLinkageKind::PrivateLinkage, *
this,
2175 uniqueName, alignment);
2189 auto arrayTy = mlir::dyn_cast<cir::ArrayType>(gv.getSymType());
2190 assert(arrayTy &&
"String literal must be array");
2194 return builder.getGlobalViewAttr(ptrTy, gv);
2211 errorNYI(
"SYCL temp address space");
2222 "emitExplicitCastExprType");
2228 auto ty = mlir::cast<cir::MethodType>(
convertType(destTy));
2229 return builder.getNullMethodAttr(ty);
2232 auto ty = mlir::cast<cir::DataMemberType>(
convertType(destTy));
2233 return builder.getNullDataMemberAttr(ty);
2244 if (
const auto *methodDecl = dyn_cast<CXXMethodDecl>(
decl)) {
2246 if (methodDecl->isVirtual())
2247 return cir::ConstantOp::create(
2248 builder, loc,
getCXXABI().buildVirtualMethodAttr(ty, methodDecl));
2254 return cir::ConstantOp::create(builder, loc,
2255 builder.getMethodAttr(ty, methodFuncOp));
2261 return cir::ConstantOp::create(
2262 builder, loc, builder.getDataMemberAttr(ty,
fieldDecl->getFieldIndex()));
2272 if (
auto *oid = dyn_cast<ObjCImplDecl>(
decl))
2273 errorNYI(oid->getSourceRange(),
"emitDeclConext: ObjCImplDecl");
2283 if (
decl->isTemplated())
2286 switch (
decl->getKind()) {
2289 decl->getDeclKindName());
2292 case Decl::CXXConversion:
2293 case Decl::CXXMethod:
2294 case Decl::Function: {
2297 if (!fd->isConsteval())
2306 case Decl::Decomposition:
2307 case Decl::VarTemplateSpecialization: {
2309 if (
auto *decomp = dyn_cast<DecompositionDecl>(
decl))
2310 for (
auto *binding : decomp->flat_bindings())
2311 if (
auto *holdingVar = binding->getHoldingVar())
2315 case Decl::OpenACCRoutine:
2318 case Decl::OpenACCDeclare:
2321 case Decl::OMPThreadPrivate:
2324 case Decl::OMPGroupPrivate:
2327 case Decl::OMPAllocate:
2330 case Decl::OMPCapturedExpr:
2333 case Decl::OMPDeclareReduction:
2336 case Decl::OMPDeclareMapper:
2339 case Decl::OMPRequires:
2344 case Decl::UsingDirective:
2345 case Decl::UsingEnum:
2346 case Decl::NamespaceAlias:
2348 case Decl::TypeAlias:
2354 case Decl::ClassTemplate:
2356 case Decl::CXXDeductionGuide:
2358 case Decl::ExplicitInstantiation:
2359 case Decl::FunctionTemplate:
2360 case Decl::StaticAssert:
2361 case Decl::TypeAliasTemplate:
2362 case Decl::UsingShadow:
2363 case Decl::VarTemplate:
2364 case Decl::VarTemplatePartialSpecialization:
2367 case Decl::CXXConstructor:
2370 case Decl::CXXDestructor:
2375 case Decl::LinkageSpec:
2376 case Decl::Namespace:
2380 case Decl::ClassTemplateSpecialization:
2381 case Decl::CXXRecord: {
2384 for (
auto *childDecl : crd->
decls())
2390 case Decl::FileScopeAsm:
2392 if (langOpts.CUDA && langOpts.CUDAIsDevice)
2395 if (langOpts.OpenMPIsTargetDevice)
2398 if (langOpts.SYCLIsDevice)
2401 std::string line = file_asm->getAsmString();
2402 globalScopeAsm.push_back(builder.getStringAttr(line));
2409 op.setInitialValueAttr(value);
2423 md->getParent()->getNumVBases() == 0)
2425 "getAddrAndTypeOfCXXStructor: MS ABI complete destructor");
2436 false, isForDefinition);
2438 return {fnType, fn};
2442 mlir::Type funcType,
bool forVTable,
2446 "consteval function should never be emitted");
2456 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(gd.
getDecl())) {
2459 dd->getParent()->getNumVBases() == 0)
2461 "getAddrOfFunction: MS ABI complete destructor");
2467 false, isForDefinition);
2469 if (langOpts.CUDA && !langOpts.CUDAIsDevice &&
2475 bool isHIPHandle = mlir::isa<cir::GlobalOp>(*handle);
2476 if (isForDefinition || isHIPHandle)
2478 return mlir::dyn_cast<cir::FuncOp>(*handle);
2487 llvm::raw_svector_ostream
out(buffer);
2496 assert(ii &&
"Attempt to mangle unnamed decl.");
2498 const auto *fd = dyn_cast<FunctionDecl>(nd);
2502 }
else if (fd && fd->hasAttr<CUDAGlobalAttr>() &&
2506 DeviceKernelAttr::isOpenCLSpelling(
2507 fd->getAttr<DeviceKernelAttr>()) &&
2524 if (
const auto *fd = dyn_cast<FunctionDecl>(nd)) {
2525 if (fd->isMultiVersion()) {
2527 "getMangledName: multi-version functions");
2532 "getMangledName: GPU relocatable device code");
2535 return std::string(
out.str());
2538static FunctionDecl *
2553 if (
auto *methodDecl = dyn_cast<CXXMethodDecl>(protoFunc);
2554 methodDecl && methodDecl->isImplicitObjectMemberFunction()) {
2556 paramTypes.insert(paramTypes.begin(), methodDecl->getThisType());
2559 fpt->getExtProtoInfo());
2570 params.reserve(fpt->getNumParams());
2573 for (
unsigned i = 0, e = fpt->getNumParams(); i != e; ++i) {
2577 nullptr, fpt->getParamType(i),
nullptr,
2580 params.push_back(parm);
2583 tempFunc->setParams(params);
2608 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(canonicalGd.
getDecl())) {
2611 "getMangledName: C++ constructor without variants");
2620 auto result = manglings.insert(std::make_pair(mangledName, gd));
2621 return mangledDeclNames[canonicalGd] = result.first->first();
2625 assert(!d->
getInit() &&
"Cannot emit definite definitions here!");
2633 if (gv && !mlir::cast<cir::GlobalOp>(gv).isDeclaration())
2649 if (langOpts.EmitAllDecls)
2652 const auto *vd = dyn_cast<VarDecl>(global);
2654 ((codeGenOpts.KeepPersistentStorageVariables &&
2655 (vd->getStorageDuration() ==
SD_Static ||
2656 vd->getStorageDuration() ==
SD_Thread)) ||
2657 (codeGenOpts.KeepStaticConsts && vd->getStorageDuration() ==
SD_Static &&
2658 vd->getType().isConstQualified())))
2671 if (langOpts.OpenMP >= 50 && !langOpts.OpenMPSimd) {
2672 std::optional<OMPDeclareTargetDeclAttr *> activeAttr =
2673 OMPDeclareTargetDeclAttr::getActiveAttr(global);
2674 if (!activeAttr || (*activeAttr)->getLevel() != (
unsigned)-1)
2678 const auto *fd = dyn_cast<FunctionDecl>(global);
2685 if (fd->hasAttr<TargetVersionAttr>() && !fd->isMultiVersion())
2687 if (langOpts.SYCLIsDevice) {
2688 errorNYI(fd->getSourceRange(),
"mayBeEmittedEagerly: SYCL");
2692 const auto *vd = dyn_cast<VarDecl>(global);
2694 if (astContext.getInlineVariableDefinitionKind(vd) ==
2702 if (langOpts.OpenMP && langOpts.OpenMPUseTLS &&
2703 astContext.getTargetInfo().isTLSSupported() &&
isa<VarDecl>(global) &&
2705 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(global))
2708 assert((fd || vd) &&
2709 "Only FunctionDecl and VarDecl should hit this path so far.");
2714 cir::CIRGlobalValueInterface gv) {
2715 if (gv.hasLocalLinkage())
2718 if (!gv.hasDefaultVisibility() && !gv.hasExternalWeakLinkage())
2726 const llvm::Triple &tt = cgm.
getTriple();
2728 if (tt.isOSCygMing()) {
2737 cgm.
errorNYI(
"shouldAssumeDSOLocal: MinGW");
2743 if (tt.isOSBinFormatCOFF() && gv.hasExternalWeakLinkage())
2751 if (tt.isOSBinFormatCOFF() || (tt.isOSWindows() && tt.isOSBinFormatMachO()))
2755 if (!tt.isOSBinFormatELF())
2760 if (rm != llvm::Reloc::Static && !lOpts.PIE) {
2768 return !(lOpts.SemanticInterposition || lOpts.HalfNoSemanticInterposition);
2772 if (!gv.isDeclarationForLinker())
2778 if (rm == llvm::Reloc::PIC_ && gv.hasExternalWeakLinkage())
2785 if (cgOpts.DirectAccessExternalData) {
2791 if (
auto globalOp = dyn_cast<cir::GlobalOp>(gv.getOperation())) {
2817 if (gv.hasLocalLinkage()) {
2818 gv.setGlobalVisibility(cir::VisibilityKind::Default);
2833 d->
hasAttr<OMPDeclareTargetDeclAttr>() &&
2834 d->
getAttr<OMPDeclareTargetDeclAttr>()->getDevType() !=
2835 OMPDeclareTargetDeclAttr::DT_NoHost &&
2837 llvm_unreachable(
"setGlobalVisibility: OpenMP is NYI");
2846 !d->
hasAttr<OMPDeclareTargetDeclAttr>()) {
2847 bool needsProtected =
false;
2851 }
else if (
const auto *vd = dyn_cast<VarDecl>(d)) {
2852 needsProtected = vd->hasAttr<CUDADeviceAttr>() ||
2853 vd->hasAttr<CUDAConstantAttr>() ||
2854 vd->getType()->isCUDADeviceBuiltinSurfaceType() ||
2855 vd->getType()->isCUDADeviceBuiltinTextureType();
2857 if (needsProtected) {
2858 gv.setGlobalVisibility(cir::VisibilityKind::Protected);
2864 gv.setGlobalVisibility(cir::VisibilityKind::Hidden);
2871 !gv.isDeclarationForLinker())
2880 if (
auto globalValue = dyn_cast<cir::CIRGlobalValueInterface>(op))
2899 auto res = manglings.find(mangledName);
2900 if (res == manglings.end())
2902 result = res->getValue();
2909 return cir::TLS_Model::GeneralDynamic;
2911 return cir::TLS_Model::LocalDynamic;
2913 return cir::TLS_Model::InitialExec;
2915 return cir::TLS_Model::LocalExec;
2917 llvm_unreachable(
"Invalid TLS model!");
2921 assert(d.
getTLSKind() &&
"setting TLS mode on non-TLS var!");
2926 if (d.
getAttr<TLSModelAttr>())
2930 global.setTlsModel(tlm);
2934 if (d.
isStaticLocal() || tlm != cir::TLS_Model::GeneralDynamic)
2942 cir::FuncOp func,
bool isThunk) {
2944 cir::CallingConv callingConv;
2945 cir::SideEffect sideEffect;
2952 mlir::NamedAttrList pal{};
2953 std::vector<mlir::NamedAttrList> argAttrs(info.
arguments().size());
2954 mlir::NamedAttrList retAttrs{};
2956 retAttrs, callingConv, sideEffect,
2959 for (mlir::NamedAttribute
attr : pal)
2960 func->setAttr(
attr.getName(),
attr.getValue());
2962 llvm::for_each(llvm::enumerate(argAttrs), [func](
auto idx_arg_pair) {
2963 mlir::function_interface_impl::setArgAttrs(func, idx_arg_pair.index(),
2964 idx_arg_pair.value());
2966 if (!retAttrs.empty())
2967 mlir::function_interface_impl::setResultAttrs(func, 0, retAttrs);
2980 bool isIncompleteFunction,
2988 if (!isIncompleteFunction)
2990 getTypes().arrangeGlobalDeclaration(globalDecl),
2993 if (!isIncompleteFunction && func.isDeclaration())
2997 if (funcDecl->isInlineBuiltinDeclaration()) {
2999 bool hasBody = funcDecl->
hasBody(fdBody);
3001 assert(hasBody &&
"Inline builtin declarations should always have an "
3006 if (funcDecl->isReplaceableGlobalAllocationFunction()) {
3009 func->setAttr(cir::CIRDialect::getNoBuiltinAttrName(),
3021 if (!langOpts.Exceptions)
3024 if (langOpts.CXXExceptions)
3027 if (langOpts.ObjCExceptions)
3038 f->setAttr(cir::CIRDialect::getNoThrowAttrName(),
3041 std::optional<cir::InlineKind> existingInlineKind = f.getInlineKind();
3043 existingInlineKind && *existingInlineKind == cir::InlineKind::NoInline;
3044 bool isAlwaysInline = existingInlineKind &&
3045 *existingInlineKind == cir::InlineKind::AlwaysInline;
3049 if (!isAlwaysInline &&
3054 f.setInlineKind(cir::InlineKind::NoInline);
3069 if (
decl->hasAttr<NoInlineAttr>() && !isAlwaysInline) {
3071 f.setInlineKind(cir::InlineKind::NoInline);
3072 }
else if (
decl->hasAttr<AlwaysInlineAttr>() && !isNoInline) {
3075 f.setInlineKind(cir::InlineKind::AlwaysInline);
3079 if (!isAlwaysInline)
3080 f.setInlineKind(cir::InlineKind::NoInline);
3085 if (
auto *fd = dyn_cast<FunctionDecl>(
decl)) {
3090 auto checkRedeclForInline = [](
const FunctionDecl *redecl) {
3091 return redecl->isInlineSpecified();
3093 if (any_of(
decl->redecls(), checkRedeclForInline))
3098 return any_of(pattern->
redecls(), checkRedeclForInline);
3100 if (checkForInline(fd)) {
3101 f.setInlineKind(cir::InlineKind::InlineHint);
3102 }
else if (codeGenOpts.getInlining() ==
3104 !fd->isInlined() && !isAlwaysInline) {
3105 f.setInlineKind(cir::InlineKind::NoInline);
3114 StringRef mangledName, mlir::Type funcType,
GlobalDecl gd,
bool forVTable,
3116 mlir::NamedAttrList extraAttrs) {
3119 if (
const auto *fd = cast_or_null<FunctionDecl>(d)) {
3121 if (
getLangOpts().OpenMPIsTargetDevice && openMPRuntime &&
3123 !dontDefer && !isForDefinition) {
3126 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(fdDef))
3128 else if (
const auto *dd = dyn_cast<CXXDestructorDecl>(fdDef))
3138 if (fd->isMultiVersion())
3139 errorNYI(fd->getSourceRange(),
"getOrCreateCIRFunction: multi-version");
3145 assert(mlir::isa<cir::FuncOp>(entry));
3150 if (d && !d->
hasAttr<DLLImportAttr>() && !d->
hasAttr<DLLExportAttr>()) {
3158 if (isForDefinition && fn && !fn.isDeclaration()) {
3165 diagnosedConflictingDefinitions.insert(gd).second) {
3169 diag::note_previous_definition);
3173 if (fn && fn.getFunctionType() == funcType) {
3177 if (!isForDefinition) {
3185 auto *funcDecl = llvm::cast_or_null<FunctionDecl>(gd.
getDecl());
3186 bool invalidLoc = !funcDecl ||
3187 funcDecl->getSourceRange().getBegin().isInvalid() ||
3188 funcDecl->getSourceRange().getEnd().isInvalid();
3190 invalidLoc ? theModule->getLoc() :
getLoc(funcDecl->getSourceRange()),
3191 mangledName, mlir::cast<cir::FuncType>(funcType), funcDecl);
3193 if (funcDecl && funcDecl->hasAttr<AnnotateAttr>())
3194 deferredAnnotations[mangledName] = funcDecl;
3205 auto symbolOp = mlir::cast<mlir::SymbolOpInterface>(entry);
3213 if (symbolOp.getSymbolUses(symbolOp->getParentOp()))
3223 if (!extraAttrs.empty()) {
3224 extraAttrs.append(funcOp->getAttrs());
3225 funcOp->setAttrs(extraAttrs);
3232 assert(funcOp.getFunctionType() == funcType);
3239 if (isa_and_nonnull<CXXDestructorDecl>(d) &&
3269 fd = fd->getPreviousDecl()) {
3271 if (fd->doesThisDeclarationHaveABody()) {
3284 cir::FuncType funcType,
3288 mlir::OpBuilder::InsertionGuard guard(builder);
3296 builder.setInsertionPoint(cgf->
curFn);
3298 func = cir::FuncOp::create(builder, loc, name, funcType);
3305 func.setNoProto(
true);
3307 assert(func.isDeclaration() &&
"expected empty body");
3311 func.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
3313 mlir::SymbolTable::setSymbolVisibility(
3314 func, mlir::SymbolTable::Visibility::Private);
3322 theModule.push_back(func);
3327 for (
const auto *
attr :
3341 fnOp.setBuiltin(
true);
3347 return cir::CtorKind::Default;
3349 return cir::CtorKind::Copy;
3351 return cir::CtorKind::Move;
3352 return cir::CtorKind::Custom;
3357 return cir::AssignKind::Copy;
3359 return cir::AssignKind::Move;
3360 llvm_unreachable(
"not a copy or move assignment operator");
3368 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(funcDecl)) {
3369 auto cxxDtor = cir::CXXDtorAttr::get(
3372 funcOp.setCxxSpecialMemberAttr(cxxDtor);
3376 if (
const auto *ctor = dyn_cast<CXXConstructorDecl>(funcDecl)) {
3378 auto cxxCtor = cir::CXXCtorAttr::get(
3380 kind, ctor->isTrivial());
3381 funcOp.setCxxSpecialMemberAttr(cxxCtor);
3385 const auto *method = dyn_cast<CXXMethodDecl>(funcDecl);
3386 if (method && (method->isCopyAssignmentOperator() ||
3387 method->isMoveAssignmentOperator())) {
3389 auto cxxAssign = cir::CXXAssignAttr::get(
3391 assignKind, method->isTrivial());
3392 funcOp.setCxxSpecialMemberAttr(cxxAssign);
3398 cir::FuncOp funcOp, StringRef name) {
3414 mlir::NamedAttrList extraAttrs,
3416 bool assumeConvergent) {
3417 if (assumeConvergent)
3418 errorNYI(
"createRuntimeFunction: assumeConvergent");
3428 entry.setDSOLocal(
true);
3434mlir::SymbolTable::Visibility
3438 if (op.isDeclaration())
3439 return mlir::SymbolTable::Visibility::Private;
3443mlir::SymbolTable::Visibility
3446 case cir::GlobalLinkageKind::InternalLinkage:
3447 case cir::GlobalLinkageKind::PrivateLinkage:
3448 return mlir::SymbolTable::Visibility::Private;
3449 case cir::GlobalLinkageKind::ExternalLinkage:
3450 case cir::GlobalLinkageKind::ExternalWeakLinkage:
3451 case cir::GlobalLinkageKind::LinkOnceODRLinkage:
3452 case cir::GlobalLinkageKind::AvailableExternallyLinkage:
3453 case cir::GlobalLinkageKind::CommonLinkage:
3454 case cir::GlobalLinkageKind::WeakAnyLinkage:
3455 case cir::GlobalLinkageKind::WeakODRLinkage:
3456 return mlir::SymbolTable::Visibility::Public;
3458 llvm::errs() <<
"visibility not implemented for '"
3459 << stringifyGlobalLinkageKind(glk) <<
"'\n";
3460 assert(0 &&
"not implemented");
3463 llvm_unreachable(
"linkage should be handled above!");
3467 clang::VisibilityAttr::VisibilityType visibility) {
3468 switch (visibility) {
3469 case clang::VisibilityAttr::VisibilityType::Default:
3470 return cir::VisibilityKind::Default;
3471 case clang::VisibilityAttr::VisibilityType::Hidden:
3472 return cir::VisibilityKind::Hidden;
3473 case clang::VisibilityAttr::VisibilityType::Protected:
3474 return cir::VisibilityKind::Protected;
3476 llvm_unreachable(
"unexpected visibility value");
3481 const clang::VisibilityAttr *va =
decl->getAttr<clang::VisibilityAttr>();
3482 cir::VisibilityAttr cirVisibility =
3485 cirVisibility = cir::VisibilityAttr::get(
3489 return cirVisibility;
3495 applyReplacements();
3497 theModule->setAttr(cir::CIRDialect::getModuleLevelAsmAttrName(),
3498 builder.getArrayAttr(globalScopeAsm));
3500 emitGlobalAnnotations();
3502 if (!recordLayoutEntries.empty())
3504 cir::CIRDialect::getRecordLayoutsAttrName(),
3505 mlir::DictionaryAttr::get(&
getMLIRContext(), recordLayoutEntries));
3514 std::string cuidName =
3517 auto loc = builder.getUnknownLoc();
3518 mlir::ptr::MemorySpaceAttrInterface addrSpace =
3520 getGlobalVarAddressSpace(
nullptr));
3524 gv.setLinkage(cir::GlobalLinkageKind::ExternalLinkage);
3526 auto zeroAttr = cir::IntAttr::get(int8Ty, 0);
3527 gv.setInitialValueAttr(zeroAttr);
3529 mlir::SymbolTable::setSymbolVisibility(
3530 gv, mlir::SymbolTable::Visibility::Public);
3535 if (astContext.getLangOpts().CUDA && cudaRuntime)
3550 const AliasAttr *aa = d->
getAttr<AliasAttr>();
3551 assert(aa &&
"Not an alias?");
3555 if (aa->getAliasee() == mangledName) {
3556 diags.Report(aa->getLocation(), diag::err_cyclic_alias) << 0;
3564 auto entryGV = mlir::dyn_cast<cir::CIRGlobalValueInterface>(entry);
3565 if (entryGV && entryGV.isDefinition())
3578 cir::GlobalLinkageKind linkage;
3591 linkage = cir::GlobalLinkageKind::WeakAnyLinkage;
3603 mlir::SymbolTable::Visibility visibility =
3607 cir::CIRGlobalValueInterface alias =
3608 isFunction ? mlir::cast<cir::CIRGlobalValueInterface>(
3610 mlir::cast<cir::FuncType>(declTy),
3613 : mlir::cast<cir::CIRGlobalValueInterface>(
3615 alias.setAliasee(aa->getAliasee());
3616 alias.setLinkage(linkage);
3617 mlir::SymbolTable::setSymbolVisibility(alias, visibility);
3625 cir::FuncOp aliasee,
3626 cir::GlobalLinkageKind linkage) {
3628 auto *aliasFD = dyn_cast<FunctionDecl>(aliasGD.
getDecl());
3629 assert(aliasFD &&
"expected FunctionDecl");
3640 mangledName, fnType, aliasFD);
3641 alias.setAliasee(aliasee.getName());
3642 alias.setLinkage(linkage);
3646 mlir::SymbolTable::setSymbolVisibility(
3647 alias, mlir::SymbolTable::Visibility::Private);
3659 "declaration exists with different type");
3671 return genTypes.convertType(
type);
3678 return mlir::verify(theModule).succeeded();
3687 return builder.getConstNullPtrAttr(builder.getUInt8PtrTy());
3690 langOpts.ObjCRuntime.isGNUFamily()) {
3691 errorNYI(loc,
"getAddrOfRTTIDescriptor: Objc PtrType & Objc RT GUN");
3701 llvm::iterator_range<CastExpr::path_const_iterator> path) {
3708 assert(!base->isVirtual() &&
"Should not see virtual bases here!");
3713 const auto *baseDecl = base->getType()->castAsCXXRecordDecl();
3725 llvm::StringRef feature) {
3726 unsigned diagID = diags.getCustomDiagID(
3728 return diags.Report(loc, diagID) << feature;
3732 llvm::StringRef feature) {
3744 "cannot compile this %0 yet");
3745 diags.Report(astContext.getFullLoc(
s->getBeginLoc()), diagId)
3746 <<
type <<
s->getSourceRange();
3752 "cannot compile this %0 yet");
3753 diags.Report(astContext.getFullLoc(d->
getLocation()), diagId) <<
type;
3757 cir::LabelOp label) {
3758 [[maybe_unused]]
auto result =
3760 assert(result.second &&
3761 "attempting to map a blockaddress info that is already mapped");
3766 assert(result.second &&
3767 "attempting to map a blockaddress operation that is already mapped");
3771 cir::LabelOp label) {
3773 assert(result.second &&
3774 "attempting to map a blockaddress operation that is already mapped");
3778 cir::LabelOp newLabel) {
3781 "trying to update a blockaddress not previously mapped");
3782 assert(!it->second &&
"blockaddress already has a resolved label");
3784 it->second = newLabel;
3797 "not a global temporary");
3809 materializedType = mte->
getType();
3818 llvm::raw_svector_ostream
out(name);
3822 auto insertResult = materializedGlobalTemporaryMap.insert({mte,
nullptr});
3823 if (!insertResult.second) {
3827 if (!insertResult.first->second) {
3830 insertResult.first->second =
3833 return insertResult.first->second;
3850 value = &evalResult.
Val;
3854 std::optional<ConstantEmitter> emitter;
3855 mlir::Attribute initialValue =
nullptr;
3856 bool isConstant =
false;
3860 emitter.emplace(*
this);
3861 initialValue = emitter->emitForInitializer(*value, materializedType);
3866 type = mlir::cast<mlir::TypedAttr>(initialValue).getType();
3875 if (linkage == cir::GlobalLinkageKind::ExternalLinkage) {
3877 if (
varDecl->isStaticDataMember() &&
varDecl->getAnyInitializer(initVD) &&
3885 linkage = cir::GlobalLinkageKind::InternalLinkage;
3889 gv.setInitialValueAttr(initialValue);
3892 emitter->finalize(gv);
3894 if (!gv.hasLocalLinkage()) {
3899 gv.setAlignment(align.getAsAlign().value());
3902 "Global temporary with comdat/weak linkage");
3905 "Global temporary with thread local storage");
3906 mlir::Operation *cv = gv;
3915 mlir::Operation *&entry = materializedGlobalTemporaryMap[mte];
3917 entry->replaceAllUsesWith(cv);
3932 return *globalOpEntry;
3939 "emitForInitializer should take gcd->getType().getAddressSpace()");
3941 auto typedInit = dyn_cast<mlir::TypedAttr>(init);
3945 "getAddrOfUnnamedGlobalConstantDecl: non-typed initializer");
3954 std::string name = numEntries == 0
3956 : (Twine(
".constant.") + Twine(numEntries)).str();
3958 typedInit.getType(),
true);
3959 globalOp.setLinkage(cir::GlobalLinkageKind::PrivateLinkage);
3962 globalOp.setAlignment(alignment.
getAsAlign().value());
3966 *globalOpEntry = globalOp;
3981 "emitForInitializer should take tpo->getType().getAddressSpace()");
3982 mlir::Attribute init =
3992 cir::GlobalLinkageKind linkage =
3994 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
3995 : cir::GlobalLinkageKind::InternalLinkage;
3999 typedInit.getType(),
true);
4000 globalOp.setLinkage(linkage);
4001 globalOp.setAlignment(alignment.
getAsAlign().value());
4003 linkage == cir::GlobalLinkageKind::LinkOnceODRLinkage);
4018CIRGenModule::getOrCreateAnnotationArgs(
const AnnotateAttr *
attr) {
4025 llvm::FoldingSetNodeID id;
4026 for (
Expr *e : exprs)
4029 mlir::ArrayAttr &lookup = annotationArgs[
id.ComputeHash()];
4034 args.reserve(exprs.size());
4035 for (
Expr *e : exprs) {
4036 if (
auto *strE = dyn_cast<clang::StringLiteral>(e->IgnoreParenCasts())) {
4037 args.push_back(builder.getStringAttr(strE->getString()));
4038 }
else if (
auto *intE =
4039 dyn_cast<clang::IntegerLiteral>(e->IgnoreParenCasts())) {
4040 auto intTy = builder.getIntegerType(intE->getValue().getBitWidth());
4041 args.push_back(builder.getIntegerAttr(intTy, intE->getValue()));
4043 errorNYI(e->getExprLoc(),
"annotation argument expression");
4047 return lookup = builder.getArrayAttr(args);
4050cir::AnnotationAttr CIRGenModule::emitAnnotateAttr(
const AnnotateAttr *aa) {
4051 mlir::StringAttr annoGV = builder.getStringAttr(aa->getAnnotation());
4052 mlir::ArrayAttr args = getOrCreateAnnotationArgs(aa);
4053 return cir::AnnotationAttr::get(&
getMLIRContext(), annoGV, args);
4057 mlir::Operation *gv) {
4058 assert(d->
hasAttr<AnnotateAttr>() &&
"no annotate attribute");
4060 "annotation only on globals");
4063 annotations.push_back(emitAnnotateAttr(i));
4064 if (
auto global = dyn_cast<cir::GlobalOp>(gv))
4065 global.setAnnotationsAttr(builder.getArrayAttr(annotations));
4066 else if (
auto func = dyn_cast<cir::FuncOp>(gv))
4067 func.setAnnotationsAttr(builder.getArrayAttr(annotations));
4070void CIRGenModule::emitGlobalAnnotations() {
4071 for (
const auto &[mangledName, vd] : deferredAnnotations) {
4076 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 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 updateResolvedBlockAddress(cir::BlockAddressOp op, cir::LabelOp newLabel)
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.
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)
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 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.
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.
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.
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 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 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
bool isReferenceType() const
bool isCUDADeviceBuiltinSurfaceType() const
Check if the type is the CUDA device builtin surface type.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isCUDADeviceBuiltinTextureType() const
Check if the type is the CUDA device builtin texture type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isObjCObjectPointerType() const
bool isMemberFunctionPointerType() const
const T * getAs() const
Member-template getAs<specific type>'.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
An artificial decl, representing a global anonymous constant value which is uniquified by value withi...
const APValue & getValue() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
TLSKind getTLSKind() const
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool hasFlexibleArrayInit(const ASTContext &Ctx) const
Whether this variable has a flexible array member initialized with one or more elements.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const
Would the destruction of this variable have any effect, and if so, what kind?
const Expr * getInit() const
bool hasExternalStorage() const
Returns true if a variable has extern or private_extern storage.
@ TLS_None
Not a TLS variable.
@ DeclarationOnly
This declaration is only a declaration.
@ Definition
This declaration is definitely a definition.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
TemplateSpecializationKind getTemplateSpecializationKind() const
If this variable is an instantiation of a variable template or a static data member of a class templa...
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
bool isMatchingAddressSpace(mlir::ptr::MemorySpaceAttrInterface cirAS, clang::LangAS as)
mlir::ptr::MemorySpaceAttrInterface toCIRAddressSpaceAttr(mlir::MLIRContext &ctx, clang::LangAS langAS)
Convert an AST LangAS to the appropriate CIR address space attribute interface.
static bool isWeakForLinker(GlobalLinkageKind linkage)
Whether the definition of this global may be replaced at link time.
@ AttributedType
The l-value was considered opaque, so the alignment was determined from a type, but that type was an ...
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
std::unique_ptr< TargetCIRGenInfo > createAMDGPUTargetCIRGenInfo(CIRGenTypes &cgt)
std::unique_ptr< TargetCIRGenInfo > createNVPTXTargetCIRGenInfo(CIRGenTypes &cgt)
CIRGenCXXABI * CreateCIRGenItaniumCXXABI(CIRGenModule &cgm)
Creates and Itanium-family ABI.
std::unique_ptr< TargetCIRGenInfo > createX8664TargetCIRGenInfo(CIRGenTypes &cgt)
std::unique_ptr< TargetCIRGenInfo > createSPIRVTargetCIRGenInfo(CIRGenTypes &cgt)
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.
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.