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