clang: lib/Parse/ParseExprCXX.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
28#include "llvm/Support/Compiler.h"
29#include "llvm/Support/ErrorHandling.h"
30#include
31
32using namespace clang;
33
35 switch (Kind) {
36
37 case tok::unknown: return 0;
38
39 case tok::kw_addrspace_cast: return 1;
40 case tok::kw_const_cast: return 2;
41 case tok::kw_dynamic_cast: return 3;
42 case tok::kw_reinterpret_cast: return 4;
43 case tok::kw_static_cast: return 5;
44 default:
45 llvm_unreachable("Unknown type for digraph error message.");
46 }
47}
48
49
50bool Parser::areTokensAdjacent(const Token &First, const Token &Second) {
54 return FirstEnd == SM.getSpellingLoc(Second.getLocation());
55}
56
57
60
61 if (!AtDigraph)
62 PP.Lex(DigraphToken);
63 PP.Lex(ColonToken);
64
68 P.Diag(DigraphToken.getLocation(), diag::err_missing_whitespace_digraph)
71
72
73 ColonToken.setKind(tok::coloncolon);
76 DigraphToken.setKind(tok::less);
78
79
80 PP.EnterToken(ColonToken, true);
81 if (!AtDigraph)
82 PP.EnterToken(DigraphToken, true);
83}
84
85
86
87void Parser::CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectType,
88 bool EnteringContext,
90 if (!Next.is(tok::l_square) || Next.getLength() != 2)
91 return;
92
93 Token SecondToken = GetLookAheadToken(2);
94 if (!SecondToken.is(tok::colon) || !areTokensAdjacent(Next, SecondToken))
95 return;
96
100 bool MemberOfUnknownSpecialization;
103 Template, MemberOfUnknownSpecialization))
104 return;
105
106 FixDigraph(*this, PP, Next, SecondToken, tok::unknown,
107 false);
108}
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159bool Parser::ParseOptionalCXXScopeSpecifier(
161 bool EnteringContext, bool *MayBePseudoDestructor, bool IsTypename,
162 const IdentifierInfo **LastII, bool OnlyNamespace, bool InUsingDeclaration,
163 bool Disambiguation) {
165 "Call sites of this function should be guarded by checking for C++");
166
167 if (Tok.is(tok::annot_cxxscope)) {
168 assert(!LastII && "want last identifier but have already annotated scope");
169 assert(!MayBePseudoDestructor && "unexpected annot_cxxscope");
172 SS);
173 ConsumeAnnotationToken();
174 return false;
175 }
176
177
178 bool CheckForDestructor = false;
179 if (MayBePseudoDestructor && *MayBePseudoDestructor) {
180 CheckForDestructor = true;
181 *MayBePseudoDestructor = false;
182 }
183
184 if (LastII)
185 *LastII = nullptr;
186
187 bool HasScopeSpecifier = false;
188
189 if (Tok.is(tok::coloncolon)) {
190
192 if (NextKind == tok::kw_new || NextKind == tok::kw_delete)
193 return false;
194
195 if (NextKind == tok::l_brace) {
196
197
199 } else {
200
202 return true;
203
204 HasScopeSpecifier = true;
205 }
206 }
207
208 if (Tok.is(tok::kw___super)) {
210 if (!Tok.is(tok::coloncolon)) {
211 Diag(Tok.getLocation(), diag::err_expected_coloncolon_after_super);
212 return true;
213 }
214
216 }
217
218 if (!HasScopeSpecifier &&
219 Tok.isOneOf(tok::kw_decltype, tok::annot_decltype)) {
223
225
226
229 AnnotateExistingDecltypeSpecifier(DS, DeclLoc, EndLoc);
230 return false;
231 }
232
235
236 HasScopeSpecifier = true;
237 }
238
239 else if (!HasScopeSpecifier && Tok.is(tok::identifier) &&
240 GetLookAheadToken(1).is(tok::ellipsis) &&
241 GetLookAheadToken(2).is(tok::l_square) &&
242 !GetLookAheadToken(3).is(tok::r_square)) {
248 return false;
249
251 DS.getRepAsType().get(), DS.getPackIndexingExpr(), DS.getBeginLoc(),
252 DS.getEllipsisLoc());
253
254 if (Type.isNull())
255 return false;
256
257
258
259
260
261
262
263
264
265
267 getCurScope()->isFunctionDeclarationScope())
268 Diag(Start, diag::warn_pre_cxx26_ambiguous_pack_indexing_type) << Type;
269
272 EndLoc);
273 return false;
274 }
276 std::move(Type)))
278 HasScopeSpecifier = true;
279 }
280
281
282 auto SavedType = PreferredType;
283 while (true) {
284 if (HasScopeSpecifier) {
285 if (Tok.is(tok::code_completion)) {
286 cutOffParsing();
287
288
290 getCurScope(), SS, EnteringContext, InUsingDeclaration,
292
293
294
295
297 return true;
298 }
299
300
301
302
303
304
305
306
307
308
309
310 ObjectType = nullptr;
311 }
312
313
314
315
316
317
318 if (Tok.is(tok::kw_template)) {
319
320
321
322 if (!HasScopeSpecifier && !ObjectType)
323 break;
324
325 TentativeParsingAction TPA(*this);
327
329 if (Tok.is(tok::identifier)) {
330
333 } else if (Tok.is(tok::kw_operator)) {
334
335
336
337
338 if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType,
340 TPA.Commit();
341 break;
342 }
343
347 diag::err_id_after_template_in_nested_name_spec)
349 TPA.Commit();
350 break;
351 }
352 } else {
353 TPA.Revert();
354 break;
355 }
356
357
358
359
360 if (Tok.isNot(tok::less)) {
361 TPA.Revert();
362 break;
363 }
364
365
366 TPA.Commit();
370 EnteringContext, Template, true);
371 if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateKWLoc,
373 return true;
374
375 continue;
376 }
377
378 if (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) {
379
380
381
382
383
384
385
387 if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde)) {
388 *MayBePseudoDestructor = true;
389 return false;
390 }
391
392 if (LastII)
393 *LastII = TemplateId->Name;
394
395
396 ConsumeAnnotationToken();
397
398 assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");
400
401 HasScopeSpecifier = true;
402
405
408 SS,
413 TemplateArgsPtr,
415 CCLoc,
416 EnteringContext)) {
421 }
422
423 continue;
424 }
425
427#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
428#include "clang/Basic/TransformTypeTraits.def"
429 if (().is(tok::l_paren)) {
430 Tok.setKind(tok::identifier);
431 Diag(Tok, diag::ext_keyword_as_ident)
433 continue;
434 }
435 [[fallthrough]];
436 default:
437 break;
438 }
439
440
441
442 if (Tok.isNot(tok::identifier))
443 break;
444
446
447
448
449
450
453 ObjectType);
454
455
456
457 if (Next.is(tok::colon) && !ColonIsSacred) {
459 EnteringContext) &&
460
461
462
464 Diag(Next, diag::err_unexpected_colon_in_nested_name_spec)
466
467 Next.setKind(tok::coloncolon);
468 }
469 }
470
471 if (Next.is(tok::coloncolon) && GetLookAheadToken(2).is(tok::l_brace)) {
472
473
475 ConsumeToken();
477 << tok::identifier;
478 UnconsumeToken(Identifier);
479 Next = NextToken();
480 }
481
482 if (Next.is(tok::coloncolon)) {
483 if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde)) {
484 *MayBePseudoDestructor = true;
485 return false;
486 }
487
488 if (ColonIsSacred) {
489 const Token &Next2 = GetLookAheadToken(2);
490 if (Next2.is(tok::kw_private) || Next2.is(tok::kw_protected) ||
491 Next2.is(tok::kw_public) || Next2.is(tok::kw_virtual)) {
492 Diag(Next2, diag::err_unexpected_token_in_nested_name_spec)
495 Token ColonColon;
496 PP.Lex(ColonColon);
497 ColonColon.setKind(tok::colon);
498 PP.EnterToken(ColonColon, true);
499 break;
500 }
501 }
502
503 if (LastII)
504 *LastII = &II;
505
506
507
510 assert(Tok.isOneOf(tok::coloncolon, tok::colon) &&
511 "NextToken() not working properly!");
512 Token ColonColon = Tok;
514
515 bool IsCorrectedToColon = false;
516 bool *CorrectionFlagPtr = ColonIsSacred ? &IsCorrectedToColon : nullptr;
518 getCurScope(), IdInfo, EnteringContext, SS, CorrectionFlagPtr,
519 OnlyNamespace)) {
520
521
522 if (CorrectionFlagPtr && IsCorrectedToColon) {
523 ColonColon.setKind(tok::colon);
524 PP.EnterToken(Tok, true);
525 PP.EnterToken(ColonColon, true);
527 break;
528 }
530 }
531 HasScopeSpecifier = true;
532 continue;
533 }
534
535 CheckForTemplateAndDigraph(Next, ObjectType, EnteringContext, II, SS);
536
537
538
539 if (Next.is(tok::less)) {
540
544 bool MemberOfUnknownSpecialization;
547 false, TemplateName, ObjectType,
548 EnteringContext, Template, MemberOfUnknownSpecialization,
549 Disambiguation)) {
550
551
552
553
555 isTemplateArgumentList(1) == TPResult::False)
556 break;
557
558
559
560
561
562
563
564
566 if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),
568 return true;
569 continue;
570 }
571
572 if (MemberOfUnknownSpecialization && !Disambiguation &&
573 (ObjectType || SS.isSet()) &&
574 (IsTypename || isTemplateArgumentList(1) == TPResult::True)) {
575
576
577 if (!ObjectHadErrors) {
578
579
580
581
582 unsigned DiagID = diag::err_missing_dependent_template_keyword;
584 DiagID = diag::warn_missing_dependent_template_keyword;
585
589 }
590
592
595 EnteringContext, Template, true);
596 if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),
598 return true;
599
600 continue;
601 }
602 }
603
604
605
606 break;
607 }
608
609
610
611
612 if (CheckForDestructor && !HasScopeSpecifier && Tok.is(tok::tilde))
613 *MayBePseudoDestructor = true;
614
615 return false;
616}
617
619 bool isAddressOfOperand,
620 Token &Replacement) {
622
623
625 case tok::annot_non_type: {
626 NamedDecl *ND = getNonTypeAnnotation(Tok);
629 break;
630 }
631
632 case tok::annot_non_type_dependent: {
635
636
637
638 if (isAddressOfOperand && isPostfixExpressionSuffixStart())
639 isAddressOfOperand = false;
640
642 isAddressOfOperand);
643 break;
644 }
645
646 case tok::annot_non_type_undeclared: {
648 "undeclared non-type annotation should be unqualified");
652 break;
653 }
654
655 default:
659 false,
660 false,
661 false,
662 false,
663 false, &TemplateKWLoc, Name))
665
666
667
668 if (isAddressOfOperand && isPostfixExpressionSuffixStart())
669 isAddressOfOperand = false;
670
672 getCurScope(), SS, TemplateKWLoc, Name, Tok.is(tok::l_paren),
673 isAddressOfOperand, nullptr, false,
674 &Replacement);
675 break;
676 }
677
678
679 E = tryParseCXXPackIndexingExpression(E);
680
681 if (.isInvalid() &&
.isUnset() && Tok.is(tok::less))
682 checkPotentialAngleBracket(E);
683 return E;
684}
685
686ExprResult Parser::ParseCXXPackIndexingExpression(ExprResult PackIdExpression) {
687 assert(Tok.is(tok::ellipsis) && NextToken().is(tok::l_square) &&
688 "expected ...[");
691 T.consumeOpen();
693 if (T.consumeClose() || IndexExpr.isInvalid())
696 EllipsisLoc, T.getOpenLocation(),
697 IndexExpr.get(), T.getCloseLocation());
698}
699
701Parser::tryParseCXXPackIndexingExpression(ExprResult PackIdExpression) {
703 if (!PackIdExpression.isInvalid() && !PackIdExpression.isUnset() &&
704 Tok.is(tok::ellipsis) && NextToken().is(tok::l_square)) {
705 E = ParseCXXPackIndexingExpression(E);
706 }
707 return E;
708}
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752ExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {
753
754
755
756
758 ParseOptionalCXXScopeSpecifier(SS, nullptr,
759 false,
760 false);
761
762 Token Replacement;
764 tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement);
765 if (Result.isUnset()) {
766
767
768 UnconsumeToken(Replacement);
769 Result = tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement);
770 }
771 assert(.isUnset() && "Typo correction suggested a keyword replacement "
772 "for a previous keyword suggestion");
774}
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821ExprResult Parser::ParseLambdaExpression() {
822
824 if (ParseLambdaIntroducer(Intro)) {
829 }
830
831 return ParseLambdaExpressionAfterIntroducer(Intro);
832}
833
834
835
836
837
838ExprResult Parser::TryParseLambdaExpression() {
840 "Not at the start of a possible lambda expression.");
841
843 if (Next.is(tok::eof))
845
846 const Token After = GetLookAheadToken(2);
847
848 if (Next.is(tok::r_square) ||
849 Next.is(tok::equal) ||
850 (Next.is(tok::amp) &&
851 After.isOneOf(tok::r_square, tok::comma)) ||
852 (Next.is(tok::identifier) &&
853 After.is(tok::r_square)) ||
854 Next.is(tok::ellipsis)) {
855 return ParseLambdaExpression();
856 }
857
858
859
860 if (Next.is(tok::identifier) && After.is(tok::identifier))
862
863
864
865
866
867
869 {
870 TentativeParsingAction TPA(*this);
871 LambdaIntroducerTentativeParse Tentative;
872 if (ParseLambdaIntroducer(Intro, &Tentative)) {
873 TPA.Commit();
875 }
876
877 switch (Tentative) {
878 case LambdaIntroducerTentativeParse::Success:
879 TPA.Commit();
880 break;
881
882 case LambdaIntroducerTentativeParse::Incomplete:
883
884
885 TPA.Revert();
887 if (ParseLambdaIntroducer(Intro))
889 break;
890
891 case LambdaIntroducerTentativeParse::MessageSend:
892 case LambdaIntroducerTentativeParse::Invalid:
893
894 TPA.Revert();
896 }
897 }
898
899 return ParseLambdaExpressionAfterIntroducer(Intro);
900}
901
902
903
904
905
906
907
908
909
910
912 LambdaIntroducerTentativeParse *Tentative) {
913 if (Tentative)
914 *Tentative = LambdaIntroducerTentativeParse::Success;
915
916 assert(Tok.is(tok::l_square) && "Lambda expressions begin with '['.");
918 T.consumeOpen();
919
921
922 bool First = true;
923
924
925
926 auto Invalid = [&](llvm::function_ref<void()> Action) {
927 if (Tentative) {
928 *Tentative = LambdaIntroducerTentativeParse::Invalid;
929 return false;
930 }
931 Action();
932 return true;
933 };
934
935
936
937 auto NonTentativeAction = [&](llvm::function_ref<void()> Action) {
938 if (Tentative)
939 *Tentative = LambdaIntroducerTentativeParse::Incomplete;
940 else
941 Action();
942 };
943
944
945 if (Tok.is(tok::amp) &&
951
952
953 Tentative = nullptr;
954 }
955 } else if (Tok.is(tok::equal)) {
959 Tentative = nullptr;
960 }
961
962 while (Tok.isNot(tok::r_square)) {
964 if (Tok.isNot(tok::comma)) {
965
966
967
968
969 if (Tok.is(tok::code_completion) &&
971 cutOffParsing();
974 false);
975 break;
976 }
977
979 Diag(Tok.getLocation(), diag::err_expected_comma_or_rsquare);
980 });
981 }
983 }
984
985 if (Tok.is(tok::code_completion)) {
986 cutOffParsing();
987
988
991 else
994 false);
995 break;
996 }
997
999
1000
1008
1009 if (Tok.is(tok::star)) {
1011 if (Tok.is(tok::kw_this)) {
1014 } else {
1016 Diag(Tok.getLocation(), diag::err_expected_star_this_capture);
1017 });
1018 }
1019 } else if (Tok.is(tok::kw_this)) {
1022 } else if (Tok.isOneOf(tok::amp, tok::equal) &&
1025
1026
1027
1028
1030 [&] { Diag(Tok.getLocation(), diag::err_capture_default_first); });
1031 } else {
1033
1034 if (Tok.is(tok::amp)) {
1037
1038 if (Tok.is(tok::code_completion)) {
1039 cutOffParsing();
1042 true);
1043 break;
1044 }
1045 }
1046
1048
1049 if (Tok.is(tok::identifier)) {
1052 } else if (Tok.is(tok::kw_this)) {
1054
1055 Diag(Tok.getLocation(), diag::err_this_captured_by_reference);
1056 });
1057 } else {
1060 });
1061 }
1062
1064
1065 if (Tok.is(tok::l_paren)) {
1067 Parens.consumeOpen();
1068
1070
1071 ExprVector Exprs;
1072 if (Tentative) {
1074 *Tentative = LambdaIntroducerTentativeParse::Incomplete;
1075 } else if (ParseExpressionList(Exprs)) {
1078 } else {
1079 Parens.consumeClose();
1081 Parens.getCloseLocation(),
1082 Exprs);
1083 }
1084 } else if (Tok.isOneOf(tok::l_brace, tok::equal)) {
1085
1086
1087
1090
1093 else
1095
1096 if (!Tentative) {
1097 Init = ParseInitializer();
1098 } else if (Tok.is(tok::l_brace)) {
1100 Braces.consumeOpen();
1102 *Tentative = LambdaIntroducerTentativeParse::Incomplete;
1103 } else {
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1126 Init = ParseInitializer();
1127 if (.isInvalid())
1129
1131
1133
1134
1136 Tok.setKind(tok::annot_primary_expr);
1137 setExprAnnotation(Tok, Init);
1140
1141
1142 ConsumeAnnotationToken();
1143 }
1144 }
1145 }
1146
1148 }
1149
1150
1151 if (Tentative && Tok.is(tok::identifier) &&
1153
1154 *Tentative = LambdaIntroducerTentativeParse::MessageSend;
1155 return false;
1156 }
1157
1158
1160 if (llvm::any_of(EllipsisLocs,
1162
1163
1166 !InitCapture ? &EllipsisLocs[2] :
1168 &EllipsisLocs[0];
1169 EllipsisLoc = *ExpectedEllipsisLoc;
1170
1171 unsigned DiagID = 0;
1173 DiagID = diag::err_lambda_capture_misplaced_ellipsis;
1176 EllipsisLoc = Loc;
1177 }
1178 } else {
1179 unsigned NumEllipses = std::accumulate(
1180 std::begin(EllipsisLocs), std::end(EllipsisLocs), 0,
1182 if (NumEllipses > 1)
1183 DiagID = diag::err_lambda_capture_multiple_ellipses;
1184 }
1185 if (DiagID) {
1186 NonTentativeAction([&] {
1187
1190 if (&Loc != ExpectedEllipsisLoc && Loc.isValid()) {
1191 DiagLoc = Loc;
1192 break;
1193 }
1194 }
1195 assert(DiagLoc.isValid() && "no location for diagnostic");
1196
1197
1198
1199 auto &&D = Diag(DiagLoc, DiagID);
1200 if (DiagID == diag::err_lambda_capture_misplaced_ellipsis) {
1202 InitCapture ? Loc
1206 }
1208 if (&Loc != ExpectedEllipsisLoc && Loc.isValid())
1210 }
1211 });
1212 }
1213 }
1214
1215
1216
1217
1218
1220 if (Init.isUsable())
1222 if (Init.isUsable()) {
1223 NonTentativeAction([&] {
1224
1225
1226 Expr *InitExpr = Init.get();
1227
1228
1230 Loc, Kind == LCK_ByRef, EllipsisLoc, Id, InitKind, InitExpr);
1231 Init = InitExpr;
1232 });
1233 }
1234
1236
1238 InitCaptureType, SourceRange(LocStart, LocEnd));
1239 }
1240
1241 T.consumeClose();
1243 return false;
1244}
1245
1254 assert(ConstexprLoc.isInvalid());
1255 assert(ConstevalLoc.isInvalid());
1256
1257
1258
1259
1260 auto ConsumeLocation = [&P, &DeclEndLoc](SourceLocation &SpecifierLoc,
1261 int DiagIndex) {
1262 if (SpecifierLoc.isValid()) {
1263 P.Diag(P.getCurToken().getLocation(),
1264 diag::err_lambda_decl_specifier_repeated)
1265 << DiagIndex
1267 }
1268 SpecifierLoc = P.ConsumeToken();
1269 DeclEndLoc = SpecifierLoc;
1270 };
1271
1272 while (true) {
1273 switch (P.getCurToken().getKind()) {
1274 case tok::kw_mutable:
1275 ConsumeLocation(MutableLoc, 0);
1276 break;
1277 case tok::kw_static:
1278 ConsumeLocation(StaticLoc, 1);
1279 break;
1280 case tok::kw_constexpr:
1281 ConsumeLocation(ConstexprLoc, 2);
1282 break;
1283 case tok::kw_consteval:
1284 ConsumeLocation(ConstevalLoc, 3);
1285 break;
1286 default:
1287 return;
1288 }
1289 }
1290}
1291
1294 if (StaticLoc.isValid()) {
1295 P.Diag(StaticLoc, .getLangOpts().CPlusPlus23
1296 ? diag::err_static_lambda
1297 : diag::warn_cxx20_compat_static_lambda);
1298 const char *PrevSpec = nullptr;
1299 unsigned DiagID = 0;
1301 PrevSpec, DiagID,
1302 P.getActions().getASTContext().getPrintingPolicy());
1303 assert(PrevSpec == nullptr && DiagID == 0 &&
1304 "Static cannot have been set previously!");
1305 }
1306}
1307
1308static void
1311 if (ConstexprLoc.isValid()) {
1312 P.Diag(ConstexprLoc, .getLangOpts().CPlusPlus17
1313 ? diag::ext_constexpr_on_lambda_cxx17
1314 : diag::warn_cxx14_compat_constexpr_on_lambda);
1315 const char *PrevSpec = nullptr;
1316 unsigned DiagID = 0;
1318 DiagID);
1319 assert(PrevSpec == nullptr && DiagID == 0 &&
1320 "Constexpr cannot have been set previously!");
1321 }
1322}
1323
1327 if (ConstevalLoc.isValid()) {
1328 P.Diag(ConstevalLoc, diag::warn_cxx20_compat_consteval);
1329 const char *PrevSpec = nullptr;
1330 unsigned DiagID = 0;
1332 DiagID);
1333 if (DiagID != 0)
1334 P.Diag(ConstevalLoc, DiagID) << PrevSpec;
1335 }
1336}
1337
1343 return;
1344
1345
1346
1347
1348
1349 if (MutableLoc.isValid())
1350 P.Diag(StaticLoc, diag::err_static_mutable_lambda);
1352 P.Diag(StaticLoc, diag::err_static_lambda_captures);
1353 }
1354}
1355
1356
1357
1358ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
1362 Diag(LambdaBeginLoc, diag::ext_hlsl_lambda) << 1;
1363 else
1365 ? diag::warn_cxx98_compat_lambda
1366 : diag::ext_lambda)
1367 << 0;
1368
1370 "lambda expression parsing");
1371
1372
1375 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
1376
1380
1383
1386
1387
1388
1389
1390
1391 while (true) {
1392 if (Tok.is(tok::kw___noinline__)) {
1395 Attributes.addNew(AttrName, AttrNameLoc, nullptr,
1396 AttrNameLoc, nullptr,
1397 0, tok::kw___noinline__);
1398 } else if (Tok.is(tok::kw___attribute))
1399 ParseGNUAttributes(Attributes, nullptr, &D);
1400 else
1401 break;
1402 }
1403
1404 D.takeAttributes(Attributes);
1405 }
1406
1407 MultiParseScope TemplateParamScope(*this);
1408 if (Tok.is(tok::less)) {
1410 ? diag::warn_cxx17_compat_lambda_template_parameter_list
1411 : diag::ext_lambda_template_parameter_list);
1412
1415 if (ParseTemplateParameters(TemplateParamScope,
1416 CurTemplateDepthTracker.getDepth(),
1417 TemplateParams, LAngleLoc, RAngleLoc)) {
1420 }
1421
1422 if (TemplateParams.empty()) {
1423 Diag(RAngleLoc,
1424 diag::err_lambda_template_parameter_list_empty);
1425 } else {
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435 ++CurTemplateDepthTracker;
1438 RequiresClause =
1440 false));
1443 }
1444
1446 Intro, LAngleLoc, TemplateParams, RAngleLoc, RequiresClause);
1447 }
1448 }
1449
1450
1451
1452
1453
1454 if (isCXX11AttributeSpecifier()) {
1456 ? diag::warn_cxx20_compat_decl_attrs_on_lambda
1457 : diag::ext_decl_attrs_on_lambda)
1459 MaybeParseCXX11Attributes(D);
1460 }
1461
1466 bool HasParentheses = false;
1467 bool HasSpecifiers = false;
1469
1473
1474
1477
1478 if (Tok.is(tok::l_paren)) {
1480 T.consumeOpen();
1481 LParenLoc = T.getOpenLocation();
1482
1483 if (Tok.isNot(tok::r_paren)) {
1485 CurTemplateDepthTracker.getOriginalDepth());
1486
1487 ParseParameterDeclarationClause(D, Attributes, ParamInfo, EllipsisLoc);
1488
1489
1490
1491
1492
1494 CurTemplateDepthTracker.setAddedDepth(1);
1495 }
1496
1497 T.consumeClose();
1498 DeclEndLoc = RParenLoc = T.getCloseLocation();
1499 HasParentheses = true;
1500 }
1501
1502 HasSpecifiers =
1503 Tok.isOneOf(tok::kw_mutable, tok::arrow, tok::kw___attribute,
1504 tok::kw_constexpr, tok::kw_consteval, tok::kw_static,
1505 tok::kw___private, tok::kw___global, tok::kw___local,
1506 tok::kw___constant, tok::kw___generic, tok::kw_groupshared,
1507 tok::kw_requires, tok::kw_noexcept) ||
1509 (Tok.is(tok::l_square) && NextToken().is(tok::l_square));
1510
1511 if (HasSpecifiers && !HasParentheses && ().CPlusPlus23) {
1512
1513
1514
1515 Diag(Tok, diag::ext_lambda_missing_parens)
1517 }
1518
1519 if (HasParentheses || HasSpecifiers) {
1520
1521
1522
1523 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec, Attributes);
1524
1525
1529
1531 ConstevalLoc, DeclEndLoc);
1532
1534
1538 }
1539
1541
1542 if (!HasParentheses)
1544
1545 if (HasSpecifiers || HasParentheses) {
1546
1553
1554 ESpecType = tryParseExceptionSpecification(
1555 false, ESpecRange, DynamicExceptions,
1556 DynamicExceptionRanges, NoexceptExpr, ExceptionSpecTokens);
1557
1559 DeclEndLoc = ESpecRange.getEnd();
1560
1561
1562 if (MaybeParseCXX11Attributes(Attributes))
1563 DeclEndLoc = Attributes.Range.getEnd();
1564
1565
1566 if (Tok.isOneOf(tok::kw___private, tok::kw___global, tok::kw___local,
1567 tok::kw___constant, tok::kw___generic)) {
1568 ParseOpenCLQualifiers(DS.getAttributes());
1570 }
1571
1573
1574
1575 if (Tok.is(tok::arrow)) {
1578 TrailingReturnType =
1579 ParseTrailingReturnType(Range, false);
1583 }
1584
1587 true,
1588 false, LParenLoc, ParamInfo.data(),
1589 ParamInfo.size(), EllipsisLoc, RParenLoc,
1590 true,
1591 NoLoc, MutableLoc, ESpecType,
1592 ESpecRange, DynamicExceptions.data(),
1593 DynamicExceptionRanges.data(), DynamicExceptions.size(),
1594 NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr,
1595 nullptr,
1596 {}, LParenLoc, FunLocalRangeEnd, D,
1597 TrailingReturnType, TrailingReturnTypeLoc, &DS),
1598 std::move(Attributes), DeclEndLoc);
1599
1600
1601
1602 if (HasParentheses)
1604
1605 if (HasParentheses && Tok.is(tok::kw_requires))
1606 ParseTrailingRequiresClause(D);
1607 }
1608
1609
1610
1612 for (const ParsedAttr &A : Attributes)
1613 if (A.getKind() == ParsedAttr::AT_CUDADevice ||
1614 A.getKind() == ParsedAttr::AT_CUDAHost ||
1615 A.getKind() == ParsedAttr::AT_CUDAGlobal)
1616 Diag(A.getLoc(), diag::warn_cuda_attr_lambda_position)
1617 << A.getAttrName()->getName();
1618 }
1619
1621
1622
1623
1626 ParseScope BodyScope(this, ScopeFlags);
1627
1629
1630
1631 if (!Tok.is(tok::l_brace)) {
1632 Diag(Tok, diag::err_expected_lambda_body);
1635 }
1636
1638 BodyScope.Exit();
1639 TemplateParamScope.Exit();
1640 LambdaScope.Exit();
1641
1642 if (.isInvalid() && !TrailingReturnType.isInvalid() &&
1643 .isInvalidType())
1645
1648}
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1663 const char *CastName = nullptr;
1664
1665 switch (Kind) {
1666 default: llvm_unreachable("Unknown C++ cast!");
1667 case tok::kw_addrspace_cast: CastName = "addrspace_cast"; break;
1668 case tok::kw_const_cast: CastName = "const_cast"; break;
1669 case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break;
1670 case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break;
1671 case tok::kw_static_cast: CastName = "static_cast"; break;
1672 }
1673
1676
1677
1678
1679 if (Tok.is(tok::l_square) && Tok.getLength() == 2) {
1681 if (Next.is(tok::colon) && areTokensAdjacent(Tok, Next))
1682 FixDigraph(*this, PP, Tok, Next, Kind, true);
1683 }
1684
1685 if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName))
1687
1688
1690 ParseSpecifierQualifierList(DS, AS_none,
1691 DeclSpecContext::DSC_type_specifier);
1692
1693
1696 ParseDeclarator(DeclaratorInfo);
1697
1699
1700 if (ExpectAndConsume(tok::greater))
1701 return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << tok::less);
1702
1704
1705 if (T.expectAndConsume(diag::err_expected_lparen_after, CastName))
1707
1709
1710
1711 T.consumeClose();
1712
1713 if (.isInvalid() && !DeclaratorInfo.isInvalidType())
1715 LAngleBracketLoc, DeclaratorInfo,
1716 RAngleBracketLoc,
1717 T.getOpenLocation(), Result.get(),
1718 T.getCloseLocation());
1719
1721}
1722
1723
1724
1725
1726
1727
1728
1729ExprResult Parser::ParseCXXTypeid() {
1730 assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!");
1731
1735
1736
1737 if (T.expectAndConsume(diag::err_expected_lparen_after, "typeid"))
1739 LParenLoc = T.getOpenLocation();
1740
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1759
1760 if (isTypeIdInParens()) {
1762
1763
1764 T.consumeClose();
1765 RParenLoc = T.getCloseLocation();
1768
1770 Ty.get().getAsOpaquePtr(), RParenLoc);
1771 } else {
1773
1774
1775 if (Result.isInvalid())
1777 else {
1778 T.consumeClose();
1779 RParenLoc = T.getCloseLocation();
1782
1784 Result.get(), RParenLoc);
1785 }
1786 }
1787
1789}
1790
1791
1792
1793
1794
1795
1796ExprResult Parser::ParseCXXUuidof() {
1797 assert(Tok.is(tok::kw___uuidof) && "Not '__uuidof'!");
1798
1801
1802
1803 if (T.expectAndConsume(diag::err_expected_lparen_after, "__uuidof"))
1805
1807
1808 if (isTypeIdInParens()) {
1810
1811
1812 T.consumeClose();
1813
1816
1818 Ty.get().getAsOpaquePtr(),
1819 T.getCloseLocation());
1820 } else {
1824
1825
1826 if (Result.isInvalid())
1828 else {
1829 T.consumeClose();
1830
1832 false,
1833 Result.get(), T.getCloseLocation());
1834 }
1835 }
1836
1838}
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1876
1877
1880 if (Tok.is(tok::identifier)) {
1883 assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail");
1885 } else if (Tok.is(tok::annot_template_id)) {
1887
1891 ConsumeAnnotationToken();
1892 assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail");
1894 } else {
1895 assert(SS.isEmpty() && "missing last component of nested name specifier");
1897 }
1898
1899
1900 assert(Tok.is(tok::tilde) && "ParseOptionalCXXScopeSpecifier fail");
1902
1903 if (Tok.is(tok::kw_decltype) && !FirstTypeName.isValid()) {
1905 ParseDecltypeSpecifier(DS);
1906 if (DS.getTypeSpecType() == TST_error)
1909 TildeLoc, DS);
1910 }
1911
1912 if (!Tok.is(tok::identifier)) {
1913 Diag(Tok, diag::err_destructor_tilde_identifier);
1915 }
1916
1917
1918 if (GetLookAheadToken(1).is(tok::ellipsis) &&
1919 GetLookAheadToken(2).is(tok::l_square)) {
1921 ParsePackIndexingType(DS);
1923 TildeLoc, DS);
1924 }
1925
1926
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940 if (Tok.is(tok::less) &&
1941 ParseUnqualifiedIdTemplateId(
1943 Name, NameLoc, false, SecondTypeName,
1944 true))
1946
1948 SS, FirstTypeName, CCLoc, TildeLoc,
1949 SecondTypeName);
1950}
1951
1952
1953
1954
1955
1956
1957ExprResult Parser::ParseCXXBoolLiteral() {
1960}
1961
1962
1963
1964
1965
1966ExprResult Parser::ParseThrowExpression() {
1967 assert(Tok.is(tok::kw_throw) && "Not throw!");
1969
1970
1971
1972
1973 switch (Tok.getKind()) {
1974 case tok:🚛
1975 case tok::r_paren:
1976 case tok::r_square:
1977 case tok::r_brace:
1978 case tok::colon:
1979 case tok::comma:
1981
1982 default:
1984 if (Expr.isInvalid()) return Expr;
1986 }
1987}
1988
1989
1990
1991
1992
1993ExprResult Parser::ParseCoyieldExpression() {
1994 assert(Tok.is(tok::kw_co_yield) && "Not co_yield!");
1995
1997 ExprResult Expr = Tok.is(tok::l_brace) ? ParseBraceInitializer()
1999 if (.isInvalid())
2001 return Expr;
2002}
2003
2004
2005
2006
2007
2008
2010 assert(Tok.is(tok::kw_this) && "Not 'this'!");
2013}
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2029Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
2033
2034 assert((Tok.is(tok::l_paren) ||
2036 && "Expected '(' or '{'!");
2037
2038 if (Tok.is(tok::l_brace)) {
2041 if (Init.isInvalid())
2042 return Init;
2043 Expr *InitList = Init.get();
2046 InitList->getEndLoc(), true);
2047 } else {
2049 T.consumeOpen();
2050
2052
2053 ExprVector Exprs;
2054
2055 auto RunSignatureHelp = [&]() {
2057 if (TypeRep)
2058 PreferredType =
2061 Exprs, T.getOpenLocation(), false);
2062 CalledSignatureHelp = true;
2063 return PreferredType;
2064 };
2065
2066 if (Tok.isNot(tok::r_paren)) {
2067 if (ParseExpressionList(Exprs, [&] {
2068 PreferredType.enterFunctionArgument(Tok.getLocation(),
2069 RunSignatureHelp);
2070 })) {
2072 RunSignatureHelp();
2075 }
2076 }
2077
2078
2079 T.consumeClose();
2080
2081
2082 if (!TypeRep)
2084
2086 Exprs, T.getCloseLocation(),
2087 false);
2088 }
2089}
2090
2092Parser::ParseAliasDeclarationInInitStatement(DeclaratorContext Context,
2094 assert(Tok.is(tok::kw_using) && "Expected using");
2097 "Unexpected Declarator Context");
2100
2101 DG = ParseUsingDeclaration(Context, {}, DeclStart, DeclEnd, Attrs, AS_none);
2102 if (!DG)
2103 return DG;
2104
2106 ? diag::ext_alias_in_init_statement
2107 : diag::warn_cxx20_alias_in_init_statement)
2109
2110 return DG;
2111}
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2147 ForRangeInfo *FRI, bool EnterForConditionScope) {
2148
2149 struct ForConditionScopeRAII {
2151 void enter(bool IsConditionVariable) {
2152 if (S) {
2154 S->setIsConditionVarScope(IsConditionVariable);
2155 }
2156 }
2157 ~ForConditionScopeRAII() {
2158 if (S)
2159 S->setIsConditionVarScope(false);
2160 }
2161 } ForConditionScope{EnterForConditionScope ? getCurScope() : nullptr};
2162
2164 PreferredType.enterCondition(Actions, Tok.getLocation());
2165
2166 if (Tok.is(tok::code_completion)) {
2167 cutOffParsing();
2171 }
2172
2174 MaybeParseCXX11Attributes(attrs);
2175
2176 const auto WarnOnInit = [this, &CK] {
2178 ? diag::warn_cxx14_compat_init_statement
2179 : diag::ext_init_statement)
2181 };
2182
2183
2184 switch (isCXXConditionDeclarationOrInitStatement(InitStmt, FRI)) {
2185 case ConditionOrInitStatement::Expression: {
2186
2187 ForConditionScope.enter(false);
2188
2189 ProhibitAttributes(attrs);
2190
2191
2192
2193 if (InitStmt && Tok.is(tok::semi)) {
2194 WarnOnInit();
2197 Diag(SemiLoc, diag::warn_empty_init_statement)
2200 }
2203 return ParseCXXCondition(nullptr, Loc, CK, MissingOK);
2204 }
2205
2206
2208 if (Expr.isInvalid())
2210
2211 if (InitStmt && Tok.is(tok::semi)) {
2212 WarnOnInit();
2215 return ParseCXXCondition(nullptr, Loc, CK, MissingOK);
2216 }
2217
2219 MissingOK);
2220 }
2221
2222 case ConditionOrInitStatement::InitStmtDecl: {
2223 WarnOnInit();
2226 if (Tok.is(tok::kw_using))
2227 DG = ParseAliasDeclarationInInitStatement(
2229 else {
2232 attrs, DeclSpecAttrs, true);
2233 }
2234 *InitStmt = Actions.ActOnDeclStmt(DG, DeclStart, DeclEnd);
2235 return ParseCXXCondition(nullptr, Loc, CK, MissingOK);
2236 }
2237
2238 case ConditionOrInitStatement::ForRangeDecl: {
2239
2240
2241
2242 assert(FRI && "should not parse a for range declaration here");
2249 }
2250
2251 case ConditionOrInitStatement::ConditionDecl:
2252 case ConditionOrInitStatement::Error:
2253 break;
2254 }
2255
2256
2257 ForConditionScope.enter(true);
2258
2259
2261 ParseSpecifierQualifierList(DS, AS_none, DeclSpecContext::DSC_condition);
2262
2263
2265 ParseDeclarator(DeclaratorInfo);
2266
2267
2268 if (Tok.is(tok::kw_asm)) {
2270 ExprResult AsmLabel(ParseSimpleAsm( true, &Loc));
2271 if (AsmLabel.isInvalid()) {
2274 }
2275 DeclaratorInfo.setAsmLabel(AsmLabel.get());
2276 DeclaratorInfo.SetRangeEnd(Loc);
2277 }
2278
2279
2280 MaybeParseGNUAttributes(DeclaratorInfo);
2281
2282
2284 DeclaratorInfo);
2287 Decl *DeclOut = Dcl.get();
2288
2289
2290
2291 bool CopyInitialization = isTokenEqualOrEqualTypo();
2292 if (CopyInitialization)
2294
2298 diag::warn_cxx98_compat_generalized_initializer_lists);
2299 InitExpr = ParseBraceInitializer();
2300 } else if (CopyInitialization) {
2301 PreferredType.enterVariableInit(Tok.getLocation(), DeclOut);
2303 } else if (Tok.is(tok::l_paren)) {
2304
2305 SourceLocation LParen = ConsumeParen(), RParen = LParen;
2307 RParen = ConsumeParen();
2309 diag::err_expected_init_in_condition_lparen)
2311 } else {
2312 Diag(DeclOut->getLocation(), diag::err_expected_init_in_condition);
2313 }
2314
2317 else
2319
2322}
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
2352 const char *PrevSpec;
2353 unsigned DiagID;
2357
2358 switch (Tok.getKind()) {
2359 case tok::identifier:
2360 case tok::coloncolon:
2361 llvm_unreachable("Annotation token should already be formed!");
2362 default:
2363 llvm_unreachable("Not a simple-type-specifier token!");
2364
2365
2366 case tok::annot_typename: {
2370 ConsumeAnnotationToken();
2371 DS.Finish(Actions, Policy);
2372 return;
2373 }
2374
2375 case tok::kw__ExtInt:
2376 case tok::kw__BitInt: {
2377 DiagnoseBitIntUse(Tok);
2378 ExprResult ER = ParseExtIntegerArgument();
2381 else
2383
2384
2386 DS.Finish(Actions, Policy);
2387 return;
2388 }
2389
2390
2391 case tok::kw_short:
2393 Policy);
2394 break;
2395 case tok::kw_long:
2397 Policy);
2398 break;
2399 case tok::kw___int64:
2401 Policy);
2402 break;
2403 case tok::kw_signed:
2405 break;
2406 case tok::kw_unsigned:
2408 break;
2409 case tok::kw_void:
2411 break;
2412 case tok::kw_auto:
2414 break;
2415 case tok::kw_char:
2417 break;
2418 case tok::kw_int:
2420 break;
2421 case tok::kw___int128:
2423 break;
2424 case tok::kw___bf16:
2426 break;
2427 case tok::kw_half:
2429 break;
2430 case tok::kw_float:
2432 break;
2433 case tok::kw_double:
2435 break;
2436 case tok::kw__Float16:
2438 break;
2439 case tok::kw___float128:
2441 break;
2442 case tok::kw___ibm128:
2444 break;
2445 case tok::kw_wchar_t:
2447 break;
2448 case tok::kw_char8_t:
2450 break;
2451 case tok::kw_char16_t:
2453 break;
2454 case tok::kw_char32_t:
2456 break;
2457 case tok::kw_bool:
2459 break;
2460 case tok::kw__Accum:
2462 break;
2463 case tok::kw__Fract:
2465 break;
2466 case tok::kw__Sat:
2468 break;
2469#define GENERIC_IMAGE_TYPE(ImgType, Id) \
2470 case tok::kw_##ImgType##_t: \
2471 DS.SetTypeSpecType(DeclSpec::TST_##ImgType##_t, Loc, PrevSpec, DiagID, \
2472 Policy); \
2473 break;
2474#include "clang/Basic/OpenCLImageTypes.def"
2475#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
2476 case tok::kw_##Name: \
2477 DS.SetTypeSpecType(DeclSpec::TST_##Name, Loc, PrevSpec, DiagID, Policy); \
2478 break;
2479#include "clang/Basic/HLSLIntangibleTypes.def"
2480
2481 case tok::annot_decltype:
2482 case tok::kw_decltype:
2483 DS.SetRangeEnd(ParseDecltypeSpecifier(DS));
2484 return DS.Finish(Actions, Policy);
2485
2486 case tok::annot_pack_indexing_type:
2487 DS.SetRangeEnd(ParsePackIndexingType(DS));
2488 return DS.Finish(Actions, Policy);
2489
2490
2491 case tok::kw_typeof:
2492 ParseTypeofSpecifier(DS);
2493 DS.Finish(Actions, Policy);
2494 return;
2495 }
2498 DS.Finish(Actions, Policy);
2499}
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2513 ParseSpecifierQualifierList(DS, AS_none,
2514 getDeclSpecContextFromDeclaratorContext(Context));
2516 return false;
2517}
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554bool Parser::ParseUnqualifiedIdTemplateId(
2557 bool EnteringContext, UnqualifiedId &Id, bool AssumeTemplateId) {
2558 assert(Tok.is(tok::less) && "Expected '<' to finish parsing a template-id");
2559
2562 switch (Id.getKind()) {
2566 if (AssumeTemplateId) {
2567
2568
2570 ObjectType, EnteringContext, Template,
2571 true);
2572 } else {
2573 bool MemberOfUnknownSpecialization;
2576 ObjectType, EnteringContext, Template,
2577 MemberOfUnknownSpecialization);
2578
2579
2580
2582 isTemplateArgumentList(0) == TPResult::False)
2583 return false;
2584
2585 if (TNK == TNK_Non_template && MemberOfUnknownSpecialization &&
2586 ObjectType && isTemplateArgumentList(0) == TPResult::True) {
2587
2588
2589 if (!ObjectHadErrors) {
2590
2591
2592
2593
2594 std::string Name;
2596 Name = std::string(Id.Identifier->getName());
2597 else {
2598 Name = "operator ";
2601 else
2602 Name += Id.Identifier->getName();
2603 }
2604 Diag(Id.StartLocation, diag::err_missing_dependent_template_keyword)
2605 << Name
2607 }
2609 getCurScope(), SS, TemplateKWLoc, Id, ObjectType, EnteringContext,
2610 Template, true);
2612 return false;
2613 }
2614 }
2615 break;
2616
2619 bool MemberOfUnknownSpecialization;
2623 EnteringContext, Template,
2624 MemberOfUnknownSpecialization);
2626 return false;
2627 break;
2628 }
2629
2632 bool MemberOfUnknownSpecialization;
2634 if (ObjectType) {
2637 EnteringContext, Template, true);
2638 } else {
2641 EnteringContext, Template,
2642 MemberOfUnknownSpecialization);
2643
2645 Diag(NameLoc, diag::err_destructor_template_id)
2647
2648 }
2649 }
2650 break;
2651 }
2652
2653 default:
2654 return false;
2655 }
2656
2657
2659 TemplateArgList TemplateArgs;
2660 if (ParseTemplateIdAfterTemplateName(true, LAngleLoc, TemplateArgs, RAngleLoc,
2661 Template))
2662 return true;
2663
2664
2666 return true;
2667
2671
2672
2673
2674
2677 : nullptr;
2681 : Id.OperatorFunctionId.Operator;
2682
2684 TemplateKWLoc, Id.StartLocation, TemplateII, OpKind, Template, TNK,
2685 LAngleLoc, RAngleLoc, TemplateArgs, false, TemplateIds);
2686
2687 Id.setTemplateId(TemplateId);
2688 return false;
2689 }
2690
2691
2693
2694
2696 getCurScope(), SS, TemplateKWLoc, Template, Name, NameLoc, LAngleLoc,
2697 TemplateArgsPtr, RAngleLoc, true);
2698 if (Type.isInvalid())
2699 return true;
2700
2702 Id.setConstructorName(Type.get(), NameLoc, RAngleLoc);
2703 else
2704 Id.setDestructorName(Id.StartLocation, Type.get(), RAngleLoc);
2705
2706 return false;
2707}
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
2752 assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
2753
2754
2756
2757
2758 unsigned SymbolIdx = 0;
2761 switch (Tok.getKind()) {
2762 case tok::kw_new:
2763 case tok::kw_delete: {
2764 bool isNew = Tok.getKind() == tok::kw_new;
2765
2766 SymbolLocations[SymbolIdx++] = ConsumeToken();
2767
2768 if (Tok.is(tok::l_square) &&
2770
2772 T.consumeOpen();
2773 T.consumeClose();
2774 if (T.getCloseLocation().isInvalid())
2775 return true;
2776
2777 SymbolLocations[SymbolIdx++] = T.getOpenLocation();
2778 SymbolLocations[SymbolIdx++] = T.getCloseLocation();
2779 Op = isNew? OO_Array_New : OO_Array_Delete;
2780 } else {
2781 Op = isNew? OO_New : OO_Delete;
2782 }
2783 break;
2784 }
2785
2786#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2787 case tok::Token: \
2788 SymbolLocations[SymbolIdx++] = ConsumeToken(); \
2789 Op = OO_##Name; \
2790 break;
2791#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
2792#include "clang/Basic/OperatorKinds.def"
2793
2794 case tok::l_paren: {
2795
2797 T.consumeOpen();
2798 T.consumeClose();
2799 if (T.getCloseLocation().isInvalid())
2800 return true;
2801
2802 SymbolLocations[SymbolIdx++] = T.getOpenLocation();
2803 SymbolLocations[SymbolIdx++] = T.getCloseLocation();
2804 Op = OO_Call;
2805 break;
2806 }
2807
2808 case tok::l_square: {
2809
2811 T.consumeOpen();
2812 T.consumeClose();
2813 if (T.getCloseLocation().isInvalid())
2814 return true;
2815
2816 SymbolLocations[SymbolIdx++] = T.getOpenLocation();
2817 SymbolLocations[SymbolIdx++] = T.getCloseLocation();
2818 Op = OO_Subscript;
2819 break;
2820 }
2821
2822 case tok::code_completion: {
2823
2824 cutOffParsing();
2825
2827 return true;
2828 }
2829
2830 default:
2831 break;
2832 }
2833
2835
2836 Result.setOperatorFunctionId(KeywordLoc, Op, SymbolLocations);
2837 return false;
2838 }
2839
2840
2841
2842
2843
2844
2845
2847 Diag(Tok.getLocation(), diag::warn_cxx98_compat_literal_operator);
2848
2850 unsigned DiagId = 0;
2851
2852
2853
2856 while (isTokenStringLiteral()) {
2857 if (!Tok.is(tok::string_literal) && !DiagId) {
2858
2859
2860
2862 DiagId = diag::err_literal_operator_string_prefix;
2863 }
2864 Toks.push_back(Tok);
2865 TokLocs.push_back(ConsumeStringToken());
2866 }
2867
2870 return true;
2871
2872
2873
2874 bool IsUDSuffix = .getUDSuffix().empty();
2877 if (IsUDSuffix) {
2879 SuffixLoc =
2881 Literal.getUDSuffixOffset(),
2883 } else if (Tok.is(tok::identifier)) {
2886 TokLocs.push_back(SuffixLoc);
2887 } else {
2888 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
2889 return true;
2890 }
2891
2892
2893 if (.GetString().empty() || Literal.Pascal) {
2894
2895
2896
2897
2898 DiagLoc = TokLocs.front();
2899 DiagId = diag::err_literal_operator_string_not_empty;
2900 }
2901
2902 if (DiagId) {
2903
2904
2906 Str += "\"\"";
2909 SourceRange(TokLocs.front(), TokLocs.back()), Str);
2910 }
2911
2912 Result.setLiteralOperatorId(II, KeywordLoc, SuffixLoc);
2913
2915 }
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2930 if (ParseCXXTypeSpecifierSeq(
2932 return true;
2933
2934
2935
2938 ParseDeclaratorInternal(D, nullptr);
2939
2940
2943 return true;
2944
2945
2946 Result.setConversionFunctionId(KeywordLoc, Ty.get(),
2948 return false;
2949}
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2988 bool ObjectHadErrors, bool EnteringContext,
2989 bool AllowDestructorName,
2990 bool AllowConstructorName,
2991 bool AllowDeductionGuide,
2994 if (TemplateKWLoc)
2996
2997
2998
2999 bool TemplateSpecified = false;
3000 if (Tok.is(tok::kw_template)) {
3001 if (TemplateKWLoc && (ObjectType || SS.isSet())) {
3002 TemplateSpecified = true;
3004 } else {
3006 Diag(TemplateLoc, diag::err_unexpected_template_in_unqualified_id)
3008 }
3009 }
3010
3011
3012
3013
3014 if (Tok.is(tok::identifier)) {
3015 ParseIdentifier:
3016
3019
3021
3022
3023 Result.setIdentifier(Id, IdLoc);
3024 return false;
3025 }
3026
3028 if (AllowConstructorName &&
3030
3032 EnteringContext);
3033 if (!Ty)
3034 return true;
3035 Result.setConstructorName(Ty, IdLoc, IdLoc);
3040
3042 } else {
3043
3044 Result.setIdentifier(Id, IdLoc);
3045 }
3046
3047
3049 if (Tok.is(tok::less))
3050 return ParseUnqualifiedIdTemplateId(
3051 SS, ObjectType, ObjectHadErrors,
3052 TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Id, IdLoc,
3053 EnteringContext, Result, TemplateSpecified);
3054
3055 if (TemplateSpecified) {
3058 ObjectType, EnteringContext, Template,
3059 true);
3061 return true;
3062
3063
3064
3065
3068 !Tok.is(tok::less))
3069 Diag(IdLoc, diag::missing_template_arg_list_after_template_kw);
3070 }
3071 return false;
3072 }
3073
3074
3075
3076 if (Tok.is(tok::annot_template_id)) {
3078
3079
3080
3082 ConsumeAnnotationToken();
3083 return true;
3084 }
3085
3086
3087 if (AllowConstructorName && TemplateId->Name &&
3089 if (SS.isSet()) {
3090
3091
3092
3093
3095 diag::err_out_of_line_constructor_template_id)
3096 << TemplateId->Name
3101 EnteringContext);
3102 if (!Ty)
3103 return true;
3106 ConsumeAnnotationToken();
3107 return false;
3108 }
3109
3110 Result.setConstructorTemplateId(TemplateId);
3111 ConsumeAnnotationToken();
3112 return false;
3113 }
3114
3115
3116
3117 Result.setTemplateId(TemplateId);
3119 if (TemplateLoc.isValid()) {
3120 if (TemplateKWLoc && (ObjectType || SS.isSet()))
3121 *TemplateKWLoc = TemplateLoc;
3122 else
3123 Diag(TemplateLoc, diag::err_unexpected_template_in_unqualified_id)
3125 }
3126 ConsumeAnnotationToken();
3127 return false;
3128 }
3129
3130
3131
3132
3133 if (Tok.is(tok::kw_operator)) {
3134 if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, Result))
3135 return true;
3136
3137
3138
3139
3140
3141
3145 Tok.is(tok::less))
3146 return ParseUnqualifiedIdTemplateId(
3147 SS, ObjectType, ObjectHadErrors,
3148 TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), nullptr,
3150 else if (TemplateSpecified &&
3153 EnteringContext, Template,
3155 return true;
3156
3157 return false;
3158 }
3159
3161 (AllowDestructorName || SS.isSet()) && Tok.is(tok::tilde)) {
3162
3163
3164
3165
3166
3167
3169
3170 if (TemplateSpecified) {
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181 Diag(*TemplateKWLoc, diag::err_unexpected_template_in_destructor_name)
3183 return true;
3184 }
3185
3186 if (SS.isEmpty() && Tok.is(tok::kw_decltype)) {
3191 Result.setDestructorName(TildeLoc, Type, EndLoc);
3192 return false;
3193 }
3194 return true;
3195 }
3196
3197
3198 if (Tok.isNot(tok::identifier)) {
3199 Diag(Tok, diag::err_destructor_tilde_identifier);
3200 return true;
3201 }
3202
3203
3204 DeclaratorScopeObj DeclScopeObj(*this, SS);
3205 if (NextToken().is(tok::coloncolon)) {
3206
3207
3208
3210
3211 if (SS.isSet()) {
3212 AnnotateScopeToken(SS, true);
3214 }
3215 if (ParseOptionalCXXScopeSpecifier(SS, ObjectType, ObjectHadErrors,
3216 EnteringContext))
3217 return true;
3219 ObjectType = nullptr;
3220 if (Tok.isNot(tok::identifier) || NextToken().is(tok::coloncolon) ||
3222 Diag(TildeLoc, diag::err_destructor_tilde_scope);
3223 return true;
3224 }
3225
3226
3227 Diag(TildeLoc, diag::err_destructor_tilde_scope)
3230
3231
3233 DeclScopeObj.EnterDeclaratorScope();
3234 }
3235
3236
3239
3240 if (Tok.is(tok::less)) {
3241 Result.setDestructorName(TildeLoc, nullptr, ClassNameLoc);
3242 return ParseUnqualifiedIdTemplateId(
3243 SS, ObjectType, ObjectHadErrors,
3244 TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), ClassName,
3245 ClassNameLoc, EnteringContext, Result, TemplateSpecified);
3246 }
3247
3248
3251 ObjectType, EnteringContext);
3252 if (!Ty)
3253 return true;
3254
3255 Result.setDestructorName(TildeLoc, Ty, ClassNameLoc);
3256 return false;
3257 }
3258
3259 switch (Tok.getKind()) {
3260#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
3261#include "clang/Basic/TransformTypeTraits.def"
3262 if (().is(tok::l_paren)) {
3263 Tok.setKind(tok::identifier);
3264 Diag(Tok, diag::ext_keyword_as_ident)
3266 goto ParseIdentifier;
3267 }
3268 [[fallthrough]];
3269 default:
3270 Diag(Tok, diag::err_expected_unqualified_id) << getLangOpts().CPlusPlus;
3271 return true;
3272 }
3273}
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3304Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
3305 assert(Tok.is(tok::kw_new) && "expected 'new' token");
3307
3308
3309
3310
3311 ExprVector PlacementArgs;
3313
3318 if (Tok.is(tok::l_paren)) {
3319
3321 T.consumeOpen();
3322 PlacementLParen = T.getOpenLocation();
3323 if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) {
3326 }
3327
3328 T.consumeClose();
3329 PlacementRParen = T.getCloseLocation();
3330 if (PlacementRParen.isInvalid()) {
3333 }
3334
3335 if (PlacementArgs.empty()) {
3336
3337 TypeIdParens = T.getRange();
3338 PlacementLParen = PlacementRParen = SourceLocation();
3339 } else {
3340
3341 if (Tok.is(tok::l_paren)) {
3343 T.consumeOpen();
3344 MaybeParseGNUAttributes(DeclaratorInfo);
3345 ParseSpecifierQualifierList(DS);
3347 ParseDeclarator(DeclaratorInfo);
3348 T.consumeClose();
3349 TypeIdParens = T.getRange();
3350 } else {
3351 MaybeParseGNUAttributes(DeclaratorInfo);
3352 if (ParseCXXTypeSpecifierSeq(DS))
3353 DeclaratorInfo.setInvalidType(true);
3354 else {
3356 ParseDeclaratorInternal(DeclaratorInfo,
3357 &Parser::ParseDirectNewDeclarator);
3358 }
3359 }
3360 }
3361 } else {
3362
3363
3364 MaybeParseGNUAttributes(DeclaratorInfo);
3366 DeclaratorInfo.setInvalidType(true);
3367 else {
3369 ParseDeclaratorInternal(DeclaratorInfo,
3370 &Parser::ParseDirectNewDeclarator);
3371 }
3372 }
3373 if (DeclaratorInfo.isInvalidType()) {
3376 }
3377
3379
3380 if (Tok.is(tok::l_paren)) {
3381 SourceLocation ConstructorLParen, ConstructorRParen;
3382 ExprVector ConstructorArgs;
3384 T.consumeOpen();
3385 ConstructorLParen = T.getOpenLocation();
3386 if (Tok.isNot(tok::r_paren)) {
3387 auto RunSignatureHelp = [&]() {
3390
3391
3392
3393 if (TypeRep)
3394 PreferredType =
3397 DeclaratorInfo.getEndLoc(), ConstructorArgs,
3398 ConstructorLParen,
3399 false);
3400 CalledSignatureHelp = true;
3401 return PreferredType;
3402 };
3403 if (ParseExpressionList(ConstructorArgs, [&] {
3404 PreferredType.enterFunctionArgument(Tok.getLocation(),
3405 RunSignatureHelp);
3406 })) {
3408 RunSignatureHelp();
3411 }
3412 }
3413 T.consumeClose();
3414 ConstructorRParen = T.getCloseLocation();
3415 if (ConstructorRParen.isInvalid()) {
3418 }
3420 ConstructorRParen,
3421 ConstructorArgs);
3424 diag::warn_cxx98_compat_generalized_initializer_lists);
3426 }
3429
3430 return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen,
3431 PlacementArgs, PlacementRParen,
3432 TypeIdParens, DeclaratorInfo, Initializer.get());
3433}
3434
3435
3436
3437
3438
3439
3440
3441
3442void Parser::ParseDirectNewDeclarator(Declarator &D) {
3443
3444 bool First = true;
3445 while (Tok.is(tok::l_square)) {
3446
3447 if (CheckProhibitedCXX11Attribute())
3448 continue;
3449
3451 T.consumeOpen();
3452
3456 if (Size.isInvalid()) {
3457
3459 return;
3460 }
3462
3463 T.consumeClose();
3464
3465
3467 MaybeParseCXX11Attributes(Attrs);
3468
3470 false, false,
3471 Size.get(), T.getOpenLocation(),
3472 T.getCloseLocation()),
3473 std::move(Attrs), T.getCloseLocation());
3474
3475 if (T.getCloseLocation().isInvalid())
3476 return;
3477 }
3478}
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490bool Parser::ParseExpressionListOrTypeId(
3493
3494 if (isTypeIdInParens()) {
3495 ParseSpecifierQualifierList(D.getMutableDeclSpec());
3497 ParseDeclarator(D);
3498 return D.isInvalidType();
3499 }
3500
3501
3502 return ParseExpressionList(PlacementArgs);
3503}
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3517Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) {
3518 assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword");
3520
3521
3522 bool ArrayDelete = false;
3523 if (Tok.is(tok::l_square) && NextToken().is(tok::r_square)) {
3524
3525
3526
3527
3528
3529
3530
3531 const Token Next = GetLookAheadToken(2);
3532
3533
3534 if (Next.isOneOf(tok::l_brace, tok::less) ||
3535 (Next.is(tok::l_paren) &&
3536 (GetLookAheadToken(3).is(tok::r_paren) ||
3537 (GetLookAheadToken(3).is(tok::identifier) &&
3538 GetLookAheadToken(4).is(tok::identifier))))) {
3539 TentativeParsingAction TPA(*this);
3542
3543
3544
3547 bool EmitFixIt = false;
3548 if (Tok.is(tok::l_brace)) {
3549 ConsumeBrace();
3552 EmitFixIt = true;
3553 }
3554
3555 TPA.Revert();
3556
3557 if (EmitFixIt)
3558 Diag(Start, diag::err_lambda_after_delete)
3564 ")");
3565 else
3566 Diag(Start, diag::err_lambda_after_delete)
3568
3569
3570
3571 ExprResult Lambda = ParseLambdaExpression();
3574
3575
3576 Lambda = ParsePostfixExpressionSuffix(Lambda);
3579 return Actions.ActOnCXXDelete(Start, UseGlobal, false,
3580 Lambda.get());
3581 }
3582
3583 ArrayDelete = true;
3585
3586 T.consumeOpen();
3587 T.consumeClose();
3588 if (T.getCloseLocation().isInvalid())
3590 }
3591
3593 if (Operand.isInvalid())
3595
3597}
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623ExprResult Parser::ParseRequiresExpression() {
3624 assert(Tok.is(tok::kw_requires) && "Expected 'requires' keyword");
3626
3629 if (Tok.is(tok::l_paren)) {
3630
3633 Parens.consumeOpen();
3634 if (!Tok.is(tok::r_paren)) {
3639 FirstArgAttrs, LocalParameters,
3640 EllipsisLoc);
3641 if (EllipsisLoc.isValid())
3642 Diag(EllipsisLoc, diag::err_requires_expr_parameter_list_ellipsis);
3643 for (auto &ParamInfo : LocalParameters)
3644 LocalParameterDecls.push_back(cast(ParamInfo.Param));
3645 }
3646 Parens.consumeClose();
3647 }
3648
3650 if (Braces.expectAndConsume())
3652
3653
3655
3656
3657
3660
3662
3663
3664
3667 RequiresKWLoc, LocalParameterDecls, getCurScope());
3668
3669 if (Tok.is(tok::r_brace)) {
3670
3671
3672
3673
3674
3675
3676 Diag(Tok, diag::err_empty_requires_expr);
3677
3678 } else {
3679 while (!Tok.is(tok::r_brace)) {
3680 switch (Tok.getKind()) {
3681 case tok::l_brace: {
3682
3683
3684
3685
3686
3687
3688
3689
3690
3692 ExprBraces.consumeOpen();
3696 ExprBraces.skipToEnd();
3698 break;
3699 }
3700 if (ExprBraces.consumeClose())
3701 ExprBraces.skipToEnd();
3702
3706 if (Tok.is(tok::semi)) {
3708 if (Req)
3709 Requirements.push_back(Req);
3710 break;
3711 }
3713
3714 Diag(Tok, diag::err_requires_expr_missing_arrow)
3716
3717 if (TryAnnotateTypeConstraint()) {
3719 break;
3720 }
3721 if (!isTypeConstraintAnnotation()) {
3722 Diag(Tok, diag::err_requires_expr_expected_type_constraint);
3724 break;
3725 }
3727 if (Tok.is(tok::annot_cxxscope)) {
3730 SS);
3731 ConsumeAnnotationToken();
3732 }
3733
3735 Expression.get(), NoexceptLoc, SS, takeTemplateIdAnnotation(Tok),
3736 TemplateParameterDepth);
3737 ConsumeAnnotationToken();
3738 if (Req)
3739 Requirements.push_back(Req);
3740 break;
3741 }
3742 default: {
3743 bool PossibleRequiresExprInSimpleRequirement = false;
3744 if (Tok.is(tok::kw_requires)) {
3745 auto IsNestedRequirement = [&] {
3746 RevertingTentativeParsingAction TPA(*this);
3748 if (Tok.is(tok::l_brace))
3749
3750
3751
3752
3753
3754 return false;
3755 if (Tok.is(tok::l_paren)) {
3756
3757 ConsumeParen();
3758 auto Res = TryParseParameterDeclarationClause();
3759 if (Res != TPResult::False) {
3760
3761 unsigned Depth = 1;
3762 while (Depth != 0) {
3763 bool FoundParen = SkipUntil(tok::l_paren, tok::r_paren,
3765 if (!FoundParen)
3766 break;
3767 if (Tok.is(tok::l_paren))
3768 Depth++;
3769 else if (Tok.is(tok::r_paren))
3770 Depth--;
3772 }
3773
3774
3775
3776
3777
3778
3779
3780 if (Tok.is(tok::l_brace))
3781
3782
3783
3784 return false;
3785 }
3786 }
3787 return true;
3788 };
3789 if (IsNestedRequirement()) {
3791
3792
3793
3794
3798 SkipUntil(tok::semi, tok::r_brace,
3800 break;
3801 }
3802 if (auto *Req =
3804 Requirements.push_back(Req);
3805 else {
3806 SkipUntil(tok::semi, tok::r_brace,
3808 break;
3809 }
3810 break;
3811 } else
3812 PossibleRequiresExprInSimpleRequirement = true;
3813 } else if (Tok.is(tok::kw_typename)) {
3814
3815
3816 TentativeParsingAction TPA(*this);
3817
3818
3821 TPA.Commit();
3823 break;
3824 }
3826 if (Tok.is(tok::annot_cxxscope)) {
3829 ConsumeAnnotationToken();
3830 }
3831
3832 if (Tok.isOneOf(tok::identifier, tok::annot_template_id) &&
3834 TPA.Commit();
3838 if (Tok.is(tok::identifier)) {
3841 } else {
3842 TemplateId = takeTemplateIdAnnotation(Tok);
3843 ConsumeAnnotationToken();
3845 break;
3846 }
3847
3849 NameLoc, II,
3850 TemplateId)) {
3851 Requirements.push_back(Req);
3852 }
3853 break;
3854 }
3855 TPA.Revert();
3856 }
3857
3858
3859
3860
3866 break;
3867 }
3868 if (.isInvalid() && PossibleRequiresExprInSimpleRequirement)
3869 Diag(StartLoc, diag::err_requires_expr_in_simple_requirement)
3872 Requirements.push_back(Req);
3873 else {
3875 break;
3876 }
3877
3878 if (Tok.is(tok::kw_noexcept)) {
3879 Diag(Tok, diag::err_requires_expr_simple_requirement_noexcept)
3883 break;
3884 }
3885 break;
3886 }
3887 }
3888 if (ExpectAndConsumeSemi(diag::err_expected_semi_requirement)) {
3891 break;
3892 }
3893 }
3894 if (Requirements.empty()) {
3895
3896
3897
3898 Braces.consumeClose();
3901 }
3902 }
3903 Braces.consumeClose();
3905 ParsingBodyDecl.complete(Body);
3907 RequiresKWLoc, Body, Parens.getOpenLocation(), LocalParameterDecls,
3908 Parens.getCloseLocation(), Requirements, Braces.getCloseLocation());
3909}
3910
3912 switch (kind) {
3913 default: llvm_unreachable("Not a known type trait");
3914#define TYPE_TRAIT_1(Spelling, Name, Key) \
3915case tok::kw_ ## Spelling: return UTT_ ## Name;
3916#define TYPE_TRAIT_2(Spelling, Name, Key) \
3917case tok::kw_ ## Spelling: return BTT_ ## Name;
3918#include "clang/Basic/TokenKinds.def"
3919#define TYPE_TRAIT_N(Spelling, Name, Key) \
3920 case tok::kw_ ## Spelling: return TT_ ## Name;
3921#include "clang/Basic/TokenKinds.def"
3922 }
3923}
3924
3926 switch (kind) {
3927 default:
3928 llvm_unreachable("Not a known array type trait");
3929#define ARRAY_TYPE_TRAIT(Spelling, Name, Key) \
3930 case tok::kw_##Spelling: \
3931 return ATT_##Name;
3932#include "clang/Basic/TokenKinds.def"
3933 }
3934}
3935
3937 switch (kind) {
3938 default:
3939 llvm_unreachable("Not a known unary expression trait.");
3940#define EXPRESSION_TRAIT(Spelling, Name, Key) \
3941 case tok::kw_##Spelling: \
3942 return ET_##Name;
3943#include "clang/Basic/TokenKinds.def"
3944 }
3945}
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958ExprResult Parser::ParseTypeTrait() {
3960
3962
3964 if (Parens.expectAndConsume())
3966
3968 do {
3969
3977 }
3978
3979
3980 if (Tok.is(tok::ellipsis)) {
3985 }
3986 }
3987
3988
3989 Args.push_back(Ty.get());
3991
3992 if (Parens.consumeClose())
3994
3996
3998}
3999
4000
4001
4002
4003
4004
4005
4006
4007ExprResult Parser::ParseArrayTypeTrait() {
4010
4012 if (T.expectAndConsume())
4014
4021 }
4022
4023 switch (ATT) {
4024 case ATT_ArrayRank: {
4025 T.consumeClose();
4027 T.getCloseLocation());
4028 }
4029 case ATT_ArrayExtent: {
4030 if (ExpectAndConsume(tok::comma)) {
4033 }
4034
4036 T.consumeClose();
4037
4040
4042 T.getCloseLocation());
4043 }
4044 }
4045 llvm_unreachable("Invalid ArrayTypeTrait!");
4046}
4047
4048
4049
4050
4051
4052
4053
4054ExprResult Parser::ParseExpressionTrait() {
4057
4059 if (T.expectAndConsume())
4061
4063
4064 T.consumeClose();
4065
4067 T.getCloseLocation());
4068}
4069
4070
4071
4072
4073
4075Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
4080 assert(ExprType == CastExpr && "Compound literals are not ambiguous!");
4081 assert(isTypeIdInParens() && "Not a type-id!");
4082
4084 CastTy = nullptr;
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105 ParenParseOption ParseAs;
4107
4108
4109
4110 if (!ConsumeAndStoreUntil(tok::r_paren, Toks)) {
4111
4114 }
4115
4116 if (Tok.is(tok::l_brace)) {
4117 ParseAs = CompoundLiteral;
4118 } else {
4119 bool NotCastExpr;
4120 if (Tok.is(tok::l_paren) && NextToken().is(tok::r_paren)) {
4121 NotCastExpr = true;
4122 } else {
4123
4124
4125
4127 Result = ParseCastExpression(AnyCastExpr,
4128 false,
4129 NotCastExpr,
4130
4132 }
4133
4134
4135
4136 ParseAs = NotCastExpr ? SimpleExpr : CastExpr;
4137 }
4138
4139
4142 AttrEnd.setKind(tok::eof);
4145 Toks.push_back(AttrEnd);
4146
4147
4148 Toks.push_back(Tok);
4149
4150
4151 PP.EnterTokenStream(Toks, true,
4152 true);
4153
4154
4156
4157 if (ParseAs >= CompoundLiteral) {
4158
4162 {
4164 ParseSpecifierQualifierList(DS);
4165 ParseDeclarator(DeclaratorInfo);
4166 }
4167
4168
4171
4172
4175
4176 if (ParseAs == CompoundLiteral) {
4177 ExprType = CompoundLiteral;
4178 if (DeclaratorInfo.isInvalidType())
4180
4182 return ParseCompoundLiteralExpression(Ty.get(),
4185 }
4186
4187
4188 assert(ParseAs == CastExpr);
4189
4190 if (DeclaratorInfo.isInvalidType())
4192
4193
4194 if (.isInvalid())
4196 DeclaratorInfo, CastTy,
4199 }
4200
4201
4202 assert(ParseAs == SimpleExpr);
4203
4204 ExprType = SimpleExpr;
4206 if (.isInvalid() && Tok.is(tok::r_paren))
4209
4210
4211 if (Result.isInvalid()) {
4212 while (Tok.isNot(tok::eof))
4217 }
4218
4220
4224}
4225
4226
4227ExprResult Parser::ParseBuiltinBitCast() {
4229
4231 if (T.expectAndConsume(diag::err_expected_lparen_after, "__builtin_bit_cast"))
4233
4234
4236 ParseSpecifierQualifierList(DS);
4237
4238
4241 ParseDeclarator(DeclaratorInfo);
4242
4243 if (ExpectAndConsume(tok::comma)) {
4244 Diag(Tok.getLocation(), diag::err_expected) << tok::comma;
4247 }
4248
4250
4251 if (T.consumeClose())
4253
4254 if (Operand.isInvalid() || DeclaratorInfo.isInvalidType())
4256
4258 T.getCloseLocation());
4259}
Defines the clang::ASTContext interface.
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
static void addConstexprToLambdaDeclSpecifier(Parser &P, SourceLocation ConstexprLoc, DeclSpec &DS)
static void FixDigraph(Parser &P, Preprocessor &PP, Token &DigraphToken, Token &ColonToken, tok::TokenKind Kind, bool AtDigraph)
static ArrayTypeTrait ArrayTypeTraitFromTokKind(tok::TokenKind kind)
static void tryConsumeLambdaSpecifierToken(Parser &P, SourceLocation &MutableLoc, SourceLocation &StaticLoc, SourceLocation &ConstexprLoc, SourceLocation &ConstevalLoc, SourceLocation &DeclEndLoc)
static ExpressionTrait ExpressionTraitFromTokKind(tok::TokenKind kind)
static void addConstevalToLambdaDeclSpecifier(Parser &P, SourceLocation ConstevalLoc, DeclSpec &DS)
static TypeTrait TypeTraitFromTokKind(tok::TokenKind kind)
static void DiagnoseStaticSpecifierRestrictions(Parser &P, SourceLocation StaticLoc, SourceLocation MutableLoc, const LambdaIntroducer &Intro)
static int SelectDigraphErrorMessage(tok::TokenKind Kind)
static void addStaticToLambdaDeclSpecifier(Parser &P, SourceLocation StaticLoc, DeclSpec &DS)
Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...
static constexpr bool isOneOf()
This file declares facilities that support code completion.
Defines the clang::TemplateNameKind enum.
Defines the clang::TokenKind enum and support functions.
const clang::PrintingPolicy & getPrintingPolicy() const
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
SourceLocation getOpenLocation() const
SourceLocation getCloseLocation() const
Represents a C++ nested-name-specifier or a global scope specifier.
bool isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
SourceRange getRange() const
SourceLocation getBeginLoc() const
bool isSet() const
Deprecated.
void setEndLoc(SourceLocation Loc)
void SetInvalid(SourceRange R)
Indicate that this nested-name-specifier is invalid.
bool isEmpty() const
No scope specifier.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and restores it when destroyed.
void restore()
restore - This can be used to restore the state early, before the dtor is run.
Captures information about "declaration specifiers".
static const TST TST_typename
SourceLocation getEndLoc() const LLVM_READONLY
bool SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
These methods set the specified attribute of the DeclSpec and return false if there was no error.
static const TST TST_char8
static const TST TST_BFloat16
bool SetConstexprSpec(ConstexprSpecKind ConstexprKind, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool SetTypeSpecWidth(TypeSpecifierWidth W, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
These methods set the specified attribute of the DeclSpec, but return true and ignore the request if ...
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceRange getSourceRange() const LLVM_READONLY
void SetRangeEnd(SourceLocation Loc)
bool SetBitIntType(SourceLocation KWLoc, Expr *BitWidth, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
static const TST TST_double
void SetRangeStart(SourceLocation Loc)
static const TST TST_char
static const TST TST_bool
static const TST TST_char16
static const TST TST_accum
static const TST TST_half
static const TST TST_ibm128
static const TST TST_float128
void Finish(Sema &S, const PrintingPolicy &Policy)
Finish - This does final analysis of the declspec, issuing diagnostics for things like "_Complex" (la...
static const TST TST_wchar
static const TST TST_void
static const TST TST_float
static const TST TST_fract
static const TST TST_float16
static const TST TST_decltype_auto
static const TST TST_error
static const TST TST_char32
static const TST TST_int128
bool SetTypeSpecSign(TypeSpecifierSign S, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_auto
Decl - This represents one declaration (or definition), e.g.
SourceLocation getLocation() const
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Information about one declarator, including the parsed type information and the identifier.
RAII object that enters a new expression evaluation context.
This represents one expression.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart, unsigned Characters, const SourceManager &SM, const LangOptions &LangOpts)
AdvanceToTokenCharacter - If the current SourceLocation specifies a location at the start of a token,...
static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, const LangOptions &LangOpts)
Computes the source location just past the end of the token at this source location.
This represents a decl that may have a name.
static OpaquePtr make(QualType P)
RAII object that makes sure paren/bracket/brace count is correct after declaration/statement parsing,...
ParsedAttr - Represents a syntactic attribute.
static const ParsedAttributesView & none()
ParsedAttributes - A collection of parsed attributes.
Parser - This implements a parser for the C family of languages.
TypeResult ParseTypeName(SourceRange *Range=nullptr, DeclaratorContext Context=DeclaratorContext::TypeName, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)
ParseTypeName type-name: [C99 6.7.6] specifier-qualifier-list abstract-declarator[opt].
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
AttributeFactory & getAttrFactory()
static TypeResult getTypeAnnotation(const Token &Tok)
getTypeAnnotation - Read a parsed type out of an annotation token.
ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause)
Parse a constraint-logical-or-expression.
bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, SourceLocation *TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext=false)
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
ExprResult ParseConstantExpression()
bool TryConsumeToken(tok::TokenKind Expected)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Scope * getCurScope() const
OpaquePtr< TemplateName > TemplateTy
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
ExprResult ParseAssignmentExpression(TypeCastState isTypeCast=NotTypeCast)
Parse an expr that doesn't include (top-level) commas.
const LangOptions & getLangOpts() const
ExprResult ParseExpression(TypeCastState isTypeCast=NotTypeCast)
Simple precedence-based parser for binary/ternary operators.
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtSemi
Stop skipping at semicolon.
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
ExprResult ParseConstraintExpression()
Parse a constraint-expression.
RAII object used to inform the actions that we're currently parsing a declaration.
void enterTypeCast(SourceLocation Tok, QualType CastType)
Handles all type casts, including C-style cast, C++ casts, etc.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
void EnterToken(const Token &Tok, bool IsReinject)
Enters a token in the token stream to be lexed next.
void AnnotateCachedTokens(const Token &Tok)
We notify the Preprocessor that if it is caching tokens (because backtrack is enabled) it should repl...
void Lex(Token &Result)
Lex the next token for this preprocessor.
const Token & LookAhead(unsigned N)
Peeks ahead N tokens and returns that token without consuming any tokens.
SourceManager & getSourceManager() const
void RevertCachedTokens(unsigned N)
When backtracking is enabled and tokens are cached, this allows to revert a specific number of tokens...
IdentifierTable & getIdentifierTable()
bool isCodeCompletionReached() const
Returns true if code-completion is enabled and we have hit the code-completion point.
SourceLocation getLastCachedTokenLocation() const
Get the location of the last cached token, suitable for setting the end location of an annotation tok...
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Computes the source location just past the end of the token at this source location.
If a crash happens while one of these objects are live, the message is printed out along with the spe...
A (possibly-)qualified type.
Represents the body of a requires-expression.
Scope - A scope is a transient data structure that is used while parsing the program.
@ FunctionPrototypeScope
This is a scope that corresponds to the parameters within a function prototype.
@ LambdaScope
This is the scope for a lambda, after the lambda introducer.
@ BlockScope
This is a scope that corresponds to a block/closure object.
@ ContinueScope
This is a while, do, for, which can have continue statements embedded into it.
@ BreakScope
This is a while, do, switch, for, etc that can have break statements embedded into it.
@ CompoundStmtScope
This is a compound statement scope.
@ FunctionDeclarationScope
This is a scope that corresponds to the parameters within a function prototype for a function declara...
@ FnScope
This indicates that the scope corresponds to a function, which means that labels are set here.
@ DeclScope
This is a scope that can contain a declaration.
void CodeCompleteObjCMessageReceiver(Scope *S)
void CodeCompleteOperatorName(Scope *S)
@ PCC_Condition
Code completion occurs within the condition of an if, while, switch, or for statement.
void CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro, bool AfterAmpersand)
QualType ProduceConstructorSignatureHelp(QualType Type, SourceLocation Loc, ArrayRef< Expr * > Args, SourceLocation OpenParLoc, bool Braced)
void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, bool EnteringContext, bool IsUsingDeclaration, QualType BaseType, QualType PreferredType)
void CodeCompleteOrdinaryName(Scope *S, ParserCompletionContext CompletionContext)
ExprResult ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc, bool isType, void *TyOrExpr, SourceLocation RParenLoc)
ActOnCXXTypeid - Parse typeid( something ).
ExprResult ActOnCXXUuidof(SourceLocation OpLoc, SourceLocation LParenLoc, bool isType, void *TyOrExpr, SourceLocation RParenLoc)
ActOnCXXUuidof - Parse __uuidof( something ).
ExprResult ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body)
ActOnLambdaExpr - This is called when the body of a lambda expression was successfully completed.
TypeResult ActOnTemplateIdType(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, TemplateTy Template, const IdentifierInfo *TemplateII, SourceLocation TemplateIILoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, SourceLocation RAngleLoc, bool IsCtorOrDtorName=false, bool IsClassName=false, ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No)
DeclResult ActOnCXXConditionDeclaration(Scope *S, Declarator &D)
ActOnCXXConditionDeclarationExpr - Parsed a condition declaration of a C++ if/switch/while/for statem...
ExprResult ActOnExpressionTrait(ExpressionTrait OET, SourceLocation KWLoc, Expr *Queried, SourceLocation RParen)
ActOnExpressionTrait - Parsed one of the unary type trait support pseudo-functions.
@ Switch
An integral condition for a 'switch' statement.
ExprResult ActOnIdExpression(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand, CorrectionCandidateCallback *CCC=nullptr, bool IsInlineAsmIdentifier=false, Token *KeywordReplacement=nullptr)
void ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, Scope *CurContext)
Once the Lambdas capture are known, we can start to create the closure, call operator method,...
concepts::Requirement * ActOnSimpleRequirement(Expr *E)
StmtResult ActOnExprStmt(ExprResult Arg, bool DiscardedValue=true)
concepts::Requirement * ActOnCompoundRequirement(Expr *E, SourceLocation NoexceptLoc)
bool ActOnCXXNestedNameSpecifierDecltype(CXXScopeSpec &SS, const DeclSpec &DS, SourceLocation ColonColonLoc)
ExprResult ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, bool ArrayForm, Expr *Operand)
ActOnCXXDelete - Parsed a C++ 'delete' expression (C++ 5.3.5), as in:
TemplateNameKind isTemplateName(Scope *S, CXXScopeSpec &SS, bool hasTemplateKeyword, const UnqualifiedId &Name, ParsedType ObjectType, bool EnteringContext, TemplateTy &Template, bool &MemberOfUnknownSpecialization, bool Disambiguation=false)
void FinalizeDeclaration(Decl *D)
FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform any semantic actions neces...
ExprResult ActOnCoyieldExpr(Scope *S, SourceLocation KwLoc, Expr *E)
ParsedType getDestructorName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec &SS, ParsedType ObjectType, bool EnteringContext)
ASTContext & getASTContext() const
bool isCurrentClassName(const IdentifierInfo &II, Scope *S, const CXXScopeSpec *SS=nullptr)
isCurrentClassName - Determine whether the identifier II is the name of the class type currently bein...
ExprResult ActOnPseudoDestructorExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, UnqualifiedId &FirstTypeName, SourceLocation CCLoc, SourceLocation TildeLoc, UnqualifiedId &SecondTypeName)
ExprResult ActOnParenListExpr(SourceLocation L, SourceLocation R, MultiExprArg Val)
ExprResult ActOnArrayTypeTrait(ArrayTypeTrait ATT, SourceLocation KWLoc, ParsedType LhsTy, Expr *DimExpr, SourceLocation RParen)
ActOnArrayTypeTrait - Parsed one of the binary type trait support pseudo-functions.
void ActOnFinishRequiresExpr()
ExprResult ActOnCXXThrow(Scope *S, SourceLocation OpLoc, Expr *expr)
sema::LambdaScopeInfo * getCurGenericLambda()
Retrieve the current generic lambda info, if any.
ExprResult ActOnNameClassifiedAsNonType(Scope *S, const CXXScopeSpec &SS, NamedDecl *Found, SourceLocation NameLoc, const Token &NextToken)
Act on the result of classifying a name as a specific non-type declaration.
ExprResult ActOnBuiltinBitCastExpr(SourceLocation KWLoc, Declarator &Dcl, ExprResult Operand, SourceLocation RParenLoc)
bool ActOnCXXGlobalScopeSpecifier(SourceLocation CCLoc, CXXScopeSpec &SS)
The parser has parsed a global nested-name-specifier '::'.
bool ActOnCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo, bool EnteringContext, CXXScopeSpec &SS, bool *IsCorrectedToColon=nullptr, bool OnlyNamespace=false)
The parser has parsed a nested-name-specifier 'identifier::'.
bool checkLiteralOperatorId(const CXXScopeSpec &SS, const UnqualifiedId &Id, bool IsUDSuffix)
ConditionResult ActOnCondition(Scope *S, SourceLocation Loc, Expr *SubExpr, ConditionKind CK, bool MissingOK=false)
sema::LambdaScopeInfo * PushLambdaScope()
SemaCodeCompletion & CodeCompletion()
void ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, Declarator &ParamInfo, const DeclSpec &DS)
ActOnStartOfLambdaDefinition - This is called just before we start parsing the body of a lambda; it a...
void ActOnLambdaClosureParameters(Scope *LambdaScope, MutableArrayRef< DeclaratorChunk::ParamInfo > ParamInfo)
ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind)
ActOnCXXBoolLiteral - Parse {true,false} literals.
bool ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS)
ExprResult ActOnCXXTypeConstructExpr(ParsedType TypeRep, SourceLocation LParenOrBraceLoc, MultiExprArg Exprs, SourceLocation RParenOrBraceLoc, bool ListInitialization)
ActOnCXXTypeConstructExpr - Parse construction of a specified type.
ConditionResult ActOnConditionVariable(Decl *ConditionVar, SourceLocation StmtLoc, ConditionKind CK)
bool ActOnSuperScopeSpecifier(SourceLocation SuperLoc, SourceLocation ColonColonLoc, CXXScopeSpec &SS)
The parser has parsed a '__super' nested-name-specifier.
ExprResult ActOnRequiresExpr(SourceLocation RequiresKWLoc, RequiresExprBodyDecl *Body, SourceLocation LParenLoc, ArrayRef< ParmVarDecl * > LocalParameters, SourceLocation RParenLoc, ArrayRef< concepts::Requirement * > Requirements, SourceLocation ClosingBraceLoc)
StmtResult ActOnNullStmt(SourceLocation SemiLoc, bool HasLeadingEmptyMacro=false)
ExprResult ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, SourceLocation LAngleBracketLoc, Declarator &D, SourceLocation RAngleBracketLoc, SourceLocation LParenLoc, Expr *E, SourceLocation RParenLoc)
ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const,addrspace}_cast's.
ExprResult ActOnPackIndexingExpr(Scope *S, Expr *PackExpression, SourceLocation EllipsisLoc, SourceLocation LSquareLoc, Expr *IndexExpr, SourceLocation RSquareLoc)
ParsedType getDestructorTypeForDecltype(const DeclSpec &DS, ParsedType ObjectType)
ExprResult ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, SourceLocation PlacementLParen, MultiExprArg PlacementArgs, SourceLocation PlacementRParen, SourceRange TypeIdParens, Declarator &D, Expr *Initializer)
Parsed a C++ 'new' expression (C++ 5.3.4).
void RestoreNestedNameSpecifierAnnotation(void *Annotation, SourceRange AnnotationRange, CXXScopeSpec &SS)
Given an annotation pointer for a nested-name-specifier, restore the nested-name-specifier structure.
TemplateNameKind ActOnTemplateName(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const UnqualifiedId &Name, ParsedType ObjectType, bool EnteringContext, TemplateTy &Template, bool AllowInjectedClassName=false)
Form a template name from a name that is syntactically required to name a template,...
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
SourceManager & getSourceManager() const
void ActOnLambdaExplicitTemplateParameterList(LambdaIntroducer &Intro, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > TParams, SourceLocation RAngleLoc, ExprResult RequiresClause)
This is called after parsing the explicit template parameter list on a lambda (if it exists) in C++2a...
bool ActOnCXXNestedNameSpecifierIndexedPack(CXXScopeSpec &SS, const DeclSpec &DS, SourceLocation ColonColonLoc, QualType Type)
ParsedType actOnLambdaInitCaptureInitialization(SourceLocation Loc, bool ByRef, SourceLocation EllipsisLoc, IdentifierInfo *Id, LambdaCaptureInitKind InitKind, Expr *&Init)
Perform initialization analysis of the init-capture and perform any implicit conversions such as an l...
void ActOnInitializerError(Decl *Dcl)
ActOnInitializerError - Given that there was an error parsing an initializer for the given declaratio...
ExprResult ActOnNameClassifiedAsUndeclaredNonType(IdentifierInfo *Name, SourceLocation NameLoc)
Act on the result of classifying a name as an undeclared (ADL-only) non-type declaration.
TypeResult ActOnTypeName(Declarator &D)
void ActOnLambdaClosureQualifiers(LambdaIntroducer &Intro, SourceLocation MutableLoc)
void ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope, bool IsInstantiation=false)
ActOnLambdaError - If there is an error parsing a lambda, this callback is invoked to pop the informa...
concepts::Requirement * ActOnTypeRequirement(SourceLocation TypenameKWLoc, CXXScopeSpec &SS, SourceLocation NameLoc, const IdentifierInfo *TypeName, TemplateIdAnnotation *TemplateId)
ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, SourceLocation EllipsisLoc)
Invoked when parsing a template argument followed by an ellipsis, which creates a pack expansion.
ExprResult ActOnRequiresClause(ExprResult ConstraintExpr)
RequiresExprBodyDecl * ActOnStartRequiresExpr(SourceLocation RequiresKWLoc, ArrayRef< ParmVarDecl * > LocalParameters, Scope *BodyScope)
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
void RecordParsingTemplateParameterDepth(unsigned Depth)
This is used to inform Sema what the current TemplateParameterDepth is during Parsing.
StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)
ExprResult ActOnCastExpr(Scope *S, SourceLocation LParenLoc, Declarator &D, ParsedType &Ty, SourceLocation RParenLoc, Expr *CastExpr)
bool isDeductionGuideName(Scope *S, const IdentifierInfo &Name, SourceLocation NameLoc, CXXScopeSpec &SS, ParsedTemplateTy *Template=nullptr)
Determine whether a particular identifier might be the name in a C++1z deduction-guide declaration.
ExprResult ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc, ArrayRef< ParsedType > Args, SourceLocation RParenLoc)
Parsed one of the type trait support pseudo-functions.
QualType ActOnPackIndexingType(QualType Pattern, Expr *IndexExpr, SourceLocation Loc, SourceLocation EllipsisLoc)
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
ParsedType getConstructorName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec &SS, bool EnteringContext)
ExprResult ActOnNameClassifiedAsDependentNonType(const CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, bool IsAddressOfOperand)
Act on the result of classifying a name as an undeclared member of a dependent base class.
concepts::Requirement * ActOnNestedRequirement(Expr *Constraint)
static ConditionResult ConditionError()
bool IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS, NestedNameSpecInfo &IdInfo, bool EnteringContext)
IsInvalidUnlessNestedName - This method is used for error recovery purposes to determine whether the ...
ExprResult ActOnCXXThis(SourceLocation Loc)
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...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
void setBegin(SourceLocation b)
SourceLocation getEnd() const
SourceLocation getBegin() const
void setEnd(SourceLocation e)
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteralParser - This decodes string escape characters and performs wide string analysis and Tra...
Represents a C++ template name within the type system.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
void setAnnotationEndLoc(SourceLocation L)
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
const char * getName() const
unsigned getLength() const
void setLength(unsigned Len)
void setKind(tok::TokenKind K)
SourceLocation getAnnotationEndLoc() const
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
void * getAnnotationValue() const
tok::TokenKind getKind() const
bool isRegularKeywordAttribute() const
Return true if the token is a keyword that is parsed in the same position as a standard attribute,...
void setEofData(const void *D)
SourceRange getAnnotationRange() const
SourceRange of the group of tokens that this annotation token represents.
void setLocation(SourceLocation L)
bool hasLeadingEmptyMacro() const
Return true if this token has an empty macro before it.
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
bool isNot(tok::TokenKind K) const
const void * getEofData() const
void startToken()
Reset all flags to cleared.
The base class of the type hierarchy.
QualType getCanonicalTypeInternal() const
Represents a C++ unqualified-id that has been parsed.
void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Specify that this unqualified-id was parsed as an identifier.
bool isValid() const
Determine whether this unqualified-id refers to a valid name.
void setTemplateId(TemplateIdAnnotation *TemplateId)
Specify that this unqualified-id was parsed as a template-id.
A static requirement that can be used in a requires-expression to check properties of types and expre...
uint32_t Literal
Literals are represented as positive integers.
@ After
Like System, but searched after the system directories.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ OO_None
Not an overloaded operator.
ArrayTypeTrait
Names for the array type traits.
LambdaCaptureKind
The different capture forms in a lambda introducer.
@ LCK_ByCopy
Capturing by copy (a.k.a., by value)
@ LCK_ByRef
Capturing by reference.
@ LCK_StarThis
Capturing the *this object by copy.
@ LCK_This
Capturing the *this object by reference.
@ IK_ConstructorName
A constructor name.
@ IK_LiteralOperatorId
A user-defined literal name, e.g., operator "" _i.
@ IK_Identifier
An identifier.
@ IK_DestructorName
A destructor name.
@ IK_OperatorFunctionId
An overloaded operator name, e.g., operator+.
@ CopyInit
[a = b], [a = {b}]
@ Result
The result type of a method or function.
ActionResult< Expr * > ExprResult
TemplateNameKind
Specifies the kind of template name that an identifier refers to.
@ TNK_Var_template
The name refers to a variable template whose specialization produces a variable.
@ TNK_Dependent_template_name
The name refers to a dependent template name:
@ TNK_Function_template
The name refers to a function template or a set of overloaded functions that includes at least one fu...
@ TNK_Non_template
The name does not refer to a template.
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
const FunctionProtoType * T
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword.
TypeTrait
Names for traits that operate specifically on types.
@ Parens
New-expression has a C++98 paren-delimited initializer.
@ Braces
New-expression has a C++11 list-initializer.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_None
no exception specification
static DeclaratorChunk getFunction(bool HasProto, bool IsAmbiguous, SourceLocation LParenLoc, ParamInfo *Params, unsigned NumParams, SourceLocation EllipsisLoc, SourceLocation RParenLoc, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, SourceRange ESpecRange, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, Expr *NoexceptExpr, CachedTokens *ExceptionSpecTokens, ArrayRef< NamedDecl * > DeclsInPrototype, SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, TypeResult TrailingReturnType=TypeResult(), SourceLocation TrailingReturnTypeLoc=SourceLocation(), DeclSpec *MethodQualifiers=nullptr)
DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic, bool isStar, Expr *NumElts, SourceLocation LBLoc, SourceLocation RBLoc)
Return a DeclaratorChunk for an array.
Represents a complete lambda introducer.
bool hasLambdaCapture() const
void addCapture(LambdaCaptureKind Kind, SourceLocation Loc, IdentifierInfo *Id, SourceLocation EllipsisLoc, LambdaCaptureInitKind InitKind, ExprResult Init, ParsedType InitCaptureType, SourceRange ExplicitRange)
Append a capture in a lambda introducer.
SourceLocation DefaultLoc
LambdaCaptureDefault Default
Describes how types, statements, expressions, and declarations should be printed.
Keeps information about an identifier in a nested-name-spec.
Information about a template-id annotation token.
const IdentifierInfo * Name
FIXME: Temporarily stores the name of a specialization.
unsigned NumArgs
NumArgs - The number of template arguments.
SourceLocation TemplateNameLoc
TemplateNameLoc - The location of the template name within the source.
ParsedTemplateArgument * getTemplateArgs()
Retrieves a pointer to the template arguments.
SourceLocation RAngleLoc
The location of the '>' after the template argument list.
SourceLocation LAngleLoc
The location of the '<' before the template argument list.
SourceLocation TemplateKWLoc
TemplateKWLoc - The location of the template keyword.
ParsedTemplateTy Template
The declaration of the template corresponding to the template-name.
static TemplateIdAnnotation * Create(SourceLocation TemplateKWLoc, SourceLocation TemplateNameLoc, const IdentifierInfo *Name, OverloadedOperatorKind OperatorKind, ParsedTemplateTy OpaqueTemplateName, TemplateNameKind TemplateKind, SourceLocation LAngleLoc, SourceLocation RAngleLoc, ArrayRef< ParsedTemplateArgument > TemplateArgs, bool ArgsInvalid, SmallVectorImpl< TemplateIdAnnotation * > &CleanupList)
Creates a new TemplateIdAnnotation with NumArgs arguments and appends it to List.