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