19#include "mlir/Dialect/OpenMP/Utils/Utils.h"
20#include "mlir/IR/SymbolTable.h"
23#include "clang/AST/Attrs.inc"
40#include "llvm/ADT/STLExtras.h"
41#include "llvm/ADT/StringExtras.h"
42#include "llvm/ADT/StringRef.h"
43#include "llvm/ADT/StringSwitch.h"
44#include "llvm/Support/raw_ostream.h"
48#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
49#include "mlir/IR/Attributes.h"
50#include "mlir/IR/BuiltinOps.h"
51#include "mlir/IR/Location.h"
52#include "mlir/IR/MLIRContext.h"
53#include "mlir/IR/Operation.h"
54#include "mlir/IR/Verifier.h"
63 case TargetCXXABI::GenericItanium:
64 case TargetCXXABI::GenericAArch64:
65 case TargetCXXABI::AppleARM64:
66 case TargetCXXABI::GenericARM:
69 case TargetCXXABI::Fuchsia:
70 case TargetCXXABI::iOS:
71 case TargetCXXABI::WatchOS:
72 case TargetCXXABI::GenericMIPS:
73 case TargetCXXABI::WebAssembly:
74 case TargetCXXABI::XL:
75 case TargetCXXABI::Microsoft:
76 cgm.
errorNYI(
"createCXXABI: C++ ABI kind");
80 llvm_unreachable(
"invalid C++ ABI kind");
83CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
87 : builder(mlirContext, *this), astContext(astContext),
88 langOpts(astContext.
getLangOpts()), codeGenOpts(cgo),
89 theModule{
mlir::ModuleOp::create(
mlir::UnknownLoc::get(&mlirContext))},
90 diags(diags), target(astContext.getTargetInfo()),
91 abi(
createCXXABI(*this)), genTypes(*this), vtables(*this) {
119 .toCharUnitsFromBits(
123 const unsigned charSize = target.getCharWidth();
126 const unsigned sizeTypeSize = target.getTypeWidth(target.getSizeType());
134 std::optional<cir::SourceLanguage> sourceLanguage = getCIRSourceLanguage();
137 cir::CIRDialect::getSourceLanguageAttrName(),
138 cir::SourceLanguageAttr::get(&mlirContext, *sourceLanguage));
139 theModule->setAttr(cir::CIRDialect::getTripleAttrName(),
140 builder.getStringAttr(
getTriple().str()));
143 theModule->setAttr(cir::CIRDialect::getSizeTypeWidthAttrName(),
144 builder.getI32IntegerAttr(sizeTypeSize));
145 theModule->setAttr(cir::CIRDialect::getIntTypeWidthAttrName(),
146 builder.getI32IntegerAttr(target.getIntWidth()));
148 if (cgo.OptimizationLevel > 0 || cgo.OptimizeSize > 0)
149 theModule->setAttr(cir::CIRDialect::getOptInfoAttrName(),
150 cir::OptInfoAttr::get(&mlirContext,
151 cgo.OptimizationLevel,
155 cir::CIRDialect::getDefaultTlsModelAttrName(),
158 if (langOpts.OpenMP) {
159 mlir::omp::OffloadModuleOpts ompOpts(
160 langOpts.OpenMPTargetDebug, langOpts.OpenMPTeamSubscription,
161 langOpts.OpenMPThreadSubscription, langOpts.OpenMPNoThreadState,
162 langOpts.OpenMPNoNestedParallelism, langOpts.OpenMPIsTargetDevice,
163 getTriple().isGPU(), langOpts.OpenMPForceUSM, langOpts.OpenMP,
164 langOpts.OMPHostIRFile, langOpts.OMPTargetTriples, langOpts.NoGPULib);
165 mlir::omp::setOffloadModuleInterfaceAttributes(theModule, ompOpts);
166 mlir::omp::setOpenMPVersionAttribute(theModule, langOpts.OpenMP);
172 createOpenMPRuntime();
177 FileID mainFileId = astContext.getSourceManager().getMainFileID();
179 *astContext.getSourceManager().getFileEntryForID(mainFileId);
182 theModule.setSymName(path);
183 theModule->setLoc(mlir::FileLineColLoc::get(&mlirContext, path,
190 llvm::StringRef cudaBinaryName = codeGenOpts.OffloadBinaryToEmbedFile;
191 if (!cudaBinaryName.empty()) {
192 theModule->setAttr(cir::CIRDialect::getCUDABinaryHandleAttrName(),
193 cir::CUDABinaryHandleAttr::get(
194 &mlirContext, mlir::StringAttr::get(
195 &mlirContext, cudaBinaryName)));
202void CIRGenModule::createCUDARuntime() {
206void CIRGenModule::createOpenMPRuntime() {
207 openMPRuntime = std::make_unique<CIRGenOpenMPRuntime>(*
this);
218 auto &layout = astContext.getASTRecordLayout(rd);
223 return layout.getAlignment();
226 return layout.getNonVirtualAlignment();
231 bool forPointeeType) {
241 if (
unsigned align = tt->getDecl()->getMaxAlignment()) {
244 return astContext.toCharUnitsFromBits(align);
252 t = astContext.getBaseElementType(t);
273 }
else if (forPointeeType && !alignForArray &&
277 alignment = astContext.getTypeAlignInChars(t);
282 if (
unsigned maxAlign = astContext.getLangOpts().MaxTypeAlign) {
284 !astContext.isAlignmentRequired(t))
298 if (theTargetCIRGenInfo)
299 return *theTargetCIRGenInfo;
302 switch (triple.getArch()) {
309 case llvm::Triple::x86_64: {
310 switch (triple.getOS()) {
317 case llvm::Triple::Linux:
319 return *theTargetCIRGenInfo;
322 case llvm::Triple::aarch64:
323 case llvm::Triple::aarch64_32:
324 case llvm::Triple::aarch64_be: {
326 return *theTargetCIRGenInfo;
328 case llvm::Triple::nvptx:
329 case llvm::Triple::nvptx64:
331 return *theTargetCIRGenInfo;
332 case llvm::Triple::amdgpu: {
334 return *theTargetCIRGenInfo;
336 case llvm::Triple::spir:
337 case llvm::Triple::spir64:
338 case llvm::Triple::spirv:
339 case llvm::Triple::spirv32:
340 case llvm::Triple::spirv64:
342 return *theTargetCIRGenInfo;
347 assert(cLoc.
isValid() &&
"expected valid source location");
351 return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
356 assert(cRange.
isValid() &&
"expected a valid source range");
359 mlir::Attribute metadata;
360 return mlir::FusedLoc::get({begin, end}, metadata, builder.getContext());
369 false, isForDefinition);
403 assert(op &&
"expected a valid global op");
411 mlir::Operation *globalValueOp = op;
412 if (
auto gv = dyn_cast<cir::GetGlobalOp>(op)) {
414 assert(globalValueOp &&
"expected a valid global op");
417 if (
auto cirGlobalValue =
418 dyn_cast<cir::CIRGlobalValueInterface>(globalValueOp))
419 if (!cirGlobalValue.isDeclaration())
440 assert(deferredVTables.empty());
450 std::vector<GlobalDecl> curDeclsToEmit;
458 if (
const auto *fd = d.getDecl()->getAsFunction()) {
459 if (langOpts.SYCLIsDevice && fd->hasAttr<SYCLKernelEntryPointAttr>() &&
463 if (!fd->getAttr<SYCLKernelEntryPointAttr>()->isInvalidAttr()) {
490 if (
auto *
attr =
decl->getAttr<AttrT>())
491 return attr->isImplicit();
492 return decl->isImplicit();
497 assert(langOpts.CUDA &&
"Should not be called by non-CUDA languages");
502 return !langOpts.CUDAIsDevice || global->
hasAttr<CUDADeviceAttr>() ||
503 global->
hasAttr<CUDAConstantAttr>() ||
504 global->
hasAttr<CUDASharedAttr>() ||
514 os << (isa<VarDecl>(d) ?
".static." :
".intern.");
516 os << (isa<VarDecl>(d) ?
"__static__" :
"__intern__");
523 "printPostfixForExternalizedDecl: CUID is not specified");
530 if (
const auto *cd = dyn_cast<clang::OpenACCConstructDecl>(gd.
getDecl())) {
538 if (global->hasAttr<WeakRefAttr>())
543 if (global->hasAttr<AliasAttr>()) {
556 "Expected Variable or Function");
557 if (
const auto *
varDecl = dyn_cast<VarDecl>(global)) {
561 }
else if (langOpts.CUDAIsDevice) {
562 const auto *
functionDecl = dyn_cast<FunctionDecl>(global);
563 if ((!global->hasAttr<CUDADeviceAttr>() ||
564 (langOpts.OffloadImplicitHostDeviceTemplates &&
569 !
getASTContext().CUDAImplicitHostDeviceFunUsedByDevice.count(
571 !global->hasAttr<CUDAGlobalAttr>() &&
573 !global->hasAttr<CUDAHostAttr>()))
576 }
else if (!global->hasAttr<CUDAHostAttr>() &&
577 global->hasAttr<CUDADeviceAttr>())
581 if (langOpts.OpenMP) {
583 if (openMPRuntime && openMPRuntime->emitTargetGlobal(gd))
585 if (
auto *drd = dyn_cast<OMPDeclareReductionDecl>(global)) {
590 if (
auto *dmd = dyn_cast<OMPDeclareMapperDecl>(global)) {
597 if (
const auto *fd = dyn_cast<FunctionDecl>(global)) {
600 if (fd->hasAttr<AnnotateAttr>()) {
603 deferredAnnotations[mangledName] = fd;
605 if (!fd->doesThisDeclarationHaveABody()) {
606 if (!fd->doesDeclarationForceExternallyVisibleDefinition() &&
617 assert(vd->isFileVarDecl() &&
"Cannot emit local var decl as global.");
619 !astContext.isMSStaticDataMemberInlineDefinition(vd)) {
623 if (astContext.getInlineVariableDefinitionKind(vd) ==
662 mlir::Operation *op) {
666 cir::FuncOp funcOp = dyn_cast_if_present<cir::FuncOp>(op);
667 if (!funcOp || funcOp.getFunctionType() != funcType) {
673 if (!funcOp.isDeclaration())
685 mlir::OpBuilder::InsertionGuard guard(builder);
690 setNonAliasAttributes(gd, funcOp);
693 auto getPriority = [
this](
const auto *
attr) ->
int {
697 return attr->DefaultPriority;
700 if (
const ConstructorAttr *ca = funcDecl->getAttr<ConstructorAttr>())
702 if (
const DestructorAttr *da = funcDecl->getAttr<DestructorAttr>())
705 if (funcDecl->getAttr<AnnotateAttr>())
708 if (
getLangOpts().OpenMP && funcDecl->hasAttr<OMPDeclareTargetDeclAttr>())
714 std::optional<int> priority) {
723 ctor.setGlobalCtorPriority(priority);
728 std::optional<int> priority) {
729 if (codeGenOpts.RegisterGlobalDtorsWithAtExit &&
731 errorNYI(dtor.getLoc(),
"registerGlobalDtorsWithAtExit");
734 dtor.setGlobalDtorPriority(priority);
760 mlir::ptr::MemorySpaceAttrInterface addrSpace,
761 mlir::Operation *insertPoint) {
766 mlir::OpBuilder::InsertionGuard guard(builder);
772 builder.setInsertionPoint(insertPoint);
778 builder.setInsertionPointToStart(
getModule().getBody());
781 g = cir::GlobalOp::create(builder, loc, name, t, isConstant, addrSpace);
787 mlir::SymbolTable::setSymbolVisibility(
788 g, mlir::SymbolTable::Visibility::Private);
796 if (isa_and_nonnull<NamedDecl>(d))
800 if (
auto gvi = mlir::dyn_cast<cir::CIRGlobalValueInterface>(gv)) {
801 if (d && d->
hasAttr<UsedAttr>())
804 if (
const auto *vd = dyn_cast_if_present<VarDecl>(d);
805 vd && ((codeGenOpts.KeepPersistentStorageVariables &&
806 (vd->getStorageDuration() ==
SD_Static ||
807 vd->getStorageDuration() ==
SD_Thread)) ||
808 (codeGenOpts.KeepStaticConsts &&
810 vd->getType().isConstQualified())))
816static std::vector<std::string>
818 llvm::StringMap<bool> &featureMap) {
819 llvm::StringMap<bool> defaultFeatureMap;
823 std::vector<std::string> delta;
824 for (
const auto &[k, v] : featureMap) {
825 auto defaultIt = defaultFeatureMap.find(k);
826 if (defaultIt == defaultFeatureMap.end() || defaultIt->getValue() != v)
827 delta.push_back((v ?
"+" :
"-") + k.str());
833bool CIRGenModule::getCPUAndFeaturesAttributes(
834 GlobalDecl gd, llvm::StringMap<std::string> &attrs,
835 bool setTargetFeatures) {
841 std::vector<std::string> features;
845 const auto *fd = dyn_cast_or_null<FunctionDecl>(gd.
getDecl());
846 fd = fd ? fd->getMostRecentDecl() : fd;
847 const auto *td = fd ? fd->getAttr<TargetAttr>() :
nullptr;
848 const auto *tv = fd ? fd->getAttr<TargetVersionAttr>() :
nullptr;
849 assert((!td || !tv) &&
"both target_version and target specified");
850 const auto *sd = fd ? fd->getAttr<CPUSpecificAttr>() :
nullptr;
851 const auto *tc = fd ? fd->getAttr<TargetClonesAttr>() :
nullptr;
852 bool addedAttr =
false;
853 if (td || tv || sd || tc) {
854 llvm::StringMap<bool> featureMap;
855 astContext.getFunctionFeatureMap(featureMap, gd);
861 llvm::StringRef featureStr = td ? td->getFeaturesStr() : llvm::StringRef();
864 if (!featureStr.empty()) {
865 clang::ParsedTargetAttr parsedAttr =
867 if (!parsedAttr.
CPU.empty() &&
869 targetCPU = parsedAttr.
CPU;
872 if (!parsedAttr.
Tune.empty() &&
874 tuneCPU = parsedAttr.
Tune;
890 features.reserve(features.size() + featureMap.size());
891 for (
const auto &entry : featureMap)
892 features.push_back((entry.getValue() ?
"+" :
"-") +
893 entry.getKey().str());
898 llvm::StringMap<bool> featureMap;
900 astContext.getFunctionFeatureMap(featureMap, gd);
911 if (!targetCPU.empty()) {
912 attrs[cir::CIRDialect::getTargetCPUAttrName()] = targetCPU.str();
915 if (!tuneCPU.empty()) {
916 attrs[cir::CIRDialect::getTuneCPUAttrName()] = tuneCPU.str();
919 if (!features.empty() && setTargetFeatures) {
920 llvm::erase_if(features, [&](
const std::string &f) {
921 assert(!f.empty() && (f[0] ==
'+' || f[0] ==
'-') &&
922 "feature string must start with '+' or '-'");
925 llvm::sort(features);
926 attrs[cir::CIRDialect::getTargetFeaturesAttrName()] =
927 llvm::join(features,
",");
935void CIRGenModule::setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op) {
940 if (
auto gvi = mlir::dyn_cast<cir::CIRGlobalValueInterface>(op)) {
941 if (
const auto *sa = d->
getAttr<SectionAttr>())
942 gvi.setSection(builder.getStringAttr(sa->getName()));
946 if (
auto func = dyn_cast<cir::FuncOp>(op)) {
947 llvm::StringMap<std::string> attrs;
948 if (getCPUAndFeaturesAttributes(gd, attrs)) {
955 for (llvm::StringRef name :
956 {cir::CIRDialect::getTargetCPUAttrName(),
957 cir::CIRDialect::getTuneCPUAttrName(),
958 cir::CIRDialect::getTargetFeaturesAttrName()})
959 func->removeAttr(name);
960 for (
const auto &[key, val] : attrs)
961 func->setAttr(key, builder.getStringAttr(val));
971std::optional<cir::SourceLanguage> CIRGenModule::getCIRSourceLanguage()
const {
972 using ClangStd = clang::LangStandard;
973 using CIRLang = cir::SourceLanguage;
976 if (opts.OpenCLCPlusPlus)
977 return CIRLang::OpenCLCXX;
979 return CIRLang::OpenCLC;
982 if (opts.C99 || opts.C11 || opts.C17 || opts.C23 || opts.C2y ||
983 opts.LangStd == ClangStd::lang_c89 ||
984 opts.LangStd == ClangStd::lang_gnu89)
989 errorNYI(
"CIR does not yet support the given source language");
993LangAS CIRGenModule::getGlobalVarAddressSpace(
const VarDecl *d) {
994 if (langOpts.OpenCL) {
1002 if (langOpts.SYCLIsDevice &&
1004 errorNYI(
"SYCL global address space");
1006 if (langOpts.CUDA && langOpts.CUDAIsDevice) {
1008 if (d->
hasAttr<CUDAConstantAttr>())
1010 if (d->
hasAttr<CUDASharedAttr>())
1012 if (d->
hasAttr<CUDADeviceAttr>())
1020 if (langOpts.OpenMP)
1021 errorNYI(
"OpenMP global address space");
1034 gv.
setLinkage(cir::GlobalLinkageKind::ExternalWeakLinkage);
1043 auto linkage = cir::GlobalLinkageKind::ExternalWeakLinkage;
1044 func.setLinkage(linkage);
1045 func.setLinkageAttr(
1046 cir::GlobalLinkageKindAttr::get(&cgm.
getMLIRContext(), linkage));
1048 if (!func.isDeclaration())
1049 mlir::SymbolTable::setSymbolVisibility(
1056 for (mlir::Attribute i : indexes) {
1057 auto ind = mlir::cast<mlir::IntegerAttr>(i);
1058 inds.push_back(ind.getValue().getSExtValue());
1064 return view.getSymbol().getValue() == glob.getSymName();
1068 cir::GlobalOp newGlob,
1069 cir::GlobalViewAttr
attr,
1080 mlir::Type newTy = newGlob.getSymType();
1086 return cir::GlobalOffsetAttr::get(
attr.getType(),
attr.getSymbol(),
1087 static_cast<int64_t
>(offset));
1089 cir::PointerType newPtrTy;
1092 newPtrTy = cir::PointerType::get(newTy);
1101 cgm.
errorNYI(
"Unhandled type in createNewGlobalView");
1107 mlir::Attribute oldInit) {
1108 if (
auto oldView = mlir::dyn_cast<cir::GlobalViewAttr>(oldInit))
1113 if (mlir::isa<cir::GlobalOffsetAttr>(oldInit))
1116 auto getNewInitElements =
1117 [&](mlir::ArrayAttr oldElements) -> mlir::ArrayAttr {
1119 for (mlir::Attribute elt : oldElements) {
1120 if (
auto view = mlir::dyn_cast<cir::GlobalViewAttr>(elt))
1122 else if (mlir::isa<cir::ConstArrayAttr, cir::ConstRecordAttr>(elt))
1125 newElements.push_back(elt);
1127 return mlir::ArrayAttr::get(cgm.
getBuilder().getContext(), newElements);
1130 if (
auto oldArray = mlir::dyn_cast<cir::ConstArrayAttr>(oldInit)) {
1136 mlir::Attribute oldElts = oldArray.getElts();
1137 if (mlir::isa<mlir::StringAttr>(oldElts))
1139 mlir::Attribute newElements =
1140 getNewInitElements(mlir::cast<mlir::ArrayAttr>(oldElts));
1142 newElements, mlir::cast<cir::ArrayType>(oldArray.getType()));
1144 if (
auto oldRecord = mlir::dyn_cast<cir::ConstRecordAttr>(oldInit)) {
1145 mlir::ArrayAttr newMembers = getNewInitElements(oldRecord.getMembers());
1146 auto recordTy = mlir::cast<cir::RecordType>(oldRecord.getType());
1152 cgm.
errorNYI(
"Unhandled type in getNewInitValue");
1160 assert(oldGV.getSymName() == newGV.getSymName() &&
"symbol names must match");
1162 mlir::Type oldTy = oldGV.getSymType();
1163 mlir::Type newTy = newGV.getSymType();
1168 assert(oldTy != newTy &&
"expected type change in replaceGlobal");
1171 std::optional<mlir::SymbolTable::UseRange> oldSymUses =
1172 oldGV.getSymbolUses(theModule);
1173 for (mlir::SymbolTable::SymbolUse use : *oldSymUses) {
1174 mlir::Operation *userOp = use.getUser();
1176 (mlir::isa<cir::GetGlobalOp, cir::GlobalOp, cir::ConstantOp>(userOp)) &&
1177 "Unexpected user for global op");
1179 if (
auto getGlobalOp = dyn_cast<cir::GetGlobalOp>(use.getUser())) {
1180 mlir::Value useOpResultValue = getGlobalOp.getAddr();
1181 useOpResultValue.setType(cir::PointerType::get(newTy));
1183 mlir::OpBuilder::InsertionGuard guard(builder);
1184 builder.setInsertionPointAfter(getGlobalOp);
1185 mlir::Type ptrTy = builder.getPointerTo(oldTy);
1187 builder.createBitcast(getGlobalOp->getLoc(), useOpResultValue, ptrTy);
1188 useOpResultValue.replaceAllUsesExcept(
cast,
cast.getDefiningOp());
1189 }
else if (
auto glob = dyn_cast<cir::GlobalOp>(userOp)) {
1190 if (
auto init = glob.getInitialValue()) {
1191 mlir::Attribute nw =
getNewInitValue(*
this, newGV, oldTy, init.value());
1192 glob.setInitialValueAttr(nw);
1194 }
else if (
auto c = dyn_cast<cir::ConstantOp>(userOp)) {
1195 mlir::Attribute init =
getNewInitValue(*
this, newGV, oldTy, c.getValue());
1196 auto typedAttr = mlir::cast<mlir::TypedAttr>(init);
1197 mlir::OpBuilder::InsertionGuard guard(builder);
1198 builder.setInsertionPointAfter(c);
1199 auto newUser = cir::ConstantOp::create(builder, c.getLoc(), typedAttr);
1200 c.replaceAllUsesWith(newUser.getOperation());
1236 cir::GlobalOp entry;
1240 "getOrCreateCIRGlobal: global with non-GlobalOp type");
1245 mlir::ptr::MemorySpaceAttrInterface entryCIRAS = entry.getAddrSpaceAttr();
1251 if (entry.getSymType() == ty &&
1261 if (isForDefinition && !entry.isDeclaration()) {
1263 "getOrCreateCIRGlobal: global with conflicting type");
1271 if (!isForDefinition)
1280 bool isConstant =
false;
1288 mlir::ptr::MemorySpaceAttrInterface declCIRAS =
1293 cir::GlobalOp gv =
createGlobalOp(loc, mangledName, ty, isConstant, declCIRAS,
1294 entry.getOperation());
1314 if (langOpts.OpenMP && !langOpts.OpenMPSimd)
1316 "getOrCreateCIRGlobal: OpenMP target global variable");
1318 gv.setAlignmentAttr(
getSize(astContext.getDeclAlign(d)));
1329 if (astContext.isMSStaticDataMemberInlineDefinition(d))
1331 "getOrCreateCIRGlobal: MS static data member inline definition");
1335 if (
const SectionAttr *sa = d->
getAttr<SectionAttr>())
1336 gv.setSectionAttr(builder.getStringAttr(sa->getName()));
1340 if (
getTriple().getArch() == llvm::Triple::xcore)
1342 "getOrCreateCIRGlobal: XCore specific ABI requirements");
1352 "getOrCreateCIRGlobal: external const declaration with initializer");
1364 "getOrCreateCIRGlobal: HIP managed attribute");
1399 mlir::Type ptrTy = builder.getPointerTo(g.getSymType(), g.getAddrSpaceAttr());
1400 return cir::GetGlobalOp::create(
1403 g.getStaticLocalGuard().has_value());
1411 cir::PointerType ptrTy =
1412 builder.getPointerTo(globalOp.getSymType(), globalOp.getAddrSpaceAttr());
1413 return builder.getGlobalViewAttr(ptrTy, globalOp);
1417 assert((mlir::isa<cir::FuncOp>(gv.getOperation()) ||
1418 !gv.isDeclarationForLinker()) &&
1419 "Only globals with definition can force usage.");
1424 assert(!gv.isDeclarationForLinker() &&
1425 "Only globals with definition can force usage.");
1430 cir::CIRGlobalValueInterface gv) {
1431 assert((mlir::isa<cir::FuncOp>(gv.getOperation()) ||
1432 !gv.isDeclarationForLinker()) &&
1433 "Only globals with definition can force usage.");
1441 std::vector<cir::CIRGlobalValueInterface> &list) {
1446 mlir::Location loc = builder.getUnknownLoc();
1448 usedArray.resize(list.size());
1449 for (
auto [i, op] : llvm::enumerate(list)) {
1450 usedArray[i] = cir::GlobalViewAttr::get(
1451 cgm.
voidPtrTy, mlir::FlatSymbolRefAttr::get(op.getNameAttr()));
1454 cir::ArrayType arrayTy = cir::ArrayType::get(cgm.
voidPtrTy, usedArray.size());
1456 cir::ConstArrayAttr initAttr = cir::ConstArrayAttr::get(
1457 arrayTy, mlir::ArrayAttr::get(&cgm.
getMLIRContext(), usedArray));
1461 gv.setLinkage(cir::GlobalLinkageKind::AppendingLinkage);
1462 gv.setInitialValueAttr(initAttr);
1463 gv.setSectionAttr(builder.getStringAttr(
"llvm.metadata"));
1475 "emitGlobalVarDefinition: emit OpenCL/OpenMP global variable");
1482 bool isDefinitionAvailableExternally =
1487 if (isDefinitionAvailableExternally &&
1495 mlir::Attribute init;
1496 bool needsGlobalCtor =
false;
1497 bool needsGlobalDtor =
1498 !isDefinitionAvailableExternally &&
1503 std::optional<ConstantEmitter> emitter;
1508 bool isCUDASharedVar =
1513 bool isCUDAShadowVar =
1515 (vd->
hasAttr<CUDAConstantAttr>() || vd->
hasAttr<CUDADeviceAttr>() ||
1516 vd->
hasAttr<CUDASharedAttr>());
1517 bool isCUDADeviceShadowVar =
1523 (isCUDASharedVar || isCUDAShadowVar || isCUDADeviceShadowVar)) {
1525 }
else if (vd->
hasAttr<LoaderUninitializedAttr>()) {
1527 "emitGlobalVarDefinition: loader uninitialized attribute");
1528 }
else if (!initExpr) {
1541 emitter.emplace(*
this);
1542 mlir::Attribute initializer = emitter->tryEmitForInitializer(*initDecl);
1551 "emitGlobalVarDefinition: flexible array initializer");
1553 if (!isDefinitionAvailableExternally)
1554 needsGlobalCtor =
true;
1557 "emitGlobalVarDefinition: static initializer");
1568 mlir::Type initType;
1569 if (mlir::isa<mlir::SymbolRefAttr>(init)) {
1572 "emitGlobalVarDefinition: global initializer is a symbol reference");
1575 assert(mlir::isa<mlir::TypedAttr>(init) &&
"This should have a type");
1576 auto typedInitAttr = mlir::cast<mlir::TypedAttr>(init);
1577 initType = typedInitAttr.getType();
1579 assert(!mlir::isa<mlir::NoneType>(initType) &&
"Should have a type by now");
1585 if (!gv || gv.getSymType() != initType) {
1587 "emitGlobalVarDefinition: global initializer with type mismatch");
1593 if (vd->
hasAttr<AnnotateAttr>())
1606 if (langOpts.CUDA) {
1607 if (langOpts.CUDAIsDevice) {
1610 if (linkage != cir::GlobalLinkageKind::InternalLinkage &&
1612 (vd->
hasAttr<CUDADeviceAttr>() || vd->
hasAttr<CUDAConstantAttr>() ||
1615 gv->setAttr(cir::CUDAExternallyInitializedAttr::getMnemonic(),
1628 emitter->finalize(gv);
1632 gv.setConstant((vd->
hasAttr<CUDAConstantAttr>() && langOpts.CUDAIsDevice) ||
1633 (!needsGlobalCtor && !needsGlobalDtor &&
1638 if (
const SectionAttr *sa = vd->
getAttr<SectionAttr>()) {
1641 gv.setConstant(
true);
1645 gv.setLinkage(linkage);
1649 if (linkage == cir::GlobalLinkageKind::CommonLinkage) {
1651 gv.setConstant(
false);
1656 std::optional<mlir::Attribute> initializer = gv.getInitialValue();
1657 if (initializer && !
getBuilder().isNullValue(*initializer))
1658 gv.setLinkage(cir::GlobalLinkageKind::WeakAnyLinkage);
1661 setNonAliasAttributes(vd, gv);
1669 if (needsGlobalCtor || needsGlobalDtor)
1675 cir::GlobalLinkageKind::AvailableExternallyLinkage)
1681 if (fd->isInlineBuiltinDeclaration())
1692 mlir::Operation *op) {
1694 if (
const auto *fd = dyn_cast<FunctionDecl>(
decl)) {
1698 if (
const auto *method = dyn_cast<CXXMethodDecl>(
decl)) {
1702 abi->emitCXXStructor(gd);
1703 else if (fd->isMultiVersion())
1704 errorNYI(method->getSourceRange(),
"multiversion functions");
1708 if (method->isVirtual())
1714 if (fd->isMultiVersion())
1715 errorNYI(fd->getSourceRange(),
"multiversion functions");
1720 if (
const auto *vd = dyn_cast<VarDecl>(
decl))
1723 llvm_unreachable(
"Invalid argument to CIRGenModule::emitGlobalDefinition");
1737 astContext.getAsConstantArrayType(e->
getType());
1738 uint64_t finalSize = cat->getZExtSize();
1739 str.resize(finalSize);
1741 mlir::Type eltTy =
convertType(cat->getElementType());
1742 return builder.getString(str, eltTy, finalSize,
false);
1747 auto arrayEltTy = mlir::cast<cir::IntType>(arrayTy.getElementType());
1749 uint64_t arraySize = arrayTy.getSize();
1751 assert(arraySize > literalSize &&
1752 "wide string literal array size must have room for null terminator?");
1756 bool isAllZero =
true;
1757 for (
unsigned i = 0; i < literalSize; ++i) {
1765 return cir::ZeroAttr::get(arrayTy);
1769 elements.reserve(arraySize);
1770 for (
unsigned i = 0; i < literalSize; ++i)
1771 elements.push_back(cir::IntAttr::get(arrayEltTy, e->
getCodeUnit(i)));
1773 auto elementsAttr = mlir::ArrayAttr::get(&
getMLIRContext(), elements);
1774 return builder.getConstArray(elementsAttr, arrayTy);
1785 if (d.
hasAttr<SelectAnyAttr>())
1789 if (
auto *vd = dyn_cast<VarDecl>(&d))
1804 llvm_unreachable(
"No such linkage");
1810 if (
auto globalOp = dyn_cast_or_null<cir::GlobalOp>(op)) {
1811 globalOp.setComdat(
true);
1814 funcOp.setComdat(
true);
1820 genTypes.updateCompletedType(td);
1824 replacements[name] = op;
1829 mlir::SymbolUserMap &userMap) {
1830 for (mlir::Operation *user : userMap.getUsers(oldF)) {
1831 auto call = mlir::dyn_cast<cir::CallOp>(user);
1835 for (
auto [argOp, fnArgType] :
1836 llvm::zip(call.getArgs(), newF.getFunctionType().getInputs())) {
1837 if (argOp.getType() != fnArgType)
1846void CIRGenModule::applyReplacements() {
1847 if (replacements.empty())
1853 mlir::SymbolTableCollection symbolTableCollection;
1854 mlir::SymbolUserMap userMap(symbolTableCollection, theModule);
1856 for (
auto &i : replacements) {
1857 StringRef mangledName = i.first;
1858 mlir::Operation *replacement = i.second;
1864 auto newF = dyn_cast<cir::FuncOp>(replacement);
1867 errorNYI(replacement->getLoc(),
"replacement is not a function");
1872 "call argument types do not match replacement function");
1876 userMap.replaceAllUsesWith(oldF, newF.getSymNameAttr());
1877 newF->moveBefore(oldF);
1884 mlir::Location loc, StringRef name, mlir::Type ty,
1886 auto gv = mlir::dyn_cast_or_null<cir::GlobalOp>(
getGlobalValue(name));
1890 if (gv.getSymType() == ty)
1896 assert(gv.isDeclaration() &&
"Declaration has wrong type!");
1898 errorNYI(loc,
"createOrReplaceCXXRuntimeVariable: declaration exists with "
1909 mlir::SymbolTable::setSymbolVisibility(gv,
1913 !gv.hasAvailableExternallyLinkage()) {
1917 gv.setAlignmentAttr(
getSize(alignment));
1928 if ((noCommon || vd->
hasAttr<NoCommonAttr>()) && !vd->
hasAttr<CommonAttr>())
1939 if (vd->
hasAttr<SectionAttr>())
1945 if (vd->
hasAttr<PragmaClangBSSSectionAttr>() ||
1946 vd->
hasAttr<PragmaClangDataSectionAttr>() ||
1947 vd->
hasAttr<PragmaClangRelroSectionAttr>() ||
1948 vd->
hasAttr<PragmaClangRodataSectionAttr>())
1956 if (vd->
hasAttr<WeakImportAttr>())
1966 if (vd->
hasAttr<AlignedAttr>())
1973 for (
const FieldDecl *fd : rd->fields()) {
1974 if (fd->isBitField())
1976 if (fd->hasAttr<AlignedAttr>())
1998cir::GlobalLinkageKind
2002 return cir::GlobalLinkageKind::InternalLinkage;
2005 return cir::GlobalLinkageKind::WeakAnyLinkage;
2009 return cir::GlobalLinkageKind::LinkOnceAnyLinkage;
2014 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
2028 return !astContext.getLangOpts().AppleKext
2029 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
2030 : cir::GlobalLinkageKind::InternalLinkage;
2044 return cir::GlobalLinkageKind::ExternalLinkage;
2047 return dd->
hasAttr<CUDAGlobalAttr>()
2048 ? cir::GlobalLinkageKind::ExternalLinkage
2049 : cir::GlobalLinkageKind::InternalLinkage;
2050 return cir::GlobalLinkageKind::WeakODRLinkage;
2058 return cir::GlobalLinkageKind::CommonLinkage;
2064 if (dd->
hasAttr<SelectAnyAttr>())
2065 return cir::GlobalLinkageKind::WeakODRLinkage;
2069 return cir::GlobalLinkageKind::ExternalLinkage;
2081 mlir::Operation *old, cir::FuncOp newFn) {
2083 auto oldFn = mlir::dyn_cast<cir::FuncOp>(old);
2091 if (oldFn->getAttrs().size() <= 1)
2093 "replaceUsesOfNonProtoTypeWithRealFunction: Attribute forwarding");
2096 newFn.setNoProto(oldFn.getNoProto());
2099 std::optional<mlir::SymbolTable::UseRange> symUses =
2100 oldFn.getSymbolUses(oldFn->getParentOp());
2105 for (
const mlir::SymbolTable::SymbolUse &use : symUses.value()) {
2106 mlir::OpBuilder::InsertionGuard guard(builder);
2108 if (
auto noProtoCallOp = mlir::dyn_cast<cir::CallOp>(use.getUser())) {
2109 builder.setInsertionPoint(noProtoCallOp);
2112 cir::FuncType newFnType = newFn.getFunctionType();
2113 mlir::OperandRange callOperands = noProtoCallOp.getOperands();
2114 bool returnTypeMatches =
2115 newFnType.hasVoidReturn()
2116 ? noProtoCallOp.getNumResults() == 0
2117 : noProtoCallOp.getNumResults() == 1 &&
2118 noProtoCallOp.getResultTypes().front() ==
2119 newFnType.getReturnType();
2120 bool typesMatch = !newFn.getNoProto() && returnTypeMatches &&
2121 callOperands.size() == newFnType.getNumInputs();
2122 for (
unsigned i = 0, e = newFnType.getNumInputs(); typesMatch && i != e;
2124 if (callOperands[i].
getType() != newFnType.getInput(i))
2128 cir::CallOp realCallOp;
2132 builder.createCallOp(noProtoCallOp.getLoc(), newFn, callOperands);
2136 cir::FuncType origFnType = oldFn.getFunctionType();
2137 cir::FuncType callFnType =
2138 origFnType.isVarArg()
2139 ? cir::FuncType::get(origFnType.getInputs(),
2140 origFnType.getReturnType(),
2143 mlir::Value addr = cir::GetGlobalOp::create(
2144 builder, noProtoCallOp.getLoc(), cir::PointerType::get(newFnType),
2145 newFn.getSymName());
2146 mlir::Value casted =
2147 builder.createBitcast(addr, cir::PointerType::get(callFnType));
2148 realCallOp = builder.createIndirectCallOp(
2149 noProtoCallOp.getLoc(), casted, callFnType, callOperands);
2153 noProtoCallOp.replaceAllUsesWith(realCallOp);
2154 noProtoCallOp.erase();
2155 }
else if (
auto getGlobalOp =
2156 mlir::dyn_cast<cir::GetGlobalOp>(use.getUser())) {
2163 mlir::Value res = getGlobalOp.getAddr();
2164 const mlir::Type oldResTy = res.getType();
2165 const auto newPtrTy = cir::PointerType::get(newFn.getFunctionType());
2166 if (oldResTy != newPtrTy) {
2167 res.setType(newPtrTy);
2168 builder.setInsertionPointAfter(getGlobalOp.getOperation());
2169 mlir::Value castRes =
2170 cir::CastOp::create(builder, getGlobalOp.getLoc(), oldResTy,
2171 cir::CastKind::bitcast, res);
2172 res.replaceAllUsesExcept(castRes, castRes.getDefiningOp());
2174 }
else if (mlir::isa<cir::GlobalOp>(use.getUser())) {
2180 "replaceUsesOfNonProtoTypeWithRealFunction: unexpected use type");
2185cir::GlobalLinkageKind
2187 GVALinkage linkage = astContext.GetGVALinkageForVariable(vd);
2194 GVALinkage linkage = astContext.GetGVALinkageForFunction(d);
2196 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(d))
2205 StringRef globalName,
CharUnits alignment) {
2210 cir::GlobalOp gv = cgm.
createGlobalOp(loc, globalName, c.getType(),
2214 gv.setAlignmentAttr(cgm.
getSize(alignment));
2216 cir::GlobalLinkageKindAttr::get(cgm.
getBuilder().getContext(), lt));
2220 if (gv.isWeakForLinker()) {
2221 assert(cgm.
supportsCOMDAT() &&
"Only COFF uses weak string literals");
2224 cgm.
setDSOLocal(
static_cast<mlir::Operation *
>(gv));
2245 std::string result =
2256 astContext.getAlignOfGlobalVarInChars(s->
getType(),
nullptr);
2264 if (!gv.getAlignment() ||
2265 uint64_t(alignment.
getQuantity()) > *gv.getAlignment())
2266 gv.setAlignmentAttr(
getSize(alignment));
2271 if (
getCXXABI().getMangleContext().shouldMangleStringLiteral(s) &&
2274 "getGlobalForStringLiteral: mangle string literals");
2284 : builder.getUnknownLoc();
2285 auto typedC = llvm::cast<mlir::TypedAttr>(c);
2287 cir::GlobalLinkageKind::PrivateLinkage, *
this,
2288 uniqueName, alignment);
2302 auto arrayTy = mlir::dyn_cast<cir::ArrayType>(gv.getSymType());
2303 assert(arrayTy &&
"String literal must be array");
2307 return builder.getGlobalViewAttr(ptrTy, gv);
2324 errorNYI(
"SYCL temp address space");
2335 "emitExplicitCastExprType");
2341 auto ty = mlir::cast<cir::MethodType>(
convertType(destTy));
2342 return builder.getNullMethodAttr(ty);
2345 auto ty = mlir::cast<cir::DataMemberType>(
convertType(destTy));
2346 return builder.getNullDataMemberAttr(ty);
2357 if (
const auto *methodDecl = dyn_cast<CXXMethodDecl>(
decl)) {
2359 if (methodDecl->isVirtual())
2360 return cir::ConstantOp::create(
2361 builder, loc,
getCXXABI().buildVirtualMethodAttr(ty, methodDecl));
2367 return cir::ConstantOp::create(builder, loc,
2368 builder.getMethodAttr(ty, methodFuncOp));
2383 assert(
fieldDecl->getParent() == destClass &&
2384 "scalar member pointer should be relative to the declaring class");
2386 astContext.toCharUnitsFromBits(astContext.getFieldOffset(
fieldDecl))
2388 return cir::ConstantOp::create(builder, loc,
2389 cir::DataMemberOffsetAttr::get(ty, offset));
2392 std::optional<llvm::SmallVector<int32_t>> path =
2396 return cir::ConstantOp::create(builder, loc,
2397 builder.getDataMemberAttr(ty, *path));
2400std::optional<llvm::SmallVector<int32_t>>
2408 if (
const auto *indirectField = dyn_cast<IndirectFieldDecl>(
decl)) {
2410 for (
const NamedDecl *nd : indirectField->chain()) {
2412 if (!findFieldMemberPath(currentClass, field, path))
2413 return std::nullopt;
2414 currentClass = field->getType()->getAsCXXRecordDecl();
2420 return std::nullopt;
2424bool CIRGenModule::findFieldMemberPath(
const CXXRecordDecl *currentClass,
2433 if (currentClass->
isUnion()) {
2439 "data member pointer for non-zero-initializable union");
2446 path.push_back(fieldIdx);
2454 for (
const CXXBaseSpecifier &base : currentClass->
bases()) {
2455 const auto *baseDecl =
2458 if (base.isVirtual()) {
2463 llvm::SmallVector<int32_t> discardedPath;
2464 if (findFieldMemberPath(baseDecl, field, discardedPath)) {
2466 "data member pointer through virtual base");
2479 path.push_back(baseFieldIdx);
2480 if (findFieldMemberPath(baseDecl, field, path))
2508 if (
auto *oid = dyn_cast<ObjCImplDecl>(
decl))
2509 errorNYI(oid->getSourceRange(),
"emitDeclConext: ObjCImplDecl");
2519 if (
decl->isTemplated())
2522 switch (
decl->getKind()) {
2525 decl->getDeclKindName());
2528 case Decl::CXXConversion:
2529 case Decl::CXXMethod:
2530 case Decl::Function: {
2533 if (!fd->isConsteval())
2542 case Decl::Decomposition:
2543 case Decl::VarTemplateSpecialization: {
2545 if (
auto *decomp = dyn_cast<DecompositionDecl>(
decl))
2546 for (
auto *binding : decomp->flat_bindings())
2547 if (
auto *holdingVar = binding->getHoldingVar())
2551 case Decl::OpenACCRoutine:
2554 case Decl::OpenACCDeclare:
2557 case Decl::OMPThreadPrivate:
2560 case Decl::OMPGroupPrivate:
2563 case Decl::OMPAllocate:
2566 case Decl::OMPCapturedExpr:
2569 case Decl::OMPDeclareReduction:
2572 case Decl::OMPDeclareMapper:
2575 case Decl::OMPRequires:
2580 case Decl::UsingDirective:
2581 case Decl::UsingEnum:
2582 case Decl::NamespaceAlias:
2584 case Decl::TypeAlias:
2591 case Decl::IndirectField:
2595 case Decl::ClassTemplate:
2597 case Decl::CXXDeductionGuide:
2599 case Decl::ExplicitInstantiation:
2600 case Decl::FunctionTemplate:
2601 case Decl::StaticAssert:
2602 case Decl::TypeAliasTemplate:
2603 case Decl::UsingShadow:
2604 case Decl::VarTemplate:
2605 case Decl::VarTemplatePartialSpecialization:
2608 case Decl::CXXConstructor:
2611 case Decl::CXXDestructor:
2616 case Decl::LinkageSpec:
2617 case Decl::Namespace:
2621 case Decl::ClassTemplateSpecialization:
2622 case Decl::CXXRecord: {
2625 for (
auto *childDecl : crd->
decls())
2631 case Decl::FileScopeAsm:
2633 if (langOpts.CUDA && langOpts.CUDAIsDevice)
2636 if (langOpts.OpenMPIsTargetDevice)
2639 if (langOpts.SYCLIsDevice)
2642 std::string line = file_asm->getAsmString();
2643 globalScopeAsm.push_back(builder.getStringAttr(line));
2650 op.setInitialValueAttr(value);
2664 md->getParent()->getNumVBases() == 0)
2666 "getAddrAndTypeOfCXXStructor: MS ABI complete destructor");
2677 false, isForDefinition);
2679 return {fnType, fn};
2683 mlir::Type funcType,
bool forVTable,
2687 "consteval function should never be emitted");
2697 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(gd.
getDecl())) {
2700 dd->getParent()->getNumVBases() == 0)
2702 "getAddrOfFunction: MS ABI complete destructor");
2708 false, isForDefinition);
2710 if (langOpts.CUDA && !langOpts.CUDAIsDevice &&
2716 bool isHIPHandle = mlir::isa<cir::GlobalOp>(*handle);
2717 if (isForDefinition || isHIPHandle)
2719 return mlir::dyn_cast<cir::FuncOp>(*handle);
2728 llvm::raw_svector_ostream
out(buffer);
2737 assert(ii &&
"Attempt to mangle unnamed decl.");
2739 const auto *fd = dyn_cast<FunctionDecl>(nd);
2743 }
else if (fd && fd->hasAttr<CUDAGlobalAttr>() &&
2747 DeviceKernelAttr::isOpenCLSpelling(
2748 fd->getAttr<DeviceKernelAttr>()) &&
2765 if (
const auto *fd = dyn_cast<FunctionDecl>(nd)) {
2766 if (fd->isMultiVersion()) {
2768 "getMangledName: multi-version functions");
2773 "getMangledName: GPU relocatable device code");
2776 return std::string(
out.str());
2779static FunctionDecl *
2794 if (
auto *methodDecl = dyn_cast<CXXMethodDecl>(protoFunc);
2795 methodDecl && methodDecl->isImplicitObjectMemberFunction()) {
2797 paramTypes.insert(paramTypes.begin(), methodDecl->getThisType());
2800 fpt->getExtProtoInfo());
2811 params.reserve(fpt->getNumParams());
2814 for (
unsigned i = 0, e = fpt->getNumParams(); i != e; ++i) {
2818 nullptr, fpt->getParamType(i),
nullptr,
2821 params.push_back(parm);
2824 tempFunc->setParams(params);
2849 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(canonicalGd.
getDecl())) {
2852 "getMangledName: C++ constructor without variants");
2861 if (!langOpts.CUDAIsDevice || !astContext.mayExternalize(gd.
getDecl())) {
2862 auto foundName = mangledDeclNames.find(canonicalGd);
2863 if (foundName != mangledDeclNames.end())
2864 return foundName->second;
2871 auto result = manglings.insert(std::make_pair(mangledName, gd));
2872 return mangledDeclNames[canonicalGd] = result.first->first();
2876 assert(!d->
getInit() &&
"Cannot emit definite definitions here!");
2884 if (gv && !mlir::cast<cir::GlobalOp>(gv).isDeclaration())
2900 if (langOpts.EmitAllDecls)
2903 const auto *vd = dyn_cast<VarDecl>(global);
2905 ((codeGenOpts.KeepPersistentStorageVariables &&
2906 (vd->getStorageDuration() ==
SD_Static ||
2907 vd->getStorageDuration() ==
SD_Thread)) ||
2908 (codeGenOpts.KeepStaticConsts && vd->getStorageDuration() ==
SD_Static &&
2909 vd->getType().isConstQualified())))
2922 if (langOpts.OpenMP >= 50 && !langOpts.OpenMPSimd) {
2923 std::optional<OMPDeclareTargetDeclAttr *> activeAttr =
2924 OMPDeclareTargetDeclAttr::getActiveAttr(global);
2925 if (!activeAttr || (*activeAttr)->getLevel() != (
unsigned)-1)
2929 const auto *fd = dyn_cast<FunctionDecl>(global);
2936 if (fd->hasAttr<TargetVersionAttr>() && !fd->isMultiVersion())
2938 if (langOpts.SYCLIsDevice) {
2939 errorNYI(fd->getSourceRange(),
"mayBeEmittedEagerly: SYCL");
2943 const auto *vd = dyn_cast<VarDecl>(global);
2945 if (astContext.getInlineVariableDefinitionKind(vd) ==
2953 if (langOpts.OpenMP && langOpts.OpenMPUseTLS &&
2954 astContext.getTargetInfo().isTLSSupported() &&
isa<VarDecl>(global) &&
2956 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(global))
2959 assert((fd || vd) &&
2960 "Only FunctionDecl and VarDecl should hit this path so far.");
2965 cir::CIRGlobalValueInterface gv) {
2966 if (gv.hasLocalLinkage())
2969 if (!gv.hasDefaultVisibility() && !gv.hasExternalWeakLinkage())
2977 const llvm::Triple &tt = cgm.
getTriple();
2979 if (tt.isOSCygMing()) {
2988 cgm.
errorNYI(
"shouldAssumeDSOLocal: MinGW");
2994 if (tt.isOSBinFormatCOFF() && gv.hasExternalWeakLinkage())
3002 if (tt.isOSBinFormatCOFF() || (tt.isOSWindows() && tt.isOSBinFormatMachO()))
3006 if (!tt.isOSBinFormatELF())
3011 if (rm != llvm::Reloc::Static && !lOpts.PIE) {
3019 return !(lOpts.SemanticInterposition || lOpts.HalfNoSemanticInterposition);
3023 if (!gv.isDeclarationForLinker())
3029 if (rm == llvm::Reloc::PIC_ && gv.hasExternalWeakLinkage())
3036 if (cgOpts.DirectAccessExternalData) {
3042 if (
auto globalOp = dyn_cast<cir::GlobalOp>(gv.getOperation())) {
3068 if (gv.hasLocalLinkage()) {
3069 gv.setGlobalVisibility(cir::VisibilityKind::Default);
3084 d->
hasAttr<OMPDeclareTargetDeclAttr>() &&
3085 d->
getAttr<OMPDeclareTargetDeclAttr>()->getDevType() !=
3086 OMPDeclareTargetDeclAttr::DT_NoHost &&
3088 llvm_unreachable(
"setGlobalVisibility: OpenMP is NYI");
3097 !d->
hasAttr<OMPDeclareTargetDeclAttr>()) {
3098 bool needsProtected =
false;
3102 }
else if (
const auto *vd = dyn_cast<VarDecl>(d)) {
3103 needsProtected = vd->hasAttr<CUDADeviceAttr>() ||
3104 vd->hasAttr<CUDAConstantAttr>() ||
3105 vd->getType()->isCUDADeviceBuiltinSurfaceType() ||
3106 vd->getType()->isCUDADeviceBuiltinTextureType();
3108 if (needsProtected) {
3109 gv.setGlobalVisibility(cir::VisibilityKind::Protected);
3115 gv.setGlobalVisibility(cir::VisibilityKind::Hidden);
3122 !gv.isDeclarationForLinker())
3131 if (
auto globalValue = dyn_cast<cir::CIRGlobalValueInterface>(op))
3150 auto res = manglings.find(mangledName);
3151 if (res == manglings.end())
3153 result = res->getValue();
3158 return llvm::StringSwitch<cir::TLSModel>(S)
3159 .Case(
"global-dynamic", cir::TLSModel::GeneralDynamic)
3160 .Case(
"local-dynamic", cir::TLSModel::LocalDynamic)
3161 .Case(
"initial-exec", cir::TLSModel::InitialExec)
3162 .Case(
"local-exec", cir::TLSModel::LocalExec);
3168 return cir::TLSModel::GeneralDynamic;
3170 return cir::TLSModel::LocalDynamic;
3172 return cir::TLSModel::InitialExec;
3174 return cir::TLSModel::LocalExec;
3176 llvm_unreachable(
"Invalid TLS model!");
3180 bool isExtendingDecl) {
3181 assert(d.
getTLSKind() &&
"setting TLS mode on non-TLS var!");
3190 global.setTlsModel(tlm);
3200 if (isExtendingDecl)
3208 cir::FuncOp func,
bool isThunk) {
3210 cir::CallingConv callingConv;
3211 cir::SideEffect sideEffect;
3218 mlir::NamedAttrList pal{};
3219 std::vector<mlir::NamedAttrList> argAttrs(info.arguments().size());
3220 mlir::NamedAttrList retAttrs{};
3222 retAttrs, callingConv, sideEffect,
3225 for (mlir::NamedAttribute
attr : pal)
3226 func->setAttr(
attr.getName(),
attr.getValue());
3228 llvm::for_each(llvm::enumerate(argAttrs), [func](
auto idx_arg_pair) {
3229 mlir::function_interface_impl::setArgAttrs(func, idx_arg_pair.index(),
3230 idx_arg_pair.value());
3232 if (!retAttrs.empty())
3233 mlir::function_interface_impl::setResultAttrs(func, 0, retAttrs);
3237 func.setCallingConv(callingConv);
3242 bool isIncompleteFunction,
3250 if (!isIncompleteFunction)
3252 getTypes().arrangeGlobalDeclaration(globalDecl),
3255 if (!isIncompleteFunction && func.isDeclaration())
3262 if (funcDecl->isInlineBuiltinDeclaration()) {
3264 bool hasBody = funcDecl->
hasBody(fdBody);
3266 assert(hasBody &&
"Inline builtin declarations should always have an "
3271 if (funcDecl->isReplaceableGlobalAllocationFunction()) {
3274 func->setAttr(cir::CIRDialect::getNoBuiltinAttrName(),
3285 f->setAttr(cir::CIRDialect::getNoThrowAttrName(),
3288 std::optional<cir::InlineKind> existingInlineKind = f.getInlineKind();
3290 existingInlineKind && *existingInlineKind == cir::InlineKind::NoInline;
3291 bool isAlwaysInline = existingInlineKind &&
3292 *existingInlineKind == cir::InlineKind::AlwaysInline;
3296 if (!isAlwaysInline &&
3301 f.setInlineKind(cir::InlineKind::NoInline);
3316 if (
decl->hasAttr<NoInlineAttr>() && !isAlwaysInline) {
3318 f.setInlineKind(cir::InlineKind::NoInline);
3319 }
else if (
decl->hasAttr<AlwaysInlineAttr>() && !isNoInline) {
3322 f.setInlineKind(cir::InlineKind::AlwaysInline);
3326 if (!isAlwaysInline)
3327 f.setInlineKind(cir::InlineKind::NoInline);
3332 if (
auto *fd = dyn_cast<FunctionDecl>(
decl)) {
3337 auto checkRedeclForInline = [](
const FunctionDecl *redecl) {
3338 return redecl->isInlineSpecified();
3340 if (any_of(
decl->redecls(), checkRedeclForInline))
3345 return any_of(pattern->
redecls(), checkRedeclForInline);
3347 if (checkForInline(fd)) {
3348 f.setInlineKind(cir::InlineKind::InlineHint);
3349 }
else if (codeGenOpts.getInlining() ==
3351 !fd->isInlined() && !isAlwaysInline) {
3352 f.setInlineKind(cir::InlineKind::NoInline);
3364static cir::LangAddressSpace
3366 switch (addressSpace) {
3368 return cir::LangAddressSpace::OffloadGlobal;
3370 return cir::LangAddressSpace::OffloadConstant;
3372 return cir::LangAddressSpace::OffloadLocal;
3374 return cir::LangAddressSpace::OffloadGeneric;
3376 return cir::LangAddressSpace::OffloadGlobalDevice;
3378 return cir::LangAddressSpace::OffloadGlobalHost;
3382 return cir::LangAddressSpace::Default;
3388 assert(fd &&
"expected a kernel function declaration");
3401 argNames.push_back(builder.getStringAttr(param->getName()));
3404 std::string typeQuals;
3406 if (
type->isImageType() ||
type->isPipeType()) {
3408 "OpenCL kernel argument metadata for image and pipe types");
3412 accessQuals.push_back(builder.getStringAttr(
"none"));
3414 auto getTypeSpelling = [&](
QualType paramType) {
3415 std::string typeName = paramType.getUnqualifiedType().getAsString(policy);
3417 if (paramType.isCanonical()) {
3418 StringRef typeNameRef = typeName;
3419 if (typeNameRef.consume_front(
"unsigned "))
3420 return std::string(
"u") + typeNameRef.str();
3421 if (typeNameRef.consume_front(
"signed "))
3422 return typeNameRef.str();
3430 if (
type->isPointerType()) {
3432 addressQuals.push_back(cir::LangAddressSpaceAttr::get(
3436 argTypeNames.push_back(
3437 builder.getStringAttr(getTypeSpelling(pointeeType) +
"*"));
3438 argBaseTypeNames.push_back(builder.getStringAttr(
3441 if (
type.isRestrictQualified())
3442 typeQuals =
"restrict";
3445 typeQuals += typeQuals.empty() ?
"const" :
" const";
3447 typeQuals += typeQuals.empty() ?
"volatile" :
" volatile";
3449 addressQuals.push_back(cir::LangAddressSpaceAttr::get(
3452 argTypeNames.push_back(builder.getStringAttr(getTypeSpelling(
type)));
3453 argBaseTypeNames.push_back(
3454 builder.getStringAttr(getTypeSpelling(
type.getCanonicalType())));
3457 argTypeQuals.push_back(builder.getStringAttr(typeQuals));
3460 mlir::ArrayAttr names;
3462 names = builder.getArrayAttr(argNames);
3464 mlir::Attribute metadata = cir::OpenCLKernelArgMetadataAttr::get(
3465 func.getContext(), builder.getArrayAttr(addressQuals),
3466 builder.getArrayAttr(accessQuals), builder.getArrayAttr(argTypeNames),
3467 builder.getArrayAttr(argBaseTypeNames),
3468 builder.getArrayAttr(argTypeQuals), names);
3469 func->setAttr(cir::CIRDialect::getOpenCLKernelArgMetadataAttrName(),
3474 StringRef mangledName, mlir::Type funcType,
GlobalDecl gd,
bool forVTable,
3476 mlir::NamedAttrList extraAttrs) {
3479 if (
const auto *fd = cast_or_null<FunctionDecl>(d)) {
3481 if (
getLangOpts().OpenMPIsTargetDevice && openMPRuntime &&
3483 !dontDefer && !isForDefinition) {
3486 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(fdDef))
3488 else if (
const auto *dd = dyn_cast<CXXDestructorDecl>(fdDef))
3498 if (fd->isMultiVersion())
3499 errorNYI(fd->getSourceRange(),
"getOrCreateCIRFunction: multi-version");
3505 assert(mlir::isa<cir::FuncOp>(entry));
3510 if (d && !d->
hasAttr<DLLImportAttr>() && !d->
hasAttr<DLLExportAttr>()) {
3518 if (isForDefinition && fn && !fn.isDeclaration()) {
3525 diagnosedConflictingDefinitions.insert(gd).second) {
3529 diag::note_previous_definition);
3533 if (fn && fn.getFunctionType() == funcType) {
3537 if (!isForDefinition) {
3545 auto *funcDecl = llvm::cast_or_null<FunctionDecl>(gd.
getDecl());
3546 bool invalidLoc = !funcDecl ||
3547 funcDecl->getSourceRange().getBegin().isInvalid() ||
3548 funcDecl->getSourceRange().getEnd().isInvalid();
3550 invalidLoc ? theModule->getLoc() :
getLoc(funcDecl->getSourceRange()),
3551 mangledName, mlir::cast<cir::FuncType>(funcType), funcDecl);
3553 if (funcDecl && funcDecl->hasAttr<AnnotateAttr>())
3554 deferredAnnotations[mangledName] = funcDecl;
3565 auto symbolOp = mlir::cast<mlir::SymbolOpInterface>(entry);
3573 if (symbolOp.getSymbolUses(symbolOp->getParentOp()))
3583 if (!extraAttrs.empty()) {
3584 extraAttrs.append(funcOp->getAttrs());
3585 funcOp->setAttrs(extraAttrs);
3592 assert(funcOp.getFunctionType() == funcType);
3599 if (isa_and_nonnull<CXXDestructorDecl>(d) &&
3629 fd = fd->getPreviousDecl()) {
3631 if (fd->doesThisDeclarationHaveABody()) {
3644 cir::FuncType funcType,
3648 mlir::OpBuilder::InsertionGuard guard(builder);
3653 builder.setInsertionPointToEnd(theModule.getBody());
3655 func = cir::FuncOp::create(builder, loc, name, funcType);
3662 func.setNoProto(
true);
3664 assert(func.isDeclaration() &&
"expected empty body");
3668 func.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
3670 mlir::SymbolTable::setSymbolVisibility(
3671 func, mlir::SymbolTable::Visibility::Private);
3682 for (
const auto *
attr :
3696 fnOp.setBuiltin(
true);
3702 return cir::CtorKind::Default;
3704 return cir::CtorKind::Copy;
3706 return cir::CtorKind::Move;
3707 return cir::CtorKind::Custom;
3712 return cir::AssignKind::Copy;
3714 return cir::AssignKind::Move;
3715 llvm_unreachable(
"not a copy or move assignment operator");
3723 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(funcDecl)) {
3724 auto cxxDtor = cir::CXXDtorAttr::get(
3727 funcOp.setFuncInfoAttr(cxxDtor);
3731 if (
const auto *ctor = dyn_cast<CXXConstructorDecl>(funcDecl)) {
3733 auto cxxCtor = cir::CXXCtorAttr::get(
3735 kind, ctor->isTrivial());
3736 funcOp.setFuncInfoAttr(cxxCtor);
3740 const auto *method = dyn_cast<CXXMethodDecl>(funcDecl);
3741 if (method && (method->isCopyAssignmentOperator() ||
3742 method->isMoveAssignmentOperator())) {
3744 auto cxxAssign = cir::CXXAssignAttr::get(
3746 assignKind, method->isTrivial());
3747 funcOp.setFuncInfoAttr(cxxAssign);
3757 bool inStdNamespace = method ? method->getParent()->isInStdNamespace()
3759 if (!inStdNamespace)
3765 std::optional<cir::KnownFuncKind>
kind;
3767 kind = llvm::StringSwitch<std::optional<cir::KnownFuncKind>>(
3769 .Case(cir::StdFindOp::getFunctionName(),
3770 cir::StdFindOp::getFuncKind())
3771 .Default(std::nullopt);
3780 cir::FuncOp funcOp, StringRef name) {
3796 mlir::NamedAttrList extraAttrs,
3798 bool assumeConvergent) {
3799 if (assumeConvergent)
3800 errorNYI(
"createRuntimeFunction: assumeConvergent");
3810 entry.setDSOLocal(
true);
3816mlir::SymbolTable::Visibility
3820 if (op.isDeclaration())
3821 return mlir::SymbolTable::Visibility::Private;
3825mlir::SymbolTable::Visibility
3828 case cir::GlobalLinkageKind::InternalLinkage:
3829 case cir::GlobalLinkageKind::PrivateLinkage:
3830 return mlir::SymbolTable::Visibility::Private;
3831 case cir::GlobalLinkageKind::ExternalLinkage:
3832 case cir::GlobalLinkageKind::ExternalWeakLinkage:
3833 case cir::GlobalLinkageKind::LinkOnceODRLinkage:
3834 case cir::GlobalLinkageKind::AvailableExternallyLinkage:
3835 case cir::GlobalLinkageKind::CommonLinkage:
3836 case cir::GlobalLinkageKind::WeakAnyLinkage:
3837 case cir::GlobalLinkageKind::WeakODRLinkage:
3838 return mlir::SymbolTable::Visibility::Public;
3840 llvm::errs() <<
"visibility not implemented for '"
3841 << stringifyGlobalLinkageKind(glk) <<
"'\n";
3842 assert(0 &&
"not implemented");
3845 llvm_unreachable(
"linkage should be handled above!");
3851 applyReplacements();
3853 theModule->setAttr(cir::CIRDialect::getModuleLevelAsmAttrName(),
3854 builder.getArrayAttr(globalScopeAsm));
3856 emitGlobalAnnotations();
3858 if (!recordLayoutEntries.empty())
3860 cir::CIRDialect::getRecordLayoutsAttrName(),
3861 mlir::DictionaryAttr::get(&
getMLIRContext(), recordLayoutEntries));
3870 std::string cuidName =
3873 auto loc = builder.getUnknownLoc();
3874 mlir::ptr::MemorySpaceAttrInterface addrSpace =
3876 getGlobalVarAddressSpace(
nullptr));
3880 gv.setLinkage(cir::GlobalLinkageKind::ExternalLinkage);
3882 auto zeroAttr = cir::IntAttr::get(int8Ty, 0);
3883 gv.setInitialValueAttr(zeroAttr);
3885 mlir::SymbolTable::setSymbolVisibility(
3886 gv, mlir::SymbolTable::Visibility::Public);
3891 if (astContext.getLangOpts().CUDA && cudaRuntime)
3899 if (langOpts.CPlusPlusModules &&
3902 if (
clang::Module *primary = astContext.getCurrentNamedModule();
3905 llvm::raw_svector_ostream
out(fnName);
3907 .mangleModuleInitializer(primary,
out);
3908 theModule->setAttr(cir::CIRDialect::getCXXModuleInitFnNameAttrName(),
3909 builder.getStringAttr(fnName));
3923 const AliasAttr *aa = d->
getAttr<AliasAttr>();
3924 assert(aa &&
"Not an alias?");
3928 if (aa->getAliasee() == mangledName) {
3929 diags.Report(aa->getLocation(), diag::err_cyclic_alias) << 0;
3937 auto entryGV = mlir::dyn_cast<cir::CIRGlobalValueInterface>(entry);
3938 if (entryGV && entryGV.isDefinition())
3951 cir::GlobalLinkageKind linkage;
3963 cir::CIRGlobalValueInterface alias =
3964 isFunction ? mlir::cast<cir::CIRGlobalValueInterface>(
3966 mlir::cast<cir::FuncType>(declTy),
3969 : mlir::cast<cir::CIRGlobalValueInterface>(
3980 entry, mlir::cast<cir::FuncOp>(alias.getOperation()));
3988 linkage = cir::GlobalLinkageKind::WeakAnyLinkage;
3992 mlir::SymbolTable::Visibility visibility =
3995 alias.setAliasee(aa->getAliasee());
3996 alias.setLinkage(linkage);
3997 mlir::SymbolTable::setSymbolVisibility(alias, visibility);
4005 cir::FuncOp aliasee,
4006 cir::GlobalLinkageKind linkage) {
4008 auto *aliasFD = dyn_cast<FunctionDecl>(aliasGD.
getDecl());
4009 assert(aliasFD &&
"expected FunctionDecl");
4020 mangledName, fnType, aliasFD);
4021 alias.setAliasee(aliasee.getName());
4022 alias.setLinkage(linkage);
4026 mlir::SymbolTable::setSymbolVisibility(
4027 alias, mlir::SymbolTable::Visibility::Private);
4039 "declaration exists with different type");
4051 return genTypes.convertType(
type);
4058 return mlir::verify(theModule).succeeded();
4067 return builder.getConstNullPtrAttr(builder.getUInt8PtrTy());
4070 langOpts.ObjCRuntime.isGNUFamily()) {
4071 errorNYI(loc,
"getAddrOfRTTIDescriptor: Objc PtrType & Objc RT GUN");
4081 llvm::iterator_range<CastExpr::path_const_iterator> path) {
4088 assert(!base->isVirtual() &&
"Should not see virtual bases here!");
4093 const auto *baseDecl = base->getType()->castAsCXXRecordDecl();
4105 llvm::StringRef feature) {
4106 unsigned diagID = diags.getCustomDiagID(
4108 return diags.Report(loc, diagID) << feature;
4112 llvm::StringRef feature) {
4124 "cannot compile this %0 yet");
4125 diags.Report(astContext.getFullLoc(s->
getBeginLoc()), diagId)
4132 "cannot compile this %0 yet");
4133 diags.Report(astContext.getFullLoc(d->
getLocation()), diagId) <<
type;
4141 "not a global temporary");
4153 materializedType = mte->
getType();
4162 llvm::raw_svector_ostream
out(name);
4166 auto insertResult = materializedGlobalTemporaryMap.insert({mte,
nullptr});
4167 if (!insertResult.second) {
4171 if (!insertResult.first->second) {
4174 insertResult.first->second =
4177 return insertResult.first->second;
4194 value = &evalResult.
Val;
4198 std::optional<ConstantEmitter> emitter;
4199 mlir::Attribute initialValue =
nullptr;
4200 bool isConstant =
false;
4204 emitter.emplace(*
this);
4205 initialValue = emitter->emitForInitializer(*value, materializedType);
4210 type = mlir::cast<mlir::TypedAttr>(initialValue).getType();
4219 if (linkage == cir::GlobalLinkageKind::ExternalLinkage) {
4221 if (
varDecl->isStaticDataMember() &&
varDecl->getAnyInitializer(initVD) &&
4229 linkage = cir::GlobalLinkageKind::InternalLinkage;
4233 gv.setInitialValueAttr(initialValue);
4234 gv.setLinkage(linkage);
4238 emitter->finalize(gv);
4240 if (!gv.hasLocalLinkage()) {
4245 gv.setAlignment(align.getAsAlign().value());
4250 mlir::Operation *cv = gv;
4259 mlir::Operation *&entry = materializedGlobalTemporaryMap[mte];
4261 entry->replaceAllUsesWith(cv);
4276 return *globalOpEntry;
4283 "emitForInitializer should take gcd->getType().getAddressSpace()");
4285 auto typedInit = dyn_cast<mlir::TypedAttr>(init);
4289 "getAddrOfUnnamedGlobalConstantDecl: non-typed initializer");
4298 std::string name = numEntries == 0
4300 : (Twine(
".constant.") + Twine(numEntries)).str();
4302 typedInit.getType(),
true);
4303 globalOp.setLinkage(cir::GlobalLinkageKind::PrivateLinkage);
4306 globalOp.setAlignment(alignment.
getAsAlign().value());
4310 *globalOpEntry = globalOp;
4325 "emitForInitializer should take tpo->getType().getAddressSpace()");
4326 mlir::Attribute init =
4336 cir::GlobalLinkageKind linkage =
4338 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
4339 : cir::GlobalLinkageKind::InternalLinkage;
4343 typedInit.getType(),
true);
4344 globalOp.setLinkage(linkage);
4345 globalOp.setAlignment(alignment.
getAsAlign().value());
4347 linkage == cir::GlobalLinkageKind::LinkOnceODRLinkage);
4362CIRGenModule::getOrCreateAnnotationArgs(
const AnnotateAttr *
attr) {
4369 llvm::FoldingSetNodeID id;
4370 for (
Expr *e : exprs)
4373 mlir::ArrayAttr &lookup = annotationArgs[
id.computeHash()];
4378 args.reserve(exprs.size());
4379 for (
Expr *e : exprs) {
4380 if (
auto *strE = dyn_cast<clang::StringLiteral>(e->IgnoreParenCasts())) {
4381 args.push_back(builder.getStringAttr(strE->getString()));
4382 }
else if (
auto *intE =
4383 dyn_cast<clang::IntegerLiteral>(e->IgnoreParenCasts())) {
4384 auto intTy = builder.getIntegerType(intE->getValue().getBitWidth());
4385 args.push_back(builder.getIntegerAttr(intTy, intE->getValue()));
4387 errorNYI(e->getExprLoc(),
"annotation argument expression");
4391 return lookup = builder.getArrayAttr(args);
4394cir::AnnotationAttr CIRGenModule::emitAnnotateAttr(
const AnnotateAttr *aa) {
4395 mlir::StringAttr annoGV = builder.getStringAttr(aa->getAnnotation());
4396 mlir::ArrayAttr args = getOrCreateAnnotationArgs(aa);
4397 return cir::AnnotationAttr::get(&
getMLIRContext(), annoGV, args);
4401 mlir::Operation *gv) {
4402 assert(d->
hasAttr<AnnotateAttr>() &&
"no annotate attribute");
4404 "annotation only on globals");
4407 annotations.push_back(emitAnnotateAttr(i));
4408 if (
auto global = dyn_cast<cir::GlobalOp>(gv))
4409 global.setAnnotationsAttr(builder.getArrayAttr(annotations));
4410 else if (
auto func = dyn_cast<cir::FuncOp>(gv))
4411 func.setAnnotationsAttr(builder.getArrayAttr(annotations));
4414void CIRGenModule::emitGlobalAnnotations() {
4415 for (
const auto &[mangledName, vd] : deferredAnnotations) {
4420 deferredAnnotations.clear();
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
static bool shouldAssumeDSOLocal(const CIRGenModule &cgm, cir::CIRGlobalValueInterface gv)
static cir::AssignKind getAssignKindFromDecl(const CXXMethodDecl *method)
static FunctionDecl * createOpenACCBindTempFunction(ASTContext &ctx, const IdentifierInfo *bindName, const FunctionDecl *protoFunc)
static cir::LangAddressSpace getOpenCLKernelArgAddressSpace(LangAS addressSpace)
static bool shouldBeInCOMDAT(CIRGenModule &cgm, const Decl &d)
static mlir::Attribute getNewInitValue(CIRGenModule &cgm, cir::GlobalOp newGlob, mlir::Type oldTy, mlir::Attribute oldInit)
static void setWindowsItaniumDLLImport(CIRGenModule &cgm, bool isLocal, cir::FuncOp funcOp, StringRef name)
static std::string getMangledNameImpl(CIRGenModule &cgm, GlobalDecl gd, const NamedDecl *nd)
static llvm::SmallVector< int64_t > indexesOfArrayAttr(mlir::ArrayAttr indexes)
static bool isViewOnGlobal(cir::GlobalOp glob, cir::GlobalViewAttr view)
static void setLinkageForFunction(CIRGenModule &cgm, cir::FuncOp &func, const NamedDecl *nd)
static cir::GlobalOp generateStringLiteral(mlir::Location loc, mlir::TypedAttr c, cir::GlobalLinkageKind lt, CIRGenModule &cgm, StringRef globalName, CharUnits alignment)
static bool hasImplicitAttr(const ValueDecl *decl)
static std::vector< std::string > getFeatureDeltaFromDefault(const CIRGenModule &cgm, llvm::StringRef targetCPU, llvm::StringMap< bool > &featureMap)
Get the feature delta from the default feature map for the given target CPU.
static CIRGenCXXABI * createCXXABI(CIRGenModule &cgm)
static bool isVarDeclStrongDefinition(const ASTContext &astContext, CIRGenModule &cgm, const VarDecl *vd, bool noCommon)
static void setLinkageForGV(cir::GlobalOp &gv, const NamedDecl *nd)
static bool verifyPointerTypeArgs(cir::FuncOp oldF, cir::FuncOp newF, mlir::SymbolUserMap &userMap)
static mlir::Attribute createNewGlobalView(CIRGenModule &cgm, cir::GlobalOp newGlob, cir::GlobalViewAttr attr, mlir::Type oldTy)
static cir::CtorKind getCtorKindFromDecl(const CXXConstructorDecl *ctor)
static void emitUsed(CIRGenModule &cgm, StringRef name, std::vector< cir::CIRGlobalValueInterface > &list)
static cir::TLSModel getCIRTLSModel(StringRef S)
static Decl::Kind getKind(const Decl *D)
This file defines OpenACC nodes for declarative directives.
static constexpr bool needsDtor()
Defines the clang::Module class, which describes a module in the source code.
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
Defines the SourceManager interface.
This file defines OpenMP AST classes for executable directives and clauses.
cir::GlobalViewAttr getGlobalViewAttr(cir::GlobalOp globalOp, mlir::ArrayAttr indices={})
Get constant address of a global variable as an MLIR attribute.
cir::PointerType getPointerTo(mlir::Type ty)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
@ Strong
Strong definition.
@ WeakUnknown
Weak for now, might become strong later in this TU.
bool DeclMustBeEmitted(const Decl *D)
Determines if the decl can be CodeGen'ed or deserialized from PCH lazily, only when used; this is onl...
StringRef getCUIDHash() const
void Deallocate(void *Ptr) const
GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const
bool isSameEntity(const NamedDecl *X, const NamedDecl *Y) const
Determine whether the two declarations refer to the same entity.
bool isAlignmentRequired(const Type *T) const
Determine if the alignment the type has was required using an alignment attribute.
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
const clang::PrintingPolicy & getPrintingPolicy() const
GVALinkage GetGVALinkageForVariable(const VarDecl *VD) const
unsigned getTypeAlignIfKnown(QualType T, bool NeedsPreferredAlignment=false) const
Return the alignment of a type, in bits, or 0 if the type is incomplete and we cannot determine the a...
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
DiagnosticsEngine & getDiagnostics() const
const TargetInfo & getTargetInfo() const
TargetCXXABI::Kind getCXXABIKind() const
Return the C++ ABI kind that should be used.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
mlir::Attribute getConstRecordOrZeroAttr(mlir::ArrayAttr arrayAttr, cir::RecordType recordTy)
uint64_t computeOffsetFromGlobalViewIndices(const cir::CIRDataLayout &layout, mlir::Type ty, llvm::ArrayRef< int64_t > indices)
cir::ConstArrayAttr getConstArray(mlir::Attribute attrs, cir::ArrayType arrayTy) const
bool computeGlobalViewIndicesFromFlatOffset(int64_t offset, mlir::Type ty, cir::CIRDataLayout layout, llvm::SmallVectorImpl< int64_t > &indices)
virtual void handleGlobalReplace(cir::GlobalOp oldGV, cir::GlobalOp newGV)
virtual mlir::Operation * getKernelHandle(cir::FuncOp fn, GlobalDecl gd)=0
virtual void finalizeModule()
Perform module finalization: on device side, mark ODR-used device variables as compiler-used.
virtual void internalizeDeviceSideVar(const VarDecl *d, cir::GlobalLinkageKind &linkage)=0
Adjust linkage of shadow variables in host compilation.
virtual void handleVarRegistration(const VarDecl *vd, cir::GlobalOp var)=0
Check whether a variable is a device variable and register it if true.
Implements C++ ABI-specific code generation functions.
virtual mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty)=0
virtual void emitCXXConstructors(const clang::CXXConstructorDecl *d)=0
Emit constructor variants required by this ABI.
virtual void emitCXXDestructors(const clang::CXXDestructorDecl *d)=0
Emit dtor variants required by this ABI.
clang::MangleContext & getMangleContext()
Gets the mangle context.
virtual cir::GlobalLinkageKind getCXXDestructorLinkage(GVALinkage linkage, const CXXDestructorDecl *dtor, CXXDtorType dt) const
cir::FuncOp generateCode(clang::GlobalDecl gd, cir::FuncOp fn, cir::FuncType funcType)
void emitVariablyModifiedType(QualType ty)
This class organizes the cross-function state that is used while generating CIR code.
cir::GlobalOp getAddrOfUnnamedGlobalConstantDecl(const UnnamedGlobalConstantDecl *gcd)
void setGlobalVisibility(cir::CIRGlobalValueInterface gv, const NamedDecl *d) const
Set the visibility for the given global.
void addUsedOrCompilerUsedGlobal(cir::CIRGlobalValueInterface gv)
Add a global to a list to be added to the llvm.compiler.used metadata.
void setFuncInfoAttr(cir::FuncOp funcOp, const clang::FunctionDecl *funcDecl)
Record the func_info tag for a function, either a C++ special member form (constructor,...
void replaceUsesOfNonProtoTypeWithRealFunction(mlir::Operation *old, cir::FuncOp newFn)
This function is called when we implement a function with no prototype, e.g.
bool shouldEmitFunction(clang::GlobalDecl gd)
Check if fd ends up calling itself directly through asm label or builtin-pointer-to-self trickery (e....
llvm::StringRef getMangledName(clang::GlobalDecl gd)
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *derivedClass, llvm::iterator_range< CastExpr::path_const_iterator > path)
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
void emitDeferred()
Emit any needed decls for which code generation was deferred.
cir::GlobalLinkageKind getCIRLinkageVarDefinition(const VarDecl *vd)
clang::ASTContext & getASTContext() const
void insertGlobalSymbol(mlir::Operation *op)
cir::FuncOp getAddrOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
CIRGenCUDARuntime & getCUDARuntime()
void emitTopLevelDecl(clang::Decl *decl)
void emitOMPDeclareMapper(const OMPDeclareMapperDecl *d)
void addReplacement(llvm::StringRef name, mlir::Operation *op)
mlir::Type convertType(clang::QualType type)
bool shouldEmitRTTI(bool forEH=false)
cir::GlobalOp getGlobalForStringLiteral(const StringLiteral *s, llvm::StringRef name=".str")
Return a global symbol reference to a constant array for the given string literal.
std::vector< cir::CIRGlobalValueInterface > llvmUsed
List of global values which are required to be present in the object file; This is used for forcing v...
void emitOMPCapturedExpr(const OMPCapturedExprDecl *d)
std::optional< llvm::SmallVector< int32_t > > buildMemberPath(const CXXRecordDecl *destClass, const ValueDecl *decl)
Build a GEP-style field-index path from destClass to decl.
bool mustBeEmitted(const clang::ValueDecl *d)
Determine whether the definition must be emitted; if this returns false, the definition can be emitte...
void emitGlobalOpenACCDeclareDecl(const clang::OpenACCDeclareDecl *cd)
mlir::IntegerAttr getSize(CharUnits size)
cir::TLSModel getDefaultCIRTLSModel() const
Get TLS mode from CodeGenOptions.
void setGlobalTlsReferences(const VarDecl &vd, cir::GlobalOp globalOp)
void emitOpenCLKernelArgMetadata(cir::FuncOp func, const clang::FunctionDecl *fd)
Generate OpenCL kernel argument metadata for a kernel function.
CIRGenBuilderTy & getBuilder()
void setDSOLocal(mlir::Operation *op) const
std::string getUniqueGlobalName(const std::string &baseName)
std::pair< cir::FuncType, cir::FuncOp > getAddrAndTypeOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
void setGVProperties(mlir::Operation *op, const NamedDecl *d) const
Set visibility, dllimport/dllexport and dso_local.
cir::GlobalOp getOrCreateCIRGlobal(llvm::StringRef mangledName, mlir::Type ty, LangAS langAS, const VarDecl *d, ForDefinition_t isForDefinition)
If the specified mangled name is not in the module, create and return an mlir::GlobalOp value.
cir::FuncOp createCIRBuiltinFunction(mlir::Location loc, llvm::StringRef name, cir::FuncType ty, const clang::FunctionDecl *fd)
Create a CIR function with builtin attribute set.
cir::GlobalOp getAddrOfTemplateParamObject(const TemplateParamObjectDecl *tpo)
Get the GlobalOp of a template parameter object.
void emitGlobalOpenACCRoutineDecl(const clang::OpenACCRoutineDecl *cd)
clang::CharUnits getClassPointerAlignment(const clang::CXXRecordDecl *rd)
Return the best known alignment for an unknown pointer to a particular class.
void handleCXXStaticMemberVarInstantiation(VarDecl *vd)
Tell the consumer that this variable has been instantiated.
llvm::DenseMap< const UnnamedGlobalConstantDecl *, cir::GlobalOp > unnamedGlobalConstantDeclMap
std::vector< cir::CIRGlobalValueInterface > llvmCompilerUsed
void emitOMPRequiresDecl(const OMPRequiresDecl *d)
void emitGlobalDefinition(clang::GlobalDecl gd, mlir::Operation *op=nullptr)
clang::DiagnosticsEngine & getDiags() const
cir::GlobalLinkageKind getCIRLinkageForDeclarator(const DeclaratorDecl *dd, GVALinkage linkage)
mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty, bool forEH=false)
Get the address of the RTTI descriptor for the given type.
void setFunctionAttributes(GlobalDecl gd, cir::FuncOp f, bool isIncompleteFunction, bool isThunk)
Set function attributes for a function declaration.
static mlir::SymbolTable::Visibility getMLIRVisibilityFromCIRLinkage(cir::GlobalLinkageKind GLK)
const clang::TargetInfo & getTarget() const
void setCIRFunctionAttributes(GlobalDecl gd, const CIRGenFunctionInfo &info, cir::FuncOp func, bool isThunk)
Set the CIR function attributes (Sext, zext, etc).
const llvm::Triple & getTriple() const
static mlir::SymbolTable::Visibility getMLIRVisibility(Visibility v)
void emitTentativeDefinition(const VarDecl *d)
void emitAliasDefinition(GlobalDecl gd)
Emit a definition for an __attribute__((alias)) declaration.
void addUsedGlobal(cir::CIRGlobalValueInterface gv)
Add a global value to the llvmUsed list.
cir::GlobalOp createOrReplaceCXXRuntimeVariable(mlir::Location loc, llvm::StringRef name, mlir::Type ty, cir::GlobalLinkageKind linkage, clang::CharUnits alignment)
Will return a global variable of the given type.
void emitOMPAllocateDecl(const OMPAllocateDecl *d)
void error(SourceLocation loc, llvm::StringRef error)
Emit a general error that something can't be done.
void emitGlobalDecl(const clang::GlobalDecl &d)
Helper for emitDeferred to apply actual codegen.
void emitGlobalVarDefinition(const clang::VarDecl *vd, bool isTentative=false)
cir::FuncOp createRuntimeFunction(cir::FuncType ty, llvm::StringRef name, mlir::NamedAttrList extraAttrs={}, bool isLocal=false, bool assumeConvergent=false)
cir::FuncOp getAddrOfFunction(clang::GlobalDecl gd, mlir::Type funcType=nullptr, bool forVTable=false, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
Return the address of the given function.
void emitAliasForGlobal(llvm::StringRef mangledName, mlir::Operation *op, GlobalDecl aliasGD, cir::FuncOp aliasee, cir::GlobalLinkageKind linkage)
void emitLLVMUsed()
Emit llvm.used and llvm.compiler.used globals.
mlir::Value emitMemberPointerConstant(const UnaryOperator *e)
void emitGlobalOpenACCDecl(const clang::OpenACCConstructDecl *cd)
bool verifyModule() const
void setTLSMode(mlir::Operation *op, const VarDecl &d, bool isExtendingDecl=false)
Set TLS mode for the given operation based on the given variable declaration.
void emitExplicitCastExprType(const ExplicitCastExpr *e, CIRGenFunction *cgf=nullptr)
Emit type info if type of an expression is a variably modified type.
const cir::CIRDataLayout getDataLayout() const
void eraseGlobalSymbol(mlir::Operation *op)
mlir::Operation * getAddrOfGlobalTemporary(const MaterializeTemporaryExpr *mte, const Expr *init)
Returns a pointer to a global variable representing a temporary with static or thread storage duratio...
std::map< llvm::StringRef, clang::GlobalDecl > deferredDecls
This contains all the decls which have definitions but which are deferred for emission and therefore ...
void errorUnsupported(const Stmt *s, llvm::StringRef type)
Print out an error that codegen doesn't support the specified stmt yet.
mlir::Value getAddrOfGlobalVar(const VarDecl *d, mlir::Type ty={}, ForDefinition_t isForDefinition=NotForDefinition)
Return the mlir::Value for the address of the given global variable.
llvm::StringMap< mlir::Operation * > symbolLookupCache
Cache for O(1) symbol lookups by name, replacing the O(N) linear scan in SymbolTable::lookupSymbolIn ...
static void setInitializer(cir::GlobalOp &op, mlir::Attribute value)
cir::GlobalViewAttr getAddrOfGlobalVarAttr(const VarDecl *d)
Return the mlir::GlobalViewAttr for the address of the given global.
void addGlobalCtor(cir::FuncOp ctor, std::optional< int > priority=std::nullopt)
Add a global constructor or destructor to the module.
cir::GlobalLinkageKind getFunctionLinkage(GlobalDecl gd)
void updateCompletedType(const clang::TagDecl *td)
const clang::CodeGenOptions & getCodeGenOpts() const
void emitDeferredVTables()
Emit any vtables which we deferred and still have a use for.
const clang::LangOptions & getLangOpts() const
void printPostfixForExternalizedDecl(llvm::raw_ostream &os, const Decl *d)
Print the postfix for externalized static variable or kernels for single source offloading languages ...
void constructAttributeList(llvm::StringRef name, const CIRGenFunctionInfo &info, CIRGenCalleeInfo calleeInfo, mlir::NamedAttrList &attrs, llvm::MutableArrayRef< mlir::NamedAttrList > argAttrs, mlir::NamedAttrList &retAttrs, cir::CallingConv &callingConv, cir::SideEffect &sideEffect, bool attrOnCallSite, bool isThunk)
Get the CIR attributes and calling convention to use for a particular function type.
cir::FuncOp getOrCreateCIRFunction(llvm::StringRef mangledName, mlir::Type funcType, clang::GlobalDecl gd, bool forVTable, bool dontDefer=false, bool isThunk=false, ForDefinition_t isForDefinition=NotForDefinition, mlir::NamedAttrList extraAttrs={})
void emitOpenACCRoutineDecl(const clang::FunctionDecl *funcDecl, cir::FuncOp func, SourceLocation pragmaLoc, ArrayRef< const OpenACCClause * > clauses)
void emitVTablesOpportunistically()
Try to emit external vtables as available_externally if they have emitted all inlined virtual functio...
cir::GlobalOp createGlobalOp(mlir::Location loc, llvm::StringRef name, mlir::Type t, bool isConstant=false, mlir::ptr::MemorySpaceAttrInterface addrSpace={}, mlir::Operation *insertPoint=nullptr)
void addGlobalDtor(cir::FuncOp dtor, std::optional< int > priority=std::nullopt)
Add a function to the list that will be called when the module is unloaded.
void addDeferredDeclToEmit(clang::GlobalDecl GD)
bool shouldEmitCUDAGlobalVar(const VarDecl *global) const
cir::FuncOp createCIRFunction(mlir::Location loc, llvm::StringRef name, cir::FuncType funcType, const clang::FunctionDecl *funcDecl)
const TargetCIRGenInfo & getTargetCIRGenInfo()
void emitCXXGlobalVarDeclInitFunc(const VarDecl *vd, cir::GlobalOp addr, bool performInit)
static cir::VisibilityKind getCIRVisibilityKind(Visibility v)
void setGVPropertiesAux(mlir::Operation *op, const NamedDecl *d) const
LangAS getLangTempAllocaAddressSpace() const
Returns the address space for temporary allocations in the language.
mlir::Location getLoc(clang::SourceLocation cLoc)
Helpers to convert the presumed location of Clang's SourceLocation to an MLIR Location.
llvm::DenseMap< mlir::Attribute, cir::GlobalOp > constantStringMap
mlir::Operation * lastGlobalOp
void replaceGlobal(cir::GlobalOp oldGV, cir::GlobalOp newGV)
Replace all uses of the old global with the new global, updating types and references as needed.
llvm::StringMap< unsigned > cgGlobalNames
mlir::TypedAttr emitNullMemberAttr(QualType t, const MemberPointerType *mpt)
Returns a null attribute to represent either a null method or null data member, depending on the type...
mlir::Operation * getGlobalValue(llvm::StringRef ref)
void emitOMPDeclareReduction(const OMPDeclareReductionDecl *d)
mlir::ModuleOp getModule() const
bool supportsCOMDAT() const
void addCompilerUsedGlobal(cir::CIRGlobalValueInterface gv)
Add a global value to the llvmCompilerUsed list.
clang::CharUnits getNaturalTypeAlignment(clang::QualType t, LValueBaseInfo *baseInfo=nullptr, bool forPointeeType=false)
FIXME: this could likely be a common helper and not necessarily related with codegen.
mlir::MLIRContext & getMLIRContext()
void emitSYCLKernelCaller(const clang::FunctionDecl *kernelEntryPointFn, clang::ASTContext &ctx)
Emit the SYCL kernel caller offload entry point function generated for a function declared with the s...
mlir::Operation * getAddrOfGlobal(clang::GlobalDecl gd, ForDefinition_t isForDefinition=NotForDefinition)
void maybeSetTrivialComdat(const clang::Decl &d, mlir::Operation *op)
bool isEmptyFieldForMemberPointer(const FieldDecl *field)
Returns true if field is a potentially-overlapping field with no CIR field index (e....
CIRGenCXXABI & getCXXABI() const
cir::GlobalViewAttr getAddrOfConstantStringFromLiteral(const StringLiteral *s, llvm::StringRef name=".str")
Return a global symbol reference to a constant array for the given string literal.
bool lookupRepresentativeDecl(llvm::StringRef mangledName, clang::GlobalDecl &gd) const
void emitDeclContext(const DeclContext *dc)
clang::CharUnits getNaturalPointeeTypeAlignment(clang::QualType t, LValueBaseInfo *baseInfo=nullptr)
void emitGlobal(clang::GlobalDecl gd)
Emit code for a single global function or variable declaration.
bool mayBeEmittedEagerly(const clang::ValueDecl *d)
Determine whether the definition can be emitted eagerly, or should be delayed until the end of the tr...
void addGlobalAnnotations(const clang::ValueDecl *d, mlir::Operation *gv)
Add global annotations for a global value (GlobalOp or FuncOp).
void setCIRFunctionAttributesForDefinition(const clang::FunctionDecl *fd, cir::FuncOp f)
Set extra attributes (inline, etc.) for a function.
std::string getOpenACCBindMangledName(const IdentifierInfo *bindName, const FunctionDecl *attachedFunction)
void emitGlobalFunctionDefinition(clang::GlobalDecl gd, mlir::Operation *op)
CIRGenVTables & getVTables()
void setFunctionLinkage(GlobalDecl gd, cir::FuncOp f)
std::vector< clang::GlobalDecl > deferredDeclsToEmit
void emitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *d)
CIRGenOpenMPRuntime & getOpenMPRuntime()
void emitAMDGPUMetadata()
Emits AMDGPU specific Metadata.
void emitOMPGroupPrivateDecl(const OMPGroupPrivateDecl *d)
mlir::Attribute getConstantArrayFromStringLiteral(const StringLiteral *e)
Return a constant array for the given string.
void setCommonAttributes(GlobalDecl gd, mlir::Operation *op)
Set attributes which are common to any form of a global definition (alias, Objective-C method,...
void emitDeclareTargetFunction(const FunctionDecl *fd, cir::FuncOp funcOp)
If the function has an OMPDeclareTargetDeclAttr, set the corresponding omp.declare_target attribute o...
This class handles record and union layout info while lowering AST types to CIR types.
bool hasNonVirtualBaseCIRField(const CXXRecordDecl *rd) const
unsigned getCIRFieldNo(const clang::FieldDecl *fd) const
Return cir::RecordType element number that corresponds to the field FD.
bool hasCIRField(const clang::FieldDecl *fd) const
bool isZeroInitializable() const
Check whether this struct can be C++ zero-initialized with a zeroinitializer.
unsigned getNonVirtualBaseCIRFieldNo(const CXXRecordDecl *rd) const
const CIRGenFunctionInfo & arrangeGlobalDeclaration(GlobalDecl gd)
const CIRGenFunctionInfo & arrangeCXXMethodDeclaration(const clang::CXXMethodDecl *md)
C++ methods have some special rules and also have implicit parameters.
const CIRGenFunctionInfo & arrangeCXXStructorDeclaration(clang::GlobalDecl gd)
cir::FuncType getFunctionType(const CIRGenFunctionInfo &info)
Get the CIR function type for.
const CIRGenRecordLayout & getCIRGenRecordLayout(const clang::RecordDecl *rd)
Return record layout info for the given record decl.
mlir::Type convertTypeForMem(clang::QualType, bool forBitField=false)
Convert type T into an mlir::Type.
void emitThunks(GlobalDecl gd)
Emit the associated thunks for the given global decl.
void finalize(cir::GlobalOp gv)
mlir::Attribute emitForInitializer(const APValue &value, QualType destType)
virtual clang::LangAS getGlobalVarAddressSpace(CIRGenModule &cgm, const clang::VarDecl *d) const
Get target favored AST address space of a global variable for languages other than OpenCL and CUDA.
virtual mlir::ptr::MemorySpaceAttrInterface getCIRAllocaAddressSpace() const
Get the address space for alloca.
virtual void setTargetAttributes(const clang::Decl *decl, mlir::Operation *global, CIRGenModule &module) const
Provides a convenient hook to handle extra target-specific attributes for the given global.
Represents a base class of a C++ class.
Represents a C++ constructor within a class.
bool isMoveConstructor(unsigned &TypeQuals) const
Determine whether this constructor is a move constructor (C++11 [class.copy]p3), which can be used to...
bool isCopyConstructor(unsigned &TypeQuals) const
Whether this constructor is a copy constructor (C++ [class.copy]p2, which can be used to copy the cla...
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
Represents a static or instance method of a struct/union/class.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
Represents a C++ struct/union/class.
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
bool hasDefinition() const
CharUnits - This is an opaque type for sizes expressed in character units.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
llvm::Reloc::Model RelocationModel
The name of the relocation model to use.
Represents the canonical version of C arrays with a specified constant size.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
bool isInExportDeclContext() const
Whether this declaration was exported in a lexical context.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
static DeclContext * castToDeclContext(const Decl *)
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Represents a ValueDecl that came out of a declarator.
A little helper class used to produce diagnostics.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
ExplicitCastExpr - An explicit cast written in the source code.
This represents one expression.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Represents a member of a struct/union/class.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
bool isPotentiallyOverlapping() const
Determine if this field is of potentially-overlapping class type, that is, subobject with the [[no_un...
Cached information about one file (either on disk or in the virtual file system).
StringRef tryGetRealPathName() const
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Represents a function declaration or definition.
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin=false, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=ConstexprSpecKind::Unspecified, const AssociatedConstraint &TrailingRequiresClause={})
ArrayRef< ParmVarDecl * > parameters() const
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
FunctionDecl * getDefinition()
Get the definition for this declaration.
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
FunctionType - C99 6.7.5.3 - Function Declarators.
CallingConv getCallConv() const
GlobalDecl - represents a global declaration.
CXXCtorType getCtorType() const
GlobalDecl getCanonicalDecl() const
KernelReferenceKind getKernelReferenceKind() const
GlobalDecl getWithDecl(const Decl *D)
unsigned getMultiVersionIndex() const
CXXDtorType getDtorType() const
const Decl * getDecl() const
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
std::string CUID
The user provided compilation unit ID, if non-empty.
Visibility getVisibility() const
void setLinkage(Linkage L)
Linkage getLinkage() const
bool isVisibilityExplicit() const
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
bool isTriviallyRecursive(const FunctionDecl *FD)
Return true if FD's body contains a direct call back to the symbol it links as, through an asm label ...
bool shouldMangleDeclName(const NamedDecl *D)
void mangleName(GlobalDecl GD, raw_ostream &)
virtual void mangleReferenceTemporary(const VarDecl *D, unsigned ManglingNumber, raw_ostream &)=0
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
APValue * getOrCreateValue(bool MayCreate) const
Get the storage for the constant value of a materialized temporary of static storage duration.
ValueDecl * getExtendingDecl()
Get the declaration which triggered the lifetime-extension of this temporary, if any.
unsigned getManglingNumber() const
A pointer to member type per C++ 8.3.3 - Pointers to members.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
Describes a module or submodule.
bool isModuleImplementation() const
Is this a module implementation.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
LinkageInfo getLinkageAndVisibility() const
Determines the linkage and visibility of this entity.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Represents a parameter to a function.
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getCanonicalType() const
bool isConstQualified() const
Determine whether this type is const-qualified.
bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor, bool ExcludeDtor)
bool hasUnaligned() const
Represents a struct/union/class.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getLength() const
uint32_t getCodeUnit(size_t I) const
Return the code unit at the given position.
StringRef getString() const
unsigned getCharByteWidth() const
Represents the declaration of a struct/union/class/enum.
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
TargetOptions & getTargetOpts() const
Retrieve the target options.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
bool isReadOnlyFeature(StringRef Feature) const
Determine whether the given target feature is read only.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
virtual ParsedTargetAttr parseTargetAttr(StringRef Str) const
virtual bool initFeatureMap(llvm::StringMap< bool > &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector< std::string > &FeatureVec) const
Initialize the map with the default set of target features for the CPU this should include all legal ...
std::vector< std::string > Features
The list of target specific features to enable or disable – this should be a list of strings starting...
std::string TuneCPU
If given, the name of the target CPU to tune code for.
std::string CPU
If given, the name of the target CPU to generate code for.
A template parameter object.
const APValue & getValue() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isCUDADeviceBuiltinSurfaceType() const
Check if the type is the CUDA device builtin surface type.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isCUDADeviceBuiltinTextureType() const
Check if the type is the CUDA device builtin texture type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isObjCObjectPointerType() const
bool isMemberFunctionPointerType() const
const T * getAs() const
Member-template getAs<specific type>'.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
An artificial decl, representing a global anonymous constant value which is uniquified by value withi...
const APValue & getValue() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
TLSKind getTLSKind() const
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool hasFlexibleArrayInit(const ASTContext &Ctx) const
Whether this variable has a flexible array member initialized with one or more elements.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const
Would the destruction of this variable have any effect, and if so, what kind?
const Expr * getInit() const
bool hasExternalStorage() const
Returns true if a variable has extern or private_extern storage.
@ TLS_None
Not a TLS variable.
@ DeclarationOnly
This declaration is only a declaration.
@ Definition
This declaration is definitely a definition.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
TemplateSpecializationKind getTemplateSpecializationKind() const
If this variable is an instantiation of a variable template or a static data member of a class templa...
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
bool isMatchingAddressSpace(mlir::ptr::MemorySpaceAttrInterface cirAS, clang::LangAS as)
mlir::ptr::MemorySpaceAttrInterface toCIRAddressSpaceAttr(mlir::MLIRContext &ctx, clang::LangAS langAS)
Convert an AST LangAS to the appropriate CIR address space attribute interface.
static bool isWeakForLinker(GlobalLinkageKind linkage)
Whether the definition of this global may be replaced at link time.
@ AttributedType
The l-value was considered opaque, so the alignment was determined from a type, but that type was an ...
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
std::unique_ptr< TargetCIRGenInfo > createAMDGPUTargetCIRGenInfo(CIRGenTypes &cgt)
std::unique_ptr< TargetCIRGenInfo > createNVPTXTargetCIRGenInfo(CIRGenTypes &cgt)
CIRGenCXXABI * CreateCIRGenItaniumCXXABI(CIRGenModule &cgm)
Creates and Itanium-family ABI.
std::unique_ptr< TargetCIRGenInfo > createX8664TargetCIRGenInfo(CIRGenTypes &cgt)
std::unique_ptr< TargetCIRGenInfo > createCommonSPIRTargetCIRGenInfo(CIRGenTypes &cgt)
bool isEmptyFieldForLayout(const ASTContext &context, const FieldDecl *fd)
isEmptyFieldForLayout - Return true if the field is "empty", that is, either a zero-width bit-field o...
std::unique_ptr< TargetCIRGenInfo > createAArch64TargetCIRGenInfo(CIRGenTypes &cgt)
CIRGenCUDARuntime * createNVCUDARuntime(CIRGenModule &cgm)
bool hasUnwindExceptions(const LangOptions &LangOpts)
Determines whether the language options require us to model unwind exceptions.
const internal::VariadicDynCastAllOfMatcher< Decl, VarDecl > varDecl
Matches variable declarations.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, FieldDecl > fieldDecl
Matches field declarations.
const internal::VariadicDynCastAllOfMatcher< Decl, FunctionDecl > functionDecl
Matches function declarations.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
GVALinkage
A more specific kind of linkage than enum Linkage.
@ GVA_AvailableExternally
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ SD_Thread
Thread storage duration.
@ SD_Static
Static storage duration.
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Dtor_Complete
Complete object dtor.
LangAS
Defines the address space values used by the address space qualifier of QualType.
@ FirstTargetAddressSpace
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
U cast(CodeGen::Address addr)
bool isExternallyVisible(Linkage L)
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 int32_t
static bool globalCtorLexOrder()
static bool opFuncArmNewAttr()
static bool getRuntimeFunctionDecl()
static bool weakRefReference()
static bool opFuncOptNoneAttr()
static bool addressSpace()
static bool opFuncMinSizeAttr()
static bool opGlobalUnnamedAddr()
static bool opGlobalThreadLocal()
static bool opFuncMultiVersioning()
static bool sourceLanguageCases()
static bool shouldSkipAliasEmission()
static bool opFuncAstDeclAttr()
static bool opFuncNoDuplicateAttr()
static bool stackProtector()
static bool moduleNameHash()
static bool opGlobalVisibility()
static bool setDLLStorageClass()
static bool opFuncUnwindTablesAttr()
static bool opFuncParameterAttributes()
static bool targetCIRGenInfoArch()
static bool opFuncExtraAttrs()
static bool opFuncNakedAttr()
static bool attributeNoBuiltin()
static bool opGlobalDLLImportExport()
static bool opGlobalPartition()
static bool opGlobalPragmaClangSection()
static bool opGlobalWeakRef()
static bool deferredCXXGlobalInit()
static bool opFuncOperandBundles()
static bool opFuncCallingConv()
static bool globalCtorAssociatedData()
static bool defaultVisibility()
static bool opFuncColdHotAttr()
static bool opFuncExceptions()
static bool opFuncArmStreamingAttr()
static bool cudaSupport()
static bool opFuncMaybeHandleStaticInExternC()
static bool checkAliases()
static bool generateDebugInfo()
static bool targetCIRGenInfoOS()
static bool maybeHandleStaticInExternC()
static bool setLLVMFunctionFEnvAttributes()
mlir::Type uCharTy
ClangIR char.
unsigned char SizeSizeInBytes
unsigned char PointerAlignInBytes
cir::PointerType allocaInt8PtrTy
void* in alloca address space
cir::PointerType uInt8PtrTy
mlir::ptr::MemorySpaceAttrInterface cirAllocaAddressSpace
cir::PointerType voidPtrTy
void* in address space 0
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
bool hasSideEffects() const
Return true if the evaluated expression has side effects.
Describes how types, statements, expressions, and declarations should be printed.