18#include "mlir/IR/Location.h"
28 bool suppressNewContext)
39 switch (
type->getTypeClass()) {
40#define TYPE(name, parent)
41#define ABSTRACT_TYPE(name, parent)
42#define NON_CANONICAL_TYPE(name, parent) case Type::name:
43#define DEPENDENT_TYPE(name, parent) case Type::name:
44#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(name, parent) case Type::name:
45#include "clang/AST/TypeNodes.inc"
46 llvm_unreachable(
"non-canonical or dependent type in IR-generation");
49 case Type::DeducedTemplateSpecialization:
50 llvm_unreachable(
"undeduced type in IR-generation");
55 case Type::BlockPointer:
56 case Type::LValueReference:
57 case Type::RValueReference:
58 case Type::MemberPointer:
61 case Type::ConstantMatrix:
62 case Type::FunctionProto:
63 case Type::FunctionNoProto:
65 case Type::ObjCObjectPointer:
68 case Type::HLSLAttributedResource:
69 case Type::HLSLInlineSpirv:
77 case Type::ConstantArray:
78 case Type::IncompleteArray:
79 case Type::VariableArray:
81 case Type::ObjCObject:
82 case Type::ObjCInterface:
83 case Type::ArrayParameter:
91 llvm_unreachable(
"unknown type kind!");
96 return cgm.getTypes().convertTypeForMem(t);
100 return cgm.getTypes().convertType(t);
110 return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
114 assert(
currSrcLoc &&
"expected to inherit some source location");
125 mlir::Attribute metadata;
132 return builder.getUnknownLoc();
137 mlir::Attribute metadata;
164 ignoreCaseStmts =
true;
167 return std::any_of(
s->child_begin(),
s->child_end(),
168 [=](
const Stmt *subStmt) {
169 return containsLabel(subStmt, ignoreCaseStmts);
178 llvm::APSInt resultInt;
182 resultBool = resultInt.getBoolValue();
190 llvm::APSInt &resultInt,
198 llvm::APSInt intValue = result.
Val.
getInt();
202 resultInt = intValue;
206void CIRGenFunction::emitAndUpdateRetAlloca(
QualType type, mlir::Location loc,
208 if (!
type->isVoidType()) {
216void CIRGenFunction::declare(mlir::Value addrVal,
const Decl *var, QualType ty,
217 mlir::Location loc, CharUnits alignment,
220 assert(!
symbolTable.count(var) &&
"not supposed to be available just yet");
222 auto allocaOp = addrVal.getDefiningOp<cir::AllocaOp>();
223 assert(allocaOp &&
"expected cir::AllocaOp");
227 if (ty->isReferenceType() || ty.isConstQualified())
237 auto applyCleanup = [&]() {
252 for (mlir::Block *retBlock : localScope->
getRetBlocks()) {
253 mlir::OpBuilder::InsertionGuard guard(builder);
254 builder.setInsertionPointToEnd(retBlock);
255 retBlocks.push_back(retBlock);
256 mlir::Location retLoc = localScope->
getRetLoc(retBlock);
260 auto insertCleanupAndLeave = [&](mlir::Block *insPt) {
261 mlir::OpBuilder::InsertionGuard guard(builder);
262 builder.setInsertionPointToEnd(insPt);
274 cir::BrOp::create(builder, insPt->back().getLoc(), cleanupBlock);
275 if (!cleanupBlock->mightHaveTerminator()) {
276 mlir::OpBuilder::InsertionGuard guard(builder);
277 builder.setInsertionPointToEnd(cleanupBlock);
278 cir::YieldOp::create(builder, localScope->endLoc);
282 if (localScope->
depth == 0) {
287 mlir::Location retLoc = localScope->
getRetLoc(retBlock);
288 if (retBlock->getUses().empty()) {
293 for (mlir::BlockOperand &blockUse : retBlock->getUses()) {
294 cir::BrOp brOp = mlir::cast<cir::BrOp>(blockUse.getOwner());
295 brOp.setSuccessor(cleanupBlock);
299 cir::BrOp::create(builder, retLoc, retBlock);
303 emitImplicitReturn();
310 if (!localScope->
isTernary() && !insPt->mightHaveTerminator()) {
311 !retVal ? cir::YieldOp::create(builder, localScope->endLoc)
312 : cir::YieldOp::create(builder, localScope->endLoc, retVal);
322 insertCleanupAndLeave(cleanupBlock);
327 mlir::Block *curBlock = builder.getBlock();
330 if (curBlock->mightHaveTerminator() && curBlock->getTerminator())
334 bool entryBlock = builder.getInsertionBlock()->isEntryBlock();
335 if (!entryBlock && curBlock->empty()) {
337 for (mlir::Block *retBlock : retBlocks) {
338 if (retBlock->getUses().empty())
346 cir::BrOp::create(builder, curBlock->back().getLoc(), cleanupBlock);
351 insertCleanupAndLeave(curBlock);
354cir::ReturnOp CIRGenFunction::LexicalScope::emitReturn(mlir::Location loc) {
360 auto fn = dyn_cast<cir::FuncOp>(cgf.curFn);
361 assert(fn &&
"emitReturn from non-function");
362 if (!fn.getFunctionType().hasVoidReturn()) {
364 auto value = cir::LoadOp::create(
365 builder, loc, fn.getFunctionType().getReturnType(), *cgf.fnRetAlloca);
366 return cir::ReturnOp::create(builder, loc,
369 return cir::ReturnOp::create(builder, loc);
379 return classDecl->hasTrivialDestructor();
383void CIRGenFunction::LexicalScope::emitImplicitReturn() {
384 CIRGenBuilderTy &builder = cgf.getBuilder();
385 LexicalScope *localScope = cgf.curLexScope;
394 if (cgf.getLangOpts().CPlusPlus && !fd->hasImplicitReturnZero() &&
395 !cgf.sawAsmBlock && !fd->getReturnType()->isVoidType() &&
396 builder.getInsertionBlock()) {
397 bool shouldEmitUnreachable =
398 cgf.cgm.getCodeGenOpts().StrictReturn ||
401 if (shouldEmitUnreachable) {
403 if (cgf.cgm.getCodeGenOpts().OptimizationLevel == 0)
404 cir::TrapOp::create(builder, localScope->endLoc);
406 cir::UnreachableOp::create(builder, localScope->endLoc);
407 builder.clearInsertionPoint();
412 (void)emitReturn(localScope->endLoc);
420 scope = scope->parentScope;
426 cir::FuncOp fn, cir::FuncType funcType,
430 "CIRGenFunction can only be used for one function at a time");
438 const auto *fd = dyn_cast_or_null<FunctionDecl>(d);
443 mlir::Block *entryBB = &fn.getBlocks().front();
444 builder.setInsertionPointToStart(entryBB);
448 for (
const auto nameValue : llvm::zip(args, entryBB->getArguments())) {
449 const VarDecl *paramVar = std::get<0>(nameValue);
450 mlir::Value paramVal = std::get<1>(nameValue);
453 paramVal.setLoc(paramLoc);
455 mlir::Value addrVal =
460 declare(addrVal, paramVar, paramVar->
getType(), paramLoc, alignment,
469 cgm.errorNYI(fd->getSourceRange(),
"Function argument demotion");
473 mlir::Location fnBodyBegin =
getLoc(fd->getBody()->getBeginLoc());
474 builder.CIRBaseBuilderTy::createStore(fnBodyBegin, paramVal, addrVal);
476 assert(builder.getInsertionBlock() &&
"Should be valid");
481 emitAndUpdateRetAlloca(returnType,
getLoc(fd->getBody()->getEndLoc()),
482 getContext().getTypeAlignInChars(returnType));
484 if (isa_and_nonnull<CXXMethodDecl>(d) &&
486 cgm.getCXXABI().emitInstanceFunctionProlog(loc, *
this);
489 if (md->getParent()->isLambda() && md->getOverloadedOperator() == OO_Call) {
491 auto fn = dyn_cast<cir::FuncOp>(
curFn);
492 assert(fn &&
"lambda in non-function region");
518 for (
auto *fd : md->getParent()->fields()) {
519 if (fd->hasCapturedVLAType())
520 cgm.errorNYI(loc,
"lambda captured VLA type");
552 if (
const CompoundStmt *block = dyn_cast<CompoundStmt>(body))
563 for (mlir::Block &block : func.getBlocks()) {
564 if (block.empty() && block.getUses().empty())
565 blocksToDelete.push_back(&block);
567 for (mlir::Block *block : blocksToDelete)
572 cir::FuncType funcType) {
576 if (funcDecl->isInlineBuiltinDeclaration()) {
580 std::string fdInlineName = (
cgm.getMangledName(funcDecl) +
".inline").str();
582 mlir::cast_or_null<cir::FuncOp>(
cgm.getGlobalValue(fdInlineName));
584 mlir::OpBuilder::InsertionGuard guard(builder);
585 builder.setInsertionPoint(fn);
586 clone = cir::FuncOp::create(builder, fn.getLoc(), fdInlineName,
587 fn.getFunctionType());
588 clone.setLinkage(cir::GlobalLinkageKind::InternalLinkage);
589 clone.setSymVisibility(
"private");
590 clone.setInlineKind(cir::InlineKind::AlwaysInline);
592 fn.setLinkage(cir::GlobalLinkageKind::ExternalLinkage);
593 fn.setSymVisibility(
"private");
601 if (LLVM_UNLIKELY(pd->isInlineBuiltinDeclaration())) {
602 std::string inlineName = funcDecl->getName().str() +
".inline";
603 if (
auto inlineFn = mlir::cast_or_null<cir::FuncOp>(
604 cgm.getGlobalValue(inlineName))) {
609 .replaceAllSymbolUses(fn.getSymNameAttr(),
cgm.getModule())
611 llvm_unreachable(
"Failed to replace inline builtin symbol uses");
620 Stmt *body = funcDecl->getBody();
625 : builder.getUnknownLoc()};
628 return clangLoc.isValid() ?
getLoc(clangLoc) : builder.getUnknownLoc();
630 const mlir::Location fusedLoc = mlir::FusedLoc::get(
632 {validMLIRLoc(bodyRange.
getBegin()), validMLIRLoc(bodyRange.
getEnd())});
633 mlir::Block *entryBB = fn.addEntryBlock();
647 if (body && isa_and_nonnull<CoroutineBodyStmt>(body))
648 llvm::append_range(
fnArgs, funcDecl->parameters());
655 funcDecl->hasAttr<CUDAGlobalAttr>()) {
676 llvm_unreachable(
"no definition for normal function");
679 if (mlir::failed(fn.verifyBody()))
694 assert((
cgm.getTarget().getCXXABI().hasConstructorVariants() ||
696 "can only generate complete ctor for this ABI");
701 cgm.getTarget().getCXXABI().hasConstructorVariants()) {
707 Stmt *body = ctor->getBody(definition);
708 assert(definition == ctor &&
"emitting wrong constructor body");
710 if (isa_and_nonnull<CXXTryStmt>(body)) {
711 cgm.errorNYI(ctor->getSourceRange(),
"emitConstructorBody: try body");
726 if (mlir::failed(
emitStmt(body,
true))) {
727 cgm.errorNYI(ctor->getSourceRange(),
728 "emitConstructorBody: emit body statement failed.");
770 const bool isTryBody = isa_and_nonnull<CXXTryStmt>(body);
786 llvm_unreachable(
"not expecting a unified dtor");
788 llvm_unreachable(
"not expecting a COMDAT");
790 llvm_unreachable(
"already handled deleting case");
793 assert((body ||
getTarget().getCXXABI().isMicrosoft()) &&
794 "can't emit a dtor without a body for non-Microsoft ABIs");
822 assert(dtor->
isImplicit() &&
"bodyless dtor not implicit");
848 CharUnits align =
cgm.getNaturalTypeAlignment(ty, &baseInfo);
855 CharUnits alignment =
cgm.getNaturalTypeAlignment(ty, &baseInfo);
864 QualType retTy = fd->getReturnType();
866 const auto *md = dyn_cast<CXXMethodDecl>(fd);
867 if (md && md->isInstance()) {
868 if (
cgm.getCXXABI().hasThisReturn(gd))
869 cgm.errorNYI(fd->getSourceRange(),
"this return");
870 else if (
cgm.getCXXABI().hasMostDerivedReturn(gd))
871 cgm.errorNYI(fd->getSourceRange(),
"most derived return");
872 cgm.getCXXABI().buildThisParam(*
this, args);
875 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(fd))
876 if (cd->getInheritedConstructor())
877 cgm.errorNYI(fd->getSourceRange(),
878 "buildFunctionArgList: inherited constructor");
880 for (
auto *param : fd->parameters())
881 args.push_back(param);
884 cgm.getCXXABI().addImplicitStructorParams(*
this, retTy, args);
897 std::string(
"l-value not implemented for '") +
900 case Expr::ConditionalOperatorClass:
902 case Expr::BinaryConditionalOperatorClass:
904 case Expr::ArraySubscriptExprClass:
906 case Expr::ExtVectorElementExprClass:
908 case Expr::UnaryOperatorClass:
910 case Expr::StringLiteralClass:
912 case Expr::MemberExprClass:
914 case Expr::CompoundLiteralExprClass:
916 case Expr::PredefinedExprClass:
918 case Expr::BinaryOperatorClass:
920 case Expr::CompoundAssignOperatorClass: {
924 "CompoundAssignOperator with AtomicType");
932 case Expr::CallExprClass:
933 case Expr::CXXMemberCallExprClass:
934 case Expr::CXXOperatorCallExprClass:
935 case Expr::UserDefinedLiteralClass:
937 case Expr::ExprWithCleanupsClass: {
944 case Expr::CXXDefaultArgExprClass: {
949 case Expr::ParenExprClass:
951 case Expr::GenericSelectionExprClass:
953 case Expr::DeclRefExprClass:
955 case Expr::CStyleCastExprClass:
956 case Expr::CXXStaticCastExprClass:
957 case Expr::CXXDynamicCastExprClass:
958 case Expr::ImplicitCastExprClass:
960 case Expr::MaterializeTemporaryExprClass:
962 case Expr::OpaqueValueExprClass:
964 case Expr::ChooseExprClass:
971 llvm::raw_svector_ostream
out(buffer);
973 return std::string(
out.str());
993 cgm.errorNYI(loc,
"Cast the dest ptr to the appropriate i8 pointer type");
1002 "emitNullInitialization for zero size VariableArrayType");
1012 if (!
cgm.getTypes().isZeroInitializable(ty)) {
1013 cgm.errorNYI(loc,
"type is not zero initializable");
1020 const mlir::Value zeroValue = builder.getNullValue(
convertType(ty), loc);
1021 builder.createStore(loc, zeroValue, destPtr);
1028 if (ce->
getCastKind() == CK_UncheckedDerivedToBase)
1038 if (ice->isGLValue())
1060 uint64_t countFromCLAs = 1;
1063 auto cirArrayType = mlir::dyn_cast<cir::ArrayType>(addr.
getElementType());
1065 while (cirArrayType) {
1067 countFromCLAs *= cirArrayType.getSize();
1071 mlir::dyn_cast<cir::ArrayType>(cirArrayType.getElementType());
1075 "CIR and Clang types are out-of-sync");
1082 cgm.errorNYI(*
currSrcLoc,
"length for non-array underlying types");
1091 SourceLocation assumptionLoc, int64_t alignment, mlir::Value offsetValue) {
1093 return cir::AssumeAlignedOp::create(builder,
getLoc(assumptionLoc), ptrValue,
1094 alignment, offsetValue);
1099 int64_t alignment, mlir::Value offsetValue) {
1108 cgm.getASTContext().getAsVariableArrayType(
type);
1109 assert(vla &&
"type was not a variable array type!");
1116 mlir::Value numElements;
1120 elementType =
type->getElementType();
1122 assert(vlaSize &&
"no size for VLA!");
1123 assert(vlaSize.getType() ==
sizeTy);
1126 numElements = vlaSize;
1132 builder.createMul(numElements.getLoc(), numElements, vlaSize,
1135 }
while ((
type =
getContext().getAsVariableArrayType(elementType)));
1137 assert(numElements &&
"Undefined elements number");
1138 return {numElements, elementType};
1144 assert(
type->isVariablyModifiedType() &&
1145 "Must pass variably modified type to EmitVLASizes!");
1150 assert(
type->isVariablyModifiedType());
1152 const Type *ty =
type.getTypePtr();
1154 case Type::CountAttributed:
1155 case Type::PackIndexing:
1156 case Type::ArrayParameter:
1157 case Type::HLSLAttributedResource:
1158 case Type::HLSLInlineSpirv:
1159 case Type::PredefinedSugar:
1160 cgm.errorNYI(
"CIRGenFunction::emitVariablyModifiedType");
1163#define TYPE(Class, Base)
1164#define ABSTRACT_TYPE(Class, Base)
1165#define NON_CANONICAL_TYPE(Class, Base)
1166#define DEPENDENT_TYPE(Class, Base) case Type::Class:
1167#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)
1168#include "clang/AST/TypeNodes.inc"
1170 "dependent type must be resolved before the CIR codegen");
1176 case Type::ExtVector:
1177 case Type::ConstantMatrix:
1181 case Type::TemplateSpecialization:
1182 case Type::ObjCTypeParam:
1183 case Type::ObjCObject:
1184 case Type::ObjCInterface:
1185 case Type::ObjCObjectPointer:
1187 llvm_unreachable(
"type class is never variably-modified!");
1189 case Type::Adjusted:
1201 case Type::BlockPointer:
1205 case Type::LValueReference:
1206 case Type::RValueReference:
1210 case Type::MemberPointer:
1214 case Type::ConstantArray:
1215 case Type::IncompleteArray:
1220 case Type::VariableArray: {
1237 entry = builder.createIntCast(size,
sizeTy);
1244 case Type::FunctionProto:
1245 case Type::FunctionNoProto:
1251 case Type::UnaryTransform:
1252 case Type::Attributed:
1253 case Type::BTFTagAttributed:
1254 case Type::SubstTemplateTypeParm:
1255 case Type::MacroQualified:
1261 case Type::Decltype:
1263 case Type::DeducedTemplateSpecialization:
1267 case Type::TypeOfExpr:
1280 }
while (
type->isVariablyModifiedType());
1284 if (
getContext().getBuiltinVaListType()->isArrayType())
Defines the clang::Expr interface and subclasses for C++ expressions.
__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
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
void forceCleanup()
Force the emission of cleanups now, instead of waiting until this object is destroyed.
static bool isConstructorDelegationValid(const clang::CXXConstructorDecl *ctor)
Checks whether the given constructor is a valid subject for the complete-to-base constructor delegati...
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
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)
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::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.
LValue emitStringLiteralLValue(const StringLiteral *e, llvm::StringRef name=".str")
mlir::Value emitScalarExpr(const clang::Expr *e, bool ignoreResultAssign=false)
Emit the computation of the specified expression of scalar type.
bool shouldNullCheckClassCastValue(const CastExpr *ce)
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.
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)
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={})
void popCleanupBlocks(EHScopeStack::stable_iterator oldCleanupStackDepth)
Takes the old cleanup stack size and emits the cleanup blocks that have been added.
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,...
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,...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
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.
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 ...
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
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 std::string getVersionedTmpName(llvm::StringRef name, unsigned cnt)
static bool mayDropFunctionReturn(const ASTContext &astContext, QualType returnType)
static void eraseEmptyAndUnusedBlocks(cir::FuncOp func)
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_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 vtableInitialization()
static bool constructABIArgDirectExtend()
static bool coroEndBuiltinCall()
static bool runCleanupsScope()
static bool emitTypeCheck()
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.