28 using namespace clang;
58 S.
Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
59 <<
"std::experimental::coroutine_traits";
78 if (
auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
79 if (MD->isInstance()) {
103 diag::err_coroutine_type_missing_specialization))
107 assert(RD &&
"specialization of class template is not a class?");
113 auto *Promise = R.getAsSingle<
TypeDecl>();
116 diag::err_implied_std_coroutine_traits_promise_type_not_found)
123 auto buildElaboratedType = [&]() {
132 diag::err_implied_std_coroutine_traits_promise_type_not_class)
133 << buildElaboratedType();
137 diag::err_coroutine_promise_type_incomplete))
150 assert(StdExp &&
"Should already be diagnosed");
155 S.
Diag(Loc, diag::err_implied_coroutine_type_not_found)
156 <<
"std::experimental::coroutine_handle";
162 Result.suppressDiagnostics();
165 S.
Diag(Found->
getLocation(), diag::err_malformed_std_coroutine_handle);
178 if (CoroHandleType.
isNull())
181 diag::err_coroutine_type_missing_specialization))
184 return CoroHandleType;
199 S.
Diag(Loc, diag::err_coroutine_unevaluated_context) << Keyword;
211 ? diag::err_coroutine_objc_method
212 : diag::err_coroutine_outside_function) << Keyword;
218 enum InvalidFuncDiag {
228 bool Diagnosed =
false;
229 auto DiagInvalid = [&](InvalidFuncDiag
ID) {
230 S.
Diag(Loc, diag::err_coroutine_invalid_func_context) <<
ID << Keyword;
239 if (MD && isa<CXXConstructorDecl>(MD))
240 return DiagInvalid(DiagCtor);
242 else if (MD && isa<CXXDestructorDecl>(MD))
243 return DiagInvalid(DiagDtor);
248 else if (MD && MD->isCopyAssignmentOperator())
249 return DiagInvalid(DiagCopyAssign);
250 else if (MD && MD->isMoveAssignmentOperator())
251 return DiagInvalid(DiagMoveAssign);
253 else if (FD->isMain())
254 return DiagInvalid(DiagMain);
260 if (FD->isConstexpr())
261 DiagInvalid(DiagConstexpr);
264 if (FD->getReturnType()->isUndeducedType())
265 DiagInvalid(DiagAutoRet);
269 if (FD->isVariadic())
270 DiagInvalid(DiagVarargs);
283 assert(!Operators.
isAmbiguous() &&
"Operator lookup cannot be ambiguous");
286 Functions.size() > 1 ||
287 (Functions.size() == 1 && isa<FunctionTemplateDecl>(*Functions.begin()));
291 Functions.begin(), Functions.end());
312 cast<UnresolvedLookupExpr>(R.
get()));
322 assert(BuiltInDecl &&
"failed to find builtin declaration");
326 assert(DeclRef.
isUsable() &&
"Builtin reference cannot fail");
331 assert(!Call.isInvalid() &&
"Call to builtin cannot fail!");
338 if (CoroHandleType.
isNull())
345 S.
Diag(Loc, diag::err_coroutine_handle_missing_member)
376 Base, Base->
getType(), Loc,
false, SS,
383 if (
auto *TE = dyn_cast<TypoExpr>(Result.
get())) {
385 S.
Diag(Loc, diag::err_no_member)
414 Expr *JustAddress = AddressExpr.
get();
433 Expr *CoroHandle = CoroHandleRes.
get();
435 const StringRef Funcs[] = {
"await_ready",
"await_suspend",
"await_resume"};
437 for (
size_t I = 0, N = llvm::array_lengthof(Funcs); I != N; ++I) {
456 diag::note_await_ready_no_bool_conversion);
457 S.
Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
463 CallExpr *AwaitSuspend = cast<CallExpr>(Calls.
Results[ACT::ACT_Suspend]);
472 Calls.
Results[ACT::ACT_Suspend] = TailCallSuspend;
478 diag::err_await_suspend_invalid_return_type)
480 S.
Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
504 assert(isa<FunctionDecl>(CurContext) &&
"not in a function scope");
505 auto *FD = cast<FunctionDecl>(CurContext);
506 bool IsThisDependentType = [&] {
507 if (
auto *MD = dyn_cast_or_null<CXXMethodDecl>(FD))
508 return MD->isInstance() && MD->getThisType()->isDependentType();
519 auto *VD =
VarDecl::Create(Context, FD, FD->getLocation(), FD->getLocation(),
520 &PP.getIdentifierTable().get(
"__promise"), T,
522 CheckVariableDeclarationType(VD);
523 if (VD->isInvalidDecl())
526 auto *ScopeInfo = getCurFunction();
532 if (
auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
537 ThisExpr = CreateBuiltinUnaryOp(Loc, UO_Deref, ThisExpr.
get());
540 CtorArgExprs.push_back(ThisExpr.
get());
544 auto &Moves = ScopeInfo->CoroutineParameterMoves;
545 for (
auto *PD : FD->parameters()) {
546 if (PD->getType()->isDependentType())
550 auto Move = Moves.find(PD);
551 assert(
Move != Moves.end() &&
552 "Coroutine function parameter not inserted into move map");
556 cast<VarDecl>(cast<DeclStmt>(
Move->second)->getSingleDecl());
558 BuildDeclRefExpr(MoveDecl, MoveDecl->getType().getNonReferenceType(),
560 if (RefExpr.isInvalid())
562 CtorArgExprs.push_back(RefExpr.get());
568 CtorArgExprs, FD->getLocation());
571 VD->getLocation(),
true, PLE);
579 ExprResult Result = InitSeq.Perform(*
this, Entity, Kind, CtorArgExprs);
582 }
else if (Result.
get()) {
583 VD->setInit(MaybeCreateExprWithCleanups(Result.
get()));
585 CheckCompleteVariableDeclaration(VD);
588 ActOnUninitializedDecl(VD);
597 bool IsImplicit =
false) {
601 assert(isa<FunctionDecl>(S.
CurContext) &&
"not in a function scope");
604 assert(ScopeInfo &&
"missing function scope for function");
606 if (ScopeInfo->FirstCoroutineStmtLoc.isInvalid() && !IsImplicit)
607 ScopeInfo->setFirstCoroutineStmt(Loc, Keyword);
609 if (ScopeInfo->CoroutinePromise)
616 if (!ScopeInfo->CoroutinePromise)
626 auto *ScopeInfo = getCurFunction();
627 assert(ScopeInfo->CoroutinePromise);
631 if (!ScopeInfo->NeedsCoroutineSuspends)
634 ScopeInfo->setNeedsCoroutineSuspends(
false);
636 auto *Fn = cast<FunctionDecl>(CurContext);
639 auto buildSuspends = [&](StringRef Name)
mutable ->
StmtResult {
647 Suspend = BuildResolvedCoawaitExpr(Loc, Suspend.
get(),
649 Suspend = ActOnFinishFullExpr(Suspend.get());
650 if (Suspend.isInvalid()) {
651 Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
652 << ((Name ==
"initial_suspend") ? 0 : 1);
653 Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword;
656 return cast<Stmt>(Suspend.get());
659 StmtResult InitSuspend = buildSuspends(
"initial_suspend");
663 StmtResult FinalSuspend = buildSuspends(
"final_suspend");
667 ScopeInfo->setCoroutineSuspends(InitSuspend.
get(), FinalSuspend.
get());
673 if (!ActOnCoroutineBodyStart(S, Loc,
"co_await")) {
674 CorrectDelayedTyposInExpr(E);
686 return BuildUnresolvedCoawaitExpr(Loc, E,
687 cast<UnresolvedLookupExpr>(Lookup.
get()));
703 auto *Promise = FSI->CoroutinePromise;
704 if (Promise->getType()->isDependentType()) {
715 diag::note_coroutine_promise_implicit_await_transform_required_here)
725 return BuildResolvedCoawaitExpr(Loc, Awaitable.
get());
741 Expr *Res =
new (Context)
749 E = CreateMaterializeTemporaryExpr(E->
getType(), E,
true);
770 if (!ActOnCoroutineBodyStart(S, Loc,
"co_yield")) {
771 CorrectDelayedTyposInExpr(E);
777 *
this, getCurFunction()->CoroutinePromise, Loc,
"yield_value", E);
786 return BuildCoyieldExpr(Loc, Awaitable.
get());
807 E = CreateMaterializeTemporaryExpr(E->
getType(), E,
true);
823 if (!ActOnCoroutineBodyStart(S, Loc,
"co_return")) {
824 CorrectDelayedTyposInExpr(E);
827 return BuildCoreturnStmt(Loc, E);
845 auto NRVOCandidate = this->getCopyElisionCandidate(E->
getType(), E, CES_AsIfByStdMove);
849 ExprResult MoveResult = this->PerformMoveOrCopyInitialization(
850 Entity, NRVOCandidate, E->
getType(), E);
851 if (MoveResult.get())
852 E = MoveResult.get();
859 VarDecl *Promise = FSI->CoroutinePromise;
864 E = MakeFullDiscardedValueExpr(E).get();
870 Expr *PCE = ActOnFinishFullExpr(PC.
get()).
get();
879 assert(Std &&
"Should already be diagnosed");
887 S.
Diag(Loc, diag::err_implicit_coroutine_std_nothrow_type_not_found);
891 auto *VD = Result.getAsSingle<
VarDecl>();
893 Result.suppressDiagnostics();
916 assert(PointeeRD &&
"PromiseType must be a CxxRecordDecl type");
921 if (!OperatorDelete) {
924 const bool Overaligned =
false;
926 Overaligned, DeleteName);
929 return OperatorDelete;
935 assert(Fn && Fn->
isCoroutine() &&
"not a coroutine");
938 "a null body is only allowed for invalid declarations");
946 if (isa<CoroutineBodyStmt>(Body)) {
955 "first coroutine location not set");
971 : S(S), FD(FD), Fn(Fn), Loc(FD.getLocation()),
972 IsPromiseDependentType(
973 !Fn.CoroutinePromise ||
974 Fn.CoroutinePromise->getType()->isDependentType()) {
978 this->ParamMovesVector.push_back(KV.second);
981 if (!IsPromiseDependentType) {
983 assert(PromiseRecordDecl &&
"Type should have already been checked");
985 this->IsValid = makePromiseStmt() && makeInitialAndFinalSuspend();
989 assert(this->IsValid &&
"coroutine already invalid");
990 this->IsValid = makeReturnObject();
991 if (this->IsValid && !IsPromiseDependentType)
993 return this->IsValid;
997 assert(this->IsValid &&
"coroutine already invalid");
998 assert(!this->IsPromiseDependentType &&
999 "coroutine cannot have a dependent promise type");
1000 this->IsValid = makeOnException() && makeOnFallthrough() &&
1001 makeGroDeclAndReturnStmt() && makeReturnOnAllocFailure() &&
1002 makeNewAndDeleteExpr();
1003 return this->IsValid;
1006 bool CoroutineStmtBuilder::makePromiseStmt() {
1018 bool CoroutineStmtBuilder::makeInitialAndFinalSuspend() {
1030 if (
auto *DeclRef = dyn_cast_or_null<DeclRefExpr>(E)) {
1031 auto *
Decl = DeclRef->getDecl();
1033 if (Method->isStatic())
1042 diag::err_coroutine_promise_get_return_object_on_allocation_failure)
1043 << PromiseRecordDecl;
1049 bool CoroutineStmtBuilder::makeReturnOnAllocFailure() {
1050 assert(!IsPromiseDependentType &&
1051 "cannot make statement while the promise type is dependent");
1076 if (ReturnObjectOnAllocationFailure.
isInvalid())
1081 if (ReturnStmt.isInvalid()) {
1093 bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
1095 assert(!IsPromiseDependentType &&
1096 "cannot make statement while the promise type is dependent");
1114 bool PassAlignment =
false;
1132 if (
auto *MD = dyn_cast<CXXMethodDecl>(&FD)) {
1140 PlacementArgs.push_back(ThisExpr.
get());
1144 if (PD->getType()->isDependentType())
1148 auto PDLoc = PD->getLocation();
1155 PlacementArgs.push_back(PDRefExpr.
get());
1159 false, PassAlignment, PlacementArgs,
1160 OperatorNew, UnusedResult,
false);
1166 if (!OperatorNew && !PlacementArgs.empty()) {
1167 PlacementArgs.clear();
1170 false, PassAlignment, PlacementArgs,
1171 OperatorNew, UnusedResult,
false);
1181 false, PassAlignment, PlacementArgs,
1182 OperatorNew, UnusedResult);
1185 bool IsGlobalOverload =
1186 OperatorNew && !isa<CXXRecordDecl>(OperatorNew->
getDeclContext());
1190 if (RequiresNoThrowAlloc && (!OperatorNew || IsGlobalOverload)) {
1194 PlacementArgs = {StdNoThrow};
1195 OperatorNew =
nullptr;
1198 false, PassAlignment, PlacementArgs,
1199 OperatorNew, UnusedResult);
1205 if (RequiresNoThrowAlloc) {
1207 if (!FT->isNothrow(
false)) {
1209 diag::err_coroutine_promise_new_requires_nothrow)
1211 S.
Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
1230 if (NewRef.isInvalid())
1234 for (
auto Arg : PlacementArgs)
1235 NewArgs.push_back(Arg);
1258 const auto *OpDeleteType =
1260 if (OpDeleteType->getNumParams() > 1)
1261 DeleteArgs.push_back(FrameSize);
1275 bool CoroutineStmtBuilder::makeOnFallthrough() {
1276 assert(!IsPromiseDependentType &&
1277 "cannot make statement while the promise type is dependent");
1282 bool HasRVoid, HasRValue;
1284 lookupMember(S,
"return_void", PromiseRecordDecl, Loc, HasRVoid);
1286 lookupMember(S,
"return_value", PromiseRecordDecl, Loc, HasRValue);
1289 if (HasRVoid && HasRValue) {
1292 diag::err_coroutine_promise_incompatible_return_functions)
1293 << PromiseRecordDecl;
1295 diag::note_member_first_declared_here)
1298 diag::note_member_first_declared_here)
1301 }
else if (!HasRVoid && !HasRValue) {
1305 diag::err_coroutine_promise_requires_return_function)
1306 << PromiseRecordDecl;
1308 << PromiseRecordDecl;
1310 }
else if (HasRVoid) {
1317 if (Fallthrough.isInvalid())
1325 bool CoroutineStmtBuilder::makeOnException() {
1327 assert(!IsPromiseDependentType &&
1328 "cannot make statement while the promise type is dependent");
1330 const bool RequireUnhandledException = S.
getLangOpts().CXXExceptions;
1332 if (!
lookupMember(S,
"unhandled_exception", PromiseRecordDecl, Loc)) {
1334 RequireUnhandledException
1335 ? diag::err_coroutine_promise_unhandled_exception_required
1337 warn_coroutine_promise_unhandled_exception_required_with_exceptions;
1338 S.
Diag(Loc, DiagID) << PromiseRecordDecl;
1340 << PromiseRecordDecl;
1341 return !RequireUnhandledException;
1349 "unhandled_exception",
None);
1367 bool CoroutineStmtBuilder::makeReturnObject() {
1380 if (
auto *MbrRef = dyn_cast<CXXMemberCallExpr>(E)) {
1381 auto *MethodDecl = MbrRef->getMethodDecl();
1382 S.
Diag(MethodDecl->getLocation(), diag::note_member_declared_here)
1389 bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() {
1390 assert(!IsPromiseDependentType &&
1391 "cannot make statement while the promise type is dependent");
1392 assert(this->
ReturnValue &&
"ReturnValue must be already formed");
1396 "get_return_object type must no longer be dependent");
1399 assert(!FnRetType->isDependentType() &&
1400 "get_return_object type must no longer be dependent");
1402 if (FnRetType->isVoidType()) {
1426 if (GroDecl->isInvalidDecl())
1448 if (GroDeclStmt.isInvalid())
1458 if (ReturnStmt.isInvalid()) {
1462 if (cast<clang::ReturnStmt>(ReturnStmt.get())->getNRVOCandidate() == GroDecl)
1463 GroDecl->setNRVOVariable(
true);
1465 this->ReturnStmt = ReturnStmt.get();
1498 assert(isa<FunctionDecl>(CurContext) &&
"not in a function scope");
1499 auto *FD = cast<FunctionDecl>(CurContext);
1501 auto *ScopeInfo = getCurFunction();
1502 assert(ScopeInfo->CoroutineParameterMoves.empty() &&
1503 "Should not build parameter moves twice");
1506 if (PD->getType()->isDependentType())
1510 BuildDeclRefExpr(PD, PD->getType().getNonReferenceType(),
1515 Expr *CExpr =
nullptr;
1516 if (PD->getType()->getAsCXXRecordDecl() ||
1517 PD->getType()->isRValueReferenceType())
1520 CExpr = PDRefExpr.
get();
1522 auto D =
buildVarDecl(*
this, Loc, PD->getType(), PD->getIdentifier());
1523 AddInitializerToDecl(D, CExpr,
true);
1526 StmtResult Stmt = ActOnDeclStmt(ConvertDeclToDeclGroup(D), Loc, Loc);
1530 ScopeInfo->CoroutineParameterMoves.insert(std::make_pair(PD, Stmt.
get()));
1544 if (!StdCoroutineTraitsCache) {
1545 if (
auto StdExp = lookupStdExperimentalNamespace()) {
1547 &PP.getIdentifierTable().get(
"coroutine_traits"),
1548 FuncLoc, LookupOrdinaryName);
1549 if (!LookupQualifiedName(
Result, StdExp)) {
1550 Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
1551 <<
"std::experimental::coroutine_traits";
1554 if (!(StdCoroutineTraitsCache =
1556 Result.suppressDiagnostics();
1563 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
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)
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.
ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false)
ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
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...
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)
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)
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.
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.
ExprResult ActOnFinishFullExpr(Expr *Expr)
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
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...
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...
ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
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 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)