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