21#include "clang/AST/Attrs.inc"
36#include "mlir/IR/BuiltinOps.h"
37#include "mlir/IR/Location.h"
38#include "mlir/IR/MLIRContext.h"
39#include "mlir/IR/Operation.h"
40#include "mlir/IR/Verifier.h"
49 case TargetCXXABI::GenericItanium:
50 case TargetCXXABI::GenericAArch64:
51 case TargetCXXABI::AppleARM64:
54 case TargetCXXABI::Fuchsia:
55 case TargetCXXABI::GenericARM:
56 case TargetCXXABI::iOS:
57 case TargetCXXABI::WatchOS:
58 case TargetCXXABI::GenericMIPS:
59 case TargetCXXABI::WebAssembly:
60 case TargetCXXABI::XL:
61 case TargetCXXABI::Microsoft:
62 cgm.
errorNYI(
"createCXXABI: C++ ABI kind");
66 llvm_unreachable(
"invalid C++ ABI kind");
69CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
73 : builder(mlirContext, *this), astContext(astContext),
74 langOpts(astContext.
getLangOpts()), codeGenOpts(cgo),
75 theModule{
mlir::ModuleOp::create(
mlir::UnknownLoc::get(&mlirContext))},
76 diags(diags), target(astContext.getTargetInfo()),
77 abi(
createCXXABI(*this)), genTypes(*this), vtables(*this) {
105 .toCharUnitsFromBits(
109 const unsigned charSize = astContext.getTargetInfo().getCharWidth();
113 const unsigned sizeTypeSize =
114 astContext.getTypeSize(astContext.getSignedSizeType());
115 SizeSizeInBytes = astContext.toCharUnitsFromBits(sizeTypeSize).getQuantity();
122 std::optional<cir::SourceLanguage> sourceLanguage = getCIRSourceLanguage();
125 cir::CIRDialect::getSourceLanguageAttrName(),
126 cir::SourceLanguageAttr::get(&mlirContext, *sourceLanguage));
127 theModule->setAttr(cir::CIRDialect::getTripleAttrName(),
128 builder.getStringAttr(
getTriple().str()));
130 if (cgo.OptimizationLevel > 0 || cgo.OptimizeSize > 0)
131 theModule->setAttr(cir::CIRDialect::getOptInfoAttrName(),
132 cir::OptInfoAttr::get(&mlirContext,
133 cgo.OptimizationLevel,
142 FileID mainFileId = astContext.getSourceManager().getMainFileID();
144 *astContext.getSourceManager().getFileEntryForID(mainFileId);
147 theModule.setSymName(path);
148 theModule->setLoc(mlir::FileLineColLoc::get(&mlirContext, path,
156void CIRGenModule::createCUDARuntime() {
168 auto &layout = astContext.getASTRecordLayout(rd);
173 return layout.getAlignment();
176 return layout.getNonVirtualAlignment();
181 bool forPointeeType) {
191 if (
unsigned align = tt->getDecl()->getMaxAlignment()) {
194 return astContext.toCharUnitsFromBits(align);
202 t = astContext.getBaseElementType(t);
223 }
else if (forPointeeType && !alignForArray &&
227 alignment = astContext.getTypeAlignInChars(t);
232 if (
unsigned maxAlign = astContext.getLangOpts().MaxTypeAlign) {
234 !astContext.isAlignmentRequired(t))
241 if (theTargetCIRGenInfo)
242 return *theTargetCIRGenInfo;
245 switch (triple.getArch()) {
252 case llvm::Triple::x86_64: {
253 switch (triple.getOS()) {
260 case llvm::Triple::Linux:
262 return *theTargetCIRGenInfo;
265 case llvm::Triple::nvptx:
266 case llvm::Triple::nvptx64:
268 return *theTargetCIRGenInfo;
269 case llvm::Triple::amdgcn: {
271 return *theTargetCIRGenInfo;
277 assert(cLoc.
isValid() &&
"expected valid source location");
281 return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
286 assert(cRange.
isValid() &&
"expected a valid source range");
289 mlir::Attribute metadata;
290 return mlir::FusedLoc::get({begin, end}, metadata, builder.getContext());
299 false, isForDefinition);
333 assert(op &&
"expected a valid global op");
341 mlir::Operation *globalValueOp = op;
342 if (
auto gv = dyn_cast<cir::GetGlobalOp>(op))
344 mlir::SymbolTable::lookupSymbolIn(
getModule(), gv.getNameAttr());
346 if (
auto cirGlobalValue =
347 dyn_cast<cir::CIRGlobalValueInterface>(globalValueOp))
348 if (!cirGlobalValue.isDeclaration())
369 assert(deferredVTables.empty());
379 std::vector<GlobalDecl> curDeclsToEmit;
398 if (
auto *
attr =
decl->getAttr<AttrT>())
399 return attr->isImplicit();
400 return decl->isImplicit();
405 assert(langOpts.CUDA &&
"Should not be called by non-CUDA languages");
410 return !langOpts.CUDAIsDevice || global->
hasAttr<CUDADeviceAttr>() ||
411 global->
hasAttr<CUDAConstantAttr>() ||
412 global->
hasAttr<CUDASharedAttr>() ||
418 if (
const auto *cd = dyn_cast<clang::OpenACCConstructDecl>(gd.
getDecl())) {
436 "Expected Variable or Function");
437 if (
const auto *
varDecl = dyn_cast<VarDecl>(global)) {
441 }
else if (langOpts.CUDAIsDevice) {
442 const auto *
functionDecl = dyn_cast<FunctionDecl>(global);
443 if ((!global->hasAttr<CUDADeviceAttr>() ||
444 (langOpts.OffloadImplicitHostDeviceTemplates &&
449 !
getASTContext().CUDAImplicitHostDeviceFunUsedByDevice.count(
451 !global->hasAttr<CUDAGlobalAttr>() &&
453 !global->hasAttr<CUDAHostAttr>()))
456 }
else if (!global->hasAttr<CUDAHostAttr>() &&
457 global->hasAttr<CUDADeviceAttr>())
461 if (
const auto *fd = dyn_cast<FunctionDecl>(global)) {
464 if (fd->hasAttr<AnnotateAttr>())
465 errorNYI(fd->getSourceRange(),
"deferredAnnotations");
466 if (!fd->doesThisDeclarationHaveABody()) {
467 if (!fd->doesDeclarationForceExternallyVisibleDefinition())
471 "function declaration that forces code gen");
476 assert(vd->isFileVarDecl() &&
"Cannot emit local var decl as global.");
478 !astContext.isMSStaticDataMemberInlineDefinition(vd)) {
482 if (astContext.getInlineVariableDefinitionKind(vd) ==
521 mlir::Operation *op) {
525 cir::FuncOp funcOp = dyn_cast_if_present<cir::FuncOp>(op);
526 if (!funcOp || funcOp.getFunctionType() != funcType) {
532 if (!funcOp.isDeclaration())
544 mlir::OpBuilder::InsertionGuard guard(builder);
549 setNonAliasAttributes(gd, funcOp);
552 auto getPriority = [
this](
const auto *
attr) ->
int {
556 return attr->DefaultPriority;
559 if (
const ConstructorAttr *ca = funcDecl->getAttr<ConstructorAttr>())
561 if (
const DestructorAttr *da = funcDecl->getAttr<DestructorAttr>())
564 if (funcDecl->getAttr<AnnotateAttr>())
565 errorNYI(funcDecl->getSourceRange(),
"deferredAnnotations");
570 std::optional<int> priority) {
579 ctor.setGlobalCtorPriority(priority);
584 std::optional<int> priority) {
585 if (codeGenOpts.RegisterGlobalDtorsWithAtExit &&
587 errorNYI(dtor.getLoc(),
"registerGlobalDtorsWithAtExit");
590 dtor.setGlobalDtorPriority(priority);
608 return mlir::SymbolTable::lookupSymbolIn(theModule, name);
612 mlir::Location loc, StringRef name,
613 mlir::Type t,
bool isConstant,
614 mlir::Operation *insertPoint) {
619 mlir::OpBuilder::InsertionGuard guard(builder);
625 builder.setInsertionPoint(insertPoint);
631 builder.setInsertionPointToStart(cgm.
getModule().getBody());
634 g = cir::GlobalOp::create(builder, loc, name, t, isConstant);
640 mlir::SymbolTable::setSymbolVisibility(
641 g, mlir::SymbolTable::Visibility::Private);
648 if (isa_and_nonnull<NamedDecl>(d))
654void CIRGenModule::setNonAliasAttributes(
GlobalDecl gd, mlir::Operation *op) {
665std::optional<cir::SourceLanguage> CIRGenModule::getCIRSourceLanguage()
const {
667 using CIRLang = cir::SourceLanguage;
672 if (opts.C99 || opts.C11 || opts.C17 || opts.C23 || opts.C2y ||
673 opts.LangStd == ClangStd::lang_c89 ||
674 opts.LangStd == ClangStd::lang_gnu89)
679 errorNYI(
"CIR does not yet support the given source language");
691 gv.
setLinkage(cir::GlobalLinkageKind::ExternalWeakLinkage);
698 assert(oldGV.getSymName() == newGV.getSymName() &&
"symbol names must match");
700 mlir::Type oldTy = oldGV.getSymType();
701 mlir::Type newTy = newGV.getSymType();
706 assert(oldTy != newTy &&
"expected type change in replaceGlobal");
709 std::optional<mlir::SymbolTable::UseRange> oldSymUses =
710 oldGV.getSymbolUses(theModule);
711 for (mlir::SymbolTable::SymbolUse use : *oldSymUses) {
712 mlir::Operation *userOp = use.getUser();
714 (mlir::isa<cir::GetGlobalOp, cir::GlobalOp, cir::ConstantOp>(userOp)) &&
715 "Unexpected user for global op");
717 if (
auto getGlobalOp = dyn_cast<cir::GetGlobalOp>(use.getUser())) {
718 mlir::Value useOpResultValue = getGlobalOp.getAddr();
719 useOpResultValue.setType(cir::PointerType::get(newTy));
721 mlir::OpBuilder::InsertionGuard guard(builder);
722 builder.setInsertionPointAfter(getGlobalOp);
723 mlir::Type ptrTy = builder.getPointerTo(oldTy);
725 builder.createBitcast(getGlobalOp->getLoc(), useOpResultValue, ptrTy);
726 useOpResultValue.replaceAllUsesExcept(
cast,
cast.getDefiningOp());
728 errorNYI(userOp->getLoc(),
"Replace global op use in global view attr");
758 "getOrCreateCIRGlobal: global with non-GlobalOp type");
769 if (entry.getSymType() == ty)
778 if (isForDefinition && !entry.isDeclaration()) {
780 "getOrCreateCIRGlobal: global with conflicting type");
788 if (!isForDefinition)
797 bool isConstant =
false;
802 astContext,
true, !needsDtor);
809 entry.getOperation());
829 if (langOpts.OpenMP && !langOpts.OpenMPSimd)
831 "getOrCreateCIRGlobal: OpenMP target global variable");
833 gv.setAlignmentAttr(
getSize(astContext.getDeclAlign(d)));
847 if (astContext.isMSStaticDataMemberInlineDefinition(d))
849 "getOrCreateCIRGlobal: MS static data member inline definition");
855 if (
getTriple().getArch() == llvm::Triple::xcore)
857 "getOrCreateCIRGlobal: XCore specific ABI requirements");
867 "getOrCreateCIRGlobal: external const declaration with initializer");
879 "getOrCreateCIRGlobal: HIP managed attribute");
914 mlir::Type ptrTy = builder.getPointerTo(g.getSymType());
915 return cir::GetGlobalOp::create(
918 g.getStaticLocalGuard().has_value());
927 cir::PointerType ptrTy = builder.getPointerTo(globalOp.getSymType());
928 return builder.getGlobalViewAttr(ptrTy, globalOp);
935 "emitGlobalVarDefinition: emit OpenCL/OpenMP global variable");
942 bool isDefinitionAvailableExternally =
947 if (isDefinitionAvailableExternally &&
955 mlir::Attribute init;
956 bool needsGlobalCtor =
false;
957 bool needsGlobalDtor =
958 !isDefinitionAvailableExternally &&
963 std::optional<ConstantEmitter> emitter;
970 bool isCUDASharedVar =
977 }
else if (vd->
hasAttr<LoaderUninitializedAttr>()) {
979 "emitGlobalVarDefinition: loader uninitialized attribute");
980 }
else if (!initExpr) {
993 emitter.emplace(*
this);
994 mlir::Attribute initializer = emitter->tryEmitForInitializer(*initDecl);
1003 "emitGlobalVarDefinition: flexible array initializer");
1005 if (!isDefinitionAvailableExternally)
1006 needsGlobalCtor =
true;
1009 "emitGlobalVarDefinition: static initializer");
1020 mlir::Type initType;
1021 if (mlir::isa<mlir::SymbolRefAttr>(init)) {
1024 "emitGlobalVarDefinition: global initializer is a symbol reference");
1027 assert(mlir::isa<mlir::TypedAttr>(init) &&
"This should have a type");
1028 auto typedInitAttr = mlir::cast<mlir::TypedAttr>(init);
1029 initType = typedInitAttr.getType();
1031 assert(!mlir::isa<mlir::NoneType>(initType) &&
"Should have a type by now");
1037 if (!gv || gv.getSymType() != initType) {
1039 "emitGlobalVarDefinition: global initializer with type mismatch");
1045 if (vd->
hasAttr<AnnotateAttr>()) {
1047 "emitGlobalVarDefinition: annotate global variable");
1051 cir::GlobalLinkageKind linkage =
1061 if (langOpts.CUDA) {
1062 if (langOpts.CUDAIsDevice) {
1065 if (linkage != cir::GlobalLinkageKind::InternalLinkage &&
1067 (vd->
hasAttr<CUDADeviceAttr>() || vd->
hasAttr<CUDAConstantAttr>() ||
1070 gv->setAttr(cir::CUDAExternallyInitializedAttr::getMnemonic(),
1086 emitter->finalize(gv);
1090 gv.setConstant((vd->
hasAttr<CUDAConstantAttr>() && langOpts.CUDAIsDevice) ||
1091 (!needsGlobalCtor && !needsGlobalDtor &&
1098 gv.setLinkage(linkage);
1102 if (linkage == cir::GlobalLinkageKind::CommonLinkage) {
1104 gv.setConstant(
false);
1109 std::optional<mlir::Attribute> initializer = gv.getInitialValue();
1110 if (initializer && !
getBuilder().isNullValue(*initializer))
1111 gv.setLinkage(cir::GlobalLinkageKind::WeakAnyLinkage);
1114 setNonAliasAttributes(vd, gv);
1121 if (needsGlobalCtor || needsGlobalDtor)
1126 mlir::Operation *op) {
1128 if (
const auto *fd = dyn_cast<FunctionDecl>(
decl)) {
1132 if (
const auto *method = dyn_cast<CXXMethodDecl>(
decl)) {
1136 abi->emitCXXStructor(gd);
1137 else if (fd->isMultiVersion())
1138 errorNYI(method->getSourceRange(),
"multiversion functions");
1142 if (method->isVirtual())
1148 if (fd->isMultiVersion())
1149 errorNYI(fd->getSourceRange(),
"multiversion functions");
1154 if (
const auto *vd = dyn_cast<VarDecl>(
decl))
1157 llvm_unreachable(
"Invalid argument to CIRGenModule::emitGlobalDefinition");
1171 astContext.getAsConstantArrayType(e->
getType());
1172 uint64_t finalSize = cat->getZExtSize();
1173 str.resize(finalSize);
1175 mlir::Type eltTy =
convertType(cat->getElementType());
1176 return builder.getString(str, eltTy, finalSize,
false);
1181 auto arrayEltTy = mlir::cast<cir::IntType>(arrayTy.getElementType());
1183 uint64_t arraySize = arrayTy.getSize();
1185 assert(arraySize == literalSize + 1 &&
1186 "wide string literal array size must be literal length plus null "
1191 bool isAllZero =
true;
1192 for (
unsigned i = 0; i < literalSize; ++i) {
1200 return cir::ZeroAttr::get(arrayTy);
1204 elements.reserve(arraySize);
1205 for (
unsigned i = 0; i < literalSize; ++i)
1206 elements.push_back(cir::IntAttr::get(arrayEltTy, e->
getCodeUnit(i)));
1208 elements.push_back(cir::IntAttr::get(arrayEltTy, 0));
1210 auto elementsAttr = mlir::ArrayAttr::get(&
getMLIRContext(), elements);
1211 return builder.getConstArray(elementsAttr, arrayTy);
1222 if (d.
hasAttr<SelectAnyAttr>())
1226 if (
auto *vd = dyn_cast<VarDecl>(&d))
1241 llvm_unreachable(
"No such linkage");
1247 if (
auto globalOp = dyn_cast_or_null<cir::GlobalOp>(op)) {
1248 globalOp.setComdat(
true);
1251 funcOp.setComdat(
true);
1257 genTypes.updateCompletedType(td);
1261 replacements[name] = op;
1264void CIRGenModule::replacePointerTypeArgs(cir::FuncOp oldF, cir::FuncOp newF) {
1265 std::optional<mlir::SymbolTable::UseRange> optionalUseRange =
1266 oldF.getSymbolUses(theModule);
1267 if (!optionalUseRange)
1270 for (
const mlir::SymbolTable::SymbolUse &u : *optionalUseRange) {
1272 auto call = mlir::dyn_cast<cir::CallOp>(u.getUser());
1276 for (
const auto [argOp, fnArgType] :
1277 llvm::zip(call.getArgs(), newF.getFunctionType().getInputs())) {
1278 if (argOp.getType() == fnArgType)
1284 errorNYI(call.getLoc(),
"replace call with mismatched types");
1289void CIRGenModule::applyReplacements() {
1290 for (
auto &i : replacements) {
1291 StringRef mangledName = i.first;
1292 mlir::Operation *replacement = i.second;
1298 auto newF = dyn_cast<cir::FuncOp>(replacement);
1301 errorNYI(replacement->getLoc(),
"replacement is not a function");
1307 replacePointerTypeArgs(oldF, newF);
1310 if (oldF.replaceAllSymbolUses(newF.getSymNameAttr(), theModule).failed())
1311 llvm_unreachable(
"internal error, cannot RAUW symbol");
1313 newF->moveBefore(oldF);
1320 mlir::Location loc, StringRef name, mlir::Type ty,
1322 auto gv = mlir::dyn_cast_or_null<cir::GlobalOp>(
1323 mlir::SymbolTable::lookupSymbolIn(theModule, name));
1327 if (gv.getSymType() == ty)
1333 assert(gv.isDeclaration() &&
"Declaration has wrong type!");
1335 errorNYI(loc,
"createOrReplaceCXXRuntimeVariable: declaration exists with "
1346 mlir::SymbolTable::setSymbolVisibility(gv,
1350 !gv.hasAvailableExternallyLinkage()) {
1354 gv.setAlignmentAttr(
getSize(alignment));
1365 if ((noCommon || vd->
hasAttr<NoCommonAttr>()) && !vd->
hasAttr<CommonAttr>())
1376 if (vd->
hasAttr<SectionAttr>())
1382 if (vd->
hasAttr<PragmaClangBSSSectionAttr>() ||
1383 vd->
hasAttr<PragmaClangDataSectionAttr>() ||
1384 vd->
hasAttr<PragmaClangRelroSectionAttr>() ||
1385 vd->
hasAttr<PragmaClangRodataSectionAttr>())
1393 if (vd->
hasAttr<WeakImportAttr>())
1403 if (vd->
hasAttr<AlignedAttr>())
1410 for (
const FieldDecl *fd : rd->fields()) {
1411 if (fd->isBitField())
1413 if (fd->hasAttr<AlignedAttr>())
1438 return cir::GlobalLinkageKind::InternalLinkage;
1440 if (dd->
hasAttr<WeakAttr>()) {
1441 if (isConstantVariable)
1442 return cir::GlobalLinkageKind::WeakODRLinkage;
1443 return cir::GlobalLinkageKind::WeakAnyLinkage;
1448 return cir::GlobalLinkageKind::LinkOnceAnyLinkage;
1453 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
1467 return !astContext.getLangOpts().AppleKext
1468 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
1469 : cir::GlobalLinkageKind::InternalLinkage;
1483 return cir::GlobalLinkageKind::ExternalLinkage;
1486 return dd->
hasAttr<CUDAGlobalAttr>()
1487 ? cir::GlobalLinkageKind::ExternalLinkage
1488 : cir::GlobalLinkageKind::InternalLinkage;
1489 return cir::GlobalLinkageKind::WeakODRLinkage;
1497 return cir::GlobalLinkageKind::CommonLinkage;
1503 if (dd->
hasAttr<SelectAnyAttr>())
1504 return cir::GlobalLinkageKind::WeakODRLinkage;
1508 return cir::GlobalLinkageKind::ExternalLinkage;
1520 mlir::Operation *old, cir::FuncOp newFn) {
1522 auto oldFn = mlir::dyn_cast<cir::FuncOp>(old);
1530 if (oldFn->getAttrs().size() <= 1)
1532 "replaceUsesOfNonProtoTypeWithRealFunction: Attribute forwarding");
1535 newFn.setNoProto(oldFn.getNoProto());
1538 std::optional<mlir::SymbolTable::UseRange> symUses =
1539 oldFn.getSymbolUses(oldFn->getParentOp());
1540 for (
const mlir::SymbolTable::SymbolUse &use : symUses.value()) {
1541 mlir::OpBuilder::InsertionGuard guard(builder);
1543 if (
auto noProtoCallOp = mlir::dyn_cast<cir::CallOp>(use.getUser())) {
1544 builder.setInsertionPoint(noProtoCallOp);
1547 cir::CallOp realCallOp = builder.createCallOp(
1548 noProtoCallOp.getLoc(), newFn, noProtoCallOp.getOperands());
1551 noProtoCallOp.replaceAllUsesWith(realCallOp);
1552 noProtoCallOp.erase();
1553 }
else if (
auto getGlobalOp =
1554 mlir::dyn_cast<cir::GetGlobalOp>(use.getUser())) {
1556 getGlobalOp.getAddr().setType(
1557 cir::PointerType::get(newFn.getFunctionType()));
1560 "replaceUsesOfNonProtoTypeWithRealFunction: unexpected use");
1565cir::GlobalLinkageKind
1567 assert(!isConstant &&
"constant variables NYI");
1568 GVALinkage linkage = astContext.GetGVALinkageForVariable(vd);
1575 GVALinkage linkage = astContext.GetGVALinkageForFunction(d);
1577 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(d))
1586 StringRef globalName,
CharUnits alignment) {
1592 cgm, loc, globalName,
c.getType(), !cgm.
getLangOpts().WritableStrings);
1595 gv.setAlignmentAttr(cgm.
getSize(alignment));
1597 cir::GlobalLinkageKindAttr::get(cgm.
getBuilder().getContext(), lt));
1601 if (gv.isWeakForLinker()) {
1602 assert(cgm.
supportsCOMDAT() &&
"Only COFF uses weak string literals");
1605 cgm.
setDSOLocal(
static_cast<mlir::Operation *
>(gv));
1626 std::string result =
1629 assert(!mlir::SymbolTable::lookupSymbolIn(theModule, result));
1637 astContext.getAlignOfGlobalVarInChars(
s->getType(),
nullptr);
1645 if (!gv.getAlignment() ||
1646 uint64_t(alignment.
getQuantity()) > *gv.getAlignment())
1647 gv.setAlignmentAttr(
getSize(alignment));
1652 if (
getCXXABI().getMangleContext().shouldMangleStringLiteral(
s) &&
1655 "getGlobalForStringLiteral: mangle string literals");
1663 mlir::Location loc =
s->getBeginLoc().isValid()
1665 : builder.getUnknownLoc();
1666 auto typedC = llvm::cast<mlir::TypedAttr>(
c);
1668 cir::GlobalLinkageKind::PrivateLinkage, *
this,
1669 uniqueName, alignment);
1683 auto arrayTy = mlir::dyn_cast<cir::ArrayType>(gv.getSymType());
1684 assert(arrayTy &&
"String literal must be array");
1688 return builder.getGlobalViewAttr(ptrTy, gv);
1704 errorNYI(
"SYCL or OpenMP temp address space");
1714 "emitExplicitCastExprType");
1725 if (
const auto *methodDecl = dyn_cast<CXXMethodDecl>(
decl)) {
1727 if (methodDecl->isVirtual())
1728 return cir::ConstantOp::create(
1729 builder, loc,
getCXXABI().buildVirtualMethodAttr(ty, methodDecl));
1732 return cir::ConstantOp::create(builder, loc,
1733 builder.getMethodAttr(ty, methodFuncOp));
1739 return cir::ConstantOp::create(
1740 builder, loc, builder.getDataMemberAttr(ty,
fieldDecl->getFieldIndex()));
1750 if (
auto *oid = dyn_cast<ObjCImplDecl>(
decl))
1751 errorNYI(oid->getSourceRange(),
"emitDeclConext: ObjCImplDecl");
1761 if (
decl->isTemplated())
1764 switch (
decl->getKind()) {
1767 decl->getDeclKindName());
1770 case Decl::CXXConversion:
1771 case Decl::CXXMethod:
1772 case Decl::Function: {
1775 if (!fd->isConsteval())
1781 case Decl::Decomposition:
1782 case Decl::VarTemplateSpecialization: {
1785 errorNYI(
decl->getSourceRange(),
"global variable decompositions");
1791 case Decl::OpenACCRoutine:
1794 case Decl::OpenACCDeclare:
1797 case Decl::OMPThreadPrivate:
1800 case Decl::OMPGroupPrivate:
1803 case Decl::OMPAllocate:
1806 case Decl::OMPCapturedExpr:
1809 case Decl::OMPDeclareReduction:
1812 case Decl::OMPDeclareMapper:
1815 case Decl::OMPRequires:
1820 case Decl::UsingDirective:
1821 case Decl::UsingEnum:
1822 case Decl::NamespaceAlias:
1824 case Decl::TypeAlias:
1830 case Decl::ClassTemplate:
1832 case Decl::CXXDeductionGuide:
1834 case Decl::FunctionTemplate:
1835 case Decl::StaticAssert:
1836 case Decl::TypeAliasTemplate:
1837 case Decl::UsingShadow:
1838 case Decl::VarTemplate:
1839 case Decl::VarTemplatePartialSpecialization:
1842 case Decl::CXXConstructor:
1845 case Decl::CXXDestructor:
1850 case Decl::LinkageSpec:
1851 case Decl::Namespace:
1855 case Decl::ClassTemplateSpecialization:
1856 case Decl::CXXRecord: {
1859 for (
auto *childDecl : crd->
decls())
1865 case Decl::FileScopeAsm:
1867 if (langOpts.CUDA && langOpts.CUDAIsDevice)
1870 if (langOpts.OpenMPIsTargetDevice)
1873 if (langOpts.SYCLIsDevice)
1876 std::string line = file_asm->getAsmString();
1877 globalScopeAsm.push_back(builder.getStringAttr(line));
1884 op.setInitialValueAttr(value);
1898 md->getParent()->getNumVBases() == 0)
1900 "getAddrAndTypeOfCXXStructor: MS ABI complete destructor");
1911 false, isForDefinition);
1913 return {fnType, fn};
1917 mlir::Type funcType,
bool forVTable,
1921 "consteval function should never be emitted");
1931 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(gd.
getDecl())) {
1934 dd->getParent()->getNumVBases() == 0)
1936 "getAddrOfFunction: MS ABI complete destructor");
1942 false, isForDefinition);
1944 if (langOpts.CUDA && !langOpts.CUDAIsDevice &&
1950 bool isHIPHandle = mlir::isa<cir::GlobalOp>(*handle);
1951 if (isForDefinition || isHIPHandle)
1953 return mlir::dyn_cast<cir::FuncOp>(*handle);
1962 llvm::raw_svector_ostream
out(buffer);
1971 assert(ii &&
"Attempt to mangle unnamed decl.");
1973 const auto *fd = dyn_cast<FunctionDecl>(nd);
1977 }
else if (fd && fd->hasAttr<CUDAGlobalAttr>() &&
1981 DeviceKernelAttr::isOpenCLSpelling(
1982 fd->getAttr<DeviceKernelAttr>()) &&
1999 if (
const auto *fd = dyn_cast<FunctionDecl>(nd)) {
2000 if (fd->isMultiVersion()) {
2002 "getMangledName: multi-version functions");
2007 "getMangledName: GPU relocatable device code");
2010 return std::string(
out.str());
2013static FunctionDecl *
2028 if (
auto *methodDecl = dyn_cast<CXXMethodDecl>(protoFunc);
2029 methodDecl && methodDecl->isImplicitObjectMemberFunction()) {
2031 paramTypes.insert(paramTypes.begin(), methodDecl->getThisType());
2034 fpt->getExtProtoInfo());
2045 params.reserve(fpt->getNumParams());
2048 for (
unsigned i = 0, e = fpt->getNumParams(); i != e; ++i) {
2052 nullptr, fpt->getParamType(i),
nullptr,
2055 params.push_back(parm);
2058 tempFunc->setParams(params);
2083 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(canonicalGd.
getDecl())) {
2086 "getMangledName: C++ constructor without variants");
2095 auto result = manglings.insert(std::make_pair(mangledName, gd));
2096 return mangledDeclNames[canonicalGd] = result.first->first();
2100 assert(!d->
getInit() &&
"Cannot emit definite definitions here!");
2108 if (gv && !mlir::cast<cir::GlobalOp>(gv).isDeclaration())
2124 if (langOpts.EmitAllDecls)
2127 const auto *vd = dyn_cast<VarDecl>(global);
2129 ((codeGenOpts.KeepPersistentStorageVariables &&
2130 (vd->getStorageDuration() ==
SD_Static ||
2131 vd->getStorageDuration() ==
SD_Thread)) ||
2132 (codeGenOpts.KeepStaticConsts && vd->getStorageDuration() ==
SD_Static &&
2133 vd->getType().isConstQualified())))
2146 if (langOpts.OpenMP >= 50 && !langOpts.OpenMPSimd) {
2147 std::optional<OMPDeclareTargetDeclAttr *> activeAttr =
2148 OMPDeclareTargetDeclAttr::getActiveAttr(global);
2149 if (!activeAttr || (*activeAttr)->getLevel() != (
unsigned)-1)
2153 const auto *fd = dyn_cast<FunctionDecl>(global);
2160 if (fd->hasAttr<TargetVersionAttr>() && !fd->isMultiVersion())
2162 if (langOpts.SYCLIsDevice) {
2163 errorNYI(fd->getSourceRange(),
"mayBeEmittedEagerly: SYCL");
2167 const auto *vd = dyn_cast<VarDecl>(global);
2169 if (astContext.getInlineVariableDefinitionKind(vd) ==
2177 if (langOpts.OpenMP && langOpts.OpenMPUseTLS &&
2178 astContext.getTargetInfo().isTLSSupported() &&
isa<VarDecl>(global) &&
2180 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(global))
2183 assert((fd || vd) &&
2184 "Only FunctionDecl and VarDecl should hit this path so far.");
2189 cir::CIRGlobalValueInterface gv) {
2190 if (gv.hasLocalLinkage())
2193 if (!gv.hasDefaultVisibility() && !gv.hasExternalWeakLinkage())
2201 const llvm::Triple &tt = cgm.
getTriple();
2203 if (tt.isOSCygMing()) {
2212 cgm.
errorNYI(
"shouldAssumeDSOLocal: MinGW");
2218 if (tt.isOSBinFormatCOFF() && gv.hasExternalWeakLinkage())
2226 if (tt.isOSBinFormatCOFF() || (tt.isOSWindows() && tt.isOSBinFormatMachO()))
2230 if (!tt.isOSBinFormatELF())
2235 if (rm != llvm::Reloc::Static && !lOpts.PIE) {
2243 return !(lOpts.SemanticInterposition || lOpts.HalfNoSemanticInterposition);
2247 if (!gv.isDeclarationForLinker())
2253 if (rm == llvm::Reloc::PIC_ && gv.hasExternalWeakLinkage())
2260 if (cgOpts.DirectAccessExternalData) {
2266 if (
auto globalOp = dyn_cast<cir::GlobalOp>(gv.getOperation())) {
2299 if (
auto globalValue = dyn_cast<cir::CIRGlobalValueInterface>(op))
2318 auto res = manglings.find(mangledName);
2319 if (res == manglings.end())
2321 result = res->getValue();
2328 return cir::TLS_Model::GeneralDynamic;
2330 return cir::TLS_Model::LocalDynamic;
2332 return cir::TLS_Model::InitialExec;
2334 return cir::TLS_Model::LocalExec;
2336 llvm_unreachable(
"Invalid TLS model!");
2340 assert(d.
getTLSKind() &&
"setting TLS mode on non-TLS var!");
2345 if (d.
getAttr<TLSModelAttr>())
2349 global.setTlsModel(tlm);
2354 cir::FuncOp func,
bool isThunk) {
2356 cir::CallingConv callingConv;
2357 cir::SideEffect sideEffect;
2364 mlir::NamedAttrList pal{};
2365 std::vector<mlir::NamedAttrList> argAttrs(info.
arguments().size());
2366 mlir::NamedAttrList retAttrs{};
2368 retAttrs, callingConv, sideEffect,
2371 for (mlir::NamedAttribute
attr : pal)
2372 func->setAttr(
attr.getName(),
attr.getValue());
2374 llvm::for_each(llvm::enumerate(argAttrs), [func](
auto idx_arg_pair) {
2375 mlir::function_interface_impl::setArgAttrs(func, idx_arg_pair.index(),
2376 idx_arg_pair.value());
2378 if (!retAttrs.empty())
2379 mlir::function_interface_impl::setResultAttrs(func, 0, retAttrs);
2392 bool isIncompleteFunction,
2398 if (!isIncompleteFunction)
2400 getTypes().arrangeGlobalDeclaration(globalDecl),
2416 if (fd->isInlineBuiltinDeclaration()) {
2418 bool hasBody = fd->
hasBody(fdBody);
2420 assert(hasBody &&
"Inline builtin declarations should always have an "
2425 if (fd->isReplaceableGlobalAllocationFunction()) {
2428 func->setAttr(cir::CIRDialect::getNoBuiltinAttrName(),
2438 std::optional<cir::InlineKind> existingInlineKind = f.getInlineKind();
2440 existingInlineKind && *existingInlineKind == cir::InlineKind::NoInline;
2441 bool isAlwaysInline = existingInlineKind &&
2442 *existingInlineKind == cir::InlineKind::AlwaysInline;
2446 if (!isAlwaysInline &&
2451 f.setInlineKind(cir::InlineKind::NoInline);
2466 if (
decl->hasAttr<NoInlineAttr>() && !isAlwaysInline) {
2468 f.setInlineKind(cir::InlineKind::NoInline);
2469 }
else if (
decl->hasAttr<AlwaysInlineAttr>() && !isNoInline) {
2472 f.setInlineKind(cir::InlineKind::AlwaysInline);
2476 if (!isAlwaysInline)
2477 f.setInlineKind(cir::InlineKind::NoInline);
2482 if (
auto *fd = dyn_cast<FunctionDecl>(
decl)) {
2487 auto checkRedeclForInline = [](
const FunctionDecl *redecl) {
2488 return redecl->isInlineSpecified();
2490 if (any_of(
decl->redecls(), checkRedeclForInline))
2495 return any_of(pattern->
redecls(), checkRedeclForInline);
2497 if (checkForInline(fd)) {
2498 f.setInlineKind(cir::InlineKind::InlineHint);
2499 }
else if (codeGenOpts.getInlining() ==
2501 !fd->isInlined() && !isAlwaysInline) {
2502 f.setInlineKind(cir::InlineKind::NoInline);
2511 StringRef mangledName, mlir::Type funcType,
GlobalDecl gd,
bool forVTable,
2513 mlir::NamedAttrList extraAttrs) {
2516 if (
const auto *fd = cast_or_null<FunctionDecl>(d)) {
2518 if (
getLangOpts().OpenMPIsTargetDevice && fd->isDefined() && !dontDefer &&
2521 "getOrCreateCIRFunction: OpenMP target function");
2525 if (fd->isMultiVersion())
2526 errorNYI(fd->getSourceRange(),
"getOrCreateCIRFunction: multi-version");
2532 assert(mlir::isa<cir::FuncOp>(entry));
2537 if (d && !d->
hasAttr<DLLImportAttr>() && !d->
hasAttr<DLLExportAttr>()) {
2545 if (isForDefinition && fn && !fn.isDeclaration()) {
2552 diagnosedConflictingDefinitions.insert(gd).second) {
2556 diag::note_previous_definition);
2560 if (fn && fn.getFunctionType() == funcType) {
2564 if (!isForDefinition) {
2572 auto *funcDecl = llvm::cast_or_null<FunctionDecl>(gd.
getDecl());
2573 bool invalidLoc = !funcDecl ||
2574 funcDecl->getSourceRange().getBegin().isInvalid() ||
2575 funcDecl->getSourceRange().getEnd().isInvalid();
2577 invalidLoc ? theModule->getLoc() :
getLoc(funcDecl->getSourceRange()),
2578 mangledName, mlir::cast<cir::FuncType>(funcType), funcDecl);
2589 auto symbolOp = mlir::cast<mlir::SymbolOpInterface>(entry);
2597 if (symbolOp.getSymbolUses(symbolOp->getParentOp()))
2606 if (!extraAttrs.empty()) {
2607 extraAttrs.append(funcOp->getAttrs());
2608 funcOp->setAttrs(extraAttrs);
2615 assert(funcOp.getFunctionType() == funcType);
2622 if (isa_and_nonnull<CXXDestructorDecl>(d) &&
2652 fd = fd->getPreviousDecl()) {
2654 if (fd->doesThisDeclarationHaveABody()) {
2667 cir::FuncType funcType,
2671 mlir::OpBuilder::InsertionGuard guard(builder);
2679 builder.setInsertionPoint(cgf->
curFn);
2681 func = cir::FuncOp::create(builder, loc, name, funcType);
2686 func.setNoProto(
true);
2688 assert(func.isDeclaration() &&
"expected empty body");
2692 func.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
2694 mlir::SymbolTable::setSymbolVisibility(
2695 func, mlir::SymbolTable::Visibility::Private);
2703 theModule.push_back(func);
2708 for (
const auto *
attr :
2722 fnOp.setBuiltin(
true);
2728 return cir::CtorKind::Default;
2730 return cir::CtorKind::Copy;
2732 return cir::CtorKind::Move;
2733 return cir::CtorKind::Custom;
2738 return cir::AssignKind::Copy;
2740 return cir::AssignKind::Move;
2741 llvm_unreachable(
"not a copy or move assignment operator");
2749 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(funcDecl)) {
2750 auto cxxDtor = cir::CXXDtorAttr::get(
2753 funcOp.setCxxSpecialMemberAttr(cxxDtor);
2757 if (
const auto *ctor = dyn_cast<CXXConstructorDecl>(funcDecl)) {
2759 auto cxxCtor = cir::CXXCtorAttr::get(
2761 kind, ctor->isTrivial());
2762 funcOp.setCxxSpecialMemberAttr(cxxCtor);
2766 const auto *method = dyn_cast<CXXMethodDecl>(funcDecl);
2767 if (method && (method->isCopyAssignmentOperator() ||
2768 method->isMoveAssignmentOperator())) {
2770 auto cxxAssign = cir::CXXAssignAttr::get(
2772 assignKind, method->isTrivial());
2773 funcOp.setCxxSpecialMemberAttr(cxxAssign);
2779 cir::FuncOp funcOp, StringRef name) {
2795 mlir::NamedAttrList extraAttrs,
2797 bool assumeConvergent) {
2798 if (assumeConvergent)
2799 errorNYI(
"createRuntimeFunction: assumeConvergent");
2809 entry.setDSOLocal(
true);
2815mlir::SymbolTable::Visibility
2819 if (op.isDeclaration())
2820 return mlir::SymbolTable::Visibility::Private;
2824mlir::SymbolTable::Visibility
2827 case cir::GlobalLinkageKind::InternalLinkage:
2828 case cir::GlobalLinkageKind::PrivateLinkage:
2829 return mlir::SymbolTable::Visibility::Private;
2830 case cir::GlobalLinkageKind::ExternalLinkage:
2831 case cir::GlobalLinkageKind::ExternalWeakLinkage:
2832 case cir::GlobalLinkageKind::LinkOnceODRLinkage:
2833 case cir::GlobalLinkageKind::AvailableExternallyLinkage:
2834 case cir::GlobalLinkageKind::CommonLinkage:
2835 case cir::GlobalLinkageKind::WeakAnyLinkage:
2836 case cir::GlobalLinkageKind::WeakODRLinkage:
2837 return mlir::SymbolTable::Visibility::Public;
2839 llvm::errs() <<
"visibility not implemented for '"
2840 << stringifyGlobalLinkageKind(glk) <<
"'\n";
2841 assert(0 &&
"not implemented");
2844 llvm_unreachable(
"linkage should be handled above!");
2848 clang::VisibilityAttr::VisibilityType visibility) {
2849 switch (visibility) {
2850 case clang::VisibilityAttr::VisibilityType::Default:
2851 return cir::VisibilityKind::Default;
2852 case clang::VisibilityAttr::VisibilityType::Hidden:
2853 return cir::VisibilityKind::Hidden;
2854 case clang::VisibilityAttr::VisibilityType::Protected:
2855 return cir::VisibilityKind::Protected;
2857 llvm_unreachable(
"unexpected visibility value");
2862 const clang::VisibilityAttr *va =
decl->getAttr<clang::VisibilityAttr>();
2863 cir::VisibilityAttr cirVisibility =
2866 cirVisibility = cir::VisibilityAttr::get(
2870 return cirVisibility;
2876 applyReplacements();
2878 theModule->setAttr(cir::CIRDialect::getModuleLevelAsmAttrName(),
2879 builder.getArrayAttr(globalScopeAsm));
2887 cir::FuncOp aliasee,
2888 cir::GlobalLinkageKind linkage) {
2890 auto *aliasFD = dyn_cast<FunctionDecl>(aliasGD.
getDecl());
2891 assert(aliasFD &&
"expected FunctionDecl");
2902 mangledName, fnType, aliasFD);
2903 alias.setAliasee(aliasee.getName());
2904 alias.setLinkage(linkage);
2908 mlir::SymbolTable::setSymbolVisibility(
2909 alias, mlir::SymbolTable::Visibility::Private);
2916 errorNYI(aliasFD->getSourceRange(),
"emitAliasForGlobal: previous uses");
2926 return genTypes.convertType(
type);
2933 return mlir::verify(theModule).succeeded();
2942 return builder.getConstNullPtrAttr(builder.getUInt8PtrTy());
2945 langOpts.ObjCRuntime.isGNUFamily()) {
2946 errorNYI(loc,
"getAddrOfRTTIDescriptor: Objc PtrType & Objc RT GUN");
2956 llvm::iterator_range<CastExpr::path_const_iterator> path) {
2963 assert(!base->isVirtual() &&
"Should not see virtual bases here!");
2968 const auto *baseDecl = base->getType()->castAsCXXRecordDecl();
2980 llvm::StringRef feature) {
2981 unsigned diagID = diags.getCustomDiagID(
2983 return diags.Report(loc, diagID) << feature;
2987 llvm::StringRef feature) {
2999 "cannot compile this %0 yet");
3000 diags.Report(astContext.getFullLoc(
s->getBeginLoc()), diagId)
3001 <<
type <<
s->getSourceRange();
3007 "cannot compile this %0 yet");
3008 diags.Report(astContext.getFullLoc(d->
getLocation()), diagId) <<
type;
3012 cir::LabelOp label) {
3013 [[maybe_unused]]
auto result =
3015 assert(result.second &&
3016 "attempting to map a blockaddress info that is already mapped");
3021 assert(result.second &&
3022 "attempting to map a blockaddress operation that is already mapped");
3026 cir::LabelOp label) {
3028 assert(result.second &&
3029 "attempting to map a blockaddress operation that is already mapped");
3033 cir::LabelOp newLabel) {
3036 "trying to update a blockaddress not previously mapped");
3037 assert(!it->second &&
"blockaddress already has a resolved label");
3039 it->second = newLabel;
3052 "not a global temporary");
3059 materializedType = mte->
getType();
3063 auto insertResult = materializedGlobalTemporaryMap.insert({mte,
nullptr});
3064 if (!insertResult.second)
3071 llvm::raw_svector_ostream
out(name);
3089 value = &evalResult.
Val;
3093 std::optional<ConstantEmitter> emitter;
3094 mlir::Attribute initialValue =
nullptr;
3095 bool isConstant =
false;
3099 emitter.emplace(*
this);
3100 initialValue = emitter->emitForInitializer(*value, materializedType);
3105 type = mlir::cast<mlir::TypedAttr>(initialValue).getType();
3113 cir::GlobalLinkageKind linkage =
3115 if (linkage == cir::GlobalLinkageKind::ExternalLinkage) {
3117 if (
varDecl->isStaticDataMember() &&
varDecl->getAnyInitializer(initVD) &&
3125 linkage = cir::GlobalLinkageKind::InternalLinkage;
3130 gv.setInitialValueAttr(initialValue);
3133 emitter->finalize(gv);
3135 if (!gv.hasLocalLinkage()) {
3140 gv.setAlignment(align.getAsAlign().value());
3143 "Global temporary with comdat/weak linkage");
3146 "Global temporary with thread local storage");
3147 mlir::Operation *cv = gv;
3153 mlir::Operation *&entry = materializedGlobalTemporaryMap[mte];
3155 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 void setWindowsItaniumDLLImport(CIRGenModule &cgm, bool isLocal, cir::FuncOp funcOp, StringRef name)
static std::string getMangledNameImpl(CIRGenModule &cgm, GlobalDecl gd, 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 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)
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::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.
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.
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.
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::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)
static cir::GlobalOp createGlobalOp(CIRGenModule &cgm, mlir::Location loc, llvm::StringRef name, mlir::Type t, bool isConstant=false, mlir::Operation *insertPoint=nullptr)
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)
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 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 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...
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
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.
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.
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
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.
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.
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.