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