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()) {
104 diag::err_coroutine_type_missing_specialization))
108 assert(RD &&
"specialization of class template is not a class?");
114 auto *Promise = R.getAsSingle<
TypeDecl>();
117 diag::err_implied_std_coroutine_traits_promise_type_not_found)
124 auto buildElaboratedType = [&]() {
133 diag::err_implied_std_coroutine_traits_promise_type_not_class)
134 << buildElaboratedType();
138 diag::err_coroutine_promise_type_incomplete))
151 assert(StdExp &&
"Should already be diagnosed");
156 S.
Diag(Loc, diag::err_implied_coroutine_type_not_found)
157 <<
"std::experimental::coroutine_handle";
163 Result.suppressDiagnostics();
166 S.
Diag(Found->
getLocation(), diag::err_malformed_std_coroutine_handle);
179 if (CoroHandleType.
isNull())
182 diag::err_coroutine_type_missing_specialization))
185 return CoroHandleType;
200 S.
Diag(Loc, diag::err_coroutine_unevaluated_context) << Keyword;
212 ? diag::err_coroutine_objc_method
213 : diag::err_coroutine_outside_function) << Keyword;
219 enum InvalidFuncDiag {
229 bool Diagnosed =
false;
230 auto DiagInvalid = [&](InvalidFuncDiag
ID) {
231 S.
Diag(Loc, diag::err_coroutine_invalid_func_context) <<
ID << Keyword;
240 if (MD && isa<CXXConstructorDecl>(MD))
241 return DiagInvalid(DiagCtor);
243 else if (MD && isa<CXXDestructorDecl>(MD))
244 return DiagInvalid(DiagDtor);
249 else if (MD && MD->isCopyAssignmentOperator())
250 return DiagInvalid(DiagCopyAssign);
251 else if (MD && MD->isMoveAssignmentOperator())
252 return DiagInvalid(DiagMoveAssign);
254 else if (FD->isMain())
255 return DiagInvalid(DiagMain);
261 if (FD->isConstexpr())
262 DiagInvalid(DiagConstexpr);
265 if (FD->getReturnType()->isUndeducedType())
266 DiagInvalid(DiagAutoRet);
270 if (FD->isVariadic())
271 DiagInvalid(DiagVarargs);
284 assert(!Operators.
isAmbiguous() &&
"Operator lookup cannot be ambiguous");
287 Functions.size() > 1 ||
288 (Functions.size() == 1 && isa<FunctionTemplateDecl>(*Functions.begin()));
292 Functions.begin(), Functions.end());
313 cast<UnresolvedLookupExpr>(R.
get()));
323 assert(BuiltInDecl &&
"failed to find builtin declaration");
327 assert(DeclRef.
isUsable() &&
"Builtin reference cannot fail");
332 assert(!Call.isInvalid() &&
"Call to builtin cannot fail!");
339 if (CoroHandleType.
isNull())
346 S.
Diag(Loc, diag::err_coroutine_handle_missing_member)
377 Base, Base->
getType(), Loc,
false, SS,
384 if (
auto *TE = dyn_cast<TypoExpr>(Result.
get())) {
386 S.
Diag(Loc, diag::err_no_member)
415 Expr *JustAddress = AddressExpr.
get();
434 Expr *CoroHandle = CoroHandleRes.
get();
436 const StringRef Funcs[] = {
"await_ready",
"await_suspend",
"await_resume"};
438 for (
size_t I = 0, N = llvm::array_lengthof(Funcs); I != N; ++I) {
457 diag::note_await_ready_no_bool_conversion);
458 S.
Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
464 CallExpr *AwaitSuspend = cast<CallExpr>(Calls.
Results[ACT::ACT_Suspend]);
473 Calls.
Results[ACT::ACT_Suspend] = TailCallSuspend;
479 diag::err_await_suspend_invalid_return_type)
481 S.
Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
505 assert(isa<FunctionDecl>(CurContext) &&
"not in a function scope");
506 auto *FD = cast<FunctionDecl>(CurContext);
507 bool IsThisDependentType = [&] {
508 if (
auto *MD = dyn_cast_or_null<CXXMethodDecl>(FD))
509 return MD->isInstance() && MD->getThisType(Context)->isDependentType();
520 auto *VD =
VarDecl::Create(Context, FD, FD->getLocation(), FD->getLocation(),
521 &PP.getIdentifierTable().get(
"__promise"), T,
523 CheckVariableDeclarationType(VD);
524 if (VD->isInvalidDecl())
527 auto *ScopeInfo = getCurFunction();
533 if (
auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
538 ThisExpr = CreateBuiltinUnaryOp(Loc, UO_Deref, ThisExpr.
get());
541 CtorArgExprs.push_back(ThisExpr.
get());
545 auto &Moves = ScopeInfo->CoroutineParameterMoves;
546 for (
auto *PD : FD->parameters()) {
547 if (PD->getType()->isDependentType())
551 auto Move = Moves.find(PD);
552 assert(
Move != Moves.end() &&
553 "Coroutine function parameter not inserted into move map");
557 cast<VarDecl>(cast<DeclStmt>(
Move->second)->getSingleDecl());
559 BuildDeclRefExpr(MoveDecl, MoveDecl->getType().getNonReferenceType(),
561 if (RefExpr.isInvalid())
563 CtorArgExprs.push_back(RefExpr.get());
569 CtorArgExprs, FD->getLocation());
572 VD->getLocation(),
true, PLE);
580 ExprResult Result = InitSeq.Perform(*
this, Entity, Kind, CtorArgExprs);
583 }
else if (Result.
get()) {
584 VD->setInit(MaybeCreateExprWithCleanups(Result.
get()));
586 CheckCompleteVariableDeclaration(VD);
589 ActOnUninitializedDecl(VD);
598 bool IsImplicit =
false) {
602 assert(isa<FunctionDecl>(S.
CurContext) &&
"not in a function scope");
605 assert(ScopeInfo &&
"missing function scope for function");
607 if (ScopeInfo->FirstCoroutineStmtLoc.isInvalid() && !IsImplicit)
608 ScopeInfo->setFirstCoroutineStmt(Loc, Keyword);
610 if (ScopeInfo->CoroutinePromise)
617 if (!ScopeInfo->CoroutinePromise)
627 auto *ScopeInfo = getCurFunction();
628 assert(ScopeInfo->CoroutinePromise);
632 if (!ScopeInfo->NeedsCoroutineSuspends)
635 ScopeInfo->setNeedsCoroutineSuspends(
false);
637 auto *Fn = cast<FunctionDecl>(CurContext);
640 auto buildSuspends = [&](StringRef Name)
mutable ->
StmtResult {
648 Suspend = BuildResolvedCoawaitExpr(Loc, Suspend.
get(),
650 Suspend = ActOnFinishFullExpr(Suspend.get());
651 if (Suspend.isInvalid()) {
652 Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
653 << ((Name ==
"initial_suspend") ? 0 : 1);
654 Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword;
657 return cast<Stmt>(Suspend.get());
660 StmtResult InitSuspend = buildSuspends(
"initial_suspend");
664 StmtResult FinalSuspend = buildSuspends(
"final_suspend");
668 ScopeInfo->setCoroutineSuspends(InitSuspend.
get(), FinalSuspend.
get());
674 if (!ActOnCoroutineBodyStart(S, Loc,
"co_await")) {
675 CorrectDelayedTyposInExpr(E);
687 return BuildUnresolvedCoawaitExpr(Loc, E,
688 cast<UnresolvedLookupExpr>(Lookup.
get()));
704 auto *Promise = FSI->CoroutinePromise;
705 if (Promise->getType()->isDependentType()) {
716 diag::note_coroutine_promise_implicit_await_transform_required_here)
726 return BuildResolvedCoawaitExpr(Loc, Awaitable.
get());
742 Expr *Res =
new (Context)
750 E = CreateMaterializeTemporaryExpr(E->
getType(), E,
true);
771 if (!ActOnCoroutineBodyStart(S, Loc,
"co_yield")) {
772 CorrectDelayedTyposInExpr(E);
778 *
this, getCurFunction()->CoroutinePromise, Loc,
"yield_value", E);
787 return BuildCoyieldExpr(Loc, Awaitable.
get());
808 E = CreateMaterializeTemporaryExpr(E->
getType(), E,
true);
824 if (!ActOnCoroutineBodyStart(S, Loc,
"co_return")) {
825 CorrectDelayedTyposInExpr(E);
828 return BuildCoreturnStmt(Loc, E);
847 VarDecl *Promise = FSI->CoroutinePromise;
852 E = MakeFullDiscardedValueExpr(E).get();
858 Expr *PCE = ActOnFinishFullExpr(PC.
get()).
get();
867 assert(Std &&
"Should already be diagnosed");
875 S.
Diag(Loc, diag::err_implicit_coroutine_std_nothrow_type_not_found);
879 auto *VD = Result.getAsSingle<
VarDecl>();
881 Result.suppressDiagnostics();
904 assert(PointeeRD &&
"PromiseType must be a CxxRecordDecl type");
909 if (!OperatorDelete) {
912 const bool Overaligned =
false;
914 Overaligned, DeleteName);
917 return OperatorDelete;
923 assert(Fn && Fn->
isCoroutine() &&
"not a coroutine");
926 "a null body is only allowed for invalid declarations");
934 if (isa<CoroutineBodyStmt>(Body)) {
943 "first coroutine location not set");
959 : S(S), FD(FD), Fn(Fn), Loc(FD.getLocation()),
960 IsPromiseDependentType(
961 !Fn.CoroutinePromise ||
962 Fn.CoroutinePromise->getType()->isDependentType()) {
966 this->ParamMovesVector.push_back(KV.second);
969 if (!IsPromiseDependentType) {
971 assert(PromiseRecordDecl &&
"Type should have already been checked");
973 this->IsValid = makePromiseStmt() && makeInitialAndFinalSuspend();
977 assert(this->IsValid &&
"coroutine already invalid");
978 this->IsValid = makeReturnObject();
979 if (this->IsValid && !IsPromiseDependentType)
981 return this->IsValid;
985 assert(this->IsValid &&
"coroutine already invalid");
986 assert(!this->IsPromiseDependentType &&
987 "coroutine cannot have a dependent promise type");
988 this->IsValid = makeOnException() && makeOnFallthrough() &&
989 makeGroDeclAndReturnStmt() && makeReturnOnAllocFailure() &&
990 makeNewAndDeleteExpr();
991 return this->IsValid;
994 bool CoroutineStmtBuilder::makePromiseStmt() {
1006 bool CoroutineStmtBuilder::makeInitialAndFinalSuspend() {
1018 if (
auto *DeclRef = dyn_cast_or_null<DeclRefExpr>(E)) {
1019 auto *
Decl = DeclRef->getDecl();
1021 if (Method->isStatic())
1030 diag::err_coroutine_promise_get_return_object_on_allocation_failure)
1031 << PromiseRecordDecl;
1037 bool CoroutineStmtBuilder::makeReturnOnAllocFailure() {
1038 assert(!IsPromiseDependentType &&
1039 "cannot make statement while the promise type is dependent");
1064 if (ReturnObjectOnAllocationFailure.
isInvalid())
1069 if (ReturnStmt.isInvalid()) {
1081 bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
1083 assert(!IsPromiseDependentType &&
1084 "cannot make statement while the promise type is dependent");
1102 bool PassAlignment =
false;
1120 if (
auto *MD = dyn_cast<CXXMethodDecl>(&FD)) {
1128 PlacementArgs.push_back(ThisExpr.
get());
1132 if (PD->getType()->isDependentType())
1136 auto PDLoc = PD->getLocation();
1143 PlacementArgs.push_back(PDRefExpr.
get());
1147 false, PassAlignment, PlacementArgs,
1148 OperatorNew, UnusedResult,
false);
1154 if (!OperatorNew && !PlacementArgs.empty()) {
1155 PlacementArgs.clear();
1158 false, PassAlignment, PlacementArgs,
1159 OperatorNew, UnusedResult,
false);
1169 false, PassAlignment, PlacementArgs,
1170 OperatorNew, UnusedResult);
1173 bool IsGlobalOverload =
1174 OperatorNew && !isa<CXXRecordDecl>(OperatorNew->
getDeclContext());
1178 if (RequiresNoThrowAlloc && (!OperatorNew || IsGlobalOverload)) {
1182 PlacementArgs = {StdNoThrow};
1183 OperatorNew =
nullptr;
1186 false, PassAlignment, PlacementArgs,
1187 OperatorNew, UnusedResult);
1193 if (RequiresNoThrowAlloc) {
1195 if (!FT->isNothrow(
false)) {
1197 diag::err_coroutine_promise_new_requires_nothrow)
1199 S.
Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
1218 if (NewRef.isInvalid())
1222 for (
auto Arg : PlacementArgs)
1223 NewArgs.push_back(Arg);
1246 const auto *OpDeleteType =
1248 if (OpDeleteType->getNumParams() > 1)
1249 DeleteArgs.push_back(FrameSize);
1263 bool CoroutineStmtBuilder::makeOnFallthrough() {
1264 assert(!IsPromiseDependentType &&
1265 "cannot make statement while the promise type is dependent");
1270 bool HasRVoid, HasRValue;
1272 lookupMember(S,
"return_void", PromiseRecordDecl, Loc, HasRVoid);
1274 lookupMember(S,
"return_value", PromiseRecordDecl, Loc, HasRValue);
1277 if (HasRVoid && HasRValue) {
1280 diag::err_coroutine_promise_incompatible_return_functions)
1281 << PromiseRecordDecl;
1283 diag::note_member_first_declared_here)
1286 diag::note_member_first_declared_here)
1289 }
else if (!HasRVoid && !HasRValue) {
1293 diag::err_coroutine_promise_requires_return_function)
1294 << PromiseRecordDecl;
1296 << PromiseRecordDecl;
1298 }
else if (HasRVoid) {
1305 if (Fallthrough.isInvalid())
1313 bool CoroutineStmtBuilder::makeOnException() {
1315 assert(!IsPromiseDependentType &&
1316 "cannot make statement while the promise type is dependent");
1318 const bool RequireUnhandledException = S.
getLangOpts().CXXExceptions;
1320 if (!
lookupMember(S,
"unhandled_exception", PromiseRecordDecl, Loc)) {
1322 RequireUnhandledException
1323 ? diag::err_coroutine_promise_unhandled_exception_required
1325 warn_coroutine_promise_unhandled_exception_required_with_exceptions;
1326 S.
Diag(Loc, DiagID) << PromiseRecordDecl;
1328 << PromiseRecordDecl;
1329 return !RequireUnhandledException;
1337 "unhandled_exception",
None);
1355 bool CoroutineStmtBuilder::makeReturnObject() {
1368 if (
auto *MbrRef = dyn_cast<CXXMemberCallExpr>(E)) {
1369 auto *MethodDecl = MbrRef->getMethodDecl();
1370 S.
Diag(MethodDecl->getLocation(), diag::note_member_declared_here)
1377 bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() {
1378 assert(!IsPromiseDependentType &&
1379 "cannot make statement while the promise type is dependent");
1380 assert(this->
ReturnValue &&
"ReturnValue must be already formed");
1384 "get_return_object type must no longer be dependent");
1387 assert(!FnRetType->isDependentType() &&
1388 "get_return_object type must no longer be dependent");
1390 if (FnRetType->isVoidType()) {
1414 if (GroDecl->isInvalidDecl())
1436 if (GroDeclStmt.isInvalid())
1446 if (ReturnStmt.isInvalid()) {
1450 if (cast<clang::ReturnStmt>(ReturnStmt.get())->getNRVOCandidate() == GroDecl)
1451 GroDecl->setNRVOVariable(
true);
1453 this->ReturnStmt = ReturnStmt.get();
1486 assert(isa<FunctionDecl>(CurContext) &&
"not in a function scope");
1487 auto *FD = cast<FunctionDecl>(CurContext);
1489 auto *ScopeInfo = getCurFunction();
1490 assert(ScopeInfo->CoroutineParameterMoves.empty() &&
1491 "Should not build parameter moves twice");
1494 if (PD->getType()->isDependentType())
1498 BuildDeclRefExpr(PD, PD->getType().getNonReferenceType(),
1503 Expr *CExpr =
nullptr;
1504 if (PD->getType()->getAsCXXRecordDecl() ||
1505 PD->getType()->isRValueReferenceType())
1508 CExpr = PDRefExpr.
get();
1510 auto D =
buildVarDecl(*
this, Loc, PD->getType(), PD->getIdentifier());
1511 AddInitializerToDecl(D, CExpr,
true);
1514 StmtResult Stmt = ActOnDeclStmt(ConvertDeclToDeclGroup(D), Loc, Loc);
1518 ScopeInfo->CoroutineParameterMoves.insert(std::make_pair(PD, Stmt.
get()));
1532 if (!StdCoroutineTraitsCache) {
1533 if (
auto StdExp = lookupStdExperimentalNamespace()) {
1535 &PP.getIdentifierTable().get(
"coroutine_traits"),
1536 FuncLoc, LookupOrdinaryName);
1537 if (!LookupQualifiedName(
Result, StdExp)) {
1538 Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
1539 <<
"std::experimental::coroutine_traits";
1542 if (!(StdCoroutineTraitsCache =
1544 Result.suppressDiagnostics();
1551 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())
static UnresolvedLookupExpr * Create(const ASTContext &C, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool ADL, bool Overloaded, UnresolvedSetIterator Begin, UnresolvedSetIterator End)
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)
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
static FunctionDecl * findDeleteForPromise(Sema &S, SourceLocation Loc, QualType PromiseType)
bool isReferenceType() const
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
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)
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.
Expr - 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)
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)
SourceLocation getLocStart() const LLVM_READONLY
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...
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return 0.
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.
DeclarationName - The name of a declaration.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
bool isBooleanType() const
A set of unresolved declarations.
SourceLocation getLocStart() const LLVM_READONLY
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)