23 using namespace clang;
53 S.
Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
54 <<
"std::experimental::coroutine_traits";
61 S.
Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
62 <<
"std::experimental::coroutine_traits";
68 Result.suppressDiagnostics();
85 if (
auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
86 if (MD->isInstance()) {
111 diag::err_coroutine_type_missing_specialization))
115 assert(RD &&
"specialization of class template is not a class?");
121 auto *Promise = R.getAsSingle<
TypeDecl>();
124 diag::err_implied_std_coroutine_traits_promise_type_not_found)
131 auto buildElaboratedType = [&]() {
140 diag::err_implied_std_coroutine_traits_promise_type_not_class)
141 << buildElaboratedType();
145 diag::err_coroutine_promise_type_incomplete))
158 assert(StdExp &&
"Should already be diagnosed");
163 S.
Diag(Loc, diag::err_implied_coroutine_type_not_found)
164 <<
"std::experimental::coroutine_handle";
170 Result.suppressDiagnostics();
173 S.
Diag(Found->
getLocation(), diag::err_malformed_std_coroutine_handle);
186 if (CoroHandleType.
isNull())
189 diag::err_coroutine_type_missing_specialization))
192 return CoroHandleType;
199 S.
Diag(Loc, diag::err_coroutine_unevaluated_context) << Keyword;
207 ? diag::err_coroutine_objc_method
208 : diag::err_coroutine_outside_function) << Keyword;
214 enum InvalidFuncDiag {
224 bool Diagnosed =
false;
225 auto DiagInvalid = [&](InvalidFuncDiag
ID) {
226 S.
Diag(Loc, diag::err_coroutine_invalid_func_context) <<
ID << Keyword;
234 if (MD && isa<CXXConstructorDecl>(MD))
235 return DiagInvalid(DiagCtor);
236 else if (MD && isa<CXXDestructorDecl>(MD))
237 return DiagInvalid(DiagDtor);
238 else if (MD && MD->isCopyAssignmentOperator())
239 return DiagInvalid(DiagCopyAssign);
240 else if (MD && MD->isMoveAssignmentOperator())
241 return DiagInvalid(DiagMoveAssign);
242 else if (FD->isMain())
243 return DiagInvalid(DiagMain);
246 if (FD->isConstexpr())
247 DiagInvalid(DiagConstexpr);
248 if (FD->getReturnType()->isUndeducedType())
249 DiagInvalid(DiagAutoRet);
250 if (FD->isVariadic())
251 DiagInvalid(DiagVarargs);
264 assert(!Operators.
isAmbiguous() &&
"Operator lookup cannot be ambiguous");
267 Functions.size() > 1 ||
268 (Functions.size() == 1 && isa<FunctionTemplateDecl>(*Functions.begin()));
272 Functions.begin(), Functions.end());
293 cast<UnresolvedLookupExpr>(R.
get()));
303 assert(BuiltInDecl &&
"failed to find builtin declaration");
307 assert(DeclRef.
isUsable() &&
"Builtin reference cannot fail");
312 assert(!Call.isInvalid() &&
"Call to builtin cannot fail!");
319 if (CoroHandleType.
isNull())
326 S.
Diag(Loc, diag::err_coroutine_handle_missing_member)
357 Base, Base->
getType(), Loc,
false, SS,
386 Expr *JustAddress = AddressExpr.
get();
405 Expr *CoroHandle = CoroHandleRes.
get();
407 const StringRef Funcs[] = {
"await_ready",
"await_suspend",
"await_resume"};
409 for (
size_t I = 0, N = llvm::array_lengthof(Funcs); I != N; ++I) {
428 diag::note_await_ready_no_bool_conversion);
429 S.
Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
435 CallExpr *AwaitSuspend = cast<CallExpr>(Calls.
Results[ACT::ACT_Suspend]);
444 Calls.
Results[ACT::ACT_Suspend] = TailCallSuspend;
450 diag::err_await_suspend_invalid_return_type)
452 S.
Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
476 assert(isa<FunctionDecl>(CurContext) &&
"not in a function scope");
477 auto *FD = cast<FunctionDecl>(CurContext);
478 bool IsThisDependentType = [&] {
479 if (
auto *MD = dyn_cast_or_null<CXXMethodDecl>(FD))
480 return MD->isInstance() && MD->getThisType(Context)->isDependentType();
491 auto *VD =
VarDecl::Create(Context, FD, FD->getLocation(), FD->getLocation(),
492 &PP.getIdentifierTable().get(
"__promise"),
T,
494 CheckVariableDeclarationType(VD);
495 if (VD->isInvalidDecl())
497 ActOnUninitializedDecl(VD);
499 assert(!VD->isInvalidDecl());
506 bool IsImplicit =
false) {
510 assert(isa<FunctionDecl>(S.
CurContext) &&
"not in a function scope");
513 assert(ScopeInfo &&
"missing function scope for function");
515 if (ScopeInfo->FirstCoroutineStmtLoc.isInvalid() && !IsImplicit)
516 ScopeInfo->setFirstCoroutineStmt(Loc, Keyword);
518 if (ScopeInfo->CoroutinePromise)
522 if (!ScopeInfo->CoroutinePromise)
532 auto *ScopeInfo = getCurFunction();
533 assert(ScopeInfo->CoroutinePromise);
537 if (!ScopeInfo->NeedsCoroutineSuspends)
540 ScopeInfo->setNeedsCoroutineSuspends(
false);
542 auto *Fn = cast<FunctionDecl>(CurContext);
545 auto buildSuspends = [&](StringRef Name)
mutable ->
StmtResult {
553 Suspend = BuildResolvedCoawaitExpr(Loc, Suspend.
get(),
555 Suspend = ActOnFinishFullExpr(Suspend.get());
556 if (Suspend.isInvalid()) {
557 Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
558 << ((Name ==
"initial_suspend") ? 0 : 1);
559 Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword;
562 return cast<Stmt>(Suspend.get());
565 StmtResult InitSuspend = buildSuspends(
"initial_suspend");
569 StmtResult FinalSuspend = buildSuspends(
"final_suspend");
573 ScopeInfo->setCoroutineSuspends(InitSuspend.
get(), FinalSuspend.
get());
579 if (!ActOnCoroutineBodyStart(S, Loc,
"co_await")) {
580 CorrectDelayedTyposInExpr(E);
592 return BuildUnresolvedCoawaitExpr(Loc, E,
593 cast<UnresolvedLookupExpr>(Lookup.
get()));
609 auto *Promise = FSI->CoroutinePromise;
610 if (Promise->getType()->isDependentType()) {
621 diag::note_coroutine_promise_implicit_await_transform_required_here)
631 return BuildResolvedCoawaitExpr(Loc, Awaitable.
get());
647 Expr *Res =
new (Context)
655 E = CreateMaterializeTemporaryExpr(E->
getType(), E,
true);
671 if (!ActOnCoroutineBodyStart(S, Loc,
"co_yield")) {
672 CorrectDelayedTyposInExpr(E);
678 *
this, getCurFunction()->CoroutinePromise, Loc,
"yield_value", E);
687 return BuildCoyieldExpr(Loc, Awaitable.
get());
708 E = CreateMaterializeTemporaryExpr(E->
getType(), E,
true);
724 if (!ActOnCoroutineBodyStart(S, Loc,
"co_return")) {
725 CorrectDelayedTyposInExpr(E);
728 return BuildCoreturnStmt(Loc, E);
747 VarDecl *Promise = FSI->CoroutinePromise;
752 E = MakeFullDiscardedValueExpr(E).get();
758 Expr *PCE = ActOnFinishFullExpr(PC.
get()).
get();
767 assert(Std &&
"Should already be diagnosed");
775 S.
Diag(Loc, diag::err_implicit_coroutine_std_nothrow_type_not_found);
779 auto *VD = Result.getAsSingle<
VarDecl>();
781 Result.suppressDiagnostics();
804 assert(PointeeRD &&
"PromiseType must be a CxxRecordDecl type");
809 if (!OperatorDelete) {
812 const bool Overaligned =
false;
814 Overaligned, DeleteName);
817 return OperatorDelete;
823 assert(Fn && Fn->
isCoroutine() &&
"not a coroutine");
826 "a null body is only allowed for invalid declarations");
834 if (isa<CoroutineBodyStmt>(Body)) {
843 "first coroutine location not set");
859 : S(S), FD(FD), Fn(Fn), Loc(FD.getLocation()),
860 IsPromiseDependentType(
861 !Fn.CoroutinePromise ||
862 Fn.CoroutinePromise->getType()->isDependentType()) {
864 if (!IsPromiseDependentType) {
866 assert(PromiseRecordDecl &&
"Type should have already been checked");
868 this->IsValid = makePromiseStmt() && makeInitialAndFinalSuspend();
872 assert(this->IsValid &&
"coroutine already invalid");
873 this->IsValid = makeReturnObject() && makeParamMoves();
874 if (this->IsValid && !IsPromiseDependentType)
876 return this->IsValid;
880 assert(this->IsValid &&
"coroutine already invalid");
881 assert(!this->IsPromiseDependentType &&
882 "coroutine cannot have a dependent promise type");
883 this->IsValid = makeOnException() && makeOnFallthrough() &&
884 makeGroDeclAndReturnStmt() && makeReturnOnAllocFailure() &&
885 makeNewAndDeleteExpr();
886 return this->IsValid;
890 assert(this->IsValid &&
"coroutine already invalid");
891 assert(this->
ParamMoves.empty() &&
"param moves already built");
892 return this->IsValid = makeParamMoves();
895 bool CoroutineStmtBuilder::makePromiseStmt() {
907 bool CoroutineStmtBuilder::makeInitialAndFinalSuspend() {
919 if (
auto *DeclRef = dyn_cast_or_null<DeclRefExpr>(E)) {
920 auto *
Decl = DeclRef->getDecl();
922 if (Method->isStatic())
931 diag::err_coroutine_promise_get_return_object_on_allocation_failure)
932 << PromiseRecordDecl;
938 bool CoroutineStmtBuilder::makeReturnOnAllocFailure() {
939 assert(!IsPromiseDependentType &&
940 "cannot make statement while the promise type is dependent");
965 if (ReturnObjectOnAllocationFailure.
isInvalid())
970 if (ReturnStmt.isInvalid()) {
982 bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
984 assert(!IsPromiseDependentType &&
985 "cannot make statement while the promise type is dependent");
998 bool PassAlignment =
false;
1003 false, PassAlignment, PlacementArgs,
1004 OperatorNew, UnusedResult);
1006 bool IsGlobalOverload =
1007 OperatorNew && !isa<CXXRecordDecl>(OperatorNew->
getDeclContext());
1011 if (RequiresNoThrowAlloc && (!OperatorNew || IsGlobalOverload)) {
1015 PlacementArgs = {StdNoThrow};
1016 OperatorNew =
nullptr;
1019 false, PassAlignment, PlacementArgs,
1020 OperatorNew, UnusedResult);
1023 assert(OperatorNew &&
"expected definition of operator new to be found");
1025 if (RequiresNoThrowAlloc) {
1027 if (!FT->isNothrow(S.
Context,
false)) {
1029 diag::err_coroutine_promise_new_requires_nothrow)
1031 S.
Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
1050 if (NewRef.isInvalid())
1054 for (
auto Arg : PlacementArgs)
1055 NewArgs.push_back(Arg);
1078 const auto *OpDeleteType =
1080 if (OpDeleteType->getNumParams() > 1)
1081 DeleteArgs.push_back(FrameSize);
1095 bool CoroutineStmtBuilder::makeOnFallthrough() {
1096 assert(!IsPromiseDependentType &&
1097 "cannot make statement while the promise type is dependent");
1102 bool HasRVoid, HasRValue;
1104 lookupMember(S,
"return_void", PromiseRecordDecl, Loc, HasRVoid);
1106 lookupMember(S,
"return_value", PromiseRecordDecl, Loc, HasRValue);
1109 if (HasRVoid && HasRValue) {
1112 diag::err_coroutine_promise_incompatible_return_functions)
1113 << PromiseRecordDecl;
1115 diag::note_member_first_declared_here)
1118 diag::note_member_first_declared_here)
1121 }
else if (!HasRVoid && !HasRValue) {
1125 diag::err_coroutine_promise_requires_return_function)
1126 << PromiseRecordDecl;
1128 << PromiseRecordDecl;
1130 }
else if (HasRVoid) {
1137 if (Fallthrough.isInvalid())
1145 bool CoroutineStmtBuilder::makeOnException() {
1147 assert(!IsPromiseDependentType &&
1148 "cannot make statement while the promise type is dependent");
1150 const bool RequireUnhandledException = S.
getLangOpts().CXXExceptions;
1152 if (!
lookupMember(S,
"unhandled_exception", PromiseRecordDecl, Loc)) {
1154 RequireUnhandledException
1155 ? diag::err_coroutine_promise_unhandled_exception_required
1157 warn_coroutine_promise_unhandled_exception_required_with_exceptions;
1158 S.
Diag(Loc, DiagID) << PromiseRecordDecl;
1160 << PromiseRecordDecl;
1161 return !RequireUnhandledException;
1169 "unhandled_exception",
None);
1187 bool CoroutineStmtBuilder::makeReturnObject() {
1200 if (
auto *MbrRef = dyn_cast<CXXMemberCallExpr>(E)) {
1201 auto *MethodDecl = MbrRef->getMethodDecl();
1202 S.
Diag(MethodDecl->getLocation(), diag::note_member_declared_here)
1209 bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() {
1210 assert(!IsPromiseDependentType &&
1211 "cannot make statement while the promise type is dependent");
1212 assert(this->
ReturnValue &&
"ReturnValue must be already formed");
1216 "get_return_object type must no longer be dependent");
1219 assert(!FnRetType->isDependentType() &&
1220 "get_return_object type must no longer be dependent");
1222 if (FnRetType->isVoidType()) {
1246 if (GroDecl->isInvalidDecl())
1259 if (GroType == FnRetType) {
1260 GroDecl->setNRVOVariable(
true);
1272 if (GroDeclStmt.isInvalid())
1282 if (ReturnStmt.isInvalid()) {
1287 this->ReturnStmt = ReturnStmt.get();
1318 bool CoroutineStmtBuilder::makeParamMoves() {
1320 auto Ty = paramDecl->
getType();
1321 if (Ty->isDependentType())
1325 if (Ty->getAsCXXRecordDecl()) {
1334 auto D =
buildVarDecl(S, Loc, Ty, paramDecl->getIdentifier());
1339 if (Stmt.isInvalid())
1342 ParamMovesVector.push_back(Stmt.get());
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)
An instance of this class is created to represent 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
NamespaceDecl - 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.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
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.
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.
ArrayRef< QualType > getParamTypes() const
bool ActOnCoroutineBodyStart(Scope *S, SourceLocation KwLoc, StringRef Keyword)
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
QualType getElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, QualType NamedType) const
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.
TypeDecl - 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.
bool FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, bool UseGlobal, QualType AllocType, bool IsArray, bool &PassAlignment, MultiExprArg PlaceArgs, FunctionDecl *&OperatorNew, FunctionDecl *&OperatorDelete)
FindAllocationFunctions - Finds the overloads of operator new and delete that are appropriate for the...
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 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.
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.
const FunctionProtoType * T
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.
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...
Encodes a location in the source.
QualType getReturnType() const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
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.
ArrayRef< Stmt * > ParamMoves
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.
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)
Represents a 'co_await' expression.
static ExprResult buildOperatorCoawaitLookupExpr(Sema &SemaRef, Scope *S, SourceLocation Loc)
ActionResult< Stmt * > StmtResult
ExprResult BuildCoyieldExpr(SourceLocation KwLoc, Expr *E)
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.
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)
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.
NamedDecl - This represents a decl with 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.
bool buildParameterMoves()
Build just parameter moves. To use for rebuilding in TreeTransform.
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
SourceLocation getLocStart() const LLVM_READONLY
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)