27 using namespace clang;
57 S.
Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
58 <<
"std::experimental::coroutine_traits";
77 if (
auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
78 if (MD->isInstance()) {
102 diag::err_coroutine_type_missing_specialization))
106 assert(RD &&
"specialization of class template is not a class?");
112 auto *Promise = R.getAsSingle<
TypeDecl>();
115 diag::err_implied_std_coroutine_traits_promise_type_not_found)
122 auto buildElaboratedType = [&]() {
131 diag::err_implied_std_coroutine_traits_promise_type_not_class)
132 << buildElaboratedType();
136 diag::err_coroutine_promise_type_incomplete))
149 assert(StdExp &&
"Should already be diagnosed");
154 S.
Diag(Loc, diag::err_implied_coroutine_type_not_found)
155 <<
"std::experimental::coroutine_handle";
161 Result.suppressDiagnostics();
164 S.
Diag(Found->
getLocation(), diag::err_malformed_std_coroutine_handle);
177 if (CoroHandleType.
isNull())
180 diag::err_coroutine_type_missing_specialization))
183 return CoroHandleType;
197 ? diag::err_coroutine_objc_method
198 : diag::err_coroutine_outside_function) << Keyword;
204 enum InvalidFuncDiag {
213 bool Diagnosed =
false;
214 auto DiagInvalid = [&](InvalidFuncDiag
ID) {
215 S.
Diag(Loc, diag::err_coroutine_invalid_func_context) <<
ID << Keyword;
224 if (MD && isa<CXXConstructorDecl>(MD))
225 return DiagInvalid(DiagCtor);
227 else if (MD && isa<CXXDestructorDecl>(MD))
228 return DiagInvalid(DiagDtor);
230 else if (FD->isMain())
231 return DiagInvalid(DiagMain);
237 if (FD->isConstexpr())
238 DiagInvalid(FD->isConsteval() ? DiagConsteval : DiagConstexpr);
241 if (FD->getReturnType()->isUndeducedType())
242 DiagInvalid(DiagAutoRet);
246 if (FD->isVariadic())
247 DiagInvalid(DiagVarargs);
260 assert(!Operators.
isAmbiguous() &&
"Operator lookup cannot be ambiguous");
263 Functions.size() > 1 ||
264 (Functions.size() == 1 && isa<FunctionTemplateDecl>(*Functions.begin()));
268 Functions.begin(), Functions.end());
289 cast<UnresolvedLookupExpr>(R.
get()));
299 assert(BuiltInDecl &&
"failed to find builtin declaration");
303 assert(DeclRef.
isUsable() &&
"Builtin reference cannot fail");
308 assert(!Call.isInvalid() &&
"Call to builtin cannot fail!");
315 if (CoroHandleType.
isNull())
322 S.
Diag(Loc, diag::err_coroutine_handle_missing_member)
353 Base, Base->
getType(), Loc,
false, SS,
360 if (
auto *TE = dyn_cast<TypoExpr>(Result.
get())) {
362 S.
Diag(Loc, diag::err_no_member)
391 Expr *JustAddress = AddressExpr.
get();
410 Expr *CoroHandle = CoroHandleRes.
get();
412 const StringRef Funcs[] = {
"await_ready",
"await_suspend",
"await_resume"};
414 for (
size_t I = 0, N = llvm::array_lengthof(Funcs); I != N; ++I) {
433 diag::note_await_ready_no_bool_conversion);
434 S.
Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
440 CallExpr *AwaitSuspend = cast<CallExpr>(Calls.
Results[ACT::ACT_Suspend]);
449 Calls.
Results[ACT::ACT_Suspend] = TailCallSuspend;
455 diag::err_await_suspend_invalid_return_type)
457 S.
Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
481 assert(isa<FunctionDecl>(CurContext) &&
"not in a function scope");
482 auto *FD = cast<FunctionDecl>(CurContext);
483 bool IsThisDependentType = [&] {
484 if (
auto *MD = dyn_cast_or_null<CXXMethodDecl>(FD))
485 return MD->isInstance() && MD->getThisType()->isDependentType();
496 auto *VD =
VarDecl::Create(Context, FD, FD->getLocation(), FD->getLocation(),
497 &PP.getIdentifierTable().get(
"__promise"), T,
499 CheckVariableDeclarationType(VD);
500 if (VD->isInvalidDecl())
503 auto *ScopeInfo = getCurFunction();
509 if (
auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
514 ThisExpr = CreateBuiltinUnaryOp(Loc, UO_Deref, ThisExpr.
get());
517 CtorArgExprs.push_back(ThisExpr.
get());
521 auto &Moves = ScopeInfo->CoroutineParameterMoves;
522 for (
auto *PD : FD->parameters()) {
523 if (PD->getType()->isDependentType())
527 auto Move = Moves.find(PD);
528 assert(
Move != Moves.end() &&
529 "Coroutine function parameter not inserted into move map");
533 cast<VarDecl>(cast<DeclStmt>(
Move->second)->getSingleDecl());
535 BuildDeclRefExpr(MoveDecl, MoveDecl->getType().getNonReferenceType(),
537 if (RefExpr.isInvalid())
539 CtorArgExprs.push_back(RefExpr.get());
545 CtorArgExprs, FD->getLocation());
548 VD->getLocation(),
true, PLE);
556 ExprResult Result = InitSeq.Perform(*
this, Entity, Kind, CtorArgExprs);
559 }
else if (Result.
get()) {
560 VD->setInit(MaybeCreateExprWithCleanups(Result.
get()));
562 CheckCompleteVariableDeclaration(VD);
565 ActOnUninitializedDecl(VD);
574 bool IsImplicit =
false) {
578 assert(isa<FunctionDecl>(S.
CurContext) &&
"not in a function scope");
581 assert(ScopeInfo &&
"missing function scope for function");
583 if (ScopeInfo->FirstCoroutineStmtLoc.isInvalid() && !IsImplicit)
584 ScopeInfo->setFirstCoroutineStmt(Loc, Keyword);
586 if (ScopeInfo->CoroutinePromise)
593 if (!ScopeInfo->CoroutinePromise)
603 auto *ScopeInfo = getCurFunction();
604 assert(ScopeInfo->CoroutinePromise);
608 if (!ScopeInfo->NeedsCoroutineSuspends)
611 ScopeInfo->setNeedsCoroutineSuspends(
false);
613 auto *Fn = cast<FunctionDecl>(CurContext);
616 auto buildSuspends = [&](StringRef Name)
mutable ->
StmtResult {
624 Suspend = BuildResolvedCoawaitExpr(Loc, Suspend.
get(),
626 Suspend = ActOnFinishFullExpr(Suspend.get(),
false);
627 if (Suspend.isInvalid()) {
628 Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
629 << ((Name ==
"initial_suspend") ? 0 : 1);
630 Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword;
633 return cast<Stmt>(Suspend.get());
636 StmtResult InitSuspend = buildSuspends(
"initial_suspend");
640 StmtResult FinalSuspend = buildSuspends(
"final_suspend");
644 ScopeInfo->setCoroutineSuspends(InitSuspend.
get(), FinalSuspend.
get());
685 S.
Diag(Loc, diag::err_coroutine_unevaluated_context) << Keyword;
689 S.
Diag(Loc, diag::err_coroutine_within_handler) << Keyword;
693 if (!ActOnCoroutineBodyStart(S, Loc,
"co_await")) {
694 CorrectDelayedTyposInExpr(E);
708 return BuildUnresolvedCoawaitExpr(Loc, E,
709 cast<UnresolvedLookupExpr>(Lookup.
get()));
725 auto *Promise = FSI->CoroutinePromise;
726 if (Promise->getType()->isDependentType()) {
737 diag::note_coroutine_promise_implicit_await_transform_required_here)
747 return BuildResolvedCoawaitExpr(Loc, Awaitable.
get());
763 Expr *Res =
new (Context)
771 E = CreateMaterializeTemporaryExpr(E->
getType(), E,
true);
792 if (!ActOnCoroutineBodyStart(S, Loc,
"co_yield")) {
793 CorrectDelayedTyposInExpr(E);
801 *
this, getCurFunction()->CoroutinePromise, Loc,
"yield_value", E);
810 return BuildCoyieldExpr(Loc, Awaitable.
get());
831 E = CreateMaterializeTemporaryExpr(E->
getType(), E,
true);
847 if (!ActOnCoroutineBodyStart(S, Loc,
"co_return")) {
848 CorrectDelayedTyposInExpr(E);
851 return BuildCoreturnStmt(Loc, E);
869 auto NRVOCandidate = this->getCopyElisionCandidate(E->
getType(), E, CES_AsIfByStdMove);
873 ExprResult MoveResult = this->PerformMoveOrCopyInitialization(
874 Entity, NRVOCandidate, E->
getType(), E);
875 if (MoveResult.get())
876 E = MoveResult.get();
883 VarDecl *Promise = FSI->CoroutinePromise;
888 E = MakeFullDiscardedValueExpr(E).get();
894 Expr *PCE = ActOnFinishFullExpr(PC.
get(),
false).
get();
903 assert(Std &&
"Should already be diagnosed");
911 S.
Diag(Loc, diag::err_implicit_coroutine_std_nothrow_type_not_found);
915 auto *VD = Result.getAsSingle<
VarDecl>();
917 Result.suppressDiagnostics();
940 assert(PointeeRD &&
"PromiseType must be a CxxRecordDecl type");
945 if (!OperatorDelete) {
948 const bool Overaligned =
false;
950 Overaligned, DeleteName);
953 return OperatorDelete;
959 assert(Fn && Fn->
isCoroutine() &&
"not a coroutine");
962 "a null body is only allowed for invalid declarations");
970 if (isa<CoroutineBodyStmt>(Body)) {
979 "first coroutine location not set");
995 : S(S), FD(FD), Fn(Fn), Loc(FD.getLocation()),
996 IsPromiseDependentType(
997 !Fn.CoroutinePromise ||
998 Fn.CoroutinePromise->getType()->isDependentType()) {
1002 this->ParamMovesVector.push_back(KV.second);
1005 if (!IsPromiseDependentType) {
1007 assert(PromiseRecordDecl &&
"Type should have already been checked");
1009 this->IsValid = makePromiseStmt() && makeInitialAndFinalSuspend();
1013 assert(this->IsValid &&
"coroutine already invalid");
1014 this->IsValid = makeReturnObject();
1015 if (this->IsValid && !IsPromiseDependentType)
1017 return this->IsValid;
1021 assert(this->IsValid &&
"coroutine already invalid");
1022 assert(!this->IsPromiseDependentType &&
1023 "coroutine cannot have a dependent promise type");
1024 this->IsValid = makeOnException() && makeOnFallthrough() &&
1025 makeGroDeclAndReturnStmt() && makeReturnOnAllocFailure() &&
1026 makeNewAndDeleteExpr();
1027 return this->IsValid;
1030 bool CoroutineStmtBuilder::makePromiseStmt() {
1042 bool CoroutineStmtBuilder::makeInitialAndFinalSuspend() {
1054 if (
auto *DeclRef = dyn_cast_or_null<DeclRefExpr>(E)) {
1055 auto *
Decl = DeclRef->getDecl();
1057 if (Method->isStatic())
1066 diag::err_coroutine_promise_get_return_object_on_allocation_failure)
1067 << PromiseRecordDecl;
1073 bool CoroutineStmtBuilder::makeReturnOnAllocFailure() {
1074 assert(!IsPromiseDependentType &&
1075 "cannot make statement while the promise type is dependent");
1100 if (ReturnObjectOnAllocationFailure.
isInvalid())
1105 if (ReturnStmt.isInvalid()) {
1117 bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
1119 assert(!IsPromiseDependentType &&
1120 "cannot make statement while the promise type is dependent");
1138 bool PassAlignment =
false;
1156 if (
auto *MD = dyn_cast<CXXMethodDecl>(&FD)) {
1164 PlacementArgs.push_back(ThisExpr.
get());
1168 if (PD->getType()->isDependentType())
1172 auto PDLoc = PD->getLocation();
1179 PlacementArgs.push_back(PDRefExpr.
get());
1183 false, PassAlignment, PlacementArgs,
1184 OperatorNew, UnusedResult,
false);
1190 if (!OperatorNew && !PlacementArgs.empty()) {
1191 PlacementArgs.clear();
1194 false, PassAlignment, PlacementArgs,
1195 OperatorNew, UnusedResult,
false);
1205 false, PassAlignment, PlacementArgs,
1206 OperatorNew, UnusedResult);
1209 bool IsGlobalOverload =
1210 OperatorNew && !isa<CXXRecordDecl>(OperatorNew->
getDeclContext());
1214 if (RequiresNoThrowAlloc && (!OperatorNew || IsGlobalOverload)) {
1218 PlacementArgs = {StdNoThrow};
1219 OperatorNew =
nullptr;
1222 false, PassAlignment, PlacementArgs,
1223 OperatorNew, UnusedResult);
1229 if (RequiresNoThrowAlloc) {
1231 if (!FT->isNothrow(
false)) {
1233 diag::err_coroutine_promise_new_requires_nothrow)
1235 S.
Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
1254 if (NewRef.isInvalid())
1258 for (
auto Arg : PlacementArgs)
1259 NewArgs.push_back(Arg);
1282 const auto *OpDeleteType =
1284 if (OpDeleteType->getNumParams() > 1)
1285 DeleteArgs.push_back(FrameSize);
1300 bool CoroutineStmtBuilder::makeOnFallthrough() {
1301 assert(!IsPromiseDependentType &&
1302 "cannot make statement while the promise type is dependent");
1307 bool HasRVoid, HasRValue;
1309 lookupMember(S,
"return_void", PromiseRecordDecl, Loc, HasRVoid);
1311 lookupMember(S,
"return_value", PromiseRecordDecl, Loc, HasRValue);
1314 if (HasRVoid && HasRValue) {
1317 diag::err_coroutine_promise_incompatible_return_functions)
1318 << PromiseRecordDecl;
1320 diag::note_member_first_declared_here)
1323 diag::note_member_first_declared_here)
1326 }
else if (!HasRVoid && !HasRValue) {
1330 diag::err_coroutine_promise_requires_return_function)
1331 << PromiseRecordDecl;
1333 << PromiseRecordDecl;
1335 }
else if (HasRVoid) {
1342 if (Fallthrough.isInvalid())
1350 bool CoroutineStmtBuilder::makeOnException() {
1352 assert(!IsPromiseDependentType &&
1353 "cannot make statement while the promise type is dependent");
1355 const bool RequireUnhandledException = S.
getLangOpts().CXXExceptions;
1357 if (!
lookupMember(S,
"unhandled_exception", PromiseRecordDecl, Loc)) {
1359 RequireUnhandledException
1360 ? diag::err_coroutine_promise_unhandled_exception_required
1362 warn_coroutine_promise_unhandled_exception_required_with_exceptions;
1363 S.
Diag(Loc, DiagID) << PromiseRecordDecl;
1365 << PromiseRecordDecl;
1366 return !RequireUnhandledException;
1374 "unhandled_exception",
None);
1393 bool CoroutineStmtBuilder::makeReturnObject() {
1406 if (
auto *MbrRef = dyn_cast<CXXMemberCallExpr>(E)) {
1407 auto *MethodDecl = MbrRef->getMethodDecl();
1408 S.
Diag(MethodDecl->getLocation(), diag::note_member_declared_here)
1415 bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() {
1416 assert(!IsPromiseDependentType &&
1417 "cannot make statement while the promise type is dependent");
1418 assert(this->
ReturnValue &&
"ReturnValue must be already formed");
1422 "get_return_object type must no longer be dependent");
1425 assert(!FnRetType->isDependentType() &&
1426 "get_return_object type must no longer be dependent");
1428 if (FnRetType->isVoidType()) {
1453 if (GroDecl->isInvalidDecl())
1475 if (GroDeclStmt.isInvalid())
1485 if (ReturnStmt.isInvalid()) {
1489 if (cast<clang::ReturnStmt>(ReturnStmt.get())->getNRVOCandidate() == GroDecl)
1490 GroDecl->setNRVOVariable(
true);
1492 this->ReturnStmt = ReturnStmt.get();
1525 assert(isa<FunctionDecl>(CurContext) &&
"not in a function scope");
1526 auto *FD = cast<FunctionDecl>(CurContext);
1528 auto *ScopeInfo = getCurFunction();
1529 assert(ScopeInfo->CoroutineParameterMoves.empty() &&
1530 "Should not build parameter moves twice");
1533 if (PD->getType()->isDependentType())
1537 BuildDeclRefExpr(PD, PD->getType().getNonReferenceType(),
1542 Expr *CExpr =
nullptr;
1543 if (PD->getType()->getAsCXXRecordDecl() ||
1544 PD->getType()->isRValueReferenceType())
1547 CExpr = PDRefExpr.
get();
1549 auto D =
buildVarDecl(*
this, Loc, PD->getType(), PD->getIdentifier());
1550 AddInitializerToDecl(D, CExpr,
true);
1553 StmtResult Stmt = ActOnDeclStmt(ConvertDeclToDeclGroup(D), Loc, Loc);
1557 ScopeInfo->CoroutineParameterMoves.insert(std::make_pair(PD, Stmt.
get()));
1571 if (!StdCoroutineTraitsCache) {
1572 if (
auto StdExp = lookupStdExperimentalNamespace()) {
1574 &PP.getIdentifierTable().get(
"coroutine_traits"),
1575 FuncLoc, LookupOrdinaryName);
1576 if (!LookupQualifiedName(
Result, StdExp)) {
1577 Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
1578 <<
"std::experimental::coroutine_traits";
1581 if (!(StdCoroutineTraitsCache =
1583 Result.suppressDiagnostics();
1590 return StdCoroutineTraitsCache;
NamespaceDecl * lookupStdExperimentalNamespace()
static Expr * buildStdNoThrowDeclRef(Sema &S, SourceLocation Loc)
Look up the std::nothrow object.
static ExprResult buildMemberCall(Sema &S, Expr *Base, SourceLocation Loc, StringRef Name, MultiExprArg Args)
void setImplicit(bool I=true)
Represents a function declaration or definition.
Represents a 'co_await' expression while the type of the promise is dependent.
bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, DeclarationName Name, FunctionDecl *&Operator, bool Diagnose=true)
NamespaceDecl * getStdNamespace() const
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
ExprResult PerformContextuallyConvertToBool(Expr *From)
PerformContextuallyConvertToBool - Perform a contextual conversion of the expression From to bool (C+...
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
static Expr * maybeTailCall(Sema &S, QualType RetType, Expr *E, SourceLocation Loc)
static VarDecl * buildVarDecl(Sema &S, SourceLocation Loc, QualType Type, IdentifierInfo *II)
Build a variable declaration for move parameter.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc...
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false)
Perform unqualified name lookup starting from a given scope.
static Expr * castForMoving(Sema &S, Expr *E, QualType T=QualType())
Represents a 'co_return' statement in the C++ Coroutines TS.
Stmt - This represents one statement.
bool isSpecificPlaceholderType(unsigned K) const
Test for a specific placeholder type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type...
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Decl - This represents one declaration (or definition), e.g.
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
The base class of the type hierarchy.
OpaqueValueExpr * OpaqueValue
This indicates that the scope corresponds to a function, which means that labels are set here...
StringRef getFirstCoroutineStmtKeyword() const
Represent a C++ namespace.
A container of type source information.
void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, bool MightBeOdrUse=true)
Mark a function referenced, and check whether it is odr-used (C++ [basic.def.odr]p2, C99 6.9p3)
std::pair< Stmt *, Stmt * > CoroutineSuspends
The initial and final coroutine suspend points.
Retains information about a function, method, or block that is currently being parsed.
This file provides some common utility functions for processing Lambda related AST Constructs...
Represents a variable declaration or definition.
ActionResult< Stmt * > StmtResult
bool isStructureType() const
static NestedNameSpecifier * Create(const ASTContext &Context, NestedNameSpecifier *Prefix, IdentifierInfo *II)
Builds a specifier combining a prefix and an identifier.
DeclarationName getLookupName() const
Gets the name to look up.
QualType getReturnType() const
const T * getAs() const
Member-template getAs<specific type>'.
DeclContext * computeDeclContext(QualType T)
Compute the DeclContext that is associated with the given type.
StmtResult BuildCoreturnStmt(SourceLocation KwLoc, Expr *E, bool IsImplicit=false)
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
bool isInvalidDecl() const
static InitializedEntity InitializeResult(SourceLocation ReturnLoc, QualType Type, bool NRVO)
Create the initialization entity for the result of a function.
static bool diagReturnOnAllocFailure(Sema &S, Expr *E, CXXRecordDecl *PromiseRecordDecl, FunctionScopeInfo &Fn)
Defines the clang::Expr interface and subclasses for C++ expressions.
llvm::SmallMapVector< ParmVarDecl *, Stmt *, 4 > CoroutineParameterMoves
A mapping between the coroutine function parameters that were moved to the coroutine frame...
bool FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, AllocationFunctionScope NewScope, AllocationFunctionScope DeleteScope, QualType AllocType, bool IsArray, bool &PassAlignment, MultiExprArg PlaceArgs, FunctionDecl *&OperatorNew, FunctionDecl *&OperatorDelete, bool Diagnose=true)
Finds the overloads of operator new and delete that are appropriate for the allocation.
One of these records is kept for each identifier that is lexed.
static ReadySuspendResumeResult buildCoawaitCalls(Sema &S, VarDecl *CoroPromise, SourceLocation Loc, Expr *E)
Build calls to await_ready, await_suspend, and await_resume for a co_await expression.
A C++ nested-name-specifier augmented with source location information.
static InitializationKind CreateForInit(SourceLocation Loc, bool DirectInit, Expr *Init)
Create an initialization from an initializer (which, for direct initialization from a parenthesized l...
ArrayRef< QualType > getParamTypes() const
bool ActOnCoroutineBodyStart(Scope *S, SourceLocation KwLoc, StringRef Keyword)
SourceLocation getBeginLoc() const LLVM_READONLY
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
static FunctionDecl * findDeleteForPromise(Sema &S, SourceLocation Loc, QualType PromiseType)
bool isReferenceType() const
SourceLocation getBeginLoc() const LLVM_READONLY
SourceLocation FirstSEHTryLoc
First SEH '__try' statement in the current function.
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
ArrayRef< ParmVarDecl * > parameters() const
static ParenListExpr * Create(const ASTContext &Ctx, SourceLocation LParenLoc, ArrayRef< Expr *> Exprs, SourceLocation RParenLoc)
Create a paren list.
bool isCompleteType(SourceLocation Loc, QualType T)
Represents the results of name lookup.
ExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, const UnresolvedSetImpl &Fns, Expr *input, bool RequiresADL=true)
Create a unary operation that may resolve to an overloaded operator.
static ExprResult buildOperatorCoawaitCall(Sema &SemaRef, SourceLocation Loc, Expr *E, UnresolvedLookupExpr *Lookup)
Build a call to 'operator co_await' if there is a suitable operator for the given expression...
DeclRefExpr * BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
A convenient class for passing around template argument information.
Stmt * ReturnStmtOnAllocFailure
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
Represents a declaration of a type.
static ExprResult buildPromiseCall(Sema &S, VarDecl *Promise, SourceLocation Loc, StringRef Name, MultiExprArg Args)
static QualType lookupPromiseType(Sema &S, const FunctionDecl *FD, SourceLocation KwLoc)
Look up the std::coroutine_traits<...>::promise_type for the given function type. ...
Scope - A scope is a transient data structure that is used while parsing the program.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
ExprResult ActOnCXXThis(SourceLocation loc)
void append(iterator I, iterator E)
Represents a C++ nested-name-specifier or a global scope specifier.
void CheckVariableDeclarationType(VarDecl *NewVD)
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
const LangOptions & getLangOpts() const
bool isLambdaCallOperator(const CXXMethodDecl *MD)
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5...
ExprResult BuildMemberReferenceExpr(Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, const Scope *S, ActOnMemberAccessExtraArgs *ExtraArgs=nullptr)
Member name lookup, which finds the names of class/struct/union members.
ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS, LookupResult &R, bool NeedsADL, bool AcceptInvalidDecl=false)
static UnresolvedLookupExpr * Create(const ASTContext &Context, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded, UnresolvedSetIterator Begin, UnresolvedSetIterator End)
unsigned getFlags() const
getFlags - Return the flags for this scope.
QualType CheckTemplateIdType(TemplateName Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs)
Sema - This implements semantic analysis and AST building for C.
StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Represents a prototype with parameter type info, e.g.
StmtResult BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp)
StmtResult ActOnCoreturnStmt(Scope *S, SourceLocation KwLoc, Expr *E)
DeclarationNameTable DeclarationNames
const char * getName(unsigned ID) const
Return the identifier name for the specified builtin, e.g.
bool buildCoroutineParameterMoves(SourceLocation Loc)
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location, which defaults to the empty location.
Scope * getCurScope() const
Retrieve the parser's current scope.
This represents one expression.
ClassTemplateDecl * lookupCoroutineTraits(SourceLocation KwLoc, SourceLocation FuncLoc)
ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false)
BuildCallExpr - Handle a call to Fn with the specified array of arguments.
const T * castAs() const
Member-template castAs<specific type>.
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
StmtResult BuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs)
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Defines the clang::Preprocessor interface.
static bool isWithinCatchScope(Scope *S)
DeclContext * getDeclContext()
ExprResult BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, TypeSourceInfo *Ty, Expr *E, SourceRange AngleBrackets, SourceRange Parens)
static bool IsOverloaded(const UnresolvedSetImpl &Functions)
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Represents a C++ template name within the type system.
decls_iterator decls_begin() const
bool RequireCompleteType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
static bool isValidCoroutineContext(Sema &S, SourceLocation Loc, StringRef Keyword)
bool buildStatements()
Build the coroutine body statements, including the "promise dependent" statements when the promise ty...
static FunctionScopeInfo * checkCoroutineContext(Sema &S, SourceLocation Loc, StringRef Keyword, bool IsImplicit=false)
Check that this is a context in which a coroutine suspension can appear.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;...
static Expr * buildBuiltinCall(Sema &S, SourceLocation Loc, Builtin::ID Id, MultiExprArg CallArgs)
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
The result type of a method or function.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
VarDecl * CoroutinePromise
The promise object for this coroutine, if any.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
static CoroutineBodyStmt * Create(const ASTContext &C, CtorArgs const &Args)
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
QualType getElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, QualType NamedType, TagDecl *OwnedTagDecl=nullptr) const
Encodes a location in the source.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
QualType getReturnType() const
void FinalizeDeclaration(Decl *D)
FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform any semantic actions neces...
FunctionDecl * FindUsualDeallocationFunction(SourceLocation StartLoc, bool CanProvideSize, bool Overaligned, DeclarationName Name)
IdentifierTable & getIdentifierTable()
static QualType lookupCoroutineHandleType(Sema &S, QualType PromiseType, SourceLocation Loc)
Look up the std::experimental::coroutine_handle<PromiseType>.
Represents a static or instance method of a struct/union/class.
Only look for allocation functions in the scope of the allocated class.
ArrayRef< Stmt * > ParamMoves
static void checkSuspensionContext(Sema &S, SourceLocation Loc, StringRef Keyword)
Describes the kind of initialization being performed, along with location information for tokens rela...
SourceLocation FirstCoroutineStmtLoc
First coroutine statement in the current function.
QualType BuildReferenceType(QualType T, bool LValueRef, SourceLocation Loc, DeclarationName Entity)
Build a reference type.
An rvalue ref-qualifier was provided (&&).
void addArgument(const TemplateArgumentLoc &Loc)
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool isPlaceholderType() const
Test for a type which does not represent an actual type-system type but is instead used as a placehol...
Represents a template argument.
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
const Scope * getParent() const
getParent - Return the scope that this is nested in.
void clearDelayedTypo(TypoExpr *TE)
Clears the state of the given TypoExpr.
CoroutineStmtBuilder(Sema &S, FunctionDecl &FD, sema::FunctionScopeInfo &Fn, Stmt *Body)
Construct a CoroutineStmtBuilder and initialize the promise statement and initial/final suspends from...
Represents a 'co_yield' expression.
The name of a declaration.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
bool isBooleanType() const
A set of unresolved declarations.
ExprResult BuildUnresolvedCoawaitExpr(SourceLocation KwLoc, Expr *E, UnresolvedLookupExpr *Lookup)
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
static ExprResult buildCoroutineHandle(Sema &S, QualType PromiseType, SourceLocation Loc)
SourceLocation FirstReturnLoc
First 'return' statement in the current function.
StmtResult ActOnFinishFullStmt(Stmt *Stmt)
const UnresolvedSetImpl & asUnresolvedSet() const
Represents the body of a coroutine.
Location wrapper for a TemplateArgument.
ExprResult ActOnCoawaitExpr(Scope *S, SourceLocation KwLoc, Expr *E)
Look for allocation functions in both the global scope and in the scope of the allocated class...
Represents a 'co_await' expression.
static ExprResult buildOperatorCoawaitLookupExpr(Sema &SemaRef, Scope *S, SourceLocation Loc)
ExprResult BuildCoyieldExpr(SourceLocation KwLoc, Expr *E)
ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *InputExpr)
ExprResult ActOnCoyieldExpr(Scope *S, SourceLocation KwLoc, Expr *E)
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
Call-style initialization (C++98)
ExprResult PerformMoveOrCopyInitialization(const InitializedEntity &Entity, const VarDecl *NRVOCandidate, QualType ResultType, Expr *Value, bool AllowNRVO=true)
Perform the initialization of a potentially-movable value, which is the result of return value...
Describes the sequence of initializations required to initialize a given object or reference with a s...
Only look for allocation functions in the global scope.
Represents a C++ struct/union/class.
QualType getRValueReferenceType(QualType T) const
Return the uniqued reference to the type for an rvalue reference to the specified type...
sema::FunctionScopeInfo * getCurFunction() const
Builtin::Context & BuiltinInfo
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Declaration of a class template.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool hasInvalidCoroutineSuspends() const
void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body)
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
ExprResult BuildResolvedCoawaitExpr(SourceLocation KwLoc, Expr *E, bool IsImplicit=false)
bool buildDependentStatements()
Build the coroutine body statements that require a non-dependent promise type in order to construct...
An l-value expression is a reference to an object with independent storage.
A trivial tuple used to represent a source range.
This is the scope of a C++ catch statement.
This represents a decl that may have a name.
No keyword precedes the qualified type name.
Describes an entity that is being initialized.
Look up of an operator name (e.g., operator+) for use with operator overloading.
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
decls_iterator decls_end() const
static LookupResult lookupMember(Sema &S, const char *Name, CXXRecordDecl *RD, SourceLocation Loc, bool &Res)
SourceLocation getLocation() const
VarDecl * buildCoroutinePromise(SourceLocation Loc)
static void noteMemberDeclaredHere(Sema &S, Expr *E, FunctionScopeInfo &Fn)