21#include "clang/AST/Attrs.inc"
37#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
38#include "mlir/IR/BuiltinOps.h"
39#include "mlir/IR/Location.h"
40#include "mlir/IR/MLIRContext.h"
41#include "mlir/IR/Operation.h"
42#include "mlir/IR/Verifier.h"
51 case TargetCXXABI::GenericItanium:
52 case TargetCXXABI::GenericAArch64:
53 case TargetCXXABI::AppleARM64:
56 case TargetCXXABI::Fuchsia:
57 case TargetCXXABI::GenericARM:
58 case TargetCXXABI::iOS:
59 case TargetCXXABI::WatchOS:
60 case TargetCXXABI::GenericMIPS:
61 case TargetCXXABI::WebAssembly:
62 case TargetCXXABI::XL:
63 case TargetCXXABI::Microsoft:
64 cgm.
errorNYI(
"createCXXABI: C++ ABI kind");
68 llvm_unreachable(
"invalid C++ ABI kind");
71CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
75 : builder(mlirContext, *this), astContext(astContext),
76 langOpts(astContext.
getLangOpts()), codeGenOpts(cgo),
77 theModule{
mlir::ModuleOp::create(
mlir::UnknownLoc::get(&mlirContext))},
78 diags(diags), target(astContext.getTargetInfo()),
79 abi(
createCXXABI(*this)), genTypes(*this), vtables(*this) {
107 .toCharUnitsFromBits(
111 const unsigned charSize = astContext.getTargetInfo().getCharWidth();
115 const unsigned sizeTypeSize =
116 astContext.getTypeSize(astContext.getSignedSizeType());
117 SizeSizeInBytes = astContext.toCharUnitsFromBits(sizeTypeSize).getQuantity();
124 std::optional<cir::SourceLanguage> sourceLanguage = getCIRSourceLanguage();
127 cir::CIRDialect::getSourceLanguageAttrName(),
128 cir::SourceLanguageAttr::get(&mlirContext, *sourceLanguage));
129 theModule->setAttr(cir::CIRDialect::getTripleAttrName(),
130 builder.getStringAttr(
getTriple().str()));
132 if (cgo.OptimizationLevel > 0 || cgo.OptimizeSize > 0)
133 theModule->setAttr(cir::CIRDialect::getOptInfoAttrName(),
134 cir::OptInfoAttr::get(&mlirContext,
135 cgo.OptimizationLevel,
144 FileID mainFileId = astContext.getSourceManager().getMainFileID();
146 *astContext.getSourceManager().getFileEntryForID(mainFileId);
149 theModule.setSymName(path);
150 theModule->setLoc(mlir::FileLineColLoc::get(&mlirContext, path,
158void CIRGenModule::createCUDARuntime() {
170 auto &layout = astContext.getASTRecordLayout(rd);
175 return layout.getAlignment();
178 return layout.getNonVirtualAlignment();
183 bool forPointeeType) {
193 if (
unsigned align = tt->getDecl()->getMaxAlignment()) {
196 return astContext.toCharUnitsFromBits(align);
204 t = astContext.getBaseElementType(t);
225 }
else if (forPointeeType && !alignForArray &&
229 alignment = astContext.getTypeAlignInChars(t);
234 if (
unsigned maxAlign = astContext.getLangOpts().MaxTypeAlign) {
236 !astContext.isAlignmentRequired(t))
250 if (theTargetCIRGenInfo)
251 return *theTargetCIRGenInfo;
254 switch (triple.getArch()) {
261 case llvm::Triple::x86_64: {
262 switch (triple.getOS()) {
269 case llvm::Triple::Linux:
271 return *theTargetCIRGenInfo;
274 case llvm::Triple::nvptx:
275 case llvm::Triple::nvptx64:
277 return *theTargetCIRGenInfo;
278 case llvm::Triple::amdgcn: {
280 return *theTargetCIRGenInfo;
286 assert(cLoc.
isValid() &&
"expected valid source location");
290 return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
295 assert(cRange.
isValid() &&
"expected a valid source range");
298 mlir::Attribute metadata;
299 return mlir::FusedLoc::get({begin, end}, metadata, builder.getContext());
308 false, isForDefinition);
342 assert(op &&
"expected a valid global op");
350 mlir::Operation *globalValueOp = op;
351 if (
auto gv = dyn_cast<cir::GetGlobalOp>(op))
353 mlir::SymbolTable::lookupSymbolIn(
getModule(), gv.getNameAttr());
355 if (
auto cirGlobalValue =
356 dyn_cast<cir::CIRGlobalValueInterface>(globalValueOp))
357 if (!cirGlobalValue.isDeclaration())
378 assert(deferredVTables.empty());
388 std::vector<GlobalDecl> curDeclsToEmit;
407 if (
auto *
attr =
decl->getAttr<AttrT>())
408 return attr->isImplicit();
409 return decl->isImplicit();
414 assert(langOpts.CUDA &&
"Should not be called by non-CUDA languages");
419 return !langOpts.CUDAIsDevice || global->
hasAttr<CUDADeviceAttr>() ||
420 global->
hasAttr<CUDAConstantAttr>() ||
421 global->
hasAttr<CUDASharedAttr>() ||
427 if (
const auto *cd = dyn_cast<clang::OpenACCConstructDecl>(gd.
getDecl())) {
445 "Expected Variable or Function");
446 if (
const auto *
varDecl = dyn_cast<VarDecl>(global)) {
450 }
else if (langOpts.CUDAIsDevice) {
451 const auto *
functionDecl = dyn_cast<FunctionDecl>(global);
452 if ((!global->hasAttr<CUDADeviceAttr>() ||
453 (langOpts.OffloadImplicitHostDeviceTemplates &&
458 !
getASTContext().CUDAImplicitHostDeviceFunUsedByDevice.count(
460 !global->hasAttr<CUDAGlobalAttr>() &&
462 !global->hasAttr<CUDAHostAttr>()))
465 }
else if (!global->hasAttr<CUDAHostAttr>() &&
466 global->hasAttr<CUDADeviceAttr>())
470 if (
const auto *fd = dyn_cast<FunctionDecl>(global)) {
473 if (fd->hasAttr<AnnotateAttr>())
474 errorNYI(fd->getSourceRange(),
"deferredAnnotations");
475 if (!fd->doesThisDeclarationHaveABody()) {
476 if (!fd->doesDeclarationForceExternallyVisibleDefinition())
480 "function declaration that forces code gen");
485 assert(vd->isFileVarDecl() &&
"Cannot emit local var decl as global.");
487 !astContext.isMSStaticDataMemberInlineDefinition(vd)) {
491 if (astContext.getInlineVariableDefinitionKind(vd) ==
530 mlir::Operation *op) {
534 cir::FuncOp funcOp = dyn_cast_if_present<cir::FuncOp>(op);
535 if (!funcOp || funcOp.getFunctionType() != funcType) {
541 if (!funcOp.isDeclaration())
553 mlir::OpBuilder::InsertionGuard guard(builder);
558 setNonAliasAttributes(gd, funcOp);
561 auto getPriority = [
this](
const auto *
attr) ->
int {
565 return attr->DefaultPriority;
568 if (
const ConstructorAttr *ca = funcDecl->getAttr<ConstructorAttr>())
570 if (
const DestructorAttr *da = funcDecl->getAttr<DestructorAttr>())
573 if (funcDecl->getAttr<AnnotateAttr>())
574 errorNYI(funcDecl->getSourceRange(),
"deferredAnnotations");
579 std::optional<int> priority) {
588 ctor.setGlobalCtorPriority(priority);
593 std::optional<int> priority) {
594 if (codeGenOpts.RegisterGlobalDtorsWithAtExit &&
596 errorNYI(dtor.getLoc(),
"registerGlobalDtorsWithAtExit");
599 dtor.setGlobalDtorPriority(priority);
617 return mlir::SymbolTable::lookupSymbolIn(theModule, name);
622 StringRef name, mlir::Type t,
bool isConstant,
623 mlir::ptr::MemorySpaceAttrInterface addrSpace,
624 mlir::Operation *insertPoint) {
629 mlir::OpBuilder::InsertionGuard guard(builder);
635 builder.setInsertionPoint(insertPoint);
641 builder.setInsertionPointToStart(cgm.
getModule().getBody());
644 g = cir::GlobalOp::create(builder, loc, name, t, isConstant, addrSpace);
650 mlir::SymbolTable::setSymbolVisibility(
651 g, mlir::SymbolTable::Visibility::Private);
658 if (isa_and_nonnull<NamedDecl>(d))
664void CIRGenModule::setNonAliasAttributes(
GlobalDecl gd, mlir::Operation *op) {
675std::optional<cir::SourceLanguage> CIRGenModule::getCIRSourceLanguage()
const {
677 using CIRLang = cir::SourceLanguage;
682 if (opts.C99 || opts.C11 || opts.C17 || opts.C23 || opts.C2y ||
683 opts.LangStd == ClangStd::lang_c89 ||
684 opts.LangStd == ClangStd::lang_gnu89)
689 errorNYI(
"CIR does not yet support the given source language");
693LangAS CIRGenModule::getGlobalVarAddressSpace(
const VarDecl *d) {
694 if (langOpts.OpenCL) {
702 if (langOpts.SYCLIsDevice &&
704 errorNYI(
"SYCL global address space");
706 if (langOpts.CUDA && langOpts.CUDAIsDevice) {
708 if (d->
hasAttr<CUDAConstantAttr>())
710 if (d->
hasAttr<CUDASharedAttr>())
712 if (d->
hasAttr<CUDADeviceAttr>())
721 errorNYI(
"OpenMP global address space");
734 gv.
setLinkage(cir::GlobalLinkageKind::ExternalWeakLinkage);
739 for (mlir::Attribute i : indexes) {
740 auto ind = mlir::cast<mlir::IntegerAttr>(i);
741 inds.push_back(ind.getValue().getSExtValue());
747 return view.getSymbol().getValue() == glob.getSymName();
751 cir::GlobalOp newGlob,
752 cir::GlobalViewAttr
attr,
763 mlir::Type newTy = newGlob.getSymType();
768 cir::PointerType newPtrTy;
771 newPtrTy = cir::PointerType::get(newTy);
780 cgm.
errorNYI(
"Unhandled type in createNewGlobalView");
786 mlir::Attribute oldInit) {
787 if (
auto oldView = mlir::dyn_cast<cir::GlobalViewAttr>(oldInit))
790 auto getNewInitElements =
791 [&](mlir::ArrayAttr oldElements) -> mlir::ArrayAttr {
793 for (mlir::Attribute elt : oldElements) {
794 if (
auto view = mlir::dyn_cast<cir::GlobalViewAttr>(elt))
796 else if (mlir::isa<cir::ConstArrayAttr, cir::ConstRecordAttr>(elt))
799 newElements.push_back(elt);
801 return mlir::ArrayAttr::get(cgm.
getBuilder().getContext(), newElements);
804 if (
auto oldArray = mlir::dyn_cast<cir::ConstArrayAttr>(oldInit)) {
805 mlir::Attribute newElements =
806 getNewInitElements(mlir::cast<mlir::ArrayAttr>(oldArray.getElts()));
808 newElements, mlir::cast<cir::ArrayType>(oldArray.getType()));
810 if (
auto oldRecord = mlir::dyn_cast<cir::ConstRecordAttr>(oldInit)) {
811 mlir::ArrayAttr newMembers = getNewInitElements(oldRecord.getMembers());
812 auto recordTy = mlir::cast<cir::RecordType>(oldRecord.getType());
814 newMembers, recordTy.getPacked(), recordTy.getPadded(), recordTy);
819 cgm.
errorNYI(
"Unhandled type in getNewInitValue");
827 assert(oldGV.getSymName() == newGV.getSymName() &&
"symbol names must match");
829 mlir::Type oldTy = oldGV.getSymType();
830 mlir::Type newTy = newGV.getSymType();
835 assert(oldTy != newTy &&
"expected type change in replaceGlobal");
838 std::optional<mlir::SymbolTable::UseRange> oldSymUses =
839 oldGV.getSymbolUses(theModule);
840 for (mlir::SymbolTable::SymbolUse use : *oldSymUses) {
841 mlir::Operation *userOp = use.getUser();
843 (mlir::isa<cir::GetGlobalOp, cir::GlobalOp, cir::ConstantOp>(userOp)) &&
844 "Unexpected user for global op");
846 if (
auto getGlobalOp = dyn_cast<cir::GetGlobalOp>(use.getUser())) {
847 mlir::Value useOpResultValue = getGlobalOp.getAddr();
848 useOpResultValue.setType(cir::PointerType::get(newTy));
850 mlir::OpBuilder::InsertionGuard guard(builder);
851 builder.setInsertionPointAfter(getGlobalOp);
852 mlir::Type ptrTy = builder.getPointerTo(oldTy);
854 builder.createBitcast(getGlobalOp->getLoc(), useOpResultValue, ptrTy);
855 useOpResultValue.replaceAllUsesExcept(
cast,
cast.getDefiningOp());
856 }
else if (
auto glob = dyn_cast<cir::GlobalOp>(userOp)) {
857 if (
auto init = glob.getInitialValue()) {
858 mlir::Attribute nw =
getNewInitValue(*
this, newGV, oldTy, init.value());
859 glob.setInitialValueAttr(nw);
861 }
else if (
auto c = dyn_cast<cir::ConstantOp>(userOp)) {
863 auto typedAttr = mlir::cast<mlir::TypedAttr>(init);
864 mlir::OpBuilder::InsertionGuard guard(builder);
865 builder.setInsertionPointAfter(
c);
866 auto newUser = cir::ConstantOp::create(builder,
c.getLoc(), typedAttr);
867 c.replaceAllUsesWith(newUser.getOperation());
898 "getOrCreateCIRGlobal: global with non-GlobalOp type");
908 if (entry.getSymType() == ty &&
918 if (isForDefinition && !entry.isDeclaration()) {
920 "getOrCreateCIRGlobal: global with conflicting type");
928 if (!isForDefinition)
937 bool isConstant =
false;
942 astContext,
true, !needsDtor);
945 mlir::ptr::MemorySpaceAttrInterface declCIRAS =
951 *
this, loc, mangledName, ty, isConstant, declCIRAS,
952 entry.getOperation());
972 if (langOpts.OpenMP && !langOpts.OpenMPSimd)
974 "getOrCreateCIRGlobal: OpenMP target global variable");
976 gv.setAlignmentAttr(
getSize(astContext.getDeclAlign(d)));
990 if (astContext.isMSStaticDataMemberInlineDefinition(d))
992 "getOrCreateCIRGlobal: MS static data member inline definition");
998 if (
getTriple().getArch() == llvm::Triple::xcore)
1000 "getOrCreateCIRGlobal: XCore specific ABI requirements");
1010 "getOrCreateCIRGlobal: external const declaration with initializer");
1022 "getOrCreateCIRGlobal: HIP managed attribute");
1057 mlir::Type ptrTy = builder.getPointerTo(g.getSymType(), g.getAddrSpaceAttr());
1058 return cir::GetGlobalOp::create(
1061 g.getStaticLocalGuard().has_value());
1069 cir::PointerType ptrTy =
1070 builder.getPointerTo(globalOp.getSymType(), globalOp.getAddrSpaceAttr());
1071 return builder.getGlobalViewAttr(ptrTy, globalOp);
1078 "emitGlobalVarDefinition: emit OpenCL/OpenMP global variable");
1085 bool isDefinitionAvailableExternally =
1090 if (isDefinitionAvailableExternally &&
1098 mlir::Attribute init;
1099 bool needsGlobalCtor =
false;
1100 bool needsGlobalDtor =
1101 !isDefinitionAvailableExternally &&
1106 std::optional<ConstantEmitter> emitter;
1111 bool isCUDASharedVar =
1116 bool isCUDAShadowVar =
1118 (vd->
hasAttr<CUDAConstantAttr>() || vd->
hasAttr<CUDADeviceAttr>() ||
1119 vd->
hasAttr<CUDASharedAttr>());
1120 bool isCUDADeviceShadowVar =
1126 (isCUDASharedVar || isCUDAShadowVar || isCUDADeviceShadowVar)) {
1128 }
else if (vd->
hasAttr<LoaderUninitializedAttr>()) {
1130 "emitGlobalVarDefinition: loader uninitialized attribute");
1131 }
else if (!initExpr) {
1144 emitter.emplace(*
this);
1145 mlir::Attribute initializer = emitter->tryEmitForInitializer(*initDecl);
1154 "emitGlobalVarDefinition: flexible array initializer");
1156 if (!isDefinitionAvailableExternally)
1157 needsGlobalCtor =
true;
1160 "emitGlobalVarDefinition: static initializer");
1171 mlir::Type initType;
1172 if (mlir::isa<mlir::SymbolRefAttr>(init)) {
1175 "emitGlobalVarDefinition: global initializer is a symbol reference");
1178 assert(mlir::isa<mlir::TypedAttr>(init) &&
"This should have a type");
1179 auto typedInitAttr = mlir::cast<mlir::TypedAttr>(init);
1180 initType = typedInitAttr.getType();
1182 assert(!mlir::isa<mlir::NoneType>(initType) &&
"Should have a type by now");
1188 if (!gv || gv.getSymType() != initType) {
1190 "emitGlobalVarDefinition: global initializer with type mismatch");
1196 if (vd->
hasAttr<AnnotateAttr>()) {
1198 "emitGlobalVarDefinition: annotate global variable");
1202 cir::GlobalLinkageKind linkage =
1212 if (langOpts.CUDA) {
1213 if (langOpts.CUDAIsDevice) {
1216 if (linkage != cir::GlobalLinkageKind::InternalLinkage &&
1218 (vd->
hasAttr<CUDADeviceAttr>() || vd->
hasAttr<CUDAConstantAttr>() ||
1221 gv->setAttr(cir::CUDAExternallyInitializedAttr::getMnemonic(),
1237 emitter->finalize(gv);
1241 gv.setConstant((vd->
hasAttr<CUDAConstantAttr>() && langOpts.CUDAIsDevice) ||
1242 (!needsGlobalCtor && !needsGlobalDtor &&
1249 gv.setLinkage(linkage);
1253 if (linkage == cir::GlobalLinkageKind::CommonLinkage) {
1255 gv.setConstant(
false);
1260 std::optional<mlir::Attribute> initializer = gv.getInitialValue();
1261 if (initializer && !
getBuilder().isNullValue(*initializer))
1262 gv.setLinkage(cir::GlobalLinkageKind::WeakAnyLinkage);
1265 setNonAliasAttributes(vd, gv);
1272 if (needsGlobalCtor || needsGlobalDtor)
1277 mlir::Operation *op) {
1279 if (
const auto *fd = dyn_cast<FunctionDecl>(
decl)) {
1283 if (
const auto *method = dyn_cast<CXXMethodDecl>(
decl)) {
1287 abi->emitCXXStructor(gd);
1288 else if (fd->isMultiVersion())
1289 errorNYI(method->getSourceRange(),
"multiversion functions");
1293 if (method->isVirtual())
1299 if (fd->isMultiVersion())
1300 errorNYI(fd->getSourceRange(),
"multiversion functions");
1305 if (
const auto *vd = dyn_cast<VarDecl>(
decl))
1308 llvm_unreachable(
"Invalid argument to CIRGenModule::emitGlobalDefinition");
1322 astContext.getAsConstantArrayType(e->
getType());
1323 uint64_t finalSize = cat->getZExtSize();
1324 str.resize(finalSize);
1326 mlir::Type eltTy =
convertType(cat->getElementType());
1327 return builder.getString(str, eltTy, finalSize,
false);
1332 auto arrayEltTy = mlir::cast<cir::IntType>(arrayTy.getElementType());
1334 uint64_t arraySize = arrayTy.getSize();
1336 assert(arraySize == literalSize + 1 &&
1337 "wide string literal array size must be literal length plus null "
1342 bool isAllZero =
true;
1343 for (
unsigned i = 0; i < literalSize; ++i) {
1351 return cir::ZeroAttr::get(arrayTy);
1355 elements.reserve(arraySize);
1356 for (
unsigned i = 0; i < literalSize; ++i)
1357 elements.push_back(cir::IntAttr::get(arrayEltTy, e->
getCodeUnit(i)));
1359 elements.push_back(cir::IntAttr::get(arrayEltTy, 0));
1361 auto elementsAttr = mlir::ArrayAttr::get(&
getMLIRContext(), elements);
1362 return builder.getConstArray(elementsAttr, arrayTy);
1373 if (d.
hasAttr<SelectAnyAttr>())
1377 if (
auto *vd = dyn_cast<VarDecl>(&d))
1392 llvm_unreachable(
"No such linkage");
1398 if (
auto globalOp = dyn_cast_or_null<cir::GlobalOp>(op)) {
1399 globalOp.setComdat(
true);
1402 funcOp.setComdat(
true);
1408 genTypes.updateCompletedType(td);
1412 replacements[name] = op;
1415void CIRGenModule::replacePointerTypeArgs(cir::FuncOp oldF, cir::FuncOp newF) {
1416 std::optional<mlir::SymbolTable::UseRange> optionalUseRange =
1417 oldF.getSymbolUses(theModule);
1418 if (!optionalUseRange)
1421 for (
const mlir::SymbolTable::SymbolUse &u : *optionalUseRange) {
1423 auto call = mlir::dyn_cast<cir::CallOp>(u.getUser());
1427 for (
const auto [argOp, fnArgType] :
1428 llvm::zip(call.getArgs(), newF.getFunctionType().getInputs())) {
1429 if (argOp.getType() == fnArgType)
1435 errorNYI(call.getLoc(),
"replace call with mismatched types");
1440void CIRGenModule::applyReplacements() {
1441 for (
auto &i : replacements) {
1442 StringRef mangledName = i.first;
1443 mlir::Operation *replacement = i.second;
1449 auto newF = dyn_cast<cir::FuncOp>(replacement);
1452 errorNYI(replacement->getLoc(),
"replacement is not a function");
1458 replacePointerTypeArgs(oldF, newF);
1461 if (oldF.replaceAllSymbolUses(newF.getSymNameAttr(), theModule).failed())
1462 llvm_unreachable(
"internal error, cannot RAUW symbol");
1464 newF->moveBefore(oldF);
1471 mlir::Location loc, StringRef name, mlir::Type ty,
1473 auto gv = mlir::dyn_cast_or_null<cir::GlobalOp>(
1474 mlir::SymbolTable::lookupSymbolIn(theModule, name));
1478 if (gv.getSymType() == ty)
1484 assert(gv.isDeclaration() &&
"Declaration has wrong type!");
1486 errorNYI(loc,
"createOrReplaceCXXRuntimeVariable: declaration exists with "
1497 mlir::SymbolTable::setSymbolVisibility(gv,
1501 !gv.hasAvailableExternallyLinkage()) {
1505 gv.setAlignmentAttr(
getSize(alignment));
1516 if ((noCommon || vd->
hasAttr<NoCommonAttr>()) && !vd->
hasAttr<CommonAttr>())
1527 if (vd->
hasAttr<SectionAttr>())
1533 if (vd->
hasAttr<PragmaClangBSSSectionAttr>() ||
1534 vd->
hasAttr<PragmaClangDataSectionAttr>() ||
1535 vd->
hasAttr<PragmaClangRelroSectionAttr>() ||
1536 vd->
hasAttr<PragmaClangRodataSectionAttr>())
1544 if (vd->
hasAttr<WeakImportAttr>())
1554 if (vd->
hasAttr<AlignedAttr>())
1561 for (
const FieldDecl *fd : rd->fields()) {
1562 if (fd->isBitField())
1564 if (fd->hasAttr<AlignedAttr>())
1589 return cir::GlobalLinkageKind::InternalLinkage;
1591 if (dd->
hasAttr<WeakAttr>()) {
1592 if (isConstantVariable)
1593 return cir::GlobalLinkageKind::WeakODRLinkage;
1594 return cir::GlobalLinkageKind::WeakAnyLinkage;
1599 return cir::GlobalLinkageKind::LinkOnceAnyLinkage;
1604 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
1618 return !astContext.getLangOpts().AppleKext
1619 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
1620 : cir::GlobalLinkageKind::InternalLinkage;
1634 return cir::GlobalLinkageKind::ExternalLinkage;
1637 return dd->
hasAttr<CUDAGlobalAttr>()
1638 ? cir::GlobalLinkageKind::ExternalLinkage
1639 : cir::GlobalLinkageKind::InternalLinkage;
1640 return cir::GlobalLinkageKind::WeakODRLinkage;
1648 return cir::GlobalLinkageKind::CommonLinkage;
1654 if (dd->
hasAttr<SelectAnyAttr>())
1655 return cir::GlobalLinkageKind::WeakODRLinkage;
1659 return cir::GlobalLinkageKind::ExternalLinkage;
1671 mlir::Operation *old, cir::FuncOp newFn) {
1673 auto oldFn = mlir::dyn_cast<cir::FuncOp>(old);
1681 if (oldFn->getAttrs().size() <= 1)
1683 "replaceUsesOfNonProtoTypeWithRealFunction: Attribute forwarding");
1686 newFn.setNoProto(oldFn.getNoProto());
1689 std::optional<mlir::SymbolTable::UseRange> symUses =
1690 oldFn.getSymbolUses(oldFn->getParentOp());
1691 for (
const mlir::SymbolTable::SymbolUse &use : symUses.value()) {
1692 mlir::OpBuilder::InsertionGuard guard(builder);
1694 if (
auto noProtoCallOp = mlir::dyn_cast<cir::CallOp>(use.getUser())) {
1695 builder.setInsertionPoint(noProtoCallOp);
1698 cir::CallOp realCallOp = builder.createCallOp(
1699 noProtoCallOp.getLoc(), newFn, noProtoCallOp.getOperands());
1702 noProtoCallOp.replaceAllUsesWith(realCallOp);
1703 noProtoCallOp.erase();
1704 }
else if (
auto getGlobalOp =
1705 mlir::dyn_cast<cir::GetGlobalOp>(use.getUser())) {
1707 getGlobalOp.getAddr().setType(
1708 cir::PointerType::get(newFn.getFunctionType()));
1711 "replaceUsesOfNonProtoTypeWithRealFunction: unexpected use");
1716cir::GlobalLinkageKind
1718 assert(!isConstant &&
"constant variables NYI");
1719 GVALinkage linkage = astContext.GetGVALinkageForVariable(vd);
1726 GVALinkage linkage = astContext.GetGVALinkageForFunction(d);
1728 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(d))
1737 StringRef globalName,
CharUnits alignment) {
1743 cgm, loc, globalName,
c.getType(), !cgm.
getLangOpts().WritableStrings);
1746 gv.setAlignmentAttr(cgm.
getSize(alignment));
1748 cir::GlobalLinkageKindAttr::get(cgm.
getBuilder().getContext(), lt));
1752 if (gv.isWeakForLinker()) {
1753 assert(cgm.
supportsCOMDAT() &&
"Only COFF uses weak string literals");
1756 cgm.
setDSOLocal(
static_cast<mlir::Operation *
>(gv));
1777 std::string result =
1780 assert(!mlir::SymbolTable::lookupSymbolIn(theModule, result));
1788 astContext.getAlignOfGlobalVarInChars(
s->getType(),
nullptr);
1796 if (!gv.getAlignment() ||
1797 uint64_t(alignment.
getQuantity()) > *gv.getAlignment())
1798 gv.setAlignmentAttr(
getSize(alignment));
1803 if (
getCXXABI().getMangleContext().shouldMangleStringLiteral(
s) &&
1806 "getGlobalForStringLiteral: mangle string literals");
1814 mlir::Location loc =
s->getBeginLoc().isValid()
1816 : builder.getUnknownLoc();
1817 auto typedC = llvm::cast<mlir::TypedAttr>(
c);
1819 cir::GlobalLinkageKind::PrivateLinkage, *
this,
1820 uniqueName, alignment);
1834 auto arrayTy = mlir::dyn_cast<cir::ArrayType>(gv.getSymType());
1835 assert(arrayTy &&
"String literal must be array");
1839 return builder.getGlobalViewAttr(ptrTy, gv);
1855 errorNYI(
"SYCL or OpenMP temp address space");
1865 "emitExplicitCastExprType");
1871 auto ty = mlir::cast<cir::MethodType>(
convertType(destTy));
1872 return builder.getNullMethodAttr(ty);
1875 auto ty = mlir::cast<cir::DataMemberType>(
convertType(destTy));
1876 return builder.getNullDataMemberAttr(ty);
1887 if (
const auto *methodDecl = dyn_cast<CXXMethodDecl>(
decl)) {
1889 if (methodDecl->isVirtual())
1890 return cir::ConstantOp::create(
1891 builder, loc,
getCXXABI().buildVirtualMethodAttr(ty, methodDecl));
1897 return cir::ConstantOp::create(builder, loc,
1898 builder.getMethodAttr(ty, methodFuncOp));
1904 return cir::ConstantOp::create(
1905 builder, loc, builder.getDataMemberAttr(ty,
fieldDecl->getFieldIndex()));
1915 if (
auto *oid = dyn_cast<ObjCImplDecl>(
decl))
1916 errorNYI(oid->getSourceRange(),
"emitDeclConext: ObjCImplDecl");
1926 if (
decl->isTemplated())
1929 switch (
decl->getKind()) {
1932 decl->getDeclKindName());
1935 case Decl::CXXConversion:
1936 case Decl::CXXMethod:
1937 case Decl::Function: {
1940 if (!fd->isConsteval())
1946 case Decl::Decomposition:
1947 case Decl::VarTemplateSpecialization: {
1950 errorNYI(
decl->getSourceRange(),
"global variable decompositions");
1956 case Decl::OpenACCRoutine:
1959 case Decl::OpenACCDeclare:
1962 case Decl::OMPThreadPrivate:
1965 case Decl::OMPGroupPrivate:
1968 case Decl::OMPAllocate:
1971 case Decl::OMPCapturedExpr:
1974 case Decl::OMPDeclareReduction:
1977 case Decl::OMPDeclareMapper:
1980 case Decl::OMPRequires:
1985 case Decl::UsingDirective:
1986 case Decl::UsingEnum:
1987 case Decl::NamespaceAlias:
1989 case Decl::TypeAlias:
1995 case Decl::ClassTemplate:
1997 case Decl::CXXDeductionGuide:
1999 case Decl::FunctionTemplate:
2000 case Decl::StaticAssert:
2001 case Decl::TypeAliasTemplate:
2002 case Decl::UsingShadow:
2003 case Decl::VarTemplate:
2004 case Decl::VarTemplatePartialSpecialization:
2007 case Decl::CXXConstructor:
2010 case Decl::CXXDestructor:
2015 case Decl::LinkageSpec:
2016 case Decl::Namespace:
2020 case Decl::ClassTemplateSpecialization:
2021 case Decl::CXXRecord: {
2024 for (
auto *childDecl : crd->
decls())
2030 case Decl::FileScopeAsm:
2032 if (langOpts.CUDA && langOpts.CUDAIsDevice)
2035 if (langOpts.OpenMPIsTargetDevice)
2038 if (langOpts.SYCLIsDevice)
2041 std::string line = file_asm->getAsmString();
2042 globalScopeAsm.push_back(builder.getStringAttr(line));
2049 op.setInitialValueAttr(value);
2063 md->getParent()->getNumVBases() == 0)
2065 "getAddrAndTypeOfCXXStructor: MS ABI complete destructor");
2076 false, isForDefinition);
2078 return {fnType, fn};
2082 mlir::Type funcType,
bool forVTable,
2086 "consteval function should never be emitted");
2096 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(gd.
getDecl())) {
2099 dd->getParent()->getNumVBases() == 0)
2101 "getAddrOfFunction: MS ABI complete destructor");
2107 false, isForDefinition);
2109 if (langOpts.CUDA && !langOpts.CUDAIsDevice &&
2115 bool isHIPHandle = mlir::isa<cir::GlobalOp>(*handle);
2116 if (isForDefinition || isHIPHandle)
2118 return mlir::dyn_cast<cir::FuncOp>(*handle);
2127 llvm::raw_svector_ostream
out(buffer);
2136 assert(ii &&
"Attempt to mangle unnamed decl.");
2138 const auto *fd = dyn_cast<FunctionDecl>(nd);
2142 }
else if (fd && fd->hasAttr<CUDAGlobalAttr>() &&
2146 DeviceKernelAttr::isOpenCLSpelling(
2147 fd->getAttr<DeviceKernelAttr>()) &&
2164 if (
const auto *fd = dyn_cast<FunctionDecl>(nd)) {
2165 if (fd->isMultiVersion()) {
2167 "getMangledName: multi-version functions");
2172 "getMangledName: GPU relocatable device code");
2175 return std::string(
out.str());
2178static FunctionDecl *
2193 if (
auto *methodDecl = dyn_cast<CXXMethodDecl>(protoFunc);
2194 methodDecl && methodDecl->isImplicitObjectMemberFunction()) {
2196 paramTypes.insert(paramTypes.begin(), methodDecl->getThisType());
2199 fpt->getExtProtoInfo());
2210 params.reserve(fpt->getNumParams());
2213 for (
unsigned i = 0, e = fpt->getNumParams(); i != e; ++i) {
2217 nullptr, fpt->getParamType(i),
nullptr,
2220 params.push_back(parm);
2223 tempFunc->setParams(params);
2248 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(canonicalGd.
getDecl())) {
2251 "getMangledName: C++ constructor without variants");
2260 auto result = manglings.insert(std::make_pair(mangledName, gd));
2261 return mangledDeclNames[canonicalGd] = result.first->first();
2265 assert(!d->
getInit() &&
"Cannot emit definite definitions here!");
2273 if (gv && !mlir::cast<cir::GlobalOp>(gv).isDeclaration())
2289 if (langOpts.EmitAllDecls)
2292 const auto *vd = dyn_cast<VarDecl>(global);
2294 ((codeGenOpts.KeepPersistentStorageVariables &&
2295 (vd->getStorageDuration() ==
SD_Static ||
2296 vd->getStorageDuration() ==
SD_Thread)) ||
2297 (codeGenOpts.KeepStaticConsts && vd->getStorageDuration() ==
SD_Static &&
2298 vd->getType().isConstQualified())))
2311 if (langOpts.OpenMP >= 50 && !langOpts.OpenMPSimd) {
2312 std::optional<OMPDeclareTargetDeclAttr *> activeAttr =
2313 OMPDeclareTargetDeclAttr::getActiveAttr(global);
2314 if (!activeAttr || (*activeAttr)->getLevel() != (
unsigned)-1)
2318 const auto *fd = dyn_cast<FunctionDecl>(global);
2325 if (fd->hasAttr<TargetVersionAttr>() && !fd->isMultiVersion())
2327 if (langOpts.SYCLIsDevice) {
2328 errorNYI(fd->getSourceRange(),
"mayBeEmittedEagerly: SYCL");
2332 const auto *vd = dyn_cast<VarDecl>(global);
2334 if (astContext.getInlineVariableDefinitionKind(vd) ==
2342 if (langOpts.OpenMP && langOpts.OpenMPUseTLS &&
2343 astContext.getTargetInfo().isTLSSupported() &&
isa<VarDecl>(global) &&
2345 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(global))
2348 assert((fd || vd) &&
2349 "Only FunctionDecl and VarDecl should hit this path so far.");
2354 cir::CIRGlobalValueInterface gv) {
2355 if (gv.hasLocalLinkage())
2358 if (!gv.hasDefaultVisibility() && !gv.hasExternalWeakLinkage())
2366 const llvm::Triple &tt = cgm.
getTriple();
2368 if (tt.isOSCygMing()) {
2377 cgm.
errorNYI(
"shouldAssumeDSOLocal: MinGW");
2383 if (tt.isOSBinFormatCOFF() && gv.hasExternalWeakLinkage())
2391 if (tt.isOSBinFormatCOFF() || (tt.isOSWindows() && tt.isOSBinFormatMachO()))
2395 if (!tt.isOSBinFormatELF())
2400 if (rm != llvm::Reloc::Static && !lOpts.PIE) {
2408 return !(lOpts.SemanticInterposition || lOpts.HalfNoSemanticInterposition);
2412 if (!gv.isDeclarationForLinker())
2418 if (rm == llvm::Reloc::PIC_ && gv.hasExternalWeakLinkage())
2425 if (cgOpts.DirectAccessExternalData) {
2431 if (
auto globalOp = dyn_cast<cir::GlobalOp>(gv.getOperation())) {
2464 if (
auto globalValue = dyn_cast<cir::CIRGlobalValueInterface>(op))
2483 auto res = manglings.find(mangledName);
2484 if (res == manglings.end())
2486 result = res->getValue();
2493 return cir::TLS_Model::GeneralDynamic;
2495 return cir::TLS_Model::LocalDynamic;
2497 return cir::TLS_Model::InitialExec;
2499 return cir::TLS_Model::LocalExec;
2501 llvm_unreachable(
"Invalid TLS model!");
2505 assert(d.
getTLSKind() &&
"setting TLS mode on non-TLS var!");
2510 if (d.
getAttr<TLSModelAttr>())
2514 global.setTlsModel(tlm);
2519 cir::FuncOp func,
bool isThunk) {
2521 cir::CallingConv callingConv;
2522 cir::SideEffect sideEffect;
2529 mlir::NamedAttrList pal{};
2530 std::vector<mlir::NamedAttrList> argAttrs(info.
arguments().size());
2531 mlir::NamedAttrList retAttrs{};
2533 retAttrs, callingConv, sideEffect,
2536 for (mlir::NamedAttribute
attr : pal)
2537 func->setAttr(
attr.getName(),
attr.getValue());
2539 llvm::for_each(llvm::enumerate(argAttrs), [func](
auto idx_arg_pair) {
2540 mlir::function_interface_impl::setArgAttrs(func, idx_arg_pair.index(),
2541 idx_arg_pair.value());
2543 if (!retAttrs.empty())
2544 mlir::function_interface_impl::setResultAttrs(func, 0, retAttrs);
2557 bool isIncompleteFunction,
2563 if (!isIncompleteFunction)
2565 getTypes().arrangeGlobalDeclaration(globalDecl),
2581 if (fd->isInlineBuiltinDeclaration()) {
2583 bool hasBody = fd->
hasBody(fdBody);
2585 assert(hasBody &&
"Inline builtin declarations should always have an "
2590 if (fd->isReplaceableGlobalAllocationFunction()) {
2593 func->setAttr(cir::CIRDialect::getNoBuiltinAttrName(),
2605 if (!langOpts.Exceptions)
2608 if (langOpts.CXXExceptions)
2611 if (langOpts.ObjCExceptions)
2622 f->setAttr(cir::CIRDialect::getNoThrowAttrName(),
2625 std::optional<cir::InlineKind> existingInlineKind = f.getInlineKind();
2627 existingInlineKind && *existingInlineKind == cir::InlineKind::NoInline;
2628 bool isAlwaysInline = existingInlineKind &&
2629 *existingInlineKind == cir::InlineKind::AlwaysInline;
2633 if (!isAlwaysInline &&
2638 f.setInlineKind(cir::InlineKind::NoInline);
2653 if (
decl->hasAttr<NoInlineAttr>() && !isAlwaysInline) {
2655 f.setInlineKind(cir::InlineKind::NoInline);
2656 }
else if (
decl->hasAttr<AlwaysInlineAttr>() && !isNoInline) {
2659 f.setInlineKind(cir::InlineKind::AlwaysInline);
2663 if (!isAlwaysInline)
2664 f.setInlineKind(cir::InlineKind::NoInline);
2669 if (
auto *fd = dyn_cast<FunctionDecl>(
decl)) {
2674 auto checkRedeclForInline = [](
const FunctionDecl *redecl) {
2675 return redecl->isInlineSpecified();
2677 if (any_of(
decl->redecls(), checkRedeclForInline))
2682 return any_of(pattern->
redecls(), checkRedeclForInline);
2684 if (checkForInline(fd)) {
2685 f.setInlineKind(cir::InlineKind::InlineHint);
2686 }
else if (codeGenOpts.getInlining() ==
2688 !fd->isInlined() && !isAlwaysInline) {
2689 f.setInlineKind(cir::InlineKind::NoInline);
2698 StringRef mangledName, mlir::Type funcType,
GlobalDecl gd,
bool forVTable,
2700 mlir::NamedAttrList extraAttrs) {
2703 if (
const auto *fd = cast_or_null<FunctionDecl>(d)) {
2705 if (
getLangOpts().OpenMPIsTargetDevice && fd->isDefined() && !dontDefer &&
2708 "getOrCreateCIRFunction: OpenMP target function");
2712 if (fd->isMultiVersion())
2713 errorNYI(fd->getSourceRange(),
"getOrCreateCIRFunction: multi-version");
2719 assert(mlir::isa<cir::FuncOp>(entry));
2724 if (d && !d->
hasAttr<DLLImportAttr>() && !d->
hasAttr<DLLExportAttr>()) {
2732 if (isForDefinition && fn && !fn.isDeclaration()) {
2739 diagnosedConflictingDefinitions.insert(gd).second) {
2743 diag::note_previous_definition);
2747 if (fn && fn.getFunctionType() == funcType) {
2751 if (!isForDefinition) {
2759 auto *funcDecl = llvm::cast_or_null<FunctionDecl>(gd.
getDecl());
2760 bool invalidLoc = !funcDecl ||
2761 funcDecl->getSourceRange().getBegin().isInvalid() ||
2762 funcDecl->getSourceRange().getEnd().isInvalid();
2764 invalidLoc ? theModule->getLoc() :
getLoc(funcDecl->getSourceRange()),
2765 mangledName, mlir::cast<cir::FuncType>(funcType), funcDecl);
2776 auto symbolOp = mlir::cast<mlir::SymbolOpInterface>(entry);
2784 if (symbolOp.getSymbolUses(symbolOp->getParentOp()))
2793 if (!extraAttrs.empty()) {
2794 extraAttrs.append(funcOp->getAttrs());
2795 funcOp->setAttrs(extraAttrs);
2802 assert(funcOp.getFunctionType() == funcType);
2809 if (isa_and_nonnull<CXXDestructorDecl>(d) &&
2839 fd = fd->getPreviousDecl()) {
2841 if (fd->doesThisDeclarationHaveABody()) {
2854 cir::FuncType funcType,
2858 mlir::OpBuilder::InsertionGuard guard(builder);
2866 builder.setInsertionPoint(cgf->
curFn);
2868 func = cir::FuncOp::create(builder, loc, name, funcType);
2873 func.setNoProto(
true);
2875 assert(func.isDeclaration() &&
"expected empty body");
2879 func.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
2881 mlir::SymbolTable::setSymbolVisibility(
2882 func, mlir::SymbolTable::Visibility::Private);
2890 theModule.push_back(func);
2895 for (
const auto *
attr :
2909 fnOp.setBuiltin(
true);
2915 return cir::CtorKind::Default;
2917 return cir::CtorKind::Copy;
2919 return cir::CtorKind::Move;
2920 return cir::CtorKind::Custom;
2925 return cir::AssignKind::Copy;
2927 return cir::AssignKind::Move;
2928 llvm_unreachable(
"not a copy or move assignment operator");
2936 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(funcDecl)) {
2937 auto cxxDtor = cir::CXXDtorAttr::get(
2940 funcOp.setCxxSpecialMemberAttr(cxxDtor);
2944 if (
const auto *ctor = dyn_cast<CXXConstructorDecl>(funcDecl)) {
2946 auto cxxCtor = cir::CXXCtorAttr::get(
2948 kind, ctor->isTrivial());
2949 funcOp.setCxxSpecialMemberAttr(cxxCtor);
2953 const auto *method = dyn_cast<CXXMethodDecl>(funcDecl);
2954 if (method && (method->isCopyAssignmentOperator() ||
2955 method->isMoveAssignmentOperator())) {
2957 auto cxxAssign = cir::CXXAssignAttr::get(
2959 assignKind, method->isTrivial());
2960 funcOp.setCxxSpecialMemberAttr(cxxAssign);
2966 cir::FuncOp funcOp, StringRef name) {
2982 mlir::NamedAttrList extraAttrs,
2984 bool assumeConvergent) {
2985 if (assumeConvergent)
2986 errorNYI(
"createRuntimeFunction: assumeConvergent");
2996 entry.setDSOLocal(
true);
3002mlir::SymbolTable::Visibility
3006 if (op.isDeclaration())
3007 return mlir::SymbolTable::Visibility::Private;
3011mlir::SymbolTable::Visibility
3014 case cir::GlobalLinkageKind::InternalLinkage:
3015 case cir::GlobalLinkageKind::PrivateLinkage:
3016 return mlir::SymbolTable::Visibility::Private;
3017 case cir::GlobalLinkageKind::ExternalLinkage:
3018 case cir::GlobalLinkageKind::ExternalWeakLinkage:
3019 case cir::GlobalLinkageKind::LinkOnceODRLinkage:
3020 case cir::GlobalLinkageKind::AvailableExternallyLinkage:
3021 case cir::GlobalLinkageKind::CommonLinkage:
3022 case cir::GlobalLinkageKind::WeakAnyLinkage:
3023 case cir::GlobalLinkageKind::WeakODRLinkage:
3024 return mlir::SymbolTable::Visibility::Public;
3026 llvm::errs() <<
"visibility not implemented for '"
3027 << stringifyGlobalLinkageKind(glk) <<
"'\n";
3028 assert(0 &&
"not implemented");
3031 llvm_unreachable(
"linkage should be handled above!");
3035 clang::VisibilityAttr::VisibilityType visibility) {
3036 switch (visibility) {
3037 case clang::VisibilityAttr::VisibilityType::Default:
3038 return cir::VisibilityKind::Default;
3039 case clang::VisibilityAttr::VisibilityType::Hidden:
3040 return cir::VisibilityKind::Hidden;
3041 case clang::VisibilityAttr::VisibilityType::Protected:
3042 return cir::VisibilityKind::Protected;
3044 llvm_unreachable(
"unexpected visibility value");
3049 const clang::VisibilityAttr *va =
decl->getAttr<clang::VisibilityAttr>();
3050 cir::VisibilityAttr cirVisibility =
3053 cirVisibility = cir::VisibilityAttr::get(
3057 return cirVisibility;
3063 applyReplacements();
3065 theModule->setAttr(cir::CIRDialect::getModuleLevelAsmAttrName(),
3066 builder.getArrayAttr(globalScopeAsm));
3078 cir::FuncOp aliasee,
3079 cir::GlobalLinkageKind linkage) {
3081 auto *aliasFD = dyn_cast<FunctionDecl>(aliasGD.
getDecl());
3082 assert(aliasFD &&
"expected FunctionDecl");
3093 mangledName, fnType, aliasFD);
3094 alias.setAliasee(aliasee.getName());
3095 alias.setLinkage(linkage);
3099 mlir::SymbolTable::setSymbolVisibility(
3100 alias, mlir::SymbolTable::Visibility::Private);
3107 errorNYI(aliasFD->getSourceRange(),
"emitAliasForGlobal: previous uses");
3117 return genTypes.convertType(
type);
3124 return mlir::verify(theModule).succeeded();
3133 return builder.getConstNullPtrAttr(builder.getUInt8PtrTy());
3136 langOpts.ObjCRuntime.isGNUFamily()) {
3137 errorNYI(loc,
"getAddrOfRTTIDescriptor: Objc PtrType & Objc RT GUN");
3147 llvm::iterator_range<CastExpr::path_const_iterator> path) {
3154 assert(!base->isVirtual() &&
"Should not see virtual bases here!");
3159 const auto *baseDecl = base->getType()->castAsCXXRecordDecl();
3171 llvm::StringRef feature) {
3172 unsigned diagID = diags.getCustomDiagID(
3174 return diags.Report(loc, diagID) << feature;
3178 llvm::StringRef feature) {
3190 "cannot compile this %0 yet");
3191 diags.Report(astContext.getFullLoc(
s->getBeginLoc()), diagId)
3192 <<
type <<
s->getSourceRange();
3198 "cannot compile this %0 yet");
3199 diags.Report(astContext.getFullLoc(d->
getLocation()), diagId) <<
type;
3203 cir::LabelOp label) {
3204 [[maybe_unused]]
auto result =
3206 assert(result.second &&
3207 "attempting to map a blockaddress info that is already mapped");
3212 assert(result.second &&
3213 "attempting to map a blockaddress operation that is already mapped");
3217 cir::LabelOp label) {
3219 assert(result.second &&
3220 "attempting to map a blockaddress operation that is already mapped");
3224 cir::LabelOp newLabel) {
3227 "trying to update a blockaddress not previously mapped");
3228 assert(!it->second &&
"blockaddress already has a resolved label");
3230 it->second = newLabel;
3243 "not a global temporary");
3250 materializedType = mte->
getType();
3254 auto insertResult = materializedGlobalTemporaryMap.insert({mte,
nullptr});
3255 if (!insertResult.second)
3262 llvm::raw_svector_ostream
out(name);
3280 value = &evalResult.
Val;
3284 std::optional<ConstantEmitter> emitter;
3285 mlir::Attribute initialValue =
nullptr;
3286 bool isConstant =
false;
3290 emitter.emplace(*
this);
3291 initialValue = emitter->emitForInitializer(*value, materializedType);
3296 type = mlir::cast<mlir::TypedAttr>(initialValue).getType();
3304 cir::GlobalLinkageKind linkage =
3306 if (linkage == cir::GlobalLinkageKind::ExternalLinkage) {
3308 if (
varDecl->isStaticDataMember() &&
varDecl->getAnyInitializer(initVD) &&
3316 linkage = cir::GlobalLinkageKind::InternalLinkage;
3321 gv.setInitialValueAttr(initialValue);
3324 emitter->finalize(gv);
3326 if (!gv.hasLocalLinkage()) {
3331 gv.setAlignment(align.getAsAlign().value());
3334 "Global temporary with comdat/weak linkage");
3337 "Global temporary with thread local storage");
3338 mlir::Operation *cv = gv;
3344 mlir::Operation *&entry = materializedGlobalTemporaryMap[mte];
3346 entry->replaceAllUsesWith(cv);
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
static bool shouldAssumeDSOLocal(const CIRGenModule &cgm, cir::CIRGlobalValueInterface gv)
static cir::AssignKind getAssignKindFromDecl(const CXXMethodDecl *method)
static FunctionDecl * createOpenACCBindTempFunction(ASTContext &ctx, const IdentifierInfo *bindName, const FunctionDecl *protoFunc)
static bool shouldBeInCOMDAT(CIRGenModule &cgm, const Decl &d)
static mlir::Attribute getNewInitValue(CIRGenModule &cgm, cir::GlobalOp newGlob, mlir::Type oldTy, mlir::Attribute oldInit)
static bool hasUnwindExceptions(const LangOptions &langOpts)
Determines whether the language options require us to model unwind exceptions.
static void setWindowsItaniumDLLImport(CIRGenModule &cgm, bool isLocal, cir::FuncOp funcOp, StringRef name)
static std::string getMangledNameImpl(CIRGenModule &cgm, GlobalDecl gd, const NamedDecl *nd)
static llvm::SmallVector< int64_t > indexesOfArrayAttr(mlir::ArrayAttr indexes)
static bool isViewOnGlobal(cir::GlobalOp glob, cir::GlobalViewAttr view)
static cir::GlobalOp generateStringLiteral(mlir::Location loc, mlir::TypedAttr c, cir::GlobalLinkageKind lt, CIRGenModule &cgm, StringRef globalName, CharUnits alignment)
static bool hasImplicitAttr(const ValueDecl *decl)
static 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 cir::CtorKind getCtorKindFromDecl(const CXXConstructorDecl *ctor)
static cir::GlobalViewAttr createNewGlobalView(CIRGenModule &cgm, cir::GlobalOp newGlob, cir::GlobalViewAttr attr, mlir::Type oldTy)
This file defines OpenACC nodes for declarative directives.
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
Defines the SourceManager interface.
__device__ __2f16 float __ockl_bool s
__device__ __2f16 float c
cir::GlobalViewAttr getGlobalViewAttr(cir::GlobalOp globalOp, mlir::ArrayAttr indices={})
Get constant address of a global variable as an MLIR attribute.
cir::PointerType getPointerTo(mlir::Type ty)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
@ Strong
Strong definition.
@ WeakUnknown
Weak for now, might become strong later in this TU.
bool DeclMustBeEmitted(const Decl *D)
Determines if the decl can be CodeGen'ed or deserialized from PCH lazily, only when used; this is onl...
void Deallocate(void *Ptr) const
GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const
bool isAlignmentRequired(const Type *T) const
Determine if the alignment the type has was required using an alignment attribute.
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
GVALinkage GetGVALinkageForVariable(const VarDecl *VD) const
unsigned getTypeAlignIfKnown(QualType T, bool NeedsPreferredAlignment=false) const
Return the alignment of a type, in bits, or 0 if the type is incomplete and we cannot determine the a...
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
const TargetInfo & getTargetInfo() const
TargetCXXABI::Kind getCXXABIKind() const
Return the C++ ABI kind that should be used.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
mlir::Attribute getConstRecordOrZeroAttr(mlir::ArrayAttr arrayAttr, bool packed=false, bool padded=false, mlir::Type type={})
uint64_t computeOffsetFromGlobalViewIndices(const cir::CIRDataLayout &layout, mlir::Type ty, llvm::ArrayRef< int64_t > indices)
void computeGlobalViewIndicesFromFlatOffset(int64_t offset, mlir::Type ty, cir::CIRDataLayout layout, llvm::SmallVectorImpl< int64_t > &indices)
cir::ConstArrayAttr getConstArray(mlir::Attribute attrs, cir::ArrayType arrayTy) const
virtual mlir::Operation * getKernelHandle(cir::FuncOp fn, GlobalDecl gd)=0
Implements C++ ABI-specific code generation functions.
virtual mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty)=0
virtual void emitCXXConstructors(const clang::CXXConstructorDecl *d)=0
Emit constructor variants required by this ABI.
virtual void emitCXXDestructors(const clang::CXXDestructorDecl *d)=0
Emit dtor variants required by this ABI.
clang::MangleContext & getMangleContext()
Gets the mangle context.
virtual cir::GlobalLinkageKind getCXXDestructorLinkage(GVALinkage linkage, const CXXDestructorDecl *dtor, CXXDtorType dt) const
llvm::ArrayRef< CanQualType > arguments() const
cir::FuncOp generateCode(clang::GlobalDecl gd, cir::FuncOp fn, cir::FuncType funcType)
void emitVariablyModifiedType(QualType ty)
mlir::Operation * curFn
The current function or global initializer that is generated code for.
This class organizes the cross-function state that is used while generating CIR code.
void updateResolvedBlockAddress(cir::BlockAddressOp op, cir::LabelOp newLabel)
void replaceUsesOfNonProtoTypeWithRealFunction(mlir::Operation *old, cir::FuncOp newFn)
This function is called when we implement a function with no prototype, e.g.
static cir::GlobalOp createGlobalOp(CIRGenModule &cgm, mlir::Location loc, llvm::StringRef name, mlir::Type t, bool isConstant=false, mlir::ptr::MemorySpaceAttrInterface addrSpace={}, mlir::Operation *insertPoint=nullptr)
llvm::StringRef getMangledName(clang::GlobalDecl gd)
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *derivedClass, llvm::iterator_range< CastExpr::path_const_iterator > path)
void setGlobalVisibility(mlir::Operation *op, const NamedDecl *d) const
Set the visibility for the given global.
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
void emitDeferred()
Emit any needed decls for which code generation was deferred.
clang::ASTContext & getASTContext() const
cir::FuncOp getAddrOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
CIRGenCUDARuntime & getCUDARuntime()
llvm::DenseMap< cir::BlockAddrInfoAttr, cir::LabelOp > blockAddressInfoToLabel
Map BlockAddrInfoAttr (function name, label name) to the corresponding CIR LabelOp.
void emitTopLevelDecl(clang::Decl *decl)
void emitOMPDeclareMapper(const OMPDeclareMapperDecl *d)
void addReplacement(llvm::StringRef name, mlir::Operation *op)
mlir::Type convertType(clang::QualType type)
bool shouldEmitRTTI(bool forEH=false)
cir::GlobalOp getGlobalForStringLiteral(const StringLiteral *s, llvm::StringRef name=".str")
Return a global symbol reference to a constant array for the given string literal.
void emitOMPCapturedExpr(const OMPCapturedExprDecl *d)
void mapUnresolvedBlockAddress(cir::BlockAddressOp op)
bool mustBeEmitted(const clang::ValueDecl *d)
Determine whether the definition must be emitted; if this returns false, the definition can be emitte...
void emitGlobalOpenACCDeclareDecl(const clang::OpenACCDeclareDecl *cd)
mlir::IntegerAttr getSize(CharUnits size)
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.
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.
void emitOMPRequiresDecl(const OMPRequiresDecl *d)
void emitGlobalDefinition(clang::GlobalDecl gd, mlir::Operation *op=nullptr)
void mapResolvedBlockAddress(cir::BlockAddressOp op, cir::LabelOp)
clang::DiagnosticsEngine & getDiags() const
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)
cir::GlobalOp createOrReplaceCXXRuntimeVariable(mlir::Location loc, llvm::StringRef name, mlir::Type ty, cir::GlobalLinkageKind linkage, clang::CharUnits alignment)
Will return a global variable of the given type.
void emitOMPAllocateDecl(const OMPAllocateDecl *d)
void error(SourceLocation loc, llvm::StringRef error)
Emit a general error that something can't be done.
void emitGlobalDecl(const clang::GlobalDecl &d)
Helper for emitDeferred to apply actual codegen.
void emitGlobalVarDefinition(const clang::VarDecl *vd, bool isTentative=false)
cir::FuncOp createRuntimeFunction(cir::FuncType ty, llvm::StringRef name, mlir::NamedAttrList extraAttrs={}, bool isLocal=false, bool assumeConvergent=false)
void setTLSMode(mlir::Operation *op, const VarDecl &d)
Set TLS mode for the given operation based on the given variable declaration.
cir::FuncOp getAddrOfFunction(clang::GlobalDecl gd, mlir::Type funcType=nullptr, bool forVTable=false, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
Return the address of the given function.
void emitAliasForGlobal(llvm::StringRef mangledName, mlir::Operation *op, GlobalDecl aliasGD, cir::FuncOp aliasee, cir::GlobalLinkageKind linkage)
mlir::Value emitMemberPointerConstant(const UnaryOperator *e)
void emitGlobalOpenACCDecl(const clang::OpenACCConstructDecl *cd)
bool verifyModule() const
void emitExplicitCastExprType(const ExplicitCastExpr *e, CIRGenFunction *cgf=nullptr)
Emit type info if type of an expression is a variably modified type.
const cir::CIRDataLayout getDataLayout() const
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.
static void setInitializer(cir::GlobalOp &op, mlir::Attribute value)
cir::GlobalViewAttr getAddrOfGlobalVarAttr(const VarDecl *d)
Return the mlir::GlobalViewAttr for the address of the given global.
void addGlobalCtor(cir::FuncOp ctor, std::optional< int > priority=std::nullopt)
Add a global constructor or destructor to the module.
cir::GlobalLinkageKind getFunctionLinkage(GlobalDecl gd)
void updateCompletedType(const clang::TagDecl *td)
const clang::CodeGenOptions & getCodeGenOpts() const
void emitDeferredVTables()
Emit any vtables which we deferred and still have a use for.
const clang::LangOptions & getLangOpts() const
void constructAttributeList(llvm::StringRef name, const CIRGenFunctionInfo &info, CIRGenCalleeInfo calleeInfo, mlir::NamedAttrList &attrs, llvm::MutableArrayRef< mlir::NamedAttrList > argAttrs, mlir::NamedAttrList &retAttrs, cir::CallingConv &callingConv, cir::SideEffect &sideEffect, bool attrOnCallSite, bool isThunk)
Get the CIR attributes and calling convention to use for a particular function type.
cir::FuncOp getOrCreateCIRFunction(llvm::StringRef mangledName, mlir::Type funcType, clang::GlobalDecl gd, bool forVTable, bool dontDefer=false, bool isThunk=false, ForDefinition_t isForDefinition=NotForDefinition, mlir::NamedAttrList extraAttrs={})
void emitOpenACCRoutineDecl(const clang::FunctionDecl *funcDecl, cir::FuncOp func, SourceLocation pragmaLoc, ArrayRef< const OpenACCClause * > clauses)
void emitVTablesOpportunistically()
Try to emit external vtables as available_externally if they have emitted all inlined virtual functio...
cir::TLS_Model getDefaultCIRTLSModel() const
Get TLS mode from CodeGenOptions.
void addGlobalDtor(cir::FuncOp dtor, std::optional< int > priority=std::nullopt)
Add a function to the list that will be called when the module is unloaded.
void addDeferredDeclToEmit(clang::GlobalDecl GD)
bool shouldEmitCUDAGlobalVar(const VarDecl *global) const
cir::FuncOp createCIRFunction(mlir::Location loc, llvm::StringRef name, cir::FuncType funcType, const clang::FunctionDecl *funcDecl)
const TargetCIRGenInfo & getTargetCIRGenInfo()
void emitCXXGlobalVarDeclInitFunc(const VarDecl *vd, cir::GlobalOp addr, bool performInit)
void setGVPropertiesAux(mlir::Operation *op, const NamedDecl *d) const
LangAS getLangTempAllocaAddressSpace() const
Returns the address space for temporary allocations in the language.
llvm::DenseSet< cir::BlockAddressOp > unresolvedBlockAddressToLabel
Track CIR BlockAddressOps that cannot be resolved immediately because their LabelOp has not yet been ...
mlir::Location getLoc(clang::SourceLocation cLoc)
Helpers to convert the presumed location of Clang's SourceLocation to an MLIR Location.
llvm::DenseMap< mlir::Attribute, cir::GlobalOp > constantStringMap
mlir::Operation * lastGlobalOp
void replaceGlobal(cir::GlobalOp oldGV, cir::GlobalOp newGV)
Replace all uses of the old global with the new global, updating types and references as needed.
static cir::VisibilityKind getGlobalVisibilityKindFromClangVisibility(clang::VisibilityAttr::VisibilityType visibility)
llvm::StringMap< unsigned > cgGlobalNames
void setCXXSpecialMemberAttr(cir::FuncOp funcOp, const clang::FunctionDecl *funcDecl)
Mark the function as a special member (e.g. constructor, destructor)
mlir::TypedAttr emitNullMemberAttr(QualType t, const MemberPointerType *mpt)
Returns a null attribute to represent either a null method or null data member, depending on the type...
mlir::Operation * getGlobalValue(llvm::StringRef ref)
void emitOMPDeclareReduction(const OMPDeclareReductionDecl *d)
mlir::ModuleOp getModule() const
bool supportsCOMDAT() const
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.
cir::GlobalLinkageKind getCIRLinkageForDeclarator(const DeclaratorDecl *dd, GVALinkage linkage, bool isConstantVariable)
mlir::MLIRContext & getMLIRContext()
mlir::Operation * getAddrOfGlobal(clang::GlobalDecl gd, ForDefinition_t isForDefinition=NotForDefinition)
void maybeSetTrivialComdat(const clang::Decl &d, mlir::Operation *op)
CIRGenCXXABI & getCXXABI() const
cir::GlobalViewAttr getAddrOfConstantStringFromLiteral(const StringLiteral *s, llvm::StringRef name=".str")
Return a global symbol reference to a constant array for the given string literal.
llvm::MapVector< cir::BlockAddressOp, cir::LabelOp > blockAddressToLabel
Map CIR BlockAddressOps directly to their resolved LabelOps.
bool lookupRepresentativeDecl(llvm::StringRef mangledName, clang::GlobalDecl &gd) const
void emitDeclContext(const DeclContext *dc)
clang::CharUnits getNaturalPointeeTypeAlignment(clang::QualType t, LValueBaseInfo *baseInfo=nullptr)
void emitGlobal(clang::GlobalDecl gd)
Emit code for a single global function or variable declaration.
cir::LabelOp lookupBlockAddressInfo(cir::BlockAddrInfoAttr blockInfo)
bool mayBeEmittedEagerly(const clang::ValueDecl *d)
Determine whether the definition can be emitted eagerly, or should be delayed until the end of the tr...
cir::GlobalLinkageKind getCIRLinkageVarDefinition(const VarDecl *vd, bool isConstant)
void mapBlockAddress(cir::BlockAddrInfoAttr blockInfo, cir::LabelOp label)
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)
void emitAMDGPUMetadata()
Emits AMDGPU specific Metadata.
void emitOMPGroupPrivateDecl(const OMPGroupPrivateDecl *d)
mlir::Attribute getConstantArrayFromStringLiteral(const StringLiteral *e)
Return a constant array for the given string.
cir::VisibilityAttr getGlobalVisibilityAttrFromDecl(const Decl *decl)
void setCommonAttributes(GlobalDecl gd, mlir::Operation *op)
Set attributes which are common to any form of a global definition (alias, Objective-C method,...
const CIRGenFunctionInfo & arrangeGlobalDeclaration(GlobalDecl gd)
const CIRGenFunctionInfo & arrangeCXXMethodDeclaration(const clang::CXXMethodDecl *md)
C++ methods have some special rules and also have implicit parameters.
const CIRGenFunctionInfo & arrangeCXXStructorDeclaration(clang::GlobalDecl gd)
cir::FuncType getFunctionType(const CIRGenFunctionInfo &info)
Get the CIR function type for.
mlir::Type convertTypeForMem(clang::QualType, bool forBitField=false)
Convert type T into an mlir::Type.
void emitThunks(GlobalDecl gd)
Emit the associated thunks for the given global decl.
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.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
llvm::Reloc::Model RelocationModel
The name of the relocation model to use.
Represents the canonical version of C arrays with a specified constant size.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Decl - This represents one declaration (or definition), e.g.
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
static DeclContext * castToDeclContext(const Decl *)
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Represents a ValueDecl that came out of a declarator.
A little helper class used to produce diagnostics.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
ExplicitCastExpr - An explicit cast written in the source code.
This represents one expression.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Represents a member of a struct/union/class.
Cached information about one file (either on disk or in the virtual file system).
StringRef tryGetRealPathName() const
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Represents a function declaration or definition.
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin=false, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=ConstexprSpecKind::Unspecified, const AssociatedConstraint &TrailingRequiresClause={})
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
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.
GlobalDecl getCanonicalDecl() const
KernelReferenceKind getKernelReferenceKind() const
GlobalDecl getWithDecl(const Decl *D)
CXXDtorType getDtorType() const
const Decl * getDecl() const
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
void setLinkage(Linkage L)
Linkage getLinkage() const
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
bool shouldMangleDeclName(const NamedDecl *D)
void mangleName(GlobalDecl GD, raw_ostream &)
virtual void mangleReferenceTemporary(const VarDecl *D, unsigned ManglingNumber, raw_ostream &)=0
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
APValue * getOrCreateValue(bool MayCreate) const
Get the storage for the constant value of a materialized temporary of static storage duration.
ValueDecl * getExtendingDecl()
Get the declaration which triggered the lifetime-extension of this temporary, if any.
unsigned getManglingNumber() const
A pointer to member type per C++ 8.3.3 - Pointers to members.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
LinkageInfo getLinkageAndVisibility() const
Determines the linkage and visibility of this entity.
bool hasUnwindExceptions() const
Does this runtime use zero-cost exceptions?
Represents a parameter to a function.
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
A (possibly-)qualified type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
bool isConstQualified() const
Determine whether this type is const-qualified.
bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor, bool ExcludeDtor)
bool hasUnaligned() const
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
StringLiteral - This represents a string literal expression, e.g.
unsigned getLength() const
uint32_t getCodeUnit(size_t i) const
StringRef getString() const
unsigned getCharByteWidth() const
Represents the declaration of a struct/union/class/enum.
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() const
bool isReferenceType() const
bool isCUDADeviceBuiltinSurfaceType() const
Check if the type is the CUDA device builtin surface type.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isCUDADeviceBuiltinTextureType() const
Check if the type is the CUDA device builtin texture type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isObjCObjectPointerType() const
bool isMemberFunctionPointerType() const
const T * getAs() const
Member-template getAs<specific type>'.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
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.
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_Dynamic
TLS with a dynamic initializer.
@ TLS_None
Not a TLS variable.
@ DeclarationOnly
This declaration is only a declaration.
@ Definition
This declaration is definitely a definition.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
TemplateSpecializationKind getTemplateSpecializationKind() const
If this variable is an instantiation of a variable template or a static data member of a class templa...
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
bool isMatchingAddressSpace(mlir::ptr::MemorySpaceAttrInterface cirAS, clang::LangAS as)
mlir::ptr::MemorySpaceAttrInterface toCIRAddressSpaceAttr(mlir::MLIRContext &ctx, clang::LangAS langAS)
Convert an AST LangAS to the appropriate CIR address space attribute interface.
static bool isWeakForLinker(GlobalLinkageKind linkage)
Whether the definition of this global may be replaced at link time.
@ AttributedType
The l-value was considered opaque, so the alignment was determined from a type, but that type was an ...
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
std::unique_ptr< TargetCIRGenInfo > createAMDGPUTargetCIRGenInfo(CIRGenTypes &cgt)
std::unique_ptr< TargetCIRGenInfo > createNVPTXTargetCIRGenInfo(CIRGenTypes &cgt)
CIRGenCXXABI * CreateCIRGenItaniumCXXABI(CIRGenModule &cgm)
Creates and Itanium-family ABI.
std::unique_ptr< TargetCIRGenInfo > createX8664TargetCIRGenInfo(CIRGenTypes &cgt)
CIRGenCUDARuntime * createNVCUDARuntime(CIRGenModule &cgm)
const internal::VariadicDynCastAllOfMatcher< Decl, VarDecl > varDecl
Matches variable declarations.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, FieldDecl > fieldDecl
Matches field declarations.
const internal::VariadicDynCastAllOfMatcher< Decl, FunctionDecl > functionDecl
Matches function declarations.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
GVALinkage
A more specific kind of linkage than enum Linkage.
@ GVA_AvailableExternally
@ SD_Thread
Thread storage duration.
@ SD_Static
Static storage duration.
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Dtor_Complete
Complete object dtor.
LangAS
Defines the address space values used by the address space qualifier of QualType.
@ FirstTargetAddressSpace
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
U cast(CodeGen::Address addr)
bool isExternallyVisible(Linkage L)
static bool globalCtorLexOrder()
static bool opFuncArmNewAttr()
static bool getRuntimeFunctionDecl()
static bool weakRefReference()
static bool opFuncOptNoneAttr()
static bool opGlobalSection()
static bool addressSpace()
static bool opFuncMinSizeAttr()
static bool opGlobalUnnamedAddr()
static bool opGlobalThreadLocal()
static bool sourceLanguageCases()
static bool opFuncAstDeclAttr()
static bool opFuncNoDuplicateAttr()
static bool opGlobalUsedOrCompilerUsed()
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 opFuncSection()
static bool attributeNoBuiltin()
static bool opGlobalDLLImportExport()
static bool opGlobalPartition()
static bool opGlobalWeakRef()
static bool setTargetAttributes()
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 generateDebugInfo()
static bool targetCIRGenInfoOS()
static bool opFuncCPUAndFeaturesAttributes()
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.
LangStandard - Information about the properties of a particular language standard.