clang: lib/Parse/ParseExpr.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
42#include "llvm/ADT/SmallVector.h"
43#include
44using namespace clang;
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
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
136 return ParseRHSOfBinaryExpression(LHS, prec::Comma);
137}
138
139
140
141
142
143
145Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) {
146 ExprResult LHS(ParseObjCAtExpression(AtLoc));
147 return ParseRHSOfBinaryExpression(LHS, prec::Comma);
148}
149
150
151
152
154Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) {
156 {
157
159
160 LHS = ParseCastExpression(AnyCastExpr);
161 }
162
163 if (!LHS.isInvalid())
165 LHS.get());
166
167 return ParseRHSOfBinaryExpression(LHS, prec::Comma);
168}
169
170
172 if (Tok.is(tok::code_completion)) {
173 cutOffParsing();
177 }
178
179 if (Tok.is(tok::kw_throw))
180 return ParseThrowExpression();
181 if (Tok.is(tok::kw_co_yield))
182 return ParseCoyieldExpression();
183
184 ExprResult LHS = ParseCastExpression(AnyCastExpr,
185 false,
186 isTypeCast);
188}
189
191 if (Tok.is(tok::code_completion)) {
192 cutOffParsing();
196 }
197
198 ExprResult LHS = ParseCastExpression(
199 AnyCastExpr, false, NotTypeCast);
201}
202
203
204
205
206
207
208
209
210
211
213Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc,
216 Expr *ReceiverExpr) {
218 = ParseObjCMessageExpressionBody(LBracLoc, SuperLoc,
219 ReceiverType, ReceiverExpr);
220 R = ParsePostfixExpressionSuffix(R);
222}
223
228 "Call this function only if your ExpressionEvaluationContext is "
229 "already ConstantEvaluated");
230 ExprResult LHS(ParseCastExpression(AnyCastExpr, false, isTypeCast));
233}
234
236
237
238
239
243}
244
248
249
250 Actions.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
251
252
253
254
255
256
257
258
259
260
261
262
263
266 if (->isUnevaluated())
267 break;
268 Iter->InConditionallyConstantEvaluateContext = true;
269 }
271}
272
279}
280
281
282
283
284
285
286
290 ExprResult LHS(ParseCastExpression(AnyCastExpr));
295 }
296 return Res;
297}
298
299
300
301
302
303
304
305
306
307
312 bool NotPrimaryExpression = false;
313 auto ParsePrimary = [&] () {
314 ExprResult E = ParseCastExpression(PrimaryExprOnly,
315 false,
317 false,
318 &NotPrimaryExpression);
319 if (E.isInvalid())
321 auto RecoverFromNonPrimary = [&] (ExprResult E, bool Note) {
322 E = ParsePostfixExpressionSuffix(E);
323
324
326 if (.isInvalid())
329 ? diag::note_unparenthesized_non_primary_expr_in_requires_clause
330 : diag::err_unparenthesized_non_primary_expr_in_requires_clause)
335 return E;
336 };
337
338 if (NotPrimaryExpression ||
339
340
343
344
345 Tok.isOneOf(tok::period, tok::plusplus, tok::minusminus) ||
346 (Tok.is(tok::l_square) && ().is(tok::l_square))) {
347 E = RecoverFromNonPrimary(E, false);
348 if (E.isInvalid())
350 NotPrimaryExpression = false;
351 }
352 bool PossibleNonPrimary;
353 bool IsConstraintExpr =
355 IsTrailingRequiresClause);
356 if (!IsConstraintExpr || PossibleNonPrimary) {
357
358
359
360
361 if (PossibleNonPrimary)
362 E = RecoverFromNonPrimary(E, !IsConstraintExpr);
365 }
366 return E;
367 };
371 while (Tok.is(tok::ampamp)) {
377 }
379 tok::ampamp, LHS.get(), RHS.get());
384 }
385 LHS = Op;
386 }
387 return LHS;
388}
389
390
391
392
393
394
395
396
397
398
399
405 while (Tok.is(tok::pipepipe)) {
412 }
414 tok::pipepipe, LHS.get(), RHS.get());
419 }
420 LHS = Op;
421 }
422 return LHS;
423}
424
425bool Parser::isNotExpressionStart() {
427 if (K == tok::l_brace || K == tok::r_brace ||
428 K == tok::kw_for || K == tok::kw_while ||
429 K == tok::kw_if || K == tok::kw_else ||
430 K == tok::kw_goto || K == tok::kw_try)
431 return true;
432
433 return isKnownToBeDeclarationSpecifier();
434}
435
436bool Parser::isFoldOperator(prec::Level Level) const {
439}
440
441bool Parser::isFoldOperator(tok::TokenKind Kind) const {
442 return isFoldOperator(getBinOpPrecedence(Kind, GreaterThanIsOperator, true));
443}
444
445
446
450 GreaterThanIsOperator,
453
454 auto SavedType = PreferredType;
455 while (true) {
456
457 PreferredType = SavedType;
458
459
460
461 if (NextTokPrec < MinPrec)
462 return LHS;
463
464
465 Token OpToken = Tok;
467
468
469
470 if (OpToken.isOneOf(tok::comma, tok::greater, tok::greatergreater,
471 tok::greatergreatergreater) &&
472 checkPotentialAngleBracketDelimiter(OpToken))
474
475
476
477
478
479
480 if (OpToken.is(tok::comma) && isNotExpressionStart()) {
481 PP.EnterToken(Tok, true);
482 Tok = OpToken;
483 return LHS;
484 }
485
486
487
488 if (isFoldOperator(NextTokPrec) && Tok.is(tok::ellipsis)) {
489
490
491 PP.EnterToken(Tok, true);
492 Tok = OpToken;
493 return LHS;
494 }
495
496
497
498
499
500
502 Tok.isOneOf(tok::colon, tok::r_square) &&
504 PP.EnterToken(Tok, true);
505 Tok = OpToken;
506 return LHS;
507 }
508
509
513
515 TernaryMiddle = ParseBraceInitializer();
516 if (!TernaryMiddle.isInvalid()) {
517 Diag(BraceLoc, diag::err_init_list_bin_op)
519 << Actions.getExprRange(TernaryMiddle.get());
521 }
522 } else if (Tok.isNot(tok::colon)) {
523
525
526
527
528
529
531 } else {
532
533
534 TernaryMiddle = nullptr;
535 Diag(Tok, diag::ext_gnu_conditional_expr);
536 }
537
538 if (TernaryMiddle.isInvalid()) {
541 TernaryMiddle = nullptr;
542 }
543
545
546
547
548
550 const char *FIText = ": ";
554 bool IsInvalid = false;
555 const char *SourcePtr =
557 if (!IsInvalid && *SourcePtr == ' ') {
558 SourcePtr =
560 if (!IsInvalid && *SourcePtr == ' ') {
562 FIText = ":";
563 }
564 }
565 }
566
567 Diag(Tok, diag::err_expected)
569 Diag(OpToken, diag::note_matching) << tok::question;
571 }
572 }
573
576
577
578
579
580
581
582
583
584
585
587 bool RHSIsInitList = false;
589 RHS = ParseBraceInitializer();
590 RHSIsInitList = true;
593 else
594 RHS = ParseCastExpression(AnyCastExpr);
595
597
598
600 if (TernaryMiddle.isUsable())
603 }
604
605
606
610
611
614
615
616
617 if (ThisPrec < NextTokPrec ||
618 (ThisPrec == NextTokPrec && isRightAssoc)) {
619 if (!RHS.isInvalid() && RHSIsInitList) {
620 Diag(Tok, diag::err_init_list_bin_op)
623 }
624
625
626
627
628
629 RHS = ParseRHSOfBinaryExpression(RHS,
630 static_cast<prec::Level>(ThisPrec + !isRightAssoc));
631 RHSIsInitList = false;
632
634
635
637 if (TernaryMiddle.isUsable())
640 }
641
644 }
645
646 if (!RHS.isInvalid() && RHSIsInitList) {
648 Diag(OpToken, diag::warn_cxx98_compat_generalized_initializer_lists)
650 } else if (ColonLoc.isValid()) {
651 Diag(ColonLoc, diag::err_init_list_bin_op)
652 << 1 << ":"
655 } else {
656 Diag(OpToken, diag::err_init_list_bin_op)
660 }
661 }
662
665
666 if (TernaryMiddle.isInvalid()) {
667
668
669
670 if (!GreaterThanIsOperator && OpToken.is(tok::greatergreater))
671 SuggestParentheses(OpToken.getLocation(),
672 diag::warn_cxx11_right_shift_in_template_arg,
675
682 {LHS.get(), RHS.get()});
683
684 LHS = BinOp;
685 } else {
687 OpToken.getLocation(), ColonLoc, LHS.get(), TernaryMiddle.get(),
688 RHS.get());
690 std::vector<clang::Expr *> Args;
691
692 if (TernaryMiddle.get())
693 Args = {LHS.get(), TernaryMiddle.get(), RHS.get()};
694 else
695 Args = {LHS.get(), RHS.get()};
698 }
699
700 LHS = CondOp;
701 }
702
703
705 continue;
706 }
707
708
713 }
714 }
715}
716
717
718
719
720
721
722
723ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
724 bool isAddressOfOperand,
725 TypeCastState isTypeCast,
726 bool isVectorLiteral,
727 bool *NotPrimaryExpression) {
728 bool NotCastExpr;
729 ExprResult Res = ParseCastExpression(ParseKind,
730 isAddressOfOperand,
731 NotCastExpr,
732 isTypeCast,
733 isVectorLiteral,
734 NotPrimaryExpression);
735 if (NotCastExpr)
736 Diag(Tok, diag::err_expected_expression);
737 return Res;
738}
739
740namespace {
742 public:
743 CastExpressionIdValidator(Token Next, bool AllowTypes, bool AllowNonTypes)
744 : NextToken(Next), AllowNonTypes(AllowNonTypes) {
745 WantTypeSpecifiers = WantFunctionLikeCasts = AllowTypes;
746 }
747
748 bool ValidateCandidate(const TypoCorrection &candidate) override {
750 if (!ND)
752
753 if (isa(ND))
754 return WantTypeSpecifiers;
755
757 return false;
758
759 if (!NextToken.isOneOf(tok::equal, tok::arrow, tok::period))
760 return true;
761
762 for (auto *C : candidate) {
763 NamedDecl *ND = C->getUnderlyingDecl();
764 if (isa(ND) && !isa(ND))
765 return true;
766 }
767 return false;
768 }
769
770 std::unique_ptr clone() override {
771 return std::make_unique(*this);
772 }
773
774 private:
776 bool AllowNonTypes;
777};
778}
779
780bool Parser::isRevertibleTypeTrait(const IdentifierInfo *II,
782 if (RevertibleTypeTraits.empty()) {
783
784
785
786#define RTT_JOIN(X, Y) X##Y
787#define REVERTIBLE_TYPE_TRAIT(Name) \
788 RevertibleTypeTraits[PP.getIdentifierInfo(#Name)] = RTT_JOIN(tok::kw_, Name)
789
846#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \
847 REVERTIBLE_TYPE_TRAIT(RTT_JOIN(__, Trait));
848#include "clang/Basic/TransformTypeTraits.def"
849#undef REVERTIBLE_TYPE_TRAIT
850#undef RTT_JOIN
851 }
852 llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind>::iterator Known =
853 RevertibleTypeTraits.find(II);
854 if (Known != RevertibleTypeTraits.end()) {
855 if (Kind)
856 *Kind = Known->second;
857 return true;
858 }
859 return false;
860}
861
862ExprResult Parser::ParseBuiltinPtrauthTypeDiscriminator() {
864
866 if (T.expectAndConsume())
868
873 }
874
876 T.consumeClose();
878 Loc, UETT_PtrAuthTypeDiscriminator,
879 true, Ty.get().getAsOpaquePtr(), SourceRange(Loc, EndLoc));
880}
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
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
1065ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
1066 bool isAddressOfOperand,
1067 bool &NotCastExpr,
1068 TypeCastState isTypeCast,
1069 bool isVectorLiteral,
1070 bool *NotPrimaryExpression) {
1073 auto SavedType = PreferredType;
1074 NotCastExpr = false;
1075
1076
1077
1078
1079 bool AllowSuffix = true;
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091 switch (SavedKind) {
1092 case tok::l_paren: {
1093
1094
1095 ParenParseOption ParenExprType;
1096 switch (ParseKind) {
1097 case CastParseKind::UnaryExprOnly:
1099 [[fallthrough]];
1100 case CastParseKind::AnyCastExpr:
1101 ParenExprType = ParenParseOption::CastExpr;
1102 break;
1103 case CastParseKind::PrimaryExprOnly:
1104 ParenExprType = FoldExpr;
1105 break;
1106 }
1109 Res = ParseParenExpression(ParenExprType, false,
1110 isTypeCast == IsTypeCast, CastTy, RParenLoc);
1111
1112
1113
1114
1115 if (isVectorLiteral)
1116 return Res;
1117
1118 switch (ParenExprType) {
1119 case SimpleExpr: break;
1120 case CompoundStmt: break;
1121 case CompoundLiteral:
1122
1123
1124 break;
1126
1127
1128 return Res;
1129 case FoldExpr:
1130
1131
1132 break;
1133 }
1134
1135 break;
1136 }
1137
1138
1139 case tok::numeric_constant:
1140 case tok::binary_data:
1141
1142
1143
1146 break;
1147
1148 case tok::kw_true:
1149 case tok::kw_false:
1150 Res = ParseCXXBoolLiteral();
1151 break;
1152
1153 case tok::kw___objc_yes:
1154 case tok::kw___objc_no:
1155 Res = ParseObjCBoolLiteral();
1156 break;
1157
1158 case tok::kw_nullptr:
1160 Diag(Tok, diag::warn_cxx98_compat_nullptr);
1161 else
1163 : diag::ext_c_nullptr) << Tok.getName();
1164
1166 break;
1167
1168 case tok::annot_primary_expr:
1169 case tok::annot_overload_set:
1170 Res = getExprAnnotation(Tok);
1171 if (!Res.isInvalid() && Tok.getKind() == tok::annot_overload_set)
1173 ConsumeAnnotationToken();
1174 if (!Res.isInvalid() && Tok.is(tok::less))
1175 checkPotentialAngleBracket(Res);
1176 break;
1177
1178 case tok::annot_non_type:
1179 case tok::annot_non_type_dependent:
1180 case tok::annot_non_type_undeclared: {
1182 Token Replacement;
1183 Res = tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement);
1184 assert(!Res.isUnset() &&
1185 "should not perform typo correction on annotation token");
1186 break;
1187 }
1188
1189 case tok::annot_embed: {
1190 injectEmbedTokens();
1191 return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast,
1192 isVectorLiteral, NotPrimaryExpression);
1193 }
1194
1195 case tok::kw___super:
1196 case tok::kw_decltype:
1197
1200 assert(Tok.isNot(tok::kw_decltype) && Tok.isNot(tok::kw___super));
1201 return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast,
1202 isVectorLiteral, NotPrimaryExpression);
1203
1204 case tok::identifier:
1205 ParseIdentifier: {
1206
1207
1208
1209
1211
1212
1214
1215 if (Next.is(tok::ellipsis) && Tok.is(tok::identifier) &&
1216 GetLookAheadToken(2).is(tok::l_square)) {
1217
1218
1219
1221 Tok.isOneOf(tok::annot_pack_indexing_type, tok::annot_cxxscope))
1222 return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast,
1223 isVectorLiteral, NotPrimaryExpression);
1224 }
1225
1226
1227
1228
1229 else if (Next.is(tok::l_paren) && Tok.is(tok::identifier) &&
1233 if (isRevertibleTypeTrait(II, &Kind)) {
1235 return ParseCastExpression(ParseKind, isAddressOfOperand,
1236 NotCastExpr, isTypeCast,
1237 isVectorLiteral, NotPrimaryExpression);
1238 }
1239 }
1240
1241 else if ((!ColonIsSacred && Next.is(tok::colon)) ||
1242 Next.isOneOf(tok::coloncolon, tok::less, tok::l_paren,
1243 tok::l_brace)) {
1244
1247 if (!Tok.is(tok::identifier))
1248 return ParseCastExpression(ParseKind, isAddressOfOperand,
1249 NotCastExpr, isTypeCast,
1250 isVectorLiteral,
1251 NotPrimaryExpression);
1252 }
1253 }
1254
1255
1256
1259
1260
1263
1264 (&II == Ident_super && getCurScope()->isInObjcMethodScope()))) {
1266
1267 if (Tok.is(tok::code_completion) && &II != Ident_super) {
1268 cutOffParsing();
1270 getCurScope(), II, ILoc, ExprStatementTokLoc == ILoc);
1272 }
1273
1274 if (Tok.isNot(tok::identifier) &&
1276 Diag(Tok, diag::err_expected_property_name);
1278 }
1281
1283 PropertyLoc);
1284 break;
1285 }
1286
1287
1288
1289
1290
1291 if (getLangOpts().ObjC && &II == Ident_super && !InMessageExpression &&
1293 ((Tok.is(tok::identifier) &&
1295 Tok.is(tok::code_completion))) {
1296 Res = ParseObjCMessageExpressionBody(SourceLocation(), ILoc, nullptr,
1297 nullptr);
1298 break;
1299 }
1300
1301
1302
1303
1304
1305
1307 ((Tok.is(tok::identifier) && !InMessageExpression) ||
1308 Tok.is(tok::code_completion))) {
1310 if (Tok.is(tok::code_completion) ||
1311 Next.is(tok::colon) || Next.is(tok::r_square))
1313 if (Typ.get()->isObjCObjectOrInterfaceType()) {
1314
1316 DS.SetRangeStart(ILoc);
1317 DS.SetRangeEnd(ILoc);
1318 const char *PrevSpec = nullptr;
1319 unsigned DiagID;
1320 DS.SetTypeSpecType(TST_typename, ILoc, PrevSpec, DiagID, Typ,
1322
1327 break;
1328
1329 Res = ParseObjCMessageExpressionBody(SourceLocation(),
1331 Ty.get(), nullptr);
1332 break;
1333 }
1334 }
1335
1336
1337 if (isAddressOfOperand && isPostfixExpressionSuffixStart())
1338 isAddressOfOperand = false;
1339
1340
1341
1342
1346 Token Replacement;
1347 CastExpressionIdValidator Validator(
1348 Tok,
1349 isTypeCast != NotTypeCast,
1350 isTypeCast != IsTypeCast);
1351 Validator.IsAddressOfOperand = isAddressOfOperand;
1352 if (Tok.isOneOf(tok::periodstar, tok::arrowstar)) {
1353 Validator.WantExpressionKeywords = false;
1354 Validator.WantRemainingKeywords = false;
1355 } else {
1356 Validator.WantRemainingKeywords = Tok.isNot(tok::r_paren);
1357 }
1358 Name.setIdentifier(&II, ILoc);
1360 getCurScope(), ScopeSpec, TemplateKWLoc, Name, Tok.is(tok::l_paren),
1361 isAddressOfOperand, &Validator,
1362 false,
1363 Tok.is(tok::r_paren) ? nullptr : &Replacement);
1365 UnconsumeToken(Replacement);
1366 return ParseCastExpression(ParseKind, isAddressOfOperand,
1367 NotCastExpr, isTypeCast,
1368 false,
1369 NotPrimaryExpression);
1370 }
1371 Res = tryParseCXXPackIndexingExpression(Res);
1372 if (!Res.isInvalid() && Tok.is(tok::less))
1373 checkPotentialAngleBracket(Res);
1374 break;
1375 }
1376 case tok::char_constant:
1377 case tok::wide_char_constant:
1378 case tok::utf8_char_constant:
1379 case tok::utf16_char_constant:
1380 case tok::utf32_char_constant:
1383 break;
1384 case tok::kw___func__:
1385 case tok::kw___FUNCTION__:
1386 case tok::kw___FUNCDNAME__:
1387 case tok::kw___FUNCSIG__:
1388 case tok::kw_L__FUNCTION__:
1389 case tok::kw_L__FUNCSIG__:
1390 case tok::kw___PRETTY_FUNCTION__:
1391
1392
1393
1399 break;
1400 }
1401 [[fallthrough]];
1402 case tok::string_literal:
1403 case tok::wide_string_literal:
1404 case tok::utf8_string_literal:
1405 case tok::utf16_string_literal:
1406 case tok::utf32_string_literal:
1408 break;
1409 case tok::kw__Generic:
1410 Res = ParseGenericSelectionExpression();
1411 break;
1412 case tok::kw___builtin_available:
1413 Res = ParseAvailabilityCheckExpr(Tok.getLocation());
1414 break;
1415 case tok::kw___builtin_va_arg:
1416 case tok::kw___builtin_offsetof:
1417 case tok::kw___builtin_choose_expr:
1418 case tok::kw___builtin_astype:
1419 case tok::kw___builtin_convertvector:
1420 case tok::kw___builtin_COLUMN:
1421 case tok::kw___builtin_FILE:
1422 case tok::kw___builtin_FILE_NAME:
1423 case tok::kw___builtin_FUNCTION:
1424 case tok::kw___builtin_FUNCSIG:
1425 case tok::kw___builtin_LINE:
1426 case tok::kw___builtin_source_location:
1427 if (NotPrimaryExpression)
1428 *NotPrimaryExpression = true;
1429
1430 return ParseBuiltinPrimaryExpression();
1431 case tok::kw___null:
1433 break;
1434
1435 case tok::plusplus:
1436 case tok::minusminus: {
1437 if (NotPrimaryExpression)
1438 *NotPrimaryExpression = true;
1439
1440
1441
1442
1443 Token SavedTok = Tok;
1445
1448
1449
1450
1452 UnaryExprOnly : AnyCastExpr,
1453 false, NotCastExpr,
1455 if (NotCastExpr) {
1456
1457
1459 UnconsumeToken(SavedTok);
1461 }
1465 SavedKind, Arg);
1469 }
1470 return Res;
1471 }
1472 case tok::amp: {
1473 if (NotPrimaryExpression)
1474 *NotPrimaryExpression = true;
1475
1478
1479 Res = ParseCastExpression(AnyCastExpr, true);
1485 Arg);
1486 }
1487 return Res;
1488 }
1489
1490 case tok:⭐
1491 case tok:➕
1492 case tok:➖
1493 case tok::tilde:
1494 case tok::exclaim:
1495 case tok::kw___real:
1496 case tok::kw___imag: {
1497 if (NotPrimaryExpression)
1498 *NotPrimaryExpression = true;
1501 Res = ParseCastExpression(AnyCastExpr);
1505 isAddressOfOperand);
1508 }
1509 return Res;
1510 }
1511
1512 case tok::kw_co_await: {
1513 if (NotPrimaryExpression)
1514 *NotPrimaryExpression = true;
1516 Res = ParseCastExpression(AnyCastExpr);
1519 return Res;
1520 }
1521
1522 case tok::kw___extension__:{
1523
1524 if (NotPrimaryExpression)
1525 *NotPrimaryExpression = true;
1528 Res = ParseCastExpression(AnyCastExpr);
1531 return Res;
1532 }
1533 case tok::kw__Alignof:
1534 diagnoseUseOfC11Keyword(Tok);
1535 [[fallthrough]];
1536 case tok::kw_alignof:
1537 case tok::kw___alignof:
1538
1539 case tok::kw_sizeof:
1540
1541
1542
1543 case tok::kw___datasizeof:
1544 case tok::kw_vec_step:
1545
1546 case tok::kw___builtin_omp_required_simd_align:
1547 case tok::kw___builtin_vectorelements:
1548 if (NotPrimaryExpression)
1549 *NotPrimaryExpression = true;
1550 AllowSuffix = false;
1551 Res = ParseUnaryExprOrTypeTraitExpression();
1552 break;
1553 case tok::ampamp: {
1554 if (NotPrimaryExpression)
1555 *NotPrimaryExpression = true;
1557 if (Tok.isNot(tok::identifier))
1558 return ExprError(Diag(Tok, diag::err_expected) << tok::identifier);
1559
1560 if (getCurScope()->getFnParent() == nullptr)
1561 return ExprError(Diag(Tok, diag::err_address_of_label_outside_fn));
1562
1563 Diag(AmpAmpLoc, diag::ext_gnu_address_of_label);
1568 AllowSuffix = false;
1569 break;
1570 }
1571 case tok::kw_const_cast:
1572 case tok::kw_dynamic_cast:
1573 case tok::kw_reinterpret_cast:
1574 case tok::kw_static_cast:
1575 case tok::kw_addrspace_cast:
1576 if (NotPrimaryExpression)
1577 *NotPrimaryExpression = true;
1578 Res = ParseCXXCasts();
1579 break;
1580 case tok::kw___builtin_bit_cast:
1581 if (NotPrimaryExpression)
1582 *NotPrimaryExpression = true;
1583 Res = ParseBuiltinBitCast();
1584 break;
1585 case tok::kw_typeid:
1586 if (NotPrimaryExpression)
1587 *NotPrimaryExpression = true;
1588 Res = ParseCXXTypeid();
1589 break;
1590 case tok::kw___uuidof:
1591 if (NotPrimaryExpression)
1592 *NotPrimaryExpression = true;
1593 Res = ParseCXXUuidof();
1594 break;
1595 case tok::kw_this:
1596 Res = ParseCXXThis();
1597 break;
1598 case tok::kw___builtin_sycl_unique_stable_name:
1599 Res = ParseSYCLUniqueStableNameExpression();
1600 break;
1601
1602 case tok::annot_typename:
1603 if (isStartOfObjCClassMessageMissingOpenBracket()) {
1605
1606
1610
1611 const char *PrevSpec = nullptr;
1612 unsigned DiagID;
1614 PrevSpec, DiagID, Type,
1616
1621 break;
1622
1623 ConsumeAnnotationToken();
1625 Ty.get(), nullptr);
1626 break;
1627 }
1628 [[fallthrough]];
1629
1630 case tok::annot_decltype:
1631 case tok::annot_pack_indexing_type:
1632 case tok::kw_char:
1633 case tok::kw_wchar_t:
1634 case tok::kw_char8_t:
1635 case tok::kw_char16_t:
1636 case tok::kw_char32_t:
1637 case tok::kw_bool:
1638 case tok::kw_short:
1639 case tok::kw_int:
1640 case tok::kw_long:
1641 case tok::kw___int64:
1642 case tok::kw___int128:
1643 case tok::kw__ExtInt:
1644 case tok::kw__BitInt:
1645 case tok::kw_signed:
1646 case tok::kw_unsigned:
1647 case tok::kw_half:
1648 case tok::kw_float:
1649 case tok::kw_double:
1650 case tok::kw___bf16:
1651 case tok::kw__Float16:
1652 case tok::kw___float128:
1653 case tok::kw___ibm128:
1654 case tok::kw_void:
1655 case tok::kw_auto:
1656 case tok::kw_typename:
1657 case tok::kw_typeof:
1658 case tok::kw___vector:
1659 case tok::kw__Accum:
1660 case tok::kw__Fract:
1661 case tok::kw__Sat:
1662#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1663#include "clang/Basic/OpenCLImageTypes.def"
1664#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1665#include "clang/Basic/HLSLIntangibleTypes.def"
1666 {
1668 Diag(Tok, diag::err_expected_expression);
1670 }
1671
1672
1673 if (NotPrimaryExpression)
1674 *NotPrimaryExpression = true;
1675
1676 if (SavedKind == tok::kw_typename) {
1677
1678
1681
1683
1684
1686 }
1687
1688
1689
1690
1692
1693 ParseCXXSimpleTypeSpecifier(DS);
1694 if (Tok.isNot(tok::l_paren) &&
1696 return ExprError(Diag(Tok, diag::err_expected_lparen_after_type)
1697 << DS.getSourceRange());
1698
1699 if (Tok.is(tok::l_brace))
1700 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
1701
1702 Res = ParseCXXTypeConstructExpression(DS);
1703 break;
1704 }
1705
1706 case tok::annot_cxxscope: {
1707
1708
1711 if (!Tok.is(tok::annot_cxxscope))
1712 return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr,
1713 isTypeCast, isVectorLiteral,
1714 NotPrimaryExpression);
1715
1717 if (Next.is(tok::annot_template_id)) {
1720
1721
1722
1724 ParseOptionalCXXScopeSpecifier(SS, nullptr,
1725 false,
1726 false);
1728 return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr,
1729 isTypeCast, isVectorLiteral,
1730 NotPrimaryExpression);
1731 }
1732 }
1733
1734
1735 Res = ParseCXXIdExpression(isAddressOfOperand);
1736 break;
1737 }
1738
1739 case tok::annot_template_id: {
1742
1743
1744
1747 return ParseCastExpression(ParseKind, isAddressOfOperand,
1748 NotCastExpr, isTypeCast, isVectorLiteral,
1749 NotPrimaryExpression);
1750 }
1751
1752
1753 [[fallthrough]];
1754 }
1755
1756 case tok::kw_operator:
1757 Res = ParseCXXIdExpression(isAddressOfOperand);
1758 break;
1759
1760 case tok::coloncolon: {
1761
1762
1765 if (!Tok.is(tok::coloncolon))
1766 return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast,
1767 isVectorLiteral, NotPrimaryExpression);
1768
1769
1770
1772 if (Tok.is(tok::kw_new)) {
1773 if (NotPrimaryExpression)
1774 *NotPrimaryExpression = true;
1775 Res = ParseCXXNewExpression(true, CCLoc);
1776 AllowSuffix = false;
1777 break;
1778 }
1779 if (Tok.is(tok::kw_delete)) {
1780 if (NotPrimaryExpression)
1781 *NotPrimaryExpression = true;
1782 Res = ParseCXXDeleteExpression(true, CCLoc);
1783 AllowSuffix = false;
1784 break;
1785 }
1786
1787
1788 Diag(CCLoc, diag::err_expected_expression);
1790 }
1791
1792 case tok::kw_new:
1793 if (NotPrimaryExpression)
1794 *NotPrimaryExpression = true;
1795 Res = ParseCXXNewExpression(false, Tok.getLocation());
1796 AllowSuffix = false;
1797 break;
1798
1799 case tok::kw_delete:
1800 if (NotPrimaryExpression)
1801 *NotPrimaryExpression = true;
1802 Res = ParseCXXDeleteExpression(false, Tok.getLocation());
1803 AllowSuffix = false;
1804 break;
1805
1806 case tok::kw_requires:
1807 Res = ParseRequiresExpression();
1808 AllowSuffix = false;
1809 break;
1810
1811 case tok::kw_noexcept: {
1812 if (NotPrimaryExpression)
1813 *NotPrimaryExpression = true;
1814 Diag(Tok, diag::warn_cxx98_compat_noexcept_expr);
1817
1818 if (T.expectAndConsume(diag::err_expected_lparen_after, "noexcept"))
1820
1821
1822
1826
1827 T.consumeClose();
1828
1831 T.getCloseLocation());
1832 AllowSuffix = false;
1833 break;
1834 }
1835
1836#define TYPE_TRAIT(N,Spelling,K) \
1837 case tok::kw_##Spelling:
1838#include "clang/Basic/TokenKinds.def"
1839 Res = ParseTypeTrait();
1840 break;
1841
1842 case tok::kw___array_rank:
1843 case tok::kw___array_extent:
1844 if (NotPrimaryExpression)
1845 *NotPrimaryExpression = true;
1846 Res = ParseArrayTypeTrait();
1847 break;
1848
1849 case tok::kw___builtin_ptrauth_type_discriminator:
1850 return ParseBuiltinPtrauthTypeDiscriminator();
1851
1852 case tok::kw___is_lvalue_expr:
1853 case tok::kw___is_rvalue_expr:
1854 if (NotPrimaryExpression)
1855 *NotPrimaryExpression = true;
1856 Res = ParseExpressionTrait();
1857 break;
1858
1859 case tok::at: {
1860 if (NotPrimaryExpression)
1861 *NotPrimaryExpression = true;
1863 return ParseObjCAtExpression(AtLoc);
1864 }
1865 case tok::caret:
1866 Res = ParseBlockLiteralExpression();
1867 break;
1868 case tok::code_completion: {
1869 cutOffParsing();
1873 }
1874#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1875#include "clang/Basic/TransformTypeTraits.def"
1876
1877
1878 if (().is(tok::l_paren)) {
1879 Tok.setKind(tok::identifier);
1880 Diag(Tok, diag::ext_keyword_as_ident)
1882 goto ParseIdentifier;
1883 }
1884 goto ExpectedExpression;
1885 case tok::l_square:
1888
1889
1890
1891
1892
1893 Res = TryParseLambdaExpression();
1895
1896
1897 if (NotPrimaryExpression)
1898 *NotPrimaryExpression = true;
1899 Res = ParseObjCMessageExpression();
1900 }
1901 break;
1902 }
1903 Res = ParseLambdaExpression();
1904 break;
1905 }
1907 Res = ParseObjCMessageExpression();
1908 break;
1909 }
1910 [[fallthrough]];
1911 default:
1912 ExpectedExpression:
1913 NotCastExpr = true;
1915 }
1916
1917
1918
1919
1920
1921 if (ParseKind == PrimaryExprOnly)
1922
1923
1924 return Res;
1925
1926 if (!AllowSuffix) {
1927
1928
1930 return Res;
1931
1932 switch (Tok.getKind()) {
1933 case tok::l_square:
1934 case tok::l_paren:
1935 case tok::plusplus:
1936 case tok::minusminus:
1937
1938
1940 return Res;
1941
1942 [[fallthrough]];
1943 case tok::period:
1944 case tok::arrow:
1945 break;
1946
1947 default:
1948 return Res;
1949 }
1950
1951
1952
1953
1954 Diag(Tok.getLocation(), diag::err_postfix_after_unary_requires_parens)
1958 ")");
1959 }
1960
1961
1962 PreferredType = SavedType;
1963 Res = ParsePostfixExpressionSuffix(Res);
1965 ().getOpenCLOptions().isAvailableOption(
1966 "__cl_clang_function_pointers", getLangOpts()))
1967 if (Expr *PostfixExpr = Res.get()) {
1968 QualType Ty = PostfixExpr->getType();
1970 Diag(PostfixExpr->getExprLoc(),
1971 diag::err_opencl_taking_function_address_parser);
1973 }
1974 }
1975
1976 return Res;
1977}
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2001Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
2002
2003
2005 auto SavedType = PreferredType;
2006 while (true) {
2007
2008 PreferredType = SavedType;
2009 switch (Tok.getKind()) {
2010 case tok::code_completion:
2011 if (InMessageExpression)
2012 return LHS;
2013
2014 cutOffParsing();
2018
2019 case tok::identifier:
2020
2021
2022
2026 nullptr, LHS.get());
2027 break;
2028 }
2029
2030 [[fallthrough]];
2031
2032 default:
2033 return LHS;
2034 case tok::l_square: {
2035
2036
2037
2038
2039
2040
2042 isSimpleObjCMessageExpression())
2043 return LHS;
2044
2045
2046
2047 if (CheckProhibitedCXX11Attribute()) {
2050 }
2052 T.consumeOpen();
2053 Loc = T.getOpenLocation();
2056 ExprVector ArgExprs;
2057 bool HasError = false;
2059
2060
2061
2062
2063
2064 if ((().OpenMP && !AllowOpenACCArraySections) ||
2065 Tok.isNot(tok::colon)) {
2069 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2070 Idx = ParseBraceInitializer();
2071 } else {
2073 }
2077 HasError = true;
2078 } else {
2079 ArgExprs.push_back(Idx.get());
2080 }
2081 } else if (Tok.isNot(tok::r_square)) {
2082 if (ParseExpressionList(ArgExprs)) {
2084 HasError = true;
2085 }
2086 }
2087 }
2088
2089
2090
2091
2092
2093 if (ArgExprs.size() <= 1 && AllowOpenACCArraySections) {
2095 if (Tok.is(tok::colon)) {
2096
2098 if (Tok.isNot(tok::r_square))
2100 }
2101 } else if (ArgExprs.size() <= 1 && getLangOpts().OpenMP) {
2103 if (Tok.is(tok::colon)) {
2104
2106 if (Tok.isNot(tok::r_square) &&
2111 }
2112 }
2114 (OMPClauseKind == llvm::omp::Clause::OMPC_to ||
2115 OMPClauseKind == llvm::omp::Clause::OMPC_from) &&
2116 Tok.is(tok::colon)) {
2117
2119 if (Tok.isNot(tok::r_square)) {
2121 }
2122 }
2123 }
2124
2127
2128 if (!LHS.isInvalid() && !HasError && !Length.isInvalid() &&
2129 !Stride.isInvalid() && Tok.is(tok::r_square)) {
2130 if (ColonLocFirst.isValid() || ColonLocSecond.isValid()) {
2131
2132
2133
2134
2135 if (AllowOpenACCArraySections) {
2136 assert(!Stride.isUsable() && !ColonLocSecond.isValid() &&
2137 "Stride/second colon not allowed for OpenACC");
2139 LHS.get(), Loc, ArgExprs.empty() ? nullptr : ArgExprs[0],
2140 ColonLocFirst, Length.get(), RLoc);
2141 } else {
2143 LHS.get(), Loc, ArgExprs.empty() ? nullptr : ArgExprs[0],
2144 ColonLocFirst, ColonLocSecond, Length.get(), Stride.get(),
2145 RLoc);
2146 }
2147 } else {
2149 ArgExprs, RLoc);
2150 }
2151 } else {
2153 }
2154
2155
2156 T.consumeClose();
2157 break;
2158 }
2159
2160 case tok::l_paren:
2161 case tok::lesslessless: {
2162
2165
2166 Expr *ExecConfig = nullptr;
2167
2169
2170 if (OpKind == tok::lesslessless) {
2171 ExprVector ExecConfigExprs;
2173
2174 if (ParseSimpleExpressionList(ExecConfigExprs)) {
2177 }
2178
2180 if (TryConsumeToken(tok::greatergreatergreater, CloseLoc)) {
2183 } else {
2184
2185 Diag(Tok, diag::err_expected) << tok::greatergreatergreater;
2186 Diag(OpenLoc, diag::note_matching) << tok::lesslessless;
2189 }
2190
2192 if (ExpectAndConsume(tok::l_paren))
2194 else
2195 Loc = PrevTokLocation;
2196 }
2197
2200 getCurScope(), OpenLoc, ExecConfigExprs, CloseLoc);
2203 else
2204 ExecConfig = ECResult.get();
2205 }
2206 } else {
2207 PT.consumeOpen();
2208 Loc = PT.getOpenLocation();
2209 }
2210
2211 ExprVector ArgExprs;
2212 auto RunSignatureHelp = [&]() -> QualType {
2215 LHS.get(), ArgExprs, PT.getOpenLocation());
2216 CalledSignatureHelp = true;
2217 return PreferredType;
2218 };
2219 if (OpKind == tok::l_paren || !LHS.isInvalid()) {
2220 if (Tok.isNot(tok::r_paren)) {
2221 bool HasTrailingComma = false;
2222 bool HasError = ParseExpressionList(
2223 ArgExprs,
2224 [&] {
2225 PreferredType.enterFunctionArgument(Tok.getLocation(),
2226 RunSignatureHelp);
2227 },
2228 false,
2229 false, &HasTrailingComma);
2230
2231 if (HasError && !HasTrailingComma) {
2233
2234
2235
2236
2238 RunSignatureHelp();
2241 for (auto &E : ArgExprs)
2243 }
2244 }
2245 }
2246
2247
2250 } else if (Tok.isNot(tok::r_paren)) {
2251 bool HadDelayedTypo = false;
2253 HadDelayedTypo = true;
2254 for (auto &E : ArgExprs)
2256 HadDelayedTypo = true;
2257
2258
2259
2260 if (HadDelayedTypo)
2262 else
2263 PT.consumeClose();
2265 } else {
2269 ExecConfig);
2271 ArgExprs.insert(ArgExprs.begin(), Fn);
2272 LHS =
2274 }
2275 PT.consumeClose();
2276 }
2277
2278 break;
2279 }
2280 case tok::arrow:
2281 case tok::period: {
2282
2283
2286
2289 bool MayBePseudoDestructor = false;
2291
2292 PreferredType.enterMemAccess(Actions, Tok.getLocation(), OrigLHS);
2293
2296 const Type* BaseType = Base->getType().getTypePtrOrNull();
2297 if (BaseType && Tok.is(tok::l_paren) &&
2300 Diag(OpLoc, diag::err_function_is_not_record)
2301 << OpKind << Base->getSourceRange()
2303 return ParsePostfixExpressionSuffix(Base);
2304 }
2305
2307 OpKind, ObjectType,
2308 MayBePseudoDestructor);
2310
2311
2312
2313 if (Tok.is(tok::code_completion)) {
2314 cutOffParsing();
2316 }
2317 break;
2318 }
2319 ParseOptionalCXXScopeSpecifier(
2321 false, &MayBePseudoDestructor);
2323 ObjectType = nullptr;
2324 }
2325
2326 if (Tok.is(tok::code_completion)) {
2328 OpKind == tok::arrow ? tok::period : tok::arrow;
2329 ExprResult CorrectedLHS(true);
2331
2332
2335 getCurScope(), OrigLHS, OpLoc, CorrectedOpKind, ObjectType,
2336 MayBePseudoDestructor);
2337 }
2338
2340 Expr *CorrectedBase = CorrectedLHS.get();
2342 CorrectedBase = Base;
2343
2344
2345 cutOffParsing();
2347 getCurScope(), Base, CorrectedBase, OpLoc, OpKind == tok::arrow,
2348 Base && ExprStatementTokLoc == Base->getBeginLoc(),
2350
2352 }
2353
2354 if (MayBePseudoDestructor && !LHS.isInvalid()) {
2355 LHS = ParseCXXPseudoDestructor(LHS.get(), OpLoc, OpKind, SS,
2356 ObjectType);
2357 break;
2358 }
2359
2360
2361
2362
2363
2364
2365
2366
2370 Tok.is(tok::kw_class)) {
2371
2372
2373
2374
2375
2376
2377
2380 Name.setIdentifier(Id, Loc);
2383 false,
2384 true,
2385
2387 false, &TemplateKWLoc, Name)) {
2390 }
2391
2394 OpKind, SS, TemplateKWLoc, Name,
2395 CurParsedObjCImpl ? CurParsedObjCImpl->Dcl
2396 : nullptr);
2398 if (Tok.is(tok::less))
2399 checkPotentialAngleBracket(LHS);
2400 } else if (OrigLHS && Name.isValid()) {
2401
2403 Name.getEndLoc(), {OrigLHS});
2404 }
2405 break;
2406 }
2407 case tok::plusplus:
2408 case tok::minusminus:
2416 }
2418 break;
2419 }
2420 }
2421}
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2456Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
2457 bool &isCastExpr,
2460
2461 assert(OpTok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual, tok::kw_sizeof,
2462 tok::kw___datasizeof, tok::kw___alignof, tok::kw_alignof,
2463 tok::kw__Alignof, tok::kw_vec_step,
2464 tok::kw___builtin_omp_required_simd_align,
2465 tok::kw___builtin_vectorelements) &&
2466 "Not a typeof/sizeof/alignof/vec_step expression!");
2467
2469
2470
2471 if (Tok.isNot(tok::l_paren)) {
2472
2473
2474 if (OpTok.isOneOf(tok::kw_sizeof, tok::kw___datasizeof, tok::kw___alignof,
2475 tok::kw_alignof, tok::kw__Alignof)) {
2476 if (isTypeIdUnambiguously()) {
2478 ParseSpecifierQualifierList(DS);
2481 ParseDeclarator(DeclaratorInfo);
2482
2487 diag::err_expected_parentheses_around_typename)
2489 } else {
2490 Diag(LParenLoc, diag::err_expected_parentheses_around_typename)
2493 }
2494 isCastExpr = true;
2496 }
2497 }
2498
2499 isCastExpr = false;
2500 if (OpTok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
2503 << tok::l_paren;
2505 }
2506
2507
2508
2509
2510
2511 if (OpTok.isOneOf(tok::kw_sizeof, tok::kw___datasizeof, tok::kw___alignof,
2512 tok::kw_alignof, tok::kw__Alignof) &&
2513 Tok.isOneOf(tok::kw_sizeof, tok::kw___datasizeof, tok::kw___alignof,
2514 tok::kw_alignof, tok::kw__Alignof))
2516 Operand = ParseCastExpression(UnaryExprOnly);
2517 });
2518 else
2519 Operand = ParseCastExpression(UnaryExprOnly);
2520 } else {
2521
2522
2523
2524
2525 ParenParseOption ExprType = CastExpr;
2527
2528 Operand = ParseParenExpression(ExprType, true,
2529 false, CastTy, RParenLoc);
2530 CastRange = SourceRange(LParenLoc, RParenLoc);
2531
2532
2533
2535 isCastExpr = true;
2537 }
2538
2540 !OpTok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual)) {
2541
2542
2543
2544
2545 if (.isInvalid())
2546 Operand = ParsePostfixExpressionSuffix(Operand.get());
2547 }
2548 }
2549
2550
2551 isCastExpr = false;
2553}
2554
2555
2556
2557ExprResult Parser::ParseSYCLUniqueStableNameExpression() {
2558 assert(Tok.is(tok::kw___builtin_sycl_unique_stable_name) &&
2559 "Not __builtin_sycl_unique_stable_name");
2560
2563
2564
2565 if (T.expectAndConsume(diag::err_expected_lparen_after,
2566 "__builtin_sycl_unique_stable_name"))
2568
2570
2572 T.skipToEnd();
2574 }
2575
2576 if (T.consumeClose())
2578
2580 OpLoc, T.getOpenLocation(), T.getCloseLocation(), Ty.get());
2581}
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() {
2598 assert(Tok.isOneOf(tok::kw_sizeof, tok::kw___datasizeof, tok::kw___alignof,
2599 tok::kw_alignof, tok::kw__Alignof, tok::kw_vec_step,
2600 tok::kw___builtin_omp_required_simd_align,
2601 tok::kw___builtin_vectorelements) &&
2602 "Not a sizeof/alignof/vec_step expression!");
2603 Token OpTok = Tok;
2605
2606
2607 if (Tok.is(tok::ellipsis) && OpTok.is(tok::kw_sizeof)) {
2612 if (Tok.is(tok::l_paren)) {
2614 T.consumeOpen();
2615 LParenLoc = T.getOpenLocation();
2616 if (Tok.is(tok::identifier)) {
2619 T.consumeClose();
2620 RParenLoc = T.getCloseLocation();
2623 } else {
2624 Diag(Tok, diag::err_expected_parameter_pack);
2626 }
2627 } else if (Tok.is(tok::identifier)) {
2632 Diag(LParenLoc, diag::err_paren_sizeof_parameter_pack)
2633 << Name
2636 } else {
2637 Diag(Tok, diag::err_sizeof_parameter_pack);
2638 }
2639
2640 if (!Name)
2642
2646
2649 *Name, NameLoc,
2650 RParenLoc);
2651 }
2652
2654 OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof))
2655 Diag(OpTok, diag::warn_cxx98_compat_alignof);
2657 Diag(OpTok, diag::warn_c23_compat_keyword) << OpTok.getName();
2658
2662
2663 bool isCastExpr;
2667 isCastExpr,
2668 CastTy,
2669 CastRange);
2670
2672 switch (OpTok.getKind()) {
2673 case tok::kw_alignof:
2674 case tok::kw__Alignof:
2675 ExprKind = UETT_AlignOf;
2676 break;
2677 case tok::kw___alignof:
2678 ExprKind = UETT_PreferredAlignOf;
2679 break;
2680 case tok::kw_vec_step:
2681 ExprKind = UETT_VecStep;
2682 break;
2683 case tok::kw___builtin_omp_required_simd_align:
2684 ExprKind = UETT_OpenMPRequiredSimdAlign;
2685 break;
2686 case tok::kw___datasizeof:
2687 ExprKind = UETT_DataSizeOf;
2688 break;
2689 case tok::kw___builtin_vectorelements:
2690 ExprKind = UETT_VectorElements;
2691 break;
2692 default:
2693 break;
2694 }
2695
2696 if (isCastExpr)
2698 ExprKind,
2699 true,
2701 CastRange);
2702
2703 if (OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof))
2705
2706
2707 if (.isInvalid())
2709 ExprKind,
2710 false,
2712 CastRange);
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
2739ExprResult Parser::ParseBuiltinPrimaryExpression() {
2742
2745
2746
2747 if (Tok.isNot(tok::l_paren))
2748 return ExprError(Diag(Tok, diag::err_expected_after) << BuiltinII
2749 << tok::l_paren);
2750
2752 PT.consumeOpen();
2753
2754
2755
2756 switch (T) {
2757 default: llvm_unreachable("Not a builtin primary expression!");
2758 case tok::kw___builtin_va_arg: {
2760
2761 if (ExpectAndConsume(tok::comma)) {
2764 }
2765
2767
2768 if (Tok.isNot(tok::r_paren)) {
2769 Diag(Tok, diag::err_expected) << tok::r_paren;
2771 }
2772
2775 else
2776 Res = Actions.ActOnVAArg(StartLoc, Expr.get(), Ty.get(), ConsumeParen());
2777 break;
2778 }
2779 case tok::kw___builtin_offsetof: {
2785 if (MacroName == "offsetof")
2787 }
2789 {
2795 }
2796 }
2797
2798 if (ExpectAndConsume(tok::comma)) {
2801 }
2802
2803
2804 if (Tok.isNot(tok::identifier)) {
2805 Diag(Tok, diag::err_expected) << tok::identifier;
2808 }
2809
2810
2812
2814 Comps.back().isBrackets = false;
2816 Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken();
2817
2818
2819 while (true) {
2820 if (Tok.is(tok::period)) {
2821
2823 Comps.back().isBrackets = false;
2825
2826 if (Tok.isNot(tok::identifier)) {
2827 Diag(Tok, diag::err_expected) << tok::identifier;
2830 }
2833 } else if (Tok.is(tok::l_square)) {
2834 if (CheckProhibitedCXX11Attribute())
2836
2837
2839 Comps.back().isBrackets = true;
2841 ST.consumeOpen();
2842 Comps.back().LocStart = ST.getOpenLocation();
2846 return Res;
2847 }
2848 Comps.back().U.E = Res.get();
2849
2850 ST.consumeClose();
2851 Comps.back().LocEnd = ST.getCloseLocation();
2852 } else {
2853 if (Tok.isNot(tok::r_paren)) {
2854 PT.consumeClose();
2858 } else {
2859 PT.consumeClose();
2861 Ty.get(), Comps,
2862 PT.getCloseLocation());
2863 }
2864 break;
2865 }
2866 }
2867 break;
2868 }
2869 case tok::kw___builtin_choose_expr: {
2871 if (Cond.isInvalid()) {
2873 return Cond;
2874 }
2875 if (ExpectAndConsume(tok::comma)) {
2878 }
2879
2881 if (Expr1.isInvalid()) {
2883 return Expr1;
2884 }
2885 if (ExpectAndConsume(tok::comma)) {
2888 }
2889
2891 if (Expr2.isInvalid()) {
2893 return Expr2;
2894 }
2895 if (Tok.isNot(tok::r_paren)) {
2896 Diag(Tok, diag::err_expected) << tok::r_paren;
2898 }
2899 Res = Actions.ActOnChooseExpr(StartLoc, Cond.get(), Expr1.get(),
2900 Expr2.get(), ConsumeParen());
2901 break;
2902 }
2903 case tok::kw___builtin_astype: {
2904
2906 if (Expr.isInvalid()) {
2909 }
2910
2911 if (ExpectAndConsume(tok::comma)) {
2914 }
2915
2916
2920
2921
2922 if (Tok.isNot(tok::r_paren)) {
2923 Diag(Tok, diag::err_expected) << tok::r_paren;
2926 }
2927
2929 ConsumeParen());
2930 break;
2931 }
2932 case tok::kw___builtin_convertvector: {
2933
2935 if (Expr.isInvalid()) {
2938 }
2939
2940 if (ExpectAndConsume(tok::comma)) {
2943 }
2944
2945
2949
2950
2951 if (Tok.isNot(tok::r_paren)) {
2952 Diag(Tok, diag::err_expected) << tok::r_paren;
2955 }
2956
2958 ConsumeParen());
2959 break;
2960 }
2961 case tok::kw___builtin_COLUMN:
2962 case tok::kw___builtin_FILE:
2963 case tok::kw___builtin_FILE_NAME:
2964 case tok::kw___builtin_FUNCTION:
2965 case tok::kw___builtin_FUNCSIG:
2966 case tok::kw___builtin_LINE:
2967 case tok::kw___builtin_source_location: {
2968
2969 if (Tok.isNot(tok::r_paren)) {
2970 Diag(Tok, diag::err_expected) << tok::r_paren;
2973 }
2975 switch (T) {
2976 case tok::kw___builtin_FILE:
2978 case tok::kw___builtin_FILE_NAME:
2980 case tok::kw___builtin_FUNCTION:
2982 case tok::kw___builtin_FUNCSIG:
2984 case tok::kw___builtin_LINE:
2986 case tok::kw___builtin_COLUMN:
2988 case tok::kw___builtin_source_location:
2990 default:
2991 llvm_unreachable("invalid keyword");
2992 }
2993 }();
2995 break;
2996 }
2997 }
2998
3001
3002
3003
3004 return ParsePostfixExpressionSuffix(Res.get());
3005}
3006
3007bool Parser::tryParseOpenMPArrayShapingCastPart() {
3008 assert(Tok.is(tok::l_square) && "Expected open bracket");
3009 bool ErrorFound = true;
3010 TentativeParsingAction TPA(*this);
3011 do {
3012 if (Tok.isNot(tok::l_square))
3013 break;
3014
3015 ConsumeBracket();
3016
3017 while ((tok::r_square, tok::annot_pragma_openmp_end,
3019 ;
3020 if (Tok.isNot(tok::r_square))
3021 break;
3022
3023 ConsumeBracket();
3024
3025 if (Tok.is(tok::r_paren)) {
3026 ErrorFound = false;
3027 break;
3028 }
3029 } while (Tok.isNot(tok::annot_pragma_openmp_end));
3030 TPA.Revert();
3031 return !ErrorFound;
3032}
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3062Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
3063 bool isTypeCast, ParsedType &CastTy,
3065 assert(Tok.is(tok::l_paren) && "Not a paren expr!");
3068 if (T.consumeOpen())
3071
3072 PreferredType.enterParenExpr(Tok.getLocation(), OpenLoc);
3073
3075 bool isAmbiguousTypeId;
3076 CastTy = nullptr;
3077
3078 if (Tok.is(tok::code_completion)) {
3079 cutOffParsing();
3082 ExprType >= CompoundLiteral);
3084 }
3085
3086
3087 bool BridgeCast = (getLangOpts().ObjC &&
3088 Tok.isOneOf(tok::kw___bridge,
3089 tok::kw___bridge_transfer,
3090 tok::kw___bridge_retained,
3091 tok::kw___bridge_retain));
3092 if (BridgeCast && ().ObjCAutoRefCount) {
3094 StringRef BridgeCastName = Tok.getName();
3097 Diag(BridgeKeywordLoc, diag::warn_arc_bridge_cast_nonarc)
3098 << BridgeCastName
3100 }
3101 BridgeCast = false;
3102 }
3103
3104
3105
3106 if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
3107 Diag(Tok, OpenLoc.isMacroID() ? diag::ext_gnu_statement_expr_macro
3108 : diag::ext_gnu_statement_expr);
3109
3110 checkCompoundToken(OpenLoc, tok::l_paren, CompoundToken::StmtExprBegin);
3111
3114 } else {
3115
3116
3117
3119 while (CodeDC->isRecord() || isa(CodeDC)) {
3122 "statement expr not in code context");
3123 }
3124 Sema::ContextRAII SavedContext(Actions, CodeDC, false);
3125
3127
3130
3131
3132 if (.isInvalid()) {
3135 } else {
3137 }
3138 }
3139 } else if (ExprType >= CompoundLiteral && BridgeCast) {
3142
3143
3145 if (tokenKind == tok::kw___bridge)
3147 else if (tokenKind == tok::kw___bridge_transfer)
3149 else if (tokenKind == tok::kw___bridge_retained)
3151 else {
3152
3153
3154 assert(tokenKind == tok::kw___bridge_retain);
3157 Diag(BridgeKeywordLoc, diag::err_arc_bridge_retain)
3159 "__bridge_retained");
3160 }
3161
3163 T.consumeClose();
3164 ColonProtection.restore();
3165 RParenLoc = T.getCloseLocation();
3166
3167 PreferredType.enterTypeCast(Tok.getLocation(), Ty.get().get());
3168 ExprResult SubExpr = ParseCastExpression(AnyCastExpr);
3169
3172
3174 BridgeKeywordLoc, Ty.get(),
3175 RParenLoc, SubExpr.get());
3176 } else if (ExprType >= CompoundLiteral &&
3177 isTypeIdInParens(isAmbiguousTypeId)) {
3178
3179
3180
3181
3182
3183
3184
3185
3186 if (isAmbiguousTypeId && !stopIfCastExpr) {
3187 ExprResult res = ParseCXXAmbiguousParenExpression(ExprType, CastTy, T,
3188 ColonProtection);
3189 RParenLoc = T.getCloseLocation();
3190 return res;
3191 }
3192
3193
3195 ParseSpecifierQualifierList(DS);
3198 ParseDeclarator(DeclaratorInfo);
3199
3200
3201
3202
3203 if (!DeclaratorInfo.isInvalidType() && Tok.is(tok::identifier) &&
3207 {
3210 }
3213 Ty.get(), nullptr);
3214 } else {
3215
3216 T.consumeClose();
3217 ColonProtection.restore();
3218 RParenLoc = T.getCloseLocation();
3219 if (Tok.is(tok::l_brace)) {
3220 ExprType = CompoundLiteral;
3222 {
3225 }
3226 return ParseCompoundLiteralExpression(Ty.get(), OpenLoc, RParenLoc);
3227 }
3228
3229 if (Tok.is(tok::l_paren)) {
3230
3232 {
3234 {
3237 }
3239 {
3241 }
3242 QualType QT = Ty.get().get().getCanonicalType();
3244 {
3245
3246
3247
3248
3249
3250 Result = ParseCastExpression(AnyCastExpr,
3251 false,
3253 true);
3254
3255 if (.isInvalid()) {
3257 DeclaratorInfo, CastTy,
3258 RParenLoc, Result.get());
3259 }
3260
3261
3262 if (.isInvalid()) {
3263 Result = ParsePostfixExpressionSuffix(Result);
3264 }
3265
3267 }
3268 }
3269 }
3270
3272
3273
3274 if (DeclaratorInfo.isInvalidType())
3276
3277
3278
3279 if (stopIfCastExpr) {
3281 {
3284 }
3285 CastTy = Ty.get();
3287 }
3288
3289
3293 GetLookAheadToken(1).isNot(tok::period)) {
3297 }
3298
3299 PreferredType.enterTypeCast(Tok.getLocation(), CastTy.get());
3300
3301
3302 Result = ParseCastExpression(AnyCastExpr,
3303 false,
3305 if (.isInvalid()) {
3307 DeclaratorInfo, CastTy,
3308 RParenLoc, Result.get());
3309 }
3311 }
3312
3313 Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
3315 }
3316 } else if (ExprType >= FoldExpr && Tok.is(tok::ellipsis) &&
3318 ExprType = FoldExpr;
3319 return ParseFoldExpression(ExprResult(), T);
3320 } else if (isTypeCast) {
3321
3323 ExprVector ArgExprs;
3324
3325 if (!ParseSimpleExpressionList(ArgExprs)) {
3326
3327
3328 if (ExprType >= FoldExpr && ArgExprs.size() == 1 &&
3329 isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) {
3330 ExprType = FoldExpr;
3331 return ParseFoldExpression(ArgExprs[0], T);
3332 }
3333
3334 ExprType = SimpleExpr;
3336 ArgExprs);
3337 }
3338 } else if (getLangOpts().OpenMP >= 50 && OpenMPDirectiveParsing &&
3339 ExprType == CastExpr && Tok.is(tok::l_square) &&
3340 tryParseOpenMPArrayShapingCastPart()) {
3341 bool ErrorFound = false;
3344 do {
3346 TS.consumeOpen();
3349 if (!NumElements.isUsable()) {
3350 ErrorFound = true;
3351 while ((tok::r_square, tok::r_paren,
3353 ;
3354 }
3355 TS.consumeClose();
3356 OMPDimensions.push_back(NumElements.get());
3357 OMPBracketsRanges.push_back(TS.getRange());
3358 } while (Tok.isNot(tok::r_paren));
3359
3360 T.consumeClose();
3361 RParenLoc = T.getCloseLocation();
3363 if (ErrorFound) {
3365 } else if (.isInvalid()) {
3367 Result.get(), OpenLoc, RParenLoc, OMPDimensions, OMPBracketsRanges);
3368 }
3370 } else {
3372
3375
3376
3378 }
3379
3380 if (ExprType >= FoldExpr && isFoldOperator(Tok.getKind()) &&
3381 NextToken().is(tok::ellipsis)) {
3382 ExprType = FoldExpr;
3383 return ParseFoldExpression(Result, T);
3384 }
3385 ExprType = SimpleExpr;
3386
3387
3388 if (.isInvalid() && Tok.is(tok::r_paren))
3391 }
3392
3393
3394 if (Result.isInvalid()) {
3397 }
3398
3399 T.consumeClose();
3400 RParenLoc = T.getCloseLocation();
3402}
3403
3404
3405
3406
3407
3408
3409
3410
3411
3413Parser::ParseCompoundLiteralExpression(ParsedType Ty,
3416 assert(Tok.is(tok::l_brace) && "Not a compound literal!");
3417 if (().C99)
3418 Diag(LParenLoc, diag::ext_c99_compound_literal);
3419 PreferredType.enterTypeCast(Tok.getLocation(), Ty.get());
3421 if (.isInvalid() && Ty)
3424}
3425
3426
3427
3428
3429
3430
3431
3432
3433
3436 false);
3437}
3438
3441 true);
3442}
3443
3447 "Not a string-literal-like token!");
3448
3449
3450
3451
3453
3454 do {
3455 StringToks.push_back(Tok);
3458
3460 assert(!AllowUserDefinedLiteral && "UDL are always evaluated");
3462 }
3463
3464
3467 : nullptr);
3468}
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489ExprResult Parser::ParseGenericSelectionExpression() {
3490 assert(Tok.is(tok::kw__Generic) && "_Generic keyword expected");
3491
3492 diagnoseUseOfC11Keyword(Tok);
3493
3496 if (T.expectAndConsume())
3498
3499
3500
3503 if (isTypeIdForGenericSelection()) {
3505 if (ControllingType.isInvalid()) {
3508 }
3509 const auto *LIT = cast(ControllingType.get().get());
3510 SourceLocation Loc = LIT->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
3512 : diag::ext_c2y_generic_with_type_arg);
3513 } else {
3514
3515
3518 ControllingExpr =
3520 if (ControllingExpr.isInvalid()) {
3523 }
3524 }
3525
3526 if (ExpectAndConsume(tok::comma)) {
3529 }
3530
3533 ExprVector Exprs;
3534 do {
3536 if (Tok.is(tok::kw_default)) {
3537
3538
3540 Diag(Tok, diag::err_duplicate_default_assoc);
3541 Diag(DefaultLoc, diag::note_previous_default_assoc);
3544 }
3546 Ty = nullptr;
3547 } else {
3553 }
3554 Ty = TR.get();
3555 }
3556 Types.push_back(Ty);
3557
3558 if (ExpectAndConsume(tok::colon)) {
3561 }
3562
3563
3564
3567 if (ER.isInvalid()) {
3570 }
3571 Exprs.push_back(ER.get());
3573
3574 T.consumeClose();
3575 if (T.getCloseLocation().isInvalid())
3577
3578 void *ExprOrTy = ControllingExpr.isUsable()
3579 ? ControllingExpr.get()
3580 : ControllingType.get().getAsOpaquePtr();
3581
3583 KeyLoc, DefaultLoc, T.getCloseLocation(), ControllingExpr.isUsable(),
3584 ExprOrTy, Types, Exprs);
3585}
3586
3587
3588
3589
3590
3591
3592
3593
3594
3598 T.skipToEnd();
3599 return true;
3600 }
3601
3606 assert(isFoldOperator(Kind) && "missing fold-operator");
3608 }
3609
3610 assert(Tok.is(tok::ellipsis) && "not a fold-expression");
3612
3614 if (Tok.isNot(tok::r_paren)) {
3615 if (!isFoldOperator(Tok.getKind()))
3616 return Diag(Tok.getLocation(), diag::err_expected_fold_operator);
3617
3618 if (Kind != tok::unknown && Tok.getKind() != Kind)
3619 Diag(Tok.getLocation(), diag::err_fold_operator_mismatch)
3623
3626 T.skipToEnd();
3627 return true;
3628 }
3629 }
3630
3632 ? diag::warn_cxx14_compat_fold_expression
3633 : diag::ext_fold_expression);
3634
3635 T.consumeClose();
3637 Kind, EllipsisLoc, RHS.get(),
3638 T.getCloseLocation());
3639}
3640
3641void Parser::injectEmbedTokens() {
3645 Data->BinaryData.size() * 2 - 1),
3646 Data->BinaryData.size() * 2 - 1);
3647 unsigned I = 0;
3648 for (auto &Byte : Data->BinaryData) {
3649 Toks[I].startToken();
3650 Toks[I].setKind(tok::binary_data);
3652 Toks[I].setLength(1);
3653 Toks[I].setLiteralData(&Byte);
3654 if (I != ((Data->BinaryData.size() - 1) * 2)) {
3655 Toks[I + 1].startToken();
3656 Toks[I + 1].setKind(tok::comma);
3657 Toks[I + 1].setLocation(Tok.getLocation());
3658 }
3659 I += 2;
3660 }
3661 PP.EnterTokenStream(std::move(Toks), true,
3662 true);
3664}
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3689 llvm::function_ref<void()> ExpressionStarts,
3690 bool FailImmediatelyOnInvalidExpr,
3691 bool EarlyTypoCorrection,
3692 bool *HasTrailingComma) {
3693 bool SawError = false;
3694 while (true) {
3695 if (ExpressionStarts)
3696 ExpressionStarts();
3697
3700 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
3701 Expr = ParseBraceInitializer();
3702 } else
3704
3705 if (EarlyTypoCorrection)
3707
3708 if (Tok.is(tok::ellipsis))
3710 else if (Tok.is(tok::code_completion)) {
3711
3712
3713
3714
3715
3716 SawError = true;
3717 cutOffParsing();
3718 break;
3719 }
3720 if (Expr.isInvalid()) {
3721 SawError = true;
3722 if (FailImmediatelyOnInvalidExpr)
3723 break;
3725 } else {
3726 Exprs.push_back(Expr.get());
3727 }
3728
3729 if (Tok.isNot(tok::comma))
3730 break;
3731
3734 checkPotentialAngleBracketDelimiter(Comma);
3735
3736 if (Tok.is(tok::r_paren)) {
3737 if (HasTrailingComma)
3738 *HasTrailingComma = true;
3739 break;
3740 }
3741 }
3742 if (SawError) {
3743
3744
3745 for (auto &E : Exprs) {
3747 if (Expr.isUsable()) E = Expr.get();
3748 }
3749 }
3750 return SawError;
3751}
3752
3753
3754
3755
3756
3757
3758
3759
3760
3762 while (true) {
3764 if (Expr.isInvalid())
3765 return true;
3766
3767 Exprs.push_back(Expr.get());
3768
3769
3770
3771 if (Tok.isNot(tok::comma) || NextToken().is(tok::ellipsis))
3772 return false;
3773
3774
3777 checkPotentialAngleBracketDelimiter(Comma);
3778 }
3779}
3780
3781
3782
3783
3784
3785
3786
3788 if (Tok.is(tok::code_completion)) {
3789 cutOffParsing();
3792 return;
3793 }
3794
3795
3797 ParseSpecifierQualifierList(DS);
3798
3799
3803 ParseDeclarator(DeclaratorInfo);
3804
3805 MaybeParseGNUAttributes(DeclaratorInfo);
3806
3807
3809}
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821ExprResult Parser::ParseBlockLiteralExpression() {
3822 assert(Tok.is(tok::caret) && "block literal starts with ^");
3824
3826 "block literal parsing");
3827
3828
3829
3830
3831
3834
3835
3837
3838
3843
3844
3846
3847
3848
3849 if (Tok.is(tok::l_paren)) {
3850 ParseParenDeclarator(ParamInfo);
3851
3852
3853
3854 SourceLocation Tmp = ParamInfo.getSourceRange().getEnd();
3855 ParamInfo.SetIdentifier(nullptr, CaretLoc);
3856 ParamInfo.SetRangeEnd(Tmp);
3857 if (ParamInfo.isInvalidType()) {
3858
3859
3860
3863 }
3864
3865 MaybeParseGNUAttributes(ParamInfo);
3866
3867
3869 } else if (!Tok.is(tok::l_brace)) {
3870 ParseBlockId(CaretLoc);
3871 } else {
3872
3874 ParamInfo.AddTypeInfo(
3876 false,
3877 NoLoc,
3878 nullptr,
3879 0,
3880 NoLoc,
3881 NoLoc,
3882 true,
3883 NoLoc,
3884 NoLoc, EST_None,
3886 nullptr,
3887 nullptr,
3888 0,
3889 nullptr,
3890 nullptr,
3891 {}, CaretLoc,
3892 CaretLoc, ParamInfo),
3893 CaretLoc);
3894
3895 MaybeParseGNUAttributes(ParamInfo);
3896
3897
3899 }
3900
3901
3903 if (!Tok.is(tok::l_brace)) {
3904
3905 Diag(Tok, diag::err_expected_expression);
3908 }
3909
3911 BlockScope.Exit();
3912 if (.isInvalid())
3914 else
3917}
3918
3919
3920
3921
3922
3923ExprResult Parser::ParseObjCBoolLiteral() {
3926}
3927
3928
3929
3932 llvm::SmallSet<StringRef, 4> Platforms;
3933 bool HasOtherPlatformSpec = false;
3934 bool Valid = true;
3935 for (const auto &Spec : AvailSpecs) {
3936 if (Spec.isOtherPlatformSpec()) {
3937 if (HasOtherPlatformSpec) {
3938 P.Diag(Spec.getBeginLoc(), diag::err_availability_query_repeated_star);
3939 Valid = false;
3940 }
3941
3942 HasOtherPlatformSpec = true;
3943 continue;
3944 }
3945
3946 bool Inserted = Platforms.insert(Spec.getPlatform()).second;
3947 if (!Inserted) {
3948
3949
3950
3951 StringRef Platform = Spec.getPlatform();
3952 P.Diag(Spec.getBeginLoc(), diag::err_availability_query_repeated_platform)
3953 << Spec.getEndLoc() << Platform;
3954 Valid = false;
3955 }
3956 }
3957
3958 if (!HasOtherPlatformSpec) {
3959 SourceLocation InsertWildcardLoc = AvailSpecs.back().getEndLoc();
3960 P.Diag(InsertWildcardLoc, diag::err_availability_query_wildcard_required)
3962 return true;
3963 }
3964
3965 return !Valid;
3966}
3967
3968
3969
3970
3971
3972
3973std::optional Parser::ParseAvailabilitySpec() {
3974 if (Tok.is(tok::star)) {
3976 } else {
3977
3978 if (Tok.is(tok::code_completion)) {
3979 cutOffParsing();
3981 return std::nullopt;
3982 }
3983 if (Tok.isNot(tok::identifier)) {
3984 Diag(Tok, diag::err_avail_query_expected_platform_name);
3985 return std::nullopt;
3986 }
3987
3988 IdentifierLoc *PlatformIdentifier = ParseIdentifierLoc();
3990 VersionTuple Version = ParseVersionTuple(VersionRange);
3991
3992 if (Version.empty())
3993 return std::nullopt;
3994
3995 StringRef GivenPlatform = PlatformIdentifier->Ident->getName();
3996 StringRef Platform =
3997 AvailabilityAttr::canonicalizePlatformName(GivenPlatform);
3998
3999 if (AvailabilityAttr::getPrettyPlatformName(Platform).empty() ||
4000 (GivenPlatform.contains("xros") || GivenPlatform.contains("xrOS"))) {
4001 Diag(PlatformIdentifier->Loc,
4002 diag::err_avail_query_unrecognized_platform_name)
4003 << GivenPlatform;
4004 return std::nullopt;
4005 }
4006
4008 VersionRange.getEnd());
4009 }
4010}
4011
4013 assert(Tok.is(tok::kw___builtin_available) ||
4015
4016
4018
4020 if (Parens.expectAndConsume())
4022
4024 bool HasError = false;
4025 while (true) {
4026 std::optional Spec = ParseAvailabilitySpec();
4027 if (!Spec)
4028 HasError = true;
4029 else
4030 AvailSpecs.push_back(*Spec);
4031
4033 break;
4034 }
4035
4036 if (HasError) {
4039 }
4040
4042
4043 if (Parens.consumeClose())
4045
4047 AvailSpecs, BeginLoc, Parens.getCloseLocation());
4048}
Defines the clang::ASTContext interface.
static Decl::Kind getKind(const Decl *D)
Defines the clang::Expr interface and subclasses for C++ expressions.
static bool CheckAvailabilitySpecList(Parser &P, ArrayRef< AvailabilitySpec > AvailSpecs)
Validate availability spec list, emitting diagnostics if necessary.
#define REVERTIBLE_TYPE_TRAIT(Name)
Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...
This file declares semantic analysis for CUDA constructs.
This file declares facilities that support code completion.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis for OpenACC constructs and clauses.
This file declares semantic analysis for OpenMP constructs and clauses.
This file declares semantic analysis for SYCL constructs.
const clang::PrintingPolicy & getPrintingPolicy() const
One specifier in an @available expression.
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
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.
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.
CompoundStmt - This represents a group of statements like { stmt stmt }.
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...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isFileContext() const
Captures information about "declaration specifiers".
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.
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
ExtensionRAIIObject - This saves the state of extension warnings when constructed and disables them.
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.
bool hasRevertedTokenIDToIdentifier() const
True if revertTokenIDToIdentifier() was called.
StringRef getName() const
Return the actual identifier string.
Represents the declaration of a label.
static StringRef getImmediateMacroNameForDiagnostics(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
This represents a decl that may have a name.
void * getAsOpaquePtr() const
static const ParsedAttributesView & none()
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.
Sema & getActions() const
static TypeResult getTypeAnnotation(const Token &Tok)
getTypeAnnotation - Read a parsed type out of an annotation token.
ExprResult ParseCaseExpression(SourceLocation CaseLoc)
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.
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
ExprResult ParseConstantExpression()
ExprResult ParseConditionalExpression()
bool TryConsumeToken(tok::TokenKind Expected)
Scope * getCurScope() const
ExprResult ParseArrayBoundExpression()
ExprResult ParseConstraintLogicalAndExpression(bool IsTrailingRequiresClause)
Parse a constraint-logical-and-expression.
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.
ExprResult ParseConstantExpressionInExprEvalContext(TypeCastState isTypeCast=NotTypeCast)
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.
bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
TypeCastState
TypeCastState - State whether an expression is or may be a type cast.
ExprResult ParseUnevaluatedStringLiteralExpression()
ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral=false)
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
ExprResult ParseConstraintExpression()
Parse a constraint-expression.
void enterSubscript(Sema &S, SourceLocation Tok, Expr *LHS)
void enterUnary(Sema &S, SourceLocation Tok, tok::TokenKind OpKind, SourceLocation OpLoc)
void enterBinary(Sema &S, SourceLocation Tok, Expr *LHS, tok::TokenKind Op)
QualType get(SourceLocation Tok) const
Get the expected type associated with this location, if any.
void EnterToken(const Token &Tok, bool IsReinject)
Enters a token in the token stream to be lexed next.
SourceManager & getSourceManager() const
llvm::BumpPtrAllocator & getPreprocessorAllocator()
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
bool isAtStartOfMacroExpansion(SourceLocation loc, SourceLocation *MacroBegin=nullptr) const
Returns true if the given MacroID location points at the first token of the macro expansion.
bool isCodeCompletionReached() const
Returns true if code-completion is enabled and we have hit the code-completion point.
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.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
@ BlockScope
This is a scope that corresponds to a block/closure object.
@ CompoundStmtScope
This is a compound statement scope.
@ 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.
ExprResult ActOnExecConfigExpr(Scope *S, SourceLocation LLLLoc, MultiExprArg ExecConfig, SourceLocation GGGLoc)
@ PCC_Type
Code completion occurs where only a type is permitted.
void CodeCompleteExpression(Scope *S, const CodeCompleteExpressionData &Data)
Perform code-completion in an expression context when we know what type we're looking for.
QualType ProduceCallSignatureHelp(Expr *Fn, ArrayRef< Expr * > Args, SourceLocation OpenParLoc)
Determines the preferred type of the current function argument, by examining the signatures of all po...
void CodeCompleteOrdinaryName(Scope *S, ParserCompletionContext CompletionContext)
void CodeCompleteObjCClassPropertyRefExpr(Scope *S, const IdentifierInfo &ClassName, SourceLocation ClassNameLoc, bool IsBaseExprStatement)
void CodeCompleteAvailabilityPlatformName()
void CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, Expr *OtherOpBase, SourceLocation OpLoc, bool IsArrow, bool IsBaseExprStatement, QualType PreferredType)
void CodeCompletePostfixExpression(Scope *S, ExprResult LHS, QualType PreferredType)
ExprResult ActOnObjCBridgedCast(Scope *S, SourceLocation LParenLoc, ObjCBridgeCastKind Kind, SourceLocation BridgeKeywordLoc, ParsedType Type, SourceLocation RParenLoc, Expr *SubExpr)
ExprResult ActOnClassPropertyRefExpr(const IdentifierInfo &receiverName, const IdentifierInfo &propertyName, SourceLocation receiverNameLoc, SourceLocation propertyNameLoc)
ExprResult ActOnObjCBoolLiteral(SourceLocation AtLoc, SourceLocation ValueLoc, bool Value)
ExprResult ActOnObjCAvailabilityCheckExpr(llvm::ArrayRef< AvailabilitySpec > AvailSpecs, SourceLocation AtLoc, SourceLocation RParen)
ExprResult ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc, Expr *LowerBound, SourceLocation ColonLocFirst, Expr *Length, SourceLocation RBLoc)
Checks and creates an Array Section used in an OpenACC construct/clause.
ExprResult ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, Expr *LowerBound, SourceLocation ColonLocFirst, SourceLocation ColonLocSecond, Expr *Length, Expr *Stride, SourceLocation RBLoc)
ExprResult ActOnOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc, SourceLocation RParenLoc, ArrayRef< Expr * > Dims, ArrayRef< SourceRange > Brackets)
ExprResult ActOnUniqueStableNameExpr(SourceLocation OpLoc, SourceLocation LParen, SourceLocation RParen, ParsedType ParsedTy)
RAII class used to indicate that we are performing provisional semantic analysis to determine the val...
ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Op, Expr *Input, bool IsAfterAmp=false)
Unary Operators. 'Tok' is the token for the operator.
ExprResult ActOnConstantExpression(ExprResult Res)
ExprResult ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation LParen, Expr *Operand, SourceLocation RParen)
ExprResult ActOnCompoundLiteral(SourceLocation LParenLoc, ParsedType Ty, SourceLocation RParenLoc, Expr *InitExpr)
void ActOnStartStmtExpr()
void ActOnStmtExprError()
ExprResult ActOnIdExpression(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand, CorrectionCandidateCallback *CCC=nullptr, bool IsInlineAsmIdentifier=false, Token *KeywordReplacement=nullptr)
ExprResult ActOnCharacterConstant(const Token &Tok, Scope *UDLScope=nullptr)
ExprResult ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, ParsedType &ObjectType, bool &MayBePseudoDestructor)
ExprResult ActOnCaseExpr(SourceLocation CaseLoc, ExprResult Val)
ExprResult ActOnCXXNullPtrLiteral(SourceLocation Loc)
ActOnCXXNullPtrLiteral - Parse 'nullptr'.
bool CheckConstraintExpression(const Expr *CE, Token NextToken=Token(), bool *PossibleNonPrimary=nullptr, bool IsTrailingRequiresClause=false)
Check whether the given expression is a valid constraint expression.
ASTContext & getASTContext() const
ExprResult ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc, LabelDecl *TheDecl)
ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
ExprResult ActOnParenListExpr(SourceLocation L, SourceLocation R, MultiExprArg Val)
ExprResult ActOnChooseExpr(SourceLocation BuiltinLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr, SourceLocation RPLoc)
ExprResult ActOnUnevaluatedStringLiteral(ArrayRef< Token > StringToks)
SourceRange getExprRange(Expr *E) const
SemaCodeCompletion & CodeCompletion()
ExprResult ActOnCoawaitExpr(Scope *S, SourceLocation KwLoc, Expr *E)
ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Member, Decl *ObjCImpDecl)
The main callback when the parser finds something like expression .
ExprResult ActOnGenericSelectionExpr(SourceLocation KeyLoc, SourceLocation DefaultLoc, SourceLocation RParenLoc, bool PredicateIsExpr, void *ControllingExprOrType, ArrayRef< ParsedType > ArgTypes, ArrayRef< Expr * > ArgExprs)
ControllingExprOrType is either an opaque pointer coming out of a ParsedType or an Expr *.
void ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope)
ActOnBlockError - If there is an error parsing a block, this callback is invoked to pop the informati...
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
ExprResult ActOnGNUNullExpr(SourceLocation TokenLoc)
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
ExprResult ActOnSourceLocExpr(SourceLocIdentKind Kind, SourceLocation BuiltinLoc, SourceLocation RPLoc)
ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr)
ActOnConditionalOp - Parse a ?: operation.
LabelDecl * LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc, SourceLocation GnuLabelLoc=SourceLocation())
LookupOrCreateLabel - Do a name lookup of a label with the specified name.
TypeResult ActOnTypeName(Declarator &D)
ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, SourceLocation EllipsisLoc)
Invoked when parsing a template argument followed by an ellipsis, which creates a pack expansion.
ExprResult ActOnStringLiteral(ArrayRef< Token > StringToks, Scope *UDLScope=nullptr)
ActOnStringLiteral - The specified tokens were lexed as pasted string fragments (e....
ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr)
Binary Operators. 'Tok' is the token for the operator.
ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS=nullptr, bool isClassName=false, bool HasTrailingDot=false, ParsedType ObjectType=nullptr, bool IsCtorOrDtorName=false, bool WantNontrivialTypeSourceInfo=false, bool IsClassTemplateDeductionContext=true, ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No, IdentifierInfo **CorrectedII=nullptr)
If the identifier refers to a type name within this scope, return the declaration of that type.
ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind)
@ ConstantEvaluated
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
ExprResult ActOnAsTypeExpr(Expr *E, ParsedType ParsedDestTy, SourceLocation BuiltinLoc, SourceLocation RParenLoc)
Parse a __builtin_astype expression.
ExprResult ActOnVAArg(SourceLocation BuiltinLoc, Expr *E, ParsedType Ty, SourceLocation RPLoc)
ExprResult ActOnCastExpr(Scope *S, SourceLocation LParenLoc, Declarator &D, ParsedType &Ty, SourceLocation RParenLoc, Expr *CastExpr)
SmallVector< ExpressionEvaluationContextRecord, 8 > ExprEvalContexts
A stack of expression evaluation contexts.
ExprResult ActOnSizeofParameterPackExpr(Scope *S, SourceLocation OpLoc, IdentifierInfo &Name, SourceLocation NameLoc, SourceLocation RParenLoc)
Called when an expression computing the size of a parameter pack is parsed.
ExprResult ActOnStmtExpr(Scope *S, SourceLocation LPLoc, Stmt *SubStmt, SourceLocation RPLoc)
ExprResult ActOnCXXFoldExpr(Scope *S, SourceLocation LParenLoc, Expr *LHS, tok::TokenKind Operator, SourceLocation EllipsisLoc, Expr *RHS, SourceLocation RParenLoc)
Handle a C++1z fold-expression: ( expr op ... op expr ).
ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, Stmt *Body, Scope *CurScope)
ActOnBlockStmtExpr - This is called when the body of a block statement literal was successfully compl...
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
ExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Kind, Expr *Input)
ExprResult CreateRecoveryExpr(SourceLocation Begin, SourceLocation End, ArrayRef< Expr * > SubExprs, QualType T=QualType())
Attempts to produce a RecoveryExpr after some AST node cannot be created.
ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope=nullptr)
void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope)
ActOnBlockStart - This callback is invoked when a block literal is started.
ExprResult ActOnArraySubscriptExpr(Scope *S, Expr *Base, SourceLocation LLoc, MultiExprArg ArgExprs, SourceLocation RLoc)
ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr)
ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
ExprResult ActOnUnaryExprOrTypeTraitExpr(SourceLocation OpLoc, UnaryExprOrTypeTrait ExprKind, bool IsType, void *TyOrEx, SourceRange ArgRange)
ActOnUnaryExprOrTypeTraitExpr - Handle sizeof(type) and sizeof expr and the same for alignof and __al...
void ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo, Scope *CurScope)
ActOnBlockArguments - This callback allows processing of block arguments.
ExprResult ActOnConvertVectorExpr(Expr *E, ParsedType ParsedDestTy, SourceLocation BuiltinLoc, SourceLocation RParenLoc)
ActOnConvertVectorExpr - create a new convert-vector expression from the provided arguments.
ExprResult ActOnBuiltinOffsetOf(Scope *S, SourceLocation BuiltinLoc, SourceLocation TypeLoc, ParsedType ParsedArgTy, ArrayRef< OffsetOfComponent > Components, SourceLocation RParenLoc)
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...
ExprResult ActOnNameClassifiedAsOverloadSet(Scope *S, Expr *OverloadSet)
Act on the result of classifying a name as an overload set.
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.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
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.
const char * getName() const
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 isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
bool isNot(tok::TokenKind K) const
bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const
Return true if we have an ObjC keyword identifier.
bool isSimpleTypeSpecifier(const LangOptions &LangOpts) const
Determine whether the token kind starts a simple-type-specifier.
SourceLocation getLastLoc() const
Base wrapper for a particular "section" of type source info.
The base class of the type hierarchy.
bool isSpecificPlaceholderType(unsigned K) const
Test for a specific placeholder type.
bool isFunctionType() const
bool isVectorType() const
Simple class containing the result of Sema::CorrectTypo.
NamedDecl * getCorrectionDecl() const
Gets the pointer to the declaration of the typo correction.
Represents a C++ unqualified-id that has been parsed.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
The JSON file list parser is used to communicate input to InstallAPI.
bool tokenIsLikeStringLiteral(const Token &Tok, const LangOptions &LO)
Return true if the token is a string literal, or a function local predefined macro,...
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
@ Result
The result type of a method or function.
ObjCBridgeCastKind
The kind of bridging performed by the Objective-C bridge cast.
@ OBC_Bridge
Bridging via __bridge, which does nothing but reinterpret the bits.
@ OBC_BridgeTransfer
Bridging via __bridge_transfer, which transfers ownership of an Objective-C pointer into ARC.
@ OBC_BridgeRetained
Bridging via __bridge_retain, which makes an ARC object available as a +1 C pointer.
ActionResult< Expr * > ExprResult
prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator, bool CPlusPlus11)
Return the precedence of the specified binary operator token.
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
const FunctionProtoType * T
@ Parens
New-expression has a C++98 paren-delimited initializer.
@ 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.
Helper class to shuttle information about #embed directives from the preprocessor to the parser throu...
Wraps an identifier and optional source location for the identifier.
Information about a template-id annotation token.
TemplateNameKind Kind
The kind of template that Template refers to.