1 //===--- SemaCoroutines.cpp - Semantic Analysis for Coroutines ------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements semantic analysis for C++ Coroutines. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "CoroutineStmtBuilder.h" 15 #include "clang/AST/ASTLambda.h" 16 #include "clang/AST/Decl.h" 17 #include "clang/AST/ExprCXX.h" 18 #include "clang/AST/StmtCXX.h" 19 #include "clang/Lex/Preprocessor.h" 20 #include "clang/Sema/Initialization.h" 21 #include "clang/Sema/Overload.h" 22 #include "clang/Sema/SemaInternal.h" 23 24 using namespace clang; 25 using namespace sema; 26 27 static LookupResult lookupMember(Sema &S, const char *Name, CXXRecordDecl *RD, 28 SourceLocation Loc, bool &Res) { 29 DeclarationName DN = S.PP.getIdentifierInfo(Name); 30 LookupResult LR(S, DN, Loc, Sema::LookupMemberName); 31 // Suppress diagnostics when a private member is selected. The same warnings 32 // will be produced again when building the call. 33 LR.suppressDiagnostics(); 34 Res = S.LookupQualifiedName(LR, RD); 35 return LR; 36 } 37 38 static bool lookupMember(Sema &S, const char *Name, CXXRecordDecl *RD, 39 SourceLocation Loc) { 40 bool Res; 41 lookupMember(S, Name, RD, Loc, Res); 42 return Res; 43 } 44 45 /// Look up the std::coroutine_traits<...>::promise_type for the given 46 /// function type. 47 static QualType lookupPromiseType(Sema &S, const FunctionDecl *FD, 48 SourceLocation KwLoc) { 49 const FunctionProtoType *FnType = FD->getType()->castAs<FunctionProtoType>(); 50 const SourceLocation FuncLoc = FD->getLocation(); 51 // FIXME: Cache std::coroutine_traits once we've found it. 52 NamespaceDecl *StdExp = S.lookupStdExperimentalNamespace(); 53 if (!StdExp) { 54 S.Diag(KwLoc, diag::err_implied_coroutine_type_not_found) 55 << "std::experimental::coroutine_traits"; 56 return QualType(); 57 } 58 59 LookupResult Result(S, &S.PP.getIdentifierTable().get("coroutine_traits"), 60 FuncLoc, Sema::LookupOrdinaryName); 61 if (!S.LookupQualifiedName(Result, StdExp)) { 62 S.Diag(KwLoc, diag::err_implied_coroutine_type_not_found) 63 << "std::experimental::coroutine_traits"; 64 return QualType(); 65 } 66 67 ClassTemplateDecl *CoroTraits = Result.getAsSingle<ClassTemplateDecl>(); 68 if (!CoroTraits) { 69 Result.suppressDiagnostics(); 70 // We found something weird. Complain about the first thing we found. 71 NamedDecl *Found = *Result.begin(); 72 S.Diag(Found->getLocation(), diag::err_malformed_std_coroutine_traits); 73 return QualType(); 74 } 75 76 // Form template argument list for coroutine_traits<R, P1, P2, ...> according 77 // to [dcl.fct.def.coroutine]3 78 TemplateArgumentListInfo Args(KwLoc, KwLoc); 79 auto AddArg = [&](QualType T) { 80 Args.addArgument(TemplateArgumentLoc( 81 TemplateArgument(T), S.Context.getTrivialTypeSourceInfo(T, KwLoc))); 82 }; 83 AddArg(FnType->getReturnType()); 84 // If the function is a non-static member function, add the type 85 // of the implicit object parameter before the formal parameters. 86 if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) { 87 if (MD->isInstance()) { 88 // [over.match.funcs]4 89 // For non-static member functions, the type of the implicit object 90 // parameter is 91 // -- "lvalue reference to cv X" for functions declared without a 92 // ref-qualifier or with the & ref-qualifier 93 // -- "rvalue reference to cv X" for functions declared with the && 94 // ref-qualifier 95 QualType T = 96 MD->getThisType(S.Context)->getAs<PointerType>()->getPointeeType(); 97 T = FnType->getRefQualifier() == RQ_RValue 98 ? S.Context.getRValueReferenceType(T) 99 : S.Context.getLValueReferenceType(T, /*SpelledAsLValue*/ true); 100 AddArg(T); 101 } 102 } 103 for (QualType T : FnType->getParamTypes()) 104 AddArg(T); 105 106 // Build the template-id. 107 QualType CoroTrait = 108 S.CheckTemplateIdType(TemplateName(CoroTraits), KwLoc, Args); 109 if (CoroTrait.isNull()) 110 return QualType(); 111 if (S.RequireCompleteType(KwLoc, CoroTrait, 112 diag::err_coroutine_type_missing_specialization)) 113 return QualType(); 114 115 auto *RD = CoroTrait->getAsCXXRecordDecl(); 116 assert(RD && "specialization of class template is not a class?"); 117 118 // Look up the ::promise_type member. 119 LookupResult R(S, &S.PP.getIdentifierTable().get("promise_type"), KwLoc, 120 Sema::LookupOrdinaryName); 121 S.LookupQualifiedName(R, RD); 122 auto *Promise = R.getAsSingle<TypeDecl>(); 123 if (!Promise) { 124 S.Diag(FuncLoc, 125 diag::err_implied_std_coroutine_traits_promise_type_not_found) 126 << RD; 127 return QualType(); 128 } 129 // The promise type is required to be a class type. 130 QualType PromiseType = S.Context.getTypeDeclType(Promise); 131 132 auto buildElaboratedType = [&]() { 133 auto *NNS = NestedNameSpecifier::Create(S.Context, nullptr, StdExp); 134 NNS = NestedNameSpecifier::Create(S.Context, NNS, false, 135 CoroTrait.getTypePtr()); 136 return S.Context.getElaboratedType(ETK_None, NNS, PromiseType); 137 }; 138 139 if (!PromiseType->getAsCXXRecordDecl()) { 140 S.Diag(FuncLoc, 141 diag::err_implied_std_coroutine_traits_promise_type_not_class) 142 << buildElaboratedType(); 143 return QualType(); 144 } 145 if (S.RequireCompleteType(FuncLoc, buildElaboratedType(), 146 diag::err_coroutine_promise_type_incomplete)) 147 return QualType(); 148 149 return PromiseType; 150 } 151 152 /// Look up the std::experimental::coroutine_handle<PromiseType>. 153 static QualType lookupCoroutineHandleType(Sema &S, QualType PromiseType, 154 SourceLocation Loc) { 155 if (PromiseType.isNull()) 156 return QualType(); 157 158 NamespaceDecl *StdExp = S.lookupStdExperimentalNamespace(); 159 assert(StdExp && "Should already be diagnosed"); 160 161 LookupResult Result(S, &S.PP.getIdentifierTable().get("coroutine_handle"), 162 Loc, Sema::LookupOrdinaryName); 163 if (!S.LookupQualifiedName(Result, StdExp)) { 164 S.Diag(Loc, diag::err_implied_coroutine_type_not_found) 165 << "std::experimental::coroutine_handle"; 166 return QualType(); 167 } 168 169 ClassTemplateDecl *CoroHandle = Result.getAsSingle<ClassTemplateDecl>(); 170 if (!CoroHandle) { 171 Result.suppressDiagnostics(); 172 // We found something weird. Complain about the first thing we found. 173 NamedDecl *Found = *Result.begin(); 174 S.Diag(Found->getLocation(), diag::err_malformed_std_coroutine_handle); 175 return QualType(); 176 } 177 178 // Form template argument list for coroutine_handle<Promise>. 179 TemplateArgumentListInfo Args(Loc, Loc); 180 Args.addArgument(TemplateArgumentLoc( 181 TemplateArgument(PromiseType), 182 S.Context.getTrivialTypeSourceInfo(PromiseType, Loc))); 183 184 // Build the template-id. 185 QualType CoroHandleType = 186 S.CheckTemplateIdType(TemplateName(CoroHandle), Loc, Args); 187 if (CoroHandleType.isNull()) 188 return QualType(); 189 if (S.RequireCompleteType(Loc, CoroHandleType, 190 diag::err_coroutine_type_missing_specialization)) 191 return QualType(); 192 193 return CoroHandleType; 194 } 195 196 static bool isValidCoroutineContext(Sema &S, SourceLocation Loc, 197 StringRef Keyword) { 198 // 'co_await' and 'co_yield' are not permitted in unevaluated operands. 199 if (S.isUnevaluatedContext()) { 200 S.Diag(Loc, diag::err_coroutine_unevaluated_context) << Keyword; 201 return false; 202 } 203 204 // Any other usage must be within a function. 205 auto *FD = dyn_cast<FunctionDecl>(S.CurContext); 206 if (!FD) { 207 S.Diag(Loc, isa<ObjCMethodDecl>(S.CurContext) 208 ? diag::err_coroutine_objc_method 209 : diag::err_coroutine_outside_function) << Keyword; 210 return false; 211 } 212 213 // An enumeration for mapping the diagnostic type to the correct diagnostic 214 // selection index. 215 enum InvalidFuncDiag { 216 DiagCtor = 0, 217 DiagDtor, 218 DiagCopyAssign, 219 DiagMoveAssign, 220 DiagMain, 221 DiagConstexpr, 222 DiagAutoRet, 223 DiagVarargs, 224 }; 225 bool Diagnosed = false; 226 auto DiagInvalid = [&](InvalidFuncDiag ID) { 227 S.Diag(Loc, diag::err_coroutine_invalid_func_context) << ID << Keyword; 228 Diagnosed = true; 229 return false; 230 }; 231 232 // Diagnose when a constructor, destructor, copy/move assignment operator, 233 // or the function 'main' are declared as a coroutine. 234 auto *MD = dyn_cast<CXXMethodDecl>(FD); 235 if (MD && isa<CXXConstructorDecl>(MD)) 236 return DiagInvalid(DiagCtor); 237 else if (MD && isa<CXXDestructorDecl>(MD)) 238 return DiagInvalid(DiagDtor); 239 else if (MD && MD->isCopyAssignmentOperator()) 240 return DiagInvalid(DiagCopyAssign); 241 else if (MD && MD->isMoveAssignmentOperator()) 242 return DiagInvalid(DiagMoveAssign); 243 else if (FD->isMain()) 244 return DiagInvalid(DiagMain); 245 246 // Emit a diagnostics for each of the following conditions which is not met. 247 if (FD->isConstexpr()) 248 DiagInvalid(DiagConstexpr); 249 if (FD->getReturnType()->isUndeducedType()) 250 DiagInvalid(DiagAutoRet); 251 if (FD->isVariadic()) 252 DiagInvalid(DiagVarargs); 253 254 return !Diagnosed; 255 } 256 257 static ExprResult buildOperatorCoawaitLookupExpr(Sema &SemaRef, Scope *S, 258 SourceLocation Loc) { 259 DeclarationName OpName = 260 SemaRef.Context.DeclarationNames.getCXXOperatorName(OO_Coawait); 261 LookupResult Operators(SemaRef, OpName, SourceLocation(), 262 Sema::LookupOperatorName); 263 SemaRef.LookupName(Operators, S); 264 265 assert(!Operators.isAmbiguous() && "Operator lookup cannot be ambiguous"); 266 const auto &Functions = Operators.asUnresolvedSet(); 267 bool IsOverloaded = 268 Functions.size() > 1 || 269 (Functions.size() == 1 && isa<FunctionTemplateDecl>(*Functions.begin())); 270 Expr *CoawaitOp = UnresolvedLookupExpr::Create( 271 SemaRef.Context, /*NamingClass*/ nullptr, NestedNameSpecifierLoc(), 272 DeclarationNameInfo(OpName, Loc), /*RequiresADL*/ true, IsOverloaded, 273 Functions.begin(), Functions.end()); 274 assert(CoawaitOp); 275 return CoawaitOp; 276 } 277 278 /// Build a call to 'operator co_await' if there is a suitable operator for 279 /// the given expression. 280 static ExprResult buildOperatorCoawaitCall(Sema &SemaRef, SourceLocation Loc, 281 Expr *E, 282 UnresolvedLookupExpr *Lookup) { 283 UnresolvedSet<16> Functions; 284 Functions.append(Lookup->decls_begin(), Lookup->decls_end()); 285 return SemaRef.CreateOverloadedUnaryOp(Loc, UO_Coawait, Functions, E); 286 } 287 288 static ExprResult buildOperatorCoawaitCall(Sema &SemaRef, Scope *S, 289 SourceLocation Loc, Expr *E) { 290 ExprResult R = buildOperatorCoawaitLookupExpr(SemaRef, S, Loc); 291 if (R.isInvalid()) 292 return ExprError(); 293 return buildOperatorCoawaitCall(SemaRef, Loc, E, 294 cast<UnresolvedLookupExpr>(R.get())); 295 } 296 297 static Expr *buildBuiltinCall(Sema &S, SourceLocation Loc, Builtin::ID Id, 298 MultiExprArg CallArgs) { 299 StringRef Name = S.Context.BuiltinInfo.getName(Id); 300 LookupResult R(S, &S.Context.Idents.get(Name), Loc, Sema::LookupOrdinaryName); 301 S.LookupName(R, S.TUScope, /*AllowBuiltinCreation=*/true); 302 303 auto *BuiltInDecl = R.getAsSingle<FunctionDecl>(); 304 assert(BuiltInDecl && "failed to find builtin declaration"); 305 306 ExprResult DeclRef = 307 S.BuildDeclRefExpr(BuiltInDecl, BuiltInDecl->getType(), VK_LValue, Loc); 308 assert(DeclRef.isUsable() && "Builtin reference cannot fail"); 309 310 ExprResult Call = 311 S.ActOnCallExpr(/*Scope=*/nullptr, DeclRef.get(), Loc, CallArgs, Loc); 312 313 assert(!Call.isInvalid() && "Call to builtin cannot fail!"); 314 return Call.get(); 315 } 316 317 static ExprResult buildCoroutineHandle(Sema &S, QualType PromiseType, 318 SourceLocation Loc) { 319 QualType CoroHandleType = lookupCoroutineHandleType(S, PromiseType, Loc); 320 if (CoroHandleType.isNull()) 321 return ExprError(); 322 323 DeclContext *LookupCtx = S.computeDeclContext(CoroHandleType); 324 LookupResult Found(S, &S.PP.getIdentifierTable().get("from_address"), Loc, 325 Sema::LookupOrdinaryName); 326 if (!S.LookupQualifiedName(Found, LookupCtx)) { 327 S.Diag(Loc, diag::err_coroutine_handle_missing_member) 328 << "from_address"; 329 return ExprError(); 330 } 331 332 Expr *FramePtr = 333 buildBuiltinCall(S, Loc, Builtin::BI__builtin_coro_frame, {}); 334 335 CXXScopeSpec SS; 336 ExprResult FromAddr = 337 S.BuildDeclarationNameExpr(SS, Found, /*NeedsADL=*/false); 338 if (FromAddr.isInvalid()) 339 return ExprError(); 340 341 return S.ActOnCallExpr(nullptr, FromAddr.get(), Loc, FramePtr, Loc); 342 } 343 344 struct ReadySuspendResumeResult { 345 enum AwaitCallType { ACT_Ready, ACT_Suspend, ACT_Resume }; 346 Expr *Results[3]; 347 OpaqueValueExpr *OpaqueValue; 348 bool IsInvalid; 349 }; 350 351 static ExprResult buildMemberCall(Sema &S, Expr *Base, SourceLocation Loc, 352 StringRef Name, MultiExprArg Args) { 353 DeclarationNameInfo NameInfo(&S.PP.getIdentifierTable().get(Name), Loc); 354 355 // FIXME: Fix BuildMemberReferenceExpr to take a const CXXScopeSpec&. 356 CXXScopeSpec SS; 357 ExprResult Result = S.BuildMemberReferenceExpr( 358 Base, Base->getType(), Loc, /*IsPtr=*/false, SS, 359 SourceLocation(), nullptr, NameInfo, /*TemplateArgs=*/nullptr, 360 /*Scope=*/nullptr); 361 if (Result.isInvalid()) 362 return ExprError(); 363 364 return S.ActOnCallExpr(nullptr, Result.get(), Loc, Args, Loc, nullptr); 365 } 366 367 // See if return type is coroutine-handle and if so, invoke builtin coro-resume 368 // on its address. This is to enable experimental support for coroutine-handle 369 // returning await_suspend that results in a guranteed tail call to the target 370 // coroutine. 371 static Expr *maybeTailCall(Sema &S, QualType RetType, Expr *E, 372 SourceLocation Loc) { 373 if (RetType->isReferenceType()) 374 return nullptr; 375 Type const *T = RetType.getTypePtr(); 376 if (!T->isClassType() && !T->isStructureType()) 377 return nullptr; 378 379 // FIXME: Add convertability check to coroutine_handle<>. Possibly via 380 // EvaluateBinaryTypeTrait(BTT_IsConvertible, ...) which is at the moment 381 // a private function in SemaExprCXX.cpp 382 383 ExprResult AddressExpr = buildMemberCall(S, E, Loc, "address", None); 384 if (AddressExpr.isInvalid()) 385 return nullptr; 386 387 Expr *JustAddress = AddressExpr.get(); 388 // FIXME: Check that the type of AddressExpr is void* 389 return buildBuiltinCall(S, Loc, Builtin::BI__builtin_coro_resume, 390 JustAddress); 391 } 392 393 /// Build calls to await_ready, await_suspend, and await_resume for a co_await 394 /// expression. 395 static ReadySuspendResumeResult buildCoawaitCalls(Sema &S, VarDecl *CoroPromise, 396 SourceLocation Loc, Expr *E) { 397 OpaqueValueExpr *Operand = new (S.Context) 398 OpaqueValueExpr(Loc, E->getType(), VK_LValue, E->getObjectKind(), E); 399 400 // Assume invalid until we see otherwise. 401 ReadySuspendResumeResult Calls = {{}, Operand, /*IsInvalid=*/true}; 402 403 ExprResult CoroHandleRes = buildCoroutineHandle(S, CoroPromise->getType(), Loc); 404 if (CoroHandleRes.isInvalid()) 405 return Calls; 406 Expr *CoroHandle = CoroHandleRes.get(); 407 408 const StringRef Funcs[] = {"await_ready", "await_suspend", "await_resume"}; 409 MultiExprArg Args[] = {None, CoroHandle, None}; 410 for (size_t I = 0, N = llvm::array_lengthof(Funcs); I != N; ++I) { 411 ExprResult Result = buildMemberCall(S, Operand, Loc, Funcs[I], Args[I]); 412 if (Result.isInvalid()) 413 return Calls; 414 Calls.Results[I] = Result.get(); 415 } 416 417 // Assume the calls are valid; all further checking should make them invalid. 418 Calls.IsInvalid = false; 419 420 using ACT = ReadySuspendResumeResult::AwaitCallType; 421 CallExpr *AwaitReady = cast<CallExpr>(Calls.Results[ACT::ACT_Ready]); 422 if (!AwaitReady->getType()->isDependentType()) { 423 // [expr.await]p3 [...] 424 // — await-ready is the expression e.await_ready(), contextually converted 425 // to bool. 426 ExprResult Conv = S.PerformContextuallyConvertToBool(AwaitReady); 427 if (Conv.isInvalid()) { 428 S.Diag(AwaitReady->getDirectCallee()->getLocStart(), 429 diag::note_await_ready_no_bool_conversion); 430 S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required) 431 << AwaitReady->getDirectCallee() << E->getSourceRange(); 432 Calls.IsInvalid = true; 433 } 434 Calls.Results[ACT::ACT_Ready] = Conv.get(); 435 } 436 CallExpr *AwaitSuspend = cast<CallExpr>(Calls.Results[ACT::ACT_Suspend]); 437 if (!AwaitSuspend->getType()->isDependentType()) { 438 // [expr.await]p3 [...] 439 // - await-suspend is the expression e.await_suspend(h), which shall be 440 // a prvalue of type void or bool. 441 QualType RetType = AwaitSuspend->getCallReturnType(S.Context); 442 443 // Experimental support for coroutine_handle returning await_suspend. 444 if (Expr *TailCallSuspend = maybeTailCall(S, RetType, AwaitSuspend, Loc)) 445 Calls.Results[ACT::ACT_Suspend] = TailCallSuspend; 446 else { 447 // non-class prvalues always have cv-unqualified types 448 if (RetType->isReferenceType() || 449 (!RetType->isBooleanType() && !RetType->isVoidType())) { 450 S.Diag(AwaitSuspend->getCalleeDecl()->getLocation(), 451 diag::err_await_suspend_invalid_return_type) 452 << RetType; 453 S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required) 454 << AwaitSuspend->getDirectCallee(); 455 Calls.IsInvalid = true; 456 } 457 } 458 } 459 460 return Calls; 461 } 462 463 static ExprResult buildPromiseCall(Sema &S, VarDecl *Promise, 464 SourceLocation Loc, StringRef Name, 465 MultiExprArg Args) { 466 467 // Form a reference to the promise. 468 ExprResult PromiseRef = S.BuildDeclRefExpr( 469 Promise, Promise->getType().getNonReferenceType(), VK_LValue, Loc); 470 if (PromiseRef.isInvalid()) 471 return ExprError(); 472 473 return buildMemberCall(S, PromiseRef.get(), Loc, Name, Args); 474 } 475 476 VarDecl *Sema::buildCoroutinePromise(SourceLocation Loc) { 477 assert(isa<FunctionDecl>(CurContext) && "not in a function scope"); 478 auto *FD = cast<FunctionDecl>(CurContext); 479 bool IsThisDependentType = [&] { 480 if (auto *MD = dyn_cast_or_null<CXXMethodDecl>(FD)) 481 return MD->isInstance() && MD->getThisType(Context)->isDependentType(); 482 else 483 return false; 484 }(); 485 486 QualType T = FD->getType()->isDependentType() || IsThisDependentType 487 ? Context.DependentTy 488 : lookupPromiseType(*this, FD, Loc); 489 if (T.isNull()) 490 return nullptr; 491 492 auto *VD = VarDecl::Create(Context, FD, FD->getLocation(), FD->getLocation(), 493 &PP.getIdentifierTable().get("__promise"), T, 494 Context.getTrivialTypeSourceInfo(T, Loc), SC_None); 495 CheckVariableDeclarationType(VD); 496 if (VD->isInvalidDecl()) 497 return nullptr; 498 499 auto *ScopeInfo = getCurFunction(); 500 // Build a list of arguments, based on the coroutine functions arguments, 501 // that will be passed to the promise type's constructor. 502 llvm::SmallVector<Expr *, 4> CtorArgExprs; 503 auto &Moves = ScopeInfo->CoroutineParameterMoves; 504 for (auto *PD : FD->parameters()) { 505 if (PD->getType()->isDependentType()) 506 continue; 507 508 auto RefExpr = ExprEmpty(); 509 auto Move = Moves.find(PD); 510 assert(Move != Moves.end() && 511 "Coroutine function parameter not inserted into move map"); 512 // If a reference to the function parameter exists in the coroutine 513 // frame, use that reference. 514 auto *MoveDecl = 515 cast<VarDecl>(cast<DeclStmt>(Move->second)->getSingleDecl()); 516 RefExpr = 517 BuildDeclRefExpr(MoveDecl, MoveDecl->getType().getNonReferenceType(), 518 ExprValueKind::VK_LValue, FD->getLocation()); 519 if (RefExpr.isInvalid()) 520 return nullptr; 521 CtorArgExprs.push_back(RefExpr.get()); 522 } 523 524 // Create an initialization sequence for the promise type using the 525 // constructor arguments, wrapped in a parenthesized list expression. 526 Expr *PLE = new (Context) ParenListExpr(Context, FD->getLocation(), 527 CtorArgExprs, FD->getLocation()); 528 InitializedEntity Entity = InitializedEntity::InitializeVariable(VD); 529 InitializationKind Kind = InitializationKind::CreateForInit( 530 VD->getLocation(), /*DirectInit=*/true, PLE); 531 InitializationSequence InitSeq(*this, Entity, Kind, CtorArgExprs, 532 /*TopLevelOfInitList=*/false, 533 /*TreatUnavailableAsInvalid=*/false); 534 535 // Attempt to initialize the promise type with the arguments. 536 // If that fails, fall back to the promise type's default constructor. 537 if (InitSeq) { 538 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, CtorArgExprs); 539 if (Result.isInvalid()) { 540 VD->setInvalidDecl(); 541 } else if (Result.get()) { 542 VD->setInit(MaybeCreateExprWithCleanups(Result.get())); 543 VD->setInitStyle(VarDecl::CallInit); 544 CheckCompleteVariableDeclaration(VD); 545 } 546 } else 547 ActOnUninitializedDecl(VD); 548 549 FD->addDecl(VD); 550 return VD; 551 } 552 553 /// Check that this is a context in which a coroutine suspension can appear. 554 static FunctionScopeInfo *checkCoroutineContext(Sema &S, SourceLocation Loc, 555 StringRef Keyword, 556 bool IsImplicit = false) { 557 if (!isValidCoroutineContext(S, Loc, Keyword)) 558 return nullptr; 559 560 assert(isa<FunctionDecl>(S.CurContext) && "not in a function scope"); 561 562 auto *ScopeInfo = S.getCurFunction(); 563 assert(ScopeInfo && "missing function scope for function"); 564 565 if (ScopeInfo->FirstCoroutineStmtLoc.isInvalid() && !IsImplicit) 566 ScopeInfo->setFirstCoroutineStmt(Loc, Keyword); 567 568 if (ScopeInfo->CoroutinePromise) 569 return ScopeInfo; 570 571 if (!S.buildCoroutineParameterMoves(Loc)) 572 return nullptr; 573 574 ScopeInfo->CoroutinePromise = S.buildCoroutinePromise(Loc); 575 if (!ScopeInfo->CoroutinePromise) 576 return nullptr; 577 578 return ScopeInfo; 579 } 580 581 bool Sema::ActOnCoroutineBodyStart(Scope *SC, SourceLocation KWLoc, 582 StringRef Keyword) { 583 if (!checkCoroutineContext(*this, KWLoc, Keyword)) 584 return false; 585 auto *ScopeInfo = getCurFunction(); 586 assert(ScopeInfo->CoroutinePromise); 587 588 // If we have existing coroutine statements then we have already built 589 // the initial and final suspend points. 590 if (!ScopeInfo->NeedsCoroutineSuspends) 591 return true; 592 593 ScopeInfo->setNeedsCoroutineSuspends(false); 594 595 auto *Fn = cast<FunctionDecl>(CurContext); 596 SourceLocation Loc = Fn->getLocation(); 597 // Build the initial suspend point 598 auto buildSuspends = [&](StringRef Name) mutable -> StmtResult { 599 ExprResult Suspend = 600 buildPromiseCall(*this, ScopeInfo->CoroutinePromise, Loc, Name, None); 601 if (Suspend.isInvalid()) 602 return StmtError(); 603 Suspend = buildOperatorCoawaitCall(*this, SC, Loc, Suspend.get()); 604 if (Suspend.isInvalid()) 605 return StmtError(); 606 Suspend = BuildResolvedCoawaitExpr(Loc, Suspend.get(), 607 /*IsImplicit*/ true); 608 Suspend = ActOnFinishFullExpr(Suspend.get()); 609 if (Suspend.isInvalid()) { 610 Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required) 611 << ((Name == "initial_suspend") ? 0 : 1); 612 Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword; 613 return StmtError(); 614 } 615 return cast<Stmt>(Suspend.get()); 616 }; 617 618 StmtResult InitSuspend = buildSuspends("initial_suspend"); 619 if (InitSuspend.isInvalid()) 620 return true; 621 622 StmtResult FinalSuspend = buildSuspends("final_suspend"); 623 if (FinalSuspend.isInvalid()) 624 return true; 625 626 ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get()); 627 628 return true; 629 } 630 631 ExprResult Sema::ActOnCoawaitExpr(Scope *S, SourceLocation Loc, Expr *E) { 632 if (!ActOnCoroutineBodyStart(S, Loc, "co_await")) { 633 CorrectDelayedTyposInExpr(E); 634 return ExprError(); 635 } 636 637 if (E->getType()->isPlaceholderType()) { 638 ExprResult R = CheckPlaceholderExpr(E); 639 if (R.isInvalid()) return ExprError(); 640 E = R.get(); 641 } 642 ExprResult Lookup = buildOperatorCoawaitLookupExpr(*this, S, Loc); 643 if (Lookup.isInvalid()) 644 return ExprError(); 645 return BuildUnresolvedCoawaitExpr(Loc, E, 646 cast<UnresolvedLookupExpr>(Lookup.get())); 647 } 648 649 ExprResult Sema::BuildUnresolvedCoawaitExpr(SourceLocation Loc, Expr *E, 650 UnresolvedLookupExpr *Lookup) { 651 auto *FSI = checkCoroutineContext(*this, Loc, "co_await"); 652 if (!FSI) 653 return ExprError(); 654 655 if (E->getType()->isPlaceholderType()) { 656 ExprResult R = CheckPlaceholderExpr(E); 657 if (R.isInvalid()) 658 return ExprError(); 659 E = R.get(); 660 } 661 662 auto *Promise = FSI->CoroutinePromise; 663 if (Promise->getType()->isDependentType()) { 664 Expr *Res = 665 new (Context) DependentCoawaitExpr(Loc, Context.DependentTy, E, Lookup); 666 return Res; 667 } 668 669 auto *RD = Promise->getType()->getAsCXXRecordDecl(); 670 if (lookupMember(*this, "await_transform", RD, Loc)) { 671 ExprResult R = buildPromiseCall(*this, Promise, Loc, "await_transform", E); 672 if (R.isInvalid()) { 673 Diag(Loc, 674 diag::note_coroutine_promise_implicit_await_transform_required_here) 675 << E->getSourceRange(); 676 return ExprError(); 677 } 678 E = R.get(); 679 } 680 ExprResult Awaitable = buildOperatorCoawaitCall(*this, Loc, E, Lookup); 681 if (Awaitable.isInvalid()) 682 return ExprError(); 683 684 return BuildResolvedCoawaitExpr(Loc, Awaitable.get()); 685 } 686 687 ExprResult Sema::BuildResolvedCoawaitExpr(SourceLocation Loc, Expr *E, 688 bool IsImplicit) { 689 auto *Coroutine = checkCoroutineContext(*this, Loc, "co_await", IsImplicit); 690 if (!Coroutine) 691 return ExprError(); 692 693 if (E->getType()->isPlaceholderType()) { 694 ExprResult R = CheckPlaceholderExpr(E); 695 if (R.isInvalid()) return ExprError(); 696 E = R.get(); 697 } 698 699 if (E->getType()->isDependentType()) { 700 Expr *Res = new (Context) 701 CoawaitExpr(Loc, Context.DependentTy, E, IsImplicit); 702 return Res; 703 } 704 705 // If the expression is a temporary, materialize it as an lvalue so that we 706 // can use it multiple times. 707 if (E->getValueKind() == VK_RValue) 708 E = CreateMaterializeTemporaryExpr(E->getType(), E, true); 709 710 // Build the await_ready, await_suspend, await_resume calls. 711 ReadySuspendResumeResult RSS = 712 buildCoawaitCalls(*this, Coroutine->CoroutinePromise, Loc, E); 713 if (RSS.IsInvalid) 714 return ExprError(); 715 716 Expr *Res = 717 new (Context) CoawaitExpr(Loc, E, RSS.Results[0], RSS.Results[1], 718 RSS.Results[2], RSS.OpaqueValue, IsImplicit); 719 720 return Res; 721 } 722 723 ExprResult Sema::ActOnCoyieldExpr(Scope *S, SourceLocation Loc, Expr *E) { 724 if (!ActOnCoroutineBodyStart(S, Loc, "co_yield")) { 725 CorrectDelayedTyposInExpr(E); 726 return ExprError(); 727 } 728 729 // Build yield_value call. 730 ExprResult Awaitable = buildPromiseCall( 731 *this, getCurFunction()->CoroutinePromise, Loc, "yield_value", E); 732 if (Awaitable.isInvalid()) 733 return ExprError(); 734 735 // Build 'operator co_await' call. 736 Awaitable = buildOperatorCoawaitCall(*this, S, Loc, Awaitable.get()); 737 if (Awaitable.isInvalid()) 738 return ExprError(); 739 740 return BuildCoyieldExpr(Loc, Awaitable.get()); 741 } 742 ExprResult Sema::BuildCoyieldExpr(SourceLocation Loc, Expr *E) { 743 auto *Coroutine = checkCoroutineContext(*this, Loc, "co_yield"); 744 if (!Coroutine) 745 return ExprError(); 746 747 if (E->getType()->isPlaceholderType()) { 748 ExprResult R = CheckPlaceholderExpr(E); 749 if (R.isInvalid()) return ExprError(); 750 E = R.get(); 751 } 752 753 if (E->getType()->isDependentType()) { 754 Expr *Res = new (Context) CoyieldExpr(Loc, Context.DependentTy, E); 755 return Res; 756 } 757 758 // If the expression is a temporary, materialize it as an lvalue so that we 759 // can use it multiple times. 760 if (E->getValueKind() == VK_RValue) 761 E = CreateMaterializeTemporaryExpr(E->getType(), E, true); 762 763 // Build the await_ready, await_suspend, await_resume calls. 764 ReadySuspendResumeResult RSS = 765 buildCoawaitCalls(*this, Coroutine->CoroutinePromise, Loc, E); 766 if (RSS.IsInvalid) 767 return ExprError(); 768 769 Expr *Res = 770 new (Context) CoyieldExpr(Loc, E, RSS.Results[0], RSS.Results[1], 771 RSS.Results[2], RSS.OpaqueValue); 772 773 return Res; 774 } 775 776 StmtResult Sema::ActOnCoreturnStmt(Scope *S, SourceLocation Loc, Expr *E) { 777 if (!ActOnCoroutineBodyStart(S, Loc, "co_return")) { 778 CorrectDelayedTyposInExpr(E); 779 return StmtError(); 780 } 781 return BuildCoreturnStmt(Loc, E); 782 } 783 784 StmtResult Sema::BuildCoreturnStmt(SourceLocation Loc, Expr *E, 785 bool IsImplicit) { 786 auto *FSI = checkCoroutineContext(*this, Loc, "co_return", IsImplicit); 787 if (!FSI) 788 return StmtError(); 789 790 if (E && E->getType()->isPlaceholderType() && 791 !E->getType()->isSpecificPlaceholderType(BuiltinType::Overload)) { 792 ExprResult R = CheckPlaceholderExpr(E); 793 if (R.isInvalid()) return StmtError(); 794 E = R.get(); 795 } 796 797 // FIXME: If the operand is a reference to a variable that's about to go out 798 // of scope, we should treat the operand as an xvalue for this overload 799 // resolution. 800 VarDecl *Promise = FSI->CoroutinePromise; 801 ExprResult PC; 802 if (E && (isa<InitListExpr>(E) || !E->getType()->isVoidType())) { 803 PC = buildPromiseCall(*this, Promise, Loc, "return_value", E); 804 } else { 805 E = MakeFullDiscardedValueExpr(E).get(); 806 PC = buildPromiseCall(*this, Promise, Loc, "return_void", None); 807 } 808 if (PC.isInvalid()) 809 return StmtError(); 810 811 Expr *PCE = ActOnFinishFullExpr(PC.get()).get(); 812 813 Stmt *Res = new (Context) CoreturnStmt(Loc, E, PCE, IsImplicit); 814 return Res; 815 } 816 817 /// Look up the std::nothrow object. 818 static Expr *buildStdNoThrowDeclRef(Sema &S, SourceLocation Loc) { 819 NamespaceDecl *Std = S.getStdNamespace(); 820 assert(Std && "Should already be diagnosed"); 821 822 LookupResult Result(S, &S.PP.getIdentifierTable().get("nothrow"), Loc, 823 Sema::LookupOrdinaryName); 824 if (!S.LookupQualifiedName(Result, Std)) { 825 // FIXME: <experimental/coroutine> should have been included already. 826 // If we require it to include <new> then this diagnostic is no longer 827 // needed. 828 S.Diag(Loc, diag::err_implicit_coroutine_std_nothrow_type_not_found); 829 return nullptr; 830 } 831 832 auto *VD = Result.getAsSingle<VarDecl>(); 833 if (!VD) { 834 Result.suppressDiagnostics(); 835 // We found something weird. Complain about the first thing we found. 836 NamedDecl *Found = *Result.begin(); 837 S.Diag(Found->getLocation(), diag::err_malformed_std_nothrow); 838 return nullptr; 839 } 840 841 ExprResult DR = S.BuildDeclRefExpr(VD, VD->getType(), VK_LValue, Loc); 842 if (DR.isInvalid()) 843 return nullptr; 844 845 return DR.get(); 846 } 847 848 // Find an appropriate delete for the promise. 849 static FunctionDecl *findDeleteForPromise(Sema &S, SourceLocation Loc, 850 QualType PromiseType) { 851 FunctionDecl *OperatorDelete = nullptr; 852 853 DeclarationName DeleteName = 854 S.Context.DeclarationNames.getCXXOperatorName(OO_Delete); 855 856 auto *PointeeRD = PromiseType->getAsCXXRecordDecl(); 857 assert(PointeeRD && "PromiseType must be a CxxRecordDecl type"); 858 859 if (S.FindDeallocationFunction(Loc, PointeeRD, DeleteName, OperatorDelete)) 860 return nullptr; 861 862 if (!OperatorDelete) { 863 // Look for a global declaration. 864 const bool CanProvideSize = S.isCompleteType(Loc, PromiseType); 865 const bool Overaligned = false; 866 OperatorDelete = S.FindUsualDeallocationFunction(Loc, CanProvideSize, 867 Overaligned, DeleteName); 868 } 869 S.MarkFunctionReferenced(Loc, OperatorDelete); 870 return OperatorDelete; 871 } 872 873 874 void Sema::CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body) { 875 FunctionScopeInfo *Fn = getCurFunction(); 876 assert(Fn && Fn->isCoroutine() && "not a coroutine"); 877 if (!Body) { 878 assert(FD->isInvalidDecl() && 879 "a null body is only allowed for invalid declarations"); 880 return; 881 } 882 // We have a function that uses coroutine keywords, but we failed to build 883 // the promise type. 884 if (!Fn->CoroutinePromise) 885 return FD->setInvalidDecl(); 886 887 if (isa<CoroutineBodyStmt>(Body)) { 888 // Nothing todo. the body is already a transformed coroutine body statement. 889 return; 890 } 891 892 // Coroutines [stmt.return]p1: 893 // A return statement shall not appear in a coroutine. 894 if (Fn->FirstReturnLoc.isValid()) { 895 assert(Fn->FirstCoroutineStmtLoc.isValid() && 896 "first coroutine location not set"); 897 Diag(Fn->FirstReturnLoc, diag::err_return_in_coroutine); 898 Diag(Fn->FirstCoroutineStmtLoc, diag::note_declared_coroutine_here) 899 << Fn->getFirstCoroutineStmtKeyword(); 900 } 901 CoroutineStmtBuilder Builder(*this, *FD, *Fn, Body); 902 if (Builder.isInvalid() || !Builder.buildStatements()) 903 return FD->setInvalidDecl(); 904 905 // Build body for the coroutine wrapper statement. 906 Body = CoroutineBodyStmt::Create(Context, Builder); 907 } 908 909 CoroutineStmtBuilder::CoroutineStmtBuilder(Sema &S, FunctionDecl &FD, 910 sema::FunctionScopeInfo &Fn, 911 Stmt *Body) 912 : S(S), FD(FD), Fn(Fn), Loc(FD.getLocation()), 913 IsPromiseDependentType( 914 !Fn.CoroutinePromise || 915 Fn.CoroutinePromise->getType()->isDependentType()) { 916 this->Body = Body; 917 918 for (auto KV : Fn.CoroutineParameterMoves) 919 this->ParamMovesVector.push_back(KV.second); 920 this->ParamMoves = this->ParamMovesVector; 921 922 if (!IsPromiseDependentType) { 923 PromiseRecordDecl = Fn.CoroutinePromise->getType()->getAsCXXRecordDecl(); 924 assert(PromiseRecordDecl && "Type should have already been checked"); 925 } 926 this->IsValid = makePromiseStmt() && makeInitialAndFinalSuspend(); 927 } 928 929 bool CoroutineStmtBuilder::buildStatements() { 930 assert(this->IsValid && "coroutine already invalid"); 931 this->IsValid = makeReturnObject(); 932 if (this->IsValid && !IsPromiseDependentType) 933 buildDependentStatements(); 934 return this->IsValid; 935 } 936 937 bool CoroutineStmtBuilder::buildDependentStatements() { 938 assert(this->IsValid && "coroutine already invalid"); 939 assert(!this->IsPromiseDependentType && 940 "coroutine cannot have a dependent promise type"); 941 this->IsValid = makeOnException() && makeOnFallthrough() && 942 makeGroDeclAndReturnStmt() && makeReturnOnAllocFailure() && 943 makeNewAndDeleteExpr(); 944 return this->IsValid; 945 } 946 947 bool CoroutineStmtBuilder::makePromiseStmt() { 948 // Form a declaration statement for the promise declaration, so that AST 949 // visitors can more easily find it. 950 StmtResult PromiseStmt = 951 S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(Fn.CoroutinePromise), Loc, Loc); 952 if (PromiseStmt.isInvalid()) 953 return false; 954 955 this->Promise = PromiseStmt.get(); 956 return true; 957 } 958 959 bool CoroutineStmtBuilder::makeInitialAndFinalSuspend() { 960 if (Fn.hasInvalidCoroutineSuspends()) 961 return false; 962 this->InitialSuspend = cast<Expr>(Fn.CoroutineSuspends.first); 963 this->FinalSuspend = cast<Expr>(Fn.CoroutineSuspends.second); 964 return true; 965 } 966 967 static bool diagReturnOnAllocFailure(Sema &S, Expr *E, 968 CXXRecordDecl *PromiseRecordDecl, 969 FunctionScopeInfo &Fn) { 970 auto Loc = E->getExprLoc(); 971 if (auto *DeclRef = dyn_cast_or_null<DeclRefExpr>(E)) { 972 auto *Decl = DeclRef->getDecl(); 973 if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(Decl)) { 974 if (Method->isStatic()) 975 return true; 976 else 977 Loc = Decl->getLocation(); 978 } 979 } 980 981 S.Diag( 982 Loc, 983 diag::err_coroutine_promise_get_return_object_on_allocation_failure) 984 << PromiseRecordDecl; 985 S.Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here) 986 << Fn.getFirstCoroutineStmtKeyword(); 987 return false; 988 } 989 990 bool CoroutineStmtBuilder::makeReturnOnAllocFailure() { 991 assert(!IsPromiseDependentType && 992 "cannot make statement while the promise type is dependent"); 993 994 // [dcl.fct.def.coroutine]/8 995 // The unqualified-id get_return_object_on_allocation_failure is looked up in 996 // the scope of class P by class member access lookup (3.4.5). ... 997 // If an allocation function returns nullptr, ... the coroutine return value 998 // is obtained by a call to ... get_return_object_on_allocation_failure(). 999 1000 DeclarationName DN = 1001 S.PP.getIdentifierInfo("get_return_object_on_allocation_failure"); 1002 LookupResult Found(S, DN, Loc, Sema::LookupMemberName); 1003 if (!S.LookupQualifiedName(Found, PromiseRecordDecl)) 1004 return true; 1005 1006 CXXScopeSpec SS; 1007 ExprResult DeclNameExpr = 1008 S.BuildDeclarationNameExpr(SS, Found, /*NeedsADL=*/false); 1009 if (DeclNameExpr.isInvalid()) 1010 return false; 1011 1012 if (!diagReturnOnAllocFailure(S, DeclNameExpr.get(), PromiseRecordDecl, Fn)) 1013 return false; 1014 1015 ExprResult ReturnObjectOnAllocationFailure = 1016 S.ActOnCallExpr(nullptr, DeclNameExpr.get(), Loc, {}, Loc); 1017 if (ReturnObjectOnAllocationFailure.isInvalid()) 1018 return false; 1019 1020 StmtResult ReturnStmt = 1021 S.BuildReturnStmt(Loc, ReturnObjectOnAllocationFailure.get()); 1022 if (ReturnStmt.isInvalid()) { 1023 S.Diag(Found.getFoundDecl()->getLocation(), diag::note_member_declared_here) 1024 << DN; 1025 S.Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here) 1026 << Fn.getFirstCoroutineStmtKeyword(); 1027 return false; 1028 } 1029 1030 this->ReturnStmtOnAllocFailure = ReturnStmt.get(); 1031 return true; 1032 } 1033 1034 bool CoroutineStmtBuilder::makeNewAndDeleteExpr() { 1035 // Form and check allocation and deallocation calls. 1036 assert(!IsPromiseDependentType && 1037 "cannot make statement while the promise type is dependent"); 1038 QualType PromiseType = Fn.CoroutinePromise->getType(); 1039 1040 if (S.RequireCompleteType(Loc, PromiseType, diag::err_incomplete_type)) 1041 return false; 1042 1043 const bool RequiresNoThrowAlloc = ReturnStmtOnAllocFailure != nullptr; 1044 1045 // [dcl.fct.def.coroutine]/7 1046 // Lookup allocation functions using a parameter list composed of the 1047 // requested size of the coroutine state being allocated, followed by 1048 // the coroutine function's arguments. If a matching allocation function 1049 // exists, use it. Otherwise, use an allocation function that just takes 1050 // the requested size. 1051 1052 FunctionDecl *OperatorNew = nullptr; 1053 FunctionDecl *OperatorDelete = nullptr; 1054 FunctionDecl *UnusedResult = nullptr; 1055 bool PassAlignment = false; 1056 SmallVector<Expr *, 1> PlacementArgs; 1057 1058 // [dcl.fct.def.coroutine]/7 1059 // "The allocation function’s name is looked up in the scope of P. 1060 // [...] If the lookup finds an allocation function in the scope of P, 1061 // overload resolution is performed on a function call created by assembling 1062 // an argument list. The first argument is the amount of space requested, 1063 // and has type std::size_t. The lvalues p1 ... pn are the succeeding 1064 // arguments." 1065 // 1066 // ...where "p1 ... pn" are defined earlier as: 1067 // 1068 // [dcl.fct.def.coroutine]/3 1069 // "For a coroutine f that is a non-static member function, let P1 denote the 1070 // type of the implicit object parameter (13.3.1) and P2 ... Pn be the types 1071 // of the function parameters; otherwise let P1 ... Pn be the types of the 1072 // function parameters. Let p1 ... pn be lvalues denoting those objects." 1073 if (auto *MD = dyn_cast<CXXMethodDecl>(&FD)) { 1074 if (MD->isInstance() && !isLambdaCallOperator(MD)) { 1075 ExprResult ThisExpr = S.ActOnCXXThis(Loc); 1076 if (ThisExpr.isInvalid()) 1077 return false; 1078 ThisExpr = S.CreateBuiltinUnaryOp(Loc, UO_Deref, ThisExpr.get()); 1079 if (ThisExpr.isInvalid()) 1080 return false; 1081 PlacementArgs.push_back(ThisExpr.get()); 1082 } 1083 } 1084 for (auto *PD : FD.parameters()) { 1085 if (PD->getType()->isDependentType()) 1086 continue; 1087 1088 // Build a reference to the parameter. 1089 auto PDLoc = PD->getLocation(); 1090 ExprResult PDRefExpr = 1091 S.BuildDeclRefExpr(PD, PD->getOriginalType().getNonReferenceType(), 1092 ExprValueKind::VK_LValue, PDLoc); 1093 if (PDRefExpr.isInvalid()) 1094 return false; 1095 1096 PlacementArgs.push_back(PDRefExpr.get()); 1097 } 1098 S.FindAllocationFunctions(Loc, SourceRange(), 1099 /*UseGlobal*/ false, PromiseType, 1100 /*isArray*/ false, PassAlignment, PlacementArgs, 1101 OperatorNew, UnusedResult, /*Diagnose*/ false); 1102 1103 // [dcl.fct.def.coroutine]/7 1104 // "If no matching function is found, overload resolution is performed again 1105 // on a function call created by passing just the amount of space required as 1106 // an argument of type std::size_t." 1107 if (!OperatorNew && !PlacementArgs.empty()) { 1108 PlacementArgs.clear(); 1109 S.FindAllocationFunctions(Loc, SourceRange(), 1110 /*UseGlobal*/ false, PromiseType, 1111 /*isArray*/ false, PassAlignment, 1112 PlacementArgs, OperatorNew, UnusedResult); 1113 } 1114 1115 bool IsGlobalOverload = 1116 OperatorNew && !isa<CXXRecordDecl>(OperatorNew->getDeclContext()); 1117 // If we didn't find a class-local new declaration and non-throwing new 1118 // was is required then we need to lookup the non-throwing global operator 1119 // instead. 1120 if (RequiresNoThrowAlloc && (!OperatorNew || IsGlobalOverload)) { 1121 auto *StdNoThrow = buildStdNoThrowDeclRef(S, Loc); 1122 if (!StdNoThrow) 1123 return false; 1124 PlacementArgs = {StdNoThrow}; 1125 OperatorNew = nullptr; 1126 S.FindAllocationFunctions(Loc, SourceRange(), 1127 /*UseGlobal*/ true, PromiseType, 1128 /*isArray*/ false, PassAlignment, PlacementArgs, 1129 OperatorNew, UnusedResult); 1130 } 1131 1132 if (!OperatorNew) 1133 return false; 1134 1135 if (RequiresNoThrowAlloc) { 1136 const auto *FT = OperatorNew->getType()->getAs<FunctionProtoType>(); 1137 if (!FT->isNothrow(S.Context, /*ResultIfDependent*/ false)) { 1138 S.Diag(OperatorNew->getLocation(), 1139 diag::err_coroutine_promise_new_requires_nothrow) 1140 << OperatorNew; 1141 S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required) 1142 << OperatorNew; 1143 return false; 1144 } 1145 } 1146 1147 if ((OperatorDelete = findDeleteForPromise(S, Loc, PromiseType)) == nullptr) 1148 return false; 1149 1150 Expr *FramePtr = 1151 buildBuiltinCall(S, Loc, Builtin::BI__builtin_coro_frame, {}); 1152 1153 Expr *FrameSize = 1154 buildBuiltinCall(S, Loc, Builtin::BI__builtin_coro_size, {}); 1155 1156 // Make new call. 1157 1158 ExprResult NewRef = 1159 S.BuildDeclRefExpr(OperatorNew, OperatorNew->getType(), VK_LValue, Loc); 1160 if (NewRef.isInvalid()) 1161 return false; 1162 1163 SmallVector<Expr *, 2> NewArgs(1, FrameSize); 1164 for (auto Arg : PlacementArgs) 1165 NewArgs.push_back(Arg); 1166 1167 ExprResult NewExpr = 1168 S.ActOnCallExpr(S.getCurScope(), NewRef.get(), Loc, NewArgs, Loc); 1169 NewExpr = S.ActOnFinishFullExpr(NewExpr.get()); 1170 if (NewExpr.isInvalid()) 1171 return false; 1172 1173 // Make delete call. 1174 1175 QualType OpDeleteQualType = OperatorDelete->getType(); 1176 1177 ExprResult DeleteRef = 1178 S.BuildDeclRefExpr(OperatorDelete, OpDeleteQualType, VK_LValue, Loc); 1179 if (DeleteRef.isInvalid()) 1180 return false; 1181 1182 Expr *CoroFree = 1183 buildBuiltinCall(S, Loc, Builtin::BI__builtin_coro_free, {FramePtr}); 1184 1185 SmallVector<Expr *, 2> DeleteArgs{CoroFree}; 1186 1187 // Check if we need to pass the size. 1188 const auto *OpDeleteType = 1189 OpDeleteQualType.getTypePtr()->getAs<FunctionProtoType>(); 1190 if (OpDeleteType->getNumParams() > 1) 1191 DeleteArgs.push_back(FrameSize); 1192 1193 ExprResult DeleteExpr = 1194 S.ActOnCallExpr(S.getCurScope(), DeleteRef.get(), Loc, DeleteArgs, Loc); 1195 DeleteExpr = S.ActOnFinishFullExpr(DeleteExpr.get()); 1196 if (DeleteExpr.isInvalid()) 1197 return false; 1198 1199 this->Allocate = NewExpr.get(); 1200 this->Deallocate = DeleteExpr.get(); 1201 1202 return true; 1203 } 1204 1205 bool CoroutineStmtBuilder::makeOnFallthrough() { 1206 assert(!IsPromiseDependentType && 1207 "cannot make statement while the promise type is dependent"); 1208 1209 // [dcl.fct.def.coroutine]/4 1210 // The unqualified-ids 'return_void' and 'return_value' are looked up in 1211 // the scope of class P. If both are found, the program is ill-formed. 1212 bool HasRVoid, HasRValue; 1213 LookupResult LRVoid = 1214 lookupMember(S, "return_void", PromiseRecordDecl, Loc, HasRVoid); 1215 LookupResult LRValue = 1216 lookupMember(S, "return_value", PromiseRecordDecl, Loc, HasRValue); 1217 1218 StmtResult Fallthrough; 1219 if (HasRVoid && HasRValue) { 1220 // FIXME Improve this diagnostic 1221 S.Diag(FD.getLocation(), 1222 diag::err_coroutine_promise_incompatible_return_functions) 1223 << PromiseRecordDecl; 1224 S.Diag(LRVoid.getRepresentativeDecl()->getLocation(), 1225 diag::note_member_first_declared_here) 1226 << LRVoid.getLookupName(); 1227 S.Diag(LRValue.getRepresentativeDecl()->getLocation(), 1228 diag::note_member_first_declared_here) 1229 << LRValue.getLookupName(); 1230 return false; 1231 } else if (!HasRVoid && !HasRValue) { 1232 // FIXME: The PDTS currently specifies this case as UB, not ill-formed. 1233 // However we still diagnose this as an error since until the PDTS is fixed. 1234 S.Diag(FD.getLocation(), 1235 diag::err_coroutine_promise_requires_return_function) 1236 << PromiseRecordDecl; 1237 S.Diag(PromiseRecordDecl->getLocation(), diag::note_defined_here) 1238 << PromiseRecordDecl; 1239 return false; 1240 } else if (HasRVoid) { 1241 // If the unqualified-id return_void is found, flowing off the end of a 1242 // coroutine is equivalent to a co_return with no operand. Otherwise, 1243 // flowing off the end of a coroutine results in undefined behavior. 1244 Fallthrough = S.BuildCoreturnStmt(FD.getLocation(), nullptr, 1245 /*IsImplicit*/false); 1246 Fallthrough = S.ActOnFinishFullStmt(Fallthrough.get()); 1247 if (Fallthrough.isInvalid()) 1248 return false; 1249 } 1250 1251 this->OnFallthrough = Fallthrough.get(); 1252 return true; 1253 } 1254 1255 bool CoroutineStmtBuilder::makeOnException() { 1256 // Try to form 'p.unhandled_exception();' 1257 assert(!IsPromiseDependentType && 1258 "cannot make statement while the promise type is dependent"); 1259 1260 const bool RequireUnhandledException = S.getLangOpts().CXXExceptions; 1261 1262 if (!lookupMember(S, "unhandled_exception", PromiseRecordDecl, Loc)) { 1263 auto DiagID = 1264 RequireUnhandledException 1265 ? diag::err_coroutine_promise_unhandled_exception_required 1266 : diag:: 1267 warn_coroutine_promise_unhandled_exception_required_with_exceptions; 1268 S.Diag(Loc, DiagID) << PromiseRecordDecl; 1269 S.Diag(PromiseRecordDecl->getLocation(), diag::note_defined_here) 1270 << PromiseRecordDecl; 1271 return !RequireUnhandledException; 1272 } 1273 1274 // If exceptions are disabled, don't try to build OnException. 1275 if (!S.getLangOpts().CXXExceptions) 1276 return true; 1277 1278 ExprResult UnhandledException = buildPromiseCall(S, Fn.CoroutinePromise, Loc, 1279 "unhandled_exception", None); 1280 UnhandledException = S.ActOnFinishFullExpr(UnhandledException.get(), Loc); 1281 if (UnhandledException.isInvalid()) 1282 return false; 1283 1284 // Since the body of the coroutine will be wrapped in try-catch, it will 1285 // be incompatible with SEH __try if present in a function. 1286 if (!S.getLangOpts().Borland && Fn.FirstSEHTryLoc.isValid()) { 1287 S.Diag(Fn.FirstSEHTryLoc, diag::err_seh_in_a_coroutine_with_cxx_exceptions); 1288 S.Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here) 1289 << Fn.getFirstCoroutineStmtKeyword(); 1290 return false; 1291 } 1292 1293 this->OnException = UnhandledException.get(); 1294 return true; 1295 } 1296 1297 bool CoroutineStmtBuilder::makeReturnObject() { 1298 // Build implicit 'p.get_return_object()' expression and form initialization 1299 // of return type from it. 1300 ExprResult ReturnObject = 1301 buildPromiseCall(S, Fn.CoroutinePromise, Loc, "get_return_object", None); 1302 if (ReturnObject.isInvalid()) 1303 return false; 1304 1305 this->ReturnValue = ReturnObject.get(); 1306 return true; 1307 } 1308 1309 static void noteMemberDeclaredHere(Sema &S, Expr *E, FunctionScopeInfo &Fn) { 1310 if (auto *MbrRef = dyn_cast<CXXMemberCallExpr>(E)) { 1311 auto *MethodDecl = MbrRef->getMethodDecl(); 1312 S.Diag(MethodDecl->getLocation(), diag::note_member_declared_here) 1313 << MethodDecl; 1314 } 1315 S.Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here) 1316 << Fn.getFirstCoroutineStmtKeyword(); 1317 } 1318 1319 bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() { 1320 assert(!IsPromiseDependentType && 1321 "cannot make statement while the promise type is dependent"); 1322 assert(this->ReturnValue && "ReturnValue must be already formed"); 1323 1324 QualType const GroType = this->ReturnValue->getType(); 1325 assert(!GroType->isDependentType() && 1326 "get_return_object type must no longer be dependent"); 1327 1328 QualType const FnRetType = FD.getReturnType(); 1329 assert(!FnRetType->isDependentType() && 1330 "get_return_object type must no longer be dependent"); 1331 1332 if (FnRetType->isVoidType()) { 1333 ExprResult Res = S.ActOnFinishFullExpr(this->ReturnValue, Loc); 1334 if (Res.isInvalid()) 1335 return false; 1336 1337 this->ResultDecl = Res.get(); 1338 return true; 1339 } 1340 1341 if (GroType->isVoidType()) { 1342 // Trigger a nice error message. 1343 InitializedEntity Entity = 1344 InitializedEntity::InitializeResult(Loc, FnRetType, false); 1345 S.PerformMoveOrCopyInitialization(Entity, nullptr, FnRetType, ReturnValue); 1346 noteMemberDeclaredHere(S, ReturnValue, Fn); 1347 return false; 1348 } 1349 1350 auto *GroDecl = VarDecl::Create( 1351 S.Context, &FD, FD.getLocation(), FD.getLocation(), 1352 &S.PP.getIdentifierTable().get("__coro_gro"), GroType, 1353 S.Context.getTrivialTypeSourceInfo(GroType, Loc), SC_None); 1354 1355 S.CheckVariableDeclarationType(GroDecl); 1356 if (GroDecl->isInvalidDecl()) 1357 return false; 1358 1359 InitializedEntity Entity = InitializedEntity::InitializeVariable(GroDecl); 1360 ExprResult Res = S.PerformMoveOrCopyInitialization(Entity, nullptr, GroType, 1361 this->ReturnValue); 1362 if (Res.isInvalid()) 1363 return false; 1364 1365 Res = S.ActOnFinishFullExpr(Res.get()); 1366 if (Res.isInvalid()) 1367 return false; 1368 1369 S.AddInitializerToDecl(GroDecl, Res.get(), 1370 /*DirectInit=*/false); 1371 1372 S.FinalizeDeclaration(GroDecl); 1373 1374 // Form a declaration statement for the return declaration, so that AST 1375 // visitors can more easily find it. 1376 StmtResult GroDeclStmt = 1377 S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(GroDecl), Loc, Loc); 1378 if (GroDeclStmt.isInvalid()) 1379 return false; 1380 1381 this->ResultDecl = GroDeclStmt.get(); 1382 1383 ExprResult declRef = S.BuildDeclRefExpr(GroDecl, GroType, VK_LValue, Loc); 1384 if (declRef.isInvalid()) 1385 return false; 1386 1387 StmtResult ReturnStmt = S.BuildReturnStmt(Loc, declRef.get()); 1388 if (ReturnStmt.isInvalid()) { 1389 noteMemberDeclaredHere(S, ReturnValue, Fn); 1390 return false; 1391 } 1392 if (cast<clang::ReturnStmt>(ReturnStmt.get())->getNRVOCandidate() == GroDecl) 1393 GroDecl->setNRVOVariable(true); 1394 1395 this->ReturnStmt = ReturnStmt.get(); 1396 return true; 1397 } 1398 1399 // Create a static_cast\<T&&>(expr). 1400 static Expr *castForMoving(Sema &S, Expr *E, QualType T = QualType()) { 1401 if (T.isNull()) 1402 T = E->getType(); 1403 QualType TargetType = S.BuildReferenceType( 1404 T, /*SpelledAsLValue*/ false, SourceLocation(), DeclarationName()); 1405 SourceLocation ExprLoc = E->getLocStart(); 1406 TypeSourceInfo *TargetLoc = 1407 S.Context.getTrivialTypeSourceInfo(TargetType, ExprLoc); 1408 1409 return S 1410 .BuildCXXNamedCast(ExprLoc, tok::kw_static_cast, TargetLoc, E, 1411 SourceRange(ExprLoc, ExprLoc), E->getSourceRange()) 1412 .get(); 1413 } 1414 1415 /// \brief Build a variable declaration for move parameter. 1416 static VarDecl *buildVarDecl(Sema &S, SourceLocation Loc, QualType Type, 1417 IdentifierInfo *II) { 1418 TypeSourceInfo *TInfo = S.Context.getTrivialTypeSourceInfo(Type, Loc); 1419 VarDecl *Decl = VarDecl::Create(S.Context, S.CurContext, Loc, Loc, II, Type, 1420 TInfo, SC_None); 1421 Decl->setImplicit(); 1422 return Decl; 1423 } 1424 1425 // Build statements that move coroutine function parameters to the coroutine 1426 // frame, and store them on the function scope info. 1427 bool Sema::buildCoroutineParameterMoves(SourceLocation Loc) { 1428 assert(isa<FunctionDecl>(CurContext) && "not in a function scope"); 1429 auto *FD = cast<FunctionDecl>(CurContext); 1430 1431 auto *ScopeInfo = getCurFunction(); 1432 assert(ScopeInfo->CoroutineParameterMoves.empty() && 1433 "Should not build parameter moves twice"); 1434 1435 for (auto *PD : FD->parameters()) { 1436 if (PD->getType()->isDependentType()) 1437 continue; 1438 1439 ExprResult PDRefExpr = 1440 BuildDeclRefExpr(PD, PD->getType().getNonReferenceType(), 1441 ExprValueKind::VK_LValue, Loc); // FIXME: scope? 1442 if (PDRefExpr.isInvalid()) 1443 return false; 1444 1445 Expr *CExpr = nullptr; 1446 if (PD->getType()->getAsCXXRecordDecl() || 1447 PD->getType()->isRValueReferenceType()) 1448 CExpr = castForMoving(*this, PDRefExpr.get()); 1449 else 1450 CExpr = PDRefExpr.get(); 1451 1452 auto D = buildVarDecl(*this, Loc, PD->getType(), PD->getIdentifier()); 1453 AddInitializerToDecl(D, CExpr, /*DirectInit=*/true); 1454 1455 // Convert decl to a statement. 1456 StmtResult Stmt = ActOnDeclStmt(ConvertDeclToDeclGroup(D), Loc, Loc); 1457 if (Stmt.isInvalid()) 1458 return false; 1459 1460 ScopeInfo->CoroutineParameterMoves.insert(std::make_pair(PD, Stmt.get())); 1461 } 1462 return true; 1463 } 1464 1465 StmtResult Sema::BuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) { 1466 CoroutineBodyStmt *Res = CoroutineBodyStmt::Create(Context, Args); 1467 if (!Res) 1468 return StmtError(); 1469 return Res; 1470 } 1471