clang: lib/Sema/SemaCoroutine.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
28
29using namespace clang;
30using namespace sema;
31
36
37
40 return LR;
41}
42
45 bool Res;
47 return Res;
48}
49
50
51
56
59 if (!CoroTraits)
61
62
63
68 };
70
71
72 if (auto *MD = dyn_cast(FD)) {
73 if (MD->isImplicitObjectMemberFunction()) {
74
75
76
77
78
79
80
81 QualType T = MD->getFunctionObjectParameterType();
85 AddArg(T);
86 }
87 }
89 AddArg(T);
90
91
94 if (CoroTrait.isNull())
97 diag::err_coroutine_type_missing_specialization))
99
101 assert(RD && "specialization of class template is not a class?");
102
103
108 if (!Promise) {
109 S.Diag(FuncLoc,
110 diag::err_implied_std_coroutine_traits_promise_type_not_found)
111 << RD;
113 }
114
116
117 auto buildElaboratedType = [&]() {
122 PromiseType);
123 };
124
126 S.Diag(FuncLoc,
127 diag::err_implied_std_coroutine_traits_promise_type_not_class)
128 << buildElaboratedType();
130 }
132 diag::err_coroutine_promise_type_incomplete))
134
135 return PromiseType;
136}
137
138
141 if (PromiseType.isNull())
143
145 assert(CoroNamespace && "Should already be diagnosed");
146
150 S.Diag(Loc, diag::err_implied_coroutine_type_not_found)
151 << "std::coroutine_handle";
153 }
154
156 if (!CoroHandle) {
157 Result.suppressDiagnostics();
158
160 S.Diag(Found->getLocation(), diag::err_malformed_std_coroutine_handle);
162 }
163
164
169
170
173 if (CoroHandleType.isNull())
176 diag::err_coroutine_type_missing_specialization))
178
179 return CoroHandleType;
180}
181
183 StringRef Keyword) {
184
185
186
187
188
189
190 auto *FD = dyn_cast(S.CurContext);
191 if (!FD) {
193 ? diag::err_coroutine_objc_method
194 : diag::err_coroutine_outside_function) << Keyword;
195 return false;
196 }
197
198
199
200 enum InvalidFuncDiag {
201 DiagCtor = 0,
202 DiagDtor,
203 DiagMain,
204 DiagConstexpr,
205 DiagAutoRet,
206 DiagVarargs,
207 DiagConsteval,
208 };
209 bool Diagnosed = false;
210 auto DiagInvalid = [&](InvalidFuncDiag ID) {
211 S.Diag(Loc, diag::err_coroutine_invalid_func_context) << ID << Keyword;
212 Diagnosed = true;
213 return false;
214 };
215
216
217
218 auto *MD = dyn_cast(FD);
219
220 if (MD && isa(MD))
221 return DiagInvalid(DiagCtor);
222
223 else if (MD && isa(MD))
224 return DiagInvalid(DiagDtor);
225
226 else if (FD->isMain())
227 return DiagInvalid(DiagMain);
228
229
230
231
232
233 if (FD->isConstexpr())
234 DiagInvalid(FD->isConsteval() ? DiagConsteval : DiagConstexpr);
235
236
237 if (FD->getReturnType()->isUndeducedType())
238 DiagInvalid(DiagAutoRet);
239
240
241
242 if (FD->isVariadic())
243 DiagInvalid(DiagVarargs);
244
245 return !Diagnosed;
246}
247
248
249
255}
256
263 cast(R.get()));
264}
265
269 if (CoroHandleType.isNull())
271
276 S.Diag(Loc, diag::err_coroutine_handle_missing_member)
277 << "from_address";
279 }
280
281 Expr *FramePtr =
283
289
291}
292
298};
299
303
304
307 Base, Base->getType(), Loc, false, SS,
308 SourceLocation(), nullptr, NameInfo, nullptr,
309 nullptr);
310 if (Result.isInvalid())
312
313
314 if (auto *TE = dyn_cast(Result.get())) {
316 S.Diag(Loc, diag::err_no_member)
317 << NameInfo.getName() << Base->getType()->getAsCXXRecordDecl()
318 << Base->getSourceRange();
320 }
321
322 auto EndLoc = Args.empty() ? Loc : Args.back()->getEndLoc();
324}
325
326
327
328
329
333 return nullptr;
336 return nullptr;
337
338
339
340
341
344 return nullptr;
345
346 Expr *JustAddress = AddressExpr.get();
347
348
350 S.Diag(cast(JustAddress)->getCalleeDecl()->getLocation(),
351 diag::warn_coroutine_handle_address_invalid_return_type)
352 << JustAddress->getType();
353
354
355
357}
358
359
360
361
362
363
364
365
366
367
368
369
370
375
376
377
379
381
382 auto BuildSubExpr = [&](ACT CallType, StringRef Func,
385 if (Result.isInvalid()) {
387 return nullptr;
388 }
391 };
392
394 cast_or_null(BuildSubExpr(ACT::ACT_Ready, "await_ready", {}));
395 if (!AwaitReady)
396 return Calls;
398
399
400
404 diag::note_await_ready_no_bool_conversion);
405 S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
408 } else
410 }
411
416 return Calls;
417 }
418 Expr *CoroHandle = CoroHandleRes.get();
419 CallExpr *AwaitSuspend = cast_or_null(
420 BuildSubExpr(ACT::ACT_Suspend, "await_suspend", CoroHandle));
421 if (!AwaitSuspend)
422 return Calls;
424
425
426
427
429
430
431 if (Expr *TailCallSuspend =
433
434
435
436
437
438 Calls.Results[ACT::ACT_Suspend] = TailCallSuspend;
439 else {
440
444 diag::err_await_suspend_invalid_return_type)
445 << RetType;
446 S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
449 } else
450 Calls.Results[ACT::ACT_Suspend] =
452 }
453 }
454
455 BuildSubExpr(ACT::ACT_Resume, "await_resume", {});
456
457
459
460 return Calls;
461}
462
466
467
472
474}
475
477 assert(isa(CurContext) && "not in a function scope");
478 auto *FD = cast(CurContext);
479 bool IsThisDependentType = [&] {
480 if (const auto *MD = dyn_cast_if_present(FD))
481 return MD->isImplicitObjectMemberFunction() &&
482 MD->getThisType()->isDependentType();
483 return false;
484 }();
485
489 if (T.isNull())
490 return nullptr;
491
495 VD->setImplicit();
497 if (VD->isInvalidDecl())
498 return nullptr;
499
501
502
503
505
506
507 if (auto *MD = dyn_cast(FD)) {
511 return nullptr;
514 return nullptr;
515 CtorArgExprs.push_back(ThisExpr.get());
516 }
517 }
518
519
520 auto &Moves = ScopeInfo->CoroutineParameterMoves;
521 for (auto *PD : FD->parameters()) {
522 if (PD->getType()->isDependentType())
523 continue;
524
526 auto Move = Moves.find(PD);
527 assert(Move != Moves.end() &&
528 "Coroutine function parameter not inserted into move map");
529
530
531 auto *MoveDecl =
532 cast(cast(Move->second)->getSingleDecl());
533 RefExpr =
534 BuildDeclRefExpr(MoveDecl, MoveDecl->getType().getNonReferenceType(),
536 if (RefExpr.isInvalid())
537 return nullptr;
538 CtorArgExprs.push_back(RefExpr.get());
539 }
540
541
542
543 if (!CtorArgExprs.empty()) {
544
545
547 CtorArgExprs, FD->getLocation());
550 VD->getLocation(), true, PLE);
552 false,
553 false);
554
555
556
557
558
559
560
561 if (InitSeq) {
563 if (Result.isInvalid()) {
564 VD->setInvalidDecl();
565 } else if (Result.get()) {
569 }
570 } else
572 } else
574
575 FD->addDecl(VD);
576 return VD;
577}
578
579
581 StringRef Keyword,
582 bool IsImplicit = false) {
584 return nullptr;
585
586 assert(isa(S.CurContext) && "not in a function scope");
587
589 assert(ScopeInfo && "missing function scope for function");
590
591 if (ScopeInfo->FirstCoroutineStmtLoc.isInvalid() && !IsImplicit)
592 ScopeInfo->setFirstCoroutineStmt(Loc, Keyword);
593
594 if (ScopeInfo->CoroutinePromise)
595 return ScopeInfo;
596
598 return nullptr;
599
601 if (!ScopeInfo->CoroutinePromise)
602 return nullptr;
603
604 return ScopeInfo;
605}
606
607
608
609
611 llvm::SmallPtrSetImpl<const Decl *> &ThrowingDecls) {
612 auto checkDeclNoexcept = [&](const Decl *D, bool IsDtor = false) {
613
614
616 if (const auto *FD = dyn_cast(D)) {
617
618
619
620
621
622
623
624 if (FD->getBuiltinID() == Builtin::BI__builtin_coro_resume)
625 return;
626 }
627 if (ThrowingDecls.empty()) {
628
629
630
631
632
633 S.Diag(cast(S.CurContext)->getLocation(),
634 diag::err_coroutine_promise_final_suspend_requires_nothrow);
635 }
636 ThrowingDecls.insert(D);
637 }
638 };
639
640 if (auto *CE = dyn_cast(E)) {
642 checkDeclNoexcept(Ctor);
643
645 } else if (auto *CE = dyn_cast(E)) {
646 if (CE->isTypeDependent())
647 return;
648
649 checkDeclNoexcept(CE->getCalleeDecl());
651
654 const auto *T =
656 checkDeclNoexcept(cast(T->getDecl())->getDestructor(),
657 true);
658 }
659 } else
660 for (const auto *Child : E->children()) {
661 if (!Child)
662 continue;
664 }
665}
666
669
670
671
672
673 checkNoThrow(*this, FinalSuspend, ThrowingDecls);
675 ThrowingDecls.end()};
676 sort(SortedDecls, [](const Decl *A, const Decl *B) {
678 });
679 for (const auto *D : SortedDecls) {
680 Diag(D->getEndLoc(), diag::note_coroutine_function_declare_noexcept);
681 }
682 return ThrowingDecls.empty();
683}
684
685
686
688 assert(FSI && "FunctionScopeInfo is null");
690 "first coroutine location not set");
692 return;
696}
697
699 StringRef Keyword) {
700
704 return false;
706 assert(ScopeInfo->CoroutinePromise);
707
708
709 if (ScopeInfo->FirstCoroutineStmtLoc == KWLoc)
711
712
713
714 if (!ScopeInfo->NeedsCoroutineSuspends)
715 return true;
716
717 ScopeInfo->setNeedsCoroutineSuspends(false);
718
719 auto *Fn = cast(CurContext);
721
722 auto buildSuspends = [&](StringRef Name) mutable -> StmtResult {
725 if (Operand.isInvalid())
732 true);
735 Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
736 << ((Name == "initial_suspend") ? 0 : 1);
737 Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword;
739 }
740 return cast(Suspend.get());
741 };
742
743 StmtResult InitSuspend = buildSuspends("initial_suspend");
745 return true;
746
747 StmtResult FinalSuspend = buildSuspends("final_suspend");
749 return true;
750
751 ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get());
752
753 return true;
754}
755
756
757
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773 while (S && !S->isFunctionScope()) {
774 if (S->isCatchScope())
775 return true;
776 S = S->getParent();
777 }
778 return false;
779}
780
781
782
783
784
785
787 StringRef Keyword) {
788
789
790
792 S.Diag(Loc, diag::err_coroutine_unevaluated_context) << Keyword;
793 return false;
794 }
795
796
798 S.Diag(Loc, diag::err_coroutine_within_handler) << Keyword;
799 return false;
800 }
801
802 return true;
803}
804
808
812 }
813
818 }
819
824 cast(Lookup.get()));
825}
826
833
834 assert(!Operators.isAmbiguous() && "Operator lookup cannot be ambiguous");
839 Functions.end(), false,
840 false);
841 assert(CoawaitOp);
842 return CoawaitOp;
843}
844
848}
849
851 auto *Call = dyn_cast(Operand->IgnoreImplicit());
852 if ( ||
->isPRValue())
853 return;
854
856 return;
857
858 Call->setCoroElideSafe();
859
860
861 auto *Fn = llvm::dyn_cast_if_present(Call->getCalleeDecl());
862 if (!Fn)
863 return;
864
865 size_t ParmIdx = 0;
866 for (ParmVarDecl *PD : Fn->parameters()) {
867 if (PD->hasAttr())
869
870 ParmIdx++;
871 }
872}
873
874
875
879 if (!FSI)
881
882 if (Operand->hasPlaceholderType()) {
886 Operand = R.get();
887 }
888
889 auto *Promise = FSI->CoroutinePromise;
890 if (Promise->getType()->isDependentType()) {
893 return Res;
894 }
895
897
900
901 if (CurFnAwaitElidable)
903
904 Expr *Transformed = Operand;
910 diag::note_coroutine_promise_implicit_await_transform_required_here)
911 << Operand->getSourceRange();
913 }
914 Transformed = R.get();
915 }
919
921}
922
924 Expr *Awaiter, bool IsImplicit) {
926 if (!Coroutine)
928
932 Awaiter = R.get();
933 }
934
938 return Res;
939 }
940
941
942
945
946
947
948
950
951
953 buildCoawaitCalls(*this, Coroutine->CoroutinePromise, CallLoc, Awaiter);
956
960
961 return Res;
962}
963
967
971 }
972
973
978
979
983
985}
988 if (!Coroutine)
990
995 }
996
998
1001 return Res;
1002 }
1003
1004
1005
1008
1009
1011 *this, Coroutine->CoroutinePromise, Loc, E);
1014
1018
1019 return Res;
1020}
1021
1026 }
1028}
1029
1031 bool IsImplicit) {
1033 if (!FSI)
1035
1041 }
1042
1043 VarDecl *Promise = FSI->CoroutinePromise;
1048 } else {
1051 }
1054
1056
1058 return Res;
1059}
1060
1061
1064 assert(Std && "Should already be diagnosed");
1065
1069
1070
1071 S.Diag(Loc, diag::err_implicit_coroutine_std_nothrow_type_not_found);
1072 return nullptr;
1073 }
1074
1076 if (!VD) {
1077 Result.suppressDiagnostics();
1078
1080 S.Diag(Found->getLocation(), diag::err_malformed_std_nothrow);
1081 return nullptr;
1082 }
1083
1086 return nullptr;
1087
1088 return DR.get();
1089}
1090
1096}
1097
1098
1103
1105 assert(PointeeRD && "PromiseType must be a CxxRecordDecl type");
1106
1107 const bool Overaligned = S.getLangOpts().CoroAlignedAllocation;
1108
1109
1110
1111
1112
1114 true, true,
1115 Overaligned))
1116 return false;
1117
1118
1119
1120
1121
1122
1123
1124 if (!OperatorDelete) {
1125
1126
1127 const bool CanProvideSize = true;
1128
1129
1130
1132 Overaligned, DeleteName);
1133
1134 if (!OperatorDelete)
1135 return false;
1136 }
1137
1139 return true;
1140}
1141
1142
1145 assert(Fn && Fn->isCoroutine() && "not a coroutine");
1146 if (!Body) {
1148 "a null body is only allowed for invalid declarations");
1149 return;
1150 }
1151
1152
1153 if (!Fn->CoroutinePromise)
1155
1156 if (isa(Body)) {
1157
1158 return;
1159 }
1160
1161
1162
1163
1164
1165
1166 if (FD->hasAttr())
1167 Diag(FD->getLocation(), diag::warn_always_inline_coroutine);
1168
1169
1170
1171 if (Fn->FirstVLALoc.isValid())
1172 Diag(Fn->FirstVLALoc, diag::err_vla_in_coroutine_unsupported);
1173
1174
1175
1177 Diag(ALE->getBeginLoc(), diag::err_coro_invalid_addr_of_label);
1178
1180 if (Builder.isInvalid() || !Builder.buildStatements())
1182
1183
1185}
1186
1188 if (auto *CS = dyn_cast(Body))
1189 return CS;
1190
1191
1192
1193
1194 assert(isa(Body) && "Unimaged coroutine body type");
1197}
1198
1202 : S(S), FD(FD), Fn(Fn), Loc(FD.getLocation()),
1203 IsPromiseDependentType(
1204 !Fn.CoroutinePromise ||
1205 Fn.CoroutinePromise->getType()->isDependentType()) {
1207
1208 for (auto KV : Fn.CoroutineParameterMoves)
1209 this->ParamMovesVector.push_back(KV.second);
1210 this->ParamMoves = this->ParamMovesVector;
1211
1212 if (!IsPromiseDependentType) {
1213 PromiseRecordDecl = Fn.CoroutinePromise->getType()->getAsCXXRecordDecl();
1214 assert(PromiseRecordDecl && "Type should have already been checked");
1215 }
1216 this->IsValid = makePromiseStmt() && makeInitialAndFinalSuspend();
1217}
1218
1220 assert(this->IsValid && "coroutine already invalid");
1221 this->IsValid = makeReturnObject();
1222 if (this->IsValid && !IsPromiseDependentType)
1224 return this->IsValid;
1225}
1226
1228 assert(this->IsValid && "coroutine already invalid");
1229 assert(!this->IsPromiseDependentType &&
1230 "coroutine cannot have a dependent promise type");
1231 this->IsValid = makeOnException() && makeOnFallthrough() &&
1232 makeGroDeclAndReturnStmt() && makeReturnOnAllocFailure() &&
1233 makeNewAndDeleteExpr();
1234 return this->IsValid;
1235}
1236
1237bool CoroutineStmtBuilder::makePromiseStmt() {
1238
1239
1243 return false;
1244
1246 return true;
1247}
1248
1249bool CoroutineStmtBuilder::makeInitialAndFinalSuspend() {
1251 return false;
1254 return true;
1255}
1256
1261 if (auto *DeclRef = dyn_cast_or_null(E)) {
1262 auto *Decl = DeclRef->getDecl();
1263 if (CXXMethodDecl *Method = dyn_cast_or_null(Decl)) {
1264 if (Method->isStatic())
1265 return true;
1266 else
1268 }
1269 }
1270
1273 diag::err_coroutine_promise_get_return_object_on_allocation_failure)
1274 << PromiseRecordDecl;
1275 S.Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
1276 << Fn.getFirstCoroutineStmtKeyword();
1277 return false;
1278}
1279
1280bool CoroutineStmtBuilder::makeReturnOnAllocFailure() {
1281 assert(!IsPromiseDependentType &&
1282 "cannot make statement while the promise type is dependent");
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1297 return true;
1298
1303 return false;
1304
1306 return false;
1307
1308 ExprResult ReturnObjectOnAllocationFailure =
1310 if (ReturnObjectOnAllocationFailure.isInvalid())
1311 return false;
1312
1316 S.Diag(Found.getFoundDecl()->getLocation(), diag::note_member_declared_here)
1317 << DN;
1320 return false;
1321 }
1322
1324 return true;
1325}
1326
1327
1328
1329
1332 if (auto *MD = dyn_cast(&FD)) {
1336 return false;
1339 return false;
1340 PlacementArgs.push_back(ThisExpr.get());
1341 }
1342 }
1343
1345 if (PD->getType()->isDependentType())
1346 continue;
1347
1348
1349 auto PDLoc = PD->getLocation();
1351 S.BuildDeclRefExpr(PD, PD->getOriginalType().getNonReferenceType(),
1354 return false;
1355
1356 PlacementArgs.push_back(PDRefExpr.get());
1357 }
1358
1359 return true;
1360}
1361
1362bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
1363
1364 assert(!IsPromiseDependentType &&
1365 "cannot make statement while the promise type is dependent");
1367
1369 return false;
1370
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1408
1409 const bool PromiseContainsNew = [this, &PromiseType]() -> bool {
1413
1416
1417 return !R.empty() && !R.isAmbiguous();
1418 }();
1419
1420
1421
1422 bool PassAlignment = S.getLangOpts().CoroAlignedAllocation;
1425 bool WithoutPlacementArgs = false,
1426 bool ForceNonAligned = false) {
1427
1428
1429
1430
1431
1432
1435
1436 PassAlignment = !ForceNonAligned && S.getLangOpts().CoroAlignedAllocation;
1440 false, PassAlignment,
1442 : PlacementArgs,
1443 OperatorNew, UnusedResult, false);
1444 };
1445
1446
1447
1448
1450 return false;
1451
1452 LookupAllocationFunction();
1453
1454 if (PromiseContainsNew && !PlacementArgs.empty()) {
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467 if (!OperatorNew ||
1468 (S.getLangOpts().CoroAlignedAllocation && !PassAlignment))
1470 true);
1471 }
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491 bool FoundNonAlignedInPromise = false;
1492 if (PromiseContainsNew && S.getLangOpts().CoroAlignedAllocation)
1493 if (!OperatorNew || !PassAlignment) {
1494 FoundNonAlignedInPromise = OperatorNew;
1495
1497 false,
1498 true);
1499
1500 if (!OperatorNew && !PlacementArgs.empty())
1502 true,
1503 true);
1504 }
1505
1506 bool IsGlobalOverload =
1507 OperatorNew && !isa(OperatorNew->getDeclContext());
1508
1509
1510
1511 if (RequiresNoThrowAlloc && (!OperatorNew || IsGlobalOverload)) {
1513 if (!StdNoThrow)
1514 return false;
1515 PlacementArgs = {StdNoThrow};
1516 OperatorNew = nullptr;
1518 }
1519
1520
1521
1522
1523 if (FoundNonAlignedInPromise) {
1524 S.Diag(OperatorNew->getLocation(),
1525 diag::warn_non_aligned_allocation_function)
1526 << &FD;
1527 }
1528
1529 if (!OperatorNew) {
1530 if (PromiseContainsNew)
1531 S.Diag(Loc, diag::err_coroutine_unusable_new) << PromiseType << &FD;
1532 else if (RequiresNoThrowAlloc)
1533 S.Diag(Loc, diag::err_coroutine_unfound_nothrow_new)
1534 << &FD << S.getLangOpts().CoroAlignedAllocation;
1535
1536 return false;
1537 }
1538
1539 if (RequiresNoThrowAlloc) {
1540 const auto *FT = OperatorNew->getType()->castAs<FunctionProtoType>();
1541 if (!FT->isNothrow( false)) {
1542 S.Diag(OperatorNew->getLocation(),
1543 diag::err_coroutine_promise_new_requires_nothrow)
1544 << OperatorNew;
1545 S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
1546 << OperatorNew;
1547 return false;
1548 }
1549 }
1550
1553
1554
1555
1556 return false;
1557 }
1558
1559 Expr *FramePtr =
1561
1562 Expr *FrameSize =
1564
1565 Expr *FrameAlignment = nullptr;
1566
1567 if (S.getLangOpts().CoroAlignedAllocation) {
1568 FrameAlignment =
1570
1572 if (!AlignValTy)
1573 return false;
1574
1575 FrameAlignment = S.BuildCXXNamedCast(Loc, tok::kw_static_cast, AlignValTy,
1579 }
1580
1581
1585 return false;
1586
1588 if (S.getLangOpts().CoroAlignedAllocation && PassAlignment)
1589 NewArgs.push_back(FrameAlignment);
1590
1591 if (OperatorNew->getNumParams() > NewArgs.size())
1592 llvm::append_range(NewArgs, PlacementArgs);
1593
1598 return false;
1599
1600
1601
1602 QualType OpDeleteQualType = OperatorDelete->getType();
1603
1607 return false;
1608
1609 Expr *CoroFree =
1611
1613
1614
1615
1616
1617
1618
1619 const auto *OpDeleteType =
1621 if (OpDeleteType->getNumParams() > DeleteArgs.size() &&
1623 OpDeleteType->getParamType(DeleteArgs.size()), FrameSize->getType()))
1624 DeleteArgs.push_back(FrameSize);
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637 if (S.getLangOpts().CoroAlignedAllocation &&
1638 OpDeleteType->getNumParams() > DeleteArgs.size() &&
1640 OpDeleteType->getParamType(DeleteArgs.size()),
1641 FrameAlignment->getType()))
1642 DeleteArgs.push_back(FrameAlignment);
1643
1646 DeleteExpr =
1649 return false;
1650
1653
1654 return true;
1655}
1656
1657bool CoroutineStmtBuilder::makeOnFallthrough() {
1658 assert(!IsPromiseDependentType &&
1659 "cannot make statement while the promise type is dependent");
1660
1661
1662
1663
1664
1665
1666
1667
1668 bool HasRVoid, HasRValue;
1670 lookupMember(S, "return_void", PromiseRecordDecl, Loc, HasRVoid);
1672 lookupMember(S, "return_value", PromiseRecordDecl, Loc, HasRValue);
1673
1675 if (HasRVoid && HasRValue) {
1676
1677 S.Diag(FD.getLocation(),
1678 diag::err_coroutine_promise_incompatible_return_functions)
1679 << PromiseRecordDecl;
1681 diag::note_member_first_declared_here)
1684 diag::note_member_first_declared_here)
1686 return false;
1687 } else if (!HasRVoid && !HasRValue) {
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1700 return false;
1701 } else if (HasRVoid) {
1703 true);
1706 return false;
1707 }
1708
1710 return true;
1711}
1712
1713bool CoroutineStmtBuilder::makeOnException() {
1714
1715 assert(!IsPromiseDependentType &&
1716 "cannot make statement while the promise type is dependent");
1717
1718 const bool RequireUnhandledException = S.getLangOpts().CXXExceptions;
1719
1720 if ((S, "unhandled_exception", PromiseRecordDecl, Loc)) {
1721 auto DiagID =
1722 RequireUnhandledException
1723 ? diag::err_coroutine_promise_unhandled_exception_required
1724 : diag::
1725 warn_coroutine_promise_unhandled_exception_required_with_exceptions;
1726 S.Diag(Loc, DiagID) << PromiseRecordDecl;
1727 S.Diag(PromiseRecordDecl->getLocation(), diag::note_defined_here)
1728 << PromiseRecordDecl;
1729 return !RequireUnhandledException;
1730 }
1731
1732
1734 return true;
1735
1739 false);
1740 if (UnhandledException.isInvalid())
1741 return false;
1742
1743
1744
1746 S.Diag(Fn.FirstSEHTryLoc, diag::err_seh_in_a_coroutine_with_cxx_exceptions);
1749 return false;
1750 }
1751
1753 return true;
1754}
1755
1756bool CoroutineStmtBuilder::makeReturnObject() {
1757
1758
1759
1763 return false;
1764
1766 return true;
1767}
1768
1770 if (auto *MbrRef = dyn_cast(E)) {
1771 auto *MethodDecl = MbrRef->getMethodDecl();
1772 S.Diag(MethodDecl->getLocation(), diag::note_member_declared_here)
1773 << MethodDecl;
1774 }
1775 S.Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
1776 << Fn.getFirstCoroutineStmtKeyword();
1777}
1778
1779bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() {
1780 assert(!IsPromiseDependentType &&
1781 "cannot make statement while the promise type is dependent");
1782 assert(this->ReturnValue && "ReturnValue must be already formed");
1783
1786 "get_return_object type must no longer be dependent");
1787
1788 QualType const FnRetType = FD.getReturnType();
1790 "get_return_object type must no longer be dependent");
1791
1792
1793
1794
1795
1796
1797
1799
1804 return false;
1805
1806 if (!GroMatchesRetType)
1808 return true;
1809 }
1810
1812
1817 return false;
1818 }
1819
1822 if (GroMatchesRetType) {
1824 } else {
1826 S.Context, &FD, FD.getLocation(), FD.getLocation(),
1830
1833 return false;
1834
1839 return false;
1840
1843 return false;
1844
1846 false);
1847
1849
1850
1851
1855 return false;
1856
1858
1861 return false;
1862
1864 }
1865
1868 return false;
1869 }
1870
1871 if (!GroMatchesRetType &&
1872 castclang::ReturnStmt(ReturnStmt.get())->getNRVOCandidate() == GroDecl)
1874
1875 this->ReturnStmt = ReturnStmt.get();
1876 return true;
1877}
1878
1879
1881 if (T.isNull())
1888
1889 return S
1893}
1894
1895
1902 return Decl;
1903}
1904
1905
1906
1908 assert(isa(CurContext) && "not in a function scope");
1909 auto *FD = cast(CurContext);
1910
1912 if (!ScopeInfo->CoroutineParameterMoves.empty())
1913 return false;
1914
1915
1916
1917
1918
1919
1920
1921 for (auto *PD : FD->parameters()) {
1922 if (PD->getType()->isDependentType())
1923 continue;
1924
1925
1926 bool DeclReferenced = PD->isReferenced();
1927
1931
1932 PD->setReferenced(DeclReferenced);
1933
1935 return false;
1936
1937 Expr *CExpr = nullptr;
1938 if (PD->getType()->getAsCXXRecordDecl() ||
1939 PD->getType()->isRValueReferenceType())
1941 else
1942 CExpr = PDRefExpr.get();
1943
1944
1945
1946 auto *D = buildVarDecl(*this, Loc, PD->getType(), PD->getIdentifier());
1948
1949
1951 if (Stmt.isInvalid())
1952 return false;
1953
1954 ScopeInfo->CoroutineParameterMoves.insert(std::make_pair(PD, Stmt.get()));
1955 }
1956 return true;
1957}
1958
1961 if (!Res)
1963 return Res;
1964}
1965
1970
1973
1977
1979
1980 Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
1981 << "std::coroutine_traits";
1982 return nullptr;
1983 }
1984
1985
1988 Result.suppressDiagnostics();
1990 Diag(Found->getLocation(), diag::err_malformed_std_coroutine_traits);
1991 return nullptr;
1992 }
1993
1995}
This file provides some common utility functions for processing Lambda related AST Constructs.
Defines enum values for all the target-independent builtin functions.
Defines the clang::Expr interface and subclasses for C++ expressions.
llvm::MachO::Record Record
Defines the clang::Preprocessor interface.
static ExprResult buildCoroutineHandle(Sema &S, QualType PromiseType, SourceLocation Loc)
static void noteMemberDeclaredHere(Sema &S, Expr *E, FunctionScopeInfo &Fn)
static void checkReturnStmtInCoroutine(Sema &S, FunctionScopeInfo *FSI)
static bool isValidCoroutineContext(Sema &S, SourceLocation Loc, StringRef Keyword)
static void applySafeElideContext(Expr *Operand)
static Expr * buildStdNoThrowDeclRef(Sema &S, SourceLocation Loc)
Look up the std::nothrow object.
static ExprResult buildOperatorCoawaitCall(Sema &SemaRef, Scope *S, SourceLocation Loc, Expr *E)
static bool diagReturnOnAllocFailure(Sema &S, Expr *E, CXXRecordDecl *PromiseRecordDecl, FunctionScopeInfo &Fn)
static ExprResult buildPromiseCall(Sema &S, VarDecl *Promise, SourceLocation Loc, StringRef Name, MultiExprArg Args)
static Expr * castForMoving(Sema &S, Expr *E, QualType T=QualType())
static Expr * maybeTailCall(Sema &S, QualType RetType, Expr *E, SourceLocation Loc)
static ExprResult buildMemberCall(Sema &S, Expr *Base, SourceLocation Loc, StringRef Name, MultiExprArg Args)
static LookupResult lookupMember(Sema &S, const char *Name, CXXRecordDecl *RD, SourceLocation Loc, bool &Res)
static TypeSourceInfo * getTypeSourceInfoForStdAlignValT(Sema &S, SourceLocation Loc)
static bool isWithinCatchScope(Scope *S)
static bool findDeleteForPromise(Sema &S, SourceLocation Loc, QualType PromiseType, FunctionDecl *&OperatorDelete)
static VarDecl * buildVarDecl(Sema &S, SourceLocation Loc, QualType Type, IdentifierInfo *II)
Build a variable declaration for move parameter.
static void checkNoThrow(Sema &S, const Stmt *E, llvm::SmallPtrSetImpl< const Decl * > &ThrowingDecls)
Recursively check E and all its children to see if any call target (including constructor call) is de...
static ReadySuspendResumeResult buildCoawaitCalls(Sema &S, VarDecl *CoroPromise, SourceLocation Loc, Expr *E)
Build calls to await_ready, await_suspend, and await_resume for a co_await expression.
static bool checkSuspensionContext(Sema &S, SourceLocation Loc, StringRef Keyword)
static QualType lookupCoroutineHandleType(Sema &S, QualType PromiseType, SourceLocation Loc)
Look up the std::coroutine_handle.
static bool collectPlacementArgs(Sema &S, FunctionDecl &FD, SourceLocation Loc, SmallVectorImpl< Expr * > &PlacementArgs)
static CompoundStmt * buildCoroutineBody(Stmt *Body, ASTContext &Context)
static QualType lookupPromiseType(Sema &S, const FunctionDecl *FD, SourceLocation KwLoc)
Look up the std::coroutine_traits<...>::promise_type for the given function type.
static bool isAttributedCoroAwaitElidable(const QualType &QT)
static FunctionScopeInfo * checkCoroutineContext(Sema &S, SourceLocation Loc, StringRef Keyword, bool IsImplicit=false)
Check that this is a context in which a coroutine suspension can appear.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getRValueReferenceType(QualType T) const
Return the uniqued reference to the type for an rvalue reference to the specified type.
DeclarationNameTable DeclarationNames
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType getElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, QualType NamedType, TagDecl *OwnedTagDecl=nullptr) const
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
AddrLabelExpr - The GNU address of label extension, representing &&label.
SourceLocation getBeginLoc() const LLVM_READONLY
Represents a C++ constructor within a class.
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Represents a C++ struct/union/class.
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
Represents a C++ nested-name-specifier or a global scope specifier.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
Declaration of a class template.
void setExprNeedsCleanups(bool SideEffects)
Represents a 'co_await' expression.
CompoundStmt - This represents a group of statements like { stmt stmt }.
static CompoundStmt * Create(const ASTContext &C, ArrayRef< Stmt * > Stmts, FPOptionsOverride FPFeatures, SourceLocation LB, SourceLocation RB)
Represents a 'co_return' statement in the C++ Coroutines TS.
Represents the body of a coroutine.
static CoroutineBodyStmt * Create(const ASTContext &C, CtorArgs const &Args)
CoroutineStmtBuilder(Sema &S, FunctionDecl &FD, sema::FunctionScopeInfo &Fn, Stmt *Body)
Construct a CoroutineStmtBuilder and initialize the promise statement and initial/final suspends from...
bool buildDependentStatements()
Build the coroutine body statements that require a non-dependent promise type in order to construct.
bool buildStatements()
Build the coroutine body statements, including the "promise dependent" statements when the promise ty...
Represents a 'co_yield' expression.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
bool isInvalidDecl() const
SourceLocation getLocation() const
void setImplicit(bool I=true)
The name of a declaration.
SourceLocation getBeginLoc() const LLVM_READONLY
Represents a 'co_await' expression while the type of the promise is dependent.
RAII object that enters a new expression evaluation context.
This represents one expression.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
Represents difference between two FPOptions values.
Represents a function declaration or definition.
ArrayRef< ParmVarDecl * > parameters() const
Represents a prototype with parameter type info, e.g.
ArrayRef< QualType > getParamTypes() const
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
QualType getReturnType() const
One of these records is kept for each identifier that is lexed.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Describes the kind of initialization being performed, along with location information for tokens rela...
static InitializationKind CreateForInit(SourceLocation Loc, bool DirectInit, Expr *Init)
Create an initialization from an initializer (which, for direct initialization from a parenthesized l...
Describes the sequence of initializations required to initialize a given object or reference with a s...
ExprResult Perform(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, QualType *ResultType=nullptr)
Perform the actual initialization of the given entity based on the computed initialization sequence.
Describes an entity that is being initialized.
static InitializedEntity InitializeResult(SourceLocation ReturnLoc, QualType Type)
Create the initialization entity for the result of a function.
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
Represents the results of name lookup.
DeclClass * getAsSingle() const
const UnresolvedSetImpl & asUnresolvedSet() const
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
DeclarationName getLookupName() const
Gets the name to look up.
This represents a decl that may have a name.
Represent a C++ namespace.
A C++ nested-name-specifier augmented with source location information.
static NestedNameSpecifier * Create(const ASTContext &Context, NestedNameSpecifier *Prefix, const IdentifierInfo *II)
Builds a specifier combining a prefix and an identifier.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
decls_iterator decls_begin() const
decls_iterator decls_end() const
static ParenListExpr * Create(const ASTContext &Ctx, SourceLocation LParenLoc, ArrayRef< Expr * > Exprs, SourceLocation RParenLoc)
Create a paren list.
Represents a parameter to a function.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
IdentifierTable & getIdentifierTable()
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Scope - A scope is a transient data structure that is used while parsing the program.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Sema - This implements semantic analysis and AST building for C.
FunctionDecl * FindUsualDeallocationFunction(SourceLocation StartLoc, bool CanProvideSize, bool Overaligned, DeclarationName Name)
ExprResult BuildOperatorCoawaitCall(SourceLocation Loc, Expr *E, UnresolvedLookupExpr *Lookup)
Build a call to 'operator co_await' if there is a suitable operator for the given expression.
Scope * getCurScope() const
Retrieve the parser's current scope.
ExprResult BuildMemberReferenceExpr(Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, const Scope *S, ActOnMemberAccessExtraArgs *ExtraArgs=nullptr)
ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *InputExpr, bool IsAfterAmp=false)
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ LookupOperatorName
Look up of an operator name (e.g., operator+) for use with operator overloading.
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
bool checkFinalSuspendNoThrow(const Stmt *FinalSuspend)
Check that the expression co_await promise.final_suspend() shall not be potentially-throwing.
StmtResult BuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs)
ExprResult BuildCoyieldExpr(SourceLocation KwLoc, Expr *E)
void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body)
bool ActOnCoroutineBodyStart(Scope *S, SourceLocation KwLoc, StringRef Keyword)
VarDecl * buildCoroutinePromise(SourceLocation Loc)
StmtResult BuildCoreturnStmt(SourceLocation KwLoc, Expr *E, bool IsImplicit=false)
Expr * BuildBuiltinCallExpr(SourceLocation Loc, Builtin::ID Id, MultiExprArg CallArgs)
BuildBuiltinCallExpr - Create a call to a builtin function specified by Id.
ExprResult BuildResolvedCoawaitExpr(SourceLocation KwLoc, Expr *Operand, Expr *Awaiter, bool IsImplicit=false)
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
void FinalizeDeclaration(Decl *D)
FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform any semantic actions neces...
ExprResult ActOnCoyieldExpr(Scope *S, SourceLocation KwLoc, Expr *E)
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
ClassTemplateDecl * StdCoroutineTraitsCache
The C++ "std::coroutine_traits" template, which is defined in <coroutine_traits>
ASTContext & getASTContext() const
DeclRefExpr * BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
EnumDecl * getStdAlignValT() const
NamedReturnInfo getNamedReturnInfo(Expr *&E, SimplerImplicitMoveMode Mode=SimplerImplicitMoveMode::Normal)
Determine whether the given expression might be move-eligible or copy-elidable in either a (co_)retur...
StmtResult ActOnCoreturnStmt(Scope *S, SourceLocation KwLoc, Expr *E)
const LangOptions & getLangOpts() const
StmtResult ActOnFinishFullStmt(Stmt *Stmt)
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.
bool FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, AllocationFunctionScope NewScope, AllocationFunctionScope DeleteScope, QualType AllocType, bool IsArray, bool &PassAlignment, MultiExprArg PlaceArgs, FunctionDecl *&OperatorNew, FunctionDecl *&OperatorDelete, bool Diagnose=true)
Finds the overloads of operator new and delete that are appropriate for the allocation.
CleanupInfo Cleanup
Used to control the generation of ExprWithCleanups.
StmtResult ActOnNullStmt(SourceLocation SemiLoc, bool HasLeadingEmptyMacro=false)
ExprResult BuildUnresolvedCoawaitExpr(SourceLocation KwLoc, Expr *Operand, UnresolvedLookupExpr *Lookup)
bool buildCoroutineParameterMoves(SourceLocation Loc)
sema::FunctionScopeInfo * getCurFunction() const
QualType BuildReferenceType(QualType T, bool LValueRef, SourceLocation Loc, DeclarationName Entity)
Build a reference type.
ExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, const UnresolvedSetImpl &Fns, Expr *input, bool RequiresADL=true)
Create a unary operation that may resolve to an overloaded operator.
ExprResult ActOnCoawaitExpr(Scope *S, SourceLocation KwLoc, Expr *E)
ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS, LookupResult &R, bool NeedsADL, bool AcceptInvalidDecl=false)
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, DeclarationName Name, FunctionDecl *&Operator, bool Diagnose=true, bool WantSize=false, bool WantAligned=false)
MaterializeTemporaryExpr * CreateMaterializeTemporaryExpr(QualType T, Expr *Temporary, bool BoundToLvalueReference)
ExprResult PerformContextuallyConvertToBool(Expr *From)
PerformContextuallyConvertToBool - Perform a contextual conversion of the expression From to bool (C+...
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
ClassTemplateDecl * lookupCoroutineTraits(SourceLocation KwLoc, SourceLocation FuncLoc)
Lookup 'coroutine_traits' in std namespace and std::experimental namespace.
DeclContext * computeDeclContext(QualType T)
Compute the DeclContext that is associated with the given type.
QualType CheckTemplateIdType(TemplateName Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs)
StmtResult BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, bool AllowRecovery=false)
void CheckCompleteVariableDeclaration(VarDecl *VD)
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
ExprResult BuildOperatorCoawaitLookupExpr(Scope *S, SourceLocation Loc)
StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
Expr * MaybeCreateExprWithCleanups(Expr *SubExpr)
MaybeCreateExprWithCleanups - If the current full-expression requires any cleanups,...
FullExprArg MakeFullDiscardedValueExpr(Expr *Arg)
NamespaceDecl * getStdNamespace() const
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
void ActOnUninitializedDecl(Decl *dcl)
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
ExprResult BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, TypeSourceInfo *Ty, Expr *E, SourceRange AngleBrackets, SourceRange Parens)
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,...
void clearDelayedTypo(TypoExpr *TE)
Clears the state of the given TypoExpr.
void CheckVariableDeclarationType(VarDecl *NewVD)
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
ExprResult ActOnCXXThis(SourceLocation Loc)
AllocationFunctionScope
The scope in which to find allocation functions.
@ AFS_Both
Look for allocation functions in both the global scope and in the scope of the allocated class.
@ AFS_Class
Only look for allocation functions in the scope of the allocated class.
@ AFS_Global
Only look for allocation functions in the global scope.
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
static CanThrowResult canCalleeThrow(Sema &S, const Expr *E, const Decl *D, SourceLocation Loc=SourceLocation())
Determine whether the callee of a particular function call can throw.
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
A convenient class for passing around template argument information.
void addArgument(const TemplateArgumentLoc &Loc)
Location wrapper for a TemplateArgument.
Represents a template argument.
Represents a C++ template name within the type system.
Represents a declaration of a type.
A container of type source information.
The base class of the type hierarchy.
bool isStructureType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isBooleanType() const
bool isVoidPointerType() const
const T * castAs() const
Member-template castAs.
bool isReferenceType() const
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isRecordType() const
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
static UnresolvedLookupExpr * Create(const ASTContext &Context, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool RequiresADL, UnresolvedSetIterator Begin, UnresolvedSetIterator End, bool KnownDependent, bool KnownInstantiationDependent)
void append(iterator I, iterator E)
A set of unresolved declarations.
Represents a variable declaration or definition.
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
@ CallInit
Call-style initialization (C++98)
void setNRVOVariable(bool NRVO)
Retains information about a function, method, or block that is currently being parsed.
SourceLocation FirstCoroutineStmtLoc
First coroutine statement in the current function.
std::pair< Stmt *, Stmt * > CoroutineSuspends
The initial and final coroutine suspend points.
VarDecl * CoroutinePromise
The promise object for this coroutine, if any.
bool hasInvalidCoroutineSuspends() const
StringRef getFirstCoroutineStmtKeyword() const
SourceLocation FirstReturnLoc
First 'return' statement in the current function.
SourceLocation FirstSEHTryLoc
First SEH '__try' statement in the current function.
The JSON file list parser is used to communicate input to InstallAPI.
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
const FunctionProtoType * T
OpaqueValueExpr * OpaqueValue
Stmt * ReturnStmtOnAllocFailure
ArrayRef< Stmt * > ParamMoves
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
DeclarationName getName() const
getName - Returns the embedded declaration name.