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