19#include "mlir/Dialect/OpenMP/OpenMPOffloadUtils.h"
22#include "clang/AST/Attrs.inc"
38#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
39#include "mlir/IR/BuiltinOps.h"
40#include "mlir/IR/Location.h"
41#include "mlir/IR/MLIRContext.h"
42#include "mlir/IR/Operation.h"
43#include "mlir/IR/Verifier.h"
52 case TargetCXXABI::GenericItanium:
53 case TargetCXXABI::GenericAArch64:
54 case TargetCXXABI::AppleARM64:
57 case TargetCXXABI::Fuchsia:
58 case TargetCXXABI::GenericARM:
59 case TargetCXXABI::iOS:
60 case TargetCXXABI::WatchOS:
61 case TargetCXXABI::GenericMIPS:
62 case TargetCXXABI::WebAssembly:
63 case TargetCXXABI::XL:
64 case TargetCXXABI::Microsoft:
65 cgm.
errorNYI(
"createCXXABI: C++ ABI kind");
69 llvm_unreachable(
"invalid C++ ABI kind");
72CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
76 : builder(mlirContext, *this), astContext(astContext),
77 langOpts(astContext.
getLangOpts()), codeGenOpts(cgo),
78 theModule{
mlir::ModuleOp::create(
mlir::UnknownLoc::get(&mlirContext))},
79 diags(diags), target(astContext.getTargetInfo()),
80 abi(
createCXXABI(*this)), genTypes(*this), vtables(*this) {
108 .toCharUnitsFromBits(
112 const unsigned charSize = astContext.getTargetInfo().getCharWidth();
116 const unsigned sizeTypeSize =
117 astContext.getTypeSize(astContext.getSignedSizeType());
118 SizeSizeInBytes = astContext.toCharUnitsFromBits(sizeTypeSize).getQuantity();
125 std::optional<cir::SourceLanguage> sourceLanguage = getCIRSourceLanguage();
128 cir::CIRDialect::getSourceLanguageAttrName(),
129 cir::SourceLanguageAttr::get(&mlirContext, *sourceLanguage));
130 theModule->setAttr(cir::CIRDialect::getTripleAttrName(),
131 builder.getStringAttr(
getTriple().str()));
133 if (cgo.OptimizationLevel > 0 || cgo.OptimizeSize > 0)
134 theModule->setAttr(cir::CIRDialect::getOptInfoAttrName(),
135 cir::OptInfoAttr::get(&mlirContext,
136 cgo.OptimizationLevel,
139 if (langOpts.OpenMP) {
140 mlir::omp::OffloadModuleOpts ompOpts(
141 langOpts.OpenMPTargetDebug, langOpts.OpenMPTeamSubscription,
142 langOpts.OpenMPThreadSubscription, langOpts.OpenMPNoThreadState,
143 langOpts.OpenMPNoNestedParallelism, langOpts.OpenMPIsTargetDevice,
144 getTriple().isGPU(), langOpts.OpenMPForceUSM, langOpts.OpenMP,
145 langOpts.OMPHostIRFile, langOpts.OMPTargetTriples, langOpts.NoGPULib);
146 mlir::omp::setOffloadModuleInterfaceAttributes(theModule, ompOpts);
155 FileID mainFileId = astContext.getSourceManager().getMainFileID();
157 *astContext.getSourceManager().getFileEntryForID(mainFileId);
160 theModule.setSymName(path);
161 theModule->setLoc(mlir::FileLineColLoc::get(&mlirContext, path,
169void CIRGenModule::createCUDARuntime() {
181 auto &layout = astContext.getASTRecordLayout(rd);
186 return layout.getAlignment();
189 return layout.getNonVirtualAlignment();
194 bool forPointeeType) {
204 if (
unsigned align = tt->getDecl()->getMaxAlignment()) {
207 return astContext.toCharUnitsFromBits(align);
215 t = astContext.getBaseElementType(t);
236 }
else if (forPointeeType && !alignForArray &&
240 alignment = astContext.getTypeAlignInChars(t);
245 if (
unsigned maxAlign = astContext.getLangOpts().MaxTypeAlign) {
247 !astContext.isAlignmentRequired(t))
261 if (theTargetCIRGenInfo)
262 return *theTargetCIRGenInfo;
265 switch (triple.getArch()) {
272 case llvm::Triple::x86_64: {
273 switch (triple.getOS()) {
280 case llvm::Triple::Linux:
282 return *theTargetCIRGenInfo;
285 case llvm::Triple::nvptx:
286 case llvm::Triple::nvptx64:
288 return *theTargetCIRGenInfo;
289 case llvm::Triple::amdgcn: {
291 return *theTargetCIRGenInfo;
297 assert(cLoc.
isValid() &&
"expected valid source location");
301 return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
306 assert(cRange.
isValid() &&
"expected a valid source range");
309 mlir::Attribute metadata;
310 return mlir::FusedLoc::get({begin, end}, metadata, builder.getContext());
319 false, isForDefinition);
353 assert(op &&
"expected a valid global op");
361 mlir::Operation *globalValueOp = op;
362 if (
auto gv = dyn_cast<cir::GetGlobalOp>(op))
364 mlir::SymbolTable::lookupSymbolIn(
getModule(), gv.getNameAttr());
366 if (
auto cirGlobalValue =
367 dyn_cast<cir::CIRGlobalValueInterface>(globalValueOp))
368 if (!cirGlobalValue.isDeclaration())
389 assert(deferredVTables.empty());
399 std::vector<GlobalDecl> curDeclsToEmit;
418 if (
auto *
attr =
decl->getAttr<AttrT>())
419 return attr->isImplicit();
420 return decl->isImplicit();
425 assert(langOpts.CUDA &&
"Should not be called by non-CUDA languages");
430 return !langOpts.CUDAIsDevice || global->
hasAttr<CUDADeviceAttr>() ||
431 global->
hasAttr<CUDAConstantAttr>() ||
432 global->
hasAttr<CUDASharedAttr>() ||
438 if (
const auto *cd = dyn_cast<clang::OpenACCConstructDecl>(gd.
getDecl())) {
456 "Expected Variable or Function");
457 if (
const auto *
varDecl = dyn_cast<VarDecl>(global)) {
461 }
else if (langOpts.CUDAIsDevice) {
462 const auto *
functionDecl = dyn_cast<FunctionDecl>(global);
463 if ((!global->hasAttr<CUDADeviceAttr>() ||
464 (langOpts.OffloadImplicitHostDeviceTemplates &&
469 !
getASTContext().CUDAImplicitHostDeviceFunUsedByDevice.count(
471 !global->hasAttr<CUDAGlobalAttr>() &&
473 !global->hasAttr<CUDAHostAttr>()))
476 }
else if (!global->hasAttr<CUDAHostAttr>() &&
477 global->hasAttr<CUDADeviceAttr>())
481 if (
const auto *fd = dyn_cast<FunctionDecl>(global)) {
484 if (fd->hasAttr<AnnotateAttr>())
485 errorNYI(fd->getSourceRange(),
"deferredAnnotations");
486 if (!fd->doesThisDeclarationHaveABody()) {
487 if (!fd->doesDeclarationForceExternallyVisibleDefinition())
491 "function declaration that forces code gen");
496 assert(vd->isFileVarDecl() &&
"Cannot emit local var decl as global.");
498 !astContext.isMSStaticDataMemberInlineDefinition(vd)) {
502 if (astContext.getInlineVariableDefinitionKind(vd) ==
541 mlir::Operation *op) {
545 cir::FuncOp funcOp = dyn_cast_if_present<cir::FuncOp>(op);
546 if (!funcOp || funcOp.getFunctionType() != funcType) {
552 if (!funcOp.isDeclaration())
564 mlir::OpBuilder::InsertionGuard guard(builder);
569 setNonAliasAttributes(gd, funcOp);
572 auto getPriority = [
this](
const auto *
attr) ->
int {
576 return attr->DefaultPriority;
579 if (
const ConstructorAttr *ca = funcDecl->getAttr<ConstructorAttr>())
581 if (
const DestructorAttr *da = funcDecl->getAttr<DestructorAttr>())
584 if (funcDecl->getAttr<AnnotateAttr>())
585 errorNYI(funcDecl->getSourceRange(),
"deferredAnnotations");
590 std::optional<int> priority) {
599 ctor.setGlobalCtorPriority(priority);
604 std::optional<int> priority) {
605 if (codeGenOpts.RegisterGlobalDtorsWithAtExit &&
607 errorNYI(dtor.getLoc(),
"registerGlobalDtorsWithAtExit");
610 dtor.setGlobalDtorPriority(priority);
628 return mlir::SymbolTable::lookupSymbolIn(theModule, name);
633 StringRef name, mlir::Type t,
bool isConstant,
634 mlir::ptr::MemorySpaceAttrInterface addrSpace,
635 mlir::Operation *insertPoint) {
640 mlir::OpBuilder::InsertionGuard guard(builder);
646 builder.setInsertionPoint(insertPoint);
652 builder.setInsertionPointToStart(cgm.
getModule().getBody());
655 g = cir::GlobalOp::create(builder, loc, name, t, isConstant, addrSpace);
661 mlir::SymbolTable::setSymbolVisibility(
662 g, mlir::SymbolTable::Visibility::Private);
669 if (isa_and_nonnull<NamedDecl>(d))
675void CIRGenModule::setNonAliasAttributes(
GlobalDecl gd, mlir::Operation *op) {
680 if (
auto gvi = mlir::dyn_cast<cir::CIRGlobalValueInterface>(op)) {
681 if (
const auto *sa = d->
getAttr<SectionAttr>())
682 gvi.setSection(builder.getStringAttr(sa->getName()));
693std::optional<cir::SourceLanguage> CIRGenModule::getCIRSourceLanguage()
const {
694 using ClangStd = clang::LangStandard;
695 using CIRLang = cir::SourceLanguage;
700 if (opts.C99 || opts.C11 || opts.C17 || opts.C23 || opts.C2y ||
701 opts.LangStd == ClangStd::lang_c89 ||
702 opts.LangStd == ClangStd::lang_gnu89)
707 errorNYI(
"CIR does not yet support the given source language");
711LangAS CIRGenModule::getGlobalVarAddressSpace(
const VarDecl *d) {
712 if (langOpts.OpenCL) {
720 if (langOpts.SYCLIsDevice &&
722 errorNYI(
"SYCL global address space");
724 if (langOpts.CUDA && langOpts.CUDAIsDevice) {
726 if (d->
hasAttr<CUDAConstantAttr>())
728 if (d->
hasAttr<CUDASharedAttr>())
730 if (d->
hasAttr<CUDADeviceAttr>())
739 errorNYI(
"OpenMP global address space");
752 gv.
setLinkage(cir::GlobalLinkageKind::ExternalWeakLinkage);
757 for (mlir::Attribute i : indexes) {
758 auto ind = mlir::cast<mlir::IntegerAttr>(i);
759 inds.push_back(ind.getValue().getSExtValue());
765 return view.getSymbol().getValue() == glob.getSymName();
769 cir::GlobalOp newGlob,
770 cir::GlobalViewAttr
attr,
781 mlir::Type newTy = newGlob.getSymType();
786 cir::PointerType newPtrTy;
789 newPtrTy = cir::PointerType::get(newTy);
798 cgm.
errorNYI(
"Unhandled type in createNewGlobalView");
804 mlir::Attribute oldInit) {
805 if (
auto oldView = mlir::dyn_cast<cir::GlobalViewAttr>(oldInit))
808 auto getNewInitElements =
809 [&](mlir::ArrayAttr oldElements) -> mlir::ArrayAttr {
811 for (mlir::Attribute elt : oldElements) {
812 if (
auto view = mlir::dyn_cast<cir::GlobalViewAttr>(elt))
814 else if (mlir::isa<cir::ConstArrayAttr, cir::ConstRecordAttr>(elt))
817 newElements.push_back(elt);
819 return mlir::ArrayAttr::get(cgm.
getBuilder().getContext(), newElements);
822 if (
auto oldArray = mlir::dyn_cast<cir::ConstArrayAttr>(oldInit)) {
823 mlir::Attribute newElements =
824 getNewInitElements(mlir::cast<mlir::ArrayAttr>(oldArray.getElts()));
826 newElements, mlir::cast<cir::ArrayType>(oldArray.getType()));
828 if (
auto oldRecord = mlir::dyn_cast<cir::ConstRecordAttr>(oldInit)) {
829 mlir::ArrayAttr newMembers = getNewInitElements(oldRecord.getMembers());
830 auto recordTy = mlir::cast<cir::RecordType>(oldRecord.getType());
832 newMembers, recordTy.getPacked(), recordTy.getPadded(), recordTy);
837 cgm.
errorNYI(
"Unhandled type in getNewInitValue");
845 assert(oldGV.getSymName() == newGV.getSymName() &&
"symbol names must match");
847 mlir::Type oldTy = oldGV.getSymType();
848 mlir::Type newTy = newGV.getSymType();
853 assert(oldTy != newTy &&
"expected type change in replaceGlobal");
856 std::optional<mlir::SymbolTable::UseRange> oldSymUses =
857 oldGV.getSymbolUses(theModule);
858 for (mlir::SymbolTable::SymbolUse use : *oldSymUses) {
859 mlir::Operation *userOp = use.getUser();
861 (mlir::isa<cir::GetGlobalOp, cir::GlobalOp, cir::ConstantOp>(userOp)) &&
862 "Unexpected user for global op");
864 if (
auto getGlobalOp = dyn_cast<cir::GetGlobalOp>(use.getUser())) {
865 mlir::Value useOpResultValue = getGlobalOp.getAddr();
866 useOpResultValue.setType(cir::PointerType::get(newTy));
868 mlir::OpBuilder::InsertionGuard guard(builder);
869 builder.setInsertionPointAfter(getGlobalOp);
870 mlir::Type ptrTy = builder.getPointerTo(oldTy);
872 builder.createBitcast(getGlobalOp->getLoc(), useOpResultValue, ptrTy);
873 useOpResultValue.replaceAllUsesExcept(
cast,
cast.getDefiningOp());
874 }
else if (
auto glob = dyn_cast<cir::GlobalOp>(userOp)) {
875 if (
auto init = glob.getInitialValue()) {
876 mlir::Attribute nw =
getNewInitValue(*
this, newGV, oldTy, init.value());
877 glob.setInitialValueAttr(nw);
879 }
else if (
auto c = dyn_cast<cir::ConstantOp>(userOp)) {
881 auto typedAttr = mlir::cast<mlir::TypedAttr>(init);
882 mlir::OpBuilder::InsertionGuard guard(builder);
883 builder.setInsertionPointAfter(
c);
884 auto newUser = cir::ConstantOp::create(builder,
c.getLoc(), typedAttr);
885 c.replaceAllUsesWith(newUser.getOperation());
917 "getOrCreateCIRGlobal: global with non-GlobalOp type");
922 mlir::ptr::MemorySpaceAttrInterface entryCIRAS = entry.getAddrSpaceAttr();
928 if (entry.getSymType() == ty &&
938 if (isForDefinition && !entry.isDeclaration()) {
940 "getOrCreateCIRGlobal: global with conflicting type");
948 if (!isForDefinition)
957 bool isConstant =
false;
962 astContext,
true, !needsDtor);
965 mlir::ptr::MemorySpaceAttrInterface declCIRAS =
971 *
this, loc, mangledName, ty, isConstant, declCIRAS,
972 entry.getOperation());
992 if (langOpts.OpenMP && !langOpts.OpenMPSimd)
994 "getOrCreateCIRGlobal: OpenMP target global variable");
996 gv.setAlignmentAttr(
getSize(astContext.getDeclAlign(d)));
1010 if (astContext.isMSStaticDataMemberInlineDefinition(d))
1012 "getOrCreateCIRGlobal: MS static data member inline definition");
1016 if (
const SectionAttr *sa = d->
getAttr<SectionAttr>())
1017 gv.setSectionAttr(builder.getStringAttr(sa->getName()));
1022 if (
getTriple().getArch() == llvm::Triple::xcore)
1024 "getOrCreateCIRGlobal: XCore specific ABI requirements");
1034 "getOrCreateCIRGlobal: external const declaration with initializer");
1046 "getOrCreateCIRGlobal: HIP managed attribute");
1081 mlir::Type ptrTy = builder.getPointerTo(g.getSymType(), g.getAddrSpaceAttr());
1082 return cir::GetGlobalOp::create(
1085 g.getStaticLocalGuard().has_value());
1093 cir::PointerType ptrTy =
1094 builder.getPointerTo(globalOp.getSymType(), globalOp.getAddrSpaceAttr());
1095 return builder.getGlobalViewAttr(ptrTy, globalOp);
1102 "emitGlobalVarDefinition: emit OpenCL/OpenMP global variable");
1109 bool isDefinitionAvailableExternally =
1114 if (isDefinitionAvailableExternally &&
1122 mlir::Attribute init;
1123 bool needsGlobalCtor =
false;
1124 bool needsGlobalDtor =
1125 !isDefinitionAvailableExternally &&
1130 std::optional<ConstantEmitter> emitter;
1135 bool isCUDASharedVar =
1140 bool isCUDAShadowVar =
1142 (vd->
hasAttr<CUDAConstantAttr>() || vd->
hasAttr<CUDADeviceAttr>() ||
1143 vd->
hasAttr<CUDASharedAttr>());
1144 bool isCUDADeviceShadowVar =
1150 (isCUDASharedVar || isCUDAShadowVar || isCUDADeviceShadowVar)) {
1152 }
else if (vd->
hasAttr<LoaderUninitializedAttr>()) {
1154 "emitGlobalVarDefinition: loader uninitialized attribute");
1155 }
else if (!initExpr) {
1168 emitter.emplace(*
this);
1169 mlir::Attribute initializer = emitter->tryEmitForInitializer(*initDecl);
1178 "emitGlobalVarDefinition: flexible array initializer");
1180 if (!isDefinitionAvailableExternally)
1181 needsGlobalCtor =
true;
1184 "emitGlobalVarDefinition: static initializer");
1195 mlir::Type initType;
1196 if (mlir::isa<mlir::SymbolRefAttr>(init)) {
1199 "emitGlobalVarDefinition: global initializer is a symbol reference");
1202 assert(mlir::isa<mlir::TypedAttr>(init) &&
"This should have a type");
1203 auto typedInitAttr = mlir::cast<mlir::TypedAttr>(init);
1204 initType = typedInitAttr.getType();
1206 assert(!mlir::isa<mlir::NoneType>(initType) &&
"Should have a type by now");
1212 if (!gv || gv.getSymType() != initType) {
1214 "emitGlobalVarDefinition: global initializer with type mismatch");
1220 if (vd->
hasAttr<AnnotateAttr>()) {
1222 "emitGlobalVarDefinition: annotate global variable");
1226 cir::GlobalLinkageKind linkage =
1236 if (langOpts.CUDA) {
1237 if (langOpts.CUDAIsDevice) {
1240 if (linkage != cir::GlobalLinkageKind::InternalLinkage &&
1242 (vd->
hasAttr<CUDADeviceAttr>() || vd->
hasAttr<CUDAConstantAttr>() ||
1245 gv->setAttr(cir::CUDAExternallyInitializedAttr::getMnemonic(),
1261 emitter->finalize(gv);
1265 gv.setConstant((vd->
hasAttr<CUDAConstantAttr>() && langOpts.CUDAIsDevice) ||
1266 (!needsGlobalCtor && !needsGlobalDtor &&
1271 if (
const SectionAttr *sa = vd->
getAttr<SectionAttr>()) {
1274 gv.setConstant(
true);
1278 gv.setLinkage(linkage);
1282 if (linkage == cir::GlobalLinkageKind::CommonLinkage) {
1284 gv.setConstant(
false);
1289 std::optional<mlir::Attribute> initializer = gv.getInitialValue();
1290 if (initializer && !
getBuilder().isNullValue(*initializer))
1291 gv.setLinkage(cir::GlobalLinkageKind::WeakAnyLinkage);
1294 setNonAliasAttributes(vd, gv);
1301 if (needsGlobalCtor || needsGlobalDtor)
1306 mlir::Operation *op) {
1308 if (
const auto *fd = dyn_cast<FunctionDecl>(
decl)) {
1312 if (
const auto *method = dyn_cast<CXXMethodDecl>(
decl)) {
1316 abi->emitCXXStructor(gd);
1317 else if (fd->isMultiVersion())
1318 errorNYI(method->getSourceRange(),
"multiversion functions");
1322 if (method->isVirtual())
1328 if (fd->isMultiVersion())
1329 errorNYI(fd->getSourceRange(),
"multiversion functions");
1334 if (
const auto *vd = dyn_cast<VarDecl>(
decl))
1337 llvm_unreachable(
"Invalid argument to CIRGenModule::emitGlobalDefinition");
1351 astContext.getAsConstantArrayType(e->
getType());
1352 uint64_t finalSize = cat->getZExtSize();
1353 str.resize(finalSize);
1355 mlir::Type eltTy =
convertType(cat->getElementType());
1356 return builder.getString(str, eltTy, finalSize,
false);
1361 auto arrayEltTy = mlir::cast<cir::IntType>(arrayTy.getElementType());
1363 uint64_t arraySize = arrayTy.getSize();
1365 assert(arraySize == literalSize + 1 &&
1366 "wide string literal array size must be literal length plus null "
1371 bool isAllZero =
true;
1372 for (
unsigned i = 0; i < literalSize; ++i) {
1380 return cir::ZeroAttr::get(arrayTy);
1384 elements.reserve(arraySize);
1385 for (
unsigned i = 0; i < literalSize; ++i)
1386 elements.push_back(cir::IntAttr::get(arrayEltTy, e->
getCodeUnit(i)));
1388 elements.push_back(cir::IntAttr::get(arrayEltTy, 0));
1390 auto elementsAttr = mlir::ArrayAttr::get(&
getMLIRContext(), elements);
1391 return builder.getConstArray(elementsAttr, arrayTy);
1402 if (d.
hasAttr<SelectAnyAttr>())
1406 if (
auto *vd = dyn_cast<VarDecl>(&d))
1421 llvm_unreachable(
"No such linkage");
1427 if (
auto globalOp = dyn_cast_or_null<cir::GlobalOp>(op)) {
1428 globalOp.setComdat(
true);
1431 funcOp.setComdat(
true);
1437 genTypes.updateCompletedType(td);
1441 replacements[name] = op;
1447 std::optional<mlir::SymbolTable::UseRange> optionalUseRange =
1448 oldF.getSymbolUses(modOp);
1449 if (!optionalUseRange)
1452 for (
const mlir::SymbolTable::SymbolUse &u : *optionalUseRange) {
1453 auto call = mlir::dyn_cast<cir::CallOp>(u.getUser());
1457 for (
auto [argOp, fnArgType] :
1458 llvm::zip(call.getArgs(), newF.getFunctionType().getInputs())) {
1459 if (argOp.getType() != fnArgType)
1468void CIRGenModule::applyReplacements() {
1469 for (
auto &i : replacements) {
1470 StringRef mangledName = i.first;
1471 mlir::Operation *replacement = i.second;
1477 auto newF = dyn_cast<cir::FuncOp>(replacement);
1480 errorNYI(replacement->getLoc(),
"replacement is not a function");
1485 "call argument types do not match replacement function");
1488 if (oldF.replaceAllSymbolUses(newF.getSymNameAttr(), theModule).failed())
1489 llvm_unreachable(
"internal error, cannot RAUW symbol");
1491 newF->moveBefore(oldF);
1498 mlir::Location loc, StringRef name, mlir::Type ty,
1500 auto gv = mlir::dyn_cast_or_null<cir::GlobalOp>(
1501 mlir::SymbolTable::lookupSymbolIn(theModule, name));
1505 if (gv.getSymType() == ty)
1511 assert(gv.isDeclaration() &&
"Declaration has wrong type!");
1513 errorNYI(loc,
"createOrReplaceCXXRuntimeVariable: declaration exists with "
1524 mlir::SymbolTable::setSymbolVisibility(gv,
1528 !gv.hasAvailableExternallyLinkage()) {
1532 gv.setAlignmentAttr(
getSize(alignment));
1543 if ((noCommon || vd->
hasAttr<NoCommonAttr>()) && !vd->
hasAttr<CommonAttr>())
1554 if (vd->
hasAttr<SectionAttr>())
1560 if (vd->
hasAttr<PragmaClangBSSSectionAttr>() ||
1561 vd->
hasAttr<PragmaClangDataSectionAttr>() ||
1562 vd->
hasAttr<PragmaClangRelroSectionAttr>() ||
1563 vd->
hasAttr<PragmaClangRodataSectionAttr>())
1571 if (vd->
hasAttr<WeakImportAttr>())
1581 if (vd->
hasAttr<AlignedAttr>())
1588 for (
const FieldDecl *fd : rd->fields()) {
1589 if (fd->isBitField())
1591 if (fd->hasAttr<AlignedAttr>())
1616 return cir::GlobalLinkageKind::InternalLinkage;
1618 if (dd->
hasAttr<WeakAttr>()) {
1619 if (isConstantVariable)
1620 return cir::GlobalLinkageKind::WeakODRLinkage;
1621 return cir::GlobalLinkageKind::WeakAnyLinkage;
1626 return cir::GlobalLinkageKind::LinkOnceAnyLinkage;
1631 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
1645 return !astContext.getLangOpts().AppleKext
1646 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
1647 : cir::GlobalLinkageKind::InternalLinkage;
1661 return cir::GlobalLinkageKind::ExternalLinkage;
1664 return dd->
hasAttr<CUDAGlobalAttr>()
1665 ? cir::GlobalLinkageKind::ExternalLinkage
1666 : cir::GlobalLinkageKind::InternalLinkage;
1667 return cir::GlobalLinkageKind::WeakODRLinkage;
1675 return cir::GlobalLinkageKind::CommonLinkage;
1681 if (dd->
hasAttr<SelectAnyAttr>())
1682 return cir::GlobalLinkageKind::WeakODRLinkage;
1686 return cir::GlobalLinkageKind::ExternalLinkage;
1698 mlir::Operation *old, cir::FuncOp newFn) {
1700 auto oldFn = mlir::dyn_cast<cir::FuncOp>(old);
1708 if (oldFn->getAttrs().size() <= 1)
1710 "replaceUsesOfNonProtoTypeWithRealFunction: Attribute forwarding");
1713 newFn.setNoProto(oldFn.getNoProto());
1716 std::optional<mlir::SymbolTable::UseRange> symUses =
1717 oldFn.getSymbolUses(oldFn->getParentOp());
1718 for (
const mlir::SymbolTable::SymbolUse &use : symUses.value()) {
1719 mlir::OpBuilder::InsertionGuard guard(builder);
1721 if (
auto noProtoCallOp = mlir::dyn_cast<cir::CallOp>(use.getUser())) {
1722 builder.setInsertionPoint(noProtoCallOp);
1725 cir::CallOp realCallOp = builder.createCallOp(
1726 noProtoCallOp.getLoc(), newFn, noProtoCallOp.getOperands());
1729 noProtoCallOp.replaceAllUsesWith(realCallOp);
1730 noProtoCallOp.erase();
1731 }
else if (
auto getGlobalOp =
1732 mlir::dyn_cast<cir::GetGlobalOp>(use.getUser())) {
1734 getGlobalOp.getAddr().setType(
1735 cir::PointerType::get(newFn.getFunctionType()));
1736 }
else if (mlir::isa<cir::GlobalOp>(use.getUser())) {
1742 "replaceUsesOfNonProtoTypeWithRealFunction: unexpected use type");
1747cir::GlobalLinkageKind
1749 assert(!isConstant &&
"constant variables NYI");
1750 GVALinkage linkage = astContext.GetGVALinkageForVariable(vd);
1757 GVALinkage linkage = astContext.GetGVALinkageForFunction(d);
1759 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(d))
1768 StringRef globalName,
CharUnits alignment) {
1774 cgm, loc, globalName,
c.getType(), !cgm.
getLangOpts().WritableStrings);
1777 gv.setAlignmentAttr(cgm.
getSize(alignment));
1779 cir::GlobalLinkageKindAttr::get(cgm.
getBuilder().getContext(), lt));
1783 if (gv.isWeakForLinker()) {
1784 assert(cgm.
supportsCOMDAT() &&
"Only COFF uses weak string literals");
1787 cgm.
setDSOLocal(
static_cast<mlir::Operation *
>(gv));
1808 std::string result =
1811 assert(!mlir::SymbolTable::lookupSymbolIn(theModule, result));
1819 astContext.getAlignOfGlobalVarInChars(
s->getType(),
nullptr);
1827 if (!gv.getAlignment() ||
1828 uint64_t(alignment.
getQuantity()) > *gv.getAlignment())
1829 gv.setAlignmentAttr(
getSize(alignment));
1834 if (
getCXXABI().getMangleContext().shouldMangleStringLiteral(
s) &&
1837 "getGlobalForStringLiteral: mangle string literals");
1845 mlir::Location loc =
s->getBeginLoc().isValid()
1847 : builder.getUnknownLoc();
1848 auto typedC = llvm::cast<mlir::TypedAttr>(
c);
1850 cir::GlobalLinkageKind::PrivateLinkage, *
this,
1851 uniqueName, alignment);
1865 auto arrayTy = mlir::dyn_cast<cir::ArrayType>(gv.getSymType());
1866 assert(arrayTy &&
"String literal must be array");
1870 return builder.getGlobalViewAttr(ptrTy, gv);
1886 errorNYI(
"SYCL or OpenMP temp address space");
1896 "emitExplicitCastExprType");
1902 auto ty = mlir::cast<cir::MethodType>(
convertType(destTy));
1903 return builder.getNullMethodAttr(ty);
1906 auto ty = mlir::cast<cir::DataMemberType>(
convertType(destTy));
1907 return builder.getNullDataMemberAttr(ty);
1918 if (
const auto *methodDecl = dyn_cast<CXXMethodDecl>(
decl)) {
1920 if (methodDecl->isVirtual())
1921 return cir::ConstantOp::create(
1922 builder, loc,
getCXXABI().buildVirtualMethodAttr(ty, methodDecl));
1928 return cir::ConstantOp::create(builder, loc,
1929 builder.getMethodAttr(ty, methodFuncOp));
1935 return cir::ConstantOp::create(
1936 builder, loc, builder.getDataMemberAttr(ty,
fieldDecl->getFieldIndex()));
1946 if (
auto *oid = dyn_cast<ObjCImplDecl>(
decl))
1947 errorNYI(oid->getSourceRange(),
"emitDeclConext: ObjCImplDecl");
1957 if (
decl->isTemplated())
1960 switch (
decl->getKind()) {
1963 decl->getDeclKindName());
1966 case Decl::CXXConversion:
1967 case Decl::CXXMethod:
1968 case Decl::Function: {
1971 if (!fd->isConsteval())
1980 case Decl::Decomposition:
1981 case Decl::VarTemplateSpecialization: {
1983 if (
auto *decomp = dyn_cast<DecompositionDecl>(
decl))
1984 for (
auto *binding : decomp->flat_bindings())
1985 if (
auto *holdingVar = binding->getHoldingVar())
1989 case Decl::OpenACCRoutine:
1992 case Decl::OpenACCDeclare:
1995 case Decl::OMPThreadPrivate:
1998 case Decl::OMPGroupPrivate:
2001 case Decl::OMPAllocate:
2004 case Decl::OMPCapturedExpr:
2007 case Decl::OMPDeclareReduction:
2010 case Decl::OMPDeclareMapper:
2013 case Decl::OMPRequires:
2018 case Decl::UsingDirective:
2019 case Decl::UsingEnum:
2020 case Decl::NamespaceAlias:
2022 case Decl::TypeAlias:
2028 case Decl::ClassTemplate:
2030 case Decl::CXXDeductionGuide:
2032 case Decl::FunctionTemplate:
2033 case Decl::StaticAssert:
2034 case Decl::TypeAliasTemplate:
2035 case Decl::UsingShadow:
2036 case Decl::VarTemplate:
2037 case Decl::VarTemplatePartialSpecialization:
2040 case Decl::CXXConstructor:
2043 case Decl::CXXDestructor:
2048 case Decl::LinkageSpec:
2049 case Decl::Namespace:
2053 case Decl::ClassTemplateSpecialization:
2054 case Decl::CXXRecord: {
2057 for (
auto *childDecl : crd->
decls())
2063 case Decl::FileScopeAsm:
2065 if (langOpts.CUDA && langOpts.CUDAIsDevice)
2068 if (langOpts.OpenMPIsTargetDevice)
2071 if (langOpts.SYCLIsDevice)
2074 std::string line = file_asm->getAsmString();
2075 globalScopeAsm.push_back(builder.getStringAttr(line));
2082 op.setInitialValueAttr(value);
2096 md->getParent()->getNumVBases() == 0)
2098 "getAddrAndTypeOfCXXStructor: MS ABI complete destructor");
2109 false, isForDefinition);
2111 return {fnType, fn};
2115 mlir::Type funcType,
bool forVTable,
2119 "consteval function should never be emitted");
2129 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(gd.
getDecl())) {
2132 dd->getParent()->getNumVBases() == 0)
2134 "getAddrOfFunction: MS ABI complete destructor");
2140 false, isForDefinition);
2142 if (langOpts.CUDA && !langOpts.CUDAIsDevice &&
2148 bool isHIPHandle = mlir::isa<cir::GlobalOp>(*handle);
2149 if (isForDefinition || isHIPHandle)
2151 return mlir::dyn_cast<cir::FuncOp>(*handle);
2160 llvm::raw_svector_ostream
out(buffer);
2169 assert(ii &&
"Attempt to mangle unnamed decl.");
2171 const auto *fd = dyn_cast<FunctionDecl>(nd);
2175 }
else if (fd && fd->hasAttr<CUDAGlobalAttr>() &&
2179 DeviceKernelAttr::isOpenCLSpelling(
2180 fd->getAttr<DeviceKernelAttr>()) &&
2197 if (
const auto *fd = dyn_cast<FunctionDecl>(nd)) {
2198 if (fd->isMultiVersion()) {
2200 "getMangledName: multi-version functions");
2205 "getMangledName: GPU relocatable device code");
2208 return std::string(
out.str());
2211static FunctionDecl *
2226 if (
auto *methodDecl = dyn_cast<CXXMethodDecl>(protoFunc);
2227 methodDecl && methodDecl->isImplicitObjectMemberFunction()) {
2229 paramTypes.insert(paramTypes.begin(), methodDecl->getThisType());
2232 fpt->getExtProtoInfo());
2243 params.reserve(fpt->getNumParams());
2246 for (
unsigned i = 0, e = fpt->getNumParams(); i != e; ++i) {
2250 nullptr, fpt->getParamType(i),
nullptr,
2253 params.push_back(parm);
2256 tempFunc->setParams(params);
2281 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(canonicalGd.
getDecl())) {
2284 "getMangledName: C++ constructor without variants");
2293 auto result = manglings.insert(std::make_pair(mangledName, gd));
2294 return mangledDeclNames[canonicalGd] = result.first->first();
2298 assert(!d->
getInit() &&
"Cannot emit definite definitions here!");
2306 if (gv && !mlir::cast<cir::GlobalOp>(gv).isDeclaration())
2322 if (langOpts.EmitAllDecls)
2325 const auto *vd = dyn_cast<VarDecl>(global);
2327 ((codeGenOpts.KeepPersistentStorageVariables &&
2328 (vd->getStorageDuration() ==
SD_Static ||
2329 vd->getStorageDuration() ==
SD_Thread)) ||
2330 (codeGenOpts.KeepStaticConsts && vd->getStorageDuration() ==
SD_Static &&
2331 vd->getType().isConstQualified())))
2344 if (langOpts.OpenMP >= 50 && !langOpts.OpenMPSimd) {
2345 std::optional<OMPDeclareTargetDeclAttr *> activeAttr =
2346 OMPDeclareTargetDeclAttr::getActiveAttr(global);
2347 if (!activeAttr || (*activeAttr)->getLevel() != (
unsigned)-1)
2351 const auto *fd = dyn_cast<FunctionDecl>(global);
2358 if (fd->hasAttr<TargetVersionAttr>() && !fd->isMultiVersion())
2360 if (langOpts.SYCLIsDevice) {
2361 errorNYI(fd->getSourceRange(),
"mayBeEmittedEagerly: SYCL");
2365 const auto *vd = dyn_cast<VarDecl>(global);
2367 if (astContext.getInlineVariableDefinitionKind(vd) ==
2375 if (langOpts.OpenMP && langOpts.OpenMPUseTLS &&
2376 astContext.getTargetInfo().isTLSSupported() &&
isa<VarDecl>(global) &&
2378 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(global))
2381 assert((fd || vd) &&
2382 "Only FunctionDecl and VarDecl should hit this path so far.");
2387 cir::CIRGlobalValueInterface gv) {
2388 if (gv.hasLocalLinkage())
2391 if (!gv.hasDefaultVisibility() && !gv.hasExternalWeakLinkage())
2399 const llvm::Triple &tt = cgm.
getTriple();
2401 if (tt.isOSCygMing()) {
2410 cgm.
errorNYI(
"shouldAssumeDSOLocal: MinGW");
2416 if (tt.isOSBinFormatCOFF() && gv.hasExternalWeakLinkage())
2424 if (tt.isOSBinFormatCOFF() || (tt.isOSWindows() && tt.isOSBinFormatMachO()))
2428 if (!tt.isOSBinFormatELF())
2433 if (rm != llvm::Reloc::Static && !lOpts.PIE) {
2441 return !(lOpts.SemanticInterposition || lOpts.HalfNoSemanticInterposition);
2445 if (!gv.isDeclarationForLinker())
2451 if (rm == llvm::Reloc::PIC_ && gv.hasExternalWeakLinkage())
2458 if (cgOpts.DirectAccessExternalData) {
2464 if (
auto globalOp = dyn_cast<cir::GlobalOp>(gv.getOperation())) {
2497 if (
auto globalValue = dyn_cast<cir::CIRGlobalValueInterface>(op))
2516 auto res = manglings.find(mangledName);
2517 if (res == manglings.end())
2519 result = res->getValue();
2526 return cir::TLS_Model::GeneralDynamic;
2528 return cir::TLS_Model::LocalDynamic;
2530 return cir::TLS_Model::InitialExec;
2532 return cir::TLS_Model::LocalExec;
2534 llvm_unreachable(
"Invalid TLS model!");
2538 assert(d.
getTLSKind() &&
"setting TLS mode on non-TLS var!");
2543 if (d.
getAttr<TLSModelAttr>())
2547 global.setTlsModel(tlm);
2552 cir::FuncOp func,
bool isThunk) {
2554 cir::CallingConv callingConv;
2555 cir::SideEffect sideEffect;
2562 mlir::NamedAttrList pal{};
2563 std::vector<mlir::NamedAttrList> argAttrs(info.
arguments().size());
2564 mlir::NamedAttrList retAttrs{};
2566 retAttrs, callingConv, sideEffect,
2569 for (mlir::NamedAttribute
attr : pal)
2570 func->setAttr(
attr.getName(),
attr.getValue());
2572 llvm::for_each(llvm::enumerate(argAttrs), [func](
auto idx_arg_pair) {
2573 mlir::function_interface_impl::setArgAttrs(func, idx_arg_pair.index(),
2574 idx_arg_pair.value());
2576 if (!retAttrs.empty())
2577 mlir::function_interface_impl::setResultAttrs(func, 0, retAttrs);
2590 bool isIncompleteFunction,
2598 if (!isIncompleteFunction)
2600 getTypes().arrangeGlobalDeclaration(globalDecl),
2603 if (!isIncompleteFunction && func.isDeclaration())
2616 if (funcDecl->isInlineBuiltinDeclaration()) {
2618 bool hasBody = funcDecl->
hasBody(fdBody);
2620 assert(hasBody &&
"Inline builtin declarations should always have an "
2625 if (funcDecl->isReplaceableGlobalAllocationFunction()) {
2628 func->setAttr(cir::CIRDialect::getNoBuiltinAttrName(),
2640 if (!langOpts.Exceptions)
2643 if (langOpts.CXXExceptions)
2646 if (langOpts.ObjCExceptions)
2657 f->setAttr(cir::CIRDialect::getNoThrowAttrName(),
2660 std::optional<cir::InlineKind> existingInlineKind = f.getInlineKind();
2662 existingInlineKind && *existingInlineKind == cir::InlineKind::NoInline;
2663 bool isAlwaysInline = existingInlineKind &&
2664 *existingInlineKind == cir::InlineKind::AlwaysInline;
2668 if (!isAlwaysInline &&
2673 f.setInlineKind(cir::InlineKind::NoInline);
2688 if (
decl->hasAttr<NoInlineAttr>() && !isAlwaysInline) {
2690 f.setInlineKind(cir::InlineKind::NoInline);
2691 }
else if (
decl->hasAttr<AlwaysInlineAttr>() && !isNoInline) {
2694 f.setInlineKind(cir::InlineKind::AlwaysInline);
2698 if (!isAlwaysInline)
2699 f.setInlineKind(cir::InlineKind::NoInline);
2704 if (
auto *fd = dyn_cast<FunctionDecl>(
decl)) {
2709 auto checkRedeclForInline = [](
const FunctionDecl *redecl) {
2710 return redecl->isInlineSpecified();
2712 if (any_of(
decl->redecls(), checkRedeclForInline))
2717 return any_of(pattern->
redecls(), checkRedeclForInline);
2719 if (checkForInline(fd)) {
2720 f.setInlineKind(cir::InlineKind::InlineHint);
2721 }
else if (codeGenOpts.getInlining() ==
2723 !fd->isInlined() && !isAlwaysInline) {
2724 f.setInlineKind(cir::InlineKind::NoInline);
2733 StringRef mangledName, mlir::Type funcType,
GlobalDecl gd,
bool forVTable,
2735 mlir::NamedAttrList extraAttrs) {
2738 if (
const auto *fd = cast_or_null<FunctionDecl>(d)) {
2740 if (
getLangOpts().OpenMPIsTargetDevice && fd->isDefined() && !dontDefer &&
2743 "getOrCreateCIRFunction: OpenMP target function");
2747 if (fd->isMultiVersion())
2748 errorNYI(fd->getSourceRange(),
"getOrCreateCIRFunction: multi-version");
2754 assert(mlir::isa<cir::FuncOp>(entry));
2759 if (d && !d->
hasAttr<DLLImportAttr>() && !d->
hasAttr<DLLExportAttr>()) {
2767 if (isForDefinition && fn && !fn.isDeclaration()) {
2774 diagnosedConflictingDefinitions.insert(gd).second) {
2778 diag::note_previous_definition);
2782 if (fn && fn.getFunctionType() == funcType) {
2786 if (!isForDefinition) {
2794 auto *funcDecl = llvm::cast_or_null<FunctionDecl>(gd.
getDecl());
2795 bool invalidLoc = !funcDecl ||
2796 funcDecl->getSourceRange().getBegin().isInvalid() ||
2797 funcDecl->getSourceRange().getEnd().isInvalid();
2799 invalidLoc ? theModule->getLoc() :
getLoc(funcDecl->getSourceRange()),
2800 mangledName, mlir::cast<cir::FuncType>(funcType), funcDecl);
2811 auto symbolOp = mlir::cast<mlir::SymbolOpInterface>(entry);
2819 if (symbolOp.getSymbolUses(symbolOp->getParentOp()))
2828 if (!extraAttrs.empty()) {
2829 extraAttrs.append(funcOp->getAttrs());
2830 funcOp->setAttrs(extraAttrs);
2837 assert(funcOp.getFunctionType() == funcType);
2844 if (isa_and_nonnull<CXXDestructorDecl>(d) &&
2874 fd = fd->getPreviousDecl()) {
2876 if (fd->doesThisDeclarationHaveABody()) {
2889 cir::FuncType funcType,
2893 mlir::OpBuilder::InsertionGuard guard(builder);
2901 builder.setInsertionPoint(cgf->
curFn);
2903 func = cir::FuncOp::create(builder, loc, name, funcType);
2908 func.setNoProto(
true);
2910 assert(func.isDeclaration() &&
"expected empty body");
2914 func.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
2916 mlir::SymbolTable::setSymbolVisibility(
2917 func, mlir::SymbolTable::Visibility::Private);
2925 theModule.push_back(func);
2930 for (
const auto *
attr :
2944 fnOp.setBuiltin(
true);
2950 return cir::CtorKind::Default;
2952 return cir::CtorKind::Copy;
2954 return cir::CtorKind::Move;
2955 return cir::CtorKind::Custom;
2960 return cir::AssignKind::Copy;
2962 return cir::AssignKind::Move;
2963 llvm_unreachable(
"not a copy or move assignment operator");
2971 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(funcDecl)) {
2972 auto cxxDtor = cir::CXXDtorAttr::get(
2975 funcOp.setCxxSpecialMemberAttr(cxxDtor);
2979 if (
const auto *ctor = dyn_cast<CXXConstructorDecl>(funcDecl)) {
2981 auto cxxCtor = cir::CXXCtorAttr::get(
2983 kind, ctor->isTrivial());
2984 funcOp.setCxxSpecialMemberAttr(cxxCtor);
2988 const auto *method = dyn_cast<CXXMethodDecl>(funcDecl);
2989 if (method && (method->isCopyAssignmentOperator() ||
2990 method->isMoveAssignmentOperator())) {
2992 auto cxxAssign = cir::CXXAssignAttr::get(
2994 assignKind, method->isTrivial());
2995 funcOp.setCxxSpecialMemberAttr(cxxAssign);
3001 cir::FuncOp funcOp, StringRef name) {
3017 mlir::NamedAttrList extraAttrs,
3019 bool assumeConvergent) {
3020 if (assumeConvergent)
3021 errorNYI(
"createRuntimeFunction: assumeConvergent");
3031 entry.setDSOLocal(
true);
3037mlir::SymbolTable::Visibility
3041 if (op.isDeclaration())
3042 return mlir::SymbolTable::Visibility::Private;
3046mlir::SymbolTable::Visibility
3049 case cir::GlobalLinkageKind::InternalLinkage:
3050 case cir::GlobalLinkageKind::PrivateLinkage:
3051 return mlir::SymbolTable::Visibility::Private;
3052 case cir::GlobalLinkageKind::ExternalLinkage:
3053 case cir::GlobalLinkageKind::ExternalWeakLinkage:
3054 case cir::GlobalLinkageKind::LinkOnceODRLinkage:
3055 case cir::GlobalLinkageKind::AvailableExternallyLinkage:
3056 case cir::GlobalLinkageKind::CommonLinkage:
3057 case cir::GlobalLinkageKind::WeakAnyLinkage:
3058 case cir::GlobalLinkageKind::WeakODRLinkage:
3059 return mlir::SymbolTable::Visibility::Public;
3061 llvm::errs() <<
"visibility not implemented for '"
3062 << stringifyGlobalLinkageKind(glk) <<
"'\n";
3063 assert(0 &&
"not implemented");
3066 llvm_unreachable(
"linkage should be handled above!");
3070 clang::VisibilityAttr::VisibilityType visibility) {
3071 switch (visibility) {
3072 case clang::VisibilityAttr::VisibilityType::Default:
3073 return cir::VisibilityKind::Default;
3074 case clang::VisibilityAttr::VisibilityType::Hidden:
3075 return cir::VisibilityKind::Hidden;
3076 case clang::VisibilityAttr::VisibilityType::Protected:
3077 return cir::VisibilityKind::Protected;
3079 llvm_unreachable(
"unexpected visibility value");
3084 const clang::VisibilityAttr *va =
decl->getAttr<clang::VisibilityAttr>();
3085 cir::VisibilityAttr cirVisibility =
3088 cirVisibility = cir::VisibilityAttr::get(
3092 return cirVisibility;
3098 applyReplacements();
3100 theModule->setAttr(cir::CIRDialect::getModuleLevelAsmAttrName(),
3101 builder.getArrayAttr(globalScopeAsm));
3103 if (!recordLayoutEntries.empty())
3105 cir::CIRDialect::getRecordLayoutsAttrName(),
3106 mlir::DictionaryAttr::get(&
getMLIRContext(), recordLayoutEntries));
3118 cir::FuncOp aliasee,
3119 cir::GlobalLinkageKind linkage) {
3121 auto *aliasFD = dyn_cast<FunctionDecl>(aliasGD.
getDecl());
3122 assert(aliasFD &&
"expected FunctionDecl");
3133 mangledName, fnType, aliasFD);
3134 alias.setAliasee(aliasee.getName());
3135 alias.setLinkage(linkage);
3139 mlir::SymbolTable::setSymbolVisibility(
3140 alias, mlir::SymbolTable::Visibility::Private);
3152 "declaration exists with different type");
3163 return genTypes.convertType(
type);
3170 return mlir::verify(theModule).succeeded();
3179 return builder.getConstNullPtrAttr(builder.getUInt8PtrTy());
3182 langOpts.ObjCRuntime.isGNUFamily()) {
3183 errorNYI(loc,
"getAddrOfRTTIDescriptor: Objc PtrType & Objc RT GUN");
3193 llvm::iterator_range<CastExpr::path_const_iterator> path) {
3200 assert(!base->isVirtual() &&
"Should not see virtual bases here!");
3205 const auto *baseDecl = base->getType()->castAsCXXRecordDecl();
3217 llvm::StringRef feature) {
3218 unsigned diagID = diags.getCustomDiagID(
3220 return diags.Report(loc, diagID) << feature;
3224 llvm::StringRef feature) {
3236 "cannot compile this %0 yet");
3237 diags.Report(astContext.getFullLoc(
s->getBeginLoc()), diagId)
3238 <<
type <<
s->getSourceRange();
3244 "cannot compile this %0 yet");
3245 diags.Report(astContext.getFullLoc(d->
getLocation()), diagId) <<
type;
3249 cir::LabelOp label) {
3250 [[maybe_unused]]
auto result =
3252 assert(result.second &&
3253 "attempting to map a blockaddress info that is already mapped");
3258 assert(result.second &&
3259 "attempting to map a blockaddress operation that is already mapped");
3263 cir::LabelOp label) {
3265 assert(result.second &&
3266 "attempting to map a blockaddress operation that is already mapped");
3270 cir::LabelOp newLabel) {
3273 "trying to update a blockaddress not previously mapped");
3274 assert(!it->second &&
"blockaddress already has a resolved label");
3276 it->second = newLabel;
3289 "not a global temporary");
3301 materializedType = mte->
getType();
3305 auto insertResult = materializedGlobalTemporaryMap.insert({mte,
nullptr});
3306 if (!insertResult.second)
3313 llvm::raw_svector_ostream
out(name);
3331 value = &evalResult.
Val;
3335 std::optional<ConstantEmitter> emitter;
3336 mlir::Attribute initialValue =
nullptr;
3337 bool isConstant =
false;
3341 emitter.emplace(*
this);
3342 initialValue = emitter->emitForInitializer(*value, materializedType);
3347 type = mlir::cast<mlir::TypedAttr>(initialValue).getType();
3355 cir::GlobalLinkageKind linkage =
3357 if (linkage == cir::GlobalLinkageKind::ExternalLinkage) {
3359 if (
varDecl->isStaticDataMember() &&
varDecl->getAnyInitializer(initVD) &&
3367 linkage = cir::GlobalLinkageKind::InternalLinkage;
3372 gv.setInitialValueAttr(initialValue);
3375 emitter->finalize(gv);
3377 if (!gv.hasLocalLinkage()) {
3382 gv.setAlignment(align.getAsAlign().value());
3385 "Global temporary with comdat/weak linkage");
3388 "Global temporary with thread local storage");
3389 mlir::Operation *cv = gv;
3395 mlir::Operation *&entry = materializedGlobalTemporaryMap[mte];
3397 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 bool verifyPointerTypeArgs(mlir::ModuleOp modOp, cir::FuncOp oldF, cir::FuncOp newF)
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.
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 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 attributeNoBuiltin()
static bool opGlobalDLLImportExport()
static bool opGlobalPartition()
static bool opGlobalPragmaClangSection()
static bool opGlobalWeakRef()
static bool deferredCXXGlobalInit()
static bool opFuncOperandBundles()
static bool opFuncCallingConv()
static bool globalCtorAssociatedData()
static bool defaultVisibility()
static bool opFuncColdHotAttr()
static bool opFuncExceptions()
static bool opFuncArmStreamingAttr()
static bool cudaSupport()
static bool opFuncMaybeHandleStaticInExternC()
static bool 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.