15#include "llvm/ADT/ScopeExit.h"
20using namespace CodeGen;
23using llvm::BasicBlock;
26enum class AwaitKind {
Init,
Normal, Yield, Final };
27static constexpr llvm::StringLiteral AwaitKindStr[] = {
"init",
"await",
"yield",
90 CodeGenFunction::CGCoroInfo &
CurCoro,
91 llvm::CallInst *CoroId,
92 CallExpr const *CoroIdExpr =
nullptr) {
95 CGF.
CGM.
Error(CoroIdExpr->getBeginLoc(),
96 "only one __builtin_coro_id can be used in a function");
98 CGF.
CGM.
Error(CoroIdExpr->getBeginLoc(),
99 "__builtin_coro_id shall not be used in a C++ coroutine");
101 llvm_unreachable(
"EmitCoroutineBodyStatement called twice?");
115 case AwaitKind::Init:
116 case AwaitKind::Final:
118 case AwaitKind::Normal:
121 case AwaitKind::Yield:
127 Twine(
No).toVector(Prefix);
145 if (
const auto *CE = dyn_cast<CallExpr>(S)) {
146 const auto *Callee = CE->getDirectCallee();
157 if (
const auto *TE = dyn_cast<CXXBindTemporaryExpr>(S)) {
162 const auto *Dtor = TE->getTemporary()->getDestructor();
169 for (
const auto *child : S->children())
217 struct LValueOrRValue {
225 bool ignoreResult,
bool forLValue) {
226 auto *E = S.getCommonExpr();
230 auto UnbindCommonOnExit =
231 llvm::make_scope_exit([&] { CommonBinder.unbind(CGF); });
235 BasicBlock *SuspendBlock = CGF.
createBasicBlock(Prefix + Twine(
".suspend"));
236 BasicBlock *CleanupBlock = CGF.
createBasicBlock(Prefix + Twine(
".cleanup"));
245 llvm::Function *CoroSave = CGF.
CGM.
getIntrinsic(llvm::Intrinsic::coro_save);
246 auto *NullPtr = llvm::ConstantPointerNull::get(CGF.
CGM.
Int8PtrTy);
247 auto *SaveCall =
Builder.CreateCall(CoroSave, {NullPtr});
250 CGF.
CurFn->getName(), Prefix, S);
255 "expected to be called in coroutine context");
258 SuspendIntrinsicCallArgs.push_back(
261 SuspendIntrinsicCallArgs.push_back(CGF.
CurCoro.
Data->CoroBegin);
262 SuspendIntrinsicCallArgs.push_back(SuspendWrapper);
264 const auto SuspendReturnType = S.getSuspendReturnType();
265 llvm::Intrinsic::ID AwaitSuspendIID;
267 switch (SuspendReturnType) {
269 AwaitSuspendIID = llvm::Intrinsic::coro_await_suspend_void;
272 AwaitSuspendIID = llvm::Intrinsic::coro_await_suspend_bool;
275 AwaitSuspendIID = llvm::Intrinsic::coro_await_suspend_handle;
279 llvm::Function *AwaitSuspendIntrinsic = CGF.
CGM.
getIntrinsic(AwaitSuspendIID);
281 const auto AwaitSuspendCanThrow =
StmtCanThrow(S.getSuspendExpr());
283 llvm::CallBase *SuspendRet =
nullptr;
285 if (AwaitSuspendCanThrow)
290 SuspendIntrinsicCallArgs);
295 switch (SuspendReturnType) {
297 assert(SuspendRet->getType()->isVoidTy());
300 assert(SuspendRet->getType()->isIntegerTy());
303 BasicBlock *RealSuspendBlock =
305 CGF.
Builder.CreateCondBr(SuspendRet, RealSuspendBlock, ReadyBlock);
310 assert(SuspendRet->getType()->isPointerTy());
312 auto ResumeIntrinsic = CGF.
CGM.
getIntrinsic(llvm::Intrinsic::coro_resume);
313 Builder.CreateCall(ResumeIntrinsic, SuspendRet);
319 const bool IsFinalSuspend = (Kind == AwaitKind::Final);
320 llvm::Function *CoroSuspend =
322 auto *SuspendResult =
Builder.CreateCall(
323 CoroSuspend, {SaveCall,
Builder.getInt1(IsFinalSuspend)});
346 auto Loc = S.getResumeExpr()->getExprLoc();
368 Res.RV = CGF.
EmitAnyExpr(S.getResumeExpr(), aggSlot, ignoreResult);
378 ignoreResult,
false).RV;
384 aggSlot, ignoreResult,
false).RV;
389 const Expr *RV = S.getOperand();
393 RunCleanupsScope cleanupScope(*
this);
407 assert(isa<CallExpr>(RE) &&
"unexpected suspend expression type");
408 return cast<CallExpr>(RE)->getCallReturnType(Ctx);
414 Twine
const &SuspendPointName,
416 std::string FuncName =
417 (CoroName +
".__await_suspend_wrapper__" + SuspendPointName).str();
425 QualType ReturnTy = S.getSuspendExpr()->getType();
427 args.push_back(&AwaiterDecl);
428 args.push_back(&FrameDecl);
435 llvm::Function *Fn = llvm::Function::Create(
436 LTy, llvm::GlobalValue::PrivateLinkage, FuncName, &
CGM.
getModule());
438 Fn->addParamAttr(0, llvm::Attribute::AttrKind::NonNull);
439 Fn->addParamAttr(0, llvm::Attribute::AttrKind::NoUndef);
441 Fn->addParamAttr(1, llvm::Attribute::AttrKind::NoUndef);
443 Fn->setMustProgress();
444 Fn->addFnAttr(llvm::Attribute::AttrKind::AlwaysInline);
457 *
this, S.getOpaqueValue(), AwaiterLValue);
461 auto UnbindCommonOnExit =
462 llvm::make_scope_exit([&] { AwaiterBinder.unbind(*
this); });
463 if (SuspendRet !=
nullptr) {
464 Fn->addRetAttr(llvm::Attribute::AttrKind::NoUndef);
476 "Can't have a scalar return unless the return type is a "
486 "Can't have a scalar return unless the return type is a "
495struct GetParamRef :
public StmtVisitor<GetParamRef> {
500 assert(
Expr ==
nullptr &&
"multilple declref in param move");
503 void VisitStmt(
Stmt *S) {
504 for (
auto *
C : S->children()) {
517 struct ParamReferenceReplacerRAII {
518 CodeGenFunction::DeclMapTy SavedLocals;
519 CodeGenFunction::DeclMapTy& LocalDeclMap;
521 ParamReferenceReplacerRAII(CodeGenFunction::DeclMapTy &LocalDeclMap)
522 : LocalDeclMap(LocalDeclMap) {}
531 Visitor.Visit(
const_cast<Expr*
>(InitExpr));
532 assert(Visitor.Expr);
536 auto it = LocalDeclMap.find(PD);
537 assert(it != LocalDeclMap.end() &&
"parameter is not found");
538 SavedLocals.insert({ PD, it->second });
540 auto copyIt = LocalDeclMap.find(VD);
541 assert(copyIt != LocalDeclMap.end() &&
"parameter copy is not found");
542 it->second = copyIt->getSecond();
545 ~ParamReferenceReplacerRAII() {
546 for (
auto&& SavedLocal : SavedLocals) {
547 LocalDeclMap.insert({SavedLocal.first, SavedLocal.second});
560 BundleList.emplace_back(
"funclet", EHPad);
572 auto *NullPtr = llvm::ConstantPointerNull::get(CGF.
Int8PtrTy);
573 llvm::Function *CoroEndFn = CGM.getIntrinsic(llvm::Intrinsic::coro_end);
577 CGF.
Builder.CreateCall(CoroEndFn,
578 {NullPtr, CGF.
Builder.getTrue(),
579 llvm::ConstantTokenNone::get(CoroEndFn->getContext())},
581 if (Bundles.empty()) {
586 CGF.
Builder.CreateCondBr(CoroEnd, ResumeBB, CleanupContBB);
609 BasicBlock *SaveInsertBlock = CGF.
Builder.GetInsertBlock();
621 CGF.
CGM.
Error(Deallocate->getBeginLoc(),
622 "Deallocation expressoin does not refer to coro.free");
627 auto *InsertPt = SaveInsertBlock->getTerminator();
628 CoroFree->moveBefore(InsertPt);
629 CGF.
Builder.SetInsertPoint(InsertPt);
632 auto *NullPtr = llvm::ConstantPointerNull::get(CGF.
Int8PtrTy);
633 auto *Cond = CGF.
Builder.CreateICmpNE(CoroFree, NullPtr);
634 CGF.
Builder.CreateCondBr(Cond, FreeBB, AfterFreeBB);
637 InsertPt->eraseFromParent();
638 CGF.
Builder.SetInsertPoint(AfterFreeBB);
640 explicit CallCoroDelete(
Stmt *DeallocStmt) : Deallocate(DeallocStmt) {}
645struct GetReturnObjectManager {
650 bool DirectEmit =
false;
653 CodeGenFunction::AutoVarEmission GroEmission;
656 : CGF(CGF), Builder(CGF.Builder), S(S), GroActiveFlag(
Address::invalid()),
678 auto *RVI = S.getReturnValueInit();
679 assert(RVI &&
"expected RVI");
680 auto GroType = RVI->getType();
690 void EmitGroAlloca() {
694 auto *GroDeclStmt = dyn_cast_or_null<DeclStmt>(S.getResultDecl());
700 auto *GroVarDecl = cast<VarDecl>(GroDeclStmt->getSingleDecl());
705 Builder.CreateStore(Builder.getFalse(), GroActiveFlag);
708 auto *GroAlloca = dyn_cast_or_null<llvm::AllocaInst>(
709 GroEmission.getOriginalAllocatedAddress().getPointer());
710 assert(GroAlloca &&
"expected alloca to be emitted");
711 GroAlloca->setMetadata(llvm::LLVMContext::MD_coro_outside_frame,
722 if (
auto *Cleanup = dyn_cast<EHCleanupScope>(&*
b)) {
723 assert(!Cleanup->hasActiveFlag() &&
"cleanup already has active flag?");
724 Cleanup->setActiveFlag(GroActiveFlag);
725 Cleanup->setTestFlagInEHCleanup();
726 Cleanup->setTestFlagInNormalCleanup();
747 S.getReturnValue()->getType().getQualifiers(),
753 if (!GroActiveFlag.
isValid()) {
761 Builder.CreateStore(Builder.getTrue(), GroActiveFlag);
769 const bool CanFallthrough = CGF.
Builder.GetInsertBlock();
771 if (
Stmt *OnFallthrough = S.getFallthroughHandler())
776 auto *NullPtr = llvm::ConstantPointerNull::get(
Builder.getPtrTy());
778 unsigned NewAlign = TI.
getNewAlign() / TI.getCharWidth();
780 auto *EntryBB =
Builder.GetInsertBlock();
786 auto *CoroId =
Builder.CreateCall(
788 {Builder.getInt32(NewAlign), NullPtr, NullPtr, NullPtr});
791 assert(ShouldEmitLifetimeMarkers &&
792 "Must emit lifetime intrinsics for coroutines");
796 auto *CoroAlloc =
Builder.CreateCall(
799 Builder.CreateCondBr(CoroAlloc, AllocBB, InitBB);
803 auto *AllocOrInvokeContBB =
Builder.GetInsertBlock();
806 if (
auto *RetOnAllocFailure = S.getReturnStmtOnAllocFailure()) {
810 auto *NullPtr = llvm::ConstantPointerNull::get(
Int8PtrTy);
811 auto *Cond =
Builder.CreateICmpNE(AllocateCall, NullPtr);
814 Builder.CreateCondBr(Cond, InitBB, RetOnFailureBB);
828 Phi->addIncoming(NullPtr, EntryBB);
829 Phi->addIncoming(AllocateCall, AllocOrInvokeContBB);
830 auto *CoroBegin =
Builder.CreateCall(
834 GetReturnObjectManager GroManager(*
this, S);
835 GroManager.EmitGroAlloca();
840 ParamReferenceReplacerRAII ParamReplacer(LocalDeclMap);
841 CodeGenFunction::RunCleanupsScope ResumeScope(*
this);
847 (ParamMoves.size() == 0 || (ParamMoves.size() ==
FnArgs.size())) &&
848 "ParamMoves and FnArgs should be the same size for coroutine function");
849 if (ParamMoves.size() ==
FnArgs.size() && DI)
850 for (
const auto Pair : llvm::zip(
FnArgs, ParamMoves))
852 {std::get<0>(Pair), std::get<1>(Pair)});
857 for (
auto *PM : S.getParamMoves()) {
859 ParamReplacer.addCopy(cast<DeclStmt>(PM));
868 auto *PromiseAddrVoidPtr =
new llvm::BitCastInst(
872 CoroId->setArgOperand(1, PromiseAddrVoidPtr);
875 GroManager.EmitGroInit();
880 CurCoro.
Data->ExceptionHandler = S.getExceptionHandler();
884 CurCoro.
Data->CurrentAwaitKind = AwaitKind::Normal;
892 BasicBlock *ContBB =
nullptr;
898 Builder.CreateCondBr(SkipBody, ContBB, BodyBB);
902 auto Loc = S.getBeginLoc();
920 const bool CanFallthrough =
Builder.GetInsertBlock();
921 const bool HasCoreturns =
CurCoro.
Data->CoreturnCount > 0;
922 if (CanFallthrough || HasCoreturns) {
938 llvm::ConstantTokenNone::get(CoroEnd->getContext())});
940 if (
Stmt *Ret = S.getReturnStmt()) {
943 if (GroManager.DirectEmit)
944 cast<ReturnStmt>(Ret)->setRetValue(
nullptr);
949 CurFn->setPresplitCoroutine();
952 RD && RD->
hasAttr<CoroOnlyDestroyWhenCompleteAttr>())
953 CurFn->setCoroDestroyOnlyWhenComplete();
965 case llvm::Intrinsic::coro_frame: {
975 "has been used earlier in this function");
976 auto *NullPtr = llvm::ConstantPointerNull::get(
Builder.getPtrTy());
979 case llvm::Intrinsic::coro_size: {
986 case llvm::Intrinsic::coro_align: {
996 case llvm::Intrinsic::coro_alloc:
997 case llvm::Intrinsic::coro_begin:
998 case llvm::Intrinsic::coro_free: {
1004 " been used earlier in this function");
1010 case llvm::Intrinsic::coro_suspend:
1018 if (IID == llvm::Intrinsic::coro_end)
1022 llvm::CallInst *
Call =
Builder.CreateCall(F, Args);
1028 if (IID == llvm::Intrinsic::coro_id) {
1031 else if (IID == llvm::Intrinsic::coro_begin) {
1035 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.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
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]).
SourceLocation getBeginLoc() const LLVM_READONLY
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 * 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.
static OpaqueValueMappingData bind(CodeGenFunction &CGF, const OpaqueValueExpr *ov, const Expr *e)
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
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...
LValue EmitCoawaitLValue(const CoawaitExpr *E)
LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its LValue mapping if it exists, otherwise create one.
AwaitSuspendWrapperInfo CurAwaitSuspendWrapper
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
llvm::BasicBlock * getEHResumeBlock(bool isCleanup)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
llvm::Function * generateAwaitSuspendWrapper(Twine const &CoroName, Twine const &SuspendPointName, CoroutineSuspendExpr const &S)
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...
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...
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
void EmitAutoVarInit(const AutoVarEmission &emission)
LValue EmitCoyieldLValue(const CoyieldExpr *E)
RValue EmitCoroutineIntrinsic(const CallExpr *E, unsigned int IID)
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 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()
void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
void EmitCoroutineBody(const CoroutineBodyStmt &S)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
void EmitAutoVarCleanups(const AutoVarEmission &emission)
llvm::CallBase * EmitCallOrInvoke(llvm::FunctionCallee Callee, ArrayRef< llvm::Value * > Args, const Twine &Name="")
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T)
llvm::SmallVector< const ParmVarDecl *, 4 > FnArgs
Save Parameter Decl for coroutine.
RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
void EmitCoreturnStmt(const CoreturnStmt &S)
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
llvm::Instruction * CurrentFuncletPad
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs=std::nullopt)
EmitStmt - Emit the code for the statement.
llvm::LLVMContext & getLLVMContext()
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
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=std::nullopt)
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)
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...
Expr * getResumeExpr() const
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.
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.
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...
const T * getAs() const
Member-template getAs<specific type>'.
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::IntegerType * SizeTy
llvm::PointerType * Int8PtrTy