75 if (
auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
76 if (MD->isImplicitObjectMemberFunction()) {
84 QualType T = MD->getFunctionObjectParameterType();
101 diag::err_coroutine_type_missing_specialization))
105 assert(RD &&
"specialization of class template is not a class?");
111 auto *Promise = R.getAsSingle<
TypeDecl>();
114 diag::err_implied_std_coroutine_traits_promise_type_not_found)
125 diag::err_implied_std_coroutine_traits_promise_type_not_class)
130 diag::err_coroutine_promise_type_incomplete))
143 assert(CoroNamespace &&
"Should already be diagnosed");
148 S.
Diag(Loc, diag::err_implied_coroutine_type_not_found)
149 <<
"std::coroutine_handle";
155 Result.suppressDiagnostics();
158 S.
Diag(
Found->getLocation(), diag::err_malformed_std_coroutine_handle);
172 if (CoroHandleType.
isNull())
175 diag::err_coroutine_type_missing_specialization))
178 return CoroHandleType;
192 ? diag::err_coroutine_objc_method
193 : diag::err_coroutine_outside_function) <<
Keyword;
199 enum InvalidFuncDiag {
208 bool Diagnosed =
false;
209 auto DiagInvalid = [&](InvalidFuncDiag ID) {
210 S.
Diag(Loc, diag::err_coroutine_invalid_func_context) << ID <<
Keyword;
217 auto *MD = dyn_cast<CXXMethodDecl>(FD);
220 return DiagInvalid(DiagCtor);
223 return DiagInvalid(DiagDtor);
225 else if (FD->isMain())
226 return DiagInvalid(DiagMain);
232 if (FD->isConstexpr())
233 DiagInvalid(FD->isConsteval() ? DiagConsteval : DiagConstexpr);
236 if (FD->getReturnType()->isUndeducedType())
237 DiagInvalid(DiagAutoRet);
241 if (FD->isVariadic())
242 DiagInvalid(DiagVarargs);
268 if (CoroHandleType.
isNull())
275 S.
Diag(Loc, diag::err_coroutine_handle_missing_member)
306 Base,
Base->getType(), Loc,
false, SS,
312 auto EndLoc = Args.empty() ? Loc : Args.back()->getEndLoc();
325 if (!
T->isClassType() && !
T->isStructureType())
336 Expr *JustAddress = AddressExpr.
get();
341 diag::warn_coroutine_handle_address_invalid_return_type)
372 auto BuildSubExpr = [&](ACT CallType, StringRef
Func,
384 cast_or_null<CallExpr>(BuildSubExpr(ACT::ACT_Ready,
"await_ready", {}));
394 diag::note_await_ready_no_bool_conversion);
395 S.
Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
408 Expr *CoroHandle = CoroHandleRes.
get();
409 CallExpr *AwaitSuspend = cast_or_null<CallExpr>(
410 BuildSubExpr(ACT::ACT_Suspend,
"await_suspend", CoroHandle));
421 if (
Expr *TailCallSuspend =
428 Calls.
Results[ACT::ACT_Suspend] = TailCallSuspend;
434 diag::err_await_suspend_invalid_return_type)
436 S.
Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
440 Calls.
Results[ACT::ACT_Suspend] =
445 BuildSubExpr(ACT::ACT_Resume,
"await_resume", {});
468 if (!PD->getType()->isDependentType())
473 auto *FD =
CurContext->castEnclosingFunction();
474 bool IsThisDependentType = [&] {
475 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FD))
476 return MD->isImplicitObjectMemberFunction() &&
477 MD->getThisType()->isDependentType();
481 QualType T = FD->getType()->isDependentType() || IsThisDependentType
488 &
PP.getIdentifierTable().get(
"__promise"),
T,
492 if (VD->isInvalidDecl())
502 if (
auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
510 CtorArgExprs.push_back(ThisExpr.
get());
515 auto &Moves = ScopeInfo->CoroutineParameterMoves;
516 for (
auto *PD : FD->parameters()) {
517 if (PD->getType()->isDependentType())
521 auto Move = Moves.find(PD);
522 assert(Move != Moves.end() &&
523 "Coroutine function parameter not inserted into move map");
531 if (RefExpr.isInvalid())
533 CtorArgExprs.push_back(RefExpr.get());
538 if (!CtorArgExprs.empty()) {
542 CtorArgExprs, FD->getLocation());
545 VD->getLocation(),
true, PLE);
559 VD->setInvalidDecl();
560 }
else if (
Result.get()) {
581 bool IsImplicit =
false) {
588 assert(ScopeInfo &&
"missing function scope for function");
590 if (ScopeInfo->FirstCoroutineStmtLoc.isInvalid() && !IsImplicit)
591 ScopeInfo->setFirstCoroutineStmt(Loc,
Keyword);
593 if (ScopeInfo->CoroutinePromise)
600 if (!ScopeInfo->CoroutinePromise)
610 llvm::SmallPtrSetImpl<const Decl *> &ThrowingDecls) {
611 auto checkDeclNoexcept = [&](
const Decl *D,
bool IsDtor =
false) {
615 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
623 if (FD->getBuiltinID() == Builtin::BI__builtin_coro_resume)
626 if (ThrowingDecls.empty()) {
633 diag::err_coroutine_promise_final_suspend_requires_nothrow);
635 ThrowingDecls.insert(D);
639 if (
auto *CE = dyn_cast<CXXConstructExpr>(E)) {
641 checkDeclNoexcept(Ctor);
644 }
else if (
auto *CE = dyn_cast<CallExpr>(E)) {
645 if (CE->isTypeDependent())
648 checkDeclNoexcept(CE->getCalleeDecl());
660 for (
const auto *Child : E->
children()) {
675 ThrowingDecls.end()};
676 sort(SortedDecls, [](
const Decl *A,
const Decl *B) {
679 for (
const auto *D : SortedDecls) {
680 Diag(D->getEndLoc(), diag::note_coroutine_function_declare_noexcept);
682 return ThrowingDecls.empty();
688 assert(FSI &&
"FunctionScopeInfo is null");
690 "first coroutine location not set");
710 if (
Context.getTargetInfo().getCXXABI().isMicrosoft() &&
711 Context.getTargetInfo().getTriple().isX86_32())
712 Diag(KWLoc, diag::warn_coroutines_x86_windows);
715 assert(ScopeInfo->CoroutinePromise);
718 if (ScopeInfo->FirstCoroutineStmtLoc == KWLoc)
723 if (!ScopeInfo->NeedsCoroutineSuspends)
726 ScopeInfo->setNeedsCoroutineSuspends(
false);
728 auto *Fn =
CurContext->castEnclosingFunction();
731 auto buildSuspends = [&](StringRef Name)
mutable ->
StmtResult {
734 if (Operand.isInvalid())
744 Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
745 << ((Name ==
"initial_suspend") ? 0 : 1);
746 Diag(KWLoc, diag::note_declared_coroutine_here) <<
Keyword;
752 StmtResult InitSuspend = buildSuspends(
"initial_suspend");
756 StmtResult FinalSuspend = buildSuspends(
"final_suspend");
760 ScopeInfo->setCoroutineSuspends(InitSuspend.
get(), FinalSuspend.
get());
801 const bool BadContext =
806 S.
Diag(Loc, diag::err_coroutine_unevaluated_context) <<
Keyword;
812 S.
Diag(Loc, diag::err_coroutine_within_handler) <<
Keyword;
841 Context.DeclarationNames.getCXXOperatorName(OO_Coawait);
846 assert(!Operators.
isAmbiguous() &&
"Operator lookup cannot be ambiguous");
851 Functions.end(),
false,
859 return Record &&
Record->hasAttr<CoroAwaitElidableAttr>();
874 Call->setCoroElideSafe();
877 auto *Fn = llvm::dyn_cast_if_present<FunctionDecl>(
Call->getCalleeDecl());
883 if (PD->hasAttr<CoroAwaitElidableArgumentAttr>())
898 if (Operand->hasPlaceholderType()) {
905 auto *Promise = FSI->CoroutinePromise;
906 if (Promise->getType()->isDependentType()) {
912 auto *RD = Promise->getType()->getAsCXXRecordDecl();
917 if (CurFnAwaitElidable)
920 Expr *Transformed = Operand;
926 diag::note_coroutine_promise_implicit_await_transform_required_here)
927 << Operand->getSourceRange();
930 Transformed = R.get();
940 Expr *Awaiter,
bool IsImplicit) {
990 *
this,
getCurFunction()->CoroutinePromise, Loc,
"yield_value", E);
1026 *
this, Coroutine->CoroutinePromise, Loc, E);
1070 VarDecl *Promise = FSI->CoroutinePromise;
1091 assert(Std &&
"Should already be diagnosed");
1098 S.
Diag(Loc, diag::err_implicit_coroutine_std_nothrow_type_not_found);
1104 Result.suppressDiagnostics();
1107 S.
Diag(
Found->getLocation(), diag::err_malformed_std_nothrow);
1128 unsigned DiagnosticID,
1135 bool HaveIssuedWarning =
false;
1136 for (
auto Decl : R) {
1137 if (!
Decl->getUnderlyingDecl()
1141 if (!HaveIssuedWarning) {
1142 S.
Diag(Loc, DiagnosticID) << Name;
1143 HaveIssuedWarning =
true;
1148 R.suppressDiagnostics();
1149 return HaveIssuedWarning;
1158 diag::warn_coroutine_type_aware_allocator_ignored,
1159 DeleteName, PromiseType);
1161 assert(PointeeRD &&
"PromiseType must be a CxxRecordDecl type");
1163 const bool Overaligned = S.
getLangOpts().CoroAlignedAllocation;
1181 if (!OperatorDelete) {
1190 if (!OperatorDelete)
1194 assert(!OperatorDelete->isTypeAwareOperatorNewOrDelete());
1202 assert(Fn && Fn->isCoroutine() &&
"not a coroutine");
1205 "a null body is only allowed for invalid declarations");
1210 if (!Fn->CoroutinePromise)
1223 if (FD->
hasAttr<AlwaysInlineAttr>())
1228 if (Fn->FirstVLALoc.isValid())
1229 Diag(Fn->FirstVLALoc, diag::err_vla_in_coroutine_unsupported);
1241 if (Builder.isInvalid() || !Builder.buildStatements())
1249 if (
auto *CS = dyn_cast<CompoundStmt>(Body))
1263 : S(S), FD(FD), Fn(Fn), Loc(FD.getLocation()),
1264 IsPromiseDependentType(
1265 !Fn.CoroutinePromise ||
1266 Fn.CoroutinePromise->
getType()->isDependentType()) {
1269 for (
auto KV : Fn.CoroutineParameterMoves)
1270 this->ParamMovesVector.push_back(KV.second);
1273 if (!IsPromiseDependentType) {
1274 PromiseRecordDecl = Fn.CoroutinePromise->getType()->getAsCXXRecordDecl();
1275 assert(PromiseRecordDecl &&
"Type should have already been checked");
1277 this->IsValid = makePromiseStmt() && makeInitialAndFinalSuspend();
1281 assert(this->IsValid &&
"coroutine already invalid");
1282 this->IsValid = makeReturnObject();
1283 if (this->IsValid && !IsPromiseDependentType)
1285 return this->IsValid;
1289 assert(this->IsValid &&
"coroutine already invalid");
1290 assert(!this->IsPromiseDependentType &&
1291 "coroutine cannot have a dependent promise type");
1292 this->IsValid = makeOnException() && makeOnFallthrough() &&
1293 makeGroDeclAndReturnStmt() && makeReturnOnAllocFailure() &&
1294 makeNewAndDeleteExpr();
1295 return this->IsValid;
1298bool CoroutineStmtBuilder::makePromiseStmt() {
1310bool CoroutineStmtBuilder::makeInitialAndFinalSuspend() {
1322 if (
auto *DeclRef = dyn_cast_or_null<DeclRefExpr>(E)) {
1323 auto *
Decl = DeclRef->getDecl();
1325 if (Method->isStatic())
1334 diag::err_coroutine_promise_get_return_object_on_allocation_failure)
1335 << PromiseRecordDecl;
1336 S.
Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
1337 << Fn.getFirstCoroutineStmtKeyword();
1341bool CoroutineStmtBuilder::makeReturnOnAllocFailure() {
1342 assert(!IsPromiseDependentType &&
1343 "cannot make statement while the promise type is dependent");
1354 DeclarationName DN =
1355 S.PP.getIdentifierInfo(
"get_return_object_on_allocation_failure");
1357 if (!S.LookupQualifiedName(
Found, PromiseRecordDecl))
1362 S.BuildDeclarationNameExpr(SS,
Found,
false);
1370 S.BuildCallExpr(
nullptr, DeclNameExpr.
get(), Loc, {}, Loc);
1371 if (ReturnObjectOnAllocationFailure.
isInvalid())
1375 S.BuildReturnStmt(Loc, ReturnObjectOnAllocationFailure.
get());
1377 S.Diag(
Found.getFoundDecl()->getLocation(), diag::note_member_declared_here)
1379 S.Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
1380 << Fn.getFirstCoroutineStmtKeyword();
1393 if (
auto *MD = dyn_cast<CXXMethodDecl>(&FD)) {
1401 PlacementArgs.push_back(ThisExpr.
get());
1406 if (PD->getType()->isDependentType())
1410 auto PDLoc = PD->getLocation();
1412 bool DeclReferenced = PD->isReferenced();
1417 PD->setReferenced(DeclReferenced);
1422 PlacementArgs.push_back(PDRefExpr.
get());
1428bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
1430 assert(!IsPromiseDependentType &&
1431 "cannot make statement while the promise type is dependent");
1432 QualType PromiseType = Fn.CoroutinePromise->getType();
1434 if (S.RequireCompleteType(Loc, PromiseType, diag::err_incomplete_type))
1472 FunctionDecl *OperatorNew =
nullptr;
1473 SmallVector<Expr *, 1> PlacementArgs;
1475 bool PlacementArgsFromCoroutine =
false;
1476 DeclarationName NewName =
1477 S.getASTContext().DeclarationNames.getCXXOperatorName(OO_New);
1479 const bool PromiseContainsNew = [
this, &PromiseType, NewName]() ->
bool {
1485 return !
R.empty() && !
R.isAmbiguous();
1490 ImplicitAllocationParameters IAP(
1494 bool WithoutPlacementArgs =
false,
1495 bool ForceNonAligned =
false) {
1506 bool ShouldUseAlignedAlloc =
1507 !ForceNonAligned && S.getLangOpts().CoroAlignedAllocation;
1508 IAP = ImplicitAllocationParameters(
1511 auto FoundAllocations = S.FindAllocationFunctions(
1512 Loc, SourceRange(), NewScope,
1517 if (FoundAllocations) {
1518 IAP = FoundAllocations->IAP;
1519 OperatorNew = FoundAllocations->OperatorNew;
1521 OperatorNew =
nullptr;
1523 assert(!OperatorNew || !OperatorNew->isTypeAwareOperatorNewOrDelete());
1529 if (PromiseContainsNew) {
1532 PlacementArgsFromCoroutine =
true;
1535 LookupAllocationFunction();
1537 if (PromiseContainsNew && !PlacementArgs.empty()) {
1550 if (!OperatorNew || (S.getLangOpts().CoroAlignedAllocation &&
1574 bool FoundNonAlignedInPromise =
false;
1575 if (PromiseContainsNew && S.getLangOpts().CoroAlignedAllocation)
1577 FoundNonAlignedInPromise = OperatorNew;
1583 if (!OperatorNew && !PlacementArgs.empty())
1589 bool IsGlobalOverload =
1594 if (RequiresNoThrowAlloc && (!OperatorNew || IsGlobalOverload)) {
1598 PlacementArgs = {StdNoThrow};
1599 PlacementArgsFromCoroutine =
false;
1600 OperatorNew =
nullptr;
1607 if (FoundNonAlignedInPromise) {
1608 S.Diag(OperatorNew->getLocation(),
1609 diag::warn_non_aligned_allocation_function)
1614 if (PromiseContainsNew) {
1615 S.Diag(Loc, diag::err_coroutine_unusable_new) << PromiseType << &FD;
1617 S, Loc, diag::note_coroutine_unusable_type_aware_allocators, NewName,
1619 }
else if (RequiresNoThrowAlloc)
1620 S.Diag(Loc, diag::err_coroutine_unfound_nothrow_new)
1621 << &FD << S.getLangOpts().CoroAlignedAllocation;
1625 assert(!OperatorNew->isTypeAwareOperatorNewOrDelete());
1628 diag::warn_coroutine_type_aware_allocator_ignored,
1629 NewName, PromiseType);
1631 if (RequiresNoThrowAlloc) {
1632 const auto *FT = OperatorNew->getType()->castAs<FunctionProtoType>();
1633 if (!FT->isNothrow(
false)) {
1634 S.Diag(OperatorNew->getLocation(),
1635 diag::err_coroutine_promise_new_requires_nothrow)
1637 S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
1643 FunctionDecl *OperatorDelete =
nullptr;
1651 assert(!OperatorDelete->isTypeAwareOperatorNewOrDelete());
1654 S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_frame, {});
1657 S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_size, {});
1659 Expr *FrameAlignment =
nullptr;
1661 if (S.getLangOpts().CoroAlignedAllocation) {
1663 S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_align, {});
1669 FrameAlignment = S.BuildCXXNamedCast(Loc, tok::kw_static_cast, AlignValTy,
1670 FrameAlignment, SourceRange(Loc, Loc),
1671 SourceRange(Loc, Loc))
1677 S.BuildDeclRefExpr(OperatorNew, OperatorNew->getType(),
VK_LValue, Loc);
1681 SmallVector<Expr *, 2> NewArgs(1, FrameSize);
1682 if (S.getLangOpts().CoroAlignedAllocation &&
1684 NewArgs.push_back(FrameAlignment);
1688 if (OperatorNew->isVariadic() ||
1689 OperatorNew->getNumParams() > NewArgs.size()) {
1690 llvm::append_range(NewArgs, PlacementArgs);
1691 if (PlacementArgsFromCoroutine)
1696 S.BuildCallExpr(S.getCurScope(), NewRef.
get(), Loc, NewArgs, Loc);
1697 NewExpr = S.ActOnFinishFullExpr(NewExpr.
get(),
false);
1703 QualType OpDeleteQualType = OperatorDelete->getType();
1706 S.BuildDeclRefExpr(OperatorDelete, OpDeleteQualType,
VK_LValue, Loc);
1711 S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_free, {FramePtr});
1713 SmallVector<Expr *, 2> DeleteArgs{CoroFree};
1720 const auto *OpDeleteType =
1722 if (OpDeleteType->getNumParams() > DeleteArgs.size() &&
1723 S.getASTContext().hasSameUnqualifiedType(
1724 OpDeleteType->getParamType(DeleteArgs.size()), FrameSize->
getType()))
1725 DeleteArgs.push_back(FrameSize);
1738 if (S.getLangOpts().CoroAlignedAllocation &&
1739 OpDeleteType->getNumParams() > DeleteArgs.size() &&
1740 S.getASTContext().hasSameUnqualifiedType(
1741 OpDeleteType->getParamType(DeleteArgs.size()),
1743 DeleteArgs.push_back(FrameAlignment);
1746 S.BuildCallExpr(S.getCurScope(), DeleteRef.
get(), Loc, DeleteArgs, Loc);
1748 S.ActOnFinishFullExpr(DeleteExpr.
get(),
false);
1758bool CoroutineStmtBuilder::makeOnFallthrough() {
1759 assert(!IsPromiseDependentType &&
1760 "cannot make statement while the promise type is dependent");
1769 bool HasRVoid, HasRValue;
1770 LookupResult LRVoid =
1771 lookupMember(S,
"return_void", PromiseRecordDecl, Loc, HasRVoid);
1772 LookupResult LRValue =
1773 lookupMember(S,
"return_value", PromiseRecordDecl, Loc, HasRValue);
1776 if (HasRVoid && HasRValue) {
1778 S.Diag(FD.getLocation(),
1779 diag::err_coroutine_promise_incompatible_return_functions)
1780 << PromiseRecordDecl;
1782 diag::note_member_first_declared_here)
1785 diag::note_member_first_declared_here)
1788 }
else if (!HasRVoid && !HasRValue) {
1799 Fallthrough = S.ActOnNullStmt(PromiseRecordDecl->getLocation());
1800 if (Fallthrough.isInvalid())
1802 }
else if (HasRVoid) {
1803 Fallthrough = S.BuildCoreturnStmt(FD.getLocation(),
nullptr,
1805 Fallthrough = S.ActOnFinishFullStmt(Fallthrough.get());
1806 if (Fallthrough.isInvalid())
1814bool CoroutineStmtBuilder::makeOnException() {
1816 assert(!IsPromiseDependentType &&
1817 "cannot make statement while the promise type is dependent");
1819 const bool RequireUnhandledException = S.getLangOpts().CXXExceptions;
1821 if (!
lookupMember(S,
"unhandled_exception", PromiseRecordDecl, Loc)) {
1823 RequireUnhandledException
1824 ? diag::err_coroutine_promise_unhandled_exception_required
1826 warn_coroutine_promise_unhandled_exception_required_with_exceptions;
1827 S.Diag(Loc, DiagID) << PromiseRecordDecl;
1828 S.Diag(PromiseRecordDecl->getLocation(), diag::note_defined_here)
1829 << PromiseRecordDecl;
1830 return !RequireUnhandledException;
1834 if (!S.getLangOpts().CXXExceptions)
1839 UnhandledException = S.ActOnFinishFullExpr(UnhandledException.
get(), Loc,
1846 if (!S.getLangOpts().Borland && Fn.FirstSEHTryLoc.isValid()) {
1847 S.Diag(Fn.FirstSEHTryLoc, diag::err_seh_in_a_coroutine_with_cxx_exceptions);
1848 S.Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
1849 << Fn.getFirstCoroutineStmtKeyword();
1857bool CoroutineStmtBuilder::makeReturnObject() {
1871 if (
auto *MbrRef = dyn_cast<CXXMemberCallExpr>(E)) {
1872 auto *MethodDecl = MbrRef->getMethodDecl();
1873 S.
Diag(MethodDecl->getLocation(), diag::note_member_declared_here)
1876 S.
Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
1877 << Fn.getFirstCoroutineStmtKeyword();
1880bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() {
1881 assert(!IsPromiseDependentType &&
1882 "cannot make statement while the promise type is dependent");
1883 assert(this->
ReturnValue &&
"ReturnValue must be already formed");
1885 QualType
const GroType = this->
ReturnValue->getType();
1887 "get_return_object type must no longer be dependent");
1889 QualType
const FnRetType = FD.getReturnType();
1891 "get_return_object type must no longer be dependent");
1899 bool GroMatchesRetType = S.getASTContext().hasSameType(GroType, FnRetType);
1903 S.ActOnFinishFullExpr(this->
ReturnValue, Loc,
false);
1907 if (!GroMatchesRetType)
1914 InitializedEntity Entity =
1916 S.PerformCopyInitialization(Entity, SourceLocation(),
ReturnValue);
1922 clang::VarDecl *GroDecl =
nullptr;
1923 if (GroMatchesRetType) {
1927 S.Context, &FD, FD.getLocation(), FD.getLocation(),
1928 &S.PP.getIdentifierTable().get(
"__coro_gro"),
1929 S.BuildDecltypeType(
ReturnValue).getCanonicalType(),
1930 S.Context.getTrivialTypeSourceInfo(GroType, Loc),
SC_None);
1933 S.CheckVariableDeclarationType(GroDecl);
1939 S.PerformCopyInitialization(Entity, SourceLocation(),
ReturnValue);
1943 Res = S.ActOnFinishFullExpr(Res.
get(),
false);
1947 S.AddInitializerToDecl(GroDecl, Res.
get(),
1950 S.FinalizeDeclaration(GroDecl);
1955 S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(GroDecl), Loc, Loc);
1956 if (GroDeclStmt.isInvalid())
1973 if (!GroMatchesRetType &&
2010 auto *FD =
CurContext->castEnclosingFunction();
2013 if (!ScopeInfo->CoroutineParameterMoves.empty())
2022 for (
auto *PD : FD->parameters()) {
2023 if (PD->getType()->isDependentType())
2027 bool DeclReferenced = PD->isReferenced();
2033 PD->setReferenced(DeclReferenced);
2038 Expr *CExpr =
nullptr;
2039 if (PD->getType()->getAsCXXRecordDecl() ||
2040 PD->getType()->isRValueReferenceType())
2043 CExpr = PDRefExpr.
get();
2047 auto *D =
buildVarDecl(*
this, Loc, PD->getType(), PD->getIdentifier());
2052 if (
Stmt.isInvalid())
2055 ScopeInfo->CoroutineParameterMoves.insert(std::make_pair(PD,
Stmt.get()));
2073 PP.getIdentifierTable().get(
"coroutine_traits");
2081 Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
2082 <<
"std::coroutine_traits";
2089 Result.suppressDiagnostics();
2091 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.
Result
Implement __builtin_bit_cast and related operations.
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 void markCoroutineParametersReferenced(FunctionDecl &FD)
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
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,...
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...
FunctionDecl * getEnclosingFunction()
Cast this to a FunctionDecl if it is one, ignoring any intervening expansion statements.
FunctionDecl * castEnclosingFunction()
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.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
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...
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...
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.
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.
Scope - A scope is a transient data structure that is used while parsing the program.
bool isCatchScope() const
isCatchScope - Return true if this scope is a C++ catch statement.
const Scope * getParent() const
getParent - Return the scope that this is nested in.
bool isFunctionScope() const
isFunctionScope() - Return true if this scope is a function scope.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Sema - This implements semantic analysis and AST building for C.
FunctionDecl * FindUsualDeallocationFunction(SourceLocation StartLoc, ImplicitDeallocationParameters, DeclarationName Name, bool Diagnose=true)
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...
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
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.
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)
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.
void CheckCompleteVariableDeclaration(VarDecl *VD)
QualType CheckTemplateIdType(ElaboratedTypeKeyword Keyword, TemplateName Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs, Scope *Scope, bool ForNestedNameSpecifier)
@ 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
friend class InitializationSequence
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.
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 declaration of a type.
A container of type source information.
The base class of the type hierarchy.
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.
Defines the clang::TargetInfo interface.
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
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)
Expr * IgnoreExprNodes(Expr *E, FnTys &&... Fns)
Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, Recursively apply each of the f...
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
bool isAlignedAllocation(AlignedAllocationMode Mode)
MutableArrayRef< Expr * > MultiExprArg
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
const FunctionProtoType * T
@ Keyword
The name has been typo-corrected to a keyword.
Expr * IgnoreImplicitSingleStep(Expr *E)
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Expr * IgnoreParensSingleStep(Expr *E)
U cast(CodeGen::Address addr)
@ None
No keyword precedes the qualified type name.
ActionResult< Expr * > ExprResult
ActionResult< Stmt * > StmtResult
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