18#include "mlir/IR/Location.h"
26#include "llvm/ADT/ScopeExit.h"
27#include "llvm/IR/FPEnv.h"
48 bool suppressNewContext)
60 cir::FastMathFlags flags = cir::FastMathFlags::none;
61 if (fpFeatures.getAllowFPReassociate())
62 flags = flags | cir::FastMathFlags::reassoc;
63 if (fpFeatures.getNoHonorNaNs())
64 flags = flags | cir::FastMathFlags::nnan;
65 if (fpFeatures.getNoHonorInfs())
66 flags = flags | cir::FastMathFlags::ninf;
67 if (fpFeatures.getNoSignedZero())
68 flags = flags | cir::FastMathFlags::nsz;
69 if (fpFeatures.getAllowReciprocal())
70 flags = flags | cir::FastMathFlags::arcp;
71 if (fpFeatures.getAllowApproxFunc())
72 flags = flags | cir::FastMathFlags::afn;
74 flags = flags | cir::FastMathFlags::contract;
75 builder.setFastMathFlags(flags);
82 switch (
type->getTypeClass()) {
83#define TYPE(name, parent)
84#define ABSTRACT_TYPE(name, parent)
85#define NON_CANONICAL_TYPE(name, parent) case Type::name:
86#define DEPENDENT_TYPE(name, parent) case Type::name:
87#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(name, parent) case Type::name:
88#include "clang/AST/TypeNodes.inc"
89 llvm_unreachable(
"non-canonical or dependent type in IR-generation");
92 case Type::DeducedTemplateSpecialization:
93 llvm_unreachable(
"undeduced type in IR-generation");
98 case Type::BlockPointer:
99 case Type::LValueReference:
100 case Type::RValueReference:
101 case Type::MemberPointer:
103 case Type::ExtVector:
104 case Type::ConstantMatrix:
105 case Type::FunctionProto:
106 case Type::FunctionNoProto:
108 case Type::ObjCObjectPointer:
111 case Type::OverflowBehavior:
112 case Type::HLSLAttributedResource:
113 case Type::HLSLInlineSpirv:
121 case Type::ConstantArray:
122 case Type::IncompleteArray:
123 case Type::VariableArray:
125 case Type::ObjCObject:
126 case Type::ObjCInterface:
127 case Type::ArrayParameter:
135 llvm_unreachable(
"unknown type kind!");
140 return cgm.getTypes().convertTypeForMem(t);
144 return cgm.getTypes().convertType(t);
154 return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
163 return builder.getUnknownLoc();
188 return builder.getUnknownLoc();
193 mlir::Attribute metadata;
220 ignoreCaseStmts =
true;
224 [=](
const Stmt *subStmt) {
225 return containsLabel(subStmt, ignoreCaseStmts);
234 llvm::APSInt resultInt;
238 resultBool = resultInt.getBoolValue();
246 llvm::APSInt &resultInt,
254 llvm::APSInt intValue = result.
Val.
getInt();
258 resultInt = intValue;
262void CIRGenFunction::emitAndUpdateRetAlloca(
QualType type, mlir::Location loc,
264 if (!
type->isVoidType()) {
271void CIRGenFunction::declare(mlir::Value addrVal,
const Decl *var, QualType ty,
272 mlir::Location loc, CharUnits alignment,
275 assert(!
symbolTable.count(var) &&
"not supposed to be available just yet");
277 Address addr(addrVal, alignment);
278 cir::AllocaOp allocaOp = addr.getUnderlyingAllocaOp();
279 assert(allocaOp &&
"expected cir::AllocaOp");
283 if (ty->isReferenceType() || ty.isConstQualified())
299 for (mlir::Block *retBlock : localScope->
getRetBlocks()) {
300 mlir::OpBuilder::InsertionGuard guard(builder);
301 builder.setInsertionPointToEnd(retBlock);
302 retBlocks.push_back(retBlock);
303 mlir::Location retLoc = localScope->
getRetLoc(retBlock);
315 mlir::Block *curBlock = builder.getBlock();
318 if (curBlock->mightHaveTerminator() && curBlock->getTerminator())
324 bool isEntryBlock = builder.getInsertionBlock()->isEntryBlock();
325 if (!isEntryBlock && curBlock->empty()) {
327 for (mlir::Block *retBlock : retBlocks) {
328 if (retBlock->getUses().empty())
334 if (localScope->
depth == 0) {
338 mlir::Location retLoc = localScope->
getRetLoc(retBlock);
339 if (retBlock->getUses().empty()) {
342 cir::BrOp::create(builder, retLoc, retBlock);
346 emitImplicitReturn();
353 if (!localScope->
isTernary() && !curBlock->mightHaveTerminator()) {
354 !retVal ? cir::YieldOp::create(builder, localScope->endLoc)
355 : cir::YieldOp::create(builder, localScope->endLoc, retVal);
359cir::ReturnOp CIRGenFunction::LexicalScope::emitReturn(mlir::Location loc) {
362 auto fn = dyn_cast<cir::FuncOp>(cgf.curFn);
363 assert(fn &&
"emitReturn from non-function");
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();
389 mlir::Operation *op = &block->back();
390 auto cleanupScopeOp = mlir::dyn_cast<cir::CleanupScopeOp>(op);
398 for (mlir::Block &bodyBlock : cleanupScopeOp.getBodyRegion()) {
399 if (bodyBlock.mightHaveTerminator()) {
400 if (mlir::isa<cir::YieldOp>(bodyBlock.getTerminator()))
402 assert(!mlir::isa<cir::BreakOp>(bodyBlock.getTerminator()) &&
403 !mlir::isa<cir::ContinueOp>(bodyBlock.getTerminator()) &&
404 !mlir::isa<cir::ResumeOp>(bodyBlock.getTerminator()));
410void CIRGenFunction::LexicalScope::emitImplicitReturn() {
411 CIRGenBuilderTy &builder = cgf.getBuilder();
412 LexicalScope *localScope = cgf.curLexScope;
417 const auto *fd = dyn_cast_or_null<clang::FunctionDecl>(cgf.curGD.getDecl());
424 if (fd && cgf.getLangOpts().CPlusPlus && !fd->hasImplicitReturnZero() &&
425 !cgf.sawAsmBlock && !fd->getReturnType()->isVoidType() &&
426 builder.getInsertionBlock() &&
428 bool shouldEmitUnreachable =
429 cgf.cgm.getCodeGenOpts().StrictReturn ||
432 if (shouldEmitUnreachable) {
434 if (cgf.cgm.getCodeGenOpts().OptimizationLevel == 0)
435 cir::TrapOp::create(builder, localScope->endLoc);
437 cir::UnreachableOp::create(builder, localScope->endLoc);
438 builder.clearInsertionPoint();
443 (void)emitReturn(localScope->endLoc);
451 scope = scope->parentScope;
464 if (value.getType() == ty)
467 assert((mlir::isa<cir::IntType>(ty) || cir::isAnyFloatingPointType(ty)) &&
468 "unexpected promotion type");
470 if (mlir::isa<cir::IntType>(ty))
471 return cgf.
getBuilder().CIRBaseBuilderTy::createIntCast(value, ty);
477 mlir::Block *entryBB,
481 if (fd && fd->
hasAttr<NakedAttr>()) {
482 cgm.errorNYI(bodyBeginLoc,
"naked function decl");
488 mlir::Location loc =
getLoc(bodyBeginLoc);
489 mlir::Value zero = builder.getNullValue(retTy, loc);
490 builder.CIRBaseBuilderTy::createStore(loc, zero,
returnValue.getPointer());
494 for (
const auto nameValue : llvm::zip(args, entryBB->getArguments())) {
495 const VarDecl *paramVar = std::get<0>(nameValue);
496 mlir::Value paramVal = std::get<1>(nameValue);
499 paramVal.setLoc(paramLoc);
501 mlir::Value addrVal =
506 mlir::ptr::MemorySpaceAttrInterface destAddrSpace =
526 mlir::Location fnBodyBegin =
getLoc(bodyBeginLoc);
527 builder.CIRBaseBuilderTy::createStore(fnBodyBegin, paramVal,
530 assert(builder.getInsertionBlock() &&
"Should be valid");
534 cir::FuncOp fn, cir::FuncType funcType,
538 "CIRGenFunction can only be used for one function at a time");
546 const auto *fd = dyn_cast_or_null<FunctionDecl>(d);
555 fn->setAttr(cir::CIRDialect::getNoRecurseAttrName(),
556 mlir::UnitAttr::get(fn.getContext()));
566 builder.setDefaultConstrainedRounding(rm);
567 builder.setDefaultConstrainedExcept(eb);
568 builder.setIsFPConstrained(
false);
569 if ((fd && (fd->UsesFPIntrin() || fd->hasAttr<StrictFPAttr>())) ||
571 rm != llvm::RoundingMode::NearestTiesToEven))) {
572 builder.setIsFPConstrained(
true);
573 fn->setAttr(cir::CIRDialect::getStrictFPAttrName(),
574 mlir::UnitAttr::get(fn.getContext()));
576 mlir::Block *entryBB = &fn.getBlocks().front();
577 builder.setInsertionPointToStart(entryBB);
586 if (
Stmt *body = fd->getBody())
587 bodyEndLoc = body->getEndLoc();
589 bodyEndLoc = fd->getLocation();
591 emitAndUpdateRetAlloca(returnType,
getLoc(bodyEndLoc),
592 getContext().getTypeAlignInChars(returnType));
606 if (
Stmt *body = fd->getBody())
607 bodyBeginLoc = body->getBeginLoc();
609 bodyBeginLoc = fd->getLocation();
614 if (
const auto *md = dyn_cast_if_present<CXXMethodDecl>(d);
615 md && !md->isStatic()) {
617 md->getParent()->isLambda() && md->getOverloadedOperator() == OO_Call;
619 if (md->isImplicitObjectMemberFunction())
620 cgm.getCXXABI().emitInstanceFunctionProlog(loc, *
this);
649 for (
auto *fd : md->getParent()->fields()) {
650 if (fd->hasCapturedVLAType())
651 cgm.errorNYI(loc,
"lambda captured VLA type");
653 }
else if (md->isImplicitObjectMemberFunction()) {
667 if (!fd || !fd->hasAttr<NakedAttr>()) {
668 for (
const VarDecl *vd : args) {
673 if (
const auto *pvd = dyn_cast<ParmVarDecl>(vd))
674 ty = pvd->getOriginalType();
697 "deferred conditional cleanups were not consumed by a "
698 "FullExprCleanupScope");
707 if (
const CompoundStmt *block = dyn_cast<CompoundStmt>(body))
718 for (mlir::Block &block : func.getBlocks()) {
719 if (block.empty() && block.getUses().empty())
720 blocksToDelete.push_back(&block);
722 for (mlir::Block *block : blocksToDelete)
727 cir::FuncType funcType) {
731 if (funcDecl->isInlineBuiltinDeclaration()) {
735 std::string fdInlineName = (
cgm.getMangledName(funcDecl) +
".inline").str();
737 mlir::cast_or_null<cir::FuncOp>(
cgm.getGlobalValue(fdInlineName));
739 mlir::OpBuilder::InsertionGuard guard(builder);
740 builder.setInsertionPoint(fn);
741 clone = cir::FuncOp::create(builder, fn.getLoc(), fdInlineName,
742 fn.getFunctionType());
743 cgm.insertGlobalSymbol(clone);
744 clone.setLinkage(cir::GlobalLinkageKind::InternalLinkage);
745 clone.setSymVisibility(
"private");
746 clone.setInlineKind(cir::InlineKind::AlwaysInline);
748 fn.setLinkage(cir::GlobalLinkageKind::ExternalLinkage);
749 fn.setSymVisibility(
"private");
757 if (LLVM_UNLIKELY(pd->isInlineBuiltinDeclaration())) {
758 std::string inlineName = funcDecl->getName().str() +
".inline";
759 if (
auto inlineFn = mlir::cast_or_null<cir::FuncOp>(
760 cgm.getGlobalValue(inlineName))) {
765 .replaceAllSymbolUses(fn.getSymNameAttr(),
cgm.getModule())
767 llvm_unreachable(
"Failed to replace inline builtin symbol uses");
768 cgm.eraseGlobalSymbol(inlineFn);
777 Stmt *body = funcDecl->getBody();
784 return clangLoc.isValid() ?
getLoc(clangLoc) : builder.getUnknownLoc();
786 const mlir::Location fusedLoc = mlir::FusedLoc::get(
788 {validMLIRLoc(bodyRange.
getBegin()), validMLIRLoc(bodyRange.
getEnd())});
789 mlir::Block *entryBB = fn.addEntryBlock();
803 if (body && isa_and_nonnull<CoroutineBodyStmt>(body))
804 llvm::append_range(
fnArgs, funcDecl->parameters());
807 fn->setAttr(cir::CIRDialect::getMustProgressAttrName(),
810 if (shouldEmitLifetimeMarkers)
818 funcDecl->hasAttr<CUDAGlobalAttr>()) {
819 cgm.getCUDARuntime().emitDeviceStub(*
this, fn, args);
839 llvm_unreachable(
"no definition for normal function");
846 if (mlir::failed(fn.verifyBody()))
851 cgm.emitOpenCLKernelArgMetadata(fn, funcDecl);
862 assert((
cgm.getTarget().getCXXABI().hasConstructorVariants() ||
864 "can only generate complete ctor for this ABI");
869 cgm.getTarget().getCXXABI().hasConstructorVariants()) {
875 Stmt *body = ctor->getBody(definition);
876 assert(definition == ctor &&
"emitting wrong constructor body");
878 bool isTryBody = isa_and_nonnull<CXXTryStmt>(body);
887 Stmt *emitterBody =
nullptr;
890 : ctor(ctor), ctorType(ctorType), args(args),
892 ~ctorTryBodyEmitter()
override =
default;
902 return cgf.
emitStmt(emitterBody,
true);
906 ctorTryBodyEmitter emitter{ctor, ctorType, args, isTryBody, body};
907 mlir::LogicalResult bodyRes =
914 if (bodyRes.failed())
915 cgm.errorNYI(ctor->getSourceRange(),
916 "emitConstructorBody: emit body statement failed.");
971 const bool isTryBody = isa_and_nonnull<CXXTryStmt>(body);
987 llvm_unreachable(
"not expecting a unified dtor");
989 llvm_unreachable(
"not expecting a COMDAT");
992 llvm_unreachable(
"already handled deleting case");
995 assert((body ||
getTarget().getCXXABI().isMicrosoft()) &&
996 "can't emit a dtor without a body for non-Microsoft ABIs");
1014 bool needsVTableInit =
1017 if (needsVTableInit &&
cgm.getCodeGenOpts().StrictVTablePointers &&
1018 cgm.getCodeGenOpts().OptimizationLevel > 0) {
1027 if (needsVTableInit)
1035 assert(dtor->
isImplicit() &&
"bodyless dtor not implicit");
1061 CharUnits align =
cgm.getNaturalTypeAlignment(ty, &baseInfo);
1068 CharUnits alignment =
cgm.getNaturalTypeAlignment(ty, &baseInfo);
1077 QualType retTy = fd->getReturnType();
1082 const auto *md = dyn_cast<CXXMethodDecl>(fd);
1083 if (md && md->isImplicitObjectMemberFunction()) {
1084 if (
cgm.getCXXABI().hasThisReturn(gd))
1085 cgm.errorNYI(fd->getSourceRange(),
"this return");
1086 else if (
cgm.getCXXABI().hasMostDerivedReturn(gd))
1087 cgm.errorNYI(fd->getSourceRange(),
"most derived return");
1088 cgm.getCXXABI().buildThisParam(*
this, args);
1091 bool passedParams =
true;
1092 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(fd))
1093 if (
auto inherited = cd->getInheritedConstructor())
1098 for (
auto *param : fd->parameters()) {
1099 args.push_back(param);
1100 if (!param->hasAttr<PassObjectSizeAttr>())
1104 getContext(), param->getDeclContext(), param->getLocation(),
1107 args.push_back(implicit);
1112 cgm.getCXXABI().addImplicitStructorParams(*
this, retTy, args);
1123 assert(e->
isTransparent() &&
"non-transparent glvalue init list");
1127static std::variant<LValue, RValue>
1132 llvm::scope_exit opaque_cleanup{
1133 [&]() { llvm::for_each(opaques, [&](OVMD &o) { o.unbind(cgf); }); }};
1137 std::variant<LValue, RValue> result;
1142 if (
const auto *ov = dyn_cast<OpaqueValueExpr>(semantic)) {
1145 if (ov->isUnique()) {
1146 assert(ov != resultExpr &&
1147 "A unique OVE cannot be used as the result expression");
1154 if (ov == resultExpr && ov->
isPRValue() && !forLValue &&
1157 "emitPseudoObjectExpr for RValue & aggregate kind");
1159 opaqueData = OVMD::bind(cgf, ov, ov->getSourceExpr());
1162 if (ov == resultExpr) {
1166 "emitPseudoObjectExpr as result");
1171 "emitPseudoObjectExpr as an RValue");
1174 opaques.push_back(opaqueData);
1175 }
else if (semantic == resultExpr) {
1186 "emitPseudoObjectExpr as an ignored value");
1197 return std::get<RValue>(
1214 "emitLValue: unsupported l-value class");
1217 case Expr::ObjCPropertyRefExprClass:
1218 llvm_unreachable(
"cannot emit a property reference directly");
1220 case Expr::ObjCSelectorExprClass:
1222 "emitLValue: ObjCSelectorExpr");
1224 case Expr::ObjCIsaExprClass:
1227 case Expr::BinaryOperatorClass:
1229 case Expr::CompoundAssignOperatorClass: {
1232 ty = at->getValueType();
1238 case Expr::CallExprClass:
1239 case Expr::CXXMemberCallExprClass:
1240 case Expr::CXXOperatorCallExprClass:
1241 case Expr::UserDefinedLiteralClass:
1243 case Expr::CXXRewrittenBinaryOperatorClass:
1246 case Expr::VAArgExprClass:
1249 case Expr::DeclRefExprClass:
1251 case Expr::ConstantExprClass:
1254 case Expr::ParenExprClass:
1256 case Expr::GenericSelectionExprClass:
1258 case Expr::PredefinedExprClass:
1260 case Expr::StringLiteralClass:
1262 case Expr::ObjCEncodeExprClass:
1264 "emitLValue: ObjCEncodeExpr");
1266 case Expr::PseudoObjectExprClass:
1268 case Expr::InitListExprClass:
1270 case Expr::CXXTemporaryObjectExprClass:
1271 case Expr::CXXConstructExprClass:
1273 case Expr::CXXBindTemporaryExprClass:
1275 case Expr::CXXUuidofExprClass:
1277 "emitLValue: CXXUuidofExpr");
1279 case Expr::LambdaExprClass:
1282 case Expr::ExprWithCleanupsClass: {
1299 case Expr::CXXDefaultArgExprClass: {
1304 case Expr::CXXDefaultInitExprClass: {
1309 case Expr::CXXTypeidExprClass:
1311 case Expr::ObjCMessageExprClass:
1313 "emitLValue: ObjCMessageExpr");
1315 case Expr::ObjCIvarRefExprClass:
1317 "emitLValue: ObjCIvarRefExpr");
1319 case Expr::StmtExprClass:
1322 case Expr::UnaryOperatorClass:
1324 case Expr::ArraySubscriptExprClass:
1326 case Expr::MatrixSingleSubscriptExprClass:
1328 "emitLValue: MatrixSingleSubscriptExpr");
1330 case Expr::MatrixSubscriptExprClass:
1332 case Expr::ArraySectionExprClass:
1334 "emitLValue: ArraySectionExpr");
1336 case Expr::ExtVectorElementExprClass:
1338 case Expr::MatrixElementExprClass:
1340 case Expr::CXXThisExprClass:
1342 case Expr::MemberExprClass:
1344 case Expr::CompoundLiteralExprClass:
1346 case Expr::ConditionalOperatorClass:
1348 case Expr::BinaryConditionalOperatorClass:
1350 case Expr::ChooseExprClass:
1352 case Expr::OpaqueValueExprClass:
1354 case Expr::SubstNonTypeTemplateParmExprClass:
1356 case Expr::ImplicitCastExprClass:
1357 case Expr::CStyleCastExprClass:
1358 case Expr::CXXFunctionalCastExprClass:
1359 case Expr::CXXStaticCastExprClass:
1360 case Expr::CXXDynamicCastExprClass:
1361 case Expr::CXXReinterpretCastExprClass:
1362 case Expr::CXXConstCastExprClass:
1364 case Expr::CXXAddrspaceCastExprClass:
1365 case Expr::ObjCBridgedCastExprClass:
1369 "emitLValue: addrspace or ObjC bridged cast");
1371 case Expr::MaterializeTemporaryExprClass:
1373 case Expr::CoawaitExprClass:
1375 case Expr::CoyieldExprClass:
1377 case Expr::PackIndexingExprClass:
1379 case Expr::HLSLOutArgExprClass:
1380 llvm_unreachable(
"cannot emit a HLSL out argument directly");
1386 llvm::raw_svector_ostream
out(buffer);
1388 return std::string(
out.str());
1411 mlir::IntegerAttr sizeVal;
1415 if (isa_and_nonnull<VariableArrayType>(
getContext().getAsArrayType(ty))) {
1417 "emitNullInitialization for zero size VariableArrayType");
1422 sizeVal =
cgm.getSize(size);
1429 if (!
cgm.getTypes().isZeroInitializable(ty)) {
1434 "emitNullInitialization: only pointer-to-data-member (directly or "
1435 "within a record) null initialization is implemented");
1436 mlir::Value nullVal =
cgm.emitNullConstant(ty, loc);
1437 builder.createStore(loc, nullVal, destPtr);
1445 mlir::Value zero = builder.getNullValue(builder.getUInt8Ty(), loc);
1446 mlir::Value sizeValue =
1447 builder.getConstAPInt(loc,
cgm.uInt64Ty, sizeVal.getValue());
1449 builder.createMemSet(loc, destPtr, zero, sizeValue);
1461 ConstructorHelper(fpFeatures);
1464void CIRGenFunction::CIRGenFPOptionsRAII::ConstructorHelper(
1466 oldFPFeatures = cgf.curFPFeatures;
1467 cgf.curFPFeatures = fpFeatures;
1469 oldExcept = cgf.builder.getDefaultConstrainedExcept();
1470 oldRounding = cgf.builder.getDefaultConstrainedRounding();
1472 if (oldFPFeatures == fpFeatures)
1475 oldFastMathFlags = cgf.builder.getFastMathFlags();
1481 cgf.builder.setDefaultConstrainedRounding(newRoundingMode);
1482 cgf.builder.setDefaultConstrainedExcept(newExceptionBehavior);
1484 cgf.setFastMathFlags(fpFeatures);
1486 assert((cgf.curFuncDecl ==
nullptr || cgf.builder.getIsFPConstrained() ||
1490 newRoundingMode == llvm::RoundingMode::NearestTiesToEven)) &&
1491 "FPConstrained should be enabled on entire function");
1498 cgf.curFPFeatures = oldFPFeatures;
1499 cgf.builder.setDefaultConstrainedExcept(oldExcept);
1500 cgf.builder.setDefaultConstrainedRounding(oldRounding);
1501 if (oldFastMathFlags)
1502 cgf.builder.setFastMathFlags(*oldFastMathFlags);
1506 cir::FastMathFlags flags = cir::FastMathFlags::none;
1508 flags |= cir::FastMathFlags::reassoc;
1510 flags |= cir::FastMathFlags::nnan;
1512 flags |= cir::FastMathFlags::ninf;
1514 flags |= cir::FastMathFlags::nsz;
1516 flags |= cir::FastMathFlags::arcp;
1518 flags |= cir::FastMathFlags::afn;
1520 flags |= cir::FastMathFlags::contract;
1525cir::FastMathFlagsAttr
1527 if (fastMathFlags == cir::FastMathFlags::none)
1529 return cir::FastMathFlagsAttr::get(&
getMLIRContext(), fastMathFlags);
1536 if (ce->
getCastKind() == CK_UncheckedDerivedToBase)
1546 if (ice->isGLValue())
1562 mlir::Value numVLAElements =
nullptr;
1574 baseType = elementType;
1575 return numVLAElements;
1588 uint64_t countFromCLAs = 1;
1591 auto cirArrayType = mlir::dyn_cast<cir::ArrayType>(addr.
getElementType());
1593 while (cirArrayType) {
1595 countFromCLAs *= cirArrayType.getSize();
1599 mlir::dyn_cast<cir::ArrayType>(cirArrayType.getElementType());
1603 "CIR and Clang types are out-of-sync");
1610 cgm.errorNYI(*
currSrcLoc,
"length for non-array underlying types");
1615 mlir::Value numElements =
1621 builder.createMul(numVLAElements.getLoc(), numVLAElements, numElements,
1631 mlir::Location assumeLoc =
getLoc(assumptionLoc);
1632 mlir::Value alignValue = builder.getUInt64(alignment, assumeLoc);
1633 mlir::Value cond = builder.getBool(
true, assumeLoc);
1636 bundleArgs.push_back(offsetValue);
1637 cir::AssumeOp::create(builder, assumeLoc, cond, cir::AssumeBundleKind::Align,
1644 int64_t alignment, mlir::Value offsetValue) {
1653 cgm.getASTContext().getAsVariableArrayType(
type);
1654 assert(vla &&
"type was not a variable array type!");
1661 mlir::Value numElements;
1665 elementType =
type->getElementType();
1667 assert(vlaSize &&
"no size for VLA!");
1668 assert(vlaSize.getType() ==
sizeTy);
1671 numElements = vlaSize;
1677 builder.createMul(numElements.getLoc(), numElements, vlaSize,
1680 }
while ((
type =
getContext().getAsVariableArrayType(elementType)));
1682 assert(numElements &&
"Undefined elements number");
1683 return {numElements, elementType};
1689 assert(vlaSize &&
"no size for VLA!");
1690 assert(vlaSize.getType() ==
sizeTy);
1697 assert(
type->isVariablyModifiedType() &&
1698 "Must pass variably modified type to EmitVLASizes!");
1703 assert(
type->isVariablyModifiedType());
1705 const Type *ty =
type.getTypePtr();
1707 case Type::CountAttributed:
1708 case Type::PackIndexing:
1709 case Type::ArrayParameter:
1710 case Type::HLSLAttributedResource:
1711 case Type::HLSLInlineSpirv:
1712 case Type::PredefinedSugar:
1713 case Type::LateParsedAttr:
1714 cgm.errorNYI(
"CIRGenFunction::emitVariablyModifiedType");
1717#define TYPE(Class, Base)
1718#define ABSTRACT_TYPE(Class, Base)
1719#define NON_CANONICAL_TYPE(Class, Base)
1720#define DEPENDENT_TYPE(Class, Base) case Type::Class:
1721#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)
1722#include "clang/AST/TypeNodes.inc"
1724 "dependent type must be resolved before the CIR codegen");
1730 case Type::ExtVector:
1731 case Type::ConstantMatrix:
1735 case Type::TemplateSpecialization:
1736 case Type::ObjCTypeParam:
1737 case Type::ObjCObject:
1738 case Type::ObjCInterface:
1739 case Type::ObjCObjectPointer:
1741 case Type::OverflowBehavior:
1742 llvm_unreachable(
"type class is never variably-modified!");
1744 case Type::Adjusted:
1756 case Type::BlockPointer:
1760 case Type::LValueReference:
1761 case Type::RValueReference:
1765 case Type::MemberPointer:
1769 case Type::ConstantArray:
1770 case Type::IncompleteArray:
1775 case Type::VariableArray: {
1792 entry = builder.createBoolIntToIntCast(size,
sizeTy);
1799 case Type::FunctionProto:
1800 case Type::FunctionNoProto:
1806 case Type::UnaryTransform:
1807 case Type::Attributed:
1808 case Type::BTFTagAttributed:
1809 case Type::SubstTemplateTypeParm:
1810 case Type::MacroQualified:
1816 case Type::Decltype:
1818 case Type::DeducedTemplateSpecialization:
1822 case Type::TypeOfExpr:
1835 }
while (
type->isVariablyModifiedType());
1839 if (
getContext().getBuiltinVaListType()->isArrayType())
Defines the clang::Expr interface and subclasses for C++ expressions.
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
Address withPointer(mlir::Value newPtr) const
Return address with different pointer, but same element type and alignment.
mlir::Value getPointer() const
mlir::Type getElementType() const
Address withElementType(CIRGenBuilderTy &builder, mlir::Type ElemTy) const
Return address with different element type, a bitcast pointer, and the same alignment.
static AggValueSlot ignored()
Returns an aggregate value slot indicating that the aggregate value is being ignored.
mlir::Value createFloatingCast(mlir::Value v, mlir::Type destType)
CIRGenFPOptionsRAII(CIRGenFunction &cgf, FPOptions FPFeatures)
The scope of a CXXDefaultInitExpr.
void exit(ArrayRef< mlir::Value * > valuesToReload={})
A non-RAII class containing all the information about a bound opaque value.
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.
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: initialize the return value of an implicit-return-zero function and decla...
mlir::Type convertType(clang::QualType t)
LValue emitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *e)
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)
CIRGenTypes & getTypes() const
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,...
mlir::Value loadCXXThis()
Load the value for 'this'.
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...
void emitDeleteCall(const FunctionDecl *deleteFD, mlir::Value ptr, QualType deleteTy)
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
clang::FPOptions curFPFeatures
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)
bool checkIfFunctionMustProgress()
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
void initializeVTablePointers(mlir::Location loc, const clang::CXXRecordDecl *rd)
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
LValue emitCoawaitLValue(const CoawaitExpr *e)
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.
Address maybeCastStackAddressSpace(Address alloca, mlir::ptr::MemorySpaceAttrInterface destAddrSpace, mlir::Value arraySize=nullptr)
llvm::SmallVector< const ParmVarDecl * > fnArgs
Save Parameter Decl for coroutine.
llvm::SmallVector< PendingCleanupEntry > deferredConditionalCleanupStack
Cleanups for temporaries constructed inside a conditional.
std::optional< mlir::Value > fnRetAlloca
The compiler-generated variable that holds the return value.
void emitImplicitAssignmentOperatorBody(FunctionArgList &args)
cir::FastMathFlagsAttr getFastMathFlagsAttr(cir::FastMathFlags fastMathFlags)
Create a CIR fast-math attribute from the specified flags.
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)
mlir::LogicalResult emitCXXTryStmt(const clang::CXXTryStmt &s, cxxTryBodyEmitter &bodyCallback, bool isFnTryBlock=false)
cir::FastMathFlags getCurrentFastMathFlags() const
Convert the active Clang floating-point options to CIR fast-math flags.
LValue emitAggExprToLValue(const Expr *e)
LValue emitCompoundAssignmentLValue(const clang::CompoundAssignOperator *e)
Address returnValue
The temporary alloca to hold the return value.
static bool hasAggregateEvaluationKind(clang::QualType type)
void finishFunction(SourceLocation endLoc)
mlir::LogicalResult emitFunctionBody(const clang::Stmt *body)
std::string getCounterAggTmpAsString()
LValue emitUnaryOpLValue(const clang::UnaryOperator *e)
LValue emitMatrixSubscriptExpr(const MatrixSubscriptExpr *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)
LValue emitStringLiteralLValue(const StringLiteral *e, llvm::StringRef name=".str")
LValue emitCoyieldLValue(const CoyieldExpr *e)
llvm::SmallDenseMap< const ParmVarDecl *, const ImplicitParamDecl * > sizeArguments
If a ParmVarDecl had the pass_object_size attribute, this will contain a mapping from said ParmVarDec...
mlir::Value loadThisForDtorDelete(const CXXDestructorDecl *dd)
Return the pointer to pass to the operator delete of the given destructor, converted to the type of i...
mlir::Value emitScalarExpr(const clang::Expr *e, bool ignoreResultAssign=false)
Emit the computation of the specified expression of scalar type.
LValue emitPseudoObjectLValue(const PseudoObjectExpr *E)
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 emitInitListLValue(const InitListExpr *e)
std::optional< SourceRange > currSrcLoc
Use to track source locations across nested visitor traversals.
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.
RValue emitPseudoObjectRValue(const PseudoObjectExpr *e, AggValueSlot slot=AggValueSlot::ignored())
LValue emitDeclRefLValue(const clang::DeclRefExpr *e)
static void eraseEmptyAndUnusedBlocks(cir::FuncOp func)
Remove leftover empty and unreachable blocks from an emitted function.
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)
void setFastMathFlags(FPOptions fpFeatures)
LValue makeAddrLValue(Address addr, QualType ty, AlignmentSource source=AlignmentSource::Type)
LValue emitMatrixElementExpr(const MatrixElementExpr *e)
LValue emitPredefinedLValue(const PredefinedExpr *e)
RValue emitAnyExpr(const clang::Expr *e, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
Emit code to compute the specified expression which can have any type.
void emitCXXDestructorCall(const CXXDestructorDecl *dd, CXXDtorType type, bool forVirtualBase, bool delegating, Address thisAddr, QualType thisTy)
void emitLambdaStaticInvokeBody(const CXXMethodDecl *md)
void emitEndEHSpec(const clang::Decl *d)
Close the cir.try opened by emitStartEHSpec.
CIRGenFunction(CIRGenModule &cgm, CIRGenBuilderTy &builder, bool suppressNewContext=false)
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.
void emitStartEHSpec(const clang::Decl *d)
Wrap the function body in a cir.try that enforces the exception specification of d: a filter handler ...
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.
Address createMemTemp(QualType t, mlir::Location loc, const Twine &name="tmp", Address *alloca=nullptr, mlir::OpBuilder::InsertPoint ip={})
Create a temporary memory object of the given type, with appropriate alignmen and cast it to the defa...
LValue emitCXXConstructLValue(const CXXConstructExpr *e)
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.
bool inheritingCtorHasParams(const InheritedConstructor &inherited, CXXCtorType type)
Determine if a C++ inheriting constructor should have parameters matching those of its inherited cons...
Type for representing both the decl and type of parameters to a function.
Address getAddress() const
static LValue makeAddr(Address address, clang::QualType t, LValueBaseInfo baseInfo)
clang::QualType getType() const
mlir::Value getPointer() const
LValueBaseInfo getBaseInfo() const
This trivial value class is used to represent the result of an expression that is evaluated.
mlir::Value getValue() const
Return the value of this scalar value.
Represents a C++ constructor within a class.
Represents a C++ destructor within a class.
const FunctionDecl * getOperatorDelete() const
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
This is an opaque type for sizes expressed in character units.
bool isZero() const
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
SourceLocation getBeginLoc() const LLVM_READONLY
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
bool allowFPContractAcrossStatement() const
RoundingMode getRoundingMode() const
Represents a function declaration or definition.
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool isDestroyingOperatorDelete() const
Determine whether this is a destroying operator delete.
QualType getReturnType() const
bool hasImplicitReturnZero() const
Whether falling off this function implicitly returns null/zero.
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.
CXXCtorType getCtorType() const
const Decl * getDecl() const
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
Describes an C or C++ initializer list.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
const Expr * getInit(unsigned Init) const
FPExceptionModeKind
Possible floating point exception behavior.
@ FPE_Ignore
Assume that floating-point exceptions are masked.
FPExceptionModeKind getDefaultExceptionMode() const
RoundingMode getDefaultRoundingMode() const
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.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
ArrayRef< Expr * > semantics()
A (possibly-)qualified type.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
LangAS getAddressSpace() const
Return the address space of this type.
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
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.
child_iterator child_begin()
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
child_iterator child_end()
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 isMemberDataPointerType() const
bool isAnyComplexType() const
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
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
mlir::ptr::MemorySpaceAttrInterface toCIRAddressSpaceAttr(mlir::MLIRContext &ctx, clang::LangAS langAS)
Convert an AST LangAS to the appropriate CIR address space attribute interface.
@ 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 bool functionMightHaveBypass(const Stmt *s)
Does the statement tree rooted at s contain a label, switch, or indirect goto that could bypass a loc...
static std::variant< LValue, RValue > emitPseudoObjectExpr(CIRGenFunction &cgf, const PseudoObjectExpr *e, bool forLValue, AggValueSlot slot)
bool canSkipVTablePointerInitialization(ASTContext &Ctx, const CXXDestructorDecl *Dtor)
Check whether we need to initialize any vtable pointers before calling this destructor.
bool shouldEmitLifetimeMarkers(const CodeGenOptions &CGOpts, const LangOptions &LangOpts)
Decide whether we need to emit the lifetime markers.
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)
@ Other
Other implicit parameter.
__builtin_bitreverse32 uint32_t __builtin_riscv_aaddu_u32 __builtin_riscv_asubu_u32 __builtin_elementwise_add_sat __builtin_elementwise_sub_sat int32_t uint32_t uint32_t __builtin_riscv_mhacc_i32 __builtin_riscv_mhaccu_u32 __builtin_riscv_mhaccsu_i32 __builtin_riscv_mulq_i32 int64_t
static bool fastMathFuncAttributes()
static bool constructABIArgDirectExtend()
static bool runCleanupsScope()
static bool emitTypeCheck()
static bool addressIsKnownNonNull()
static bool generateDebugInfo()
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)
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.