72 if (
auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
73 if (MD->isImplicitObjectMemberFunction()) {
81 QualType T = MD->getFunctionObjectParameterType();
93 ElaboratedTypeKeyword::None,
TemplateName(CoroTraits), KwLoc, Args);
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)
121 diag::err_implied_std_coroutine_traits_promise_type_not_class)
126 diag::err_coroutine_promise_type_incomplete))
139 assert(CoroNamespace &&
"Should already be diagnosed");
144 S.
Diag(
Loc, diag::err_implied_coroutine_type_not_found)
145 <<
"std::coroutine_handle";
151 Result.suppressDiagnostics();
154 S.
Diag(
Found->getLocation(), diag::err_malformed_std_coroutine_handle);
167 if (CoroHandleType.
isNull())
170 diag::err_coroutine_type_missing_specialization))
173 return CoroHandleType;
184 auto *FD = dyn_cast<FunctionDecl>(S.
CurContext);
187 ? diag::err_coroutine_objc_method
188 : diag::err_coroutine_outside_function) <<
Keyword;
194 enum InvalidFuncDiag {
203 bool Diagnosed =
false;
204 auto DiagInvalid = [&](InvalidFuncDiag ID) {
205 S.
Diag(
Loc, diag::err_coroutine_invalid_func_context) << ID <<
Keyword;
212 auto *MD = dyn_cast<CXXMethodDecl>(FD);
214 if (MD && isa<CXXConstructorDecl>(MD))
215 return DiagInvalid(DiagCtor);
217 else if (MD && isa<CXXDestructorDecl>(MD))
218 return DiagInvalid(DiagDtor);
220 else if (FD->isMain())
221 return DiagInvalid(DiagMain);
227 if (FD->isConstexpr())
228 DiagInvalid(FD->isConsteval() ? DiagConsteval : DiagConstexpr);
231 if (FD->getReturnType()->isUndeducedType())
232 DiagInvalid(DiagAutoRet);
236 if (FD->isVariadic())
237 DiagInvalid(DiagVarargs);
257 cast<UnresolvedLookupExpr>(R.
get()));
263 if (CoroHandleType.
isNull())
270 S.
Diag(
Loc, diag::err_coroutine_handle_missing_member)
307 auto EndLoc = Args.empty() ?
Loc : Args.back()->getEndLoc();
331 Expr *JustAddress = AddressExpr.
get();
335 S.
Diag(cast<CallExpr>(JustAddress)->getCalleeDecl()->getLocation(),
336 diag::warn_coroutine_handle_address_invalid_return_type)
367 auto BuildSubExpr = [&](ACT CallType, StringRef
Func,
379 cast_or_null<CallExpr>(BuildSubExpr(ACT::ACT_Ready,
"await_ready", {}));
389 diag::note_await_ready_no_bool_conversion);
390 S.
Diag(
Loc, diag::note_coroutine_promise_call_implicitly_required)
403 Expr *CoroHandle = CoroHandleRes.
get();
404 CallExpr *AwaitSuspend = cast_or_null<CallExpr>(
405 BuildSubExpr(ACT::ACT_Suspend,
"await_suspend", CoroHandle));
416 if (
Expr *TailCallSuspend =
423 Calls.
Results[ACT::ACT_Suspend] = TailCallSuspend;
429 diag::err_await_suspend_invalid_return_type)
431 S.
Diag(
Loc, diag::note_coroutine_promise_call_implicitly_required)
435 Calls.
Results[ACT::ACT_Suspend] =
440 BuildSubExpr(ACT::ACT_Resume,
"await_resume", {});
462 assert(isa<FunctionDecl>(
CurContext) &&
"not in a function scope");
464 bool IsThisDependentType = [&] {
465 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FD))
466 return MD->isImplicitObjectMemberFunction() &&
467 MD->getThisType()->isDependentType();
482 if (VD->isInvalidDecl())
492 if (
auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
500 CtorArgExprs.push_back(ThisExpr.
get());
505 auto &Moves = ScopeInfo->CoroutineParameterMoves;
506 for (
auto *PD : FD->parameters()) {
507 if (PD->getType()->isDependentType())
511 auto Move = Moves.find(PD);
512 assert(Move != Moves.end() &&
513 "Coroutine function parameter not inserted into move map");
517 cast<VarDecl>(cast<DeclStmt>(Move->second)->getSingleDecl());
521 if (RefExpr.isInvalid())
523 CtorArgExprs.push_back(RefExpr.get());
528 if (!CtorArgExprs.empty()) {
532 CtorArgExprs, FD->getLocation());
535 VD->getLocation(),
true, PLE);
549 VD->setInvalidDecl();
550 }
else if (
Result.get()) {
567 bool IsImplicit =
false) {
571 assert(isa<FunctionDecl>(S.
CurContext) &&
"not in a function scope");
574 assert(ScopeInfo &&
"missing function scope for function");
576 if (ScopeInfo->FirstCoroutineStmtLoc.isInvalid() && !IsImplicit)
577 ScopeInfo->setFirstCoroutineStmt(
Loc,
Keyword);
579 if (ScopeInfo->CoroutinePromise)
586 if (!ScopeInfo->CoroutinePromise)
596 llvm::SmallPtrSetImpl<const Decl *> &ThrowingDecls) {
597 auto checkDeclNoexcept = [&](
const Decl *
D,
bool IsDtor =
false) {
601 if (
const auto *FD = dyn_cast<FunctionDecl>(
D)) {
609 if (FD->getBuiltinID() == Builtin::BI__builtin_coro_resume)
612 if (ThrowingDecls.empty()) {
619 diag::err_coroutine_promise_final_suspend_requires_nothrow);
621 ThrowingDecls.insert(
D);
625 if (
auto *CE = dyn_cast<CXXConstructExpr>(
E)) {
627 checkDeclNoexcept(Ctor);
630 }
else if (
auto *CE = dyn_cast<CallExpr>(
E)) {
631 if (CE->isTypeDependent())
634 checkDeclNoexcept(CE->getCalleeDecl());
641 checkDeclNoexcept(cast<CXXRecordDecl>(
T->getOriginalDecl())
647 for (
const auto *Child :
E->
children()) {
662 ThrowingDecls.end()};
663 sort(SortedDecls, [](
const Decl *A,
const Decl *B) {
666 for (
const auto *
D : SortedDecls) {
667 Diag(
D->
getEndLoc(), diag::note_coroutine_function_declare_noexcept);
669 return ThrowingDecls.empty();
675 assert(FSI &&
"FunctionScopeInfo is null");
677 "first coroutine location not set");
695 assert(ScopeInfo->CoroutinePromise);
698 if (ScopeInfo->FirstCoroutineStmtLoc == KWLoc)
703 if (!ScopeInfo->NeedsCoroutineSuspends)
706 ScopeInfo->setNeedsCoroutineSuspends(
false);
711 auto buildSuspends = [&](StringRef Name)
mutable ->
StmtResult {
714 if (Operand.isInvalid())
724 Diag(
Loc, diag::note_coroutine_promise_suspend_implicitly_required)
725 << ((Name ==
"initial_suspend") ? 0 : 1);
726 Diag(KWLoc, diag::note_declared_coroutine_here) <<
Keyword;
729 return cast<Stmt>(Suspend.
get());
732 StmtResult InitSuspend = buildSuspends(
"initial_suspend");
736 StmtResult FinalSuspend = buildSuspends(
"final_suspend");
740 ScopeInfo->setCoroutineSuspends(InitSuspend.
get(), FinalSuspend.
get());
762 while (S && !S->isFunctionScope()) {
763 if (S->isCatchScope())
781 const bool BadContext =
816 cast<UnresolvedLookupExpr>(Lookup.
get()));
826 assert(!Operators.
isAmbiguous() &&
"Operator lookup cannot be ambiguous");
831 Functions.end(),
false,
843 auto *
Call = dyn_cast<CallExpr>(Operand->IgnoreImplicit());
850 Call->setCoroElideSafe();
853 auto *Fn = llvm::dyn_cast_if_present<FunctionDecl>(
Call->getCalleeDecl());
859 if (PD->hasAttr<CoroAwaitElidableArgumentAttr>())
874 if (Operand->hasPlaceholderType()) {
881 auto *Promise = FSI->CoroutinePromise;
882 if (Promise->getType()->isDependentType()) {
893 if (CurFnAwaitElidable)
896 Expr *Transformed = Operand;
902 diag::note_coroutine_promise_implicit_await_transform_required_here)
903 << Operand->getSourceRange();
906 Transformed = R.
get();
916 Expr *Awaiter,
bool IsImplicit) {
1002 *
this, Coroutine->CoroutinePromise,
Loc,
E);
1033 VarDecl *Promise = FSI->CoroutinePromise;
1054 assert(
Std &&
"Should already be diagnosed");
1061 S.
Diag(
Loc, diag::err_implicit_coroutine_std_nothrow_type_not_found);
1067 Result.suppressDiagnostics();
1070 S.
Diag(
Found->getLocation(), diag::err_malformed_std_nothrow);
1091 unsigned DiagnosticID,
1098 bool HaveIssuedWarning =
false;
1099 for (
auto Decl : R) {
1102 if (!HaveIssuedWarning) {
1103 S.
Diag(
Loc, DiagnosticID) << Name;
1104 HaveIssuedWarning =
true;
1110 return HaveIssuedWarning;
1119 diag::warn_coroutine_type_aware_allocator_ignored,
1120 DeleteName, PromiseType);
1122 assert(PointeeRD &&
"PromiseType must be a CxxRecordDecl type");
1124 const bool Overaligned = S.
getLangOpts().CoroAlignedAllocation;
1142 if (!OperatorDelete) {
1151 if (!OperatorDelete)
1155 assert(!OperatorDelete->isTypeAwareOperatorNewOrDelete());
1163 assert(Fn && Fn->isCoroutine() &&
"not a coroutine");
1166 "a null body is only allowed for invalid declarations");
1171 if (!Fn->CoroutinePromise)
1174 if (isa<CoroutineBodyStmt>(Body)) {
1184 if (FD->
hasAttr<AlwaysInlineAttr>())
1189 if (Fn->FirstVLALoc.isValid())
1190 Diag(Fn->FirstVLALoc, diag::err_vla_in_coroutine_unsupported);
1202 if (Builder.isInvalid() || !Builder.buildStatements())
1210 if (
auto *CS = dyn_cast<CompoundStmt>(Body))
1216 assert(isa<CXXTryStmt>(Body) &&
"Unimaged coroutine body type");
1224 : S(S), FD(FD), Fn(Fn),
Loc(FD.getLocation()),
1225 IsPromiseDependentType(
1226 !Fn.CoroutinePromise ||
1227 Fn.CoroutinePromise->getType()->isDependentType()) {
1230 for (
auto KV : Fn.CoroutineParameterMoves)
1231 this->ParamMovesVector.push_back(KV.second);
1234 if (!IsPromiseDependentType) {
1235 PromiseRecordDecl = Fn.CoroutinePromise->getType()->getAsCXXRecordDecl();
1236 assert(PromiseRecordDecl &&
"Type should have already been checked");
1238 this->IsValid = makePromiseStmt() && makeInitialAndFinalSuspend();
1242 assert(this->IsValid &&
"coroutine already invalid");
1243 this->IsValid = makeReturnObject();
1244 if (this->IsValid && !IsPromiseDependentType)
1246 return this->IsValid;
1250 assert(this->IsValid &&
"coroutine already invalid");
1251 assert(!this->IsPromiseDependentType &&
1252 "coroutine cannot have a dependent promise type");
1253 this->IsValid = makeOnException() && makeOnFallthrough() &&
1254 makeGroDeclAndReturnStmt() && makeReturnOnAllocFailure() &&
1255 makeNewAndDeleteExpr();
1256 return this->IsValid;
1259bool CoroutineStmtBuilder::makePromiseStmt() {
1271bool CoroutineStmtBuilder::makeInitialAndFinalSuspend() {
1283 if (
auto *DeclRef = dyn_cast_or_null<DeclRefExpr>(
E)) {
1284 auto *
Decl = DeclRef->getDecl();
1295 diag::err_coroutine_promise_get_return_object_on_allocation_failure)
1296 << PromiseRecordDecl;
1297 S.
Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
1298 << Fn.getFirstCoroutineStmtKeyword();
1302bool CoroutineStmtBuilder::makeReturnOnAllocFailure() {
1303 assert(!IsPromiseDependentType &&
1304 "cannot make statement while the promise type is dependent");
1332 if (ReturnObjectOnAllocationFailure.
isInvalid())
1338 S.
Diag(
Found.getFoundDecl()->getLocation(), diag::note_member_declared_here)
1354 if (
auto *MD = dyn_cast<CXXMethodDecl>(&FD)) {
1362 PlacementArgs.push_back(ThisExpr.
get());
1367 if (PD->getType()->isDependentType())
1371 auto PDLoc = PD->getLocation();
1378 PlacementArgs.push_back(PDRefExpr.
get());
1384bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
1386 assert(!IsPromiseDependentType &&
1387 "cannot make statement while the promise type is dependent");
1433 const bool PromiseContainsNew = [
this, &PromiseType, NewName]() ->
bool {
1439 return !R.empty() && !R.isAmbiguous();
1448 bool WithoutPlacementArgs =
false,
1449 bool ForceNonAligned =
false) {
1460 bool ShouldUseAlignedAlloc =
1461 !ForceNonAligned && S.
getLangOpts().CoroAlignedAllocation;
1470 WithoutPlacementArgs ?
MultiExprArg{} : PlacementArgs, OperatorNew,
1471 UnusedResult,
false);
1472 assert(!OperatorNew || !OperatorNew->isTypeAwareOperatorNewOrDelete());
1481 LookupAllocationFunction();
1483 if (PromiseContainsNew && !PlacementArgs.empty()) {
1496 if (!OperatorNew || (S.
getLangOpts().CoroAlignedAllocation &&
1520 bool FoundNonAlignedInPromise =
false;
1521 if (PromiseContainsNew && S.
getLangOpts().CoroAlignedAllocation)
1523 FoundNonAlignedInPromise = OperatorNew;
1529 if (!OperatorNew && !PlacementArgs.empty())
1535 bool IsGlobalOverload =
1536 OperatorNew && !isa<CXXRecordDecl>(OperatorNew->getDeclContext());
1540 if (RequiresNoThrowAlloc && (!OperatorNew || IsGlobalOverload)) {
1544 PlacementArgs = {StdNoThrow};
1545 OperatorNew =
nullptr;
1552 if (FoundNonAlignedInPromise) {
1553 S.
Diag(OperatorNew->getLocation(),
1554 diag::warn_non_aligned_allocation_function)
1559 if (PromiseContainsNew) {
1560 S.
Diag(Loc, diag::err_coroutine_unusable_new) << PromiseType << &FD;
1562 S, Loc, diag::note_coroutine_unusable_type_aware_allocators, NewName,
1564 }
else if (RequiresNoThrowAlloc)
1565 S.
Diag(Loc, diag::err_coroutine_unfound_nothrow_new)
1570 assert(!OperatorNew->isTypeAwareOperatorNewOrDelete());
1573 diag::warn_coroutine_type_aware_allocator_ignored,
1574 NewName, PromiseType);
1576 if (RequiresNoThrowAlloc) {
1578 if (!FT->isNothrow(
false)) {
1579 S.
Diag(OperatorNew->getLocation(),
1580 diag::err_coroutine_promise_new_requires_nothrow)
1582 S.
Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
1596 assert(!OperatorDelete->isTypeAwareOperatorNewOrDelete());
1604 Expr *FrameAlignment =
nullptr;
1629 NewArgs.push_back(FrameAlignment);
1631 if (OperatorNew->getNumParams() > NewArgs.size())
1632 llvm::append_range(NewArgs, PlacementArgs);
1642 QualType OpDeleteQualType = OperatorDelete->getType();
1659 const auto *OpDeleteType =
1661 if (OpDeleteType->getNumParams() > DeleteArgs.size() &&
1663 OpDeleteType->getParamType(DeleteArgs.size()), FrameSize->
getType()))
1664 DeleteArgs.push_back(FrameSize);
1678 OpDeleteType->getNumParams() > DeleteArgs.size() &&
1680 OpDeleteType->getParamType(DeleteArgs.size()),
1682 DeleteArgs.push_back(FrameAlignment);
1697bool CoroutineStmtBuilder::makeOnFallthrough() {
1698 assert(!IsPromiseDependentType &&
1699 "cannot make statement while the promise type is dependent");
1708 bool HasRVoid, HasRValue;
1710 lookupMember(S,
"return_void", PromiseRecordDecl, Loc, HasRVoid);
1712 lookupMember(S,
"return_value", PromiseRecordDecl, Loc, HasRValue);
1715 if (HasRVoid && HasRValue) {
1718 diag::err_coroutine_promise_incompatible_return_functions)
1719 << PromiseRecordDecl;
1721 diag::note_member_first_declared_here)
1724 diag::note_member_first_declared_here)
1727 }
else if (!HasRVoid && !HasRValue) {
1741 }
else if (HasRVoid) {
1753bool CoroutineStmtBuilder::makeOnException() {
1755 assert(!IsPromiseDependentType &&
1756 "cannot make statement while the promise type is dependent");
1758 const bool RequireUnhandledException = S.
getLangOpts().CXXExceptions;
1760 if (!
lookupMember(S,
"unhandled_exception", PromiseRecordDecl, Loc)) {
1762 RequireUnhandledException
1763 ? diag::err_coroutine_promise_unhandled_exception_required
1765 warn_coroutine_promise_unhandled_exception_required_with_exceptions;
1766 S.
Diag(Loc, DiagID) << PromiseRecordDecl;
1768 << PromiseRecordDecl;
1769 return !RequireUnhandledException;
1796bool CoroutineStmtBuilder::makeReturnObject() {
1810 if (
auto *MbrRef = dyn_cast<CXXMemberCallExpr>(
E)) {
1811 auto *MethodDecl = MbrRef->getMethodDecl();
1812 S.
Diag(MethodDecl->getLocation(), diag::note_member_declared_here)
1815 S.
Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
1816 << Fn.getFirstCoroutineStmtKeyword();
1819bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() {
1820 assert(!IsPromiseDependentType &&
1821 "cannot make statement while the promise type is dependent");
1822 assert(this->
ReturnValue &&
"ReturnValue must be already formed");
1826 "get_return_object type must no longer be dependent");
1830 "get_return_object type must no longer be dependent");
1846 if (!GroMatchesRetType)
1862 if (GroMatchesRetType) {
1911 if (!GroMatchesRetType &&
1912 cast<clang::ReturnStmt>(
ReturnStmt.get())->getNRVOCandidate() == GroDecl)
1948 assert(isa<FunctionDecl>(
CurContext) &&
"not in a function scope");
1952 if (!ScopeInfo->CoroutineParameterMoves.empty())
1961 for (
auto *PD : FD->parameters()) {
1962 if (PD->getType()->isDependentType())
1966 bool DeclReferenced = PD->isReferenced();
1972 PD->setReferenced(DeclReferenced);
1977 Expr *CExpr =
nullptr;
1978 if (PD->getType()->getAsCXXRecordDecl() ||
1979 PD->getType()->isRValueReferenceType())
1982 CExpr = PDRefExpr.
get();
1991 if (
Stmt.isInvalid())
1994 ScopeInfo->CoroutineParameterMoves.insert(std::make_pair(PD,
Stmt.get()));
2020 Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
2021 <<
"std::coroutine_traits";
2028 Result.suppressDiagnostics();
2030 Diag(
Found->getLocation(), diag::err_malformed_std_coroutine_traits);
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.
llvm::MachO::Record Record
Defines the clang::Preprocessor interface.
static ExprResult buildCoroutineHandle(Sema &S, QualType PromiseType, SourceLocation Loc)
static bool DiagnoseTypeAwareAllocators(Sema &S, SourceLocation Loc, unsigned DiagnosticID, DeclarationName Name, QualType PromiseType)
static void noteMemberDeclaredHere(Sema &S, Expr *E, FunctionScopeInfo &Fn)
static void checkReturnStmtInCoroutine(Sema &S, FunctionScopeInfo *FSI)
static bool isValidCoroutineContext(Sema &S, SourceLocation Loc, StringRef Keyword)
static void applySafeElideContext(Expr *Operand)
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 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 bool isAttributedCoroAwaitElidable(const QualType &QT)
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.
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.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
QualType getTypeDeclType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypeDecl *Decl) const
CanQualType getCanonicalTagType(const TagDecl *TD) const
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.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
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.
RAII object that enters a new function expression evaluation context.
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.
bool isNoReturn() const
Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
bool isTypeAwareOperatorNewOrDelete() const
Determine whether this is a type aware operator new or delete.
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.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
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.
Represents a parameter to a function.
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.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Sema - This implements semantic analysis and AST building for C.
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)
bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, DeclarationName Name, FunctionDecl *&Operator, ImplicitDeallocationParameters, bool Diagnose=true)
ExprResult BuildCoyieldExpr(SourceLocation KwLoc, Expr *E)
void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body)
bool ActOnCoroutineBodyStart(Scope *S, SourceLocation KwLoc, StringRef Keyword)
VarDecl * buildCoroutinePromise(SourceLocation Loc)
const ExpressionEvaluationContextRecord & currentEvaluationContext() const
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)
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
QualType CheckTemplateIdType(ElaboratedTypeKeyword Keyword, TemplateName Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs)
void FinalizeDeclaration(Decl *D)
FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform any semantic actions neces...
ExprResult ActOnCoyieldExpr(Scope *S, SourceLocation KwLoc, Expr *E)
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.
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.
MaterializeTemporaryExpr * CreateMaterializeTemporaryExpr(QualType T, Expr *Temporary, bool BoundToLvalueReference)
bool FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, AllocationFunctionScope NewScope, AllocationFunctionScope DeleteScope, QualType AllocType, bool IsArray, ImplicitAllocationParameters &IAP, MultiExprArg PlaceArgs, FunctionDecl *&OperatorNew, FunctionDecl *&OperatorDelete, bool Diagnose=true)
Finds the overloads of operator new and delete that are appropriate for the allocation.
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.
StmtResult BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, bool AllowRecovery=false)
void CheckCompleteVariableDeclaration(VarDecl *VD)
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
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 CheckVariableDeclarationType(VarDecl *NewVD)
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
FunctionDecl * FindUsualDeallocationFunction(SourceLocation StartLoc, ImplicitDeallocationParameters, DeclarationName Name)
ExprResult ActOnCXXThis(SourceLocation Loc)
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
bool isBooleanType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
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, UnresolvedSetIterator Begin, UnresolvedSetIterator End, bool KnownDependent, bool KnownInstantiationDependent)
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 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.
The JSON file list parser is used to communicate input to InstallAPI.
AllocationFunctionScope
The scope in which to find allocation functions.
@ Both
Look for allocation functions in both the global scope and in the scope of the allocated class.
@ Global
Only look for allocation functions in the global scope.
@ Class
Only look for allocation functions in the scope of the allocated class.
AlignedAllocationMode alignedAllocationModeFromBool(bool IsAligned)
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
bool isAlignedAllocation(AlignedAllocationMode Mode)
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
@ Keyword
The name has been typo-corrected to a keyword.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
const FunctionProtoType * T
OpaqueValueExpr * OpaqueValue
Stmt * ReturnStmtOnAllocFailure
ArrayRef< Stmt * > ParamMoves
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
SizedDeallocationMode PassSize
enum clang::Sema::ExpressionEvaluationContextRecord::ExpressionKind ExprContext