clang 20.0.0git
SemaCoroutine.cpp
Go to the documentation of this file.
1//===-- SemaCoroutine.cpp - Semantic Analysis for Coroutines --------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements semantic analysis for C++ Coroutines.
10//
11// This file contains references to sections of the Coroutines TS, which
12// can be found at http://wg21.link/coroutines.
13//
14//===----------------------------------------------------------------------===//
15
17#include "clang/AST/ASTLambda.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/Expr.h"
20#include "clang/AST/ExprCXX.h"
21#include "clang/AST/StmtCXX.h"
26#include "clang/Sema/Overload.h"
29#include "llvm/ADT/SmallSet.h"
30
31using namespace clang;
32using namespace sema;
33
34static LookupResult lookupMember(Sema &S, const char *Name, CXXRecordDecl *RD,
35 SourceLocation Loc, bool &Res) {
38 // Suppress diagnostics when a private member is selected. The same warnings
39 // will be produced again when building the call.
41 Res = S.LookupQualifiedName(LR, RD);
42 return LR;
43}
44
45static bool lookupMember(Sema &S, const char *Name, CXXRecordDecl *RD,
47 bool Res;
48 lookupMember(S, Name, RD, Loc, Res);
49 return Res;
50}
51
52/// Look up the std::coroutine_traits<...>::promise_type for the given
53/// function type.
55 SourceLocation KwLoc) {
56 const FunctionProtoType *FnType = FD->getType()->castAs<FunctionProtoType>();
57 const SourceLocation FuncLoc = FD->getLocation();
58
59 ClassTemplateDecl *CoroTraits =
60 S.lookupCoroutineTraits(KwLoc, FuncLoc);
61 if (!CoroTraits)
62 return QualType();
63
64 // Form template argument list for coroutine_traits<R, P1, P2, ...> according
65 // to [dcl.fct.def.coroutine]3
66 TemplateArgumentListInfo Args(KwLoc, KwLoc);
67 auto AddArg = [&](QualType T) {
70 };
71 AddArg(FnType->getReturnType());
72 // If the function is a non-static member function, add the type
73 // of the implicit object parameter before the formal parameters.
74 if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
75 if (MD->isImplicitObjectMemberFunction()) {
76 // [over.match.funcs]4
77 // For non-static member functions, the type of the implicit object
78 // parameter is
79 // -- "lvalue reference to cv X" for functions declared without a
80 // ref-qualifier or with the & ref-qualifier
81 // -- "rvalue reference to cv X" for functions declared with the &&
82 // ref-qualifier
83 QualType T = MD->getFunctionObjectParameterType();
84 T = FnType->getRefQualifier() == RQ_RValue
86 : S.Context.getLValueReferenceType(T, /*SpelledAsLValue*/ true);
87 AddArg(T);
88 }
89 }
90 for (QualType T : FnType->getParamTypes())
91 AddArg(T);
92
93 // Build the template-id.
94 QualType CoroTrait =
95 S.CheckTemplateIdType(TemplateName(CoroTraits), KwLoc, Args);
96 if (CoroTrait.isNull())
97 return QualType();
98 if (S.RequireCompleteType(KwLoc, CoroTrait,
99 diag::err_coroutine_type_missing_specialization))
100 return QualType();
101
102 auto *RD = CoroTrait->getAsCXXRecordDecl();
103 assert(RD && "specialization of class template is not a class?");
104
105 // Look up the ::promise_type member.
106 LookupResult R(S, &S.PP.getIdentifierTable().get("promise_type"), KwLoc,
108 S.LookupQualifiedName(R, RD);
109 auto *Promise = R.getAsSingle<TypeDecl>();
110 if (!Promise) {
111 S.Diag(FuncLoc,
112 diag::err_implied_std_coroutine_traits_promise_type_not_found)
113 << RD;
114 return QualType();
115 }
116 // The promise type is required to be a class type.
117 QualType PromiseType = S.Context.getTypeDeclType(Promise);
118
119 auto buildElaboratedType = [&]() {
120 auto *NNS = NestedNameSpecifier::Create(S.Context, nullptr, S.getStdNamespace());
121 NNS = NestedNameSpecifier::Create(S.Context, NNS, false,
122 CoroTrait.getTypePtr());
123 return S.Context.getElaboratedType(ElaboratedTypeKeyword::None, NNS,
124 PromiseType);
125 };
126
127 if (!PromiseType->getAsCXXRecordDecl()) {
128 S.Diag(FuncLoc,
129 diag::err_implied_std_coroutine_traits_promise_type_not_class)
130 << buildElaboratedType();
131 return QualType();
132 }
133 if (S.RequireCompleteType(FuncLoc, buildElaboratedType(),
134 diag::err_coroutine_promise_type_incomplete))
135 return QualType();
136
137 return PromiseType;
138}
139
140/// Look up the std::coroutine_handle<PromiseType>.
143 if (PromiseType.isNull())
144 return QualType();
145
146 NamespaceDecl *CoroNamespace = S.getStdNamespace();
147 assert(CoroNamespace && "Should already be diagnosed");
148
149 LookupResult Result(S, &S.PP.getIdentifierTable().get("coroutine_handle"),
151 if (!S.LookupQualifiedName(Result, CoroNamespace)) {
152 S.Diag(Loc, diag::err_implied_coroutine_type_not_found)
153 << "std::coroutine_handle";
154 return QualType();
155 }
156
157 ClassTemplateDecl *CoroHandle = Result.getAsSingle<ClassTemplateDecl>();
158 if (!CoroHandle) {
159 Result.suppressDiagnostics();
160 // We found something weird. Complain about the first thing we found.
161 NamedDecl *Found = *Result.begin();
162 S.Diag(Found->getLocation(), diag::err_malformed_std_coroutine_handle);
163 return QualType();
164 }
165
166 // Form template argument list for coroutine_handle<Promise>.
169 TemplateArgument(PromiseType),
170 S.Context.getTrivialTypeSourceInfo(PromiseType, Loc)));
171
172 // Build the template-id.
173 QualType CoroHandleType =
174 S.CheckTemplateIdType(TemplateName(CoroHandle), Loc, Args);
175 if (CoroHandleType.isNull())
176 return QualType();
177 if (S.RequireCompleteType(Loc, CoroHandleType,
178 diag::err_coroutine_type_missing_specialization))
179 return QualType();
180
181 return CoroHandleType;
182}
183
185 StringRef Keyword) {
186 // [expr.await]p2 dictates that 'co_await' and 'co_yield' must be used within
187 // a function body.
188 // FIXME: This also covers [expr.await]p2: "An await-expression shall not
189 // appear in a default argument." But the diagnostic QoI here could be
190 // improved to inform the user that default arguments specifically are not
191 // allowed.
192 auto *FD = dyn_cast<FunctionDecl>(S.CurContext);
193 if (!FD) {
194 S.Diag(Loc, isa<ObjCMethodDecl>(S.CurContext)
195 ? diag::err_coroutine_objc_method
196 : diag::err_coroutine_outside_function) << Keyword;
197 return false;
198 }
199
200 // An enumeration for mapping the diagnostic type to the correct diagnostic
201 // selection index.
202 enum InvalidFuncDiag {
203 DiagCtor = 0,
204 DiagDtor,
205 DiagMain,
206 DiagConstexpr,
207 DiagAutoRet,
208 DiagVarargs,
209 DiagConsteval,
210 };
211 bool Diagnosed = false;
212 auto DiagInvalid = [&](InvalidFuncDiag ID) {
213 S.Diag(Loc, diag::err_coroutine_invalid_func_context) << ID << Keyword;
214 Diagnosed = true;
215 return false;
216 };
217
218 // Diagnose when a constructor, destructor
219 // or the function 'main' are declared as a coroutine.
220 auto *MD = dyn_cast<CXXMethodDecl>(FD);
221 // [class.ctor]p11: "A constructor shall not be a coroutine."
222 if (MD && isa<CXXConstructorDecl>(MD))
223 return DiagInvalid(DiagCtor);
224 // [class.dtor]p17: "A destructor shall not be a coroutine."
225 else if (MD && isa<CXXDestructorDecl>(MD))
226 return DiagInvalid(DiagDtor);
227 // [basic.start.main]p3: "The function main shall not be a coroutine."
228 else if (FD->isMain())
229 return DiagInvalid(DiagMain);
230
231 // Emit a diagnostics for each of the following conditions which is not met.
232 // [expr.const]p2: "An expression e is a core constant expression unless the
233 // evaluation of e [...] would evaluate one of the following expressions:
234 // [...] an await-expression [...] a yield-expression."
235 if (FD->isConstexpr())
236 DiagInvalid(FD->isConsteval() ? DiagConsteval : DiagConstexpr);
237 // [dcl.spec.auto]p15: "A function declared with a return type that uses a
238 // placeholder type shall not be a coroutine."
239 if (FD->getReturnType()->isUndeducedType())
240 DiagInvalid(DiagAutoRet);
241 // [dcl.fct.def.coroutine]p1
242 // The parameter-declaration-clause of the coroutine shall not terminate with
243 // an ellipsis that is not part of a parameter-declaration.
244 if (FD->isVariadic())
245 DiagInvalid(DiagVarargs);
246
247 return !Diagnosed;
248}
249
250/// Build a call to 'operator co_await' if there is a suitable operator for
251/// the given expression.
253 UnresolvedLookupExpr *Lookup) {
254 UnresolvedSet<16> Functions;
255 Functions.append(Lookup->decls_begin(), Lookup->decls_end());
256 return CreateOverloadedUnaryOp(Loc, UO_Coawait, Functions, E);
257}
258
262 if (R.isInvalid())
263 return ExprError();
264 return SemaRef.BuildOperatorCoawaitCall(Loc, E,
265 cast<UnresolvedLookupExpr>(R.get()));
266}
267
270 QualType CoroHandleType = lookupCoroutineHandleType(S, PromiseType, Loc);
271 if (CoroHandleType.isNull())
272 return ExprError();
273
274 DeclContext *LookupCtx = S.computeDeclContext(CoroHandleType);
275 LookupResult Found(S, &S.PP.getIdentifierTable().get("from_address"), Loc,
277 if (!S.LookupQualifiedName(Found, LookupCtx)) {
278 S.Diag(Loc, diag::err_coroutine_handle_missing_member)
279 << "from_address";
280 return ExprError();
281 }
282
283 Expr *FramePtr =
284 S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_frame, {});
285
286 CXXScopeSpec SS;
287 ExprResult FromAddr =
288 S.BuildDeclarationNameExpr(SS, Found, /*NeedsADL=*/false);
289 if (FromAddr.isInvalid())
290 return ExprError();
291
292 return S.BuildCallExpr(nullptr, FromAddr.get(), Loc, FramePtr, Loc);
293}
294
296 enum AwaitCallType { ACT_Ready, ACT_Suspend, ACT_Resume };
297 Expr *Results[3];
300};
301
303 StringRef Name, MultiExprArg Args) {
304 DeclarationNameInfo NameInfo(&S.PP.getIdentifierTable().get(Name), Loc);
305
306 // FIXME: Fix BuildMemberReferenceExpr to take a const CXXScopeSpec&.
307 CXXScopeSpec SS;
309 Base, Base->getType(), Loc, /*IsPtr=*/false, SS,
310 SourceLocation(), nullptr, NameInfo, /*TemplateArgs=*/nullptr,
311 /*Scope=*/nullptr);
312 if (Result.isInvalid())
313 return ExprError();
314
315 // We meant exactly what we asked for. No need for typo correction.
316 if (auto *TE = dyn_cast<TypoExpr>(Result.get())) {
317 S.clearDelayedTypo(TE);
318 S.Diag(Loc, diag::err_no_member)
319 << NameInfo.getName() << Base->getType()->getAsCXXRecordDecl()
320 << Base->getSourceRange();
321 return ExprError();
322 }
323
324 auto EndLoc = Args.empty() ? Loc : Args.back()->getEndLoc();
325 return S.BuildCallExpr(nullptr, Result.get(), Loc, Args, EndLoc, nullptr);
326}
327
328// See if return type is coroutine-handle and if so, invoke builtin coro-resume
329// on its address. This is to enable the support for coroutine-handle
330// returning await_suspend that results in a guaranteed tail call to the target
331// coroutine.
332static Expr *maybeTailCall(Sema &S, QualType RetType, Expr *E,
334 if (RetType->isReferenceType())
335 return nullptr;
336 Type const *T = RetType.getTypePtr();
337 if (!T->isClassType() && !T->isStructureType())
338 return nullptr;
339
340 // FIXME: Add convertability check to coroutine_handle<>. Possibly via
341 // EvaluateBinaryTypeTrait(BTT_IsConvertible, ...) which is at the moment
342 // a private function in SemaExprCXX.cpp
343
344 ExprResult AddressExpr = buildMemberCall(S, E, Loc, "address", std::nullopt);
345 if (AddressExpr.isInvalid())
346 return nullptr;
347
348 Expr *JustAddress = AddressExpr.get();
349
350 // Check that the type of AddressExpr is void*
351 if (!JustAddress->getType().getTypePtr()->isVoidPointerType())
352 S.Diag(cast<CallExpr>(JustAddress)->getCalleeDecl()->getLocation(),
353 diag::warn_coroutine_handle_address_invalid_return_type)
354 << JustAddress->getType();
355
356 // Clean up temporary objects, because the resulting expression
357 // will become the body of await_suspend wrapper.
358 return S.MaybeCreateExprWithCleanups(JustAddress);
359}
360
361/// Build calls to await_ready, await_suspend, and await_resume for a co_await
362/// expression.
363/// The generated AST tries to clean up temporary objects as early as
364/// possible so that they don't live across suspension points if possible.
365/// Having temporary objects living across suspension points unnecessarily can
366/// lead to large frame size, and also lead to memory corruptions if the
367/// coroutine frame is destroyed after coming back from suspension. This is done
368/// by wrapping both the await_ready call and the await_suspend call with
369/// ExprWithCleanups. In the end of this function, we also need to explicitly
370/// set cleanup state so that the CoawaitExpr is also wrapped with an
371/// ExprWithCleanups to clean up the awaiter associated with the co_await
372/// expression.
375 OpaqueValueExpr *Operand = new (S.Context)
377
378 // Assume valid until we see otherwise.
379 // Further operations are responsible for setting IsInalid to true.
380 ReadySuspendResumeResult Calls = {{}, Operand, /*IsInvalid=*/false};
381
383
384 auto BuildSubExpr = [&](ACT CallType, StringRef Func,
385 MultiExprArg Arg) -> Expr * {
386 ExprResult Result = buildMemberCall(S, Operand, Loc, Func, Arg);
387 if (Result.isInvalid()) {
388 Calls.IsInvalid = true;
389 return nullptr;
390 }
391 Calls.Results[CallType] = Result.get();
392 return Result.get();
393 };
394
395 CallExpr *AwaitReady = cast_or_null<CallExpr>(
396 BuildSubExpr(ACT::ACT_Ready, "await_ready", std::nullopt));
397 if (!AwaitReady)
398 return Calls;
399 if (!AwaitReady->getType()->isDependentType()) {
400 // [expr.await]p3 [...]
401 // — await-ready is the expression e.await_ready(), contextually converted
402 // to bool.
403 ExprResult Conv = S.PerformContextuallyConvertToBool(AwaitReady);
404 if (Conv.isInvalid()) {
405 S.Diag(AwaitReady->getDirectCallee()->getBeginLoc(),
406 diag::note_await_ready_no_bool_conversion);
407 S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
408 << AwaitReady->getDirectCallee() << E->getSourceRange();
409 Calls.IsInvalid = true;
410 } else
411 Calls.Results[ACT::ACT_Ready] = S.MaybeCreateExprWithCleanups(Conv.get());
412 }
413
414 ExprResult CoroHandleRes =
415 buildCoroutineHandle(S, CoroPromise->getType(), Loc);
416 if (CoroHandleRes.isInvalid()) {
417 Calls.IsInvalid = true;
418 return Calls;
419 }
420 Expr *CoroHandle = CoroHandleRes.get();
421 CallExpr *AwaitSuspend = cast_or_null<CallExpr>(
422 BuildSubExpr(ACT::ACT_Suspend, "await_suspend", CoroHandle));
423 if (!AwaitSuspend)
424 return Calls;
425 if (!AwaitSuspend->getType()->isDependentType()) {
426 // [expr.await]p3 [...]
427 // - await-suspend is the expression e.await_suspend(h), which shall be
428 // a prvalue of type void, bool, or std::coroutine_handle<Z> for some
429 // type Z.
430 QualType RetType = AwaitSuspend->getCallReturnType(S.Context);
431
432 // Support for coroutine_handle returning await_suspend.
433 if (Expr *TailCallSuspend =
434 maybeTailCall(S, RetType, AwaitSuspend, Loc))
435 // Note that we don't wrap the expression with ExprWithCleanups here
436 // because that might interfere with tailcall contract (e.g. inserting
437 // clean up instructions in-between tailcall and return). Instead
438 // ExprWithCleanups is wrapped within maybeTailCall() prior to the resume
439 // call.
440 Calls.Results[ACT::ACT_Suspend] = TailCallSuspend;
441 else {
442 // non-class prvalues always have cv-unqualified types
443 if (RetType->isReferenceType() ||
444 (!RetType->isBooleanType() && !RetType->isVoidType())) {
445 S.Diag(AwaitSuspend->getCalleeDecl()->getLocation(),
446 diag::err_await_suspend_invalid_return_type)
447 << RetType;
448 S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
449 << AwaitSuspend->getDirectCallee();
450 Calls.IsInvalid = true;
451 } else
452 Calls.Results[ACT::ACT_Suspend] =
453 S.MaybeCreateExprWithCleanups(AwaitSuspend);
454 }
455 }
456
457 BuildSubExpr(ACT::ACT_Resume, "await_resume", std::nullopt);
458
459 // Make sure the awaiter object gets a chance to be cleaned up.
461
462 return Calls;
463}
464
466 SourceLocation Loc, StringRef Name,
467 MultiExprArg Args) {
468
469 // Form a reference to the promise.
470 ExprResult PromiseRef = S.BuildDeclRefExpr(
471 Promise, Promise->getType().getNonReferenceType(), VK_LValue, Loc);
472 if (PromiseRef.isInvalid())
473 return ExprError();
474
475 return buildMemberCall(S, PromiseRef.get(), Loc, Name, Args);
476}
477
479 assert(isa<FunctionDecl>(CurContext) && "not in a function scope");
480 auto *FD = cast<FunctionDecl>(CurContext);
481 bool IsThisDependentType = [&] {
482 if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FD))
483 return MD->isImplicitObjectMemberFunction() &&
484 MD->getThisType()->isDependentType();
485 return false;
486 }();
487
488 QualType T = FD->getType()->isDependentType() || IsThisDependentType
490 : lookupPromiseType(*this, FD, Loc);
491 if (T.isNull())
492 return nullptr;
493
494 auto *VD = VarDecl::Create(Context, FD, FD->getLocation(), FD->getLocation(),
495 &PP.getIdentifierTable().get("__promise"), T,
497 VD->setImplicit();
499 if (VD->isInvalidDecl())
500 return nullptr;
501
502 auto *ScopeInfo = getCurFunction();
503
504 // Build a list of arguments, based on the coroutine function's arguments,
505 // that if present will be passed to the promise type's constructor.
506 llvm::SmallVector<Expr *, 4> CtorArgExprs;
507
508 // Add implicit object parameter.
509 if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
510 if (MD->isImplicitObjectMemberFunction() && !isLambdaCallOperator(MD)) {
511 ExprResult ThisExpr = ActOnCXXThis(Loc);
512 if (ThisExpr.isInvalid())
513 return nullptr;
514 ThisExpr = CreateBuiltinUnaryOp(Loc, UO_Deref, ThisExpr.get());
515 if (ThisExpr.isInvalid())
516 return nullptr;
517 CtorArgExprs.push_back(ThisExpr.get());
518 }
519 }
520
521 // Add the coroutine function's parameters.
522 auto &Moves = ScopeInfo->CoroutineParameterMoves;
523 for (auto *PD : FD->parameters()) {
524 if (PD->getType()->isDependentType())
525 continue;
526
527 auto RefExpr = ExprEmpty();
528 auto Move = Moves.find(PD);
529 assert(Move != Moves.end() &&
530 "Coroutine function parameter not inserted into move map");
531 // If a reference to the function parameter exists in the coroutine
532 // frame, use that reference.
533 auto *MoveDecl =
534 cast<VarDecl>(cast<DeclStmt>(Move->second)->getSingleDecl());
535 RefExpr =
536 BuildDeclRefExpr(MoveDecl, MoveDecl->getType().getNonReferenceType(),
537 ExprValueKind::VK_LValue, FD->getLocation());
538 if (RefExpr.isInvalid())
539 return nullptr;
540 CtorArgExprs.push_back(RefExpr.get());
541 }
542
543 // If we have a non-zero number of constructor arguments, try to use them.
544 // Otherwise, fall back to the promise type's default constructor.
545 if (!CtorArgExprs.empty()) {
546 // Create an initialization sequence for the promise type using the
547 // constructor arguments, wrapped in a parenthesized list expression.
548 Expr *PLE = ParenListExpr::Create(Context, FD->getLocation(),
549 CtorArgExprs, FD->getLocation());
552 VD->getLocation(), /*DirectInit=*/true, PLE);
553 InitializationSequence InitSeq(*this, Entity, Kind, CtorArgExprs,
554 /*TopLevelOfInitList=*/false,
555 /*TreatUnavailableAsInvalid=*/false);
556
557 // [dcl.fct.def.coroutine]5.7
558 // promise-constructor-arguments is determined as follows: overload
559 // resolution is performed on a promise constructor call created by
560 // assembling an argument list q_1 ... q_n . If a viable constructor is
561 // found ([over.match.viable]), then promise-constructor-arguments is ( q_1
562 // , ..., q_n ), otherwise promise-constructor-arguments is empty.
563 if (InitSeq) {
564 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, CtorArgExprs);
565 if (Result.isInvalid()) {
566 VD->setInvalidDecl();
567 } else if (Result.get()) {
568 VD->setInit(MaybeCreateExprWithCleanups(Result.get()));
569 VD->setInitStyle(VarDecl::CallInit);
571 }
572 } else
574 } else
576
577 FD->addDecl(VD);
578 return VD;
579}
580
581/// Check that this is a context in which a coroutine suspension can appear.
583 StringRef Keyword,
584 bool IsImplicit = false) {
585 if (!isValidCoroutineContext(S, Loc, Keyword))
586 return nullptr;
587
588 assert(isa<FunctionDecl>(S.CurContext) && "not in a function scope");
589
590 auto *ScopeInfo = S.getCurFunction();
591 assert(ScopeInfo && "missing function scope for function");
592
593 if (ScopeInfo->FirstCoroutineStmtLoc.isInvalid() && !IsImplicit)
594 ScopeInfo->setFirstCoroutineStmt(Loc, Keyword);
595
596 if (ScopeInfo->CoroutinePromise)
597 return ScopeInfo;
598
600 return nullptr;
601
602 ScopeInfo->CoroutinePromise = S.buildCoroutinePromise(Loc);
603 if (!ScopeInfo->CoroutinePromise)
604 return nullptr;
605
606 return ScopeInfo;
607}
608
609/// Recursively check \p E and all its children to see if any call target
610/// (including constructor call) is declared noexcept. Also any value returned
611/// from the call has a noexcept destructor.
612static void checkNoThrow(Sema &S, const Stmt *E,
613 llvm::SmallPtrSetImpl<const Decl *> &ThrowingDecls) {
614 auto checkDeclNoexcept = [&](const Decl *D, bool IsDtor = false) {
615 // In the case of dtor, the call to dtor is implicit and hence we should
616 // pass nullptr to canCalleeThrow.
617 if (Sema::canCalleeThrow(S, IsDtor ? nullptr : cast<Expr>(E), D)) {
618 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
619 // co_await promise.final_suspend() could end up calling
620 // __builtin_coro_resume for symmetric transfer if await_suspend()
621 // returns a handle. In that case, even __builtin_coro_resume is not
622 // declared as noexcept and may throw, it does not throw _into_ the
623 // coroutine that just suspended, but rather throws back out from
624 // whoever called coroutine_handle::resume(), hence we claim that
625 // logically it does not throw.
626 if (FD->getBuiltinID() == Builtin::BI__builtin_coro_resume)
627 return;
628 }
629 if (ThrowingDecls.empty()) {
630 // [dcl.fct.def.coroutine]p15
631 // The expression co_await promise.final_suspend() shall not be
632 // potentially-throwing ([except.spec]).
633 //
634 // First time seeing an error, emit the error message.
635 S.Diag(cast<FunctionDecl>(S.CurContext)->getLocation(),
636 diag::err_coroutine_promise_final_suspend_requires_nothrow);
637 }
638 ThrowingDecls.insert(D);
639 }
640 };
641
642 if (auto *CE = dyn_cast<CXXConstructExpr>(E)) {
643 CXXConstructorDecl *Ctor = CE->getConstructor();
644 checkDeclNoexcept(Ctor);
645 // Check the corresponding destructor of the constructor.
646 checkDeclNoexcept(Ctor->getParent()->getDestructor(), /*IsDtor=*/true);
647 } else if (auto *CE = dyn_cast<CallExpr>(E)) {
648 if (CE->isTypeDependent())
649 return;
650
651 checkDeclNoexcept(CE->getCalleeDecl());
652 QualType ReturnType = CE->getCallReturnType(S.getASTContext());
653 // Check the destructor of the call return type, if any.
654 if (ReturnType.isDestructedType() ==
656 const auto *T =
657 cast<RecordType>(ReturnType.getCanonicalType().getTypePtr());
658 checkDeclNoexcept(cast<CXXRecordDecl>(T->getDecl())->getDestructor(),
659 /*IsDtor=*/true);
660 }
661 } else
662 for (const auto *Child : E->children()) {
663 if (!Child)
664 continue;
665 checkNoThrow(S, Child, ThrowingDecls);
666 }
667}
668
669bool Sema::checkFinalSuspendNoThrow(const Stmt *FinalSuspend) {
671 // We first collect all declarations that should not throw but not declared
672 // with noexcept. We then sort them based on the location before printing.
673 // This is to avoid emitting the same note multiple times on the same
674 // declaration, and also provide a deterministic order for the messages.
675 checkNoThrow(*this, FinalSuspend, ThrowingDecls);
676 auto SortedDecls = llvm::SmallVector<const Decl *, 4>{ThrowingDecls.begin(),
677 ThrowingDecls.end()};
678 sort(SortedDecls, [](const Decl *A, const Decl *B) {
679 return A->getEndLoc() < B->getEndLoc();
680 });
681 for (const auto *D : SortedDecls) {
682 Diag(D->getEndLoc(), diag::note_coroutine_function_declare_noexcept);
683 }
684 return ThrowingDecls.empty();
685}
686
687// [stmt.return.coroutine]p1:
688// A coroutine shall not enclose a return statement ([stmt.return]).
690 assert(FSI && "FunctionScopeInfo is null");
691 assert(FSI->FirstCoroutineStmtLoc.isValid() &&
692 "first coroutine location not set");
693 if (FSI->FirstReturnLoc.isInvalid())
694 return;
695 S.Diag(FSI->FirstReturnLoc, diag::err_return_in_coroutine);
696 S.Diag(FSI->FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
698}
699
701 StringRef Keyword) {
702 // Ignore previous expr evaluation contexts.
705 if (!checkCoroutineContext(*this, KWLoc, Keyword))
706 return false;
707 auto *ScopeInfo = getCurFunction();
708 assert(ScopeInfo->CoroutinePromise);
709
710 // Avoid duplicate errors, report only on first keyword.
711 if (ScopeInfo->FirstCoroutineStmtLoc == KWLoc)
712 checkReturnStmtInCoroutine(*this, ScopeInfo);
713
714 // If we have existing coroutine statements then we have already built
715 // the initial and final suspend points.
716 if (!ScopeInfo->NeedsCoroutineSuspends)
717 return true;
718
719 ScopeInfo->setNeedsCoroutineSuspends(false);
720
721 auto *Fn = cast<FunctionDecl>(CurContext);
722 SourceLocation Loc = Fn->getLocation();
723 // Build the initial suspend point
724 auto buildSuspends = [&](StringRef Name) mutable -> StmtResult {
725 ExprResult Operand = buildPromiseCall(*this, ScopeInfo->CoroutinePromise,
726 Loc, Name, std::nullopt);
727 if (Operand.isInvalid())
728 return StmtError();
729 ExprResult Suspend =
730 buildOperatorCoawaitCall(*this, SC, Loc, Operand.get());
731 if (Suspend.isInvalid())
732 return StmtError();
733 Suspend = BuildResolvedCoawaitExpr(Loc, Operand.get(), Suspend.get(),
734 /*IsImplicit*/ true);
735 Suspend = ActOnFinishFullExpr(Suspend.get(), /*DiscardedValue*/ false);
736 if (Suspend.isInvalid()) {
737 Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
738 << ((Name == "initial_suspend") ? 0 : 1);
739 Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword;
740 return StmtError();
741 }
742 return cast<Stmt>(Suspend.get());
743 };
744
745 StmtResult InitSuspend = buildSuspends("initial_suspend");
746 if (InitSuspend.isInvalid())
747 return true;
748
749 StmtResult FinalSuspend = buildSuspends("final_suspend");
750 if (FinalSuspend.isInvalid() || !checkFinalSuspendNoThrow(FinalSuspend.get()))
751 return true;
752
753 ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get());
754
755 return true;
756}
757
758// Recursively walks up the scope hierarchy until either a 'catch' or a function
759// scope is found, whichever comes first.
760static bool isWithinCatchScope(Scope *S) {
761 // 'co_await' and 'co_yield' keywords are disallowed within catch blocks, but
762 // lambdas that use 'co_await' are allowed. The loop below ends when a
763 // function scope is found in order to ensure the following behavior:
764 //
765 // void foo() { // <- function scope
766 // try { //
767 // co_await x; // <- 'co_await' is OK within a function scope
768 // } catch { // <- catch scope
769 // co_await x; // <- 'co_await' is not OK within a catch scope
770 // []() { // <- function scope
771 // co_await x; // <- 'co_await' is OK within a function scope
772 // }();
773 // }
774 // }
775 while (S && !S->isFunctionScope()) {
776 if (S->isCatchScope())
777 return true;
778 S = S->getParent();
779 }
780 return false;
781}
782
783// [expr.await]p2, emphasis added: "An await-expression shall appear only in
784// a *potentially evaluated* expression within the compound-statement of a
785// function-body *outside of a handler* [...] A context within a function
786// where an await-expression can appear is called a suspension context of the
787// function."
789 StringRef Keyword) {
790 // First emphasis of [expr.await]p2: must be a potentially evaluated context.
791 // That is, 'co_await' and 'co_yield' cannot appear in subexpressions of
792 // \c sizeof.
793 if (S.isUnevaluatedContext()) {
794 S.Diag(Loc, diag::err_coroutine_unevaluated_context) << Keyword;
795 return false;
796 }
797
798 // Second emphasis of [expr.await]p2: must be outside of an exception handler.
800 S.Diag(Loc, diag::err_coroutine_within_handler) << Keyword;
801 return false;
802 }
803
804 return true;
805}
806
808 if (!checkSuspensionContext(*this, Loc, "co_await"))
809 return ExprError();
810
811 if (!ActOnCoroutineBodyStart(S, Loc, "co_await")) {
813 return ExprError();
814 }
815
816 if (E->hasPlaceholderType()) {
818 if (R.isInvalid()) return ExprError();
819 E = R.get();
820 }
821
823 if (Lookup.isInvalid())
824 return ExprError();
826 cast<UnresolvedLookupExpr>(Lookup.get()));
827}
828
830 DeclarationName OpName =
832 LookupResult Operators(*this, OpName, SourceLocation(),
834 LookupName(Operators, S);
835
836 assert(!Operators.isAmbiguous() && "Operator lookup cannot be ambiguous");
837 const auto &Functions = Operators.asUnresolvedSet();
839 Context, /*NamingClass*/ nullptr, NestedNameSpecifierLoc(),
840 DeclarationNameInfo(OpName, Loc), /*RequiresADL*/ true, Functions.begin(),
841 Functions.end(), /*KnownDependent=*/false,
842 /*KnownInstantiationDependent=*/false);
843 assert(CoawaitOp);
844 return CoawaitOp;
845}
846
847// Attempts to resolve and build a CoawaitExpr from "raw" inputs, bailing out to
848// DependentCoawaitExpr if needed.
850 UnresolvedLookupExpr *Lookup) {
851 auto *FSI = checkCoroutineContext(*this, Loc, "co_await");
852 if (!FSI)
853 return ExprError();
854
855 if (Operand->hasPlaceholderType()) {
856 ExprResult R = CheckPlaceholderExpr(Operand);
857 if (R.isInvalid())
858 return ExprError();
859 Operand = R.get();
860 }
861
862 auto *Promise = FSI->CoroutinePromise;
863 if (Promise->getType()->isDependentType()) {
864 Expr *Res = new (Context)
865 DependentCoawaitExpr(Loc, Context.DependentTy, Operand, Lookup);
866 return Res;
867 }
868
869 auto *RD = Promise->getType()->getAsCXXRecordDecl();
870 auto *Transformed = Operand;
871 if (lookupMember(*this, "await_transform", RD, Loc)) {
872 ExprResult R =
873 buildPromiseCall(*this, Promise, Loc, "await_transform", Operand);
874 if (R.isInvalid()) {
875 Diag(Loc,
876 diag::note_coroutine_promise_implicit_await_transform_required_here)
877 << Operand->getSourceRange();
878 return ExprError();
879 }
880 Transformed = R.get();
881 }
882 ExprResult Awaiter = BuildOperatorCoawaitCall(Loc, Transformed, Lookup);
883 if (Awaiter.isInvalid())
884 return ExprError();
885
886 return BuildResolvedCoawaitExpr(Loc, Operand, Awaiter.get());
887}
888
890 Expr *Awaiter, bool IsImplicit) {
891 auto *Coroutine = checkCoroutineContext(*this, Loc, "co_await", IsImplicit);
892 if (!Coroutine)
893 return ExprError();
894
895 if (Awaiter->hasPlaceholderType()) {
896 ExprResult R = CheckPlaceholderExpr(Awaiter);
897 if (R.isInvalid()) return ExprError();
898 Awaiter = R.get();
899 }
900
901 if (Awaiter->getType()->isDependentType()) {
902 Expr *Res = new (Context)
903 CoawaitExpr(Loc, Context.DependentTy, Operand, Awaiter, IsImplicit);
904 return Res;
905 }
906
907 // If the expression is a temporary, materialize it as an lvalue so that we
908 // can use it multiple times.
909 if (Awaiter->isPRValue())
910 Awaiter = CreateMaterializeTemporaryExpr(Awaiter->getType(), Awaiter, true);
911
912 // The location of the `co_await` token cannot be used when constructing
913 // the member call expressions since it's before the location of `Expr`, which
914 // is used as the start of the member call expression.
915 SourceLocation CallLoc = Awaiter->getExprLoc();
916
917 // Build the await_ready, await_suspend, await_resume calls.
919 buildCoawaitCalls(*this, Coroutine->CoroutinePromise, CallLoc, Awaiter);
920 if (RSS.IsInvalid)
921 return ExprError();
922
923 Expr *Res = new (Context)
924 CoawaitExpr(Loc, Operand, Awaiter, RSS.Results[0], RSS.Results[1],
925 RSS.Results[2], RSS.OpaqueValue, IsImplicit);
926
927 return Res;
928}
929
931 if (!checkSuspensionContext(*this, Loc, "co_yield"))
932 return ExprError();
933
934 if (!ActOnCoroutineBodyStart(S, Loc, "co_yield")) {
936 return ExprError();
937 }
938
939 // Build yield_value call.
940 ExprResult Awaitable = buildPromiseCall(
941 *this, getCurFunction()->CoroutinePromise, Loc, "yield_value", E);
942 if (Awaitable.isInvalid())
943 return ExprError();
944
945 // Build 'operator co_await' call.
946 Awaitable = buildOperatorCoawaitCall(*this, S, Loc, Awaitable.get());
947 if (Awaitable.isInvalid())
948 return ExprError();
949
950 return BuildCoyieldExpr(Loc, Awaitable.get());
951}
953 auto *Coroutine = checkCoroutineContext(*this, Loc, "co_yield");
954 if (!Coroutine)
955 return ExprError();
956
957 if (E->hasPlaceholderType()) {
959 if (R.isInvalid()) return ExprError();
960 E = R.get();
961 }
962
963 Expr *Operand = E;
964
965 if (E->getType()->isDependentType()) {
966 Expr *Res = new (Context) CoyieldExpr(Loc, Context.DependentTy, Operand, E);
967 return Res;
968 }
969
970 // If the expression is a temporary, materialize it as an lvalue so that we
971 // can use it multiple times.
972 if (E->isPRValue())
974
975 // Build the await_ready, await_suspend, await_resume calls.
977 *this, Coroutine->CoroutinePromise, Loc, E);
978 if (RSS.IsInvalid)
979 return ExprError();
980
981 Expr *Res =
982 new (Context) CoyieldExpr(Loc, Operand, E, RSS.Results[0], RSS.Results[1],
983 RSS.Results[2], RSS.OpaqueValue);
984
985 return Res;
986}
987
989 if (!ActOnCoroutineBodyStart(S, Loc, "co_return")) {
991 return StmtError();
992 }
993 return BuildCoreturnStmt(Loc, E);
994}
995
997 bool IsImplicit) {
998 auto *FSI = checkCoroutineContext(*this, Loc, "co_return", IsImplicit);
999 if (!FSI)
1000 return StmtError();
1001
1002 if (E && E->hasPlaceholderType() &&
1003 !E->hasPlaceholderType(BuiltinType::Overload)) {
1005 if (R.isInvalid()) return StmtError();
1006 E = R.get();
1007 }
1008
1009 VarDecl *Promise = FSI->CoroutinePromise;
1010 ExprResult PC;
1011 if (E && (isa<InitListExpr>(E) || !E->getType()->isVoidType())) {
1013 PC = buildPromiseCall(*this, Promise, Loc, "return_value", E);
1014 } else {
1016 PC = buildPromiseCall(*this, Promise, Loc, "return_void", std::nullopt);
1017 }
1018 if (PC.isInvalid())
1019 return StmtError();
1020
1021 Expr *PCE = ActOnFinishFullExpr(PC.get(), /*DiscardedValue*/ false).get();
1022
1023 Stmt *Res = new (Context) CoreturnStmt(Loc, E, PCE, IsImplicit);
1024 return Res;
1025}
1026
1027/// Look up the std::nothrow object.
1030 assert(Std && "Should already be diagnosed");
1031
1032 LookupResult Result(S, &S.PP.getIdentifierTable().get("nothrow"), Loc,
1034 if (!S.LookupQualifiedName(Result, Std)) {
1035 // <coroutine> is not requred to include <new>, so we couldn't omit
1036 // the check here.
1037 S.Diag(Loc, diag::err_implicit_coroutine_std_nothrow_type_not_found);
1038 return nullptr;
1039 }
1040
1041 auto *VD = Result.getAsSingle<VarDecl>();
1042 if (!VD) {
1043 Result.suppressDiagnostics();
1044 // We found something weird. Complain about the first thing we found.
1045 NamedDecl *Found = *Result.begin();
1046 S.Diag(Found->getLocation(), diag::err_malformed_std_nothrow);
1047 return nullptr;
1048 }
1049
1050 ExprResult DR = S.BuildDeclRefExpr(VD, VD->getType(), VK_LValue, Loc);
1051 if (DR.isInvalid())
1052 return nullptr;
1053
1054 return DR.get();
1055}
1056
1059 EnumDecl *StdAlignValT = S.getStdAlignValT();
1060 QualType StdAlignValDecl = S.Context.getTypeDeclType(StdAlignValT);
1061 return S.Context.getTrivialTypeSourceInfo(StdAlignValDecl);
1062}
1063
1064// Find an appropriate delete for the promise.
1066 FunctionDecl *&OperatorDelete) {
1067 DeclarationName DeleteName =
1069
1070 auto *PointeeRD = PromiseType->getAsCXXRecordDecl();
1071 assert(PointeeRD && "PromiseType must be a CxxRecordDecl type");
1072
1073 const bool Overaligned = S.getLangOpts().CoroAlignedAllocation;
1074
1075 // [dcl.fct.def.coroutine]p12
1076 // The deallocation function's name is looked up by searching for it in the
1077 // scope of the promise type. If nothing is found, a search is performed in
1078 // the global scope.
1079 if (S.FindDeallocationFunction(Loc, PointeeRD, DeleteName, OperatorDelete,
1080 /*Diagnose*/ true, /*WantSize*/ true,
1081 /*WantAligned*/ Overaligned))
1082 return false;
1083
1084 // [dcl.fct.def.coroutine]p12
1085 // If both a usual deallocation function with only a pointer parameter and a
1086 // usual deallocation function with both a pointer parameter and a size
1087 // parameter are found, then the selected deallocation function shall be the
1088 // one with two parameters. Otherwise, the selected deallocation function
1089 // shall be the function with one parameter.
1090 if (!OperatorDelete) {
1091 // Look for a global declaration.
1092 // Coroutines can always provide their required size.
1093 const bool CanProvideSize = true;
1094 // Sema::FindUsualDeallocationFunction will try to find the one with two
1095 // parameters first. It will return the deallocation function with one
1096 // parameter if failed.
1097 OperatorDelete = S.FindUsualDeallocationFunction(Loc, CanProvideSize,
1098 Overaligned, DeleteName);
1099
1100 if (!OperatorDelete)
1101 return false;
1102 }
1103
1104 S.MarkFunctionReferenced(Loc, OperatorDelete);
1105 return true;
1106}
1107
1108
1111 assert(Fn && Fn->isCoroutine() && "not a coroutine");
1112 if (!Body) {
1113 assert(FD->isInvalidDecl() &&
1114 "a null body is only allowed for invalid declarations");
1115 return;
1116 }
1117 // We have a function that uses coroutine keywords, but we failed to build
1118 // the promise type.
1119 if (!Fn->CoroutinePromise)
1120 return FD->setInvalidDecl();
1121
1122 if (isa<CoroutineBodyStmt>(Body)) {
1123 // Nothing todo. the body is already a transformed coroutine body statement.
1124 return;
1125 }
1126
1127 // The always_inline attribute doesn't reliably apply to a coroutine,
1128 // because the coroutine will be split into pieces and some pieces
1129 // might be called indirectly, as in a virtual call. Even the ramp
1130 // function cannot be inlined at -O0, due to pipeline ordering
1131 // problems (see https://llvm.org/PR53413). Tell the user about it.
1132 if (FD->hasAttr<AlwaysInlineAttr>())
1133 Diag(FD->getLocation(), diag::warn_always_inline_coroutine);
1134
1135 // The design of coroutines means we cannot allow use of VLAs within one, so
1136 // diagnose if we've seen a VLA in the body of this function.
1137 if (Fn->FirstVLALoc.isValid())
1138 Diag(Fn->FirstVLALoc, diag::err_vla_in_coroutine_unsupported);
1139
1140 // Coroutines will get splitted into pieces. The GNU address of label
1141 // extension wouldn't be meaningful in coroutines.
1142 for (AddrLabelExpr *ALE : Fn->AddrLabels)
1143 Diag(ALE->getBeginLoc(), diag::err_coro_invalid_addr_of_label);
1144
1145 CoroutineStmtBuilder Builder(*this, *FD, *Fn, Body);
1146 if (Builder.isInvalid() || !Builder.buildStatements())
1147 return FD->setInvalidDecl();
1148
1149 // Build body for the coroutine wrapper statement.
1150 Body = CoroutineBodyStmt::Create(Context, Builder);
1151}
1152
1154 if (auto *CS = dyn_cast<CompoundStmt>(Body))
1155 return CS;
1156
1157 // The body of the coroutine may be a try statement if it is in
1158 // 'function-try-block' syntax. Here we wrap it into a compound
1159 // statement for consistency.
1160 assert(isa<CXXTryStmt>(Body) && "Unimaged coroutine body type");
1161 return CompoundStmt::Create(Context, {Body}, FPOptionsOverride(),
1163}
1164
1167 Stmt *Body)
1168 : S(S), FD(FD), Fn(Fn), Loc(FD.getLocation()),
1169 IsPromiseDependentType(
1170 !Fn.CoroutinePromise ||
1171 Fn.CoroutinePromise->getType()->isDependentType()) {
1172 this->Body = buildCoroutineBody(Body, S.getASTContext());
1173
1174 for (auto KV : Fn.CoroutineParameterMoves)
1175 this->ParamMovesVector.push_back(KV.second);
1176 this->ParamMoves = this->ParamMovesVector;
1177
1178 if (!IsPromiseDependentType) {
1179 PromiseRecordDecl = Fn.CoroutinePromise->getType()->getAsCXXRecordDecl();
1180 assert(PromiseRecordDecl && "Type should have already been checked");
1181 }
1182 this->IsValid = makePromiseStmt() && makeInitialAndFinalSuspend();
1183}
1184
1186 assert(this->IsValid && "coroutine already invalid");
1187 this->IsValid = makeReturnObject();
1188 if (this->IsValid && !IsPromiseDependentType)
1190 return this->IsValid;
1191}
1192
1194 assert(this->IsValid && "coroutine already invalid");
1195 assert(!this->IsPromiseDependentType &&
1196 "coroutine cannot have a dependent promise type");
1197 this->IsValid = makeOnException() && makeOnFallthrough() &&
1198 makeGroDeclAndReturnStmt() && makeReturnOnAllocFailure() &&
1199 makeNewAndDeleteExpr();
1200 return this->IsValid;
1201}
1202
1203bool CoroutineStmtBuilder::makePromiseStmt() {
1204 // Form a declaration statement for the promise declaration, so that AST
1205 // visitors can more easily find it.
1206 StmtResult PromiseStmt =
1208 if (PromiseStmt.isInvalid())
1209 return false;
1210
1211 this->Promise = PromiseStmt.get();
1212 return true;
1213}
1214
1215bool CoroutineStmtBuilder::makeInitialAndFinalSuspend() {
1217 return false;
1218 this->InitialSuspend = cast<Expr>(Fn.CoroutineSuspends.first);
1219 this->FinalSuspend = cast<Expr>(Fn.CoroutineSuspends.second);
1220 return true;
1221}
1222
1224 CXXRecordDecl *PromiseRecordDecl,
1225 FunctionScopeInfo &Fn) {
1226 auto Loc = E->getExprLoc();
1227 if (auto *DeclRef = dyn_cast_or_null<DeclRefExpr>(E)) {
1228 auto *Decl = DeclRef->getDecl();
1229 if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(Decl)) {
1230 if (Method->isStatic())
1231 return true;
1232 else
1233 Loc = Decl->getLocation();
1234 }
1235 }
1236
1237 S.Diag(
1238 Loc,
1239 diag::err_coroutine_promise_get_return_object_on_allocation_failure)
1240 << PromiseRecordDecl;
1241 S.Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
1242 << Fn.getFirstCoroutineStmtKeyword();
1243 return false;
1244}
1245
1246bool CoroutineStmtBuilder::makeReturnOnAllocFailure() {
1247 assert(!IsPromiseDependentType &&
1248 "cannot make statement while the promise type is dependent");
1249
1250 // [dcl.fct.def.coroutine]p10
1251 // If a search for the name get_return_object_on_allocation_failure in
1252 // the scope of the promise type ([class.member.lookup]) finds any
1253 // declarations, then the result of a call to an allocation function used to
1254 // obtain storage for the coroutine state is assumed to return nullptr if it
1255 // fails to obtain storage, ... If the allocation function returns nullptr,
1256 // ... and the return value is obtained by a call to
1257 // T::get_return_object_on_allocation_failure(), where T is the
1258 // promise type.
1259 DeclarationName DN =
1260 S.PP.getIdentifierInfo("get_return_object_on_allocation_failure");
1262 if (!S.LookupQualifiedName(Found, PromiseRecordDecl))
1263 return true;
1264
1265 CXXScopeSpec SS;
1266 ExprResult DeclNameExpr =
1267 S.BuildDeclarationNameExpr(SS, Found, /*NeedsADL=*/false);
1268 if (DeclNameExpr.isInvalid())
1269 return false;
1270
1271 if (!diagReturnOnAllocFailure(S, DeclNameExpr.get(), PromiseRecordDecl, Fn))
1272 return false;
1273
1274 ExprResult ReturnObjectOnAllocationFailure =
1275 S.BuildCallExpr(nullptr, DeclNameExpr.get(), Loc, {}, Loc);
1276 if (ReturnObjectOnAllocationFailure.isInvalid())
1277 return false;
1278
1280 S.BuildReturnStmt(Loc, ReturnObjectOnAllocationFailure.get());
1281 if (ReturnStmt.isInvalid()) {
1282 S.Diag(Found.getFoundDecl()->getLocation(), diag::note_member_declared_here)
1283 << DN;
1284 S.Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
1286 return false;
1287 }
1288
1289 this->ReturnStmtOnAllocFailure = ReturnStmt.get();
1290 return true;
1291}
1292
1293// Collect placement arguments for allocation function of coroutine FD.
1294// Return true if we collect placement arguments succesfully. Return false,
1295// otherwise.
1297 SmallVectorImpl<Expr *> &PlacementArgs) {
1298 if (auto *MD = dyn_cast<CXXMethodDecl>(&FD)) {
1299 if (MD->isImplicitObjectMemberFunction() && !isLambdaCallOperator(MD)) {
1300 ExprResult ThisExpr = S.ActOnCXXThis(Loc);
1301 if (ThisExpr.isInvalid())
1302 return false;
1303 ThisExpr = S.CreateBuiltinUnaryOp(Loc, UO_Deref, ThisExpr.get());
1304 if (ThisExpr.isInvalid())
1305 return false;
1306 PlacementArgs.push_back(ThisExpr.get());
1307 }
1308 }
1309
1310 for (auto *PD : FD.parameters()) {
1311 if (PD->getType()->isDependentType())
1312 continue;
1313
1314 // Build a reference to the parameter.
1315 auto PDLoc = PD->getLocation();
1316 ExprResult PDRefExpr =
1317 S.BuildDeclRefExpr(PD, PD->getOriginalType().getNonReferenceType(),
1319 if (PDRefExpr.isInvalid())
1320 return false;
1321
1322 PlacementArgs.push_back(PDRefExpr.get());
1323 }
1324
1325 return true;
1326}
1327
1328bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
1329 // Form and check allocation and deallocation calls.
1330 assert(!IsPromiseDependentType &&
1331 "cannot make statement while the promise type is dependent");
1332 QualType PromiseType = Fn.CoroutinePromise->getType();
1333
1334 if (S.RequireCompleteType(Loc, PromiseType, diag::err_incomplete_type))
1335 return false;
1336
1337 const bool RequiresNoThrowAlloc = ReturnStmtOnAllocFailure != nullptr;
1338
1339 // According to [dcl.fct.def.coroutine]p9, Lookup allocation functions using a
1340 // parameter list composed of the requested size of the coroutine state being
1341 // allocated, followed by the coroutine function's arguments. If a matching
1342 // allocation function exists, use it. Otherwise, use an allocation function
1343 // that just takes the requested size.
1344 //
1345 // [dcl.fct.def.coroutine]p9
1346 // An implementation may need to allocate additional storage for a
1347 // coroutine.
1348 // This storage is known as the coroutine state and is obtained by calling a
1349 // non-array allocation function ([basic.stc.dynamic.allocation]). The
1350 // allocation function's name is looked up by searching for it in the scope of
1351 // the promise type.
1352 // - If any declarations are found, overload resolution is performed on a
1353 // function call created by assembling an argument list. The first argument is
1354 // the amount of space requested, and has type std::size_t. The
1355 // lvalues p1 ... pn are the succeeding arguments.
1356 //
1357 // ...where "p1 ... pn" are defined earlier as:
1358 //
1359 // [dcl.fct.def.coroutine]p3
1360 // The promise type of a coroutine is `std::coroutine_traits<R, P1, ...,
1361 // Pn>`
1362 // , where R is the return type of the function, and `P1, ..., Pn` are the
1363 // sequence of types of the non-object function parameters, preceded by the
1364 // type of the object parameter ([dcl.fct]) if the coroutine is a non-static
1365 // member function. [dcl.fct.def.coroutine]p4 In the following, p_i is an
1366 // lvalue of type P_i, where p1 denotes the object parameter and p_i+1 denotes
1367 // the i-th non-object function parameter for a non-static member function,
1368 // and p_i denotes the i-th function parameter otherwise. For a non-static
1369 // member function, q_1 is an lvalue that denotes *this; any other q_i is an
1370 // lvalue that denotes the parameter copy corresponding to p_i.
1371
1372 FunctionDecl *OperatorNew = nullptr;
1373 SmallVector<Expr *, 1> PlacementArgs;
1374
1375 const bool PromiseContainsNew = [this, &PromiseType]() -> bool {
1376 DeclarationName NewName =
1378 LookupResult R(S, NewName, Loc, Sema::LookupOrdinaryName);
1379
1380 if (PromiseType->isRecordType())
1381 S.LookupQualifiedName(R, PromiseType->getAsCXXRecordDecl());
1382
1383 return !R.empty() && !R.isAmbiguous();
1384 }();
1385
1386 // Helper function to indicate whether the last lookup found the aligned
1387 // allocation function.
1388 bool PassAlignment = S.getLangOpts().CoroAlignedAllocation;
1389 auto LookupAllocationFunction = [&](Sema::AllocationFunctionScope NewScope =
1391 bool WithoutPlacementArgs = false,
1392 bool ForceNonAligned = false) {
1393 // [dcl.fct.def.coroutine]p9
1394 // The allocation function's name is looked up by searching for it in the
1395 // scope of the promise type.
1396 // - If any declarations are found, ...
1397 // - If no declarations are found in the scope of the promise type, a search
1398 // is performed in the global scope.
1399 if (NewScope == Sema::AFS_Both)
1400 NewScope = PromiseContainsNew ? Sema::AFS_Class : Sema::AFS_Global;
1401
1402 PassAlignment = !ForceNonAligned && S.getLangOpts().CoroAlignedAllocation;
1403 FunctionDecl *UnusedResult = nullptr;
1404 S.FindAllocationFunctions(Loc, SourceRange(), NewScope,
1405 /*DeleteScope*/ Sema::AFS_Both, PromiseType,
1406 /*isArray*/ false, PassAlignment,
1407 WithoutPlacementArgs ? MultiExprArg{}
1408 : PlacementArgs,
1409 OperatorNew, UnusedResult, /*Diagnose*/ false);
1410 };
1411
1412 // We don't expect to call to global operator new with (size, p0, …, pn).
1413 // So if we choose to lookup the allocation function in global scope, we
1414 // shouldn't lookup placement arguments.
1415 if (PromiseContainsNew && !collectPlacementArgs(S, FD, Loc, PlacementArgs))
1416 return false;
1417
1418 LookupAllocationFunction();
1419
1420 if (PromiseContainsNew && !PlacementArgs.empty()) {
1421 // [dcl.fct.def.coroutine]p9
1422 // If no viable function is found ([over.match.viable]), overload
1423 // resolution
1424 // is performed again on a function call created by passing just the amount
1425 // of space required as an argument of type std::size_t.
1426 //
1427 // Proposed Change of [dcl.fct.def.coroutine]p9 in P2014R0:
1428 // Otherwise, overload resolution is performed again on a function call
1429 // created
1430 // by passing the amount of space requested as an argument of type
1431 // std::size_t as the first argument, and the requested alignment as
1432 // an argument of type std:align_val_t as the second argument.
1433 if (!OperatorNew ||
1434 (S.getLangOpts().CoroAlignedAllocation && !PassAlignment))
1435 LookupAllocationFunction(/*NewScope*/ Sema::AFS_Class,
1436 /*WithoutPlacementArgs*/ true);
1437 }
1438
1439 // Proposed Change of [dcl.fct.def.coroutine]p12 in P2014R0:
1440 // Otherwise, overload resolution is performed again on a function call
1441 // created
1442 // by passing the amount of space requested as an argument of type
1443 // std::size_t as the first argument, and the lvalues p1 ... pn as the
1444 // succeeding arguments. Otherwise, overload resolution is performed again
1445 // on a function call created by passing just the amount of space required as
1446 // an argument of type std::size_t.
1447 //
1448 // So within the proposed change in P2014RO, the priority order of aligned
1449 // allocation functions wiht promise_type is:
1450 //
1451 // void* operator new( std::size_t, std::align_val_t, placement_args... );
1452 // void* operator new( std::size_t, std::align_val_t);
1453 // void* operator new( std::size_t, placement_args... );
1454 // void* operator new( std::size_t);
1455
1456 // Helper variable to emit warnings.
1457 bool FoundNonAlignedInPromise = false;
1458 if (PromiseContainsNew && S.getLangOpts().CoroAlignedAllocation)
1459 if (!OperatorNew || !PassAlignment) {
1460 FoundNonAlignedInPromise = OperatorNew;
1461
1462 LookupAllocationFunction(/*NewScope*/ Sema::AFS_Class,
1463 /*WithoutPlacementArgs*/ false,
1464 /*ForceNonAligned*/ true);
1465
1466 if (!OperatorNew && !PlacementArgs.empty())
1467 LookupAllocationFunction(/*NewScope*/ Sema::AFS_Class,
1468 /*WithoutPlacementArgs*/ true,
1469 /*ForceNonAligned*/ true);
1470 }
1471
1472 bool IsGlobalOverload =
1473 OperatorNew && !isa<CXXRecordDecl>(OperatorNew->getDeclContext());
1474 // If we didn't find a class-local new declaration and non-throwing new
1475 // was is required then we need to lookup the non-throwing global operator
1476 // instead.
1477 if (RequiresNoThrowAlloc && (!OperatorNew || IsGlobalOverload)) {
1478 auto *StdNoThrow = buildStdNoThrowDeclRef(S, Loc);
1479 if (!StdNoThrow)
1480 return false;
1481 PlacementArgs = {StdNoThrow};
1482 OperatorNew = nullptr;
1483 LookupAllocationFunction(Sema::AFS_Global);
1484 }
1485
1486 // If we found a non-aligned allocation function in the promise_type,
1487 // it indicates the user forgot to update the allocation function. Let's emit
1488 // a warning here.
1489 if (FoundNonAlignedInPromise) {
1490 S.Diag(OperatorNew->getLocation(),
1491 diag::warn_non_aligned_allocation_function)
1492 << &FD;
1493 }
1494
1495 if (!OperatorNew) {
1496 if (PromiseContainsNew)
1497 S.Diag(Loc, diag::err_coroutine_unusable_new) << PromiseType << &FD;
1498 else if (RequiresNoThrowAlloc)
1499 S.Diag(Loc, diag::err_coroutine_unfound_nothrow_new)
1500 << &FD << S.getLangOpts().CoroAlignedAllocation;
1501
1502 return false;
1503 }
1504
1505 if (RequiresNoThrowAlloc) {
1506 const auto *FT = OperatorNew->getType()->castAs<FunctionProtoType>();
1507 if (!FT->isNothrow(/*ResultIfDependent*/ false)) {
1508 S.Diag(OperatorNew->getLocation(),
1509 diag::err_coroutine_promise_new_requires_nothrow)
1510 << OperatorNew;
1511 S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
1512 << OperatorNew;
1513 return false;
1514 }
1515 }
1516
1517 FunctionDecl *OperatorDelete = nullptr;
1518 if (!findDeleteForPromise(S, Loc, PromiseType, OperatorDelete)) {
1519 // FIXME: We should add an error here. According to:
1520 // [dcl.fct.def.coroutine]p12
1521 // If no usual deallocation function is found, the program is ill-formed.
1522 return false;
1523 }
1524
1525 Expr *FramePtr =
1526 S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_frame, {});
1527
1528 Expr *FrameSize =
1529 S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_size, {});
1530
1531 Expr *FrameAlignment = nullptr;
1532
1533 if (S.getLangOpts().CoroAlignedAllocation) {
1534 FrameAlignment =
1535 S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_align, {});
1536
1538 if (!AlignValTy)
1539 return false;
1540
1541 FrameAlignment = S.BuildCXXNamedCast(Loc, tok::kw_static_cast, AlignValTy,
1542 FrameAlignment, SourceRange(Loc, Loc),
1543 SourceRange(Loc, Loc))
1544 .get();
1545 }
1546
1547 // Make new call.
1548 ExprResult NewRef =
1549 S.BuildDeclRefExpr(OperatorNew, OperatorNew->getType(), VK_LValue, Loc);
1550 if (NewRef.isInvalid())
1551 return false;
1552
1553 SmallVector<Expr *, 2> NewArgs(1, FrameSize);
1554 if (S.getLangOpts().CoroAlignedAllocation && PassAlignment)
1555 NewArgs.push_back(FrameAlignment);
1556
1557 if (OperatorNew->getNumParams() > NewArgs.size())
1558 llvm::append_range(NewArgs, PlacementArgs);
1559
1560 ExprResult NewExpr =
1561 S.BuildCallExpr(S.getCurScope(), NewRef.get(), Loc, NewArgs, Loc);
1562 NewExpr = S.ActOnFinishFullExpr(NewExpr.get(), /*DiscardedValue*/ false);
1563 if (NewExpr.isInvalid())
1564 return false;
1565
1566 // Make delete call.
1567
1568 QualType OpDeleteQualType = OperatorDelete->getType();
1569
1570 ExprResult DeleteRef =
1571 S.BuildDeclRefExpr(OperatorDelete, OpDeleteQualType, VK_LValue, Loc);
1572 if (DeleteRef.isInvalid())
1573 return false;
1574
1575 Expr *CoroFree =
1576 S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_free, {FramePtr});
1577
1578 SmallVector<Expr *, 2> DeleteArgs{CoroFree};
1579
1580 // [dcl.fct.def.coroutine]p12
1581 // The selected deallocation function shall be called with the address of
1582 // the block of storage to be reclaimed as its first argument. If a
1583 // deallocation function with a parameter of type std::size_t is
1584 // used, the size of the block is passed as the corresponding argument.
1585 const auto *OpDeleteType =
1586 OpDeleteQualType.getTypePtr()->castAs<FunctionProtoType>();
1587 if (OpDeleteType->getNumParams() > DeleteArgs.size() &&
1589 OpDeleteType->getParamType(DeleteArgs.size()), FrameSize->getType()))
1590 DeleteArgs.push_back(FrameSize);
1591
1592 // Proposed Change of [dcl.fct.def.coroutine]p12 in P2014R0:
1593 // If deallocation function lookup finds a usual deallocation function with
1594 // a pointer parameter, size parameter and alignment parameter then this
1595 // will be the selected deallocation function, otherwise if lookup finds a
1596 // usual deallocation function with both a pointer parameter and a size
1597 // parameter, then this will be the selected deallocation function.
1598 // Otherwise, if lookup finds a usual deallocation function with only a
1599 // pointer parameter, then this will be the selected deallocation
1600 // function.
1601 //
1602 // So we are not forced to pass alignment to the deallocation function.
1603 if (S.getLangOpts().CoroAlignedAllocation &&
1604 OpDeleteType->getNumParams() > DeleteArgs.size() &&
1606 OpDeleteType->getParamType(DeleteArgs.size()),
1607 FrameAlignment->getType()))
1608 DeleteArgs.push_back(FrameAlignment);
1609
1610 ExprResult DeleteExpr =
1611 S.BuildCallExpr(S.getCurScope(), DeleteRef.get(), Loc, DeleteArgs, Loc);
1612 DeleteExpr =
1613 S.ActOnFinishFullExpr(DeleteExpr.get(), /*DiscardedValue*/ false);
1614 if (DeleteExpr.isInvalid())
1615 return false;
1616
1617 this->Allocate = NewExpr.get();
1618 this->Deallocate = DeleteExpr.get();
1619
1620 return true;
1621}
1622
1623bool CoroutineStmtBuilder::makeOnFallthrough() {
1624 assert(!IsPromiseDependentType &&
1625 "cannot make statement while the promise type is dependent");
1626
1627 // [dcl.fct.def.coroutine]/p6
1628 // If searches for the names return_void and return_value in the scope of
1629 // the promise type each find any declarations, the program is ill-formed.
1630 // [Note 1: If return_void is found, flowing off the end of a coroutine is
1631 // equivalent to a co_return with no operand. Otherwise, flowing off the end
1632 // of a coroutine results in undefined behavior ([stmt.return.coroutine]). —
1633 // end note]
1634 bool HasRVoid, HasRValue;
1635 LookupResult LRVoid =
1636 lookupMember(S, "return_void", PromiseRecordDecl, Loc, HasRVoid);
1637 LookupResult LRValue =
1638 lookupMember(S, "return_value", PromiseRecordDecl, Loc, HasRValue);
1639
1640 StmtResult Fallthrough;
1641 if (HasRVoid && HasRValue) {
1642 // FIXME Improve this diagnostic
1643 S.Diag(FD.getLocation(),
1644 diag::err_coroutine_promise_incompatible_return_functions)
1645 << PromiseRecordDecl;
1647 diag::note_member_first_declared_here)
1648 << LRVoid.getLookupName();
1649 S.Diag(LRValue.getRepresentativeDecl()->getLocation(),
1650 diag::note_member_first_declared_here)
1651 << LRValue.getLookupName();
1652 return false;
1653 } else if (!HasRVoid && !HasRValue) {
1654 // We need to set 'Fallthrough'. Otherwise the other analysis part might
1655 // think the coroutine has defined a return_value method. So it might emit
1656 // **false** positive warning. e.g.,
1657 //
1658 // promise_without_return_func foo() {
1659 // co_await something();
1660 // }
1661 //
1662 // Then AnalysisBasedWarning would emit a warning about `foo()` lacking a
1663 // co_return statements, which isn't correct.
1664 Fallthrough = S.ActOnNullStmt(PromiseRecordDecl->getLocation());
1665 if (Fallthrough.isInvalid())
1666 return false;
1667 } else if (HasRVoid) {
1668 Fallthrough = S.BuildCoreturnStmt(FD.getLocation(), nullptr,
1669 /*IsImplicit=*/true);
1670 Fallthrough = S.ActOnFinishFullStmt(Fallthrough.get());
1671 if (Fallthrough.isInvalid())
1672 return false;
1673 }
1674
1675 this->OnFallthrough = Fallthrough.get();
1676 return true;
1677}
1678
1679bool CoroutineStmtBuilder::makeOnException() {
1680 // Try to form 'p.unhandled_exception();'
1681 assert(!IsPromiseDependentType &&
1682 "cannot make statement while the promise type is dependent");
1683
1684 const bool RequireUnhandledException = S.getLangOpts().CXXExceptions;
1685
1686 if (!lookupMember(S, "unhandled_exception", PromiseRecordDecl, Loc)) {
1687 auto DiagID =
1688 RequireUnhandledException
1689 ? diag::err_coroutine_promise_unhandled_exception_required
1690 : diag::
1691 warn_coroutine_promise_unhandled_exception_required_with_exceptions;
1692 S.Diag(Loc, DiagID) << PromiseRecordDecl;
1693 S.Diag(PromiseRecordDecl->getLocation(), diag::note_defined_here)
1694 << PromiseRecordDecl;
1695 return !RequireUnhandledException;
1696 }
1697
1698 // If exceptions are disabled, don't try to build OnException.
1699 if (!S.getLangOpts().CXXExceptions)
1700 return true;
1701
1702 ExprResult UnhandledException = buildPromiseCall(
1703 S, Fn.CoroutinePromise, Loc, "unhandled_exception", std::nullopt);
1704 UnhandledException = S.ActOnFinishFullExpr(UnhandledException.get(), Loc,
1705 /*DiscardedValue*/ false);
1706 if (UnhandledException.isInvalid())
1707 return false;
1708
1709 // Since the body of the coroutine will be wrapped in try-catch, it will
1710 // be incompatible with SEH __try if present in a function.
1711 if (!S.getLangOpts().Borland && Fn.FirstSEHTryLoc.isValid()) {
1712 S.Diag(Fn.FirstSEHTryLoc, diag::err_seh_in_a_coroutine_with_cxx_exceptions);
1713 S.Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
1715 return false;
1716 }
1717
1718 this->OnException = UnhandledException.get();
1719 return true;
1720}
1721
1722bool CoroutineStmtBuilder::makeReturnObject() {
1723 // [dcl.fct.def.coroutine]p7
1724 // The expression promise.get_return_object() is used to initialize the
1725 // returned reference or prvalue result object of a call to a coroutine.
1726 ExprResult ReturnObject = buildPromiseCall(S, Fn.CoroutinePromise, Loc,
1727 "get_return_object", std::nullopt);
1728 if (ReturnObject.isInvalid())
1729 return false;
1730
1731 this->ReturnValue = ReturnObject.get();
1732 return true;
1733}
1734
1736 if (auto *MbrRef = dyn_cast<CXXMemberCallExpr>(E)) {
1737 auto *MethodDecl = MbrRef->getMethodDecl();
1738 S.Diag(MethodDecl->getLocation(), diag::note_member_declared_here)
1739 << MethodDecl;
1740 }
1741 S.Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
1742 << Fn.getFirstCoroutineStmtKeyword();
1743}
1744
1745bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() {
1746 assert(!IsPromiseDependentType &&
1747 "cannot make statement while the promise type is dependent");
1748 assert(this->ReturnValue && "ReturnValue must be already formed");
1749
1750 QualType const GroType = this->ReturnValue->getType();
1751 assert(!GroType->isDependentType() &&
1752 "get_return_object type must no longer be dependent");
1753
1754 QualType const FnRetType = FD.getReturnType();
1755 assert(!FnRetType->isDependentType() &&
1756 "get_return_object type must no longer be dependent");
1757
1758 // The call to get_­return_­object is sequenced before the call to
1759 // initial_­suspend and is invoked at most once, but there are caveats
1760 // regarding on whether the prvalue result object may be initialized
1761 // directly/eager or delayed, depending on the types involved.
1762 //
1763 // More info at https://github.com/cplusplus/papers/issues/1414
1764 bool GroMatchesRetType = S.getASTContext().hasSameType(GroType, FnRetType);
1765
1766 if (FnRetType->isVoidType()) {
1767 ExprResult Res =
1768 S.ActOnFinishFullExpr(this->ReturnValue, Loc, /*DiscardedValue*/ false);
1769 if (Res.isInvalid())
1770 return false;
1771
1772 if (!GroMatchesRetType)
1773 this->ResultDecl = Res.get();
1774 return true;
1775 }
1776
1777 if (GroType->isVoidType()) {
1778 // Trigger a nice error message.
1779 InitializedEntity Entity =
1783 return false;
1784 }
1785
1787 clang::VarDecl *GroDecl = nullptr;
1788 if (GroMatchesRetType) {
1790 } else {
1791 GroDecl = VarDecl::Create(
1792 S.Context, &FD, FD.getLocation(), FD.getLocation(),
1793 &S.PP.getIdentifierTable().get("__coro_gro"), GroType,
1794 S.Context.getTrivialTypeSourceInfo(GroType, Loc), SC_None);
1795 GroDecl->setImplicit();
1796
1798 if (GroDecl->isInvalidDecl())
1799 return false;
1800
1802 ExprResult Res =
1804 if (Res.isInvalid())
1805 return false;
1806
1807 Res = S.ActOnFinishFullExpr(Res.get(), /*DiscardedValue*/ false);
1808 if (Res.isInvalid())
1809 return false;
1810
1811 S.AddInitializerToDecl(GroDecl, Res.get(),
1812 /*DirectInit=*/false);
1813
1814 S.FinalizeDeclaration(GroDecl);
1815
1816 // Form a declaration statement for the return declaration, so that AST
1817 // visitors can more easily find it.
1818 StmtResult GroDeclStmt =
1819 S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(GroDecl), Loc, Loc);
1820 if (GroDeclStmt.isInvalid())
1821 return false;
1822
1823 this->ResultDecl = GroDeclStmt.get();
1824
1825 ExprResult declRef = S.BuildDeclRefExpr(GroDecl, GroType, VK_LValue, Loc);
1826 if (declRef.isInvalid())
1827 return false;
1828
1829 ReturnStmt = S.BuildReturnStmt(Loc, declRef.get());
1830 }
1831
1832 if (ReturnStmt.isInvalid()) {
1834 return false;
1835 }
1836
1837 if (!GroMatchesRetType &&
1838 cast<clang::ReturnStmt>(ReturnStmt.get())->getNRVOCandidate() == GroDecl)
1839 GroDecl->setNRVOVariable(true);
1840
1841 this->ReturnStmt = ReturnStmt.get();
1842 return true;
1843}
1844
1845// Create a static_cast<T&&>(expr).
1847 if (T.isNull())
1848 T = E->getType();
1849 QualType TargetType = S.BuildReferenceType(
1850 T, /*SpelledAsLValue*/ false, SourceLocation(), DeclarationName());
1851 SourceLocation ExprLoc = E->getBeginLoc();
1852 TypeSourceInfo *TargetLoc =
1853 S.Context.getTrivialTypeSourceInfo(TargetType, ExprLoc);
1854
1855 return S
1856 .BuildCXXNamedCast(ExprLoc, tok::kw_static_cast, TargetLoc, E,
1857 SourceRange(ExprLoc, ExprLoc), E->getSourceRange())
1858 .get();
1859}
1860
1861/// Build a variable declaration for move parameter.
1863 IdentifierInfo *II) {
1866 TInfo, SC_None);
1867 Decl->setImplicit();
1868 return Decl;
1869}
1870
1871// Build statements that move coroutine function parameters to the coroutine
1872// frame, and store them on the function scope info.
1874 assert(isa<FunctionDecl>(CurContext) && "not in a function scope");
1875 auto *FD = cast<FunctionDecl>(CurContext);
1876
1877 auto *ScopeInfo = getCurFunction();
1878 if (!ScopeInfo->CoroutineParameterMoves.empty())
1879 return false;
1880
1881 // [dcl.fct.def.coroutine]p13
1882 // When a coroutine is invoked, after initializing its parameters
1883 // ([expr.call]), a copy is created for each coroutine parameter. For a
1884 // parameter of type cv T, the copy is a variable of type cv T with
1885 // automatic storage duration that is direct-initialized from an xvalue of
1886 // type T referring to the parameter.
1887 for (auto *PD : FD->parameters()) {
1888 if (PD->getType()->isDependentType())
1889 continue;
1890
1891 // Preserve the referenced state for unused parameter diagnostics.
1892 bool DeclReferenced = PD->isReferenced();
1893
1894 ExprResult PDRefExpr =
1895 BuildDeclRefExpr(PD, PD->getType().getNonReferenceType(),
1896 ExprValueKind::VK_LValue, Loc); // FIXME: scope?
1897
1898 PD->setReferenced(DeclReferenced);
1899
1900 if (PDRefExpr.isInvalid())
1901 return false;
1902
1903 Expr *CExpr = nullptr;
1904 if (PD->getType()->getAsCXXRecordDecl() ||
1905 PD->getType()->isRValueReferenceType())
1906 CExpr = castForMoving(*this, PDRefExpr.get());
1907 else
1908 CExpr = PDRefExpr.get();
1909 // [dcl.fct.def.coroutine]p13
1910 // The initialization and destruction of each parameter copy occurs in the
1911 // context of the called coroutine.
1912 auto *D = buildVarDecl(*this, Loc, PD->getType(), PD->getIdentifier());
1913 AddInitializerToDecl(D, CExpr, /*DirectInit=*/true);
1914
1915 // Convert decl to a statement.
1917 if (Stmt.isInvalid())
1918 return false;
1919
1920 ScopeInfo->CoroutineParameterMoves.insert(std::make_pair(PD, Stmt.get()));
1921 }
1922 return true;
1923}
1924
1927 if (!Res)
1928 return StmtError();
1929 return Res;
1930}
1931
1933 SourceLocation FuncLoc) {
1936
1937 IdentifierInfo const &TraitIdent =
1938 PP.getIdentifierTable().get("coroutine_traits");
1939
1940 NamespaceDecl *StdSpace = getStdNamespace();
1941 LookupResult Result(*this, &TraitIdent, FuncLoc, LookupOrdinaryName);
1942 bool Found = StdSpace && LookupQualifiedName(Result, StdSpace);
1943
1944 if (!Found) {
1945 // The goggles, we found nothing!
1946 Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
1947 << "std::coroutine_traits";
1948 return nullptr;
1949 }
1950
1951 // coroutine_traits is required to be a class template.
1954 Result.suppressDiagnostics();
1955 NamedDecl *Found = *Result.begin();
1956 Diag(Found->getLocation(), diag::err_malformed_std_coroutine_traits);
1957 return nullptr;
1958 }
1959
1961}
This file provides some common utility functions for processing Lambda related AST Constructs.
Defines enum values for all the target-independent builtin functions.
const Decl * D
Expr * E
Defines the clang::Expr interface and subclasses for C++ expressions.
LangStandard::Kind Std
Defines the clang::Preprocessor interface.
static ExprResult buildCoroutineHandle(Sema &S, QualType PromiseType, SourceLocation Loc)
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 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 FunctionScopeInfo * checkCoroutineContext(Sema &S, SourceLocation Loc, StringRef Keyword, bool IsImplicit=false)
Check that this is a context in which a coroutine suspension can appear.
SourceLocation Loc
Definition: SemaObjC.cpp:759
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:187
QualType getRValueReferenceType(QualType T) const
Return the uniqued reference to the type for an rvalue reference to the specified type.
DeclarationNameTable DeclarationNames
Definition: ASTContext.h:664
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Definition: ASTContext.h:2644
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
CanQualType DependentTy
Definition: ASTContext.h:1147
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
Definition: ASTContext.h:1637
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.
Definition: ASTContext.h:2675
PtrTy get() const
Definition: Ownership.h:170
bool isInvalid() const
Definition: Ownership.h:166
AddrLabelExpr - The GNU address of label extension, representing &&label.
Definition: Expr.h:4372
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Expr.h:4392
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2539
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2064
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition: DeclCXX.h:2190
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
Definition: DeclCXX.cpp:2014
Represents a C++ nested-name-specifier or a global scope specifier.
Definition: DeclSpec.h:74
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2830
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition: Expr.h:3000
Decl * getCalleeDecl()
Definition: Expr.h:2994
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
Definition: Expr.cpp:1590
Declaration of a class template.
void setExprNeedsCleanups(bool SideEffects)
Definition: CleanupInfo.h:28
Represents a 'co_await' expression.
Definition: ExprCXX.h:5185
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition: Stmt.h:1611
static CompoundStmt * Create(const ASTContext &C, ArrayRef< Stmt * > Stmts, FPOptionsOverride FPFeatures, SourceLocation LB, SourceLocation RB)
Definition: Stmt.cpp:383
Represents a 'co_return' statement in the C++ Coroutines TS.
Definition: StmtCXX.h:473
Represents the body of a coroutine.
Definition: StmtCXX.h:320
static CoroutineBodyStmt * Create(const ASTContext &C, CtorArgs const &Args)
Definition: StmtCXX.cpp:87
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.
Definition: ExprCXX.h:5266
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1436
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
SourceLocation getEndLoc() const LLVM_READONLY
Definition: DeclBase.h:442
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Definition: DeclBase.cpp:154
bool isInvalidDecl() const
Definition: DeclBase.h:595
SourceLocation getLocation() const
Definition: DeclBase.h:446
void setImplicit(bool I=true)
Definition: DeclBase.h:601
DeclContext * getDeclContext()
Definition: DeclBase.h:455
bool hasAttr() const
Definition: DeclBase.h:584
DeclarationName getCXXOperatorName(OverloadedOperatorKind Op)
Get the name of the overloadable C++ operator corresponding to Op.
The name of a declaration.
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Decl.h:783
Represents a 'co_await' expression while the type of the promise is dependent.
Definition: ExprCXX.h:5217
RAII object that enters a new expression evaluation context.
Represents an enum.
Definition: Decl.h:3844
This represents one expression.
Definition: Expr.h:110
bool isPRValue() const
Definition: Expr.h:278
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
Definition: Expr.h:444
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition: Expr.cpp:277
QualType getType() const
Definition: Expr.h:142
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
Definition: Expr.h:516
Represents difference between two FPOptions values.
Definition: LangOptions.h:947
Represents a function declaration or definition.
Definition: Decl.h:1932
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2646
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Definition: Decl.cpp:3678
Represents a prototype with parameter type info, e.g.
Definition: Type.h:5002
ArrayRef< QualType > getParamTypes() const
Definition: Type.h:5262
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Definition: Type.h:5405
QualType getReturnType() const
Definition: Type.h:4630
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.
Definition: SemaInit.cpp:7522
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.
Definition: Lookup.h:46
DeclClass * getAsSingle() const
Definition: Lookup.h:558
bool isAmbiguous() const
Definition: Lookup.h:324
const UnresolvedSetImpl & asUnresolvedSet() const
Definition: Lookup.h:354
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
Definition: Lookup.h:575
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
Definition: Lookup.h:634
DeclarationName getLookupName() const
Gets the name to look up.
Definition: Lookup.h:265
This represents a decl that may have a name.
Definition: Decl.h:249
Represent a C++ namespace.
Definition: Decl.h:547
A C++ nested-name-specifier augmented with source location information.
static NestedNameSpecifier * Create(const ASTContext &Context, NestedNameSpecifier *Prefix, const 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.
Definition: Expr.h:1173
decls_iterator decls_begin() const
Definition: ExprCXX.h:3076
decls_iterator decls_end() const
Definition: ExprCXX.h:3079
static ParenListExpr * Create(const ASTContext &Ctx, SourceLocation LParenLoc, ArrayRef< Expr * > Exprs, SourceLocation RParenLoc)
Create a paren list.
Definition: Expr.cpp:4746
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
IdentifierTable & getIdentifierTable()
A (possibly-)qualified type.
Definition: Type.h:941
@ DK_cxx_destructor
Definition: Type.h:1532
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:1008
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:7750
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Definition: Type.h:7951
QualType getCanonicalType() const
Definition: Type.h:7802
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
Definition: Type.h:1542
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Definition: Stmt.h:3029
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:41
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: SemaBase.cpp:60
Expr * get() const
Definition: Sema.h:7300
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:493
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.
Definition: Sema.h:763
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)
Definition: SemaExpr.cpp:15288
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
Definition: Sema.h:9015
@ LookupOperatorName
Look up of an operator name (e.g., operator+) for use with operator overloading.
Definition: Sema.h:9027
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
Definition: Sema.h:9023
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)
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.
Definition: SemaExpr.cpp:6609
ExprResult BuildResolvedCoawaitExpr(SourceLocation KwLoc, Expr *Operand, Expr *Awaiter, bool IsImplicit=false)
ASTContext & Context
Definition: Sema.h:962
void FinalizeDeclaration(Decl *D)
FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform any semantic actions neces...
Definition: SemaDecl.cpp:14569
ExprResult ActOnCoyieldExpr(Scope *S, SourceLocation KwLoc, Expr *E)
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
Definition: SemaDecl.cpp:72
ClassTemplateDecl * StdCoroutineTraitsCache
The C++ "std::coroutine_traits" template, which is defined in <coroutine_traits>
Definition: Sema.h:2696
ASTContext & getASTContext() const
Definition: Sema.h:560
DeclRefExpr * BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
Definition: SemaExpr.cpp:2198
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...
Definition: SemaStmt.cpp:3238
StmtResult ActOnCoreturnStmt(Scope *S, SourceLocation KwLoc, Expr *E)
const LangOptions & getLangOpts() const
Definition: Sema.h:553
StmtResult ActOnFinishFullStmt(Stmt *Stmt)
Preprocessor & PP
Definition: Sema.h:961
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.
Definition: SemaExpr.cpp:6408
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.
Definition: Sema.h:6487
StmtResult ActOnNullStmt(SourceLocation SemiLoc, bool HasLeadingEmptyMacro=false)
Definition: SemaStmt.cpp:74
ExprResult BuildUnresolvedCoawaitExpr(SourceLocation KwLoc, Expr *Operand, UnresolvedLookupExpr *Lookup)
bool buildCoroutineParameterMoves(SourceLocation Loc)
sema::FunctionScopeInfo * getCurFunction() const
Definition: Sema.h:993
QualType BuildReferenceType(QualType T, bool LValueRef, SourceLocation Loc, DeclarationName Entity)
Build a reference type.
Definition: SemaType.cpp:1844
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)
Definition: SemaExpr.cpp:3175
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition: Sema.h:1097
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)
Definition: SemaInit.cpp:7466
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.
Definition: Sema.h:7796
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
Definition: SemaExpr.cpp:20717
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)
Definition: SemaStmt.cpp:3790
void CheckCompleteVariableDeclaration(VarDecl *VD)
Definition: SemaDecl.cpp:14205
@ 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)
Definition: SemaStmt.cpp:79
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Definition: SemaType.cpp:8907
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)
Definition: Sema.h:7321
NamespaceDecl * getStdNamespace() const
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
Definition: SemaInit.cpp:9656
void ActOnUninitializedDecl(Decl *dcl)
Definition: SemaDecl.cpp:13837
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
Definition: SemaDecl.cpp:13277
ExprResult BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, TypeSourceInfo *Ty, Expr *E, SourceRange AngleBrackets, SourceRange Parens)
Definition: SemaCast.cpp:297
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,...
Definition: SemaExpr.cpp:17862
void clearDelayedTypo(TypoExpr *TE)
Clears the state of the given TypoExpr.
void CheckVariableDeclarationType(VarDecl *NewVD)
Definition: SemaDecl.cpp:8526
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)
AllocationFunctionScope
The scope in which to find allocation functions.
Definition: Sema.h:8188
@ AFS_Both
Look for allocation functions in both the global scope and in the scope of the allocated class.
Definition: Sema.h:8196
@ AFS_Class
Only look for allocation functions in the scope of the allocated class.
Definition: Sema.h:8193
@ AFS_Global
Only look for allocation functions in the global scope.
Definition: Sema.h:8190
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)
Definition: Sema.h:8293
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.
Definition: Stmt.h:84
child_range children()
Definition: Stmt.cpp:287
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:326
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:338
A convenient class for passing around template argument information.
Definition: TemplateBase.h:632
void addArgument(const TemplateArgumentLoc &Loc)
Definition: TemplateBase.h:667
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:524
Represents a template argument.
Definition: TemplateBase.h:61
Represents a C++ template name within the type system.
Definition: TemplateName.h:203
Represents a declaration of a type.
Definition: Decl.h:3367
A container of type source information.
Definition: Type.h:7721
The base class of the type hierarchy.
Definition: Type.h:1829
bool isStructureType() const
Definition: Type.cpp:629
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1882
bool isVoidType() const
Definition: Type.h:8319
bool isBooleanType() const
Definition: Type.h:8447
bool isVoidPointerType() const
Definition: Type.cpp:665
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8607
bool isReferenceType() const
Definition: Type.h:8021
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2695
bool isClassType() const
Definition: Type.cpp:623
bool isRecordType() const
Definition: Type.h:8103
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
Definition: ExprCXX.h:3203
static UnresolvedLookupExpr * Create(const ASTContext &Context, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool RequiresADL, UnresolvedSetIterator Begin, UnresolvedSetIterator End, bool KnownDependent, bool KnownInstantiationDependent)
Definition: ExprCXX.cpp:420
void append(iterator I, iterator E)
A set of unresolved declarations.
QualType getType() const
Definition: Decl.h:678
Represents a variable declaration or definition.
Definition: Decl.h:879
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
Definition: Decl.cpp:2133
@ CallInit
Call-style initialization (C++98)
Definition: Decl.h:887
void setNRVOVariable(bool NRVO)
Definition: Decl.h:1456
Retains information about a function, method, or block that is currently being parsed.
Definition: ScopeInfo.h:104
SourceLocation FirstCoroutineStmtLoc
First coroutine statement in the current function.
Definition: ScopeInfo.h:183
std::pair< Stmt *, Stmt * > CoroutineSuspends
The initial and final coroutine suspend points.
Definition: ScopeInfo.h:224
VarDecl * CoroutinePromise
The promise object for this coroutine, if any.
Definition: ScopeInfo.h:217
bool hasInvalidCoroutineSuspends() const
Definition: ScopeInfo.h:540
StringRef getFirstCoroutineStmtKeyword() const
Definition: ScopeInfo.h:518
SourceLocation FirstReturnLoc
First 'return' statement in the current function.
Definition: ScopeInfo.h:186
SourceLocation FirstSEHTryLoc
First SEH '__try' statement in the current function.
Definition: ScopeInfo.h:193
The JSON file list parser is used to communicate input to InstallAPI.
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
Definition: Type.h:1784
@ SC_None
Definition: Specifiers.h:250
ExprResult ExprEmpty()
Definition: Ownership.h:271
StmtResult StmtError()
Definition: Ownership.h:265
bool isLambdaCallOperator(const CXXMethodDecl *MD)
Definition: ASTLambda.h:27
@ Result
The result type of a method or function.
ExprResult ExprError()
Definition: Ownership.h:264
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Definition: Specifiers.h:139
const FunctionProtoType * T
OpaqueValueExpr * OpaqueValue
ArrayRef< Stmt * > ParamMoves
Definition: StmtCXX.h:361
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
DeclarationName getName() const
getName - Returns the embedded declaration name.