27#include "llvm/ADT/SmallSet.h"
72 if (
auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
73 if (MD->isImplicitObjectMemberFunction()) {
81 QualType T = MD->getFunctionObjectParameterType();
97 diag::err_coroutine_type_missing_specialization))
101 assert(RD &&
"specialization of class template is not a class?");
110 diag::err_implied_std_coroutine_traits_promise_type_not_found)
117 auto buildElaboratedType = [&]() {
127 diag::err_implied_std_coroutine_traits_promise_type_not_class)
128 << buildElaboratedType();
132 diag::err_coroutine_promise_type_incomplete))
145 assert(CoroNamespace &&
"Should already be diagnosed");
150 S.
Diag(Loc, diag::err_implied_coroutine_type_not_found)
151 <<
"std::coroutine_handle";
157 Result.suppressDiagnostics();
160 S.
Diag(Found->
getLocation(), diag::err_malformed_std_coroutine_handle);
173 if (CoroHandleType.
isNull())
176 diag::err_coroutine_type_missing_specialization))
179 return CoroHandleType;
190 auto *FD = dyn_cast<FunctionDecl>(S.
CurContext);
193 ? diag::err_coroutine_objc_method
194 : diag::err_coroutine_outside_function) << Keyword;
200 enum InvalidFuncDiag {
209 bool Diagnosed =
false;
210 auto DiagInvalid = [&](InvalidFuncDiag ID) {
211 S.
Diag(Loc, diag::err_coroutine_invalid_func_context) << ID << Keyword;
218 auto *MD = dyn_cast<CXXMethodDecl>(FD);
220 if (MD && isa<CXXConstructorDecl>(MD))
221 return DiagInvalid(DiagCtor);
223 else if (MD && isa<CXXDestructorDecl>(MD))
224 return DiagInvalid(DiagDtor);
226 else if (FD->isMain())
227 return DiagInvalid(DiagMain);
233 if (FD->isConstexpr())
234 DiagInvalid(FD->isConsteval() ? DiagConsteval : DiagConstexpr);
237 if (FD->getReturnType()->isUndeducedType())
238 DiagInvalid(DiagAutoRet);
242 if (FD->isVariadic())
243 DiagInvalid(DiagVarargs);
263 cast<UnresolvedLookupExpr>(R.
get()));
269 if (CoroHandleType.
isNull())
276 S.
Diag(Loc, diag::err_coroutine_handle_missing_member)
307 Base,
Base->getType(), Loc,
false, SS,
314 if (
auto *TE = dyn_cast<TypoExpr>(
Result.get())) {
316 S.
Diag(Loc, diag::err_no_member)
317 << NameInfo.
getName() <<
Base->getType()->getAsCXXRecordDecl()
318 <<
Base->getSourceRange();
322 auto EndLoc = Args.empty() ? Loc : Args.back()->getEndLoc();
346 Expr *JustAddress = AddressExpr.
get();
365 if (
auto *FD = cast<CallExpr>(JustAddress)->getDirectCallee())
366 if (!FD->hasAttr<AlwaysInlineAttr>() && !FD->hasAttr<NoInlineAttr>())
367 FD->addAttr(AlwaysInlineAttr::CreateImplicit(S.
getASTContext(),
372 S.
Diag(cast<CallExpr>(JustAddress)->getCalleeDecl()->getLocation(),
373 diag::warn_coroutine_handle_address_invalid_return_type)
429 if (FD->
hasAttr<NoInlineAttr>() || FD->
hasAttr<AlwaysInlineAttr>())
466 auto BuildSubExpr = [&](ACT CallType, StringRef
Func,
477 CallExpr *AwaitReady = cast_or_null<CallExpr>(
478 BuildSubExpr(ACT::ACT_Ready,
"await_ready", std::nullopt));
488 diag::note_await_ready_no_bool_conversion);
489 S.
Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
502 Expr *CoroHandle = CoroHandleRes.
get();
503 CallExpr *AwaitSuspend = cast_or_null<CallExpr>(
504 BuildSubExpr(ACT::ACT_Suspend,
"await_suspend", CoroHandle));
519 if (
Expr *TailCallSuspend =
526 Calls.
Results[ACT::ACT_Suspend] = TailCallSuspend;
532 diag::err_await_suspend_invalid_return_type)
534 S.
Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
538 Calls.
Results[ACT::ACT_Suspend] =
543 BuildSubExpr(ACT::ACT_Resume,
"await_resume", std::nullopt);
565 assert(isa<FunctionDecl>(
CurContext) &&
"not in a function scope");
567 bool IsThisDependentType = [&] {
568 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FD))
569 return MD->isImplicitObjectMemberFunction() &&
570 MD->getThisType()->isDependentType();
585 if (VD->isInvalidDecl())
595 if (
auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
603 CtorArgExprs.push_back(ThisExpr.
get());
608 auto &Moves = ScopeInfo->CoroutineParameterMoves;
609 for (
auto *PD : FD->parameters()) {
610 if (PD->getType()->isDependentType())
614 auto Move = Moves.find(PD);
615 assert(Move != Moves.end() &&
616 "Coroutine function parameter not inserted into move map");
620 cast<VarDecl>(cast<DeclStmt>(Move->second)->getSingleDecl());
624 if (RefExpr.isInvalid())
626 CtorArgExprs.push_back(RefExpr.get());
631 if (!CtorArgExprs.empty()) {
635 CtorArgExprs, FD->getLocation());
638 VD->getLocation(),
true, PLE);
652 VD->setInvalidDecl();
653 }
else if (
Result.get()) {
670 bool IsImplicit =
false) {
674 assert(isa<FunctionDecl>(S.
CurContext) &&
"not in a function scope");
677 assert(ScopeInfo &&
"missing function scope for function");
679 if (ScopeInfo->FirstCoroutineStmtLoc.isInvalid() && !IsImplicit)
680 ScopeInfo->setFirstCoroutineStmt(Loc, Keyword);
682 if (ScopeInfo->CoroutinePromise)
689 if (!ScopeInfo->CoroutinePromise)
699 llvm::SmallPtrSetImpl<const Decl *> &ThrowingDecls) {
700 auto checkDeclNoexcept = [&](
const Decl *D,
bool IsDtor =
false) {
704 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
712 if (FD->getBuiltinID() == Builtin::BI__builtin_coro_resume)
715 if (ThrowingDecls.empty()) {
722 diag::err_coroutine_promise_final_suspend_requires_nothrow);
724 ThrowingDecls.insert(D);
728 if (
auto *CE = dyn_cast<CXXConstructExpr>(E)) {
730 checkDeclNoexcept(Ctor);
733 }
else if (
auto *CE = dyn_cast<CallExpr>(E)) {
734 if (CE->isTypeDependent())
737 checkDeclNoexcept(CE->getCalleeDecl());
744 checkDeclNoexcept(cast<CXXRecordDecl>(T->getDecl())->getDestructor(),
748 for (
const auto *Child : E->
children()) {
763 ThrowingDecls.end()};
764 sort(SortedDecls, [](
const Decl *A,
const Decl *B) {
767 for (
const auto *D : SortedDecls) {
768 Diag(D->getEndLoc(), diag::note_coroutine_function_declare_noexcept);
770 return ThrowingDecls.empty();
778 assert(ScopeInfo->CoroutinePromise);
782 if (!ScopeInfo->NeedsCoroutineSuspends)
785 ScopeInfo->setNeedsCoroutineSuspends(
false);
790 auto buildSuspends = [&](StringRef Name)
mutable ->
StmtResult {
792 Loc, Name, std::nullopt);
793 if (Operand.isInvalid())
803 Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
804 << ((Name ==
"initial_suspend") ? 0 : 1);
805 Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword;
808 return cast<Stmt>(Suspend.
get());
811 StmtResult InitSuspend = buildSuspends(
"initial_suspend");
815 StmtResult FinalSuspend = buildSuspends(
"final_suspend");
819 ScopeInfo->setCoroutineSuspends(InitSuspend.
get(), FinalSuspend.
get());
841 while (S && !S->isFunctionScope()) {
842 if (S->isCatchScope())
860 S.
Diag(Loc, diag::err_coroutine_unevaluated_context) << Keyword;
866 S.
Diag(Loc, diag::err_coroutine_within_handler) << Keyword;
891 cast<UnresolvedLookupExpr>(Lookup.
get()));
901 assert(!Operators.
isAmbiguous() &&
"Operator lookup cannot be ambiguous");
904 Functions.size() > 1 ||
905 (Functions.size() == 1 && isa<FunctionTemplateDecl>(*Functions.begin()));
909 Functions.begin(), Functions.end());
922 if (Operand->hasPlaceholderType()) {
929 auto *Promise = FSI->CoroutinePromise;
930 if (Promise->getType()->isDependentType()) {
937 auto *Transformed = Operand;
943 diag::note_coroutine_promise_implicit_await_transform_required_here)
944 << Operand->getSourceRange();
947 Transformed = R.
get();
957 Expr *Awaiter,
bool IsImplicit) {
1008 *
this,
getCurFunction()->CoroutinePromise, Loc,
"yield_value", E);
1044 *
this, Coroutine->CoroutinePromise, Loc, E);
1076 VarDecl *Promise = FSI->CoroutinePromise;
1097 assert(
Std &&
"Should already be diagnosed");
1104 S.
Diag(Loc, diag::err_implicit_coroutine_std_nothrow_type_not_found);
1110 Result.suppressDiagnostics();
1138 assert(PointeeRD &&
"PromiseType must be a CxxRecordDecl type");
1140 const bool Overaligned = S.
getLangOpts().CoroAlignedAllocation;
1157 if (!OperatorDelete) {
1160 const bool CanProvideSize =
true;
1165 Overaligned, DeleteName);
1167 if (!OperatorDelete)
1178 assert(Fn && Fn->
isCoroutine() &&
"not a coroutine");
1181 "a null body is only allowed for invalid declarations");
1189 if (isa<CoroutineBodyStmt>(Body)) {
1199 if (FD->
hasAttr<AlwaysInlineAttr>())
1211 "first coroutine location not set");
1223 if (Builder.isInvalid() || !Builder.buildStatements())
1231 if (
auto *CS = dyn_cast<CompoundStmt>(Body))
1237 assert(isa<CXXTryStmt>(Body) &&
"Unimaged coroutine body type");
1245 : S(S), FD(FD), Fn(Fn), Loc(FD.getLocation()),
1246 IsPromiseDependentType(
1247 !Fn.CoroutinePromise ||
1248 Fn.CoroutinePromise->getType()->isDependentType()) {
1252 this->ParamMovesVector.push_back(KV.second);
1255 if (!IsPromiseDependentType) {
1257 assert(PromiseRecordDecl &&
"Type should have already been checked");
1259 this->IsValid = makePromiseStmt() && makeInitialAndFinalSuspend();
1263 assert(this->IsValid &&
"coroutine already invalid");
1264 this->IsValid = makeReturnObject();
1265 if (this->IsValid && !IsPromiseDependentType)
1267 return this->IsValid;
1271 assert(this->IsValid &&
"coroutine already invalid");
1272 assert(!this->IsPromiseDependentType &&
1273 "coroutine cannot have a dependent promise type");
1274 this->IsValid = makeOnException() && makeOnFallthrough() &&
1275 makeGroDeclAndReturnStmt() && makeReturnOnAllocFailure() &&
1276 makeNewAndDeleteExpr();
1277 return this->IsValid;
1280bool CoroutineStmtBuilder::makePromiseStmt() {
1292bool CoroutineStmtBuilder::makeInitialAndFinalSuspend() {
1304 if (
auto *DeclRef = dyn_cast_or_null<DeclRefExpr>(E)) {
1305 auto *
Decl = DeclRef->getDecl();
1307 if (Method->isStatic())
1316 diag::err_coroutine_promise_get_return_object_on_allocation_failure)
1317 << PromiseRecordDecl;
1323bool CoroutineStmtBuilder::makeReturnOnAllocFailure() {
1324 assert(!IsPromiseDependentType &&
1325 "cannot make statement while the promise type is dependent");
1353 if (ReturnObjectOnAllocationFailure.
isInvalid())
1359 S.
Diag(Found.getFoundDecl()->getLocation(), diag::note_member_declared_here)
1375 if (
auto *MD = dyn_cast<CXXMethodDecl>(&FD)) {
1383 PlacementArgs.push_back(ThisExpr.
get());
1388 if (PD->getType()->isDependentType())
1392 auto PDLoc = PD->getLocation();
1399 PlacementArgs.push_back(PDRefExpr.
get());
1405bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
1407 assert(!IsPromiseDependentType &&
1408 "cannot make statement while the promise type is dependent");
1452 const bool PromiseContainsNew = [
this, &PromiseType]() ->
bool {
1460 return !R.empty() && !R.isAmbiguous();
1465 bool PassAlignment = S.
getLangOpts().CoroAlignedAllocation;
1468 bool WithoutPlacementArgs =
false,
1469 bool ForceNonAligned =
false) {
1479 PassAlignment = !ForceNonAligned && S.
getLangOpts().CoroAlignedAllocation;
1483 false, PassAlignment,
1486 OperatorNew, UnusedResult,
false);
1495 LookupAllocationFunction();
1497 if (PromiseContainsNew && !PlacementArgs.empty()) {
1511 (S.
getLangOpts().CoroAlignedAllocation && !PassAlignment))
1534 bool FoundNonAlignedInPromise =
false;
1535 if (PromiseContainsNew && S.
getLangOpts().CoroAlignedAllocation)
1536 if (!OperatorNew || !PassAlignment) {
1537 FoundNonAlignedInPromise = OperatorNew;
1543 if (!OperatorNew && !PlacementArgs.empty())
1549 bool IsGlobalOverload =
1550 OperatorNew && !isa<CXXRecordDecl>(OperatorNew->
getDeclContext());
1554 if (RequiresNoThrowAlloc && (!OperatorNew || IsGlobalOverload)) {
1558 PlacementArgs = {StdNoThrow};
1559 OperatorNew =
nullptr;
1566 if (FoundNonAlignedInPromise) {
1568 diag::warn_non_aligned_allocation_function)
1573 if (PromiseContainsNew)
1574 S.
Diag(Loc, diag::err_coroutine_unusable_new) << PromiseType << &FD;
1575 else if (RequiresNoThrowAlloc)
1576 S.
Diag(Loc, diag::err_coroutine_unfound_nothrow_new)
1582 if (RequiresNoThrowAlloc) {
1584 if (!FT->isNothrow(
false)) {
1586 diag::err_coroutine_promise_new_requires_nothrow)
1588 S.
Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
1608 Expr *FrameAlignment =
nullptr;
1631 if (S.
getLangOpts().CoroAlignedAllocation && PassAlignment)
1632 NewArgs.push_back(FrameAlignment);
1635 llvm::append_range(NewArgs, PlacementArgs);
1662 const auto *OpDeleteType =
1664 if (OpDeleteType->getNumParams() > DeleteArgs.size() &&
1666 OpDeleteType->getParamType(DeleteArgs.size()), FrameSize->
getType()))
1667 DeleteArgs.push_back(FrameSize);
1681 OpDeleteType->getNumParams() > DeleteArgs.size() &&
1683 OpDeleteType->getParamType(DeleteArgs.size()),
1685 DeleteArgs.push_back(FrameAlignment);
1700bool CoroutineStmtBuilder::makeOnFallthrough() {
1701 assert(!IsPromiseDependentType &&
1702 "cannot make statement while the promise type is dependent");
1711 bool HasRVoid, HasRValue;
1713 lookupMember(S,
"return_void", PromiseRecordDecl, Loc, HasRVoid);
1715 lookupMember(S,
"return_value", PromiseRecordDecl, Loc, HasRValue);
1718 if (HasRVoid && HasRValue) {
1720 S.
Diag(FD.getLocation(),
1721 diag::err_coroutine_promise_incompatible_return_functions)
1722 << PromiseRecordDecl;
1724 diag::note_member_first_declared_here)
1727 diag::note_member_first_declared_here)
1730 }
else if (!HasRVoid && !HasRValue) {
1744 }
else if (HasRVoid) {
1756bool CoroutineStmtBuilder::makeOnException() {
1758 assert(!IsPromiseDependentType &&
1759 "cannot make statement while the promise type is dependent");
1761 const bool RequireUnhandledException = S.
getLangOpts().CXXExceptions;
1763 if (!
lookupMember(S,
"unhandled_exception", PromiseRecordDecl, Loc)) {
1765 RequireUnhandledException
1766 ? diag::err_coroutine_promise_unhandled_exception_required
1768 warn_coroutine_promise_unhandled_exception_required_with_exceptions;
1769 S.
Diag(Loc, DiagID) << PromiseRecordDecl;
1771 << PromiseRecordDecl;
1772 return !RequireUnhandledException;
1799bool CoroutineStmtBuilder::makeReturnObject() {
1804 "get_return_object", std::nullopt);
1813 if (
auto *MbrRef = dyn_cast<CXXMemberCallExpr>(E)) {
1814 auto *MethodDecl = MbrRef->getMethodDecl();
1815 S.
Diag(MethodDecl->getLocation(), diag::note_member_declared_here)
1822bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() {
1823 assert(!IsPromiseDependentType &&
1824 "cannot make statement while the promise type is dependent");
1825 assert(this->
ReturnValue &&
"ReturnValue must be already formed");
1829 "get_return_object type must no longer be dependent");
1831 QualType const FnRetType = FD.getReturnType();
1833 "get_return_object type must no longer be dependent");
1849 if (!GroMatchesRetType)
1865 if (GroMatchesRetType) {
1869 S.
Context, &FD, FD.getLocation(), FD.getLocation(),
1914 if (!GroMatchesRetType &&
1915 cast<clang::ReturnStmt>(
ReturnStmt.get())->getNRVOCandidate() == GroDecl)
1951 assert(isa<FunctionDecl>(
CurContext) &&
"not in a function scope");
1955 if (!ScopeInfo->CoroutineParameterMoves.empty())
1964 for (
auto *PD : FD->parameters()) {
1965 if (PD->getType()->isDependentType())
1969 bool DeclReferenced = PD->isReferenced();
1975 PD->setReferenced(DeclReferenced);
1980 Expr *CExpr =
nullptr;
1981 if (PD->getType()->getAsCXXRecordDecl() ||
1982 PD->getType()->isRValueReferenceType())
1985 CExpr = PDRefExpr.
get();
1989 auto *D =
buildVarDecl(*
this, Loc, PD->getType(), PD->getIdentifier());
1994 if (
Stmt.isInvalid())
1997 ScopeInfo->CoroutineParameterMoves.insert(std::make_pair(PD,
Stmt.get()));
2023 Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
2024 <<
"std::coroutine_traits";
2031 Result.suppressDiagnostics();
This file provides some common utility functions for processing Lambda related AST Constructs.
Defines enum values for all the target-independent builtin functions.
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines the clang::Preprocessor interface.
static ExprResult buildCoroutineHandle(Sema &S, QualType PromiseType, SourceLocation Loc)
static void noteMemberDeclaredHere(Sema &S, Expr *E, FunctionScopeInfo &Fn)
static bool isValidCoroutineContext(Sema &S, SourceLocation Loc, StringRef Keyword)
static Expr * buildStdNoThrowDeclRef(Sema &S, SourceLocation Loc)
Look up the std::nothrow object.
static ExprResult buildOperatorCoawaitCall(Sema &SemaRef, Scope *S, SourceLocation Loc, Expr *E)
static bool diagReturnOnAllocFailure(Sema &S, Expr *E, CXXRecordDecl *PromiseRecordDecl, FunctionScopeInfo &Fn)
static ExprResult buildPromiseCall(Sema &S, VarDecl *Promise, SourceLocation Loc, StringRef Name, MultiExprArg Args)
static Expr * castForMoving(Sema &S, Expr *E, QualType T=QualType())
static Expr * maybeTailCall(Sema &S, QualType RetType, Expr *E, SourceLocation Loc)
static ExprResult buildMemberCall(Sema &S, Expr *Base, SourceLocation Loc, StringRef Name, MultiExprArg Args)
static LookupResult lookupMember(Sema &S, const char *Name, CXXRecordDecl *RD, SourceLocation Loc, bool &Res)
static void tryMarkAwaitSuspendNoInline(Sema &S, OpaqueValueExpr *Awaiter, CallExpr *AwaitSuspend)
The await_suspend call performed by co_await is essentially asynchronous to the execution of the coro...
static TypeSourceInfo * getTypeSourceInfoForStdAlignValT(Sema &S, SourceLocation Loc)
static bool isWithinCatchScope(Scope *S)
static bool findDeleteForPromise(Sema &S, SourceLocation Loc, QualType PromiseType, FunctionDecl *&OperatorDelete)
static VarDecl * buildVarDecl(Sema &S, SourceLocation Loc, QualType Type, IdentifierInfo *II)
Build a variable declaration for move parameter.
static void checkNoThrow(Sema &S, const Stmt *E, llvm::SmallPtrSetImpl< const Decl * > &ThrowingDecls)
Recursively check E and all its children to see if any call target (including constructor call) is de...
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.
static bool checkSuspensionContext(Sema &S, SourceLocation Loc, StringRef Keyword)
static QualType lookupCoroutineHandleType(Sema &S, QualType PromiseType, SourceLocation Loc)
Look up the std::coroutine_handle<PromiseType>.
static bool collectPlacementArgs(Sema &S, FunctionDecl &FD, SourceLocation Loc, SmallVectorImpl< Expr * > &PlacementArgs)
static CompoundStmt * buildCoroutineBody(Stmt *Body, ASTContext &Context)
static QualType lookupPromiseType(Sema &S, const FunctionDecl *FD, SourceLocation KwLoc)
Look up the std::coroutine_traits<...>::promise_type for the given function type.
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.
static bool IsOverloaded(const UnresolvedSetImpl &Functions)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getRValueReferenceType(QualType T) const
Return the uniqued reference to the type for an rvalue reference to the specified type.
DeclarationNameTable DeclarationNames
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType getElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, QualType NamedType, TagDecl *OwnedTagDecl=nullptr) const
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
AddrLabelExpr - The GNU address of label extension, representing &&label.
SourceLocation getBeginLoc() const LLVM_READONLY
Represents a C++ constructor within a class.
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Represents a C++ struct/union/class.
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
Represents a C++ nested-name-specifier or a global scope specifier.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
Declaration of a class template.
void setExprNeedsCleanups(bool SideEffects)
Represents a 'co_await' expression.
CompoundStmt - This represents a group of statements like { stmt stmt }.
static CompoundStmt * Create(const ASTContext &C, ArrayRef< Stmt * > Stmts, FPOptionsOverride FPFeatures, SourceLocation LB, SourceLocation RB)
Represents a 'co_return' statement in the C++ Coroutines TS.
Represents the body of a coroutine.
static CoroutineBodyStmt * Create(const ASTContext &C, CtorArgs const &Args)
CoroutineStmtBuilder(Sema &S, FunctionDecl &FD, sema::FunctionScopeInfo &Fn, Stmt *Body)
Construct a CoroutineStmtBuilder and initialize the promise statement and initial/final suspends from...
bool buildDependentStatements()
Build the coroutine body statements that require a non-dependent promise type in order to construct.
bool buildStatements()
Build the coroutine body statements, including the "promise dependent" statements when the promise ty...
Represents a 'co_yield' expression.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
bool isInvalidDecl() const
SourceLocation getLocation() const
void setImplicit(bool I=true)
DeclContext * getDeclContext()
The name of a declaration.
SourceLocation getBeginLoc() const LLVM_READONLY
Represents a 'co_await' expression while the type of the promise is dependent.
This represents one expression.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
Represents difference between two FPOptions values.
Represents a function declaration or definition.
ArrayRef< ParmVarDecl * > parameters() const
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Represents a prototype with parameter type info, e.g.
ArrayRef< QualType > getParamTypes() const
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
QualType getReturnType() const
One of these records is kept for each identifier that is lexed.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Describes the kind of initialization being performed, along with location information for tokens rela...
static InitializationKind CreateForInit(SourceLocation Loc, bool DirectInit, Expr *Init)
Create an initialization from an initializer (which, for direct initialization from a parenthesized l...
Describes the sequence of initializations required to initialize a given object or reference with a s...
ExprResult Perform(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, QualType *ResultType=nullptr)
Perform the actual initialization of the given entity based on the computed initialization sequence.
Describes an entity that is being initialized.
static InitializedEntity InitializeResult(SourceLocation ReturnLoc, QualType Type)
Create the initialization entity for the result of a function.
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
Represents the results of name lookup.
DeclClass * getAsSingle() const
const UnresolvedSetImpl & asUnresolvedSet() const
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
DeclarationName getLookupName() const
Gets the name to look up.
This represents a decl that may have a name.
Represent a C++ namespace.
A C++ nested-name-specifier augmented with source location information.
static NestedNameSpecifier * Create(const ASTContext &Context, NestedNameSpecifier *Prefix, IdentifierInfo *II)
Builds a specifier combining a prefix and an identifier.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
decls_iterator decls_begin() const
decls_iterator decls_end() const
static ParenListExpr * Create(const ASTContext &Ctx, SourceLocation LParenLoc, ArrayRef< Expr * > Exprs, SourceLocation RParenLoc)
Create a paren list.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
IdentifierTable & getIdentifierTable()
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Scope - A scope is a transient data structure that is used while parsing the program.
Sema - This implements semantic analysis and AST building for C.
FunctionDecl * FindUsualDeallocationFunction(SourceLocation StartLoc, bool CanProvideSize, bool Overaligned, DeclarationName Name)
ExprResult BuildOperatorCoawaitCall(SourceLocation Loc, Expr *E, UnresolvedLookupExpr *Lookup)
Build a call to 'operator co_await' if there is a suitable operator for the given expression.
Scope * getCurScope() const
Retrieve the parser's current scope.
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)
ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *InputExpr, bool IsAfterAmp=false)
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ LookupOperatorName
Look up of an operator name (e.g., operator+) for use with operator overloading.
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
bool checkFinalSuspendNoThrow(const Stmt *FinalSuspend)
Check that the expression co_await promise.final_suspend() shall not be potentially-throwing.
StmtResult BuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs)
ExprResult BuildCoyieldExpr(SourceLocation KwLoc, Expr *E)
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body)
bool ActOnCoroutineBodyStart(Scope *S, SourceLocation KwLoc, StringRef Keyword)
VarDecl * buildCoroutinePromise(SourceLocation Loc)
StmtResult BuildCoreturnStmt(SourceLocation KwLoc, Expr *E, bool IsImplicit=false)
Expr * BuildBuiltinCallExpr(SourceLocation Loc, Builtin::ID Id, MultiExprArg CallArgs)
BuildBuiltinCallExpr - Create a call to a builtin function specified by Id.
ExprResult BuildResolvedCoawaitExpr(SourceLocation KwLoc, Expr *Operand, Expr *Awaiter, bool IsImplicit=false)
void FinalizeDeclaration(Decl *D)
FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform any semantic actions neces...
ExprResult ActOnCoyieldExpr(Scope *S, SourceLocation KwLoc, Expr *E)
ExprResult ActOnCXXThis(SourceLocation loc)
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
ClassTemplateDecl * StdCoroutineTraitsCache
The C++ "std::coroutine_traits" template, which is defined in <coroutine_traits>
ASTContext & getASTContext() const
DeclRefExpr * BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
EnumDecl * getStdAlignValT() const
NamedReturnInfo getNamedReturnInfo(Expr *&E, SimplerImplicitMoveMode Mode=SimplerImplicitMoveMode::Normal)
Determine whether the given expression might be move-eligible or copy-elidable in either a (co_)retur...
StmtResult ActOnCoreturnStmt(Scope *S, SourceLocation KwLoc, Expr *E)
const LangOptions & getLangOpts() const
StmtResult ActOnFinishFullStmt(Stmt *Stmt)
ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false, bool AllowRecovery=false)
BuildCallExpr - Handle a call to Fn with the specified array of arguments.
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.
CleanupInfo Cleanup
Used to control the generation of ExprWithCleanups.
StmtResult ActOnNullStmt(SourceLocation SemiLoc, bool HasLeadingEmptyMacro=false)
ExprResult BuildUnresolvedCoawaitExpr(SourceLocation KwLoc, Expr *Operand, UnresolvedLookupExpr *Lookup)
bool buildCoroutineParameterMoves(SourceLocation Loc)
sema::FunctionScopeInfo * getCurFunction() const
QualType BuildReferenceType(QualType T, bool LValueRef, SourceLocation Loc, DeclarationName Entity)
Build a reference type.
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.
ExprResult ActOnCoawaitExpr(Scope *S, SourceLocation KwLoc, Expr *E)
ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS, LookupResult &R, bool NeedsADL, bool AcceptInvalidDecl=false)
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, DeclarationName Name, FunctionDecl *&Operator, bool Diagnose=true, bool WantSize=false, bool WantAligned=false)
MaterializeTemporaryExpr * CreateMaterializeTemporaryExpr(QualType T, Expr *Temporary, bool BoundToLvalueReference)
ExprResult PerformContextuallyConvertToBool(Expr *From)
PerformContextuallyConvertToBool - Perform a contextual conversion of the expression From to bool (C+...
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
ClassTemplateDecl * lookupCoroutineTraits(SourceLocation KwLoc, SourceLocation FuncLoc)
Lookup 'coroutine_traits' in std namespace and std::experimental namespace.
DeclContext * computeDeclContext(QualType T)
Compute the DeclContext that is associated with the given type.
QualType CheckTemplateIdType(TemplateName Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs)
StmtResult BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, bool AllowRecovery=false)
void CheckCompleteVariableDeclaration(VarDecl *VD)
ExprResult BuildOperatorCoawaitLookupExpr(Scope *S, SourceLocation Loc)
StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
Expr * MaybeCreateExprWithCleanups(Expr *SubExpr)
MaybeCreateExprWithCleanups - If the current full-expression requires any cleanups,...
FullExprArg MakeFullDiscardedValueExpr(Expr *Arg)
NamespaceDecl * getStdNamespace() const
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
void ActOnUninitializedDecl(Decl *dcl)
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
ExprResult BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, TypeSourceInfo *Ty, Expr *E, SourceRange AngleBrackets, SourceRange Parens)
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,...
void clearDelayedTypo(TypoExpr *TE)
Clears the state of the given TypoExpr.
void CheckVariableDeclarationType(VarDecl *NewVD)
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
AllocationFunctionScope
The scope in which to find allocation functions.
@ AFS_Both
Look for allocation functions in both the global scope and in the scope of the allocated class.
@ AFS_Class
Only look for allocation functions in the scope of the allocated class.
@ AFS_Global
Only look for allocation functions in the global scope.
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
static CanThrowResult canCalleeThrow(Sema &S, const Expr *E, const Decl *D, SourceLocation Loc=SourceLocation())
Determine whether the callee of a particular function call can throw.
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
A convenient class for passing around template argument information.
void addArgument(const TemplateArgumentLoc &Loc)
Location wrapper for a TemplateArgument.
Represents a template argument.
Represents a C++ template name within the type system.
Represents a declaration of a type.
A container of type source information.
The base class of the type hierarchy.
bool isStructureType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isBooleanType() const
bool isVoidPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isRecordType() const
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
static UnresolvedLookupExpr * Create(const ASTContext &Context, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded, UnresolvedSetIterator Begin, UnresolvedSetIterator End)
void append(iterator I, iterator E)
A set of unresolved declarations.
Represents a variable declaration or definition.
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
@ CallInit
Call-style initialization (C++98)
void setNRVOVariable(bool NRVO)
Retains information about a function, method, or block that is currently being parsed.
SourceLocation FirstVLALoc
First use of a VLA within the current function.
llvm::SmallMapVector< ParmVarDecl *, Stmt *, 4 > CoroutineParameterMoves
A mapping between the coroutine function parameters that were moved to the coroutine frame,...
SourceLocation FirstCoroutineStmtLoc
First coroutine statement in the current function.
std::pair< Stmt *, Stmt * > CoroutineSuspends
The initial and final coroutine suspend points.
VarDecl * CoroutinePromise
The promise object for this coroutine, if any.
bool hasInvalidCoroutineSuspends() const
StringRef getFirstCoroutineStmtKeyword() const
SourceLocation FirstReturnLoc
First 'return' statement in the current function.
SourceLocation FirstSEHTryLoc
First SEH '__try' statement in the current function.
llvm::SmallVector< AddrLabelExpr *, 4 > AddrLabels
The set of GNU address of label extension "&&label".
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
OpaqueValueExpr * OpaqueValue
Stmt * ReturnStmtOnAllocFailure
ArrayRef< Stmt * > ParamMoves
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
DeclarationName getName() const
getName - Returns the embedded declaration name.