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(cast<CXXRecordDecl>(T->getOriginalDecl())
644 ->getDefinition()
645 ->getDestructor(),
646 /*IsDtor=*/true);
647 }
648 } else
649 for (const auto *Child : E->children()) {
650 if (!Child)
651 continue;
652 checkNoThrow(S, Child, ThrowingDecls);
653 }
654}
655
656bool Sema::checkFinalSuspendNoThrow(const Stmt *FinalSuspend) {
658 // We first collect all declarations that should not throw but not declared
659 // with noexcept. We then sort them based on the location before printing.
660 // This is to avoid emitting the same note multiple times on the same
661 // declaration, and also provide a deterministic order for the messages.
662 checkNoThrow(*this, FinalSuspend, ThrowingDecls);
663 auto SortedDecls = llvm::SmallVector<const Decl *, 4>{ThrowingDecls.begin(),
664 ThrowingDecls.end()};
665 sort(SortedDecls, [](const Decl *A, const Decl *B) {
666 return A->getEndLoc() < B->getEndLoc();
667 });
668 for (const auto *D : SortedDecls) {
669 Diag(D->getEndLoc(), diag::note_coroutine_function_declare_noexcept);
670 }
671 return ThrowingDecls.empty();
672}
673
674// [stmt.return.coroutine]p1:
675// A coroutine shall not enclose a return statement ([stmt.return]).
677 assert(FSI && "FunctionScopeInfo is null");
678 assert(FSI->FirstCoroutineStmtLoc.isValid() &&
679 "first coroutine location not set");
680 if (FSI->FirstReturnLoc.isInvalid())
681 return;
682 S.Diag(FSI->FirstReturnLoc, diag::err_return_in_coroutine);
683 S.Diag(FSI->FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
685}
686
688 StringRef Keyword) {
689 // Ignore previous expr evaluation contexts.
692 dyn_cast_or_null<FunctionDecl>(CurContext));
693
694 if (!checkCoroutineContext(*this, KWLoc, Keyword))
695 return false;
696 auto *ScopeInfo = getCurFunction();
697 assert(ScopeInfo->CoroutinePromise);
698
699 // Avoid duplicate errors, report only on first keyword.
700 if (ScopeInfo->FirstCoroutineStmtLoc == KWLoc)
701 checkReturnStmtInCoroutine(*this, ScopeInfo);
702
703 // If we have existing coroutine statements then we have already built
704 // the initial and final suspend points.
705 if (!ScopeInfo->NeedsCoroutineSuspends)
706 return true;
707
708 ScopeInfo->setNeedsCoroutineSuspends(false);
709
710 auto *Fn = cast<FunctionDecl>(CurContext);
711 SourceLocation Loc = Fn->getLocation();
712 // Build the initial suspend point
713 auto buildSuspends = [&](StringRef Name) mutable -> StmtResult {
714 ExprResult Operand =
715 buildPromiseCall(*this, ScopeInfo->CoroutinePromise, Loc, Name, {});
716 if (Operand.isInvalid())
717 return StmtError();
718 ExprResult Suspend =
719 buildOperatorCoawaitCall(*this, SC, Loc, Operand.get());
720 if (Suspend.isInvalid())
721 return StmtError();
722 Suspend = BuildResolvedCoawaitExpr(Loc, Operand.get(), Suspend.get(),
723 /*IsImplicit*/ true);
724 Suspend = ActOnFinishFullExpr(Suspend.get(), /*DiscardedValue*/ false);
725 if (Suspend.isInvalid()) {
726 Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
727 << ((Name == "initial_suspend") ? 0 : 1);
728 Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword;
729 return StmtError();
730 }
731 return cast<Stmt>(Suspend.get());
732 };
733
734 StmtResult InitSuspend = buildSuspends("initial_suspend");
735 if (InitSuspend.isInvalid())
736 return true;
737
738 StmtResult FinalSuspend = buildSuspends("final_suspend");
739 if (FinalSuspend.isInvalid() || !checkFinalSuspendNoThrow(FinalSuspend.get()))
740 return true;
741
742 ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get());
743
744 return true;
745}
746
747// Recursively walks up the scope hierarchy until either a 'catch' or a function
748// scope is found, whichever comes first.
749static bool isWithinCatchScope(Scope *S) {
750 // 'co_await' and 'co_yield' keywords are disallowed within catch blocks, but
751 // lambdas that use 'co_await' are allowed. The loop below ends when a
752 // function scope is found in order to ensure the following behavior:
753 //
754 // void foo() { // <- function scope
755 // try { //
756 // co_await x; // <- 'co_await' is OK within a function scope
757 // } catch { // <- catch scope
758 // co_await x; // <- 'co_await' is not OK within a catch scope
759 // []() { // <- function scope
760 // co_await x; // <- 'co_await' is OK within a function scope
761 // }();
762 // }
763 // }
764 while (S && !S->isFunctionScope()) {
765 if (S->isCatchScope())
766 return true;
767 S = S->getParent();
768 }
769 return false;
770}
771
772// [expr.await]p2, emphasis added: "An await-expression shall appear only in
773// a *potentially evaluated* expression within the compound-statement of a
774// function-body *outside of a handler* [...] A context within a function
775// where an await-expression can appear is called a suspension context of the
776// function."
778 StringRef Keyword) {
779 // First emphasis of [expr.await]p2: must be a potentially evaluated context.
780 // That is, 'co_await' and 'co_yield' cannot appear in subexpressions of
781 // \c sizeof.
782 const auto ExprContext = S.currentEvaluationContext().ExprContext;
783 const bool BadContext =
787 if (BadContext) {
788 S.Diag(Loc, diag::err_coroutine_unevaluated_context) << Keyword;
789 return false;
790 }
791
792 // Second emphasis of [expr.await]p2: must be outside of an exception handler.
794 S.Diag(Loc, diag::err_coroutine_within_handler) << Keyword;
795 return false;
796 }
797 return true;
798}
799
801 if (!checkSuspensionContext(*this, Loc, "co_await"))
802 return ExprError();
803
804 if (!ActOnCoroutineBodyStart(S, Loc, "co_await")) {
805 return ExprError();
806 }
807
808 if (E->hasPlaceholderType()) {
810 if (R.isInvalid()) return ExprError();
811 E = R.get();
812 }
813
815 if (Lookup.isInvalid())
816 return ExprError();
817 return BuildUnresolvedCoawaitExpr(Loc, E,
819}
820
822 DeclarationName OpName =
823 Context.DeclarationNames.getCXXOperatorName(OO_Coawait);
824 LookupResult Operators(*this, OpName, SourceLocation(),
826 LookupName(Operators, S);
827
828 assert(!Operators.isAmbiguous() && "Operator lookup cannot be ambiguous");
829 const auto &Functions = Operators.asUnresolvedSet();
831 Context, /*NamingClass*/ nullptr, NestedNameSpecifierLoc(),
832 DeclarationNameInfo(OpName, Loc), /*RequiresADL*/ true, Functions.begin(),
833 Functions.end(), /*KnownDependent=*/false,
834 /*KnownInstantiationDependent=*/false);
835 assert(CoawaitOp);
836 return CoawaitOp;
837}
838
840 auto *Record = QT->getAsCXXRecordDecl();
841 return Record && Record->hasAttr<CoroAwaitElidableAttr>();
842}
843
844static void applySafeElideContext(Expr *Operand) {
845 auto *Call = dyn_cast<CallExpr>(Operand->IgnoreImplicit());
846 if (!Call || !Call->isPRValue())
847 return;
848
849 if (!isAttributedCoroAwaitElidable(Call->getType()))
850 return;
851
852 Call->setCoroElideSafe();
853
854 // Check parameter
855 auto *Fn = llvm::dyn_cast_if_present<FunctionDecl>(Call->getCalleeDecl());
856 if (!Fn)
857 return;
858
859 size_t ParmIdx = 0;
860 for (ParmVarDecl *PD : Fn->parameters()) {
861 if (PD->hasAttr<CoroAwaitElidableArgumentAttr>())
862 applySafeElideContext(Call->getArg(ParmIdx));
863
864 ParmIdx++;
865 }
866}
867
868// Attempts to resolve and build a CoawaitExpr from "raw" inputs, bailing out to
869// DependentCoawaitExpr if needed.
871 UnresolvedLookupExpr *Lookup) {
872 auto *FSI = checkCoroutineContext(*this, Loc, "co_await");
873 if (!FSI)
874 return ExprError();
875
876 if (Operand->hasPlaceholderType()) {
877 ExprResult R = CheckPlaceholderExpr(Operand);
878 if (R.isInvalid())
879 return ExprError();
880 Operand = R.get();
881 }
882
883 auto *Promise = FSI->CoroutinePromise;
884 if (Promise->getType()->isDependentType()) {
885 Expr *Res = new (Context)
886 DependentCoawaitExpr(Loc, Context.DependentTy, Operand, Lookup);
887 return Res;
888 }
889
890 auto *RD = Promise->getType()->getAsCXXRecordDecl();
891
892 bool CurFnAwaitElidable = isAttributedCoroAwaitElidable(
893 getCurFunctionDecl(/*AllowLambda=*/true)->getReturnType());
894
895 if (CurFnAwaitElidable)
896 applySafeElideContext(Operand);
897
898 Expr *Transformed = Operand;
899 if (lookupMember(*this, "await_transform", RD, Loc)) {
900 ExprResult R =
901 buildPromiseCall(*this, Promise, Loc, "await_transform", Operand);
902 if (R.isInvalid()) {
903 Diag(Loc,
904 diag::note_coroutine_promise_implicit_await_transform_required_here)
905 << Operand->getSourceRange();
906 return ExprError();
907 }
908 Transformed = R.get();
909 }
910 ExprResult Awaiter = BuildOperatorCoawaitCall(Loc, Transformed, Lookup);
911 if (Awaiter.isInvalid())
912 return ExprError();
913
914 return BuildResolvedCoawaitExpr(Loc, Operand, Awaiter.get());
915}
916
918 Expr *Awaiter, bool IsImplicit) {
919 auto *Coroutine = checkCoroutineContext(*this, Loc, "co_await", IsImplicit);
920 if (!Coroutine)
921 return ExprError();
922
923 if (Awaiter->hasPlaceholderType()) {
924 ExprResult R = CheckPlaceholderExpr(Awaiter);
925 if (R.isInvalid()) return ExprError();
926 Awaiter = R.get();
927 }
928
929 if (Awaiter->getType()->isDependentType()) {
930 Expr *Res = new (Context)
931 CoawaitExpr(Loc, Context.DependentTy, Operand, Awaiter, IsImplicit);
932 return Res;
933 }
934
935 // If the expression is a temporary, materialize it as an lvalue so that we
936 // can use it multiple times.
937 if (Awaiter->isPRValue())
938 Awaiter = CreateMaterializeTemporaryExpr(Awaiter->getType(), Awaiter, true);
939
940 // The location of the `co_await` token cannot be used when constructing
941 // the member call expressions since it's before the location of `Expr`, which
942 // is used as the start of the member call expression.
943 SourceLocation CallLoc = Awaiter->getExprLoc();
944
945 // Build the await_ready, await_suspend, await_resume calls.
947 buildCoawaitCalls(*this, Coroutine->CoroutinePromise, CallLoc, Awaiter);
948 if (RSS.IsInvalid)
949 return ExprError();
950
951 Expr *Res = new (Context)
952 CoawaitExpr(Loc, Operand, Awaiter, RSS.Results[0], RSS.Results[1],
953 RSS.Results[2], RSS.OpaqueValue, IsImplicit);
954
955 return Res;
956}
957
959 if (!checkSuspensionContext(*this, Loc, "co_yield"))
960 return ExprError();
961
962 if (!ActOnCoroutineBodyStart(S, Loc, "co_yield")) {
963 return ExprError();
964 }
965
966 // Build yield_value call.
967 ExprResult Awaitable = buildPromiseCall(
968 *this, getCurFunction()->CoroutinePromise, Loc, "yield_value", E);
969 if (Awaitable.isInvalid())
970 return ExprError();
971
972 // Build 'operator co_await' call.
973 Awaitable = buildOperatorCoawaitCall(*this, S, Loc, Awaitable.get());
974 if (Awaitable.isInvalid())
975 return ExprError();
976
977 return BuildCoyieldExpr(Loc, Awaitable.get());
978}
980 auto *Coroutine = checkCoroutineContext(*this, Loc, "co_yield");
981 if (!Coroutine)
982 return ExprError();
983
984 if (E->hasPlaceholderType()) {
986 if (R.isInvalid()) return ExprError();
987 E = R.get();
988 }
989
990 Expr *Operand = E;
991
992 if (E->getType()->isDependentType()) {
993 Expr *Res = new (Context) CoyieldExpr(Loc, Context.DependentTy, Operand, E);
994 return Res;
995 }
996
997 // If the expression is a temporary, materialize it as an lvalue so that we
998 // can use it multiple times.
999 if (E->isPRValue())
1000 E = CreateMaterializeTemporaryExpr(E->getType(), E, true);
1001
1002 // Build the await_ready, await_suspend, await_resume calls.
1004 *this, Coroutine->CoroutinePromise, Loc, E);
1005 if (RSS.IsInvalid)
1006 return ExprError();
1007
1008 Expr *Res =
1009 new (Context) CoyieldExpr(Loc, Operand, E, RSS.Results[0], RSS.Results[1],
1010 RSS.Results[2], RSS.OpaqueValue);
1011
1012 return Res;
1013}
1014
1016 if (!ActOnCoroutineBodyStart(S, Loc, "co_return")) {
1017 return StmtError();
1018 }
1019 return BuildCoreturnStmt(Loc, E);
1020}
1021
1023 bool IsImplicit) {
1024 auto *FSI = checkCoroutineContext(*this, Loc, "co_return", IsImplicit);
1025 if (!FSI)
1026 return StmtError();
1027
1028 if (E && E->hasPlaceholderType() &&
1029 !E->hasPlaceholderType(BuiltinType::Overload)) {
1031 if (R.isInvalid()) return StmtError();
1032 E = R.get();
1033 }
1034
1035 VarDecl *Promise = FSI->CoroutinePromise;
1036 ExprResult PC;
1037 if (E && (isa<InitListExpr>(E) || !E->getType()->isVoidType())) {
1039 PC = buildPromiseCall(*this, Promise, Loc, "return_value", E);
1040 } else {
1042 PC = buildPromiseCall(*this, Promise, Loc, "return_void", {});
1043 }
1044 if (PC.isInvalid())
1045 return StmtError();
1046
1047 Expr *PCE = ActOnFinishFullExpr(PC.get(), /*DiscardedValue*/ false).get();
1048
1049 Stmt *Res = new (Context) CoreturnStmt(Loc, E, PCE, IsImplicit);
1050 return Res;
1051}
1052
1053/// Look up the std::nothrow object.
1055 NamespaceDecl *Std = S.getStdNamespace();
1056 assert(Std && "Should already be diagnosed");
1057
1058 LookupResult Result(S, &S.PP.getIdentifierTable().get("nothrow"), Loc,
1060 if (!S.LookupQualifiedName(Result, Std)) {
1061 // <coroutine> is not requred to include <new>, so we couldn't omit
1062 // the check here.
1063 S.Diag(Loc, diag::err_implicit_coroutine_std_nothrow_type_not_found);
1064 return nullptr;
1065 }
1066
1067 auto *VD = Result.getAsSingle<VarDecl>();
1068 if (!VD) {
1069 Result.suppressDiagnostics();
1070 // We found something weird. Complain about the first thing we found.
1071 NamedDecl *Found = *Result.begin();
1072 S.Diag(Found->getLocation(), diag::err_malformed_std_nothrow);
1073 return nullptr;
1074 }
1075
1076 ExprResult DR = S.BuildDeclRefExpr(VD, VD->getType(), VK_LValue, Loc);
1077 if (DR.isInvalid())
1078 return nullptr;
1079
1080 return DR.get();
1081}
1082
1084 SourceLocation Loc) {
1085 EnumDecl *StdAlignValDecl = S.getStdAlignValT();
1086 CanQualType StdAlignValT = S.Context.getCanonicalTagType(StdAlignValDecl);
1087 return S.Context.getTrivialTypeSourceInfo(StdAlignValT);
1088}
1089
1090// When searching for custom allocators on the PromiseType we want to
1091// warn that we will ignore type aware allocators.
1093 unsigned DiagnosticID,
1094 DeclarationName Name,
1095 QualType PromiseType) {
1096 assert(PromiseType->isRecordType());
1097
1098 LookupResult R(S, Name, Loc, Sema::LookupOrdinaryName);
1099 S.LookupQualifiedName(R, PromiseType->getAsCXXRecordDecl());
1100 bool HaveIssuedWarning = false;
1101 for (auto Decl : R) {
1103 continue;
1104 if (!HaveIssuedWarning) {
1105 S.Diag(Loc, DiagnosticID) << Name;
1106 HaveIssuedWarning = true;
1107 }
1108 S.Diag(Decl->getLocation(), diag::note_type_aware_operator_declared)
1109 << /* isTypeAware=*/1 << Decl << Decl->getDeclContext();
1110 }
1112 return HaveIssuedWarning;
1113}
1114
1115// Find an appropriate delete for the promise.
1116static bool findDeleteForPromise(Sema &S, SourceLocation Loc, QualType PromiseType,
1117 FunctionDecl *&OperatorDelete) {
1118 DeclarationName DeleteName =
1121 diag::warn_coroutine_type_aware_allocator_ignored,
1122 DeleteName, PromiseType);
1123 auto *PointeeRD = PromiseType->getAsCXXRecordDecl();
1124 assert(PointeeRD && "PromiseType must be a CxxRecordDecl type");
1125
1126 const bool Overaligned = S.getLangOpts().CoroAlignedAllocation;
1127
1128 // [dcl.fct.def.coroutine]p12
1129 // The deallocation function's name is looked up by searching for it in the
1130 // scope of the promise type. If nothing is found, a search is performed in
1131 // the global scope.
1134 if (S.FindDeallocationFunction(Loc, PointeeRD, DeleteName, OperatorDelete,
1135 IDP, /*Diagnose=*/true))
1136 return false;
1137
1138 // [dcl.fct.def.coroutine]p12
1139 // If both a usual deallocation function with only a pointer parameter and a
1140 // usual deallocation function with both a pointer parameter and a size
1141 // parameter are found, then the selected deallocation function shall be the
1142 // one with two parameters. Otherwise, the selected deallocation function
1143 // shall be the function with one parameter.
1144 if (!OperatorDelete) {
1145 // Look for a global declaration.
1146 // Sema::FindUsualDeallocationFunction will try to find the one with two
1147 // parameters first. It will return the deallocation function with one
1148 // parameter if failed.
1149 // Coroutines can always provide their required size.
1151 OperatorDelete = S.FindUsualDeallocationFunction(Loc, IDP, DeleteName);
1152
1153 if (!OperatorDelete)
1154 return false;
1155 }
1156
1157 assert(!OperatorDelete->isTypeAwareOperatorNewOrDelete());
1158 S.MarkFunctionReferenced(Loc, OperatorDelete);
1159 return true;
1160}
1161
1162
1165 assert(Fn && Fn->isCoroutine() && "not a coroutine");
1166 if (!Body) {
1167 assert(FD->isInvalidDecl() &&
1168 "a null body is only allowed for invalid declarations");
1169 return;
1170 }
1171 // We have a function that uses coroutine keywords, but we failed to build
1172 // the promise type.
1173 if (!Fn->CoroutinePromise)
1174 return FD->setInvalidDecl();
1175
1176 if (isa<CoroutineBodyStmt>(Body)) {
1177 // Nothing todo. the body is already a transformed coroutine body statement.
1178 return;
1179 }
1180
1181 // The always_inline attribute doesn't reliably apply to a coroutine,
1182 // because the coroutine will be split into pieces and some pieces
1183 // might be called indirectly, as in a virtual call. Even the ramp
1184 // function cannot be inlined at -O0, due to pipeline ordering
1185 // problems (see https://llvm.org/PR53413). Tell the user about it.
1186 if (FD->hasAttr<AlwaysInlineAttr>())
1187 Diag(FD->getLocation(), diag::warn_always_inline_coroutine);
1188
1189 // The design of coroutines means we cannot allow use of VLAs within one, so
1190 // diagnose if we've seen a VLA in the body of this function.
1191 if (Fn->FirstVLALoc.isValid())
1192 Diag(Fn->FirstVLALoc, diag::err_vla_in_coroutine_unsupported);
1193
1194 // Coroutines will get splitted into pieces. The GNU address of label
1195 // extension wouldn't be meaningful in coroutines.
1196 for (AddrLabelExpr *ALE : Fn->AddrLabels)
1197 Diag(ALE->getBeginLoc(), diag::err_coro_invalid_addr_of_label);
1198
1199 // Coroutines always return a handle, so they can't be [[noreturn]].
1200 if (FD->isNoReturn())
1201 Diag(FD->getLocation(), diag::warn_noreturn_coroutine) << FD;
1202
1203 CoroutineStmtBuilder Builder(*this, *FD, *Fn, Body);
1204 if (Builder.isInvalid() || !Builder.buildStatements())
1205 return FD->setInvalidDecl();
1206
1207 // Build body for the coroutine wrapper statement.
1208 Body = CoroutineBodyStmt::Create(Context, Builder);
1209}
1210
1212 if (auto *CS = dyn_cast<CompoundStmt>(Body))
1213 return CS;
1214
1215 // The body of the coroutine may be a try statement if it is in
1216 // 'function-try-block' syntax. Here we wrap it into a compound
1217 // statement for consistency.
1218 assert(isa<CXXTryStmt>(Body) && "Unimaged coroutine body type");
1219 return CompoundStmt::Create(Context, {Body}, FPOptionsOverride(),
1221}
1222
1225 Stmt *Body)
1226 : S(S), FD(FD), Fn(Fn), Loc(FD.getLocation()),
1227 IsPromiseDependentType(
1228 !Fn.CoroutinePromise ||
1229 Fn.CoroutinePromise->getType()->isDependentType()) {
1230 this->Body = buildCoroutineBody(Body, S.getASTContext());
1231
1232 for (auto KV : Fn.CoroutineParameterMoves)
1233 this->ParamMovesVector.push_back(KV.second);
1234 this->ParamMoves = this->ParamMovesVector;
1235
1236 if (!IsPromiseDependentType) {
1237 PromiseRecordDecl = Fn.CoroutinePromise->getType()->getAsCXXRecordDecl();
1238 assert(PromiseRecordDecl && "Type should have already been checked");
1239 }
1240 this->IsValid = makePromiseStmt() && makeInitialAndFinalSuspend();
1241}
1242
1244 assert(this->IsValid && "coroutine already invalid");
1245 this->IsValid = makeReturnObject();
1246 if (this->IsValid && !IsPromiseDependentType)
1248 return this->IsValid;
1249}
1250
1252 assert(this->IsValid && "coroutine already invalid");
1253 assert(!this->IsPromiseDependentType &&
1254 "coroutine cannot have a dependent promise type");
1255 this->IsValid = makeOnException() && makeOnFallthrough() &&
1256 makeGroDeclAndReturnStmt() && makeReturnOnAllocFailure() &&
1257 makeNewAndDeleteExpr();
1258 return this->IsValid;
1259}
1260
1261bool CoroutineStmtBuilder::makePromiseStmt() {
1262 // Form a declaration statement for the promise declaration, so that AST
1263 // visitors can more easily find it.
1264 StmtResult PromiseStmt =
1266 if (PromiseStmt.isInvalid())
1267 return false;
1268
1269 this->Promise = PromiseStmt.get();
1270 return true;
1271}
1272
1273bool CoroutineStmtBuilder::makeInitialAndFinalSuspend() {
1275 return false;
1277 this->FinalSuspend = cast<Expr>(Fn.CoroutineSuspends.second);
1278 return true;
1279}
1280
1282 CXXRecordDecl *PromiseRecordDecl,
1283 FunctionScopeInfo &Fn) {
1284 auto Loc = E->getExprLoc();
1285 if (auto *DeclRef = dyn_cast_or_null<DeclRefExpr>(E)) {
1286 auto *Decl = DeclRef->getDecl();
1287 if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(Decl)) {
1288 if (Method->isStatic())
1289 return true;
1290 else
1291 Loc = Decl->getLocation();
1292 }
1293 }
1294
1295 S.Diag(
1296 Loc,
1297 diag::err_coroutine_promise_get_return_object_on_allocation_failure)
1298 << PromiseRecordDecl;
1299 S.Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
1300 << Fn.getFirstCoroutineStmtKeyword();
1301 return false;
1302}
1303
1304bool CoroutineStmtBuilder::makeReturnOnAllocFailure() {
1305 assert(!IsPromiseDependentType &&
1306 "cannot make statement while the promise type is dependent");
1307
1308 // [dcl.fct.def.coroutine]p10
1309 // If a search for the name get_return_object_on_allocation_failure in
1310 // the scope of the promise type ([class.member.lookup]) finds any
1311 // declarations, then the result of a call to an allocation function used to
1312 // obtain storage for the coroutine state is assumed to return nullptr if it
1313 // fails to obtain storage, ... If the allocation function returns nullptr,
1314 // ... and the return value is obtained by a call to
1315 // T::get_return_object_on_allocation_failure(), where T is the
1316 // promise type.
1317 DeclarationName DN =
1318 S.PP.getIdentifierInfo("get_return_object_on_allocation_failure");
1319 LookupResult Found(S, DN, Loc, Sema::LookupMemberName);
1320 if (!S.LookupQualifiedName(Found, PromiseRecordDecl))
1321 return true;
1322
1323 CXXScopeSpec SS;
1324 ExprResult DeclNameExpr =
1325 S.BuildDeclarationNameExpr(SS, Found, /*NeedsADL=*/false);
1326 if (DeclNameExpr.isInvalid())
1327 return false;
1328
1329 if (!diagReturnOnAllocFailure(S, DeclNameExpr.get(), PromiseRecordDecl, Fn))
1330 return false;
1331
1332 ExprResult ReturnObjectOnAllocationFailure =
1333 S.BuildCallExpr(nullptr, DeclNameExpr.get(), Loc, {}, Loc);
1334 if (ReturnObjectOnAllocationFailure.isInvalid())
1335 return false;
1336
1338 S.BuildReturnStmt(Loc, ReturnObjectOnAllocationFailure.get());
1339 if (ReturnStmt.isInvalid()) {
1340 S.Diag(Found.getFoundDecl()->getLocation(), diag::note_member_declared_here)
1341 << DN;
1342 S.Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
1343 << Fn.getFirstCoroutineStmtKeyword();
1344 return false;
1345 }
1346
1348 return true;
1349}
1350
1351// Collect placement arguments for allocation function of coroutine FD.
1352// Return true if we collect placement arguments succesfully. Return false,
1353// otherwise.
1355 SmallVectorImpl<Expr *> &PlacementArgs) {
1356 if (auto *MD = dyn_cast<CXXMethodDecl>(&FD)) {
1357 if (MD->isImplicitObjectMemberFunction() && !isLambdaCallOperator(MD)) {
1358 ExprResult ThisExpr = S.ActOnCXXThis(Loc);
1359 if (ThisExpr.isInvalid())
1360 return false;
1361 ThisExpr = S.CreateBuiltinUnaryOp(Loc, UO_Deref, ThisExpr.get());
1362 if (ThisExpr.isInvalid())
1363 return false;
1364 PlacementArgs.push_back(ThisExpr.get());
1365 }
1366 }
1367
1368 for (auto *PD : FD.parameters()) {
1369 if (PD->getType()->isDependentType())
1370 continue;
1371
1372 // Build a reference to the parameter.
1373 auto PDLoc = PD->getLocation();
1374 ExprResult PDRefExpr =
1375 S.BuildDeclRefExpr(PD, PD->getOriginalType().getNonReferenceType(),
1377 if (PDRefExpr.isInvalid())
1378 return false;
1379
1380 PlacementArgs.push_back(PDRefExpr.get());
1381 }
1382
1383 return true;
1384}
1385
1386bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
1387 // Form and check allocation and deallocation calls.
1388 assert(!IsPromiseDependentType &&
1389 "cannot make statement while the promise type is dependent");
1390 QualType PromiseType = Fn.CoroutinePromise->getType();
1391
1392 if (S.RequireCompleteType(Loc, PromiseType, diag::err_incomplete_type))
1393 return false;
1394
1395 const bool RequiresNoThrowAlloc = ReturnStmtOnAllocFailure != nullptr;
1396
1397 // According to [dcl.fct.def.coroutine]p9, Lookup allocation functions using a
1398 // parameter list composed of the requested size of the coroutine state being
1399 // allocated, followed by the coroutine function's arguments. If a matching
1400 // allocation function exists, use it. Otherwise, use an allocation function
1401 // that just takes the requested size.
1402 //
1403 // [dcl.fct.def.coroutine]p9
1404 // An implementation may need to allocate additional storage for a
1405 // coroutine.
1406 // This storage is known as the coroutine state and is obtained by calling a
1407 // non-array allocation function ([basic.stc.dynamic.allocation]). The
1408 // allocation function's name is looked up by searching for it in the scope of
1409 // the promise type.
1410 // - If any declarations are found, overload resolution is performed on a
1411 // function call created by assembling an argument list. The first argument is
1412 // the amount of space requested, and has type std::size_t. The
1413 // lvalues p1 ... pn are the succeeding arguments.
1414 //
1415 // ...where "p1 ... pn" are defined earlier as:
1416 //
1417 // [dcl.fct.def.coroutine]p3
1418 // The promise type of a coroutine is `std::coroutine_traits<R, P1, ...,
1419 // Pn>`
1420 // , where R is the return type of the function, and `P1, ..., Pn` are the
1421 // sequence of types of the non-object function parameters, preceded by the
1422 // type of the object parameter ([dcl.fct]) if the coroutine is a non-static
1423 // member function. [dcl.fct.def.coroutine]p4 In the following, p_i is an
1424 // lvalue of type P_i, where p1 denotes the object parameter and p_i+1 denotes
1425 // the i-th non-object function parameter for a non-static member function,
1426 // and p_i denotes the i-th function parameter otherwise. For a non-static
1427 // member function, q_1 is an lvalue that denotes *this; any other q_i is an
1428 // lvalue that denotes the parameter copy corresponding to p_i.
1429
1430 FunctionDecl *OperatorNew = nullptr;
1431 SmallVector<Expr *, 1> PlacementArgs;
1432 DeclarationName NewName =
1433 S.getASTContext().DeclarationNames.getCXXOperatorName(OO_New);
1434
1435 const bool PromiseContainsNew = [this, &PromiseType, NewName]() -> bool {
1436 LookupResult R(S, NewName, Loc, Sema::LookupOrdinaryName);
1437
1438 if (PromiseType->isRecordType())
1439 S.LookupQualifiedName(R, PromiseType->getAsCXXRecordDecl());
1440
1441 return !R.empty() && !R.isAmbiguous();
1442 }();
1443
1444 // Helper function to indicate whether the last lookup found the aligned
1445 // allocation function.
1446 ImplicitAllocationParameters IAP(
1447 alignedAllocationModeFromBool(S.getLangOpts().CoroAlignedAllocation));
1448 auto LookupAllocationFunction = [&](AllocationFunctionScope NewScope =
1450 bool WithoutPlacementArgs = false,
1451 bool ForceNonAligned = false) {
1452 // [dcl.fct.def.coroutine]p9
1453 // The allocation function's name is looked up by searching for it in the
1454 // scope of the promise type.
1455 // - If any declarations are found, ...
1456 // - If no declarations are found in the scope of the promise type, a search
1457 // is performed in the global scope.
1458 if (NewScope == AllocationFunctionScope::Both)
1459 NewScope = PromiseContainsNew ? AllocationFunctionScope::Class
1461
1462 bool ShouldUseAlignedAlloc =
1463 !ForceNonAligned && S.getLangOpts().CoroAlignedAllocation;
1464 IAP = ImplicitAllocationParameters(
1465 alignedAllocationModeFromBool(ShouldUseAlignedAlloc));
1466
1467 FunctionDecl *UnusedResult = nullptr;
1468 S.FindAllocationFunctions(
1469 Loc, SourceRange(), NewScope,
1470 /*DeleteScope=*/AllocationFunctionScope::Both, PromiseType,
1471 /*isArray=*/false, IAP,
1472 WithoutPlacementArgs ? MultiExprArg{} : PlacementArgs, OperatorNew,
1473 UnusedResult, /*Diagnose=*/false);
1474 assert(!OperatorNew || !OperatorNew->isTypeAwareOperatorNewOrDelete());
1475 };
1476
1477 // We don't expect to call to global operator new with (size, p0, â€Ļ, pn).
1478 // So if we choose to lookup the allocation function in global scope, we
1479 // shouldn't lookup placement arguments.
1480 if (PromiseContainsNew && !collectPlacementArgs(S, FD, Loc, PlacementArgs))
1481 return false;
1482
1483 LookupAllocationFunction();
1484
1485 if (PromiseContainsNew && !PlacementArgs.empty()) {
1486 // [dcl.fct.def.coroutine]p9
1487 // If no viable function is found ([over.match.viable]), overload
1488 // resolution
1489 // is performed again on a function call created by passing just the amount
1490 // of space required as an argument of type std::size_t.
1491 //
1492 // Proposed Change of [dcl.fct.def.coroutine]p9 in P2014R0:
1493 // Otherwise, overload resolution is performed again on a function call
1494 // created
1495 // by passing the amount of space requested as an argument of type
1496 // std::size_t as the first argument, and the requested alignment as
1497 // an argument of type std:align_val_t as the second argument.
1498 if (!OperatorNew || (S.getLangOpts().CoroAlignedAllocation &&
1499 !isAlignedAllocation(IAP.PassAlignment)))
1500 LookupAllocationFunction(/*NewScope*/ AllocationFunctionScope::Class,
1501 /*WithoutPlacementArgs*/ true);
1502 }
1503
1504 // Proposed Change of [dcl.fct.def.coroutine]p12 in P2014R0:
1505 // Otherwise, overload resolution is performed again on a function call
1506 // created
1507 // by passing the amount of space requested as an argument of type
1508 // std::size_t as the first argument, and the lvalues p1 ... pn as the
1509 // succeeding arguments. Otherwise, overload resolution is performed again
1510 // on a function call created by passing just the amount of space required as
1511 // an argument of type std::size_t.
1512 //
1513 // So within the proposed change in P2014RO, the priority order of aligned
1514 // allocation functions wiht promise_type is:
1515 //
1516 // void* operator new( std::size_t, std::align_val_t, placement_args... );
1517 // void* operator new( std::size_t, std::align_val_t);
1518 // void* operator new( std::size_t, placement_args... );
1519 // void* operator new( std::size_t);
1520
1521 // Helper variable to emit warnings.
1522 bool FoundNonAlignedInPromise = false;
1523 if (PromiseContainsNew && S.getLangOpts().CoroAlignedAllocation)
1524 if (!OperatorNew || !isAlignedAllocation(IAP.PassAlignment)) {
1525 FoundNonAlignedInPromise = OperatorNew;
1526
1527 LookupAllocationFunction(/*NewScope*/ AllocationFunctionScope::Class,
1528 /*WithoutPlacementArgs*/ false,
1529 /*ForceNonAligned*/ true);
1530
1531 if (!OperatorNew && !PlacementArgs.empty())
1532 LookupAllocationFunction(/*NewScope*/ AllocationFunctionScope::Class,
1533 /*WithoutPlacementArgs*/ true,
1534 /*ForceNonAligned*/ true);
1535 }
1536
1537 bool IsGlobalOverload =
1538 OperatorNew && !isa<CXXRecordDecl>(OperatorNew->getDeclContext());
1539 // If we didn't find a class-local new declaration and non-throwing new
1540 // was is required then we need to lookup the non-throwing global operator
1541 // instead.
1542 if (RequiresNoThrowAlloc && (!OperatorNew || IsGlobalOverload)) {
1543 auto *StdNoThrow = buildStdNoThrowDeclRef(S, Loc);
1544 if (!StdNoThrow)
1545 return false;
1546 PlacementArgs = {StdNoThrow};
1547 OperatorNew = nullptr;
1548 LookupAllocationFunction(AllocationFunctionScope::Global);
1549 }
1550
1551 // If we found a non-aligned allocation function in the promise_type,
1552 // it indicates the user forgot to update the allocation function. Let's emit
1553 // a warning here.
1554 if (FoundNonAlignedInPromise) {
1555 S.Diag(OperatorNew->getLocation(),
1556 diag::warn_non_aligned_allocation_function)
1557 << &FD;
1558 }
1559
1560 if (!OperatorNew) {
1561 if (PromiseContainsNew) {
1562 S.Diag(Loc, diag::err_coroutine_unusable_new) << PromiseType << &FD;
1564 S, Loc, diag::note_coroutine_unusable_type_aware_allocators, NewName,
1565 PromiseType);
1566 } else if (RequiresNoThrowAlloc)
1567 S.Diag(Loc, diag::err_coroutine_unfound_nothrow_new)
1568 << &FD << S.getLangOpts().CoroAlignedAllocation;
1569
1570 return false;
1571 }
1572 assert(!OperatorNew->isTypeAwareOperatorNewOrDelete());
1573
1575 diag::warn_coroutine_type_aware_allocator_ignored,
1576 NewName, PromiseType);
1577
1578 if (RequiresNoThrowAlloc) {
1579 const auto *FT = OperatorNew->getType()->castAs<FunctionProtoType>();
1580 if (!FT->isNothrow(/*ResultIfDependent*/ false)) {
1581 S.Diag(OperatorNew->getLocation(),
1582 diag::err_coroutine_promise_new_requires_nothrow)
1583 << OperatorNew;
1584 S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
1585 << OperatorNew;
1586 return false;
1587 }
1588 }
1589
1590 FunctionDecl *OperatorDelete = nullptr;
1591 if (!findDeleteForPromise(S, Loc, PromiseType, OperatorDelete)) {
1592 // FIXME: We should add an error here. According to:
1593 // [dcl.fct.def.coroutine]p12
1594 // If no usual deallocation function is found, the program is ill-formed.
1595 return false;
1596 }
1597
1598 assert(!OperatorDelete->isTypeAwareOperatorNewOrDelete());
1599
1600 Expr *FramePtr =
1601 S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_frame, {});
1602
1603 Expr *FrameSize =
1604 S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_size, {});
1605
1606 Expr *FrameAlignment = nullptr;
1607
1608 if (S.getLangOpts().CoroAlignedAllocation) {
1609 FrameAlignment =
1610 S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_align, {});
1611
1612 TypeSourceInfo *AlignValTy = getTypeSourceInfoForStdAlignValT(S, Loc);
1613 if (!AlignValTy)
1614 return false;
1615
1616 FrameAlignment = S.BuildCXXNamedCast(Loc, tok::kw_static_cast, AlignValTy,
1617 FrameAlignment, SourceRange(Loc, Loc),
1618 SourceRange(Loc, Loc))
1619 .get();
1620 }
1621
1622 // Make new call.
1623 ExprResult NewRef =
1624 S.BuildDeclRefExpr(OperatorNew, OperatorNew->getType(), VK_LValue, Loc);
1625 if (NewRef.isInvalid())
1626 return false;
1627
1628 SmallVector<Expr *, 2> NewArgs(1, FrameSize);
1629 if (S.getLangOpts().CoroAlignedAllocation &&
1630 isAlignedAllocation(IAP.PassAlignment))
1631 NewArgs.push_back(FrameAlignment);
1632
1633 if (OperatorNew->getNumParams() > NewArgs.size())
1634 llvm::append_range(NewArgs, PlacementArgs);
1635
1636 ExprResult NewExpr =
1637 S.BuildCallExpr(S.getCurScope(), NewRef.get(), Loc, NewArgs, Loc);
1638 NewExpr = S.ActOnFinishFullExpr(NewExpr.get(), /*DiscardedValue*/ false);
1639 if (NewExpr.isInvalid())
1640 return false;
1641
1642 // Make delete call.
1643
1644 QualType OpDeleteQualType = OperatorDelete->getType();
1645
1646 ExprResult DeleteRef =
1647 S.BuildDeclRefExpr(OperatorDelete, OpDeleteQualType, VK_LValue, Loc);
1648 if (DeleteRef.isInvalid())
1649 return false;
1650
1651 Expr *CoroFree =
1652 S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_free, {FramePtr});
1653
1654 SmallVector<Expr *, 2> DeleteArgs{CoroFree};
1655
1656 // [dcl.fct.def.coroutine]p12
1657 // The selected deallocation function shall be called with the address of
1658 // the block of storage to be reclaimed as its first argument. If a
1659 // deallocation function with a parameter of type std::size_t is
1660 // used, the size of the block is passed as the corresponding argument.
1661 const auto *OpDeleteType =
1662 OpDeleteQualType.getTypePtr()->castAs<FunctionProtoType>();
1663 if (OpDeleteType->getNumParams() > DeleteArgs.size() &&
1664 S.getASTContext().hasSameUnqualifiedType(
1665 OpDeleteType->getParamType(DeleteArgs.size()), FrameSize->getType()))
1666 DeleteArgs.push_back(FrameSize);
1667
1668 // Proposed Change of [dcl.fct.def.coroutine]p12 in P2014R0:
1669 // If deallocation function lookup finds a usual deallocation function with
1670 // a pointer parameter, size parameter and alignment parameter then this
1671 // will be the selected deallocation function, otherwise if lookup finds a
1672 // usual deallocation function with both a pointer parameter and a size
1673 // parameter, then this will be the selected deallocation function.
1674 // Otherwise, if lookup finds a usual deallocation function with only a
1675 // pointer parameter, then this will be the selected deallocation
1676 // function.
1677 //
1678 // So we are not forced to pass alignment to the deallocation function.
1679 if (S.getLangOpts().CoroAlignedAllocation &&
1680 OpDeleteType->getNumParams() > DeleteArgs.size() &&
1681 S.getASTContext().hasSameUnqualifiedType(
1682 OpDeleteType->getParamType(DeleteArgs.size()),
1683 FrameAlignment->getType()))
1684 DeleteArgs.push_back(FrameAlignment);
1685
1686 ExprResult DeleteExpr =
1687 S.BuildCallExpr(S.getCurScope(), DeleteRef.get(), Loc, DeleteArgs, Loc);
1688 DeleteExpr =
1689 S.ActOnFinishFullExpr(DeleteExpr.get(), /*DiscardedValue*/ false);
1690 if (DeleteExpr.isInvalid())
1691 return false;
1692
1693 this->Allocate = NewExpr.get();
1694 this->Deallocate = DeleteExpr.get();
1695
1696 return true;
1697}
1698
1699bool CoroutineStmtBuilder::makeOnFallthrough() {
1700 assert(!IsPromiseDependentType &&
1701 "cannot make statement while the promise type is dependent");
1702
1703 // [dcl.fct.def.coroutine]/p6
1704 // If searches for the names return_void and return_value in the scope of
1705 // the promise type each find any declarations, the program is ill-formed.
1706 // [Note 1: If return_void is found, flowing off the end of a coroutine is
1707 // equivalent to a co_return with no operand. Otherwise, flowing off the end
1708 // of a coroutine results in undefined behavior ([stmt.return.coroutine]). —
1709 // end note]
1710 bool HasRVoid, HasRValue;
1711 LookupResult LRVoid =
1712 lookupMember(S, "return_void", PromiseRecordDecl, Loc, HasRVoid);
1713 LookupResult LRValue =
1714 lookupMember(S, "return_value", PromiseRecordDecl, Loc, HasRValue);
1715
1716 StmtResult Fallthrough;
1717 if (HasRVoid && HasRValue) {
1718 // FIXME Improve this diagnostic
1719 S.Diag(FD.getLocation(),
1720 diag::err_coroutine_promise_incompatible_return_functions)
1721 << PromiseRecordDecl;
1722 S.Diag(LRVoid.getRepresentativeDecl()->getLocation(),
1723 diag::note_member_first_declared_here)
1724 << LRVoid.getLookupName();
1725 S.Diag(LRValue.getRepresentativeDecl()->getLocation(),
1726 diag::note_member_first_declared_here)
1727 << LRValue.getLookupName();
1728 return false;
1729 } else if (!HasRVoid && !HasRValue) {
1730 // We need to set 'Fallthrough'. Otherwise the other analysis part might
1731 // think the coroutine has defined a return_value method. So it might emit
1732 // **false** positive warning. e.g.,
1733 //
1734 // promise_without_return_func foo() {
1735 // co_await something();
1736 // }
1737 //
1738 // Then AnalysisBasedWarning would emit a warning about `foo()` lacking a
1739 // co_return statements, which isn't correct.
1740 Fallthrough = S.ActOnNullStmt(PromiseRecordDecl->getLocation());
1741 if (Fallthrough.isInvalid())
1742 return false;
1743 } else if (HasRVoid) {
1744 Fallthrough = S.BuildCoreturnStmt(FD.getLocation(), nullptr,
1745 /*IsImplicit=*/true);
1746 Fallthrough = S.ActOnFinishFullStmt(Fallthrough.get());
1747 if (Fallthrough.isInvalid())
1748 return false;
1749 }
1750
1751 this->OnFallthrough = Fallthrough.get();
1752 return true;
1753}
1754
1755bool CoroutineStmtBuilder::makeOnException() {
1756 // Try to form 'p.unhandled_exception();'
1757 assert(!IsPromiseDependentType &&
1758 "cannot make statement while the promise type is dependent");
1759
1760 const bool RequireUnhandledException = S.getLangOpts().CXXExceptions;
1761
1762 if (!lookupMember(S, "unhandled_exception", PromiseRecordDecl, Loc)) {
1763 auto DiagID =
1764 RequireUnhandledException
1765 ? diag::err_coroutine_promise_unhandled_exception_required
1766 : diag::
1767 warn_coroutine_promise_unhandled_exception_required_with_exceptions;
1768 S.Diag(Loc, DiagID) << PromiseRecordDecl;
1769 S.Diag(PromiseRecordDecl->getLocation(), diag::note_defined_here)
1770 << PromiseRecordDecl;
1771 return !RequireUnhandledException;
1772 }
1773
1774 // If exceptions are disabled, don't try to build OnException.
1775 if (!S.getLangOpts().CXXExceptions)
1776 return true;
1777
1778 ExprResult UnhandledException =
1779 buildPromiseCall(S, Fn.CoroutinePromise, Loc, "unhandled_exception", {});
1780 UnhandledException = S.ActOnFinishFullExpr(UnhandledException.get(), Loc,
1781 /*DiscardedValue*/ false);
1782 if (UnhandledException.isInvalid())
1783 return false;
1784
1785 // Since the body of the coroutine will be wrapped in try-catch, it will
1786 // be incompatible with SEH __try if present in a function.
1787 if (!S.getLangOpts().Borland && Fn.FirstSEHTryLoc.isValid()) {
1788 S.Diag(Fn.FirstSEHTryLoc, diag::err_seh_in_a_coroutine_with_cxx_exceptions);
1789 S.Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
1790 << Fn.getFirstCoroutineStmtKeyword();
1791 return false;
1792 }
1793
1794 this->OnException = UnhandledException.get();
1795 return true;
1796}
1797
1798bool CoroutineStmtBuilder::makeReturnObject() {
1799 // [dcl.fct.def.coroutine]p7
1800 // The expression promise.get_return_object() is used to initialize the
1801 // returned reference or prvalue result object of a call to a coroutine.
1802 ExprResult ReturnObject =
1803 buildPromiseCall(S, Fn.CoroutinePromise, Loc, "get_return_object", {});
1804 if (ReturnObject.isInvalid())
1805 return false;
1806
1807 this->ReturnValue = ReturnObject.get();
1808 return true;
1809}
1810
1812 if (auto *MbrRef = dyn_cast<CXXMemberCallExpr>(E)) {
1813 auto *MethodDecl = MbrRef->getMethodDecl();
1814 S.Diag(MethodDecl->getLocation(), diag::note_member_declared_here)
1815 << MethodDecl;
1816 }
1817 S.Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
1818 << Fn.getFirstCoroutineStmtKeyword();
1819}
1820
1821bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() {
1822 assert(!IsPromiseDependentType &&
1823 "cannot make statement while the promise type is dependent");
1824 assert(this->ReturnValue && "ReturnValue must be already formed");
1825
1826 QualType const GroType = this->ReturnValue->getType();
1827 assert(!GroType->isDependentType() &&
1828 "get_return_object type must no longer be dependent");
1829
1830 QualType const FnRetType = FD.getReturnType();
1831 assert(!FnRetType->isDependentType() &&
1832 "get_return_object type must no longer be dependent");
1833
1834 // The call to get_­return_­object is sequenced before the call to
1835 // initial_­suspend and is invoked at most once, but there are caveats
1836 // regarding on whether the prvalue result object may be initialized
1837 // directly/eager or delayed, depending on the types involved.
1838 //
1839 // More info at https://github.com/cplusplus/papers/issues/1414
1840 bool GroMatchesRetType = S.getASTContext().hasSameType(GroType, FnRetType);
1841
1842 if (FnRetType->isVoidType()) {
1843 ExprResult Res =
1844 S.ActOnFinishFullExpr(this->ReturnValue, Loc, /*DiscardedValue*/ false);
1845 if (Res.isInvalid())
1846 return false;
1847
1848 if (!GroMatchesRetType)
1849 this->ResultDecl = Res.get();
1850 return true;
1851 }
1852
1853 if (GroType->isVoidType()) {
1854 // Trigger a nice error message.
1855 InitializedEntity Entity =
1857 S.PerformCopyInitialization(Entity, SourceLocation(), ReturnValue);
1859 return false;
1860 }
1861
1863 clang::VarDecl *GroDecl = nullptr;
1864 if (GroMatchesRetType) {
1865 ReturnStmt = S.BuildReturnStmt(Loc, ReturnValue);
1866 } else {
1867 GroDecl = VarDecl::Create(
1868 S.Context, &FD, FD.getLocation(), FD.getLocation(),
1869 &S.PP.getIdentifierTable().get("__coro_gro"), GroType,
1870 S.Context.getTrivialTypeSourceInfo(GroType, Loc), SC_None);
1871 GroDecl->setImplicit();
1872
1873 S.CheckVariableDeclarationType(GroDecl);
1874 if (GroDecl->isInvalidDecl())
1875 return false;
1876
1877 InitializedEntity Entity = InitializedEntity::InitializeVariable(GroDecl);
1878 ExprResult Res =
1879 S.PerformCopyInitialization(Entity, SourceLocation(), ReturnValue);
1880 if (Res.isInvalid())
1881 return false;
1882
1883 Res = S.ActOnFinishFullExpr(Res.get(), /*DiscardedValue*/ false);
1884 if (Res.isInvalid())
1885 return false;
1886
1887 S.AddInitializerToDecl(GroDecl, Res.get(),
1888 /*DirectInit=*/false);
1889
1890 S.FinalizeDeclaration(GroDecl);
1891
1892 // Form a declaration statement for the return declaration, so that AST
1893 // visitors can more easily find it.
1894 StmtResult GroDeclStmt =
1895 S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(GroDecl), Loc, Loc);
1896 if (GroDeclStmt.isInvalid())
1897 return false;
1898
1899 this->ResultDecl = GroDeclStmt.get();
1900
1901 ExprResult declRef = S.BuildDeclRefExpr(GroDecl, GroType, VK_LValue, Loc);
1902 if (declRef.isInvalid())
1903 return false;
1904
1905 ReturnStmt = S.BuildReturnStmt(Loc, declRef.get());
1906 }
1907
1908 if (ReturnStmt.isInvalid()) {
1910 return false;
1911 }
1912
1913 if (!GroMatchesRetType &&
1914 cast<clang::ReturnStmt>(ReturnStmt.get())->getNRVOCandidate() == GroDecl)
1915 GroDecl->setNRVOVariable(true);
1916
1917 this->ReturnStmt = ReturnStmt.get();
1918 return true;
1919}
1920
1921// Create a static_cast<T&&>(expr).
1923 if (T.isNull())
1924 T = E->getType();
1925 QualType TargetType = S.BuildReferenceType(
1926 T, /*SpelledAsLValue*/ false, SourceLocation(), DeclarationName());
1927 SourceLocation ExprLoc = E->getBeginLoc();
1928 TypeSourceInfo *TargetLoc =
1929 S.Context.getTrivialTypeSourceInfo(TargetType, ExprLoc);
1930
1931 return S
1932 .BuildCXXNamedCast(ExprLoc, tok::kw_static_cast, TargetLoc, E,
1933 SourceRange(ExprLoc, ExprLoc), E->getSourceRange())
1934 .get();
1935}
1936
1937/// Build a variable declaration for move parameter.
1939 IdentifierInfo *II) {
1941 VarDecl *Decl = VarDecl::Create(S.Context, S.CurContext, Loc, Loc, II, Type,
1942 TInfo, SC_None);
1943 Decl->setImplicit();
1944 return Decl;
1945}
1946
1947// Build statements that move coroutine function parameters to the coroutine
1948// frame, and store them on the function scope info.
1950 assert(isa<FunctionDecl>(CurContext) && "not in a function scope");
1951 auto *FD = cast<FunctionDecl>(CurContext);
1952
1953 auto *ScopeInfo = getCurFunction();
1954 if (!ScopeInfo->CoroutineParameterMoves.empty())
1955 return false;
1956
1957 // [dcl.fct.def.coroutine]p13
1958 // When a coroutine is invoked, after initializing its parameters
1959 // ([expr.call]), a copy is created for each coroutine parameter. For a
1960 // parameter of type cv T, the copy is a variable of type cv T with
1961 // automatic storage duration that is direct-initialized from an xvalue of
1962 // type T referring to the parameter.
1963 for (auto *PD : FD->parameters()) {
1964 if (PD->getType()->isDependentType())
1965 continue;
1966
1967 // Preserve the referenced state for unused parameter diagnostics.
1968 bool DeclReferenced = PD->isReferenced();
1969
1970 ExprResult PDRefExpr =
1971 BuildDeclRefExpr(PD, PD->getType().getNonReferenceType(),
1972 ExprValueKind::VK_LValue, Loc); // FIXME: scope?
1973
1974 PD->setReferenced(DeclReferenced);
1975
1976 if (PDRefExpr.isInvalid())
1977 return false;
1978
1979 Expr *CExpr = nullptr;
1980 if (PD->getType()->getAsCXXRecordDecl() ||
1981 PD->getType()->isRValueReferenceType())
1982 CExpr = castForMoving(*this, PDRefExpr.get());
1983 else
1984 CExpr = PDRefExpr.get();
1985 // [dcl.fct.def.coroutine]p13
1986 // The initialization and destruction of each parameter copy occurs in the
1987 // context of the called coroutine.
1988 auto *D = buildVarDecl(*this, Loc, PD->getType(), PD->getIdentifier());
1989 AddInitializerToDecl(D, CExpr, /*DirectInit=*/true);
1990
1991 // Convert decl to a statement.
1993 if (Stmt.isInvalid())
1994 return false;
1995
1996 ScopeInfo->CoroutineParameterMoves.insert(std::make_pair(PD, Stmt.get()));
1997 }
1998 return true;
1999}
2000
2003 if (!Res)
2004 return StmtError();
2005 return Res;
2006}
2007
2009 SourceLocation FuncLoc) {
2012
2013 IdentifierInfo const &TraitIdent =
2014 PP.getIdentifierTable().get("coroutine_traits");
2015
2016 NamespaceDecl *StdSpace = getStdNamespace();
2017 LookupResult Result(*this, &TraitIdent, FuncLoc, LookupOrdinaryName);
2018 bool Found = StdSpace && LookupQualifiedName(Result, StdSpace);
2019
2020 if (!Found) {
2021 // The goggles, we found nothing!
2022 Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
2023 << "std::coroutine_traits";
2024 return nullptr;
2025 }
2026
2027 // coroutine_traits is required to be a class template.
2030 Result.suppressDiagnostics();
2031 NamedDecl *Found = *Result.begin();
2032 Diag(Found->getLocation(), diag::err_malformed_std_coroutine_traits);
2033 return nullptr;
2034 }
2035
2037}
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:188
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:741
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:4486
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Expr.h:4506
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:2879
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition Expr.h:3062
Decl * getCalleeDecl()
Definition Expr.h:3056
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:5363
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:390
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:5444
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:156
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
Definition DeclBase.cpp:251
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:830
Represents a 'co_await' expression while the type of the promise is dependent.
Definition ExprCXX.h:5395
RAII object that enters a new function expression evaluation context.
Represents an enum.
Definition Decl.h:4004
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:1999
bool isNoReturn() const
Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...
Definition Decl.cpp:3592
ArrayRef< ParmVarDecl * > parameters() const
Definition Decl.h:2771
bool isTypeAwareOperatorNewOrDelete() const
Determine whether this is a type aware operator new or delete.
Definition Decl.cpp:3547
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5264
ArrayRef< QualType > getParamTypes() const
Definition TypeBase.h:5549
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Definition TypeBase.h:5698
QualType getReturnType() const
Definition TypeBase.h:4800
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:273
Represent a C++ namespace.
Definition Decl.h:591
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:1180
decls_iterator decls_begin() const
Definition ExprCXX.h:3215
decls_iterator decls_end() const
Definition ExprCXX.h:3218
static ParenListExpr * Create(const ASTContext &Ctx, SourceLocation LParenLoc, ArrayRef< Expr * > Exprs, SourceLocation RParenLoc)
Create a paren list.
Definition Expr.cpp:4810
Represents a parameter to a function.
Definition Decl.h:1789
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:8285
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:8470
QualType getCanonicalType() const
Definition TypeBase.h:8337
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, bool DeferHint=false)
Emit a diagnostic.
Definition SemaBase.cpp:61
Expr * get() const
Definition Sema.h:7724
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:854
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:9288
@ LookupOperatorName
Look up of an operator name (e.g., operator+) for use with operator overloading.
Definition Sema.h:9300
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
Definition Sema.h:9296
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:6889
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:1647
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:3148
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:6922
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:1418
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:8129
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:6705
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:7745
NamespaceDecl * getStdNamespace() const
friend class InitializationSequence
Definition Sema.h:1560
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.
FunctionDecl * FindUsualDeallocationFunction(SourceLocation StartLoc, ImplicitDeallocationParameters, DeclarationName Name)
ExprResult ActOnCXXThis(SourceLocation Loc)
static CanThrowResult canCalleeThrow(Sema &S, const Expr *E, const Decl *D, SourceLocation Loc=SourceLocation())
Determine whether the callee of a particular function call can throw.
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
Definition Sema.h:8606
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:295
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition Stmt.cpp:334
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Stmt.cpp:346
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:3510
A container of type source information.
Definition TypeBase.h:8256
The base class of the type hierarchy.
Definition TypeBase.h:1833
bool isVoidType() const
Definition TypeBase.h:8878
bool isBooleanType() const
Definition TypeBase.h:9008
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:9168
bool isReferenceType() const
Definition TypeBase.h:8546
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:8649
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
Definition ExprCXX.h:3384
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:722
Represents a variable declaration or definition.
Definition Decl.h:925
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:933
void setNRVOVariable(bool NRVO)
Definition Decl.h:1514
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:5884
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