18#include "mlir/IR/Location.h"
29 bool suppressNewContext)
40 switch (
type->getTypeClass()) {
41#define TYPE(name, parent)
42#define ABSTRACT_TYPE(name, parent)
43#define NON_CANONICAL_TYPE(name, parent) case Type::name:
44#define DEPENDENT_TYPE(name, parent) case Type::name:
45#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(name, parent) case Type::name:
46#include "clang/AST/TypeNodes.inc"
47 llvm_unreachable(
"non-canonical or dependent type in IR-generation");
50 case Type::DeducedTemplateSpecialization:
51 llvm_unreachable(
"undeduced type in IR-generation");
56 case Type::BlockPointer:
57 case Type::LValueReference:
58 case Type::RValueReference:
59 case Type::MemberPointer:
62 case Type::ConstantMatrix:
63 case Type::FunctionProto:
64 case Type::FunctionNoProto:
66 case Type::ObjCObjectPointer:
69 case Type::HLSLAttributedResource:
70 case Type::HLSLInlineSpirv:
78 case Type::ConstantArray:
79 case Type::IncompleteArray:
80 case Type::VariableArray:
82 case Type::ObjCObject:
83 case Type::ObjCInterface:
84 case Type::ArrayParameter:
92 llvm_unreachable(
"unknown type kind!");
97 return cgm.getTypes().convertTypeForMem(t);
101 return cgm.getTypes().convertType(t);
111 return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
115 assert(
currSrcLoc &&
"expected to inherit some source location");
126 mlir::Attribute metadata;
133 return builder.getUnknownLoc();
138 mlir::Attribute metadata;
165 ignoreCaseStmts =
true;
168 return std::any_of(
s->child_begin(),
s->child_end(),
169 [=](
const Stmt *subStmt) {
170 return containsLabel(subStmt, ignoreCaseStmts);
179 llvm::APSInt resultInt;
183 resultBool = resultInt.getBoolValue();
191 llvm::APSInt &resultInt,
199 llvm::APSInt intValue = result.
Val.
getInt();
203 resultInt = intValue;
207void CIRGenFunction::emitAndUpdateRetAlloca(
QualType type, mlir::Location loc,
209 if (!
type->isVoidType()) {
217void CIRGenFunction::declare(mlir::Value addrVal,
const Decl *var, QualType ty,
218 mlir::Location loc, CharUnits alignment,
221 assert(!
symbolTable.count(var) &&
"not supposed to be available just yet");
223 auto allocaOp = addrVal.getDefiningOp<cir::AllocaOp>();
224 assert(allocaOp &&
"expected cir::AllocaOp");
228 if (ty->isReferenceType() || ty.isConstQualified())
238 auto applyCleanup = [&]() {
253 for (mlir::Block *retBlock : localScope->
getRetBlocks()) {
254 mlir::OpBuilder::InsertionGuard guard(builder);
255 builder.setInsertionPointToEnd(retBlock);
256 retBlocks.push_back(retBlock);
257 mlir::Location retLoc = localScope->
getRetLoc(retBlock);
261 auto insertCleanupAndLeave = [&](mlir::Block *insPt) {
262 mlir::OpBuilder::InsertionGuard guard(builder);
263 builder.setInsertionPointToEnd(insPt);
275 cir::BrOp::create(builder, insPt->back().getLoc(), cleanupBlock);
276 if (!cleanupBlock->mightHaveTerminator()) {
277 mlir::OpBuilder::InsertionGuard guard(builder);
278 builder.setInsertionPointToEnd(cleanupBlock);
279 cir::YieldOp::create(builder, localScope->endLoc);
283 if (localScope->
depth == 0) {
288 mlir::Location retLoc = localScope->
getRetLoc(retBlock);
289 if (retBlock->getUses().empty()) {
294 for (mlir::BlockOperand &blockUse : retBlock->getUses()) {
295 cir::BrOp brOp = mlir::cast<cir::BrOp>(blockUse.getOwner());
296 brOp.setSuccessor(cleanupBlock);
300 cir::BrOp::create(builder, retLoc, retBlock);
304 emitImplicitReturn();
311 if (!localScope->
isTernary() && !insPt->mightHaveTerminator()) {
312 !retVal ? cir::YieldOp::create(builder, localScope->endLoc)
313 : cir::YieldOp::create(builder, localScope->endLoc, retVal);
323 insertCleanupAndLeave(cleanupBlock);
328 mlir::Block *curBlock = builder.getBlock();
331 if (curBlock->mightHaveTerminator() && curBlock->getTerminator())
335 bool entryBlock = builder.getInsertionBlock()->isEntryBlock();
336 if (!entryBlock && curBlock->empty()) {
338 for (mlir::Block *retBlock : retBlocks) {
339 if (retBlock->getUses().empty())
347 cir::BrOp::create(builder, curBlock->back().getLoc(), cleanupBlock);
352 insertCleanupAndLeave(curBlock);
355cir::ReturnOp CIRGenFunction::LexicalScope::emitReturn(mlir::Location loc) {
358 auto fn = dyn_cast<cir::FuncOp>(cgf.curFn);
359 assert(fn &&
"emitReturn from non-function");
362 if (fn.getCoroutine())
363 cgf.emitCoroEndBuiltinCall(loc,
364 builder.getNullPtr(builder.getVoidPtrTy(), loc));
365 if (!fn.getFunctionType().hasVoidReturn()) {
367 auto value = cir::LoadOp::create(
368 builder, loc, fn.getFunctionType().getReturnType(), *cgf.fnRetAlloca);
369 return cir::ReturnOp::create(builder, loc,
372 return cir::ReturnOp::create(builder, loc);
382 return classDecl->hasTrivialDestructor();
386void CIRGenFunction::LexicalScope::emitImplicitReturn() {
387 CIRGenBuilderTy &builder = cgf.getBuilder();
388 LexicalScope *localScope = cgf.curLexScope;
397 if (cgf.getLangOpts().CPlusPlus && !fd->hasImplicitReturnZero() &&
398 !cgf.sawAsmBlock && !fd->getReturnType()->isVoidType() &&
399 builder.getInsertionBlock()) {
400 bool shouldEmitUnreachable =
401 cgf.cgm.getCodeGenOpts().StrictReturn ||
404 if (shouldEmitUnreachable) {
406 if (cgf.cgm.getCodeGenOpts().OptimizationLevel == 0)
407 cir::TrapOp::create(builder, localScope->endLoc);
409 cir::UnreachableOp::create(builder, localScope->endLoc);
410 builder.clearInsertionPoint();
415 (void)emitReturn(localScope->endLoc);
423 scope = scope->parentScope;
436 if (value.getType() == ty)
439 assert((mlir::isa<cir::IntType>(ty) || cir::isAnyFloatingPointType(ty)) &&
440 "unexpected promotion type");
442 if (mlir::isa<cir::IntType>(ty))
443 return cgf.
getBuilder().CIRBaseBuilderTy::createIntCast(value, ty);
449 mlir::Block *entryBB,
453 if (fd && fd->
hasAttr<NakedAttr>()) {
454 cgm.errorNYI(bodyBeginLoc,
"naked function decl");
458 for (
const auto nameValue : llvm::zip(args, entryBB->getArguments())) {
459 const VarDecl *paramVar = std::get<0>(nameValue);
460 mlir::Value paramVal = std::get<1>(nameValue);
463 paramVal.setLoc(paramLoc);
465 mlir::Value addrVal =
470 declare(addrVal, paramVar, paramVar->
getType(), paramLoc, alignment,
483 mlir::Location fnBodyBegin =
getLoc(bodyBeginLoc);
484 builder.CIRBaseBuilderTy::createStore(fnBodyBegin, paramVal, addrVal);
486 assert(builder.getInsertionBlock() &&
"Should be valid");
490 cir::FuncOp fn, cir::FuncType funcType,
494 "CIRGenFunction can only be used for one function at a time");
502 const auto *fd = dyn_cast_or_null<FunctionDecl>(d);
507 mlir::Block *entryBB = &fn.getBlocks().front();
508 builder.setInsertionPointToStart(entryBB);
514 if (
Stmt *body = fd->getBody())
515 bodyBeginLoc = body->getBeginLoc();
517 bodyBeginLoc = fd->getLocation();
529 if (
Stmt *body = fd->getBody())
530 bodyEndLoc = body->getEndLoc();
532 bodyEndLoc = fd->getLocation();
534 emitAndUpdateRetAlloca(returnType,
getLoc(bodyEndLoc),
535 getContext().getTypeAlignInChars(returnType));
538 if (isa_and_nonnull<CXXMethodDecl>(d) &&
540 cgm.getCXXABI().emitInstanceFunctionProlog(loc, *
this);
543 if (md->getParent()->isLambda() && md->getOverloadedOperator() == OO_Call) {
545 auto fn = dyn_cast<cir::FuncOp>(
curFn);
546 assert(fn &&
"lambda in non-function region");
572 for (
auto *fd : md->getParent()->fields()) {
573 if (fd->hasCapturedVLAType())
574 cgm.errorNYI(loc,
"lambda captured VLA type");
589 for (cir::BlockAddressOp &blockAddress :
cgm.unresolvedBlockAddressToLabel) {
590 cir::LabelOp labelOp =
591 cgm.lookupBlockAddressInfo(blockAddress.getBlockAddrInfo());
592 assert(labelOp &&
"expected cir.labelOp to already be emitted");
593 cgm.updateResolvedBlockAddress(blockAddress, labelOp);
595 cgm.unresolvedBlockAddressToLabel.clear();
603 mlir::OpBuilder::InsertionGuard guard(builder);
605 for (
auto &[blockAdd, labelOp] :
cgm.blockAddressToLabel) {
606 succesors.push_back(labelOp->getBlock());
607 rangeOperands.push_back(labelOp->getBlock()->getArguments());
609 cir::IndirectBrOp::create(builder, builder.getUnknownLoc(),
611 rangeOperands, succesors);
612 cgm.blockAddressToLabel.clear();
627 indrBr.setPoison(
true);
647 if (
const CompoundStmt *block = dyn_cast<CompoundStmt>(body))
658 for (mlir::Block &block : func.getBlocks()) {
659 if (block.empty() && block.getUses().empty())
660 blocksToDelete.push_back(&block);
662 for (mlir::Block *block : blocksToDelete)
667 cir::FuncType funcType) {
671 if (funcDecl->isInlineBuiltinDeclaration()) {
675 std::string fdInlineName = (
cgm.getMangledName(funcDecl) +
".inline").str();
677 mlir::cast_or_null<cir::FuncOp>(
cgm.getGlobalValue(fdInlineName));
679 mlir::OpBuilder::InsertionGuard guard(builder);
680 builder.setInsertionPoint(fn);
681 clone = cir::FuncOp::create(builder, fn.getLoc(), fdInlineName,
682 fn.getFunctionType());
683 clone.setLinkage(cir::GlobalLinkageKind::InternalLinkage);
684 clone.setSymVisibility(
"private");
685 clone.setInlineKind(cir::InlineKind::AlwaysInline);
687 fn.setLinkage(cir::GlobalLinkageKind::ExternalLinkage);
688 fn.setSymVisibility(
"private");
696 if (LLVM_UNLIKELY(pd->isInlineBuiltinDeclaration())) {
697 std::string inlineName = funcDecl->getName().str() +
".inline";
698 if (
auto inlineFn = mlir::cast_or_null<cir::FuncOp>(
699 cgm.getGlobalValue(inlineName))) {
704 .replaceAllSymbolUses(fn.getSymNameAttr(),
cgm.getModule())
706 llvm_unreachable(
"Failed to replace inline builtin symbol uses");
715 Stmt *body = funcDecl->getBody();
720 : builder.getUnknownLoc()};
723 return clangLoc.isValid() ?
getLoc(clangLoc) : builder.getUnknownLoc();
725 const mlir::Location fusedLoc = mlir::FusedLoc::get(
727 {validMLIRLoc(bodyRange.
getBegin()), validMLIRLoc(bodyRange.
getEnd())});
728 mlir::Block *entryBB = fn.addEntryBlock();
742 if (body && isa_and_nonnull<CoroutineBodyStmt>(body))
743 llvm::append_range(
fnArgs, funcDecl->parameters());
750 funcDecl->hasAttr<CUDAGlobalAttr>()) {
771 llvm_unreachable(
"no definition for normal function");
774 if (mlir::failed(fn.verifyBody()))
789 assert((
cgm.getTarget().getCXXABI().hasConstructorVariants() ||
791 "can only generate complete ctor for this ABI");
796 cgm.getTarget().getCXXABI().hasConstructorVariants()) {
802 Stmt *body = ctor->getBody(definition);
803 assert(definition == ctor &&
"emitting wrong constructor body");
805 if (isa_and_nonnull<CXXTryStmt>(body)) {
806 cgm.errorNYI(ctor->getSourceRange(),
"emitConstructorBody: try body");
821 if (mlir::failed(
emitStmt(body,
true))) {
822 cgm.errorNYI(ctor->getSourceRange(),
823 "emitConstructorBody: emit body statement failed.");
867 const bool isTryBody = isa_and_nonnull<CXXTryStmt>(body);
883 llvm_unreachable(
"not expecting a unified dtor");
885 llvm_unreachable(
"not expecting a COMDAT");
888 llvm_unreachable(
"already handled deleting case");
891 assert((body ||
getTarget().getCXXABI().isMicrosoft()) &&
892 "can't emit a dtor without a body for non-Microsoft ABIs");
920 assert(dtor->
isImplicit() &&
"bodyless dtor not implicit");
946 CharUnits align =
cgm.getNaturalTypeAlignment(ty, &baseInfo);
953 CharUnits alignment =
cgm.getNaturalTypeAlignment(ty, &baseInfo);
962 QualType retTy = fd->getReturnType();
964 const auto *md = dyn_cast<CXXMethodDecl>(fd);
965 if (md && md->isInstance()) {
966 if (
cgm.getCXXABI().hasThisReturn(gd))
967 cgm.errorNYI(fd->getSourceRange(),
"this return");
968 else if (
cgm.getCXXABI().hasMostDerivedReturn(gd))
969 cgm.errorNYI(fd->getSourceRange(),
"most derived return");
970 cgm.getCXXABI().buildThisParam(*
this, args);
973 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(fd))
974 if (cd->getInheritedConstructor())
975 cgm.errorNYI(fd->getSourceRange(),
976 "buildFunctionArgList: inherited constructor");
978 for (
auto *param : fd->parameters())
979 args.push_back(param);
982 cgm.getCXXABI().addImplicitStructorParams(*
this, retTy, args);
995 std::string(
"l-value not implemented for '") +
998 case Expr::ConditionalOperatorClass:
1000 case Expr::BinaryConditionalOperatorClass:
1002 case Expr::ArraySubscriptExprClass:
1004 case Expr::ExtVectorElementExprClass:
1006 case Expr::UnaryOperatorClass:
1008 case Expr::StringLiteralClass:
1010 case Expr::MemberExprClass:
1012 case Expr::CompoundLiteralExprClass:
1014 case Expr::PredefinedExprClass:
1016 case Expr::BinaryOperatorClass:
1018 case Expr::CompoundAssignOperatorClass: {
1022 "CompoundAssignOperator with AtomicType");
1030 case Expr::CallExprClass:
1031 case Expr::CXXMemberCallExprClass:
1032 case Expr::CXXOperatorCallExprClass:
1033 case Expr::UserDefinedLiteralClass:
1035 case Expr::ExprWithCleanupsClass: {
1042 case Expr::CXXDefaultArgExprClass: {
1047 case Expr::ParenExprClass:
1049 case Expr::GenericSelectionExprClass:
1051 case Expr::DeclRefExprClass:
1053 case Expr::CStyleCastExprClass:
1054 case Expr::CXXStaticCastExprClass:
1055 case Expr::CXXDynamicCastExprClass:
1056 case Expr::ImplicitCastExprClass:
1058 case Expr::MaterializeTemporaryExprClass:
1060 case Expr::OpaqueValueExprClass:
1062 case Expr::ChooseExprClass:
1069 llvm::raw_svector_ostream
out(buffer);
1071 return std::string(
out.str());
1091 cgm.errorNYI(loc,
"Cast the dest ptr to the appropriate i8 pointer type");
1100 "emitNullInitialization for zero size VariableArrayType");
1110 if (!
cgm.getTypes().isZeroInitializable(ty)) {
1111 cgm.errorNYI(loc,
"type is not zero initializable");
1118 const mlir::Value zeroValue = builder.getNullValue(
convertType(ty), loc);
1119 builder.createStore(loc, zeroValue, destPtr);
1126 if (ce->
getCastKind() == CK_UncheckedDerivedToBase)
1136 if (ice->isGLValue())
1158 uint64_t countFromCLAs = 1;
1161 auto cirArrayType = mlir::dyn_cast<cir::ArrayType>(addr.
getElementType());
1163 while (cirArrayType) {
1165 countFromCLAs *= cirArrayType.getSize();
1169 mlir::dyn_cast<cir::ArrayType>(cirArrayType.getElementType());
1173 "CIR and Clang types are out-of-sync");
1180 cgm.errorNYI(*
currSrcLoc,
"length for non-array underlying types");
1192 mlir::OpBuilder::InsertionGuard guard(builder);
1194 builder.createBlock(builder.getBlock()->getParent(), {}, {voidPtrTy},
1195 {builder.getUnknownLoc()});
1200 SourceLocation assumptionLoc, int64_t alignment, mlir::Value offsetValue) {
1202 return cir::AssumeAlignedOp::create(builder,
getLoc(assumptionLoc), ptrValue,
1203 alignment, offsetValue);
1208 int64_t alignment, mlir::Value offsetValue) {
1217 cgm.getASTContext().getAsVariableArrayType(
type);
1218 assert(vla &&
"type was not a variable array type!");
1225 mlir::Value numElements;
1229 elementType =
type->getElementType();
1231 assert(vlaSize &&
"no size for VLA!");
1232 assert(vlaSize.getType() ==
sizeTy);
1235 numElements = vlaSize;
1241 builder.createMul(numElements.getLoc(), numElements, vlaSize,
1244 }
while ((
type =
getContext().getAsVariableArrayType(elementType)));
1246 assert(numElements &&
"Undefined elements number");
1247 return {numElements, elementType};
1253 assert(vlaSize &&
"no size for VLA!");
1254 assert(vlaSize.getType() ==
sizeTy);
1261 assert(
type->isVariablyModifiedType() &&
1262 "Must pass variably modified type to EmitVLASizes!");
1267 assert(
type->isVariablyModifiedType());
1269 const Type *ty =
type.getTypePtr();
1271 case Type::CountAttributed:
1272 case Type::PackIndexing:
1273 case Type::ArrayParameter:
1274 case Type::HLSLAttributedResource:
1275 case Type::HLSLInlineSpirv:
1276 case Type::PredefinedSugar:
1277 cgm.errorNYI(
"CIRGenFunction::emitVariablyModifiedType");
1280#define TYPE(Class, Base)
1281#define ABSTRACT_TYPE(Class, Base)
1282#define NON_CANONICAL_TYPE(Class, Base)
1283#define DEPENDENT_TYPE(Class, Base) case Type::Class:
1284#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)
1285#include "clang/AST/TypeNodes.inc"
1287 "dependent type must be resolved before the CIR codegen");
1293 case Type::ExtVector:
1294 case Type::ConstantMatrix:
1298 case Type::TemplateSpecialization:
1299 case Type::ObjCTypeParam:
1300 case Type::ObjCObject:
1301 case Type::ObjCInterface:
1302 case Type::ObjCObjectPointer:
1304 llvm_unreachable(
"type class is never variably-modified!");
1306 case Type::Adjusted:
1318 case Type::BlockPointer:
1322 case Type::LValueReference:
1323 case Type::RValueReference:
1327 case Type::MemberPointer:
1331 case Type::ConstantArray:
1332 case Type::IncompleteArray:
1337 case Type::VariableArray: {
1354 entry = builder.createIntCast(size,
sizeTy);
1361 case Type::FunctionProto:
1362 case Type::FunctionNoProto:
1368 case Type::UnaryTransform:
1369 case Type::Attributed:
1370 case Type::BTFTagAttributed:
1371 case Type::SubstTemplateTypeParm:
1372 case Type::MacroQualified:
1378 case Type::Decltype:
1380 case Type::DeducedTemplateSpecialization:
1384 case Type::TypeOfExpr:
1397 }
while (
type->isVariablyModifiedType());
1401 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
mlir::Value createFloatingCast(mlir::Value v, mlir::Type destType)
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...
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
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.
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.
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={})
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 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)
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 vtableInitialization()
static bool constructABIArgDirectExtend()
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.