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;
198 ? diag::err_coroutine_objc_method
199 : diag::err_coroutine_outside_function) << Keyword;
205 enum InvalidFuncDiag {
214 bool Diagnosed =
false;
215 auto DiagInvalid = [&](InvalidFuncDiag
ID) {
216 S.
Diag(Loc, diag::err_coroutine_invalid_func_context) <<
ID << Keyword;
225 if (MD && isa<CXXConstructorDecl>(MD))
226 return DiagInvalid(DiagCtor);
228 else if (MD && isa<CXXDestructorDecl>(MD))
229 return DiagInvalid(DiagDtor);
231 else if (FD->isMain())
232 return DiagInvalid(DiagMain);
238 if (FD->isConstexpr())
239 DiagInvalid(FD->isConsteval() ? DiagConsteval : DiagConstexpr);
242 if (FD->getReturnType()->isUndeducedType())
243 DiagInvalid(DiagAutoRet);
247 if (FD->isVariadic())
248 DiagInvalid(DiagVarargs);
261 assert(!Operators.
isAmbiguous() &&
"Operator lookup cannot be ambiguous");
264 Functions.size() > 1 ||
265 (Functions.size() == 1 && isa<FunctionTemplateDecl>(*Functions.begin()));
269 Functions.begin(), Functions.end());
290 cast<UnresolvedLookupExpr>(R.
get()));
300 assert(BuiltInDecl &&
"failed to find builtin declaration");
304 assert(DeclRef.
isUsable() &&
"Builtin reference cannot fail");
309 assert(!Call.isInvalid() &&
"Call to builtin cannot fail!");
316 if (CoroHandleType.
isNull())
323 S.
Diag(Loc, diag::err_coroutine_handle_missing_member)
354 Base, Base->
getType(), Loc,
false, SS,
361 if (
auto *TE = dyn_cast<TypoExpr>(Result.
get())) {
363 S.
Diag(Loc, diag::err_no_member)
392 Expr *JustAddress = AddressExpr.
get();
411 Expr *CoroHandle = CoroHandleRes.
get();
413 const StringRef Funcs[] = {
"await_ready",
"await_suspend",
"await_resume"};
415 for (
size_t I = 0, N = llvm::array_lengthof(Funcs); I != N; ++I) {
434 diag::note_await_ready_no_bool_conversion);
435 S.
Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
441 CallExpr *AwaitSuspend = cast<CallExpr>(Calls.
Results[ACT::ACT_Suspend]);
450 Calls.
Results[ACT::ACT_Suspend] = TailCallSuspend;
456 diag::err_await_suspend_invalid_return_type)
458 S.
Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
482 assert(isa<FunctionDecl>(CurContext) &&
"not in a function scope");
483 auto *FD = cast<FunctionDecl>(CurContext);
484 bool IsThisDependentType = [&] {
485 if (
auto *MD = dyn_cast_or_null<CXXMethodDecl>(FD))
486 return MD->isInstance() && MD->getThisType()->isDependentType();
497 auto *VD =
VarDecl::Create(Context, FD, FD->getLocation(), FD->getLocation(),
498 &PP.getIdentifierTable().get(
"__promise"), T,
500 CheckVariableDeclarationType(VD);
501 if (VD->isInvalidDecl())
504 auto *ScopeInfo = getCurFunction();
510 if (
auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
515 ThisExpr = CreateBuiltinUnaryOp(Loc, UO_Deref, ThisExpr.
get());
518 CtorArgExprs.push_back(ThisExpr.
get());
522 auto &Moves = ScopeInfo->CoroutineParameterMoves;
523 for (
auto *PD : FD->parameters()) {
524 if (PD->getType()->isDependentType())
528 auto Move = Moves.find(PD);
529 assert(
Move != Moves.end() &&
530 "Coroutine function parameter not inserted into move map");
534 cast<VarDecl>(cast<DeclStmt>(
Move->second)->getSingleDecl());
536 BuildDeclRefExpr(MoveDecl, MoveDecl->getType().getNonReferenceType(),
538 if (RefExpr.isInvalid())
540 CtorArgExprs.push_back(RefExpr.get());
546 CtorArgExprs, FD->getLocation());
549 VD->getLocation(),
true, PLE);
557 ExprResult Result = InitSeq.Perform(*
this, Entity, Kind, CtorArgExprs);
560 }
else if (Result.
get()) {
561 VD->setInit(MaybeCreateExprWithCleanups(Result.
get()));
563 CheckCompleteVariableDeclaration(VD);
566 ActOnUninitializedDecl(VD);
575 bool IsImplicit =
false) {
579 assert(isa<FunctionDecl>(S.
CurContext) &&
"not in a function scope");
582 assert(ScopeInfo &&
"missing function scope for function");
584 if (ScopeInfo->FirstCoroutineStmtLoc.isInvalid() && !IsImplicit)
585 ScopeInfo->setFirstCoroutineStmt(Loc, Keyword);
587 if (ScopeInfo->CoroutinePromise)
594 if (!ScopeInfo->CoroutinePromise)
604 auto *ScopeInfo = getCurFunction();
605 assert(ScopeInfo->CoroutinePromise);
609 if (!ScopeInfo->NeedsCoroutineSuspends)
612 ScopeInfo->setNeedsCoroutineSuspends(
false);
614 auto *Fn = cast<FunctionDecl>(CurContext);
617 auto buildSuspends = [&](StringRef Name)
mutable ->
StmtResult {
625 Suspend = BuildResolvedCoawaitExpr(Loc, Suspend.
get(),
627 Suspend = ActOnFinishFullExpr(Suspend.get(),
false);
628 if (Suspend.isInvalid()) {
629 Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
630 << ((Name ==
"initial_suspend") ? 0 : 1);
631 Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword;
634 return cast<Stmt>(Suspend.get());
637 StmtResult InitSuspend = buildSuspends(
"initial_suspend");
641 StmtResult FinalSuspend = buildSuspends(
"final_suspend");
645 ScopeInfo->setCoroutineSuspends(InitSuspend.
get(), FinalSuspend.
get());
686 S.
Diag(Loc, diag::err_coroutine_unevaluated_context) << Keyword;
690 S.
Diag(Loc, diag::err_coroutine_within_handler) << Keyword;
694 if (!ActOnCoroutineBodyStart(S, Loc,
"co_await")) {
695 CorrectDelayedTyposInExpr(E);
709 return BuildUnresolvedCoawaitExpr(Loc, E,
710 cast<UnresolvedLookupExpr>(Lookup.
get()));
726 auto *Promise = FSI->CoroutinePromise;
727 if (Promise->getType()->isDependentType()) {
738 diag::note_coroutine_promise_implicit_await_transform_required_here)
748 return BuildResolvedCoawaitExpr(Loc, Awaitable.
get());
764 Expr *Res =
new (Context)
772 E = CreateMaterializeTemporaryExpr(E->
getType(), E,
true);
793 if (!ActOnCoroutineBodyStart(S, Loc,
"co_yield")) {
794 CorrectDelayedTyposInExpr(E);
802 *
this, getCurFunction()->CoroutinePromise, Loc,
"yield_value", E);
811 return BuildCoyieldExpr(Loc, Awaitable.
get());
832 E = CreateMaterializeTemporaryExpr(E->
getType(), E,
true);
848 if (!ActOnCoroutineBodyStart(S, Loc,
"co_return")) {
849 CorrectDelayedTyposInExpr(E);
852 return BuildCoreturnStmt(Loc, E);
870 auto NRVOCandidate = this->getCopyElisionCandidate(E->
getType(), E, CES_AsIfByStdMove);
874 ExprResult MoveResult = this->PerformMoveOrCopyInitialization(
875 Entity, NRVOCandidate, E->
getType(), E);
876 if (MoveResult.get())
877 E = MoveResult.get();
884 VarDecl *Promise = FSI->CoroutinePromise;
889 E = MakeFullDiscardedValueExpr(E).get();
895 Expr *PCE = ActOnFinishFullExpr(PC.
get(),
false).
get();
904 assert(Std &&
"Should already be diagnosed");
912 S.
Diag(Loc, diag::err_implicit_coroutine_std_nothrow_type_not_found);
916 auto *VD = Result.getAsSingle<
VarDecl>();
918 Result.suppressDiagnostics();
941 assert(PointeeRD &&
"PromiseType must be a CxxRecordDecl type");
946 if (!OperatorDelete) {
949 const bool Overaligned =
false;
951 Overaligned, DeleteName);
954 return OperatorDelete;
960 assert(Fn && Fn->
isCoroutine() &&
"not a coroutine");
963 "a null body is only allowed for invalid declarations");
971 if (isa<CoroutineBodyStmt>(Body)) {
980 "first coroutine location not set");
996 : S(S), FD(FD), Fn(Fn), Loc(FD.getLocation()),
997 IsPromiseDependentType(
998 !Fn.CoroutinePromise ||
999 Fn.CoroutinePromise->getType()->isDependentType()) {
1003 this->ParamMovesVector.push_back(KV.second);
1006 if (!IsPromiseDependentType) {
1008 assert(PromiseRecordDecl &&
"Type should have already been checked");
1010 this->IsValid = makePromiseStmt() && makeInitialAndFinalSuspend();
1014 assert(this->IsValid &&
"coroutine already invalid");
1015 this->IsValid = makeReturnObject();
1016 if (this->IsValid && !IsPromiseDependentType)
1018 return this->IsValid;
1022 assert(this->IsValid &&
"coroutine already invalid");
1023 assert(!this->IsPromiseDependentType &&
1024 "coroutine cannot have a dependent promise type");
1025 this->IsValid = makeOnException() && makeOnFallthrough() &&
1026 makeGroDeclAndReturnStmt() && makeReturnOnAllocFailure() &&
1027 makeNewAndDeleteExpr();
1028 return this->IsValid;
1031 bool CoroutineStmtBuilder::makePromiseStmt() {
1043 bool CoroutineStmtBuilder::makeInitialAndFinalSuspend() {
1055 if (
auto *DeclRef = dyn_cast_or_null<DeclRefExpr>(E)) {
1056 auto *
Decl = DeclRef->getDecl();
1058 if (Method->isStatic())
1067 diag::err_coroutine_promise_get_return_object_on_allocation_failure)
1068 << PromiseRecordDecl;
1074 bool CoroutineStmtBuilder::makeReturnOnAllocFailure() {
1075 assert(!IsPromiseDependentType &&
1076 "cannot make statement while the promise type is dependent");
1101 if (ReturnObjectOnAllocationFailure.
isInvalid())
1106 if (ReturnStmt.isInvalid()) {
1118 bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
1120 assert(!IsPromiseDependentType &&
1121 "cannot make statement while the promise type is dependent");
1139 bool PassAlignment =
false;
1157 if (
auto *MD = dyn_cast<CXXMethodDecl>(&FD)) {
1165 PlacementArgs.push_back(ThisExpr.
get());
1169 if (PD->getType()->isDependentType())
1173 auto PDLoc = PD->getLocation();
1180 PlacementArgs.push_back(PDRefExpr.
get());
1184 false, PassAlignment, PlacementArgs,
1185 OperatorNew, UnusedResult,
false);
1191 if (!OperatorNew && !PlacementArgs.empty()) {
1192 PlacementArgs.clear();
1195 false, PassAlignment, PlacementArgs,
1196 OperatorNew, UnusedResult,
false);
1206 false, PassAlignment, PlacementArgs,
1207 OperatorNew, UnusedResult);
1210 bool IsGlobalOverload =
1211 OperatorNew && !isa<CXXRecordDecl>(OperatorNew->
getDeclContext());
1215 if (RequiresNoThrowAlloc && (!OperatorNew || IsGlobalOverload)) {
1219 PlacementArgs = {StdNoThrow};
1220 OperatorNew =
nullptr;
1223 false, PassAlignment, PlacementArgs,
1224 OperatorNew, UnusedResult);
1230 if (RequiresNoThrowAlloc) {
1232 if (!FT->isNothrow(
false)) {
1234 diag::err_coroutine_promise_new_requires_nothrow)
1236 S.
Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
1255 if (NewRef.isInvalid())
1259 for (
auto Arg : PlacementArgs)
1260 NewArgs.push_back(Arg);
1283 const auto *OpDeleteType =
1285 if (OpDeleteType->getNumParams() > 1)
1286 DeleteArgs.push_back(FrameSize);
1301 bool CoroutineStmtBuilder::makeOnFallthrough() {
1302 assert(!IsPromiseDependentType &&
1303 "cannot make statement while the promise type is dependent");
1308 bool HasRVoid, HasRValue;
1310 lookupMember(S,
"return_void", PromiseRecordDecl, Loc, HasRVoid);
1312 lookupMember(S,
"return_value", PromiseRecordDecl, Loc, HasRValue);
1315 if (HasRVoid && HasRValue) {
1318 diag::err_coroutine_promise_incompatible_return_functions)
1319 << PromiseRecordDecl;
1321 diag::note_member_first_declared_here)
1324 diag::note_member_first_declared_here)
1327 }
else if (!HasRVoid && !HasRValue) {
1331 diag::err_coroutine_promise_requires_return_function)
1332 << PromiseRecordDecl;
1334 << PromiseRecordDecl;
1336 }
else if (HasRVoid) {
1343 if (Fallthrough.isInvalid())
1351 bool CoroutineStmtBuilder::makeOnException() {
1353 assert(!IsPromiseDependentType &&
1354 "cannot make statement while the promise type is dependent");
1356 const bool RequireUnhandledException = S.
getLangOpts().CXXExceptions;
1358 if (!
lookupMember(S,
"unhandled_exception", PromiseRecordDecl, Loc)) {
1360 RequireUnhandledException
1361 ? diag::err_coroutine_promise_unhandled_exception_required
1363 warn_coroutine_promise_unhandled_exception_required_with_exceptions;
1364 S.
Diag(Loc, DiagID) << PromiseRecordDecl;
1366 << PromiseRecordDecl;
1367 return !RequireUnhandledException;
1375 "unhandled_exception",
None);
1394 bool CoroutineStmtBuilder::makeReturnObject() {
1407 if (
auto *MbrRef = dyn_cast<CXXMemberCallExpr>(E)) {
1408 auto *MethodDecl = MbrRef->getMethodDecl();
1409 S.
Diag(MethodDecl->getLocation(), diag::note_member_declared_here)
1416 bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() {
1417 assert(!IsPromiseDependentType &&
1418 "cannot make statement while the promise type is dependent");
1419 assert(this->
ReturnValue &&
"ReturnValue must be already formed");
1423 "get_return_object type must no longer be dependent");
1426 assert(!FnRetType->isDependentType() &&
1427 "get_return_object type must no longer be dependent");
1429 if (FnRetType->isVoidType()) {
1454 if (GroDecl->isInvalidDecl())
1476 if (GroDeclStmt.isInvalid())
1486 if (ReturnStmt.isInvalid()) {
1490 if (cast<clang::ReturnStmt>(ReturnStmt.get())->getNRVOCandidate() == GroDecl)
1491 GroDecl->setNRVOVariable(
true);
1493 this->ReturnStmt = ReturnStmt.get();
1526 assert(isa<FunctionDecl>(CurContext) &&
"not in a function scope");
1527 auto *FD = cast<FunctionDecl>(CurContext);
1529 auto *ScopeInfo = getCurFunction();
1530 if (!ScopeInfo->CoroutineParameterMoves.empty())
1534 if (PD->getType()->isDependentType())
1538 BuildDeclRefExpr(PD, PD->getType().getNonReferenceType(),
1543 Expr *CExpr =
nullptr;
1544 if (PD->getType()->getAsCXXRecordDecl() ||
1545 PD->getType()->isRValueReferenceType())
1548 CExpr = PDRefExpr.
get();
1550 auto D =
buildVarDecl(*
this, Loc, PD->getType(), PD->getIdentifier());
1551 AddInitializerToDecl(D, CExpr,
true);
1554 StmtResult Stmt = ActOnDeclStmt(ConvertDeclToDeclGroup(D), Loc, Loc);
1558 ScopeInfo->CoroutineParameterMoves.insert(std::make_pair(PD, Stmt.
get()));
1572 if (!StdCoroutineTraitsCache) {
1573 if (
auto StdExp = lookupStdExperimentalNamespace()) {
1575 &PP.getIdentifierTable().get(
"coroutine_traits"),
1576 FuncLoc, LookupOrdinaryName);
1577 if (!LookupQualifiedName(
Result, StdExp)) {
1578 Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
1579 <<
"std::experimental::coroutine_traits";
1582 if (!(StdCoroutineTraitsCache =
1584 Result.suppressDiagnostics();
1591 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
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
Defines enum values for all the target-independent builtin functions.
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)