clang: lib/Parse/ParseTentative.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
17using namespace clang;
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49bool Parser::isCXXDeclarationStatement(
50 bool DisambiguatingWithExpression ) {
52
54
55 case tok::kw_asm:
56
57 case tok::kw_namespace:
58
59
60 case tok::kw_using:
61
62 case tok::kw_static_assert:
63 case tok::kw__Static_assert:
64 return true;
65 case tok::coloncolon:
66 case tok::identifier: {
67 if (DisambiguatingWithExpression) {
68 RevertingTentativeParsingAction TPA(*this);
69
71 ParseOptionalCXXScopeSpecifier(SS, nullptr,
72 false,
73 true);
74
76 case tok::identifier: {
81 isDeductionGuide) {
82 if (isConstructorDeclarator(
83 SS.isEmpty(), isDeductionGuide,
85 return true;
87
88
89
90
91
92
93
94
95 if (NextToken().is(tok::identifier))
96 return true;
97 }
98 break;
99 }
100 case tok::kw_operator:
101 return true;
102 case tok::tilde:
103 return true;
104 default:
105 break;
106 }
107 }
108 }
109 [[fallthrough]];
110
111 default:
112 return isCXXSimpleDeclaration(false);
113 }
114}
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136bool Parser::isCXXSimpleDeclaration(bool AllowForRangeDecl) {
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161 bool InvalidAsDeclaration = false;
162 TPResult TPR = isCXXDeclarationSpecifier(
164 if (TPR != TPResult::Ambiguous)
165 return TPR != TPResult::False;
166
167
168
169
170
171
172
173 if (InvalidAsDeclaration)
174 return false;
175
176
177
178
179
180
181
182
183 {
184 RevertingTentativeParsingAction PA(*this);
185 TPR = TryParseSimpleDeclaration(AllowForRangeDecl);
186 }
187
188
189 if (TPR == TPResult::Error)
190 return true;
191
192
193 if (TPR == TPResult::Ambiguous)
194 TPR = TPResult::True;
195
196 assert(TPR == TPResult::True || TPR == TPResult::False);
197 return TPR == TPResult::True;
198}
199
200
201
202Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
204 case tok::kw__Atomic:
205 if (NextToken().isNot(tok::l_paren)) {
207 break;
208 }
209 [[fallthrough]];
210 case tok::kw_typeof:
211 case tok::kw___attribute:
212#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
213#include "clang/Basic/TransformTypeTraits.def"
214 {
216 if (Tok.isNot(tok::l_paren))
217 return TPResult::Error;
218 ConsumeParen();
220 return TPResult::Error;
221 break;
222 }
223
224 case tok::kw_class:
225 case tok::kw_struct:
226 case tok::kw_union:
227 case tok::kw___interface:
228 case tok::kw_enum:
229
230
231
232
233
234
235
237
238
239 if (!TrySkipAttributes())
240 return TPResult::Error;
241
243 return TPResult::Error;
244 if (Tok.is(tok::annot_cxxscope))
245 ConsumeAnnotationToken();
246 if (Tok.is(tok::identifier))
248 else if (Tok.is(tok::annot_template_id))
249 ConsumeAnnotationToken();
250 else
251 return TPResult::Error;
252 break;
253
254 case tok::annot_cxxscope:
255 ConsumeAnnotationToken();
256 [[fallthrough]];
257 default:
259
261 return TryParseProtocolQualifiers();
262 break;
263 }
264
265 return TPResult::Ambiguous;
266}
267
268
269
270
271
272
273
274
275
276Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) {
277 bool DeclSpecifierIsAuto = Tok.is(tok::kw_auto);
278 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
279 return TPResult::Error;
280
281
282
283
284 if (Tok.isNot(tok::l_paren)) {
286 if (TPR == TPResult::Ambiguous)
287 return TPResult::True;
288 if (TPR == TPResult::True || TPR == TPResult::Error)
289 return TPR;
290 assert(TPR == TPResult::False);
291 }
292
293 TPResult TPR = TryParseInitDeclaratorList(
294 DeclSpecifierIsAuto);
295 if (TPR != TPResult::Ambiguous)
296 return TPR;
297
298 if (Tok.isNot(tok::semi) && (!AllowForRangeDecl || Tok.isNot(tok::colon)))
299 return TPResult::False;
300
301 return TPResult::Ambiguous;
302}
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331Parser::TPResult
332Parser::TryParseInitDeclaratorList(bool MayHaveTrailingReturnType) {
333 while (true) {
334
335 TPResult TPR = TryParseDeclarator(
336 false,
337 true,
338 false,
339 MayHaveTrailingReturnType);
340 if (TPR != TPResult::Ambiguous)
341 return TPR;
342
343
344 if (Tok.isOneOf(tok::kw_asm, tok::kw___attribute))
345 return TPResult::True;
346
347
348 if (Tok.is(tok::l_paren)) {
349
350 ConsumeParen();
352 return TPResult::Error;
353 } else if (Tok.is(tok::l_brace)) {
354
355
356 return TPResult::True;
357 } else if (Tok.is(tok::equal) || isTokIdentifier_in()) {
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374 return TPResult::True;
375 }
376
378 break;
379 }
380
381 return TPResult::Ambiguous;
382}
383
390
395
399 }
400
403
405
406
407
408
409 RevertingTentativeParsingAction PA(P);
411
412
413 unsigned QuestionColonDepth = 0;
414 while (true) {
415 P.SkipUntil({tok::r_paren, tok::semi, tok::question, tok::colon},
417 if (P.Tok.is(tok::question))
418 ++QuestionColonDepth;
419 else if (P.Tok.is(tok::colon)) {
420 if (QuestionColonDepth)
421 --QuestionColonDepth;
422 else {
424 return;
425 }
426 } else {
428 break;
429 }
431 }
432 } else {
433
435 }
436 if (P.Tok.isNot(tok::r_paren))
438 if (P.Tok.isNot(tok::semi))
440 }
441 }
442
446 }
447
451 }
452
454 switch (IsDecl) {
455 case TPResult::True:
457 assert(resolved() && "can't continue after tentative parsing bails out");
458 break;
459 case TPResult::False:
461 break;
462 case TPResult::Ambiguous:
463 break;
464 case TPResult::Error:
467 break;
468 }
470 }
471
472 ConditionOrInitStatement result() const {
475 "result called but not yet resolved");
477 return ConditionOrInitStatement::Expression;
479 return ConditionOrInitStatement::ConditionDecl;
481 return ConditionOrInitStatement::InitStmtDecl;
483 return ConditionOrInitStatement::ForRangeDecl;
484 return ConditionOrInitStatement::Error;
485 }
486};
487
488bool Parser::isEnumBase(bool AllowSemi) {
489 assert(Tok.is(tok::colon) && "should be looking at the ':'");
490
491 RevertingTentativeParsingAction PA(*this);
492
494
495
496 bool InvalidAsDeclSpec = false;
497
498
499
501 TPResult::True,
502 &InvalidAsDeclSpec);
503 if (R == TPResult::Ambiguous) {
504
505
506 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
507 return true;
508
509
510
511 if (Tok.is(tok::l_brace) || (AllowSemi && Tok.is(tok::semi)))
512 return true;
513
514
516 &InvalidAsDeclSpec);
517 }
518
519 return R != TPResult::False;
520}
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539Parser::ConditionOrInitStatement
540Parser::isCXXConditionDeclarationOrInitStatement(bool CanBeInitStatement,
541 bool CanBeForRangeDecl) {
542 ConditionDeclarationOrInitStatementState State(*this, CanBeInitStatement,
543 CanBeForRangeDecl);
544
545 if (CanBeInitStatement && Tok.is(tok::kw_using))
546 return ConditionOrInitStatement::InitStmtDecl;
548 return State.result();
549
550
551 RevertingTentativeParsingAction PA(*this);
552
553
554 bool MayHaveTrailingReturnType = Tok.is(tok::kw_auto);
555 if (State.update(TryConsumeDeclarationSpecifier()))
556 return State.result();
557 assert(Tok.is(tok::l_paren) && "Expected '('");
558
559 while (true) {
560
561 if (State.update(TryParseDeclarator(
562 false,
563 true,
564 false,
565 MayHaveTrailingReturnType)))
566 return State.result();
567
568
569
570
571 if (Tok.isOneOf(tok::equal, tok::kw_asm, tok::kw___attribute) ||
573 State.markNotExpression();
574 return State.result();
575 }
576
577
578 if (State.CanBeForRangeDecl && Tok.is(tok::colon))
579 return ConditionOrInitStatement::ForRangeDecl;
580
581
582
583 if (State.markNotCondition())
584 return State.result();
585
586
587 if (State.markNotForRangeDecl())
588 return State.result();
589
590
591
592 if (Tok.is(tok::l_paren)) {
593 ConsumeParen();
595 }
596
598 break;
599 }
600
601
602 if (State.CanBeCondition && Tok.is(tok::r_paren))
603 return ConditionOrInitStatement::ConditionDecl;
604 else if (State.CanBeInitStatement && Tok.is(tok::semi))
605 return ConditionOrInitStatement::InitStmtDecl;
606 else
607 return ConditionOrInitStatement::Expression;
608}
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {
628
629 isAmbiguous = false;
630
631
632
633
634
635
636
637
639 if (TPR != TPResult::Ambiguous)
640 return TPR != TPResult::False;
641
642
643
644
645
646
647
648
649 RevertingTentativeParsingAction PA(*this);
650 bool MayHaveTrailingReturnType = Tok.is(tok::kw_auto);
651
652
653 TryConsumeDeclarationSpecifier();
654 assert(Tok.is(tok::l_paren) && "Expected '('");
655
656
657 TPR = TryParseDeclarator(true , false ,
658 false,
659 MayHaveTrailingReturnType);
660
661
662 if (TPR == TPResult::Error)
663 TPR = TPResult::True;
664
665 if (TPR == TPResult::Ambiguous) {
666
667
668 if (Context == TypeIdInParens && Tok.is(tok::r_paren)) {
669 TPR = TPResult::True;
670 isAmbiguous = true;
671
672
673
674 } else if (Context == TypeIdAsGenericSelectionArgument && Tok.is(tok::comma)) {
675 TPR = TPResult::True;
676 isAmbiguous = true;
677
678
679
680
681 } else if (Context == TypeIdAsTemplateArgument &&
682 (Tok.isOneOf(tok::greater, tok::comma) ||
684 (Tok.isOneOf(tok::greatergreater,
685 tok::greatergreatergreater) ||
686 (Tok.is(tok::ellipsis) &&
688 tok::greatergreatergreater,
689 tok::comma)))))) {
690 TPR = TPResult::True;
691 isAmbiguous = true;
692
693 } else if (Context == TypeIdInTrailingReturnType) {
694 TPR = TPResult::True;
695 isAmbiguous = true;
696 } else
697 TPR = TPResult::False;
698 }
699
700 assert(TPR == TPResult::True || TPR == TPResult::False);
701 return TPR == TPResult::True;
702}
703
704
705
706
707
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
737Parser::CXX11AttributeKind
738Parser::isCXX11AttributeSpecifier(bool Disambiguate,
739 bool OuterMightBeMessageSend) {
740
742 return CAK_AttributeSpecifier;
743
745 return CAK_AttributeSpecifier;
746
747 if (Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square))
748 return CAK_NotAttributeSpecifier;
749
750
752 return CAK_AttributeSpecifier;
753
754
755 if (GetLookAheadToken(2).is(tok::kw_using))
756 return CAK_AttributeSpecifier;
757
758 RevertingTentativeParsingAction PA(*this);
759
760
761 ConsumeBracket();
762
764 ConsumeBracket();
765
766 bool IsAttribute = SkipUntil(tok::r_square);
767 IsAttribute &= Tok.is(tok::r_square);
768
769 return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier;
770 }
771
772
773
774
775
776
777
778
779
780
781
782
783
784 {
785 RevertingTentativeParsingAction LambdaTPA(*this);
787 LambdaIntroducerTentativeParse Tentative;
788 if (ParseLambdaIntroducer(Intro, &Tentative)) {
789
790
791
792 return CAK_NotAttributeSpecifier;
793 }
794
795 switch (Tentative) {
796 case LambdaIntroducerTentativeParse::MessageSend:
797
798
799 return CAK_NotAttributeSpecifier;
800
801 case LambdaIntroducerTentativeParse::Success:
802 case LambdaIntroducerTentativeParse::Incomplete:
803
804 if (Tok.is(tok::r_square))
805
806 return CAK_AttributeSpecifier;
807
808 if (OuterMightBeMessageSend)
809
810 return CAK_NotAttributeSpecifier;
811
812
813 return CAK_InvalidAttributeSpecifier;
814
815 case LambdaIntroducerTentativeParse::Invalid:
816
817
818 break;
819 }
820 }
821
822 ConsumeBracket();
823
824
825
826 bool IsAttribute = true;
827 while (Tok.isNot(tok::r_square)) {
828 if (Tok.is(tok::comma)) {
829
830 return CAK_AttributeSpecifier;
831 }
832
833
834
835
836
837
839 if (!TryParseCXX11AttributeIdentifier(Loc)) {
840 IsAttribute = false;
841 break;
842 }
843 if (Tok.is(tok::coloncolon)) {
845 if (!TryParseCXX11AttributeIdentifier(Loc)) {
846 IsAttribute = false;
847 break;
848 }
849 }
850
851
852 if (Tok.is(tok::l_paren)) {
853 ConsumeParen();
855 IsAttribute = false;
856 break;
857 }
858 }
859
861
863 break;
864 }
865
866
867 if (IsAttribute) {
868 if (Tok.is(tok::r_square)) {
869 ConsumeBracket();
870 IsAttribute = Tok.is(tok::r_square);
871 } else {
872 IsAttribute = false;
873 }
874 }
875
876 if (IsAttribute)
877
878 return CAK_AttributeSpecifier;
879
880
881 return CAK_NotAttributeSpecifier;
882}
883
884bool Parser::TrySkipAttributes() {
885 while (Tok.isOneOf(tok::l_square, tok::kw___attribute, tok::kw___declspec,
886 tok::kw_alignas) ||
888 if (Tok.is(tok::l_square)) {
889 ConsumeBracket();
890 if (Tok.isNot(tok::l_square))
891 return false;
892 ConsumeBracket();
893 if ((tok::r_square) || Tok.isNot(tok::r_square))
894 return false;
895
896
897 ConsumeBracket();
901 } else {
903 if (Tok.isNot(tok::l_paren))
904 return false;
905 ConsumeParen();
907 return false;
908 }
909 }
910
911 return true;
912}
913
914Parser::TPResult Parser::TryParsePtrOperatorSeq() {
915 while (true) {
917 return TPResult::Error;
918
919 if (Tok.isOneOf(tok::star, tok::amp, tok::caret, tok::ampamp) ||
920 (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) {
921
923
924
925 if (!TrySkipAttributes())
926 return TPResult::Error;
927
928 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,
929 tok::kw__Nonnull, tok::kw__Nullable,
930 tok::kw__Nullable_result, tok::kw__Null_unspecified,
931 tok::kw__Atomic))
933 } else {
934 return TPResult::True;
935 }
936 }
937}
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957Parser::TPResult Parser::TryParseOperatorId() {
958 assert(Tok.is(tok::kw_operator));
960
961
963 case tok::kw_new: case tok::kw_delete:
965 if (Tok.is(tok::l_square) && NextToken().is(tok::r_square)) {
966 ConsumeBracket();
967 ConsumeBracket();
968 }
969 return TPResult::True;
970
971#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \
972 case tok::Token:
973#define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly)
974#include "clang/Basic/OperatorKinds.def"
976 return TPResult::True;
977
978 case tok::l_square:
979 if (NextToken().is(tok::r_square)) {
980 ConsumeBracket();
981 ConsumeBracket();
982 return TPResult::True;
983 }
984 break;
985
986 case tok::l_paren:
987 if (NextToken().is(tok::r_paren)) {
988 ConsumeParen();
989 ConsumeParen();
990 return TPResult::True;
991 }
992 break;
993
994 default:
995 break;
996 }
997
998
1000 bool FoundUDSuffix = false;
1001 do {
1003 ConsumeStringToken();
1004 } while (isTokenStringLiteral());
1005
1006 if (!FoundUDSuffix) {
1007 if (Tok.is(tok::identifier))
1009 else
1010 return TPResult::Error;
1011 }
1012 return TPResult::True;
1013 }
1014
1015
1016 bool AnyDeclSpecifiers = false;
1017 while (true) {
1019 if (TPR == TPResult::Error)
1020 return TPR;
1021 if (TPR == TPResult::False) {
1022 if (!AnyDeclSpecifiers)
1023 return TPResult::Error;
1024 break;
1025 }
1026 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
1027 return TPResult::Error;
1028 AnyDeclSpecifiers = true;
1029 }
1030 return TryParsePtrOperatorSeq();
1031}
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
1087 bool mayHaveIdentifier,
1088 bool mayHaveDirectInit,
1089 bool mayHaveTrailingReturnType) {
1090
1091
1092
1093 if (TryParsePtrOperatorSeq() == TPResult::Error)
1094 return TPResult::Error;
1095
1096
1097
1098 if (Tok.is(tok::ellipsis))
1100
1101 if ((Tok.isOneOf(tok::identifier, tok::kw_operator) ||
1102 (Tok.is(tok::annot_cxxscope) && (NextToken().is(tok::identifier) ||
1103 NextToken().is(tok::kw_operator)))) &&
1104 mayHaveIdentifier) {
1105
1106 if (Tok.is(tok::annot_cxxscope)) {
1111 return TPResult::Error;
1112 ConsumeAnnotationToken();
1113 } else if (Tok.is(tok::identifier)) {
1114 TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());
1115 }
1116 if (Tok.is(tok::kw_operator)) {
1117 if (TryParseOperatorId() == TPResult::Error)
1118 return TPResult::Error;
1119 } else
1121 } else if (Tok.is(tok::l_paren)) {
1122 ConsumeParen();
1123 if (mayBeAbstract &&
1124 (Tok.is(tok::r_paren) ||
1125
1126 (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren)) ||
1127 isDeclarationSpecifier(
1129
1130
1131 TPResult TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
1132 if (TPR != TPResult::Ambiguous)
1133 return TPR;
1134 } else {
1135
1136
1137
1138 if (Tok.isOneOf(tok::kw___attribute, tok::kw___declspec, tok::kw___cdecl,
1139 tok::kw___stdcall, tok::kw___fastcall, tok::kw___thiscall,
1140 tok::kw___regcall, tok::kw___vectorcall))
1141 return TPResult::True;
1142 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
1143 if (TPR != TPResult::Ambiguous)
1144 return TPR;
1145 if (Tok.isNot(tok::r_paren))
1146 return TPResult::False;
1147 ConsumeParen();
1148 }
1149 } else if (!mayBeAbstract) {
1150 return TPResult::False;
1151 }
1152
1153 if (mayHaveDirectInit)
1154 return TPResult::Ambiguous;
1155
1156 while (true) {
1157 TPResult TPR(TPResult::Ambiguous);
1158
1159 if (Tok.is(tok::l_paren)) {
1160
1161
1162
1163
1164 if (!mayBeAbstract && !isCXXFunctionDeclarator())
1165 break;
1166
1167
1168
1169 ConsumeParen();
1170 TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
1171 } else if (Tok.is(tok::l_square)) {
1172
1173
1174 TPR = TryParseBracketDeclarator();
1175 } else if (Tok.is(tok::kw_requires)) {
1176
1177
1178 TPR = TPResult::True;
1179 } else {
1180 break;
1181 }
1182
1183 if (TPR != TPResult::Ambiguous)
1184 return TPR;
1185 }
1186
1187 return TPResult::Ambiguous;
1188}
1189
1190bool Parser::isTentativelyDeclared(IdentifierInfo *II) {
1191 return llvm::is_contained(TentativelyDeclaredIdentifiers, II);
1192}
1193
1194namespace {
1196public:
1197 TentativeParseCCC(const Token &Next) {
1198 WantRemainingKeywords = false;
1199 WantTypeSpecifiers =
1200 Next.isOneOf(tok::l_paren, tok::r_paren, tok::greater, tok::l_brace,
1201 tok::identifier, tok::comma);
1202 }
1203
1204 bool ValidateCandidate(const TypoCorrection &Candidate) override {
1205
1206
1208 llvm::all_of(Candidate,
1209 [](NamedDecl *ND) { return ND->isCXXInstanceMember(); }))
1210 return false;
1211
1213 }
1214
1215 std::unique_ptr clone() override {
1216 return std::make_unique(*this);
1217 }
1218};
1219}
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332Parser::TPResult
1334 Parser::TPResult BracedCastResult,
1335 bool *InvalidAsDeclSpec) {
1337 int Lookahead) {
1338
1339
1341 (GetLookAheadToken(Lookahead + 1)
1342 .isOneOf(tok::kw_auto, tok::kw_decltype,
1343
1344
1345
1346
1347 tok::identifier,
1348
1349
1350
1351
1352 tok::kw_const, tok::kw_volatile, tok::kw_restrict) ||
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362 (TemplateId->NumArgs == 0 &&
1363 GetLookAheadToken(Lookahead + 1).isOneOf(tok::amp, tok::ampamp)));
1364 };
1365 switch (Tok.getKind()) {
1366 case tok::identifier: {
1367 if (GetLookAheadToken(1).is(tok::ellipsis) &&
1368 GetLookAheadToken(2).is(tok::l_square)) {
1369
1371 return TPResult::Error;
1372 if (Tok.is(tok::identifier))
1373 return TPResult::False;
1375 BracedCastResult, InvalidAsDeclSpec);
1376 }
1377
1378
1379
1380 if (TryAltiVecVectorToken())
1381 return TPResult::True;
1382
1384
1386 return TPResult::True;
1387
1388
1389
1390
1391 if (Next.is(tok::l_paren) &&
1394 return TPResult::False;
1395 }
1396
1397 if (Next.isNot(tok::coloncolon) && Next.isNot(tok::less)) {
1398
1399
1400
1401
1402 TentativeParseCCC CCC(Next);
1403 switch (TryAnnotateName(&CCC)) {
1404 case ANK_Error:
1405 return TPResult::Error;
1406 case ANK_TentativeDecl:
1407 return TPResult::False;
1408 case ANK_TemplateName:
1409
1410
1411
1412
1415 return TPResult::Error;
1416 if (Tok.isNot(tok::identifier))
1417 break;
1418 }
1419
1420
1421
1422 return GreaterThanIsOperator ? TPResult::True : TPResult::False;
1423 case ANK_Unresolved:
1424 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1425 case ANK_Success:
1426 break;
1427 }
1428 assert(Tok.isNot(tok::identifier) &&
1429 "TryAnnotateName succeeded without producing an annotation");
1430 } else {
1431
1432
1433
1434
1436 return TPResult::Error;
1437
1438
1439
1440 if (Tok.is(tok::identifier))
1441 return TPResult::False;
1442 }
1443
1444
1445 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1446 InvalidAsDeclSpec);
1447 }
1448
1449 case tok::kw_typename:
1450
1451
1453 return TPResult::Error;
1455 BracedCastResult, InvalidAsDeclSpec);
1456
1457 case tok::kw_auto: {
1459 return TPResult::True;
1460 if (NextToken().is(tok::l_brace))
1461 return TPResult::False;
1462 if (NextToken().is(tok::l_paren))
1463 return TPResult::Ambiguous;
1464 return TPResult::True;
1465 }
1466
1467 case tok::coloncolon: {
1469 if (Next.isOneOf(tok::kw_new,
1470 tok::kw_delete))
1471 return TPResult::False;
1472 [[fallthrough]];
1473 }
1474 case tok::kw___super:
1475 case tok::kw_decltype:
1476
1477
1479 return TPResult::Error;
1480 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1481 InvalidAsDeclSpec);
1482
1483
1484
1485
1486
1487
1488
1489
1490 case tok::kw_friend:
1491 case tok::kw_typedef:
1492 case tok::kw_constexpr:
1493 case tok::kw_consteval:
1494 case tok::kw_constinit:
1495
1496 case tok::kw_register:
1497 case tok::kw_static:
1498 case tok::kw_extern:
1499 case tok::kw_mutable:
1500 case tok::kw___thread:
1501 case tok::kw_thread_local:
1502 case tok::kw__Thread_local:
1503
1504 case tok::kw_inline:
1505 case tok::kw_virtual:
1506 case tok::kw_explicit:
1507
1508
1509 case tok::kw___module_private__:
1510
1511
1512 case tok::kw___unknown_anytype:
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524 case tok::kw_class:
1525 case tok::kw_struct:
1526 case tok::kw_union:
1527 case tok::kw___interface:
1528
1529 case tok::kw_enum:
1530
1531 case tok::kw_const:
1532 case tok::kw_volatile:
1533 return TPResult::True;
1534
1535
1536 case tok::kw_private:
1538 return TPResult::False;
1539 [[fallthrough]];
1540 case tok::kw___private:
1541 case tok::kw___local:
1542 case tok::kw___global:
1543 case tok::kw___constant:
1544 case tok::kw___generic:
1545
1546 case tok::kw___read_only:
1547 case tok::kw___write_only:
1548 case tok::kw___read_write:
1549
1550 case tok::kw_pipe:
1551
1552
1553 case tok::kw_groupshared:
1554 case tok::kw_in:
1555 case tok::kw_inout:
1556 case tok::kw_out:
1557
1558
1559 case tok::kw_restrict:
1560 case tok::kw__Complex:
1561 case tok::kw___attribute:
1562 case tok::kw___auto_type:
1563 return TPResult::True;
1564
1565
1566 case tok::kw___declspec:
1567 case tok::kw___cdecl:
1568 case tok::kw___stdcall:
1569 case tok::kw___fastcall:
1570 case tok::kw___thiscall:
1571 case tok::kw___regcall:
1572 case tok::kw___vectorcall:
1573 case tok::kw___w64:
1574 case tok::kw___sptr:
1575 case tok::kw___uptr:
1576 case tok::kw___ptr64:
1577 case tok::kw___ptr32:
1578 case tok::kw___forceinline:
1579 case tok::kw___unaligned:
1580 case tok::kw__Nonnull:
1581 case tok::kw__Nullable:
1582 case tok::kw__Nullable_result:
1583 case tok::kw__Null_unspecified:
1584 case tok::kw___kindof:
1585 return TPResult::True;
1586
1587
1588 case tok::kw___funcref:
1589 return TPResult::True;
1590
1591
1592 case tok::kw___pascal:
1593 return TPResult::True;
1594
1595
1596 case tok::kw___vector:
1597 return TPResult::True;
1598
1599 case tok::kw_this: {
1600
1601
1603 RevertingTentativeParsingAction PA(*this);
1605 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1606 InvalidAsDeclSpec);
1607 }
1608 return TPResult::False;
1609 }
1610 case tok::annot_template_id: {
1612
1613
1616 InvalidAsDeclSpec) {
1617
1618
1619
1620
1621 *InvalidAsDeclSpec = NextToken().is(tok::l_paren);
1622 return TPResult::Ambiguous;
1623 }
1625 return TPResult::Error;
1626 if (IsPlaceholderSpecifier(TemplateId, 0))
1627 return TPResult::True;
1629 return TPResult::False;
1631 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
1632 assert(Tok.is(tok::annot_typename));
1633 goto case_typename;
1634 }
1635
1636 case tok::annot_cxxscope:
1637
1639 return TPResult::Error;
1640 if (!Tok.is(tok::annot_typename)) {
1641 if (Tok.is(tok::annot_cxxscope) &&
1642 NextToken().is(tok::annot_template_id)) {
1644 takeTemplateIdAnnotation(NextToken());
1646 if (InvalidAsDeclSpec) {
1647 *InvalidAsDeclSpec = NextToken().is(tok::l_paren);
1648 return TPResult::Ambiguous;
1649 }
1650 return TPResult::Error;
1651 }
1652 if (IsPlaceholderSpecifier(TemplateId, 1))
1653 return TPResult::True;
1654 }
1655
1656
1657 if (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier)) {
1661 SS);
1663 RevertingTentativeParsingAction PA(*this);
1664 ConsumeAnnotationToken();
1666 bool isIdentifier = Tok.is(tok::identifier);
1667 TPResult TPR = TPResult::False;
1668 if (!isIdentifier)
1669 TPR = isCXXDeclarationSpecifier(
1670 AllowImplicitTypename, BracedCastResult, InvalidAsDeclSpec);
1671
1672 if (isIdentifier ||
1673 TPR == TPResult::True || TPR == TPResult::Error)
1674 return TPResult::Error;
1675
1676 if (InvalidAsDeclSpec) {
1677
1678
1679 *InvalidAsDeclSpec = true;
1680 return TPResult::Ambiguous;
1681 } else {
1682
1683
1684
1686 if (((Tok.is(tok::amp) || Tok.is(tok::star)) &&
1687 (NextToken().is(tok::r_paren) ||
1688 NextToken().is(tok::greater))) ||
1689 (Tok.is(tok::ampamp) && NextToken().is(tok::greater)))
1690 return TPResult::True;
1691 }
1692 }
1693 } else {
1694
1695
1696 switch (TryAnnotateName(nullptr, AllowImplicitTypename)) {
1697 case ANK_Error:
1698 return TPResult::Error;
1699 case ANK_TentativeDecl:
1700 return TPResult::False;
1701 case ANK_TemplateName:
1702
1703
1706 return TPResult::Error;
1707
1708
1709
1710 if (Tok.isNot(tok::annot_cxxscope))
1711 break;
1712 }
1713
1714
1715
1716
1718 ? TPResult::True
1719 : TPResult::False;
1720 case ANK_Unresolved:
1721 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1722 case ANK_Success:
1723 break;
1724 }
1725
1726
1727 assert(Tok.isNot(tok::annot_cxxscope) ||
1728 NextToken().isNot(tok::identifier));
1729 return isCXXDeclarationSpecifier(AllowImplicitTypename,
1730 BracedCastResult, InvalidAsDeclSpec);
1731 }
1732 }
1733 return TPResult::False;
1734 }
1735
1736 [[fallthrough]];
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756 case tok::annot_typename:
1757 case_typename:
1758
1760
1761 RevertingTentativeParsingAction PA(*this);
1763
1764 TPResult TPR = TryParseProtocolQualifiers();
1765 bool isFollowedByParen = Tok.is(tok::l_paren);
1766 bool isFollowedByBrace = Tok.is(tok::l_brace);
1767
1768 if (TPR == TPResult::Error)
1769 return TPResult::Error;
1770
1771 if (isFollowedByParen)
1772 return TPResult::Ambiguous;
1773
1775 return BracedCastResult;
1776
1777 return TPResult::True;
1778 }
1779
1780 [[fallthrough]];
1781
1782 case tok::kw_char:
1783 case tok::kw_wchar_t:
1784 case tok::kw_char8_t:
1785 case tok::kw_char16_t:
1786 case tok::kw_char32_t:
1787 case tok::kw_bool:
1788 case tok::kw_short:
1789 case tok::kw_int:
1790 case tok::kw_long:
1791 case tok::kw___int64:
1792 case tok::kw___int128:
1793 case tok::kw_signed:
1794 case tok::kw_unsigned:
1795 case tok::kw_half:
1796 case tok::kw_float:
1797 case tok::kw_double:
1798 case tok::kw___bf16:
1799 case tok::kw__Float16:
1800 case tok::kw___float128:
1801 case tok::kw___ibm128:
1802 case tok::kw_void:
1803 case tok::annot_decltype:
1804 case tok::kw__Accum:
1805 case tok::kw__Fract:
1806 case tok::kw__Sat:
1807 case tok::annot_pack_indexing_type:
1808#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1809#include "clang/Basic/OpenCLImageTypes.def"
1810#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1811#include "clang/Basic/HLSLIntangibleTypes.def"
1812 if (NextToken().is(tok::l_paren))
1813 return TPResult::Ambiguous;
1814
1815
1816
1817
1818
1819
1820
1822 return BracedCastResult;
1823
1824 if (isStartOfObjCClassMessageMissingOpenBracket())
1825 return TPResult::False;
1826
1827 return TPResult::True;
1828
1829
1830 case tok::kw_typeof: {
1831 if (NextToken().isNot(tok::l_paren))
1832 return TPResult::True;
1833
1834 RevertingTentativeParsingAction PA(*this);
1835
1836 TPResult TPR = TryParseTypeofSpecifier();
1837 bool isFollowedByParen = Tok.is(tok::l_paren);
1838 bool isFollowedByBrace = Tok.is(tok::l_brace);
1839
1840 if (TPR == TPResult::Error)
1841 return TPResult::Error;
1842
1843 if (isFollowedByParen)
1844 return TPResult::Ambiguous;
1845
1847 return BracedCastResult;
1848
1849 return TPResult::True;
1850 }
1851
1852#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1853#include "clang/Basic/TransformTypeTraits.def"
1854 return TPResult::True;
1855
1856
1857 case tok::kw__Alignas:
1858 return TPResult::True;
1859
1860 case tok::kw__Atomic:
1861 return TPResult::True;
1862
1863 case tok::kw__BitInt:
1864 case tok::kw__ExtInt: {
1865 if (NextToken().isNot(tok::l_paren))
1866 return TPResult::Error;
1867 RevertingTentativeParsingAction PA(*this);
1869 ConsumeParen();
1870
1872 return TPResult::Error;
1873
1874 if (Tok.is(tok::l_paren))
1875 return TPResult::Ambiguous;
1876
1878 return BracedCastResult;
1879
1880 return TPResult::True;
1881 }
1882 default:
1883 return TPResult::False;
1884 }
1885}
1886
1887bool Parser::isCXXDeclarationSpecifierAType() {
1888 switch (Tok.getKind()) {
1889
1890 case tok::annot_decltype:
1891 case tok::annot_pack_indexing_type:
1892 case tok::annot_template_id:
1893 case tok::annot_typename:
1894 case tok::kw_typeof:
1895#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1896#include "clang/Basic/TransformTypeTraits.def"
1897 return true;
1898
1899
1900 case tok::kw_class:
1901 case tok::kw_struct:
1902 case tok::kw_union:
1903 case tok::kw___interface:
1904 case tok::kw_enum:
1905 return true;
1906
1907
1908 case tok::kw_char:
1909 case tok::kw_wchar_t:
1910 case tok::kw_char8_t:
1911 case tok::kw_char16_t:
1912 case tok::kw_char32_t:
1913 case tok::kw_bool:
1914 case tok::kw_short:
1915 case tok::kw_int:
1916 case tok::kw__ExtInt:
1917 case tok::kw__BitInt:
1918 case tok::kw_long:
1919 case tok::kw___int64:
1920 case tok::kw___int128:
1921 case tok::kw_signed:
1922 case tok::kw_unsigned:
1923 case tok::kw_half:
1924 case tok::kw_float:
1925 case tok::kw_double:
1926 case tok::kw___bf16:
1927 case tok::kw__Float16:
1928 case tok::kw___float128:
1929 case tok::kw___ibm128:
1930 case tok::kw_void:
1931 case tok::kw___unknown_anytype:
1932 case tok::kw___auto_type:
1933 case tok::kw__Accum:
1934 case tok::kw__Fract:
1935 case tok::kw__Sat:
1936#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1937#include "clang/Basic/OpenCLImageTypes.def"
1938#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1939#include "clang/Basic/HLSLIntangibleTypes.def"
1940 return true;
1941
1942 case tok::kw_auto:
1944
1945 case tok::kw__Atomic:
1946
1948
1949 default:
1950 return false;
1951 }
1952}
1953
1954
1955
1956
1957
1958Parser::TPResult Parser::TryParseTypeofSpecifier() {
1959 assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!");
1961
1962 assert(Tok.is(tok::l_paren) && "Expected '('");
1963
1964 ConsumeParen();
1966 return TPResult::Error;
1967
1968 return TPResult::Ambiguous;
1969}
1970
1971
1972
1973Parser::TPResult Parser::TryParseProtocolQualifiers() {
1974 assert(Tok.is(tok::less) && "Expected '<' for qualifier list");
1976 do {
1977 if (Tok.isNot(tok::identifier))
1978 return TPResult::Error;
1980
1981 if (Tok.is(tok::comma)) {
1983 continue;
1984 }
1985
1986 if (Tok.is(tok::greater)) {
1988 return TPResult::Ambiguous;
1989 }
1990 } while (false);
1991
1992 return TPResult::Error;
1993}
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005bool Parser::isCXXFunctionDeclarator(
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017 RevertingTentativeParsingAction PA(*this);
2018
2019 ConsumeParen();
2020 bool InvalidAsDeclaration = false;
2021 TPResult TPR = TryParseParameterDeclarationClause(
2022 &InvalidAsDeclaration, false,
2023 AllowImplicitTypename);
2024 if (TPR == TPResult::Ambiguous) {
2025 if (Tok.isNot(tok::r_paren))
2026 TPR = TPResult::False;
2027 else {
2029 if (Next.isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
2030 tok::kw_throw, tok::kw_noexcept, tok::l_square,
2031 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
2032 isCXX11VirtSpecifier(Next))
2033
2034
2035
2036 TPR = TPResult::True;
2037 else if (InvalidAsDeclaration)
2038
2039 TPR = TPResult::False;
2040 }
2041 }
2042
2043 if (IsAmbiguous && TPR == TPResult::Ambiguous)
2044 *IsAmbiguous = true;
2045
2046
2047 return TPR != TPResult::False;
2048}
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067Parser::TPResult Parser::TryParseParameterDeclarationClause(
2068 bool *InvalidAsDeclaration, bool VersusTemplateArgument,
2070
2071 if (Tok.is(tok::r_paren))
2072 return TPResult::Ambiguous;
2073
2074
2075
2076
2077
2078
2079
2080
2081 while (true) {
2082
2083 if (Tok.is(tok::ellipsis)) {
2085 if (Tok.is(tok::r_paren))
2086 return TPResult::True;
2087 else
2088 return TPResult::False;
2089 }
2090
2091
2092 if (isCXX11AttributeSpecifier(false,
2093 true))
2094 return TPResult::True;
2095
2097 MaybeParseMicrosoftAttributes(attrs);
2098
2099
2100
2101
2102 TPResult TPR = isCXXDeclarationSpecifier(
2103 AllowImplicitTypename, TPResult::False, InvalidAsDeclaration);
2104
2105
2106 if (TPR != TPResult::Ambiguous &&
2107 !(VersusTemplateArgument && TPR == TPResult::True))
2108 return TPR;
2109
2110 bool SeenType = false;
2111 bool DeclarationSpecifierIsAuto = Tok.is(tok::kw_auto);
2112 do {
2113 SeenType |= isCXXDeclarationSpecifierAType();
2114 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
2115 return TPResult::Error;
2116
2117
2118 if (SeenType && Tok.is(tok::identifier))
2119 return TPResult::True;
2120
2121 TPR = isCXXDeclarationSpecifier(AllowImplicitTypename, TPResult::False,
2122 InvalidAsDeclaration);
2123 if (TPR == TPResult::Error)
2124 return TPR;
2125
2126
2127 if (TPR == TPResult::True && !VersusTemplateArgument)
2128 return TPR;
2129 } while (TPR != TPResult::False);
2130
2131
2132
2133 TPR = TryParseDeclarator(
2134 true,
2135 true,
2136 false,
2137 DeclarationSpecifierIsAuto);
2138 if (TPR != TPResult::Ambiguous)
2139 return TPR;
2140
2141
2142 if (Tok.is(tok::kw___attribute))
2143 return TPResult::True;
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154 if (VersusTemplateArgument)
2155 return Tok.is(tok::equal) ? TPResult::True : TPResult::False;
2156
2157 if (Tok.is(tok::equal)) {
2158
2159
2161 return TPResult::Error;
2162 }
2163
2164 if (Tok.is(tok::ellipsis)) {
2166 if (Tok.is(tok::r_paren))
2167 return TPResult::True;
2168 else
2169 return TPResult::False;
2170 }
2171
2173 break;
2174 }
2175
2176 return TPResult::Ambiguous;
2177}
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191Parser::TPResult
2192Parser::TryParseFunctionDeclarator(bool MayHaveTrailingReturnType) {
2193
2194
2195 TPResult TPR = TryParseParameterDeclarationClause();
2196 if (TPR == TPResult::Ambiguous && Tok.isNot(tok::r_paren))
2197 TPR = TPResult::False;
2198
2199 if (TPR == TPResult::False || TPR == TPResult::Error)
2200 return TPR;
2201
2202
2204 return TPResult::Error;
2205
2206
2207 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,
2208 tok::kw_restrict))
2210
2211
2212 if (Tok.isOneOf(tok::amp, tok::ampamp))
2214
2215
2216 if (Tok.is(tok::kw_throw)) {
2218 if (Tok.isNot(tok::l_paren))
2219 return TPResult::Error;
2220
2221
2222 ConsumeParen();
2224 return TPResult::Error;
2225 }
2226 if (Tok.is(tok::kw_noexcept)) {
2228
2229 if (Tok.is(tok::l_paren)) {
2230
2231 ConsumeParen();
2233 return TPResult::Error;
2234 }
2235 }
2236
2237
2238 if (!TrySkipAttributes())
2239 return TPResult::Ambiguous;
2240
2241
2242 if (Tok.is(tok::arrow) && MayHaveTrailingReturnType) {
2243 if (TPR == TPResult::True)
2244 return TPR;
2246 if (Tok.is(tok::identifier) && NameAfterArrowIsNonType()) {
2247 return TPResult::False;
2248 }
2249 if (isCXXTypeId(TentativeCXXTypeIdContext::TypeIdInTrailingReturnType))
2250 return TPResult::True;
2251 }
2252
2253 return TPResult::Ambiguous;
2254}
2255
2256
2257
2258
2259
2260bool Parser::NameAfterArrowIsNonType() {
2261 assert(Tok.is(tok::identifier));
2263 if (Next.is(tok::coloncolon))
2264 return false;
2268 TentativeParseCCC CCC(Next);
2271 switch (Classification.getKind()) {
2276 return true;
2277 default:
2278 break;
2279 }
2280 return false;
2281}
2282
2283
2284
2285Parser::TPResult Parser::TryParseBracketDeclarator() {
2286 ConsumeBracket();
2287
2288
2289
2290 if (Tok.is(tok::l_brace))
2291 return TPResult::False;
2292
2294 return TPResult::Error;
2295
2296
2297
2298 if (Tok.isNot(tok::r_square))
2299 return TPResult::False;
2300
2301 ConsumeBracket();
2302 return TPResult::Ambiguous;
2303}
2304
2305
2306
2307
2308
2309Parser::TPResult Parser::isTemplateArgumentList(unsigned TokensToSkip) {
2310 if (!TokensToSkip) {
2311 if (Tok.isNot(tok::less))
2312 return TPResult::False;
2313 if (NextToken().is(tok::greater))
2314 return TPResult::True;
2315 }
2316
2317 RevertingTentativeParsingAction PA(*this);
2318
2319 while (TokensToSkip) {
2321 --TokensToSkip;
2322 }
2323
2325 return TPResult::False;
2326
2327
2328
2329
2330 bool InvalidAsTemplateArgumentList = false;
2332 &InvalidAsTemplateArgumentList) ==
2333 TPResult::True)
2334 return TPResult::True;
2335 if (InvalidAsTemplateArgumentList)
2336 return TPResult::False;
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350 if (SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater},
2352 return TPResult::Ambiguous;
2353 return TPResult::False;
2354}
2355
2356
2357
2358Parser::TPResult Parser::isExplicitBool() {
2359 assert(Tok.is(tok::l_paren) && "expected to be looking at a '(' token");
2360
2361 RevertingTentativeParsingAction PA(*this);
2362 ConsumeParen();
2363
2364
2365
2366
2367
2368
2369 while (Tok.is(tok::l_paren))
2370 ConsumeParen();
2371
2373 return TPResult::Error;
2374
2375
2376
2378 if (Tok.is(tok::annot_cxxscope)) {
2381 SS);
2382 ConsumeAnnotationToken();
2383 }
2384
2385
2386
2387 if (Tok.is(tok::kw_operator))
2388 return TPResult::Ambiguous;
2389
2390
2391 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
2392 return TPResult::True;
2395 : *takeTemplateIdAnnotation(Tok)->Name,
2397 return TPResult::True;
2398
2399
2400
2401
2402 if (().is(tok::r_paren) &&
2403 !isConstructorDeclarator(SS.isEmpty(),
2404 false))
2405 return TPResult::True;
2406
2407
2408 return TPResult::Ambiguous;
2409}
static constexpr bool isOneOf()
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.
NestedNameSpecifier * getScopeRep() const
Retrieve the representation of the nested-name-specifier.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
bool isEmpty() const
No scope specifier.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
virtual bool ValidateCandidate(const TypoCorrection &candidate)
Simple predicate used by the default RankCandidate to determine whether to return an edit distance of...
One of these records is kept for each identifier that is lexed.
bool hasRevertedTokenIDToIdentifier() const
True if revertTokenIDToIdentifier() was called.
This represents a decl that may have a name.
bool isDependent() const
Whether this nested name specifier refers to a dependent type or not.
ParsedAttributes - A collection of parsed attributes.
Parser - This implements a parser for the C family of languages.
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext=false)
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
bool TryConsumeToken(tok::TokenKind Expected)
Scope * getCurScope() const
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 ...
const LangOptions & getLangOpts() const
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtSemi
Stop skipping at semicolon.
bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
NameClassificationKind getKind() 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...
@ NC_VarTemplate
The name was classified as a variable template name.
@ NC_NonType
The name was classified as a specific non-type, non-template declaration.
@ NC_FunctionTemplate
The name was classified as a function template name.
@ NC_OverloadSet
The name was classified as an overload set, and an expression representing that overload set has been...
NameClassification ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name, SourceLocation NameLoc, const Token &NextToken, CorrectionCandidateCallback *CCC=nullptr)
Perform name lookup on the given name, classifying it based on the results of name lookup and the fol...
void RestoreNestedNameSpecifierAnnotation(void *Annotation, SourceRange AnnotationRange, CXXScopeSpec &SS)
Given an annotation pointer for a nested-name-specifier, restore the nested-name-specifier structure.
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.
Encodes a location in the source.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
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,...
SourceRange getAnnotationRange() const
SourceRange of the group of tokens that this annotation token represents.
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
bool isNot(tok::TokenKind K) const
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix.
Simple class containing the result of Sema::CorrectTypo.
The JSON file list parser is used to communicate input to InstallAPI.
bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
@ TNK_Concept_template
The name refers to a concept.
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
bool markNotForRangeDecl()
ConditionDeclarationOrInitStatementState(Parser &P, bool CanBeInitStatement, bool CanBeForRangeDecl)
bool update(TPResult IsDecl)
ConditionOrInitStatement result() const
Represents a complete lambda introducer.
Information about a template-id annotation token.
bool hasInvalidName() const
TemplateNameKind Kind
The kind of template that Template refers to.
unsigned NumArgs
NumArgs - The number of template arguments.