29#include "mlir/IR/BuiltinOps.h"
30#include "mlir/IR/Location.h"
31#include "mlir/IR/MLIRContext.h"
32#include "mlir/IR/Verifier.h"
39 case TargetCXXABI::GenericItanium:
40 case TargetCXXABI::GenericAArch64:
41 case TargetCXXABI::AppleARM64:
44 case TargetCXXABI::Fuchsia:
45 case TargetCXXABI::GenericARM:
46 case TargetCXXABI::iOS:
47 case TargetCXXABI::WatchOS:
48 case TargetCXXABI::GenericMIPS:
49 case TargetCXXABI::WebAssembly:
50 case TargetCXXABI::XL:
51 case TargetCXXABI::Microsoft:
52 cgm.
errorNYI(
"C++ ABI kind not yet implemented");
56 llvm_unreachable(
"invalid C++ ABI kind");
59CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
63 : builder(mlirContext, *this), astContext(astContext),
64 langOpts(astContext.getLangOpts()), codeGenOpts(cgo),
65 theModule{
mlir::ModuleOp::create(
mlir::UnknownLoc::get(&mlirContext))},
66 diags(diags), target(astContext.getTargetInfo()),
67 abi(
createCXXABI(*this)), genTypes(*this), vtables(*this) {
97 const unsigned sizeTypeSize =
106 std::optional<cir::SourceLanguage> sourceLanguage = getCIRSourceLanguage();
109 cir::CIRDialect::getSourceLanguageAttrName(),
110 cir::SourceLanguageAttr::get(&mlirContext, *sourceLanguage));
111 theModule->setAttr(cir::CIRDialect::getTripleAttrName(),
112 builder.getStringAttr(
getTriple().str()));
114 if (cgo.OptimizationLevel > 0 || cgo.OptimizeSize > 0)
115 theModule->setAttr(cir::CIRDialect::getOptInfoAttrName(),
116 cir::OptInfoAttr::get(&mlirContext,
117 cgo.OptimizationLevel,
139 return layout.getNonVirtualAlignment();
153 if (
unsigned align = tt->getDecl()->getMaxAlignment()) {
189 if (
unsigned maxAlign = astContext.
getLangOpts().MaxTypeAlign) {
198 if (theTargetCIRGenInfo)
199 return *theTargetCIRGenInfo;
202 switch (triple.getArch()) {
209 case llvm::Triple::x86_64: {
210 switch (triple.getOS()) {
217 case llvm::Triple::Linux:
219 return *theTargetCIRGenInfo;
226 assert(cLoc.
isValid() &&
"expected valid source location");
230 return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
235 assert(cRange.
isValid() &&
"expected a valid source range");
238 mlir::Attribute metadata;
239 return mlir::FusedLoc::get({begin, end}, metadata, builder.getContext());
246 if (isa<CXXConstructorDecl>(d) || isa<CXXDestructorDecl>(d))
248 false, isForDefinition);
250 if (isa<CXXMethodDecl>(d)) {
258 if (isa<FunctionDecl>(d)) {
282 assert(op &&
"expected a valid global op");
290 mlir::Operation *globalValueOp = op;
291 if (
auto gv = dyn_cast<cir::GetGlobalOp>(op))
293 mlir::SymbolTable::lookupSymbolIn(
getModule(), gv.getNameAttr());
295 if (
auto cirGlobalValue =
296 dyn_cast<cir::CIRGlobalValueInterface>(globalValueOp))
297 if (!cirGlobalValue.isDeclaration())
322 std::vector<GlobalDecl> curDeclsToEmit;
339 if (
const auto *cd = dyn_cast<clang::OpenACCConstructDecl>(gd.
getDecl())) {
344 const auto *global = cast<ValueDecl>(gd.
getDecl());
346 if (
const auto *fd = dyn_cast<FunctionDecl>(global)) {
349 if (fd->hasAttr<AnnotateAttr>())
350 errorNYI(fd->getSourceRange(),
"deferredAnnotations");
351 if (!fd->doesThisDeclarationHaveABody()) {
352 if (!fd->doesDeclarationForceExternallyVisibleDefinition())
356 "function declaration that forces code gen");
360 const auto *vd = cast<VarDecl>(global);
361 assert(vd->isFileVarDecl() &&
"Cannot emit local var decl as global.");
406 mlir::Operation *op) {
407 auto const *funcDecl = cast<FunctionDecl>(gd.
getDecl());
410 cir::FuncOp funcOp = dyn_cast_if_present<cir::FuncOp>(op);
411 if (!funcOp || funcOp.getFunctionType() != funcType) {
417 if (!funcOp.isDeclaration())
429 mlir::OpBuilder::InsertionGuard guard(builder);
434 setNonAliasAttributes(gd, funcOp);
437 if (funcDecl->getAttr<ConstructorAttr>())
438 errorNYI(funcDecl->getSourceRange(),
"constructor attribute");
439 if (funcDecl->getAttr<DestructorAttr>())
440 errorNYI(funcDecl->getSourceRange(),
"destructor attribute");
442 if (funcDecl->getAttr<AnnotateAttr>())
443 errorNYI(funcDecl->getSourceRange(),
"deferredAnnotations");
461 return mlir::SymbolTable::lookupSymbolIn(theModule, name);
465 mlir::Location loc, StringRef name,
466 mlir::Type t,
bool isConstant,
467 mlir::Operation *insertPoint) {
472 mlir::OpBuilder::InsertionGuard guard(builder);
478 builder.setInsertionPoint(insertPoint);
484 builder.setInsertionPointToStart(cgm.
getModule().getBody());
487 g = builder.create<cir::GlobalOp>(loc, name, t, isConstant);
493 mlir::SymbolTable::setSymbolVisibility(
494 g, mlir::SymbolTable::Visibility::Private);
501 if (isa_and_nonnull<NamedDecl>(d))
507void CIRGenModule::setNonAliasAttributes(
GlobalDecl gd, mlir::Operation *op) {
518std::optional<cir::SourceLanguage> CIRGenModule::getCIRSourceLanguage()
const {
520 using CIRLang = cir::SourceLanguage;
525 if (opts.C99 || opts.C11 || opts.C17 || opts.C23 || opts.C2y ||
526 opts.LangStd == ClangStd::lang_c89 ||
527 opts.LangStd == ClangStd::lang_gnu89)
532 errorNYI(
"CIR does not yet support the given source language");
544 gv.
setLinkage(cir::GlobalLinkageKind::ExternalWeakLinkage);
568 if (!isa<cir::GlobalOp>(v))
570 entry = cast<cir::GlobalOp>(v);
580 if (entry.getSymType() == ty)
589 if (isForDefinition && !entry.isDeclaration()) {
598 if (!isForDefinition)
608 entry.getOperation());
623 if (langOpts.OpenMP && !langOpts.OpenMPSimd)
645 if (
getTriple().getArch() == llvm::Triple::xcore)
655 "external const declaration with initializer");
690 mlir::Type ptrTy = builder.
getPointerTo(g.getSymType());
701 cir::PointerType ptrTy = builder.
getPointerTo(globalOp.getSymType());
715 bool isDefinitionAvailableExternally =
721 if (isDefinitionAvailableExternally &&
729 mlir::Attribute init;
733 std::optional<ConstantEmitter> emitter;
737 if (vd->
hasAttr<LoaderUninitializedAttr>()) {
740 }
else if (!initExpr) {
753 emitter.emplace(*
this);
754 mlir::Attribute initializer = emitter->tryEmitForInitializer(*initDecl);
780 if (mlir::isa<mlir::SymbolRefAttr>(init)) {
784 assert(mlir::isa<mlir::TypedAttr>(init) &&
"This should have a type");
785 auto typedInitAttr = mlir::cast<mlir::TypedAttr>(init);
786 initType = typedInitAttr.getType();
788 assert(!mlir::isa<mlir::NoneType>(initType) &&
"Should have a type by now");
794 if (!gv || gv.getSymType() != initType) {
801 if (vd->
hasAttr<AnnotateAttr>()) {
812 emitter->finalize(gv);
815 cir::GlobalLinkageKind linkage =
819 gv.setLinkage(linkage);
823 if (linkage == cir::GlobalLinkageKind::CommonLinkage)
826 setNonAliasAttributes(vd, gv);
834 mlir::Operation *op) {
836 if (
const auto *fd = dyn_cast<FunctionDecl>(
decl)) {
840 if (
const auto *method = dyn_cast<CXXMethodDecl>(
decl)) {
843 if (isa<CXXConstructorDecl>(method) || isa<CXXDestructorDecl>(method))
844 abi->emitCXXStructor(gd);
845 else if (fd->isMultiVersion())
846 errorNYI(method->getSourceRange(),
"multiversion functions");
850 if (method->isVirtual())
856 if (fd->isMultiVersion())
857 errorNYI(fd->getSourceRange(),
"multiversion functions");
862 if (
const auto *vd = dyn_cast<VarDecl>(
decl))
865 llvm_unreachable(
"Invalid argument to CIRGenModule::emitGlobalDefinition");
880 uint64_t finalSize = cat->getZExtSize();
881 str.resize(finalSize);
883 mlir::Type eltTy =
convertType(cat->getElementType());
884 return builder.
getString(str, eltTy, finalSize);
888 "getConstantArrayFromStringLiteral: wide characters");
889 return mlir::Attribute();
900 if (d.
hasAttr<SelectAnyAttr>())
904 if (
auto *vd = dyn_cast<VarDecl>(&d))
919 llvm_unreachable(
"No such linkage");
925 if (
auto globalOp = dyn_cast_or_null<cir::GlobalOp>(op)) {
926 globalOp.setComdat(
true);
928 auto funcOp = cast<cir::FuncOp>(op);
929 funcOp.setComdat(
true);
939 replacements[name] = op;
942void CIRGenModule::replacePointerTypeArgs(cir::FuncOp oldF, cir::FuncOp newF) {
943 std::optional<mlir::SymbolTable::UseRange> optionalUseRange =
944 oldF.getSymbolUses(theModule);
945 if (!optionalUseRange)
948 for (
const mlir::SymbolTable::SymbolUse &u : *optionalUseRange) {
950 auto call = mlir::dyn_cast<cir::CallOp>(u.getUser());
954 for (
const auto [argOp, fnArgType] :
955 llvm::zip(call.getArgs(), newF.getFunctionType().getInputs())) {
956 if (argOp.getType() == fnArgType)
962 errorNYI(call.getLoc(),
"replace call with mismatched types");
967void CIRGenModule::applyReplacements() {
968 for (
auto &i : replacements) {
969 StringRef mangledName = i.first();
970 mlir::Operation *replacement = i.second;
974 assert(isa<cir::FuncOp>(entry) &&
"expected function");
975 auto oldF = cast<cir::FuncOp>(entry);
976 auto newF = dyn_cast<cir::FuncOp>(replacement);
979 errorNYI(replacement->getLoc(),
"replacement is not a function");
985 replacePointerTypeArgs(oldF, newF);
988 if (oldF.replaceAllSymbolUses(newF.getSymNameAttr(), theModule).failed())
989 llvm_unreachable(
"internal error, cannot RAUW symbol");
991 newF->moveBefore(oldF);
998 mlir::Location loc, StringRef name, mlir::Type ty,
1000 auto gv = mlir::dyn_cast_or_null<cir::GlobalOp>(
1001 mlir::SymbolTable::lookupSymbolIn(theModule, name));
1007 errorNYI(loc,
"createOrReplaceCXXRuntimeVariable: already exists");
1017 mlir::SymbolTable::setSymbolVisibility(gv,
1021 !gv.hasAvailableExternallyLinkage()) {
1025 gv.setAlignmentAttr(
getSize(alignment));
1036 if ((noCommon || vd->
hasAttr<NoCommonAttr>()) && !vd->
hasAttr<CommonAttr>())
1047 if (vd->
hasAttr<SectionAttr>())
1053 if (vd->
hasAttr<PragmaClangBSSSectionAttr>() ||
1054 vd->
hasAttr<PragmaClangDataSectionAttr>() ||
1055 vd->
hasAttr<PragmaClangRelroSectionAttr>() ||
1056 vd->
hasAttr<PragmaClangRodataSectionAttr>())
1064 if (vd->
hasAttr<WeakImportAttr>())
1074 if (vd->
hasAttr<AlignedAttr>())
1081 for (
const FieldDecl *fd : rd->fields()) {
1082 if (fd->isBitField())
1084 if (fd->hasAttr<AlignedAttr>())
1109 return cir::GlobalLinkageKind::InternalLinkage;
1111 if (dd->
hasAttr<WeakAttr>()) {
1112 if (isConstantVariable)
1113 return cir::GlobalLinkageKind::WeakODRLinkage;
1114 return cir::GlobalLinkageKind::WeakAnyLinkage;
1119 return cir::GlobalLinkageKind::LinkOnceAnyLinkage;
1124 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
1139 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
1140 : cir::GlobalLinkageKind::InternalLinkage;
1154 return cir::GlobalLinkageKind::ExternalLinkage;
1157 return dd->
hasAttr<CUDAGlobalAttr>()
1158 ? cir::GlobalLinkageKind::ExternalLinkage
1159 : cir::GlobalLinkageKind::InternalLinkage;
1160 return cir::GlobalLinkageKind::WeakODRLinkage;
1165 if (!
getLangOpts().CPlusPlus && isa<VarDecl>(dd) &&
1169 return cir::GlobalLinkageKind::CommonLinkage;
1176 if (dd->
hasAttr<SelectAnyAttr>())
1177 return cir::GlobalLinkageKind::WeakODRLinkage;
1181 return cir::GlobalLinkageKind::ExternalLinkage;
1193 mlir::Operation *old, cir::FuncOp newFn) {
1195 auto oldFn = mlir::dyn_cast<cir::FuncOp>(old);
1203 if (oldFn->getAttrs().size() <= 1)
1205 "replaceUsesOfNonProtoTypeWithRealFunction: Attribute forwarding");
1208 newFn.setNoProto(oldFn.getNoProto());
1211 std::optional<mlir::SymbolTable::UseRange> symUses =
1212 oldFn.getSymbolUses(oldFn->getParentOp());
1213 for (
const mlir::SymbolTable::SymbolUse &use : symUses.value()) {
1214 mlir::OpBuilder::InsertionGuard guard(builder);
1216 if (
auto noProtoCallOp = mlir::dyn_cast<cir::CallOp>(use.getUser())) {
1217 builder.setInsertionPoint(noProtoCallOp);
1221 noProtoCallOp.getLoc(), newFn, noProtoCallOp.getOperands());
1224 noProtoCallOp.replaceAllUsesWith(realCallOp);
1225 noProtoCallOp.erase();
1226 }
else if (
auto getGlobalOp =
1227 mlir::dyn_cast<cir::GetGlobalOp>(use.getUser())) {
1229 getGlobalOp.getAddr().setType(
1230 cir::PointerType::get(newFn.getFunctionType()));
1233 "replaceUsesOfNonProtoTypeWithRealFunction: unexpected use");
1238cir::GlobalLinkageKind
1240 assert(!isConstant &&
"constant variables NYI");
1246 const auto *d = cast<FunctionDecl>(gd.
getDecl());
1250 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(d))
1259 StringRef globalName,
CharUnits alignment) {
1265 cgm, loc, globalName,
c.getType(), !cgm.
getLangOpts().WritableStrings);
1268 gv.setAlignmentAttr(cgm.
getSize(alignment));
1270 cir::GlobalLinkageKindAttr::get(cgm.
getBuilder().getContext(), lt));
1274 if (gv.isWeakForLinker()) {
1275 assert(cgm.
supportsCOMDAT() &&
"Only COFF uses weak string literals");
1278 cgm.
setDSOLocal(
static_cast<mlir::Operation *
>(gv));
1299 std::string result =
1302 assert(!mlir::SymbolTable::lookupSymbolIn(theModule, result));
1316 "getGlobalForStringLiteral: Writable strings");
1322 if (
getCXXABI().getMangleContext().shouldMangleStringLiteral(
s) &&
1325 "getGlobalForStringLiteral: mangle string literals");
1331 mlir::Location loc =
getLoc(
s->getSourceRange());
1332 auto typedC = llvm::cast<mlir::TypedAttr>(
c);
1335 *
this, uniqueName, alignment);
1348 auto arrayTy = mlir::dyn_cast<cir::ArrayType>(gv.getSymType());
1349 assert(arrayTy &&
"String literal must be array");
1362 "emitExplicitCastExprType");
1372 if (
auto *oid = dyn_cast<ObjCImplDecl>(
decl))
1373 errorNYI(oid->getSourceRange(),
"emitDeclConext: ObjCImplDecl");
1383 if (
decl->isTemplated())
1386 switch (
decl->getKind()) {
1389 decl->getDeclKindName());
1392 case Decl::CXXConversion:
1393 case Decl::CXXMethod:
1394 case Decl::Function: {
1395 auto *fd = cast<FunctionDecl>(
decl);
1397 if (!fd->isConsteval())
1403 case Decl::Decomposition:
1404 case Decl::VarTemplateSpecialization: {
1405 auto *vd = cast<VarDecl>(
decl);
1406 if (isa<DecompositionDecl>(
decl)) {
1407 errorNYI(
decl->getSourceRange(),
"global variable decompositions");
1413 case Decl::OpenACCRoutine:
1416 case Decl::OpenACCDeclare:
1421 case Decl::UsingDirective:
1422 case Decl::UsingEnum:
1423 case Decl::NamespaceAlias:
1425 case Decl::TypeAlias:
1431 case Decl::ClassTemplate:
1433 case Decl::CXXDeductionGuide:
1435 case Decl::FunctionTemplate:
1436 case Decl::StaticAssert:
1437 case Decl::TypeAliasTemplate:
1438 case Decl::UsingShadow:
1439 case Decl::VarTemplate:
1440 case Decl::VarTemplatePartialSpecialization:
1443 case Decl::CXXConstructor:
1446 case Decl::CXXDestructor:
1451 case Decl::LinkageSpec:
1452 case Decl::Namespace:
1456 case Decl::ClassTemplateSpecialization:
1457 case Decl::CXXRecord:
1462 case Decl::FileScopeAsm:
1464 if (langOpts.CUDA && langOpts.CUDAIsDevice)
1467 if (langOpts.OpenMPIsTargetDevice)
1470 if (langOpts.SYCLIsDevice)
1472 auto *file_asm = cast<FileScopeAsmDecl>(
decl);
1473 std::string line = file_asm->getAsmString();
1474 globalScopeAsm.push_back(builder.getStringAttr(line));
1481 op.setInitialValueAttr(value);
1488 auto *md = cast<CXXMethodDecl>(gd.
getDecl());
1490 if (isa<CXXDestructorDecl>(md)) {
1495 md->getParent()->getNumVBases() == 0)
1497 "getAddrAndTypeOfCXXStructor: MS ABI complete destructor");
1508 false, isForDefinition);
1510 return {fnType, fn};
1514 mlir::Type funcType,
bool forVTable,
1517 assert(!cast<FunctionDecl>(gd.
getDecl())->isConsteval() &&
1518 "consteval function should never be emitted");
1521 const auto *fd = cast<FunctionDecl>(gd.
getDecl());
1528 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(gd.
getDecl())) {
1531 dd->getParent()->getNumVBases() == 0)
1533 "getAddrOfFunction: MS ABI complete destructor");
1539 false, isForDefinition);
1547 llvm::raw_svector_ostream
out(buffer);
1556 assert(ii &&
"Attempt to mangle unnamed decl.");
1558 const auto *fd = dyn_cast<FunctionDecl>(nd);
1562 }
else if (fd && fd->hasAttr<CUDAGlobalAttr>() &&
1578 if (
const auto *fd = dyn_cast<FunctionDecl>(nd)) {
1579 if (fd->isMultiVersion()) {
1581 "getMangledName: multi-version functions");
1586 "getMangledName: GPU relocatable device code");
1589 return std::string(
out.str());
1597 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(canonicalGd.
getDecl())) {
1600 "getMangledName: C++ constructor without variants");
1601 return cast<NamedDecl>(gd.
getDecl())->getIdentifier()->getName();
1606 const auto *nd = cast<NamedDecl>(gd.
getDecl());
1609 auto result = manglings.insert(std::make_pair(mangledName, gd));
1610 return mangledDeclNames[canonicalGd] = result.first->first();
1614 assert(!d->
getInit() &&
"Cannot emit definite definitions here!");
1622 if (gv && !mlir::cast<cir::GlobalOp>(gv).isDeclaration())
1638 if (langOpts.EmitAllDecls)
1641 const auto *vd = dyn_cast<VarDecl>(global);
1643 ((codeGenOpts.KeepPersistentStorageVariables &&
1644 (vd->getStorageDuration() ==
SD_Static ||
1645 vd->getStorageDuration() ==
SD_Thread)) ||
1646 (codeGenOpts.KeepStaticConsts && vd->getStorageDuration() ==
SD_Static &&
1647 vd->getType().isConstQualified())))
1660 if (langOpts.OpenMP >= 50 && !langOpts.OpenMPSimd) {
1661 std::optional<OMPDeclareTargetDeclAttr *> activeAttr =
1662 OMPDeclareTargetDeclAttr::getActiveAttr(global);
1663 if (!activeAttr || (*activeAttr)->getLevel() != (
unsigned)-1)
1667 const auto *fd = dyn_cast<FunctionDecl>(global);
1674 if (fd->hasAttr<TargetVersionAttr>() && !fd->isMultiVersion())
1676 if (langOpts.SYCLIsDevice) {
1677 errorNYI(fd->getSourceRange(),
"mayBeEmittedEagerly: SYCL");
1681 const auto *vd = dyn_cast<VarDecl>(global);
1691 if (langOpts.OpenMP && langOpts.OpenMPUseTLS &&
1694 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(global))
1697 assert((fd || vd) &&
1698 "Only FunctionDecl and VarDecl should hit this path so far.");
1703 cir::CIRGlobalValueInterface gv) {
1704 if (gv.hasLocalLinkage())
1707 if (!gv.hasDefaultVisibility() && !gv.hasExternalWeakLinkage())
1715 const llvm::Triple &tt = cgm.
getTriple();
1717 if (tt.isOSCygMing()) {
1726 cgm.
errorNYI(
"shouldAssumeDSOLocal: MinGW");
1732 if (tt.isOSBinFormatCOFF() && gv.hasExternalWeakLinkage())
1740 if (tt.isOSBinFormatCOFF() || (tt.isOSWindows() && tt.isOSBinFormatMachO()))
1744 if (!tt.isOSBinFormatELF())
1749 if (rm != llvm::Reloc::Static && !lOpts.PIE) {
1755 if (!(isa<cir::FuncOp>(gv) && gv.canBenefitFromLocalAlias()))
1757 return !(lOpts.SemanticInterposition || lOpts.HalfNoSemanticInterposition);
1761 if (!gv.isDeclarationForLinker())
1767 if (rm == llvm::Reloc::PIC_ && gv.hasExternalWeakLinkage())
1774 if (cgOpts.DirectAccessExternalData) {
1780 if (
auto globalOp = dyn_cast<cir::GlobalOp>(gv.getOperation())) {
1792 if (isa<cir::FuncOp>(gv) && !cgOpts.NoPLT && rm == llvm::Reloc::Static)
1813 if (
auto globalValue = dyn_cast<cir::CIRGlobalValueInterface>(op))
1832 bool isIncompleteFunction,
1852 StringRef mangledName, mlir::Type funcType,
GlobalDecl gd,
bool forVTable,
1854 mlir::ArrayAttr extraAttrs) {
1863 if (
const auto *fd = cast_or_null<FunctionDecl>(d)) {
1865 if (
getLangOpts().OpenMPIsTargetDevice && fd->isDefined() && !dontDefer &&
1868 "getOrCreateCIRFunction: OpenMP target function");
1872 if (fd->isMultiVersion())
1873 errorNYI(fd->getSourceRange(),
"getOrCreateCIRFunction: multi-version");
1879 assert(mlir::isa<cir::FuncOp>(entry));
1884 if (d && !d->
hasAttr<DLLImportAttr>() && !d->
hasAttr<DLLExportAttr>()) {
1891 auto fn = cast<cir::FuncOp>(entry);
1892 if (isForDefinition && fn && !fn.isDeclaration()) {
1895 if (fn && fn.getFunctionType() == funcType) {
1899 if (!isForDefinition) {
1907 auto *funcDecl = llvm::cast_or_null<FunctionDecl>(gd.
getDecl());
1908 bool invalidLoc = !funcDecl ||
1909 funcDecl->getSourceRange().getBegin().isInvalid() ||
1910 funcDecl->getSourceRange().getEnd().isInvalid();
1912 invalidLoc ? theModule->getLoc() :
getLoc(funcDecl->getSourceRange()),
1913 mangledName, mlir::cast<cir::FuncType>(funcType), funcDecl);
1924 auto symbolOp = mlir::cast<mlir::SymbolOpInterface>(entry);
1932 if (symbolOp.getSymbolUses(symbolOp->getParentOp()))
1946 assert(funcOp.getFunctionType() == funcType);
1953 if (isa_and_nonnull<CXXDestructorDecl>(d) &&
1954 getCXXABI().useThunkForDtorVariant(cast<CXXDestructorDecl>(d),
1982 for (
const auto *fd = cast<FunctionDecl>(d)->getMostRecentDecl(); fd;
1983 fd = fd->getPreviousDecl()) {
1984 if (isa<CXXRecordDecl>(fd->getLexicalDeclContext())) {
1985 if (fd->doesThisDeclarationHaveABody()) {
1998 cir::FuncType funcType,
2002 mlir::OpBuilder::InsertionGuard guard(builder);
2010 builder.setInsertionPoint(cgf->
curFn);
2012 func = builder.create<cir::FuncOp>(loc, name, funcType);
2017 func.setNoProto(
true);
2019 assert(func.isDeclaration() &&
"expected empty body");
2023 func.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
2025 mlir::SymbolTable::setSymbolVisibility(
2026 func, mlir::SymbolTable::Visibility::Private);
2031 theModule.push_back(func);
2036mlir::SymbolTable::Visibility
2040 if (op.isDeclaration())
2041 return mlir::SymbolTable::Visibility::Private;
2045mlir::SymbolTable::Visibility
2048 case cir::GlobalLinkageKind::InternalLinkage:
2049 case cir::GlobalLinkageKind::PrivateLinkage:
2050 return mlir::SymbolTable::Visibility::Private;
2051 case cir::GlobalLinkageKind::ExternalLinkage:
2052 case cir::GlobalLinkageKind::ExternalWeakLinkage:
2053 case cir::GlobalLinkageKind::LinkOnceODRLinkage:
2054 case cir::GlobalLinkageKind::AvailableExternallyLinkage:
2055 case cir::GlobalLinkageKind::CommonLinkage:
2056 case cir::GlobalLinkageKind::WeakAnyLinkage:
2057 case cir::GlobalLinkageKind::WeakODRLinkage:
2058 return mlir::SymbolTable::Visibility::Public;
2060 llvm::errs() <<
"visibility not implemented for '"
2061 << stringifyGlobalLinkageKind(glk) <<
"'\n";
2062 assert(0 &&
"not implemented");
2065 llvm_unreachable(
"linkage should be handled above!");
2069 clang::VisibilityAttr::VisibilityType visibility) {
2070 switch (visibility) {
2071 case clang::VisibilityAttr::VisibilityType::Default:
2072 return cir::VisibilityKind::Default;
2073 case clang::VisibilityAttr::VisibilityType::Hidden:
2074 return cir::VisibilityKind::Hidden;
2075 case clang::VisibilityAttr::VisibilityType::Protected:
2076 return cir::VisibilityKind::Protected;
2078 llvm_unreachable(
"unexpected visibility value");
2083 const clang::VisibilityAttr *va =
decl->getAttr<clang::VisibilityAttr>();
2084 cir::VisibilityAttr cirVisibility =
2087 cirVisibility = cir::VisibilityAttr::get(
2091 return cirVisibility;
2096 applyReplacements();
2098 theModule->setAttr(cir::CIRDialect::getModuleLevelAsmAttrName(),
2099 builder.getArrayAttr(globalScopeAsm));
2107 cir::FuncOp aliasee,
2108 cir::GlobalLinkageKind linkage) {
2110 auto *aliasFD = dyn_cast<FunctionDecl>(aliasGD.
getDecl());
2111 assert(aliasFD &&
"expected FunctionDecl");
2122 mangledName, fnType, aliasFD);
2123 alias.setAliasee(aliasee.getName());
2124 alias.setLinkage(linkage);
2128 mlir::SymbolTable::setSymbolVisibility(
2129 alias, mlir::SymbolTable::Visibility::Private);
2136 errorNYI(aliasFD->getSourceRange(),
"emitAliasForGlobal: previous uses");
2153 return mlir::verify(theModule).succeeded();
2164 errorNYI(loc,
"getAddrOfRTTIDescriptor");
2165 return mlir::Attribute();
2171 llvm::iterator_range<CastExpr::path_const_iterator> path) {
2178 assert(!base->isVirtual() &&
"Should not see virtual bases here!");
2183 const auto *baseDecl = base->getType()->castAsCXXRecordDecl();
2195 llvm::StringRef feature) {
2198 return diags.
Report(loc, diagID) << feature;
2202 llvm::StringRef feature) {
Defines the clang::ASTContext interface.
static bool shouldAssumeDSOLocal(const CIRGenModule &cgm, cir::CIRGlobalValueInterface gv)
static bool shouldBeInCOMDAT(CIRGenModule &cgm, const Decl &d)
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 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)
This file defines OpenACC nodes for declarative directives.
Defines the SourceManager interface.
__device__ __2f16 float __ockl_bool s
__device__ __2f16 float c
mlir::TypedAttr getConstNullPtrAttr(mlir::Type t)
cir::GlobalViewAttr getGlobalViewAttr(cir::PointerType type, cir::GlobalOp globalOp, mlir::ArrayAttr indices={})
Get constant address of a global variable as an MLIR attribute.
cir::PointerType getPointerTo(mlir::Type ty)
cir::CallOp createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee, mlir::Type returnType, mlir::ValueRange operands, llvm::ArrayRef< mlir::NamedAttribute > attrs={})
mlir::TypedAttr getZeroInitAttr(mlir::Type ty)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
const ConstantArrayType * getAsConstantArrayType(QualType T) 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.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
bool DeclMustBeEmitted(const Decl *D)
Determines if the decl can be CodeGen'ed or deserialized from PCH lazily, only when used; this is onl...
bool isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const
Returns true if this is an inline-initialized static data member which is treated as a definition for...
const LangOptions & getLangOpts() const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
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.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
CharUnits getAlignOfGlobalVarInChars(QualType T, const VarDecl *VD) const
Return the alignment in characters that should be given to a global variable with type T.
GVALinkage GetGVALinkageForVariable(const VarDecl *VD) const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
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...
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
TargetCXXABI::Kind getCXXABIKind() const
Return the C++ ABI kind that should be used.
QualType getSignedSizeType() const
Return the unique signed counterpart of the integer type corresponding to size_t.
InlineVariableDefinitionKind getInlineVariableDefinitionKind(const VarDecl *VD) const
Determine whether a definition of this inline variable should be treated as a weak or strong definiti...
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getAlignment() const
getAlignment - Get the record alignment in characters.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
cir::PointerType getUInt8PtrTy()
mlir::Attribute getString(llvm::StringRef str, mlir::Type eltTy, std::optional< size_t > size)
Get a cir::ConstArrayAttr for a string literal.
Implements C++ ABI-specific code generation functions.
virtual void emitCXXConstructors(const clang::CXXConstructorDecl *d)=0
Emit constructor variants required by this ABI.
virtual void emitCXXDestructors(const clang::CXXDestructorDecl *d)=0
Emit dtor variants required by this ABI.
clang::MangleContext & getMangleContext()
Gets the mangle context.
virtual cir::GlobalLinkageKind getCXXDestructorLinkage(GVALinkage linkage, const CXXDestructorDecl *dtor, CXXDtorType dt) const
cir::FuncOp generateCode(clang::GlobalDecl gd, cir::FuncOp fn, cir::FuncType funcType)
void emitVariablyModifiedType(QualType ty)
cir::FuncOp curFn
The function for which code is currently being generated.
This class organizes the cross-function state that is used while generating CIR code.
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)
void emitTopLevelDecl(clang::Decl *decl)
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.
bool mustBeEmitted(const clang::ValueDecl *d)
Determine whether the definition must be emitted; if this returns false, the definition can be emitte...
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.
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 emitGlobalDefinition(clang::GlobalDecl gd, mlir::Operation *op=nullptr)
mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty, bool forEH=false)
Get the address of the RTTI descriptor for the given type.
clang::CharUnits getNaturalTypeAlignment(clang::QualType t, LValueBaseInfo *baseInfo)
FIXME: this could likely be a common helper and not necessarily related with codegen.
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
static mlir::SymbolTable::Visibility getMLIRVisibility(cir::GlobalOp op)
const llvm::Triple & getTriple() const
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 emitGlobalDecl(const clang::GlobalDecl &d)
Helper for emitDeferred to apply actual codegen.
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::ArrayAttr extraAttrs={})
void emitGlobalVarDefinition(const clang::VarDecl *vd, bool isTentative=false)
cir::FuncOp getAddrOfFunction(clang::GlobalDecl gd, mlir::Type funcType=nullptr, bool forVTable=false, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
Return the address of the given function.
void emitAliasForGlobal(llvm::StringRef mangledName, mlir::Operation *op, GlobalDecl aliasGD, cir::FuncOp aliasee, cir::GlobalLinkageKind linkage)
void 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.
std::map< llvm::StringRef, clang::GlobalDecl > deferredDecls
This contains all the decls which have definitions but which are deferred for emission and therefore ...
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.
cir::GlobalLinkageKind getFunctionLinkage(GlobalDecl gd)
void updateCompletedType(const clang::TagDecl *td)
const clang::CodeGenOptions & getCodeGenOpts() const
const clang::LangOptions & getLangOpts() const
void addDeferredDeclToEmit(clang::GlobalDecl GD)
cir::FuncOp createCIRFunction(mlir::Location loc, llvm::StringRef name, cir::FuncType funcType, const clang::FunctionDecl *funcDecl)
const TargetCIRGenInfo & getTargetCIRGenInfo()
void setGVPropertiesAux(mlir::Operation *op, const NamedDecl *d) const
mlir::Location getLoc(clang::SourceLocation cLoc)
Helpers to convert the presumed location of Clang's SourceLocation to an MLIR Location.
mlir::Operation * lastGlobalOp
static cir::VisibilityKind getGlobalVisibilityKindFromClangVisibility(clang::VisibilityAttr::VisibilityType visibility)
llvm::StringMap< unsigned > cgGlobalNames
mlir::Operation * getGlobalValue(llvm::StringRef ref)
mlir::ModuleOp getModule() const
bool supportsCOMDAT() const
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.
void emitDeclContext(const DeclContext *dc)
void emitGlobal(clang::GlobalDecl gd)
Emit code for a single global function or variable declaration.
bool mayBeEmittedEagerly(const clang::ValueDecl *d)
Determine whether the definition can be emitted eagerly, or should be delayed until the end of the tr...
cir::GlobalLinkageKind getCIRLinkageVarDefinition(const VarDecl *vd, bool isConstant)
void emitGlobalFunctionDefinition(clang::GlobalDecl gd, mlir::Operation *op)
CIRGenVTables & getVTables()
void setFunctionLinkage(GlobalDecl gd, cir::FuncOp f)
std::vector< clang::GlobalDecl > deferredDeclsToEmit
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.
void updateCompletedType(const clang::TagDecl *td)
UpdateCompletedType - when we find the full definition for a TagDecl, replace the 'opaque' type we pr...
mlir::Type convertType(clang::QualType type)
Convert a Clang type into a mlir::Type.
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.
Represents a base class of a C++ class.
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 *)
const char * getDeclKindName() const
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Represents a ValueDecl that came out of a declarator.
SourceLocation getBeginLoc() const LLVM_READONLY
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.
Represents a member of a struct/union/class.
Represents a function declaration or definition.
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
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 &)
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 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
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.
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.
bool isTLSSupported() const
Whether the target supports thread-local storage.
uint64_t getPointerAlign(LangAS AddrSpace) const
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() const
bool isReferenceType() const
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
const T * getAs() const
Member-template getAs<specific type>'.
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.
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.
@ 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 LLVM_ATTRIBUTE_UNUSED 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.
CIRGenCXXABI * CreateCIRGenItaniumCXXABI(CIRGenModule &cgm)
Creates and Itanium-family ABI.
std::unique_ptr< TargetCIRGenInfo > createX8664TargetCIRGenInfo(CIRGenTypes &cgt)
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
The JSON file list parser is used to communicate input to InstallAPI.
GVALinkage
A more specific kind of linkage than enum Linkage.
@ GVA_AvailableExternally
@ SD_Thread
Thread storage duration.
@ SD_Static
Static storage duration.
@ 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.
bool isExternallyVisible(Linkage L)
static bool alignCXXRecordDecl()
static bool weakRefReference()
static bool opGlobalSection()
static bool opGlobalConstant()
static bool addressSpace()
static bool opGlobalUnnamedAddr()
static bool needsGlobalCtorDtor()
static bool opGlobalThreadLocal()
static bool sourceLanguageCases()
static bool cxxRecordStaticMembers()
static bool opFuncAstDeclAttr()
static bool opGlobalUsedOrCompilerUsed()
static bool moduleNameHash()
static bool opGlobalVisibility()
static bool setFunctionAttributes()
static bool setDLLStorageClass()
static bool opFuncParameterAttributes()
static bool targetCIRGenInfoArch()
static bool opFuncExtraAttrs()
static bool opFuncSection()
static bool opFuncAttributesForDefinition()
static bool opGlobalDLLImportExport()
static bool opGlobalPartition()
static bool opGlobalWeakRef()
static bool setTargetAttributes()
static bool deferredCXXGlobalInit()
static bool opFuncOperandBundles()
static bool defaultVisibility()
static bool opFuncExceptions()
static bool deferredVtables()
static bool cudaSupport()
static bool opFuncMaybeHandleStaticInExternC()
static bool generateDebugInfo()
static bool targetCIRGenInfoOS()
static bool opFuncCPUAndFeaturesAttributes()
static bool maybeHandleStaticInExternC()
static bool setLLVMFunctionFEnvAttributes()
cir::PointerType VoidPtrTy
void* in address space 0
unsigned char PointerAlignInBytes
unsigned char SizeAlignInBytes
The alignment of size_t.
cir::PointerType UInt8PtrTy
LangStandard - Information about the properties of a particular language standard.