18#include "llvm/ADT/ScopeExit.h"
21using namespace CodeGen;
24using llvm::BasicBlock;
27enum class AwaitKind {
Init,
Normal, Yield, Final };
28static constexpr llvm::StringLiteral AwaitKindStr[] = {
"init",
"await",
"yield",
92 llvm::CallInst *CoroId,
93 CallExpr const *CoroIdExpr =
nullptr) {
96 CGF.
CGM.
Error(CoroIdExpr->getBeginLoc(),
97 "only one __builtin_coro_id can be used in a function");
99 CGF.
CGM.
Error(CoroIdExpr->getBeginLoc(),
100 "__builtin_coro_id shall not be used in a C++ coroutine");
102 llvm_unreachable(
"EmitCoroutineBodyStatement called twice?");
116 case AwaitKind::Init:
117 case AwaitKind::Final:
119 case AwaitKind::Normal:
122 case AwaitKind::Yield:
128 Twine(
No).toVector(Prefix);
146 if (
const auto *CE = dyn_cast<CallExpr>(S)) {
147 const auto *Callee = CE->getDirectCallee();
158 if (
const auto *TE = dyn_cast<CXXBindTemporaryExpr>(S)) {
163 const auto *Dtor = TE->getTemporary()->getDestructor();
170 for (
const auto *child : S->children())
218 struct LValueOrRValue {
226 bool ignoreResult,
bool forLValue) {
227 auto *
E = S.getCommonExpr();
231 auto UnbindCommonOnExit =
232 llvm::make_scope_exit([&] { CommonBinder.unbind(CGF); });
236 BasicBlock *SuspendBlock = CGF.
createBasicBlock(Prefix + Twine(
".suspend"));
237 BasicBlock *CleanupBlock = CGF.
createBasicBlock(Prefix + Twine(
".cleanup"));
246 llvm::Function *CoroSave = CGF.
CGM.
getIntrinsic(llvm::Intrinsic::coro_save);
247 auto *NullPtr = llvm::ConstantPointerNull::get(CGF.
CGM.
Int8PtrTy);
248 auto *SaveCall =
Builder.CreateCall(CoroSave, {NullPtr});
251 CGF.
CurFn->getName(), Prefix, S);
256 "expected to be called in coroutine context");
259 SuspendIntrinsicCallArgs.push_back(
262 SuspendIntrinsicCallArgs.push_back(CGF.
CurCoro.
Data->CoroBegin);
263 SuspendIntrinsicCallArgs.push_back(SuspendWrapper);
265 const auto SuspendReturnType = S.getSuspendReturnType();
266 llvm::Intrinsic::ID AwaitSuspendIID;
268 switch (SuspendReturnType) {
270 AwaitSuspendIID = llvm::Intrinsic::coro_await_suspend_void;
273 AwaitSuspendIID = llvm::Intrinsic::coro_await_suspend_bool;
276 AwaitSuspendIID = llvm::Intrinsic::coro_await_suspend_handle;
280 llvm::Function *AwaitSuspendIntrinsic = CGF.
CGM.
getIntrinsic(AwaitSuspendIID);
283 const bool AwaitSuspendCanThrow =
288 llvm::CallBase *SuspendRet =
nullptr;
290 if (AwaitSuspendCanThrow)
295 SuspendIntrinsicCallArgs);
300 switch (SuspendReturnType) {
302 assert(SuspendRet->getType()->isVoidTy());
305 assert(SuspendRet->getType()->isIntegerTy());
308 BasicBlock *RealSuspendBlock =
310 CGF.
Builder.CreateCondBr(SuspendRet, RealSuspendBlock, ReadyBlock);
315 assert(SuspendRet->getType()->isVoidTy());
321 const bool IsFinalSuspend = (Kind == AwaitKind::Final);
322 llvm::Function *CoroSuspend =
324 auto *SuspendResult =
Builder.CreateCall(
325 CoroSuspend, {SaveCall,
Builder.getInt1(IsFinalSuspend)});
348 auto Loc = S.getResumeExpr()->getExprLoc();
370 Res.RV = CGF.
EmitAnyExpr(S.getResumeExpr(), aggSlot, ignoreResult);
380 ignoreResult,
false).RV;
386 aggSlot, ignoreResult,
false).RV;
391 const Expr *RV = S.getOperand();
406 const auto *RE =
E->getResumeExpr();
409 assert(isa<CallExpr>(RE) &&
"unexpected suspend expression type");
410 return cast<CallExpr>(RE)->getCallReturnType(Ctx);
416 Twine
const &SuspendPointName,
418 std::string FuncName =
419 (CoroName +
".__await_suspend_wrapper__" + SuspendPointName).str();
427 QualType ReturnTy = S.getSuspendExpr()->getType();
429 args.push_back(&AwaiterDecl);
430 args.push_back(&FrameDecl);
437 llvm::Function *Fn = llvm::Function::Create(
438 LTy, llvm::GlobalValue::InternalLinkage, FuncName, &
CGM.
getModule());
440 Fn->addParamAttr(0, llvm::Attribute::AttrKind::NonNull);
441 Fn->addParamAttr(0, llvm::Attribute::AttrKind::NoUndef);
443 Fn->addParamAttr(1, llvm::Attribute::AttrKind::NoUndef);
445 Fn->setMustProgress();
446 Fn->addFnAttr(llvm::Attribute::AttrKind::AlwaysInline);
459 *
this, S.getOpaqueValue(), AwaiterLValue);
463 auto UnbindCommonOnExit =
464 llvm::make_scope_exit([&] { AwaiterBinder.unbind(*
this); });
465 if (SuspendRet !=
nullptr) {
466 Fn->addRetAttr(llvm::Attribute::AttrKind::NoUndef);
478 "Can't have a scalar return unless the return type is a "
488 "Can't have a scalar return unless the return type is a "
497struct GetParamRef :
public StmtVisitor<GetParamRef> {
502 assert(
Expr ==
nullptr &&
"multilple declref in param move");
505 void VisitStmt(
Stmt *S) {
506 for (
auto *
C : S->children()) {
519 struct ParamReferenceReplacerRAII {
524 : LocalDeclMap(LocalDeclMap) {}
533 Visitor.Visit(
const_cast<Expr*
>(InitExpr));
534 assert(Visitor.Expr);
538 auto it = LocalDeclMap.find(PD);
539 assert(it != LocalDeclMap.end() &&
"parameter is not found");
540 SavedLocals.insert({ PD, it->second });
542 auto copyIt = LocalDeclMap.find(VD);
543 assert(copyIt != LocalDeclMap.end() &&
"parameter copy is not found");
544 it->second = copyIt->getSecond();
547 ~ParamReferenceReplacerRAII() {
548 for (
auto&& SavedLocal : SavedLocals) {
549 LocalDeclMap.insert({SavedLocal.first, SavedLocal.second});
562 BundleList.emplace_back(
"funclet", EHPad);
574 auto *NullPtr = llvm::ConstantPointerNull::get(CGF.
Int8PtrTy);
575 llvm::Function *CoroEndFn = CGM.getIntrinsic(llvm::Intrinsic::coro_end);
579 CGF.
Builder.CreateCall(CoroEndFn,
580 {NullPtr, CGF.
Builder.getTrue(),
581 llvm::ConstantTokenNone::get(CoroEndFn->getContext())},
583 if (Bundles.empty()) {
588 CGF.
Builder.CreateCondBr(CoroEnd, ResumeBB, CleanupContBB);
611 BasicBlock *SaveInsertBlock = CGF.
Builder.GetInsertBlock();
623 CGF.
CGM.
Error(Deallocate->getBeginLoc(),
624 "Deallocation expressoin does not refer to coro.free");
629 auto *InsertPt = SaveInsertBlock->getTerminator();
630 CoroFree->moveBefore(InsertPt->getIterator());
631 CGF.
Builder.SetInsertPoint(InsertPt);
634 auto *NullPtr = llvm::ConstantPointerNull::get(CGF.
Int8PtrTy);
635 auto *Cond = CGF.
Builder.CreateICmpNE(CoroFree, NullPtr);
636 CGF.
Builder.CreateCondBr(Cond, FreeBB, AfterFreeBB);
639 InsertPt->eraseFromParent();
640 CGF.
Builder.SetInsertPoint(AfterFreeBB);
642 explicit CallCoroDelete(
Stmt *DeallocStmt) : Deallocate(DeallocStmt) {}
647struct GetReturnObjectManager {
652 bool DirectEmit =
false;
658 : CGF(CGF), Builder(CGF.Builder), S(S), GroActiveFlag(
Address::invalid()),
680 auto *RVI = S.getReturnValueInit();
681 assert(RVI &&
"expected RVI");
682 auto GroType = RVI->getType();
692 void EmitGroAlloca() {
696 auto *GroDeclStmt = dyn_cast_or_null<DeclStmt>(S.getResultDecl());
702 auto *GroVarDecl = cast<VarDecl>(GroDeclStmt->getSingleDecl());
707 Builder.CreateStore(Builder.getFalse(), GroActiveFlag);
711 if (!GroVarDecl->isNRVOVariable()) {
713 auto *GroAlloca = dyn_cast_or_null<llvm::AllocaInst>(
715 assert(GroAlloca &&
"expected alloca to be emitted");
716 GroAlloca->setMetadata(llvm::LLVMContext::MD_coro_outside_frame,
728 if (
auto *Cleanup = dyn_cast<EHCleanupScope>(&*
b)) {
729 assert(!Cleanup->hasActiveFlag() &&
"cleanup already has active flag?");
730 Cleanup->setActiveFlag(GroActiveFlag);
731 Cleanup->setTestFlagInEHCleanup();
732 Cleanup->setTestFlagInNormalCleanup();
753 S.getReturnValue()->getType().getQualifiers(),
759 if (!GroActiveFlag.
isValid()) {
767 Builder.CreateStore(Builder.getTrue(), GroActiveFlag);
775 const bool CanFallthrough = CGF.
Builder.GetInsertBlock();
777 if (
Stmt *OnFallthrough = S.getFallthroughHandler())
782 auto *NullPtr = llvm::ConstantPointerNull::get(
Builder.getPtrTy());
784 unsigned NewAlign = TI.
getNewAlign() / TI.getCharWidth();
786 auto *EntryBB =
Builder.GetInsertBlock();
792 auto *CoroId =
Builder.CreateCall(
794 {Builder.getInt32(NewAlign), NullPtr, NullPtr, NullPtr});
797 assert(ShouldEmitLifetimeMarkers &&
798 "Must emit lifetime intrinsics for coroutines");
802 auto *CoroAlloc =
Builder.CreateCall(
805 Builder.CreateCondBr(CoroAlloc, AllocBB, InitBB);
809 auto *AllocOrInvokeContBB =
Builder.GetInsertBlock();
812 if (
auto *RetOnAllocFailure = S.getReturnStmtOnAllocFailure()) {
816 auto *NullPtr = llvm::ConstantPointerNull::get(
Int8PtrTy);
817 auto *Cond =
Builder.CreateICmpNE(AllocateCall, NullPtr);
820 Builder.CreateCondBr(Cond, InitBB, RetOnFailureBB);
834 Phi->addIncoming(NullPtr, EntryBB);
835 Phi->addIncoming(AllocateCall, AllocOrInvokeContBB);
836 auto *CoroBegin =
Builder.CreateCall(
840 GetReturnObjectManager GroManager(*
this, S);
841 GroManager.EmitGroAlloca();
846 ParamReferenceReplacerRAII ParamReplacer(LocalDeclMap);
853 (ParamMoves.size() == 0 || (ParamMoves.size() ==
FnArgs.size())) &&
854 "ParamMoves and FnArgs should be the same size for coroutine function");
855 if (ParamMoves.size() ==
FnArgs.size() && DI)
856 for (
const auto Pair : llvm::zip(
FnArgs, ParamMoves))
858 {std::get<0>(Pair), std::get<1>(Pair)});
871 if (
auto *ParmAlloca =
873 ParmAlloca->setMetadata(llvm::LLVMContext::MD_coro_outside_frame,
877 for (
auto *PM : S.getParamMoves()) {
879 ParamReplacer.addCopy(cast<DeclStmt>(PM));
888 auto *PromiseAddrVoidPtr =
890 CoroId->getIterator());
893 CoroId->setArgOperand(1, PromiseAddrVoidPtr);
896 GroManager.EmitGroInit();
901 CurCoro.
Data->ExceptionHandler = S.getExceptionHandler();
905 CurCoro.
Data->CurrentAwaitKind = AwaitKind::Normal;
913 BasicBlock *ContBB =
nullptr;
919 Builder.CreateCondBr(SkipBody, ContBB, BodyBB);
923 auto Loc = S.getBeginLoc();
941 const bool CanFallthrough =
Builder.GetInsertBlock();
942 const bool HasCoreturns =
CurCoro.
Data->CoreturnCount > 0;
943 if (CanFallthrough || HasCoreturns) {
959 llvm::ConstantTokenNone::get(CoroEnd->getContext())});
961 if (
Stmt *Ret = S.getReturnStmt()) {
964 Expr *PreviousRetValue =
nullptr;
965 if (GroManager.DirectEmit) {
966 PreviousRetValue = cast<ReturnStmt>(Ret)->getRetValue();
967 cast<ReturnStmt>(Ret)->setRetValue(
nullptr);
972 if (PreviousRetValue)
973 cast<ReturnStmt>(Ret)->setRetValue(PreviousRetValue);
977 CurFn->setPresplitCoroutine();
980 RD && RD->
hasAttr<CoroOnlyDestroyWhenCompleteAttr>())
981 CurFn->setCoroDestroyOnlyWhenComplete();
993 case llvm::Intrinsic::coro_frame: {
1003 "has been used earlier in this function");
1004 auto *NullPtr = llvm::ConstantPointerNull::get(
Builder.getPtrTy());
1007 case llvm::Intrinsic::coro_size: {
1009 llvm::IntegerType *
T =
1014 case llvm::Intrinsic::coro_align: {
1016 llvm::IntegerType *
T =
1024 case llvm::Intrinsic::coro_alloc:
1025 case llvm::Intrinsic::coro_begin:
1026 case llvm::Intrinsic::coro_free: {
1032 " been used earlier in this function");
1038 case llvm::Intrinsic::coro_suspend:
1042 for (
const Expr *Arg :
E->arguments())
1046 if (IID == llvm::Intrinsic::coro_end)
1050 llvm::CallInst *
Call =
Builder.CreateCall(F, Args);
1056 if (IID == llvm::Intrinsic::coro_id) {
1059 else if (IID == llvm::Intrinsic::coro_begin) {
1063 else if (IID == llvm::Intrinsic::coro_free) {
static LValueOrRValue emitSuspendExpression(CodeGenFunction &CGF, CGCoroData &Coro, CoroutineSuspendExpr const &S, AwaitKind Kind, AggValueSlot aggSlot, bool ignoreResult, bool forLValue)
static SmallString< 32 > buildSuspendPrefixStr(CGCoroData &Coro, AwaitKind Kind)
static QualType getCoroutineSuspendExprReturnType(const ASTContext &Ctx, const CoroutineSuspendExpr *E)
static void createCoroData(CodeGenFunction &CGF, CodeGenFunction::CGCoroInfo &CurCoro, llvm::CallInst *CoroId, CallExpr const *CoroIdExpr=nullptr)
static void emitBodyAndFallthrough(CodeGenFunction &CGF, const CoroutineBodyStmt &S, Stmt *Body)
static bool StmtCanThrow(const Stmt *S)
static bool FunctionCanThrow(const FunctionDecl *D)
static SmallVector< llvm::OperandBundleDef, 1 > getBundlesForCoroEnd(CodeGenFunction &CGF)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
const TargetInfo & getTargetInfo() const
CXXCatchStmt - This represents a C++ catch block.
Represents a C++ struct/union/class.
CXXTryStmt - A C++ try block, including all handlers.
static CXXTryStmt * Create(const ASTContext &C, SourceLocation tryLoc, CompoundStmt *tryBlock, ArrayRef< Stmt * > handlers)
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
static CharUnits One()
One - Construct a CharUnits quantity of one.
Represents a 'co_await' expression.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * getBasePointer() const
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
static AggValueSlot ignored()
ignored - Returns an aggregate value slot indicating that the aggregate value is being ignored.
llvm::StoreInst * CreateFlagStore(bool Value, llvm::Value *Addr)
Emit a store to an i1 flag variable.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateFlagLoad(llvm::Value *Addr, const llvm::Twine &Name="")
Emit a load from an i1 flag variable.
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
ParamDecl2StmtTy & getCoroutineParameterMappings()
CGFunctionInfo - Class to encapsulate the information about a function definition.
RawAddress getOriginalAllocatedAddress() const
Returns the address for the original alloca instruction.
static OpaqueValueMappingData bind(CodeGenFunction &CGF, const OpaqueValueExpr *ov, const Expr *e)
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
LValue EmitCoawaitLValue(const CoawaitExpr *E)
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr, const VarDecl *ConditionalDecl=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
RValue EmitCoroutineIntrinsic(const CallExpr *E, unsigned int IID)
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...
AwaitSuspendWrapperInfo CurAwaitSuspendWrapper
llvm::CallBase * EmitCallOrInvoke(llvm::FunctionCallee Callee, ArrayRef< llvm::Value * > Args, const Twine &Name="")
Emits a call or invoke instruction to the given function, depending on the current state of the EH st...
void EmitCoreturnStmt(const CoreturnStmt &S)
void EmitAutoVarInit(const AutoVarEmission &emission)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
EmitAutoVarAlloca - Emit the alloca and debug information for a local variable.
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
llvm::BasicBlock * getEHResumeBlock(bool isCleanup)
llvm::DenseMap< const Decl *, Address > DeclMapTy
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
CGDebugInfo * getDebugInfo()
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its LValue mapping if it exists, otherwise create one.
llvm::Function * generateAwaitSuspendWrapper(Twine const &CoroName, Twine const &SuspendPointName, CoroutineSuspendExpr const &S)
void EmitCoroutineBody(const CoroutineBodyStmt &S)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
void EmitAutoVarCleanups(const AutoVarEmission &emission)
void EmitAnyExprToMem(const Expr *E, Address Location, Qualifiers Quals, bool IsInitializer)
EmitAnyExprToMem - Emits the code necessary to evaluate an arbitrary expression into the given memory...
RValue EmitAnyExpr(const Expr *E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
EmitAnyExpr - Emit code to compute the specified expression which can have any type.
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
LValue EmitCoyieldLValue(const CoyieldExpr *E)
RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
llvm::SmallVector< const ParmVarDecl *, 4 > FnArgs
Save Parameter Decl for coroutine.
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
llvm::Instruction * CurrentFuncletPad
llvm::LLVMContext & getLLVMContext()
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
llvm::Module & getModule() const
CodeGenTypes & getTypes()
void Error(SourceLocation loc, StringRef error)
Emit a general error that something can't be done.
ASTContext & getContext() const
llvm::LLVMContext & getLLVMContext()
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
Information for lazily generating a cleanup.
stable_iterator stable_begin() const
Create a stable reference to the top of the EH stack.
iterator find(stable_iterator save) const
Turn a stable reference to a scope depth into a unstable pointer to the EH stack.
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
llvm::Value * getPointer(CodeGenFunction &CGF) const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue getIgnored()
static RValue get(llvm::Value *V)
llvm::Value * getPointer() const
static CompoundStmt * Create(const ASTContext &C, ArrayRef< Stmt * > Stmts, FPOptionsOverride FPFeatures, SourceLocation LB, SourceLocation RB)
Represents a 'co_return' statement in the C++ Coroutines TS.
Represents the body of a coroutine.
Represents an expression that might suspend coroutine execution; either a co_await or co_yield expres...
Represents a 'co_yield' expression.
A reference to a declared variable, function, enum, etc.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl.
const Decl * getSingleDecl() const
This represents one expression.
Represents difference between two FPOptions values.
Represents a function declaration or definition.
Represents a prototype with parameter type info, e.g.
GlobalDecl - represents a global declaration.
Represents a parameter to a function.
A (possibly-)qualified type.
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Stmt - This represents one statement.
@ LH_Likely
Branch has the [[likely]] attribute.
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getNewAlign() const
Return the largest alignment for which a suitably-sized allocation with '::operator new(size_t)' is g...
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Represents a variable declaration or definition.
const Expr * getInit() const
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
The JSON file list parser is used to communicate input to InstallAPI.
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
const FunctionProtoType * T
@ Other
Other implicit parameter.
llvm::Value * ResumeEHVar
CodeGenFunction::JumpDest FinalJD
CallExpr const * CoroIdExpr
CodeGenFunction::JumpDest CleanupJD
llvm::BasicBlock * SuspendBB
AwaitKind CurrentAwaitKind
llvm::CallInst * CoroBegin
llvm::CallInst * LastCoroFree
std::unique_ptr< CGCoroData > Data
A jump destination is an abstract label, branching to which may require a jump out through normal cle...
llvm::PointerType * VoidPtrTy
llvm::PointerType * Int8PtrTy