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