18#include "mlir/IR/Location.h"
23#include "llvm/IR/FPEnv.h"
30 bool suppressNewContext)
41 switch (
type->getTypeClass()) {
42#define TYPE(name, parent)
43#define ABSTRACT_TYPE(name, parent)
44#define NON_CANONICAL_TYPE(name, parent) case Type::name:
45#define DEPENDENT_TYPE(name, parent) case Type::name:
46#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(name, parent) case Type::name:
47#include "clang/AST/TypeNodes.inc"
48 llvm_unreachable(
"non-canonical or dependent type in IR-generation");
51 case Type::DeducedTemplateSpecialization:
52 llvm_unreachable(
"undeduced type in IR-generation");
57 case Type::BlockPointer:
58 case Type::LValueReference:
59 case Type::RValueReference:
60 case Type::MemberPointer:
63 case Type::ConstantMatrix:
64 case Type::FunctionProto:
65 case Type::FunctionNoProto:
67 case Type::ObjCObjectPointer:
70 case Type::OverflowBehavior:
71 case Type::HLSLAttributedResource:
72 case Type::HLSLInlineSpirv:
80 case Type::ConstantArray:
81 case Type::IncompleteArray:
82 case Type::VariableArray:
84 case Type::ObjCObject:
85 case Type::ObjCInterface:
86 case Type::ArrayParameter:
94 llvm_unreachable(
"unknown type kind!");
99 return cgm.getTypes().convertTypeForMem(t);
103 return cgm.getTypes().convertType(t);
113 return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
119 assert(
currSrcLoc &&
"expected to inherit some source location");
123 return builder.getUnknownLoc();
133 mlir::Attribute metadata;
139 assert(
currSrcLoc &&
"expected to inherit some source location");
143 return builder.getUnknownLoc();
148 mlir::Attribute metadata;
175 ignoreCaseStmts =
true;
178 return std::any_of(
s->child_begin(),
s->child_end(),
179 [=](
const Stmt *subStmt) {
180 return containsLabel(subStmt, ignoreCaseStmts);
189 llvm::APSInt resultInt;
193 resultBool = resultInt.getBoolValue();
201 llvm::APSInt &resultInt,
209 llvm::APSInt intValue = result.
Val.
getInt();
213 resultInt = intValue;
217void CIRGenFunction::emitAndUpdateRetAlloca(
QualType type, mlir::Location loc,
219 if (!
type->isVoidType()) {
227void CIRGenFunction::declare(mlir::Value addrVal,
const Decl *var, QualType ty,
228 mlir::Location loc, CharUnits alignment,
231 assert(!
symbolTable.count(var) &&
"not supposed to be available just yet");
233 auto allocaOp = addrVal.getDefiningOp<cir::AllocaOp>();
234 assert(allocaOp &&
"expected cir::AllocaOp");
238 if (ty->isReferenceType() || ty.isConstQualified())
248 auto applyCleanup = [&]() {
263 for (mlir::Block *retBlock : localScope->
getRetBlocks()) {
264 mlir::OpBuilder::InsertionGuard guard(builder);
265 builder.setInsertionPointToEnd(retBlock);
266 retBlocks.push_back(retBlock);
267 mlir::Location retLoc = localScope->
getRetLoc(retBlock);
271 auto insertCleanupAndLeave = [&](mlir::Block *insPt) {
272 mlir::OpBuilder::InsertionGuard guard(builder);
273 builder.setInsertionPointToEnd(insPt);
282 mlir::Block *currentBlock = builder.getBlock();
287 cir::BrOp::create(builder, insPt->back().getLoc(), cleanupBlock);
288 if (!cleanupBlock->mightHaveTerminator()) {
289 mlir::OpBuilder::InsertionGuard guard(builder);
290 builder.setInsertionPointToEnd(cleanupBlock);
291 cir::YieldOp::create(builder, localScope->endLoc);
295 if (localScope->
depth == 0) {
300 mlir::Location retLoc = localScope->
getRetLoc(retBlock);
301 if (retBlock->getUses().empty()) {
306 for (mlir::BlockOperand &blockUse : retBlock->getUses()) {
307 cir::BrOp brOp = mlir::cast<cir::BrOp>(blockUse.getOwner());
308 brOp.setSuccessor(cleanupBlock);
312 cir::BrOp::create(builder, retLoc, retBlock);
316 emitImplicitReturn();
323 if (!localScope->
isTernary() && !currentBlock->mightHaveTerminator()) {
324 !retVal ? cir::YieldOp::create(builder, localScope->endLoc)
325 : cir::YieldOp::create(builder, localScope->endLoc, retVal);
335 insertCleanupAndLeave(cleanupBlock);
340 mlir::Block *curBlock = builder.getBlock();
343 if (curBlock->mightHaveTerminator() && curBlock->getTerminator())
347 bool isEntryBlock = builder.getInsertionBlock()->isEntryBlock();
348 if (!isEntryBlock && curBlock->empty()) {
350 for (mlir::Block *retBlock : retBlocks) {
351 if (retBlock->getUses().empty())
361 builder.setInsertionPointToEnd(entryBlock);
362 insertCleanupAndLeave(entryBlock);
369 cir::BrOp::create(builder, curBlock->back().getLoc(), cleanupBlock);
374 insertCleanupAndLeave(curBlock);
377cir::ReturnOp CIRGenFunction::LexicalScope::emitReturn(mlir::Location loc) {
380 auto fn = dyn_cast<cir::FuncOp>(cgf.curFn);
381 assert(fn &&
"emitReturn from non-function");
384 if (fn.getCoroutine())
385 cgf.emitCoroEndBuiltinCall(loc,
386 builder.getNullPtr(builder.getVoidPtrTy(), loc));
387 if (!fn.getFunctionType().hasVoidReturn()) {
389 auto value = cir::LoadOp::create(
390 builder, loc, fn.getFunctionType().getReturnType(), *cgf.fnRetAlloca);
391 return cir::ReturnOp::create(builder, loc,
394 return cir::ReturnOp::create(builder, loc);
404 return classDecl->hasTrivialDestructor();
411 mlir::Operation *op = &block->back();
412 auto cleanupScopeOp = mlir::dyn_cast<cir::CleanupScopeOp>(op);
420 for (mlir::Block &bodyBlock : cleanupScopeOp.getBodyRegion()) {
421 if (bodyBlock.mightHaveTerminator()) {
422 if (mlir::isa<cir::YieldOp>(bodyBlock.getTerminator()))
424 assert(!mlir::isa<cir::BreakOp>(bodyBlock.getTerminator()) &&
425 !mlir::isa<cir::ContinueOp>(bodyBlock.getTerminator()) &&
426 !mlir::isa<cir::ResumeOp>(bodyBlock.getTerminator()));
432void CIRGenFunction::LexicalScope::emitImplicitReturn() {
433 CIRGenBuilderTy &builder = cgf.getBuilder();
434 LexicalScope *localScope = cgf.curLexScope;
443 if (cgf.getLangOpts().CPlusPlus && !fd->hasImplicitReturnZero() &&
444 !cgf.sawAsmBlock && !fd->getReturnType()->isVoidType() &&
445 builder.getInsertionBlock() &&
447 bool shouldEmitUnreachable =
448 cgf.cgm.getCodeGenOpts().StrictReturn ||
451 if (shouldEmitUnreachable) {
453 if (cgf.cgm.getCodeGenOpts().OptimizationLevel == 0)
454 cir::TrapOp::create(builder, localScope->endLoc);
456 cir::UnreachableOp::create(builder, localScope->endLoc);
457 builder.clearInsertionPoint();
462 (void)emitReturn(localScope->endLoc);
470 scope = scope->parentScope;
483 if (value.getType() == ty)
486 assert((mlir::isa<cir::IntType>(ty) || cir::isAnyFloatingPointType(ty)) &&
487 "unexpected promotion type");
489 if (mlir::isa<cir::IntType>(ty))
490 return cgf.
getBuilder().CIRBaseBuilderTy::createIntCast(value, ty);
496 mlir::Block *entryBB,
500 if (fd && fd->
hasAttr<NakedAttr>()) {
501 cgm.errorNYI(bodyBeginLoc,
"naked function decl");
505 for (
const auto nameValue : llvm::zip(args, entryBB->getArguments())) {
506 const VarDecl *paramVar = std::get<0>(nameValue);
507 mlir::Value paramVal = std::get<1>(nameValue);
510 paramVal.setLoc(paramLoc);
512 mlir::Value addrVal =
517 declare(addrVal, paramVar, paramVar->
getType(), paramLoc, alignment,
530 mlir::Location fnBodyBegin =
getLoc(bodyBeginLoc);
531 builder.CIRBaseBuilderTy::createStore(fnBodyBegin, paramVal, addrVal);
533 assert(builder.getInsertionBlock() &&
"Should be valid");
537 cir::FuncOp fn, cir::FuncType funcType,
541 "CIRGenFunction can only be used for one function at a time");
549 const auto *fd = dyn_cast_or_null<FunctionDecl>(d);
554 mlir::Block *entryBB = &fn.getBlocks().front();
555 builder.setInsertionPointToStart(entryBB);
561 if (
Stmt *body = fd->getBody())
562 bodyBeginLoc = body->getBeginLoc();
564 bodyBeginLoc = fd->getLocation();
576 if (
Stmt *body = fd->getBody())
577 bodyEndLoc = body->getEndLoc();
579 bodyEndLoc = fd->getLocation();
581 emitAndUpdateRetAlloca(returnType,
getLoc(bodyEndLoc),
582 getContext().getTypeAlignInChars(returnType));
585 if (isa_and_nonnull<CXXMethodDecl>(d) &&
587 cgm.getCXXABI().emitInstanceFunctionProlog(loc, *
this);
590 if (md->getParent()->isLambda() && md->getOverloadedOperator() == OO_Call) {
592 auto fn = dyn_cast<cir::FuncOp>(
curFn);
593 assert(fn &&
"lambda in non-function region");
619 for (
auto *fd : md->getParent()->fields()) {
620 if (fd->hasCapturedVLAType())
621 cgm.errorNYI(loc,
"lambda captured VLA type");
636 for (cir::BlockAddressOp &blockAddress :
cgm.unresolvedBlockAddressToLabel) {
637 cir::LabelOp labelOp =
638 cgm.lookupBlockAddressInfo(blockAddress.getBlockAddrInfo());
639 assert(labelOp &&
"expected cir.labelOp to already be emitted");
640 cgm.updateResolvedBlockAddress(blockAddress, labelOp);
642 cgm.unresolvedBlockAddressToLabel.clear();
650 mlir::OpBuilder::InsertionGuard guard(builder);
652 for (
auto &[blockAdd, labelOp] :
cgm.blockAddressToLabel) {
653 succesors.push_back(labelOp->getBlock());
654 rangeOperands.push_back(labelOp->getBlock()->getArguments());
656 cir::IndirectBrOp::create(builder, builder.getUnknownLoc(),
658 rangeOperands, succesors);
659 cgm.blockAddressToLabel.clear();
674 indrBr.setPoison(
true);
694 if (
const CompoundStmt *block = dyn_cast<CompoundStmt>(body))
705 for (mlir::Block &block : func.getBlocks()) {
706 if (block.empty() && block.getUses().empty())
707 blocksToDelete.push_back(&block);
709 for (mlir::Block *block : blocksToDelete)
714 cir::FuncType funcType) {
718 if (funcDecl->isInlineBuiltinDeclaration()) {
722 std::string fdInlineName = (
cgm.getMangledName(funcDecl) +
".inline").str();
724 mlir::cast_or_null<cir::FuncOp>(
cgm.getGlobalValue(fdInlineName));
726 mlir::OpBuilder::InsertionGuard guard(builder);
727 builder.setInsertionPoint(fn);
728 clone = cir::FuncOp::create(builder, fn.getLoc(), fdInlineName,
729 fn.getFunctionType());
730 clone.setLinkage(cir::GlobalLinkageKind::InternalLinkage);
731 clone.setSymVisibility(
"private");
732 clone.setInlineKind(cir::InlineKind::AlwaysInline);
734 fn.setLinkage(cir::GlobalLinkageKind::ExternalLinkage);
735 fn.setSymVisibility(
"private");
743 if (LLVM_UNLIKELY(pd->isInlineBuiltinDeclaration())) {
744 std::string inlineName = funcDecl->getName().str() +
".inline";
745 if (
auto inlineFn = mlir::cast_or_null<cir::FuncOp>(
746 cgm.getGlobalValue(inlineName))) {
751 .replaceAllSymbolUses(fn.getSymNameAttr(),
cgm.getModule())
753 llvm_unreachable(
"Failed to replace inline builtin symbol uses");
762 Stmt *body = funcDecl->getBody();
767 : builder.getUnknownLoc()};
770 return clangLoc.isValid() ?
getLoc(clangLoc) : builder.getUnknownLoc();
772 const mlir::Location fusedLoc = mlir::FusedLoc::get(
774 {validMLIRLoc(bodyRange.
getBegin()), validMLIRLoc(bodyRange.
getEnd())});
775 mlir::Block *entryBB = fn.addEntryBlock();
789 if (body && isa_and_nonnull<CoroutineBodyStmt>(body))
790 llvm::append_range(
fnArgs, funcDecl->parameters());
797 funcDecl->hasAttr<CUDAGlobalAttr>()) {
798 cgm.getCUDARuntime().emitDeviceStub(*
this, fn, args);
818 llvm_unreachable(
"no definition for normal function");
821 if (mlir::failed(fn.verifyBody()))
836 assert((
cgm.getTarget().getCXXABI().hasConstructorVariants() ||
838 "can only generate complete ctor for this ABI");
843 cgm.getTarget().getCXXABI().hasConstructorVariants()) {
849 Stmt *body = ctor->getBody(definition);
850 assert(definition == ctor &&
"emitting wrong constructor body");
852 if (isa_and_nonnull<CXXTryStmt>(body)) {
853 cgm.errorNYI(ctor->getSourceRange(),
"emitConstructorBody: try body");
868 if (mlir::failed(
emitStmt(body,
true))) {
869 cgm.errorNYI(ctor->getSourceRange(),
870 "emitConstructorBody: emit body statement failed.");
916 const bool isTryBody = isa_and_nonnull<CXXTryStmt>(body);
932 llvm_unreachable(
"not expecting a unified dtor");
934 llvm_unreachable(
"not expecting a COMDAT");
937 llvm_unreachable(
"already handled deleting case");
940 assert((body ||
getTarget().getCXXABI().isMicrosoft()) &&
941 "can't emit a dtor without a body for non-Microsoft ABIs");
969 assert(dtor->
isImplicit() &&
"bodyless dtor not implicit");
995 CharUnits align =
cgm.getNaturalTypeAlignment(ty, &baseInfo);
1002 CharUnits alignment =
cgm.getNaturalTypeAlignment(ty, &baseInfo);
1010static llvm::fp::ExceptionBehavior
1014 return llvm::fp::ebIgnore;
1016 return llvm::fp::ebMayTrap;
1018 return llvm::fp::ebStrict;
1020 llvm_unreachable(
"expected explicitly initialized exception behavior");
1022 llvm_unreachable(
"unsupported FP exception behavior");
1028 QualType retTy = fd->getReturnType();
1030 const auto *md = dyn_cast<CXXMethodDecl>(fd);
1031 if (md && md->isInstance()) {
1032 if (
cgm.getCXXABI().hasThisReturn(gd))
1033 cgm.errorNYI(fd->getSourceRange(),
"this return");
1034 else if (
cgm.getCXXABI().hasMostDerivedReturn(gd))
1035 cgm.errorNYI(fd->getSourceRange(),
"most derived return");
1036 cgm.getCXXABI().buildThisParam(*
this, args);
1039 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(fd))
1040 if (cd->getInheritedConstructor())
1041 cgm.errorNYI(fd->getSourceRange(),
1042 "buildFunctionArgList: inherited constructor");
1044 for (
auto *param : fd->parameters())
1045 args.push_back(param);
1048 cgm.getCXXABI().addImplicitStructorParams(*
this, retTy, args);
1061 std::string(
"l-value not implemented for '") +
1064 case Expr::ConditionalOperatorClass:
1066 case Expr::BinaryConditionalOperatorClass:
1068 case Expr::ArraySubscriptExprClass:
1070 case Expr::ExtVectorElementExprClass:
1072 case Expr::UnaryOperatorClass:
1074 case Expr::StringLiteralClass:
1076 case Expr::MemberExprClass:
1078 case Expr::CompoundLiteralExprClass:
1080 case Expr::PredefinedExprClass:
1082 case Expr::BinaryOperatorClass:
1084 case Expr::CompoundAssignOperatorClass: {
1088 "CompoundAssignOperator with AtomicType");
1096 case Expr::CallExprClass:
1097 case Expr::CXXMemberCallExprClass:
1098 case Expr::CXXOperatorCallExprClass:
1099 case Expr::UserDefinedLiteralClass:
1101 case Expr::ExprWithCleanupsClass: {
1108 case Expr::CXXDefaultArgExprClass: {
1113 case Expr::CXXTypeidExprClass:
1115 case Expr::ParenExprClass:
1117 case Expr::GenericSelectionExprClass:
1119 case Expr::DeclRefExprClass:
1121 case Expr::ImplicitCastExprClass:
1122 case Expr::CStyleCastExprClass:
1123 case Expr::CXXStaticCastExprClass:
1124 case Expr::CXXDynamicCastExprClass:
1125 case Expr::CXXReinterpretCastExprClass:
1126 case Expr::CXXConstCastExprClass:
1130 case Expr::MaterializeTemporaryExprClass:
1132 case Expr::OpaqueValueExprClass:
1134 case Expr::ChooseExprClass:
1136 case Expr::SubstNonTypeTemplateParmExprClass:
1143 llvm::raw_svector_ostream
out(buffer);
1145 return std::string(
out.str());
1165 cgm.errorNYI(loc,
"Cast the dest ptr to the appropriate i8 pointer type");
1174 "emitNullInitialization for zero size VariableArrayType");
1184 if (!
cgm.getTypes().isZeroInitializable(ty)) {
1185 cgm.errorNYI(loc,
"type is not zero initializable");
1192 const mlir::Value zeroValue = builder.getNullValue(
convertType(ty), loc);
1193 builder.createStore(loc, zeroValue, destPtr);
1205 ConstructorHelper(fpFeatures);
1208void CIRGenFunction::CIRGenFPOptionsRAII::ConstructorHelper(
1210 oldFPFeatures = cgf.curFPFeatures;
1211 cgf.curFPFeatures = fpFeatures;
1213 oldExcept = cgf.builder.getDefaultConstrainedExcept();
1214 oldRounding = cgf.builder.getDefaultConstrainedRounding();
1216 if (oldFPFeatures == fpFeatures)
1222 [[maybe_unused]] llvm::RoundingMode newRoundingBehavior =
1225 [[maybe_unused]] llvm::fp::ExceptionBehavior newExceptionBehavior =
1233 assert((cgf.curFuncDecl ==
nullptr || cgf.builder.getIsFPConstrained() ||
1236 (newExceptionBehavior == llvm::fp::ebIgnore &&
1237 newRoundingBehavior == llvm::RoundingMode::NearestTiesToEven)) &&
1238 "FPConstrained should be enabled on entire function");
1245 cgf.curFPFeatures = oldFPFeatures;
1246 cgf.builder.setDefaultConstrainedExcept(oldExcept);
1247 cgf.builder.setDefaultConstrainedRounding(oldRounding);
1254 if (ce->
getCastKind() == CK_UncheckedDerivedToBase)
1264 if (ice->isGLValue())
1286 uint64_t countFromCLAs = 1;
1289 auto cirArrayType = mlir::dyn_cast<cir::ArrayType>(addr.
getElementType());
1291 while (cirArrayType) {
1293 countFromCLAs *= cirArrayType.getSize();
1297 mlir::dyn_cast<cir::ArrayType>(cirArrayType.getElementType());
1301 "CIR and Clang types are out-of-sync");
1308 cgm.errorNYI(*
currSrcLoc,
"length for non-array underlying types");
1320 mlir::OpBuilder::InsertionGuard guard(builder);
1322 builder.createBlock(builder.getBlock()->getParent(), {}, {voidPtrTy},
1323 {builder.getUnknownLoc()});
1328 SourceLocation assumptionLoc, int64_t alignment, mlir::Value offsetValue) {
1330 return cir::AssumeAlignedOp::create(builder,
getLoc(assumptionLoc), ptrValue,
1331 alignment, offsetValue);
1336 int64_t alignment, mlir::Value offsetValue) {
1345 cgm.getASTContext().getAsVariableArrayType(
type);
1346 assert(vla &&
"type was not a variable array type!");
1353 mlir::Value numElements;
1357 elementType =
type->getElementType();
1359 assert(vlaSize &&
"no size for VLA!");
1360 assert(vlaSize.getType() ==
sizeTy);
1363 numElements = vlaSize;
1369 builder.createMul(numElements.getLoc(), numElements, vlaSize,
1372 }
while ((
type =
getContext().getAsVariableArrayType(elementType)));
1374 assert(numElements &&
"Undefined elements number");
1375 return {numElements, elementType};
1381 assert(vlaSize &&
"no size for VLA!");
1382 assert(vlaSize.getType() ==
sizeTy);
1389 assert(
type->isVariablyModifiedType() &&
1390 "Must pass variably modified type to EmitVLASizes!");
1395 assert(
type->isVariablyModifiedType());
1397 const Type *ty =
type.getTypePtr();
1399 case Type::CountAttributed:
1400 case Type::PackIndexing:
1401 case Type::ArrayParameter:
1402 case Type::HLSLAttributedResource:
1403 case Type::HLSLInlineSpirv:
1404 case Type::PredefinedSugar:
1405 cgm.errorNYI(
"CIRGenFunction::emitVariablyModifiedType");
1408#define TYPE(Class, Base)
1409#define ABSTRACT_TYPE(Class, Base)
1410#define NON_CANONICAL_TYPE(Class, Base)
1411#define DEPENDENT_TYPE(Class, Base) case Type::Class:
1412#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)
1413#include "clang/AST/TypeNodes.inc"
1415 "dependent type must be resolved before the CIR codegen");
1421 case Type::ExtVector:
1422 case Type::ConstantMatrix:
1426 case Type::TemplateSpecialization:
1427 case Type::ObjCTypeParam:
1428 case Type::ObjCObject:
1429 case Type::ObjCInterface:
1430 case Type::ObjCObjectPointer:
1432 case Type::OverflowBehavior:
1433 llvm_unreachable(
"type class is never variably-modified!");
1435 case Type::Adjusted:
1447 case Type::BlockPointer:
1451 case Type::LValueReference:
1452 case Type::RValueReference:
1456 case Type::MemberPointer:
1460 case Type::ConstantArray:
1461 case Type::IncompleteArray:
1466 case Type::VariableArray: {
1483 entry = builder.createIntCast(size,
sizeTy);
1490 case Type::FunctionProto:
1491 case Type::FunctionNoProto:
1497 case Type::UnaryTransform:
1498 case Type::Attributed:
1499 case Type::BTFTagAttributed:
1500 case Type::SubstTemplateTypeParm:
1501 case Type::MacroQualified:
1507 case Type::Decltype:
1509 case Type::DeducedTemplateSpecialization:
1513 case Type::TypeOfExpr:
1526 }
while (
type->isVariablyModifiedType());
1530 if (
getContext().getBuiltinVaListType()->isArrayType())
Defines the clang::Expr interface and subclasses for C++ expressions.
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
__device__ __2f16 float __ockl_bool s
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
mlir::Type getElementType() const
mlir::Value createFloatingCast(mlir::Value v, mlir::Type destType)
CIRGenFPOptionsRAII(CIRGenFunction &cgf, FPOptions FPFeatures)
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
void forceCleanup(ArrayRef< mlir::Value * > valuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
bool hasPendingCleanups() const
Whether there are any pending cleanups that have been pushed since this scope was entered.
static bool isConstructorDelegationValid(const clang::CXXConstructorDecl *ctor)
Checks whether the given constructor is a valid subject for the complete-to-base constructor delegati...
void emitFunctionProlog(const FunctionArgList &args, mlir::Block *entryBB, const FunctionDecl *fd, SourceLocation bodyBeginLoc)
Emit the function prologue: declare function arguments in the symbol table.
mlir::Type convertType(clang::QualType t)
LValue emitOpaqueValueLValue(const OpaqueValueExpr *e)
static cir::TypeEvaluationKind getEvaluationKind(clang::QualType type)
Return the cir::TypeEvaluationKind of QualType type.
clang::GlobalDecl curGD
The GlobalDecl for the current function being compiled or the global variable currently being initial...
EHScopeStack::stable_iterator prologueCleanupDepth
The cleanup depth enclosing all the cleanups associated with the parameters.
cir::FuncOp generateCode(clang::GlobalDecl gd, cir::FuncOp fn, cir::FuncType funcType)
Address emitPointerWithAlignment(const clang::Expr *expr, LValueBaseInfo *baseInfo=nullptr)
Given an expression with a pointer type, emit the value and compute our best estimate of the alignmen...
void emitVariablyModifiedType(QualType ty)
RValue emitLoadOfLValue(LValue lv, SourceLocation loc)
Given an expression that represents a value lvalue, this method emits the address of the lvalue,...
const clang::LangOptions & getLangOpts() const
mlir::Value cxxStructorImplicitParamValue
void emitTrap(mlir::Location loc, bool createNewBlock)
Emit a trap instruction, which is used to abort the program in an abnormal way, usually for debugging...
VlaSizePair getVLASize(const VariableArrayType *type)
Returns an MLIR::Value+QualType pair that corresponds to the size, in non-variably-sized elements,...
LValue makeNaturalAlignPointeeAddrLValue(mlir::Value v, clang::QualType t)
Given a value of type T* that may not be to a complete object, construct an l-vlaue withi the natural...
LValue emitMemberExpr(const MemberExpr *e)
const TargetInfo & getTarget() const
LValue emitConditionalOperatorLValue(const AbstractConditionalOperator *expr)
LValue emitLValue(const clang::Expr *e)
Emit code to compute a designator that specifies the location of the expression.
const clang::Decl * curFuncDecl
Address loadCXXThisAddress()
LValue emitLValueForLambdaField(const FieldDecl *field)
std::string getCounterRefTmpAsString()
LValue makeNaturalAlignAddrLValue(mlir::Value val, QualType ty)
llvm::DenseMap< const Expr *, mlir::Value > vlaSizeMap
bool constantFoldsToSimpleInteger(const clang::Expr *cond, llvm::APSInt &resultInt, bool allowLabels=false)
If the specified expression does not fold to a constant, or if it does fold but contains a label,...
LValue emitComplexCompoundAssignmentLValue(const CompoundAssignOperator *e)
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
bool constantFoldsToBool(const clang::Expr *cond, bool &resultBool, bool allowLabels=false)
If the specified expression does not fold to a constant, or if it does but contains a label,...
void emitDelegateCXXConstructorCall(const clang::CXXConstructorDecl *ctor, clang::CXXCtorType ctorType, const FunctionArgList &args, clang::SourceLocation loc)
VlaSizePair getVLAElements1D(const VariableArrayType *vla)
Return the number of elements for a single dimension for the given array type.
mlir::Value emitArrayLength(const clang::ArrayType *arrayType, QualType &baseType, Address &addr)
Computes the length of an array in elements, as well as the base element type and a properly-typed fi...
void emitNullInitialization(mlir::Location loc, Address destPtr, QualType ty)
LValue emitArraySubscriptExpr(const clang::ArraySubscriptExpr *e)
llvm::ScopedHashTableScope< const clang::Decl *, mlir::Value > SymTableScopeTy
mlir::Block * indirectGotoBlock
IndirectBranch - The first time an indirect goto is seen we create a block reserved for the indirect ...
mlir::Operation * curFn
The current function or global initializer that is generated code for.
EHScopeStack ehStack
Tracks function scope overall cleanup handling.
void enterDtorCleanups(const CXXDestructorDecl *dtor, CXXDtorType type)
Enter the cleanups necessary to complete the given phase of destruction for a destructor.
llvm::SmallVector< const ParmVarDecl * > fnArgs
Save Parameter Decl for coroutine.
std::optional< mlir::Value > fnRetAlloca
The compiler-generated variable that holds the return value.
void emitImplicitAssignmentOperatorBody(FunctionArgList &args)
mlir::Type convertTypeForMem(QualType t)
clang::QualType buildFunctionArgList(clang::GlobalDecl gd, FunctionArgList &args)
void emitCtorPrologue(const clang::CXXConstructorDecl *ctor, clang::CXXCtorType ctorType, FunctionArgList &args)
This routine generates necessary code to initialize base classes and non-static data members belongin...
mlir::Value emitAlloca(llvm::StringRef name, mlir::Type ty, mlir::Location loc, clang::CharUnits alignment, bool insertIntoFnEntryBlock, mlir::Value arraySize=nullptr)
LValue emitCompoundAssignmentLValue(const clang::CompoundAssignOperator *e)
Address returnValue
The temporary alloca to hold the return value.
void finishFunction(SourceLocation endLoc)
mlir::LogicalResult emitFunctionBody(const clang::Stmt *body)
std::string getCounterAggTmpAsString()
LValue emitUnaryOpLValue(const clang::UnaryOperator *e)
clang::FieldDecl * lambdaThisCaptureField
const clang::Decl * curCodeDecl
This is the inner-most code context, which includes blocks.
void emitConstructorBody(FunctionArgList &args)
LValue emitCallExprLValue(const clang::CallExpr *e)
bool haveInsertPoint() const
True if an insertion point is defined.
void finishIndirectBranch()
LValue emitStringLiteralLValue(const StringLiteral *e, llvm::StringRef name=".str")
void resolveBlockAddresses()
mlir::Value emitScalarExpr(const clang::Expr *e, bool ignoreResultAssign=false)
Emit the computation of the specified expression of scalar type.
void popCleanupBlocks(EHScopeStack::stable_iterator oldCleanupStackDepth, ArrayRef< mlir::Value * > valuesToReload={})
Takes the old cleanup stack size and emits the cleanup blocks that have been added.
bool shouldNullCheckClassCastValue(const CastExpr *ce)
CIRGenBuilderTy & getBuilder()
bool didCallStackSave
Whether a cir.stacksave operation has been added.
LValue emitBinaryOperatorLValue(const BinaryOperator *e)
void startFunction(clang::GlobalDecl gd, clang::QualType returnType, cir::FuncOp fn, cir::FuncType funcType, FunctionArgList args, clang::SourceLocation loc, clang::SourceLocation startLoc)
Emit code for the start of a function.
CIRGenModule & getCIRGenModule()
unsigned counterRefTmp
Hold counters for incrementally naming temporaries.
mlir::MLIRContext & getMLIRContext()
void emitDestructorBody(FunctionArgList &args)
Emits the body of the current destructor.
LValue emitCastLValue(const CastExpr *e)
Casts are never lvalues unless that cast is to a reference type.
LValue emitCXXTypeidLValue(const CXXTypeidExpr *e)
bool containsLabel(const clang::Stmt *s, bool ignoreCaseStmts=false)
Return true if the statement contains a label in it.
LValue emitDeclRefLValue(const clang::DeclRefExpr *e)
llvm::DenseMap< const clang::ValueDecl *, clang::FieldDecl * > lambdaCaptureFields
mlir::Value emitAlignmentAssumption(mlir::Value ptrValue, QualType ty, SourceLocation loc, SourceLocation assumptionLoc, int64_t alignment, mlir::Value offsetValue=nullptr)
LValue makeAddrLValue(Address addr, QualType ty, AlignmentSource source=AlignmentSource::Type)
LValue emitPredefinedLValue(const PredefinedExpr *e)
void emitCXXDestructorCall(const CXXDestructorDecl *dd, CXXDtorType type, bool forVirtualBase, bool delegating, Address thisAddr, QualType thisTy)
void emitLambdaStaticInvokeBody(const CXXMethodDecl *md)
void instantiateIndirectGotoBlock()
CIRGenFunction(CIRGenModule &cgm, CIRGenBuilderTy &builder, bool suppressNewContext=false)
std::optional< mlir::Location > currSrcLoc
Use to track source locations across nested visitor traversals.
LValue emitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *e)
LValue emitExtVectorElementExpr(const ExtVectorElementExpr *e)
clang::ASTContext & getContext() const
void setAddrOfLocalVar(const clang::VarDecl *vd, Address addr)
Set the address of a local variable.
mlir::Value cxxabiThisValue
mlir::LogicalResult emitStmt(const clang::Stmt *s, bool useCurrentScope, llvm::ArrayRef< const Attr * > attrs={})
Address emitVAListRef(const Expr *e)
Build a "reference" to a va_list; this is either the address or the value of the expression,...
mlir::LogicalResult emitCompoundStmtWithoutScope(const clang::CompoundStmt &s, Address *lastValue=nullptr, AggValueSlot slot=AggValueSlot::ignored())
void emitIgnoredExpr(const clang::Expr *e)
Emit code to compute the specified expression, ignoring the result.
LValue emitCompoundLiteralLValue(const CompoundLiteralExpr *e)
This class organizes the cross-function state that is used while generating CIR code.
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
Type for representing both the decl and type of parameters to a function.
Address getAddress() const
mlir::Value getPointer() const
mlir::Value getValue() const
Return the value of this scalar value.
Represents a C++ destructor within a class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
QualType getFunctionObjectParameterType() const
bool isAbstract() const
Determine whether this class has a pure virtual function.
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
CompoundStmt - This represents a group of statements like { stmt stmt }.
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Decl * getNonClosureContext()
Find the innermost non-closure ancestor of this declaration, walking up through blocks,...
SourceLocation getLocation() const
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Returns the set of floating point options that apply to this expression.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
LangOptions::FPExceptionModeKind getExceptionMode() const
RoundingMode getRoundingMode() const
Represents a function declaration or definition.
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
FunctionDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
GlobalDecl - represents a global declaration.
const Decl * getDecl() const
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
FPExceptionModeKind
Possible floating point exception behavior.
@ FPE_Default
Used internally to represent initial unspecified value.
@ FPE_Strict
Strictly preserve the floating-point exception semantics.
@ FPE_MayTrap
Transformations do not cause new exceptions but may hide some.
@ FPE_Ignore
Assume that floating-point exceptions are masked.
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
A (possibly-)qualified type.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
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.
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
const char * getStmtClassName() const
SourceLocation getBeginLoc() const LLVM_READONLY
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isAnyComplexType() const
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
Represents a variable declaration or definition.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Represents a C array with a specified size that is not an integer-constant-expression.
Expr * getSizeExpr() const
@ 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 ...
static bool previousOpIsNonYieldingCleanup(mlir::Block *block)
static std::string getVersionedTmpName(llvm::StringRef name, unsigned cnt)
static bool mayDropFunctionReturn(const ASTContext &astContext, QualType returnType)
static mlir::Value emitArgumentDemotion(CIRGenFunction &cgf, const VarDecl *var, mlir::Value value)
An argument came in as a promoted argument; demote it back to its declared type.
static void eraseEmptyAndUnusedBlocks(cir::FuncOp func)
static llvm::fp::ExceptionBehavior toConstrainedExceptMd(LangOptions::FPExceptionModeKind kind)
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
CXXCtorType
C++ constructor types.
@ Ctor_Base
Base object ctor.
@ Ctor_Complete
Complete object ctor.
bool isa(CodeGen::Address addr)
CXXDtorType
C++ destructor types.
@ Dtor_VectorDeleting
Vector deleting dtor.
@ Dtor_Comdat
The COMDAT used for dtors.
@ Dtor_Unified
GCC-style unified dtor.
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
U cast(CodeGen::Address addr)
static bool fastMathFuncAttributes()
static bool vtableInitialization()
static bool constructABIArgDirectExtend()
static bool runCleanupsScope()
static bool emitTypeCheck()
static bool fastMathGuard()
static bool fastMathFlags()
static bool generateDebugInfo()
static bool cleanupWithPreservedValues()
static bool incrementProfileCounter()
Represents a scope, including function bodies, compound statements, and the substatements of if/while...
llvm::ArrayRef< mlir::Block * > getRetBlocks()
LexicalScope(CIRGenFunction &cgf, mlir::Location loc, mlir::Block *eb)
mlir::Block * getCleanupBlock(mlir::OpBuilder &builder)
cir::TryOp getClosestTryParent()
mlir::Location getRetLoc(mlir::Block *b)
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.