clang: lib/Parse/ParseStmt.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
30#include "llvm/ADT/STLExtras.h"
31#include
32
33using namespace clang;
34
35
36
37
38
39
40
42 ParsedStmtContext StmtCtx) {
44
45
46
48 do {
49 Res = ParseStatementOrDeclaration(Stmts, StmtCtx, TrailingElseLoc);
51
52 return Res;
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
105Parser::ParseStatementOrDeclaration(StmtVector &Stmts,
106 ParsedStmtContext StmtCtx,
108
110
111
112
113
114
115
117 MaybeParseCXX11Attributes(CXX11Attrs, true);
120 MaybeParseGNUAttributes(GNUOrMSAttrs);
121
123 MaybeParseMicrosoftAttributes(GNUOrMSAttrs);
124
125 StmtResult Res = ParseStatementOrDeclarationAfterAttributes(
126 Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs, GNUOrMSAttrs);
127 MaybeDestroyTemplateIds();
128
129
130
133
135 "attributes on empty statement");
136
137 if (Attrs.empty() || Res.isInvalid())
138 return Res;
139
141}
142
143namespace {
145public:
146 StatementFilterCCC(Token nextTok) : NextToken(nextTok) {
147 WantTypeSpecifiers = nextTok.isOneOf(tok::l_paren, tok::less, tok::l_square,
148 tok::identifier, tok::star, tok::amp);
149 WantExpressionKeywords =
150 nextTok.isOneOf(tok::l_paren, tok::identifier, tok::arrow, tok::period);
151 WantRemainingKeywords =
152 nextTok.isOneOf(tok::l_paren, tok::semi, tok::identifier, tok::l_brace);
153 WantCXXNamedCasts = false;
154 }
155
156 bool ValidateCandidate(const TypoCorrection &candidate) override {
159 if (NextToken.is(tok::equal))
161 if (NextToken.is(tok::period) &&
163 return false;
165 }
166
167 std::unique_ptr clone() override {
168 return std::make_unique(*this);
169 }
170
171private:
173};
174}
175
176StmtResult Parser::ParseStatementOrDeclarationAfterAttributes(
177 StmtVector &Stmts, ParsedStmtContext StmtCtx,
180 const char *SemiError = nullptr;
183
184
185
186
187Retry:
190 switch (Kind) {
191 case tok::at:
192 {
194 return ParseObjCAtStatement(AtLoc, StmtCtx);
195 }
196
197 case tok::code_completion:
198 cutOffParsing();
202
203 case tok::identifier:
204 ParseIdentifier: {
206 if (Next.is(tok::colon)) {
207
208
209
212
213
214 return ParseLabeledStatement(Attrs, StmtCtx);
215 }
216
217
218
219 if (Next.isNot(tok::coloncolon)) {
220
221
222 StatementFilterCCC CCC(Next);
223 if (TryAnnotateName(&CCC) == ANK_Error) {
224
225
227 if (Tok.is(tok::semi))
230 }
231
232
233 if (Tok.isNot(tok::identifier))
234 goto Retry;
235 }
236
237
238 [[fallthrough]];
239 }
240
241 default: {
242 bool HaveAttrs = !CXX11Attrs.empty() || !GNUAttrs.empty();
243 auto IsStmtAttr = [](ParsedAttr &Attr) { return Attr.isStmtAttr(); };
244 bool AllAttrsAreStmtAttrs = llvm::all_of(CXX11Attrs, IsStmtAttr) &&
245 llvm::all_of(GNUAttrs, IsStmtAttr);
246
247
248
249
250
252 (StmtCtx & ParsedStmtContext::AllowDeclarationsInC) !=
253 ParsedStmtContext()) &&
254 ((GNUAttributeLoc.isValid() && !(HaveAttrs && AllAttrsAreStmtAttrs)) ||
255 isDeclarationStatement())) {
258 if (GNUAttributeLoc.isValid()) {
259 DeclStart = GNUAttributeLoc;
261 GNUAttrs, &GNUAttributeLoc);
262 } else {
264 GNUAttrs);
265 }
267
268
275 }
276
277 if (Tok.is(tok::r_brace)) {
278 Diag(Tok, diag::err_expected_statement);
280 }
281
283#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
284#include "clang/Basic/TransformTypeTraits.def"
286 Tok.setKind(tok::identifier);
287 Diag(Tok, diag::ext_keyword_as_ident)
289 goto ParseIdentifier;
290 }
291 [[fallthrough]];
292 default:
293 return ParseExprStatement(StmtCtx);
294 }
295 }
296
297 case tok::kw___attribute: {
299 ParseGNUAttributes(GNUAttrs);
300 goto Retry;
301 }
302
303 case tok::kw_template: {
307 Attrs,
308 getAccessSpecifierIfPresent());
310 }
311
312 case tok::kw_case:
313 return ParseCaseStatement(StmtCtx);
314 case tok::kw_default:
315 return ParseDefaultStatement(StmtCtx);
316
317 case tok::l_brace:
318 return ParseCompoundStatement();
319 case tok:🚛 {
322 }
323
324 case tok::kw_if:
325 return ParseIfStatement(TrailingElseLoc);
326 case tok::kw_switch:
327 return ParseSwitchStatement(TrailingElseLoc);
328
329 case tok::kw_while:
330 return ParseWhileStatement(TrailingElseLoc);
331 case tok::kw_do:
332 Res = ParseDoStatement();
333 SemiError = "do/while";
334 break;
335 case tok::kw_for:
336 return ParseForStatement(TrailingElseLoc);
337
338 case tok::kw_goto:
339 Res = ParseGotoStatement();
340 SemiError = "goto";
341 break;
342 case tok::kw_continue:
343 Res = ParseContinueStatement();
344 SemiError = "continue";
345 break;
346 case tok::kw_break:
347 Res = ParseBreakStatement();
348 SemiError = "break";
349 break;
350 case tok::kw_return:
351 Res = ParseReturnStatement();
352 SemiError = "return";
353 break;
354 case tok::kw_co_return:
355 Res = ParseReturnStatement();
356 SemiError = "co_return";
357 break;
358
359 case tok::kw_asm: {
360 for (const ParsedAttr &AL : CXX11Attrs)
361
362
363 (AL.isRegularKeywordAttribute()
364 ? Diag(AL.getRange().getBegin(), diag::err_keyword_not_allowed)
365 : Diag(AL.getRange().getBegin(), diag::warn_attribute_ignored))
366 << AL;
367
368 CXX11Attrs.clear();
369 ProhibitAttributes(GNUAttrs);
370 bool msAsm = false;
371 Res = ParseAsmStatement(msAsm);
372 if (msAsm) return Res;
373 SemiError = "asm";
374 break;
375 }
376
377 case tok::kw___if_exists:
378 case tok::kw___if_not_exists:
379 ProhibitAttributes(CXX11Attrs);
380 ProhibitAttributes(GNUAttrs);
381 ParseMicrosoftIfExistsStatement(Stmts);
382
383
385
386 case tok::kw_try:
387 return ParseCXXTryBlock();
388
389 case tok::kw___try:
390 ProhibitAttributes(CXX11Attrs);
391 ProhibitAttributes(GNUAttrs);
392 return ParseSEHTryBlock();
393
394 case tok::kw___leave:
395 Res = ParseSEHLeaveStatement();
396 SemiError = "__leave";
397 break;
398
399 case tok::annot_pragma_vis:
400 ProhibitAttributes(CXX11Attrs);
401 ProhibitAttributes(GNUAttrs);
402 HandlePragmaVisibility();
404
405 case tok::annot_pragma_pack:
406 ProhibitAttributes(CXX11Attrs);
407 ProhibitAttributes(GNUAttrs);
408 HandlePragmaPack();
410
411 case tok::annot_pragma_msstruct:
412 ProhibitAttributes(CXX11Attrs);
413 ProhibitAttributes(GNUAttrs);
414 HandlePragmaMSStruct();
416
417 case tok::annot_pragma_align:
418 ProhibitAttributes(CXX11Attrs);
419 ProhibitAttributes(GNUAttrs);
420 HandlePragmaAlign();
422
423 case tok::annot_pragma_weak:
424 ProhibitAttributes(CXX11Attrs);
425 ProhibitAttributes(GNUAttrs);
426 HandlePragmaWeak();
428
429 case tok::annot_pragma_weakalias:
430 ProhibitAttributes(CXX11Attrs);
431 ProhibitAttributes(GNUAttrs);
432 HandlePragmaWeakAlias();
434
435 case tok::annot_pragma_redefine_extname:
436 ProhibitAttributes(CXX11Attrs);
437 ProhibitAttributes(GNUAttrs);
438 HandlePragmaRedefineExtname();
440
441 case tok::annot_pragma_fp_contract:
442 ProhibitAttributes(CXX11Attrs);
443 ProhibitAttributes(GNUAttrs);
444 Diag(Tok, diag::err_pragma_file_or_compound_scope) << "fp_contract";
445 ConsumeAnnotationToken();
447
448 case tok::annot_pragma_fp:
449 ProhibitAttributes(CXX11Attrs);
450 ProhibitAttributes(GNUAttrs);
451 Diag(Tok, diag::err_pragma_file_or_compound_scope) << "clang fp";
452 ConsumeAnnotationToken();
454
455 case tok::annot_pragma_fenv_access:
456 case tok::annot_pragma_fenv_access_ms:
457 ProhibitAttributes(CXX11Attrs);
458 ProhibitAttributes(GNUAttrs);
459 Diag(Tok, diag::err_pragma_file_or_compound_scope)
460 << (Kind == tok::annot_pragma_fenv_access ? "STDC FENV_ACCESS"
461 : "fenv_access");
462 ConsumeAnnotationToken();
464
465 case tok::annot_pragma_fenv_round:
466 ProhibitAttributes(CXX11Attrs);
467 ProhibitAttributes(GNUAttrs);
468 Diag(Tok, diag::err_pragma_file_or_compound_scope) << "STDC FENV_ROUND";
469 ConsumeAnnotationToken();
471
472 case tok::annot_pragma_cx_limited_range:
473 ProhibitAttributes(CXX11Attrs);
474 ProhibitAttributes(GNUAttrs);
475 Diag(Tok, diag::err_pragma_file_or_compound_scope)
476 << "STDC CX_LIMITED_RANGE";
477 ConsumeAnnotationToken();
479
480 case tok::annot_pragma_float_control:
481 ProhibitAttributes(CXX11Attrs);
482 ProhibitAttributes(GNUAttrs);
483 Diag(Tok, diag::err_pragma_file_or_compound_scope) << "float_control";
484 ConsumeAnnotationToken();
486
487 case tok::annot_pragma_opencl_extension:
488 ProhibitAttributes(CXX11Attrs);
489 ProhibitAttributes(GNUAttrs);
490 HandlePragmaOpenCLExtension();
492
493 case tok::annot_pragma_captured:
494 ProhibitAttributes(CXX11Attrs);
495 ProhibitAttributes(GNUAttrs);
496 return HandlePragmaCaptured();
497
498 case tok::annot_pragma_openmp:
499
500
501 ProhibitAttributes(CXX11Attrs);
502 ProhibitAttributes(GNUAttrs);
503 [[fallthrough]];
504 case tok::annot_attr_openmp:
505
506 return ParseOpenMPDeclarativeOrExecutableDirective(StmtCtx);
507
508 case tok::annot_pragma_openacc:
510
511 case tok::annot_pragma_ms_pointers_to_members:
512 ProhibitAttributes(CXX11Attrs);
513 ProhibitAttributes(GNUAttrs);
514 HandlePragmaMSPointersToMembers();
516
517 case tok::annot_pragma_ms_pragma:
518 ProhibitAttributes(CXX11Attrs);
519 ProhibitAttributes(GNUAttrs);
520 HandlePragmaMSPragma();
522
523 case tok::annot_pragma_ms_vtordisp:
524 ProhibitAttributes(CXX11Attrs);
525 ProhibitAttributes(GNUAttrs);
526 HandlePragmaMSVtorDisp();
528
529 case tok::annot_pragma_loop_hint:
530 ProhibitAttributes(CXX11Attrs);
531 ProhibitAttributes(GNUAttrs);
532 return ParsePragmaLoopHint(Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs);
533
534 case tok::annot_pragma_dump:
535 HandlePragmaDump();
537
538 case tok::annot_pragma_attribute:
539 HandlePragmaAttribute();
541 }
542
543
545
546
547
548 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt, SemiError);
549
551 }
552
553 return Res;
554}
555
556
557StmtResult Parser::ParseExprStatement(ParsedStmtContext StmtCtx) {
558
559 Token OldToken = Tok;
560
562
563
565 if (Expr.isInvalid()) {
566
567
568
570 if (Tok.is(tok::semi))
573 }
574
575 if (Tok.is(tok::colon) && getCurScope()->isSwitchScope() &&
577
578
579 Diag(OldToken, diag::err_expected_case_before_expression)
581
582
583 return ParseCaseStatement(StmtCtx, true, Expr);
584 }
585
586 Token *CurTok = nullptr;
587
588 if (Tok.is(tok::annot_repl_input_end))
589 CurTok = &Tok;
590 else
591
592 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
593
597
598 return R;
599}
600
601
602
603
604
605
606
607
608
609
610StmtResult Parser::ParseSEHTryBlock() {
611 assert(Tok.is(tok::kw___try) && "Expected '__try'");
613
614 if (Tok.isNot(tok::l_brace))
615 return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
616
617 StmtResult TryBlock(ParseCompoundStatement(
618 false,
620 if (TryBlock.isInvalid())
621 return TryBlock;
622
624 if (Tok.is(tok::identifier) &&
627 Handler = ParseSEHExceptBlock(Loc);
628 } else if (Tok.is(tok::kw___finally)) {
630 Handler = ParseSEHFinallyBlock(Loc);
631 } else {
632 return StmtError(Diag(Tok, diag::err_seh_expected_handler));
633 }
634
636 return Handler;
637
639 TryLoc,
640 TryBlock.get(),
641 Handler.get());
642}
643
644
645
646
647
648
651 raii2(Ident___exception_code, false),
652 raii3(Ident_GetExceptionCode, false);
653
654 if (ExpectAndConsume(tok::l_paren))
656
659
664 }
665
667 {
668 ParseScopeFlags FilterScope(this, getCurScope()->getFlags() |
671 }
672
677 }
678
681
682 if (ExpectAndConsume(tok::r_paren))
684
685 if (Tok.isNot(tok::l_brace))
686 return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
687
689
690 if(Block.isInvalid())
692
694}
695
696
697
698
699
700
703 raii2(Ident___abnormal_termination, false),
704 raii3(Ident_AbnormalTermination, false);
705
706 if (Tok.isNot(tok::l_brace))
707 return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
708
709 ParseScope FinallyScope(this, 0);
711
713 if(Block.isInvalid()) {
716 }
717
719}
720
721
722
723
724
725
726StmtResult Parser::ParseSEHLeaveStatement() {
729}
730
732
733
734 if (.getLangOpts().CPlusPlus &&
.getLangOpts().MicrosoftExt &&
735 isa(SubStmt)) {
737 P.getLangOpts().C23
738 ? diag::warn_c23_compat_label_followed_by_declaration
739 : diag::ext_c_label_followed_by_declaration);
740 }
741}
742
743
744
745
746
747
748
749
750
751
753 ParsedStmtContext StmtCtx) {
755 "Not an identifier!");
756
757
758
759
760 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
761
762 Token IdentTok = Tok;
764
765 assert(Tok.is(tok::colon) && "Not a label!");
766
767
769
770
772 if (Tok.is(tok::kw___attribute)) {
774 ParseGNUAttributes(TempAttrs);
775
776
777
778
779
780
781
782
785 else {
788 SubStmt = ParseStatementOrDeclarationAfterAttributes(
789 Stmts, StmtCtx, nullptr, EmptyCXX11Attrs, TempAttrs);
790 if (!TempAttrs.empty() && !SubStmt.isInvalid())
792 }
793 }
794
795
796 if (SubStmt.isUnset() && Tok.is(tok::r_brace)) {
797 DiagnoseLabelAtEndOfCompoundStatement();
799 }
800
801
803 SubStmt = ParseStatement(nullptr, StmtCtx);
804
805
808
810
815
817 SubStmt.get());
818}
819
820
821
822
823
824
825StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx,
827 assert((MissingCase || Tok.is(tok::kw_case)) && "Not a case stmt!");
828
829
830
831
832 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
851
852
853
854
855 Stmt *DeepestParsedCaseStmt = nullptr;
856
857
859 do {
863
864 if (Tok.is(tok::code_completion)) {
865 cutOffParsing();
868 }
869
870
871
872
874
876 if (!MissingCase) {
879
880
883 }
884 } else {
886 MissingCase = false;
887 }
888
889
893
894 unsigned DiagId;
896 DiagId = diag::ext_gnu_case_range;
898 DiagId = diag::warn_c23_compat_case_range;
899 else
900 DiagId = diag::ext_c2y_case_range;
901 Diag(DotDotDotLoc, DiagId);
906 }
907 }
908
909 ColonProtection.restore();
910
914
915 Diag(ColonLoc, diag::err_expected_after)
916 << "'case'" << tok::colon
918 } else {
920 Diag(ExpectedLoc, diag::err_expected_after)
921 << "'case'" << tok::colon
923 ColonLoc = ExpectedLoc;
924 }
925
927 Actions.ActOnCaseStmt(CaseLoc, LHS, DotDotDotLoc, RHS, ColonLoc);
928
929
930
932 if (TopLevelCase.isInvalid())
933 return ParseStatement(nullptr, StmtCtx);
934
935 } else {
936
937
938 Stmt *NextDeepest = Case.get();
939 if (TopLevelCase.isInvalid())
940 TopLevelCase = Case;
941 else
943 DeepestParsedCaseStmt = NextDeepest;
944 }
945
946
947 } while (Tok.is(tok::kw_case));
948
949
951
952 if (Tok.is(tok::r_brace)) {
953
954
955 DiagnoseLabelAtEndOfCompoundStatement();
957 } else {
958 SubStmt = ParseStatement(nullptr, StmtCtx);
959 }
960
961
962 if (DeepestParsedCaseStmt) {
963
968 }
969
970
971 return TopLevelCase;
972}
973
974
975
976
977
978
979StmtResult Parser::ParseDefaultStatement(ParsedStmtContext StmtCtx) {
980 assert(Tok.is(tok::kw_default) && "Not a default stmt!");
981
982
983
984
985 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
986
988
992
993 Diag(ColonLoc, diag::err_expected_after)
994 << "'default'" << tok::colon
996 } else {
998 Diag(ExpectedLoc, diag::err_expected_after)
999 << "'default'" << tok::colon
1001 ColonLoc = ExpectedLoc;
1002 }
1003
1005
1006 if (Tok.is(tok::r_brace)) {
1007
1008
1009 DiagnoseLabelAtEndOfCompoundStatement();
1011 } else {
1012 SubStmt = ParseStatement(nullptr, StmtCtx);
1013 }
1014
1015
1018
1022}
1023
1024StmtResult Parser::ParseCompoundStatement(bool isStmtExpr) {
1025 return ParseCompoundStatement(isStmtExpr,
1027}
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051StmtResult Parser::ParseCompoundStatement(bool isStmtExpr,
1052 unsigned ScopeFlags) {
1053 assert(Tok.is(tok::l_brace) && "Not a compound stmt!");
1054
1055
1056
1057 ParseScope CompoundScope(this, ScopeFlags);
1058
1059
1060 return ParseCompoundStatementBody(isStmtExpr);
1061}
1062
1063
1064
1065
1066void Parser::ParseCompoundStatementLeadingPragmas() {
1067 bool checkForPragmas = true;
1068 while (checkForPragmas) {
1069 switch (Tok.getKind()) {
1070 case tok::annot_pragma_vis:
1071 HandlePragmaVisibility();
1072 break;
1073 case tok::annot_pragma_pack:
1074 HandlePragmaPack();
1075 break;
1076 case tok::annot_pragma_msstruct:
1077 HandlePragmaMSStruct();
1078 break;
1079 case tok::annot_pragma_align:
1080 HandlePragmaAlign();
1081 break;
1082 case tok::annot_pragma_weak:
1083 HandlePragmaWeak();
1084 break;
1085 case tok::annot_pragma_weakalias:
1086 HandlePragmaWeakAlias();
1087 break;
1088 case tok::annot_pragma_redefine_extname:
1089 HandlePragmaRedefineExtname();
1090 break;
1091 case tok::annot_pragma_opencl_extension:
1092 HandlePragmaOpenCLExtension();
1093 break;
1094 case tok::annot_pragma_fp_contract:
1095 HandlePragmaFPContract();
1096 break;
1097 case tok::annot_pragma_fp:
1098 HandlePragmaFP();
1099 break;
1100 case tok::annot_pragma_fenv_access:
1101 case tok::annot_pragma_fenv_access_ms:
1102 HandlePragmaFEnvAccess();
1103 break;
1104 case tok::annot_pragma_fenv_round:
1105 HandlePragmaFEnvRound();
1106 break;
1107 case tok::annot_pragma_cx_limited_range:
1108 HandlePragmaCXLimitedRange();
1109 break;
1110 case tok::annot_pragma_float_control:
1111 HandlePragmaFloatControl();
1112 break;
1113 case tok::annot_pragma_ms_pointers_to_members:
1114 HandlePragmaMSPointersToMembers();
1115 break;
1116 case tok::annot_pragma_ms_pragma:
1117 HandlePragmaMSPragma();
1118 break;
1119 case tok::annot_pragma_ms_vtordisp:
1120 HandlePragmaMSVtorDisp();
1121 break;
1122 case tok::annot_pragma_dump:
1123 HandlePragmaDump();
1124 break;
1125 default:
1126 checkForPragmas = false;
1127 break;
1128 }
1129 }
1130
1131}
1132
1133void Parser::DiagnoseLabelAtEndOfCompoundStatement() {
1136 ? diag::warn_cxx20_compat_label_end_of_compound_statement
1137 : diag::ext_cxx_label_end_of_compound_statement);
1138 } else {
1140 ? diag::warn_c23_compat_label_end_of_compound_statement
1141 : diag::ext_c_label_end_of_compound_statement);
1142 }
1143}
1144
1145
1146
1147bool Parser::ConsumeNullStmt(StmtVector &Stmts) {
1148 if (!Tok.is(tok::semi))
1149 return false;
1150
1153
1157
1158
1160 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::SubStmt);
1162 Stmts.push_back(R.get());
1163 }
1164
1165
1167 return false;
1168
1169 Diag(StartLoc, diag::warn_null_statement)
1171 return true;
1172}
1173
1175 bool IsStmtExprResult = false;
1176 if ((StmtCtx & ParsedStmtContext::InStmtExpr) != ParsedStmtContext()) {
1177
1178 unsigned LookAhead = 0;
1179 while (GetLookAheadToken(LookAhead).is(tok::semi)) {
1180 ++LookAhead;
1181 }
1182
1183
1184
1185 IsStmtExprResult = GetLookAheadToken(LookAhead).is(tok::r_brace) &&
1186 GetLookAheadToken(LookAhead + 1).is(tok::r_paren);
1187 }
1188
1189 if (IsStmtExprResult)
1191 return Actions.ActOnExprStmt(E, !IsStmtExprResult);
1192}
1193
1194
1195
1196
1197
1198StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
1201 "in compound statement ('{}')");
1202
1203
1204
1206
1209 if (T.consumeOpen())
1211
1213
1214
1215 ParseCompoundStatementLeadingPragmas();
1217
1219
1220
1221
1222 while (Tok.is(tok::kw___label__)) {
1224
1226 while (true) {
1227 if (Tok.isNot(tok::identifier)) {
1228 Diag(Tok, diag::err_expected) << tok::identifier;
1229 break;
1230 }
1231
1234 DeclsInGroup.push_back(Actions.LookupOrCreateLabel(II, IdLoc, LabelLoc));
1235
1237 break;
1238 }
1239
1244
1245 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
1247 Stmts.push_back(R.get());
1248 }
1249
1250 ParsedStmtContext SubStmtCtx =
1251 ParsedStmtContext::Compound |
1252 (isStmtExpr ? ParsedStmtContext::InStmtExpr : ParsedStmtContext());
1253
1254 bool LastIsError = false;
1255 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
1256 Tok.isNot(tok::eof)) {
1257 if (Tok.is(tok::annot_pragma_unused)) {
1258 HandlePragmaUnused();
1259 continue;
1260 }
1261
1262 if (ConsumeNullStmt(Stmts))
1263 continue;
1264
1266 if (Tok.isNot(tok::kw___extension__)) {
1267 R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
1268 } else {
1269
1270
1271
1272
1274 while (Tok.is(tok::kw___extension__))
1276
1278 MaybeParseCXX11Attributes(attrs, true);
1279
1280
1281 if (isDeclarationStatement()) {
1282
1283
1285
1289 attrs, DeclSpecAttrs);
1290 R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);
1291 } else {
1292
1293 ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
1294
1295 if (Res.isInvalid()) {
1297 continue;
1298 }
1299
1300
1301
1302 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
1303 R = handleExprStmt(Res, SubStmtCtx);
1306 }
1307 }
1308
1310 Stmts.push_back(R.get());
1312 }
1313
1314
1315
1316
1317 if (isStmtExpr && LastIsError && !Stmts.empty())
1319
1320
1321
1322
1323
1329 diag::warn_no_support_for_eval_method_source_on_m32);
1330
1332
1333
1334 if (.consumeClose()) {
1335
1336
1337 if (isStmtExpr && Tok.is(tok::r_paren))
1338 checkCompoundToken(CloseLoc, tok::r_brace, CompoundToken::StmtExprEnd);
1339 } else {
1340
1341
1342 }
1343
1344 if (T.getCloseLocation().isValid())
1345 CloseLoc = T.getCloseLocation();
1346
1348 Stmts, isStmtExpr);
1349}
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365bool Parser::ParseParenExprOrCondition(StmtResult *InitStmt,
1372 T.consumeOpen();
1374
1376 Cond = ParseCXXCondition(InitStmt, Loc, CK, false);
1377 } else {
1379
1380
1383 else
1385 false);
1386 }
1387
1388
1389
1390
1393
1394
1395 if (Tok.isNot(tok::r_paren))
1396 return true;
1397 }
1398
1401 Start, Tok.getLocation() == Start ? Start : PrevTokLocation, {},
1405 false);
1406 }
1407
1408
1409 T.consumeClose();
1410 LParenLoc = T.getOpenLocation();
1411 RParenLoc = T.getCloseLocation();
1412
1413
1414
1415
1416 while (Tok.is(tok::r_paren)) {
1417 Diag(Tok, diag::err_extraneous_rparen_in_condition)
1419 ConsumeParen();
1420 }
1421
1422 return false;
1423}
1424
1425namespace {
1426
1427enum MisleadingStatementKind { MSK_if, MSK_else, MSK_for, MSK_while };
1428
1429struct MisleadingIndentationChecker {
1433 unsigned NumDirectives;
1434 MisleadingStatementKind Kind;
1435 bool ShouldSkip;
1436 MisleadingIndentationChecker(Parser &P, MisleadingStatementKind K,
1438 : P(P), StmtLoc(SL), PrevLoc(P.getCurToken().getLocation()),
1439 NumDirectives(P.getPreprocessor().getNumDirectives()), Kind(K),
1440 ShouldSkip(P.getCurToken().is(tok::l_brace)) {
1441 if (.MisleadingIndentationElseLoc.isInvalid()) {
1442 StmtLoc = P.MisleadingIndentationElseLoc;
1444 }
1445 if (Kind == MSK_else && !ShouldSkip)
1446 P.MisleadingIndentationElseLoc = SL;
1447 }
1448
1449
1450
1452 unsigned TabStop = SM.getDiagnostics().getDiagnosticOptions().TabStop;
1453
1454 unsigned ColNo = SM.getSpellingColumnNumber(Loc);
1455 if (ColNo == 0 || TabStop == 1)
1456 return ColNo;
1457
1458 std::pair<FileID, unsigned> FIDAndOffset = SM.getDecomposedLoc(Loc);
1459
1461 StringRef BufData = SM.getBufferData(FIDAndOffset.first, &Invalid);
1463 return 0;
1464
1465 const char *EndPos = BufData.data() + FIDAndOffset.second;
1466
1467 assert(FIDAndOffset.second + 1 >= ColNo &&
1468 "Column number smaller than file offset?");
1469
1470 unsigned VisualColumn = 0;
1471
1472
1473 for (const char *CurPos = EndPos - (ColNo - 1); CurPos != EndPos;
1474 ++CurPos) {
1475 if (*CurPos == '\t')
1476
1477 VisualColumn += (TabStop - VisualColumn % TabStop);
1478 else
1479 VisualColumn++;
1480 }
1481 return VisualColumn + 1;
1482 }
1483
1484 void Check() {
1485 Token Tok = P.getCurToken();
1486 if (P.getActions().getDiagnostics().isIgnored(
1487 diag::warn_misleading_indentation, Tok.getLocation()) ||
1488 ShouldSkip || NumDirectives != P.getPreprocessor().getNumDirectives() ||
1492 (Kind == MSK_else && P.MisleadingIndentationElseLoc.isInvalid())) {
1494 return;
1495 }
1496 if (Kind == MSK_else)
1498
1500 unsigned PrevColNum = getVisualIndentation(SM, PrevLoc);
1501 unsigned CurColNum = getVisualIndentation(SM, Tok.getLocation());
1502 unsigned StmtColNum = getVisualIndentation(SM, StmtLoc);
1503
1504 if (PrevColNum != 0 && CurColNum != 0 && StmtColNum != 0 &&
1505 ((PrevColNum > StmtColNum && PrevColNum == CurColNum) ||
1507 SM.getPresumedLineNumber(StmtLoc) !=
1509 (Tok.isNot(tok::identifier) ||
1510 P.getPreprocessor().LookAhead(0).isNot(tok::colon))) {
1511 P.Diag(Tok.getLocation(), diag::warn_misleading_indentation) << Kind;
1512 P.Diag(StmtLoc, diag::note_previous_statement);
1513 }
1514 }
1515};
1516
1517}
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1529 assert(Tok.is(tok::kw_if) && "Not an if stmt!");
1531
1532 bool IsConstexpr = false;
1533 bool IsConsteval = false;
1536
1537 if (Tok.is(tok::kw_constexpr)) {
1538
1541 : diag::ext_constexpr_if);
1542 IsConstexpr = true;
1544 }
1545 } else {
1546 if (Tok.is(tok::exclaim)) {
1548 }
1549
1550 if (Tok.is(tok::kw_consteval)) {
1552 : diag::ext_consteval_if);
1553 IsConsteval = true;
1555 }
1556 }
1557 if (!IsConsteval && (NotLocation.isValid() || Tok.isNot(tok::l_paren))) {
1558 Diag(Tok, diag::err_expected_lparen_after) << "if";
1561 }
1562
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1578
1579
1584 std::optional ConstexprCondition;
1585 if (!IsConsteval) {
1586
1587 if (ParseParenExprOrCondition(&InitStmt, Cond, IfLoc,
1590 LParen, RParen))
1592
1593 if (IsConstexpr)
1595 }
1596
1597 bool IsBracedThen = Tok.is(tok::l_brace);
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617 ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, IsBracedThen);
1618
1619 MisleadingIndentationChecker MIChecker(*this, MSK_if, IfLoc);
1620
1621
1623
1626 {
1627 bool ShouldEnter = ConstexprCondition && !*ConstexprCondition;
1630 if (NotLocation.isInvalid() && IsConsteval) {
1632 ShouldEnter = true;
1633 }
1634
1636 Actions, Context, nullptr,
1638 ThenStmt = ParseStatement(&InnerStatementTrailingElseLoc);
1639 }
1640
1641 if (Tok.isNot(tok::kw_else))
1642 MIChecker.Check();
1643
1644
1645 InnerScope.Exit();
1646
1647
1651
1652 if (Tok.is(tok::kw_else)) {
1653 if (TrailingElseLoc)
1655
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1669 Tok.is(tok::l_brace));
1670
1671 MisleadingIndentationChecker MIChecker(*this, MSK_else, ElseLoc);
1672 bool ShouldEnter = ConstexprCondition && *ConstexprCondition;
1675 if (NotLocation.isValid() && IsConsteval) {
1677 ShouldEnter = true;
1678 }
1679
1681 Actions, Context, nullptr,
1683 ElseStmt = ParseStatement();
1684
1686 MIChecker.Check();
1687
1688
1689 InnerScope.Exit();
1690 } else if (Tok.is(tok::code_completion)) {
1691 cutOffParsing();
1694 } else if (InnerStatementTrailingElseLoc.isValid()) {
1695 Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else);
1696 }
1697
1698 IfScope.Exit();
1699
1700
1701
1702
1704 (ThenStmt.isInvalid() && ElseStmt.get() == nullptr) ||
1705 (ThenStmt.get() == nullptr && ElseStmt.isInvalid())) {
1706
1708 }
1709
1710 if (IsConsteval) {
1711 auto IsCompoundStatement = [](const Stmt *S) {
1712 if (const auto *Outer = dyn_cast_if_present(S))
1713 S = Outer->getSubStmt();
1714 return isa_and_nonnullclang::CompoundStmt(S);
1715 };
1716
1717 if (!IsCompoundStatement(ThenStmt.get())) {
1718 Diag(ConstevalLoc, diag::err_expected_after) << "consteval"
1719 << "{";
1721 }
1722 if (!ElseStmt.isUnset() && !IsCompoundStatement(ElseStmt.get())) {
1723 Diag(ElseLoc, diag::err_expected_after) << "else"
1724 << "{";
1726 }
1727 }
1728
1729
1734
1736 if (IsConstexpr)
1738 else if (IsConsteval)
1741
1742 return Actions.ActOnIfStmt(IfLoc, Kind, LParen, InitStmt.get(), Cond, RParen,
1743 ThenStmt.get(), ElseLoc, ElseStmt.get());
1744}
1745
1746
1747
1748
1749
1751 assert(Tok.is(tok::kw_switch) && "Not a switch stmt!");
1753
1754 if (Tok.isNot(tok::l_paren)) {
1755 Diag(Tok, diag::err_expected_lparen_after) << "switch";
1758 }
1759
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1775 if (C99orCXX)
1777 ParseScope SwitchScope(this, ScopeFlags);
1778
1779
1784 if (ParseParenExprOrCondition(&InitStmt, Cond, SwitchLoc,
1787
1789 SwitchLoc, LParen, InitStmt.get(), Cond, RParen);
1790
1791 if (Switch.isInvalid()) {
1792
1793
1794
1795
1796 if (Tok.is(tok::l_brace)) {
1797 ConsumeBrace();
1799 } else
1802 }
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1816 ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
1817
1818
1819
1820 if (C99orCXX)
1822
1823
1824 StmtResult Body(ParseStatement(TrailingElseLoc));
1825
1826
1827 InnerScope.Exit();
1828 SwitchScope.Exit();
1829
1831}
1832
1833
1834
1835
1836
1838 assert(Tok.is(tok::kw_while) && "Not a while stmt!");
1841
1842 if (Tok.isNot(tok::l_paren)) {
1843 Diag(Tok, diag::err_expected_lparen_after) << "while";
1846 }
1847
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862 unsigned ScopeFlags;
1863 if (C99orCXX)
1866 else
1868 ParseScope WhileScope(this, ScopeFlags);
1869
1870
1874 if (ParseParenExprOrCondition(nullptr, Cond, WhileLoc,
1877
1878
1879
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894 ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
1895
1896 MisleadingIndentationChecker MIChecker(*this, MSK_while, WhileLoc);
1897
1898
1899 StmtResult Body(ParseStatement(TrailingElseLoc));
1900
1901 if (Body.isUsable())
1902 MIChecker.Check();
1903
1904 InnerScope.Exit();
1905 WhileScope.Exit();
1906
1907 if (Cond.isInvalid() || Body.isInvalid())
1909
1910 return Actions.ActOnWhileStmt(WhileLoc, LParen, Cond, RParen, Body.get());
1911}
1912
1913
1914
1915
1916
1917StmtResult Parser::ParseDoStatement() {
1918 assert(Tok.is(tok::kw_do) && "Not a do stmt!");
1920
1921
1922
1923 unsigned ScopeFlags;
1926 else
1928
1929 ParseScope DoScope(this, ScopeFlags);
1930
1931
1932
1935
1936
1937
1938
1939
1940
1941
1942
1943
1945 ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
1946
1947
1949
1950
1951 InnerScope.Exit();
1952
1953 if (Tok.isNot(tok::kw_while)) {
1954 if (!Body.isInvalid()) {
1955 Diag(Tok, diag::err_expected_while);
1956 Diag(DoLoc, diag::note_matching) << "'do'";
1958 }
1960 }
1962
1963 if (Tok.isNot(tok::l_paren)) {
1964 Diag(Tok, diag::err_expected_lparen_after) << "do/while";
1967 }
1968
1969
1971 T.consumeOpen();
1972
1973
1974 DiagnoseAndSkipCXX11Attributes();
1975
1978
1981 true);
1982 else {
1983 if (!Tok.isOneOf(tok::r_paren, tok::r_square, tok::r_brace))
1986 Start, Start == Tok.getLocation() ? Start : PrevTokLocation, {},
1988 }
1989 T.consumeClose();
1990 DoScope.Exit();
1991
1992 if (Cond.isInvalid() || Body.isInvalid())
1994
1995 return Actions.ActOnDoStmt(DoLoc, Body.get(), WhileLoc, T.getOpenLocation(),
1996 Cond.get(), T.getCloseLocation());
1997}
1998
1999bool Parser::isForRangeIdentifier() {
2000 assert(Tok.is(tok::identifier));
2001
2003 if (Next.is(tok::colon))
2004 return true;
2005
2006 if (Next.isOneOf(tok::l_square, tok::kw_alignas)) {
2007 TentativeParsingAction PA(*this);
2009 SkipCXX11Attributes();
2010 bool Result = Tok.is(tok::colon);
2011 PA.Revert();
2013 }
2014
2015 return false;
2016}
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2042 assert(Tok.is(tok::kw_for) && "Not a for stmt!");
2044
2046 if (Tok.is(tok::kw_co_await))
2048
2049 if (Tok.isNot(tok::l_paren)) {
2050 Diag(Tok, diag::err_expected_lparen_after) << "for";
2053 }
2054
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073 unsigned ScopeFlags = 0;
2074 if (C99orCXXorObjC)
2076
2077 ParseScope ForScope(this, ScopeFlags);
2078
2080 T.consumeOpen();
2081
2083
2084 bool ForEach = false;
2088 ForRangeInfo ForRangeInfo;
2090
2091 if (Tok.is(tok::code_completion)) {
2092 cutOffParsing();
2097 }
2098
2100 MaybeParseCXX11Attributes(attrs);
2101
2103
2104
2105 if (Tok.is(tok::semi)) {
2106 ProhibitAttributes(attrs);
2107
2110 EmptyInitStmtSemiLoc = SemiLoc;
2113 isForRangeIdentifier()) {
2114 ProhibitAttributes(attrs);
2117 MaybeParseCXX11Attributes(attrs);
2118
2120 if (Tok.is(tok::l_brace))
2121 ForRangeInfo.RangeExpr = ParseBraceInitializer();
2122 else
2124
2125 Diag(Loc, diag::err_for_range_identifier)
2129
2130 ForRangeInfo.LoopVar =
2132 } else if (isForInitDeclaration()) {
2134
2135
2136 if (!C99orCXXorObjC) {
2137 Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
2138 Diag(Tok, diag::warn_gcc_variable_decl_in_for_loop);
2139 }
2142 if (Tok.is(tok::kw_using)) {
2144 attrs);
2146 } else {
2147
2148 bool MightBeForRangeStmt = getLangOpts().CPlusPlus;
2151 DG = ParseSimpleDeclaration(
2153 MightBeForRangeStmt ? &ForRangeInfo : nullptr);
2155 if (ForRangeInfo.ParsedForRangeDecl()) {
2157 ? diag::warn_cxx98_compat_for_range
2158 : diag::ext_for_range);
2159 ForRangeInfo.LoopVar = FirstPart;
2161 } else if (Tok.is(tok::semi)) {
2163 } else if ((ForEach = isTokIdentifier_in())) {
2165
2167
2168 if (Tok.is(tok::code_completion)) {
2169 cutOffParsing();
2171 DG);
2173 }
2175 } else {
2176 Diag(Tok, diag::err_expected_semi_for);
2177 }
2178 }
2179 } else {
2180 ProhibitAttributes(attrs);
2182
2183 ForEach = isTokIdentifier_in();
2184
2185
2186 if (.isInvalid()) {
2187 if (ForEach)
2189 else {
2190
2191
2192
2193
2194
2195 bool IsRangeBasedFor =
2196 getLangOpts().CPlusPlus11 && !ForEach && Tok.is(tok::colon);
2198 }
2199 }
2200
2201 if (Tok.is(tok::semi)) {
2203 } else if (ForEach) {
2205
2206 if (Tok.is(tok::code_completion)) {
2207 cutOffParsing();
2209 nullptr);
2211 }
2214
2215
2216 Diag(Tok, diag::err_for_range_expected_decl)
2220 } else {
2221 if (.isInvalid()) {
2222 Diag(Tok, diag::err_expected_semi_for);
2223 } else {
2224
2226 if (Tok.is(tok::semi))
2228 }
2229 }
2230 }
2231
2232
2233 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl() &&
2235
2236 if (Tok.is(tok::semi)) {
2237
2238 } else if (Tok.is(tok::r_paren)) {
2239
2240 } else {
2242
2243
2244 bool MightBeForRangeStmt = !ForRangeInfo.ParsedForRangeDecl();
2248 SecondPart = ParseCXXCondition(
2249 nullptr, ForLoc, CK,
2250
2251 true, MightBeForRangeStmt ? &ForRangeInfo : nullptr,
2252 true);
2253
2254 if (ForRangeInfo.ParsedForRangeDecl()) {
2256 : ForRangeInfo.ColonLoc,
2258 ? diag::warn_cxx17_compat_for_range_init_stmt
2259 : diag::ext_for_range_init_stmt)
2262 if (EmptyInitStmtSemiLoc.isValid()) {
2263 Diag(EmptyInitStmtSemiLoc, diag::warn_empty_init_statement)
2264 << 2
2266 }
2267 }
2268
2271 SecondPartStart,
2272 Tok.getLocation() == SecondPartStart ? SecondPartStart
2273 : PrevTokLocation,
2277 CondExpr.get(), CK,
2278 false);
2279 }
2280
2281 } else {
2282
2284
2288 else
2292 }
2293 }
2294 }
2295
2296
2297
2300
2301
2302 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl()) {
2303 if (Tok.isNot(tok::semi)) {
2305 Diag(Tok, diag::err_expected_semi_for);
2307 }
2308
2309 if (Tok.is(tok::semi)) {
2311 }
2312
2313 if (Tok.isNot(tok::r_paren)) {
2315
2316
2318 }
2319 }
2320
2321 T.consumeClose();
2322
2323
2324
2325 if (CoawaitLoc.isValid() && !ForRangeInfo.ParsedForRangeDecl()) {
2326 Diag(CoawaitLoc, diag::err_for_co_await_not_range_for);
2328 }
2329
2331 Diag(CoawaitLoc, diag::warn_deprecated_for_co_await);
2332
2333
2334
2335
2338
2339 if (ForRangeInfo.ParsedForRangeDecl()) {
2344 ForRangeInfo.LoopVar.get(), ForRangeInfo.ColonLoc, CorrectedRange.get(),
2346 ForRangeInfo.LifetimeExtendTemps);
2347 } else if (ForEach) {
2348
2349
2351 ForLoc, FirstPart.get(), Collection.get(), T.getCloseLocation());
2352 } else {
2353
2354
2357 }
2358 }
2359
2360
2361
2363 if (ForRangeInfo.ParsedForRangeDecl())
2365 else
2367 ForLoc, FirstPart.get(), SecondPart.get().second, ThirdPart.get());
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380 ParseScope InnerScope(this, Scope::DeclScope, C99orCXXorObjC,
2381 Tok.is(tok::l_brace));
2382
2383
2384
2385
2386
2387 if (C99orCXXorObjC)
2389
2390 MisleadingIndentationChecker MIChecker(*this, MSK_for, ForLoc);
2391
2392
2393 StmtResult Body(ParseStatement(TrailingElseLoc));
2394
2395 if (Body.isUsable())
2396 MIChecker.Check();
2397
2398
2399 InnerScope.Exit();
2400
2402
2403
2404 ForScope.Exit();
2405
2406 if (Body.isInvalid())
2408
2409 if (ForEach)
2411 Body.get());
2412
2413 if (ForRangeInfo.ParsedForRangeDecl())
2415
2416 return Actions.ActOnForStmt(ForLoc, T.getOpenLocation(), FirstPart.get(),
2417 SecondPart, ThirdPart, T.getCloseLocation(),
2418 Body.get());
2419}
2420
2421
2422
2423
2424
2425
2426
2427
2428StmtResult Parser::ParseGotoStatement() {
2429 assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");
2431
2433 if (Tok.is(tok::identifier)) {
2438 } else if (Tok.is(tok::star)) {
2439
2440 Diag(Tok, diag::ext_gnu_indirect_goto);
2443 if (R.isInvalid()) {
2446 }
2448 } else {
2449 Diag(Tok, diag::err_expected) << tok::identifier;
2451 }
2452
2453 return Res;
2454}
2455
2456
2457
2458
2459
2460
2461
2462StmtResult Parser::ParseContinueStatement() {
2465}
2466
2467
2468
2469
2470
2471
2472
2473StmtResult Parser::ParseBreakStatement() {
2476}
2477
2478
2479
2480
2481
2482
2483
2484StmtResult Parser::ParseReturnStatement() {
2485 assert((Tok.is(tok::kw_return) || Tok.is(tok::kw_co_return)) &&
2486 "Not a return stmt!");
2487 bool IsCoreturn = Tok.is(tok::kw_co_return);
2489
2491 if (Tok.isNot(tok::semi)) {
2492 if (!IsCoreturn)
2494
2495 if (Tok.is(tok::code_completion) && !IsCoreturn) {
2496 cutOffParsing();
2500 }
2501
2503 R = ParseInitializer();
2507 ? diag::warn_cxx98_compat_generalized_initializer_lists
2508 : diag::ext_generalized_initializer_lists)
2510 } else
2515 }
2516 }
2517 if (IsCoreturn)
2520}
2521
2522StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
2523 ParsedStmtContext StmtCtx,
2526
2528
2530
2531
2532 while (Tok.is(tok::annot_pragma_loop_hint)) {
2534 if (!HandlePragmaLoopHint(Hint))
2535 continue;
2536
2541 ParsedAttr::Form::Pragma());
2542 }
2543
2544
2545 MaybeParseCXX11Attributes(Attrs);
2546
2548 StmtResult S = ParseStatementOrDeclarationAfterAttributes(
2549 Stmts, StmtCtx, TrailingElseLoc, Attrs, EmptyDeclSpecAttrs);
2550
2552
2553
2554
2557
2558 return S;
2559}
2560
2561Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) {
2562 assert(Tok.is(tok::l_brace));
2564
2566 "parsing function body");
2567
2568
2569 bool IsCXXMethod =
2572 PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod);
2573
2574
2575
2576
2577 StmtResult FnBody(ParseCompoundStatementBody());
2578
2579
2580 if (FnBody.isInvalid()) {
2582 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, {}, false);
2583 }
2584
2585 BodyScope.Exit();
2587}
2588
2589
2590
2591
2592
2593
2594Decl *Parser::ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope) {
2595 assert(Tok.is(tok::kw_try) && "Expected 'try'");
2597
2599 "parsing function try block");
2600
2601
2602 if (Tok.is(tok::colon))
2603 ParseConstructorInitializer(Decl);
2604 else
2606
2607
2608 bool IsCXXMethod =
2611 PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod);
2612
2614 StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc, true));
2615
2616
2617 if (FnBody.isInvalid()) {
2619 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, {}, false);
2620 }
2621
2622 BodyScope.Exit();
2624}
2625
2626bool Parser::trySkippingFunctionBody() {
2627 assert(SkipFunctionBodies &&
2628 "Should only be called when SkipFunctionBodies is enabled");
2630 SkipFunctionBody();
2631 return true;
2632 }
2633
2634
2635
2636 TentativeParsingAction PA(*this);
2637 bool IsTryCatch = Tok.is(tok::kw_try);
2639 bool ErrorInPrologue = ConsumeAndStoreFunctionPrologue(Toks);
2640 if (llvm::any_of(Toks, [](const Token &Tok) {
2641 return Tok.is(tok::code_completion);
2642 })) {
2643 PA.Revert();
2644 return false;
2645 }
2646 if (ErrorInPrologue) {
2647 PA.Commit();
2649 return true;
2650 }
2652 PA.Revert();
2653 return false;
2654 }
2655 while (IsTryCatch && Tok.is(tok::kw_catch)) {
2658 PA.Revert();
2659 return false;
2660 }
2661 }
2662 PA.Commit();
2663 return true;
2664}
2665
2666
2667
2668
2669
2670
2671StmtResult Parser::ParseCXXTryBlock() {
2672 assert(Tok.is(tok::kw_try) && "Expected 'try'");
2673
2675 return ParseCXXTryBlockCommon(TryLoc);
2676}
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2695 if (Tok.isNot(tok::l_brace))
2696 return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
2697
2698 StmtResult TryBlock(ParseCompoundStatement(
2702 if (TryBlock.isInvalid())
2703 return TryBlock;
2704
2705
2706
2707 if ((Tok.is(tok::identifier) &&
2709 Tok.is(tok::kw___finally)) {
2710
2714 Handler = ParseSEHExceptBlock(Loc);
2715 }
2716 else {
2718 Handler = ParseSEHFinallyBlock(Loc);
2719 }
2721 return Handler;
2722
2724 TryLoc,
2725 TryBlock.get(),
2726 Handler.get());
2727 }
2728 else {
2730
2731
2732
2733 DiagnoseAndSkipCXX11Attributes();
2734
2735 if (Tok.isNot(tok::kw_catch))
2736 return StmtError(Diag(Tok, diag::err_expected_catch));
2737 while (Tok.is(tok::kw_catch)) {
2738 StmtResult Handler(ParseCXXCatchBlock(FnTry));
2740 Handlers.push_back(Handler.get());
2741 }
2742
2743
2744 if (Handlers.empty())
2746
2747 return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.get(), Handlers);
2748 }
2749}
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761StmtResult Parser::ParseCXXCatchBlock(bool FnCatch) {
2762 assert(Tok.is(tok::kw_catch) && "Expected 'catch'");
2763
2765
2767 if (T.expectAndConsume())
2769
2770
2771
2772
2776
2777
2778
2779 Decl *ExceptionDecl = nullptr;
2780 if (Tok.isNot(tok::ellipsis)) {
2782 MaybeParseCXX11Attributes(Attributes);
2783
2785
2786 if (ParseCXXTypeSpecifierSeq(DS))
2788
2790 ParseDeclarator(ExDecl);
2792 } else
2794
2795 T.consumeClose();
2796 if (T.getCloseLocation().isInvalid())
2798
2799 if (Tok.isNot(tok::l_brace))
2800 return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
2801
2802
2804 if (Block.isInvalid())
2806
2808}
2809
2810void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
2811 IfExistsCondition Result;
2812 if (ParseMicrosoftIfExistsCondition(Result))
2813 return;
2814
2815
2816
2817
2818
2819 if (Result.Behavior == IEB_Dependent) {
2820 if (!Tok.is(tok::l_brace)) {
2821 Diag(Tok, diag::err_expected) << tok::l_brace;
2822 return;
2823 }
2824
2825 StmtResult Compound = ParseCompoundStatement();
2827 return;
2828
2833 Compound.get());
2835 Stmts.push_back(DepResult.get());
2836 return;
2837 }
2838
2840 if (Braces.consumeOpen()) {
2841 Diag(Tok, diag::err_expected) << tok::l_brace;
2842 return;
2843 }
2844
2845 switch (Result.Behavior) {
2846 case IEB_Parse:
2847
2848 break;
2849
2850 case IEB_Dependent:
2851 llvm_unreachable("Dependent case handled above");
2852
2853 case IEB_Skip:
2855 return;
2856 }
2857
2858
2859 while (Tok.isNot(tok::r_brace)) {
2861 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::Compound);
2863 Stmts.push_back(R.get());
2864 }
2865 Braces.consumeClose();
2866}
enum clang::sema::@1725::IndirectLocalPathEntry::EntryKind Kind
static void DiagnoseLabelFollowedByDecl(Parser &P, const Stmt *SubStmt)
Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...
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.
static CharSourceRange getRange(const CharSourceRange &EditRange, const SourceManager &SM, const LangOptions &LangOpts, bool IncludeMacroExpansion)
Defines the clang::TokenKind enum and support functions.
Attr - This represents one attribute.
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and restores it when destroyed.
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...
Captures information about "declaration specifiers".
Decl - This represents one declaration (or definition), e.g.
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.
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.
Represents a member of a struct/union/class.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
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.
void setIsPoisoned(bool Value=true)
setIsPoisoned - Mark this identifier as poisoned.
StringRef getName() const
Return the actual identifier string.
Represents the declaration of a label.
@ FEM_Source
Use the declared type for fp arithmetic.
Represent a C++ namespace.
RAII object that makes sure paren/bracket/brace count is correct after declaration/statement parsing,...
ParsedAttr - Represents a syntactic attribute.
ParsedAttributes - A collection of parsed attributes.
void takeAllFrom(ParsedAttributes &Other)
Parser - This implements a parser for the C family of languages.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Sema::FullExprArg FullExprArg
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Sema & getActions() const
ExprResult ParseCaseExpression(SourceLocation CaseLoc)
StmtResult ParseOpenACCDirectiveStmt()
bool TryConsumeToken(tok::TokenKind Expected)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
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 ...
void SkipMalformedDecl()
SkipMalformedDecl - Read tokens until we get to some likely good stopping point for skipping past a s...
const LangOptions & getLangOpts() const
ExprResult ParseExpression(TypeCastState isTypeCast=NotTypeCast)
Simple precedence-based parser for binary/ternary operators.
SmallVector< Stmt *, 32 > StmtVector
A SmallVector of statements.
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtCodeCompletion
Stop at code completion.
@ StopAtSemi
Stop skipping at semicolon.
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
An RAII object for [un]poisoning an identifier within a scope.
void enterReturn(Sema &S, SourceLocation Tok)
QualType get(SourceLocation Tok) const
Get the expected type associated with this location, if any.
SourceLocation getLastFPEvalPragmaLocation() const
LangOptions::FPEvalMethodKind getCurrentFPEvalMethod() const
SourceManager & getSourceManager() const
const TargetInfo & getTargetInfo() const
bool isCodeCompletionEnabled() const
Determine if we are performing code completion.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Computes the source location just past the end of the token at this source location.
PrettyDeclStackTraceEntry - If a crash occurs in the parser while parsing something related to a decl...
If a crash happens while one of these objects are live, the message is printed out along with the spe...
void AddFlags(unsigned Flags)
Sets up the specified scope flags and adjusts the scope state variables accordingly.
void decrementMSManglingNumber()
@ SEHTryScope
This scope corresponds to an SEH try.
@ ContinueScope
This is a while, do, for, which can have continue statements embedded into it.
@ ControlScope
The controlling scope in a if/switch/while/for statement.
@ SEHFilterScope
We are currently in the filter expression of an SEH except block.
@ SwitchScope
This is a scope that corresponds to a switch statement.
@ BreakScope
This is a while, do, switch, for, etc that can have break statements embedded into it.
@ CatchScope
This is the scope of a C++ catch statement.
@ CompoundStmtScope
This is a compound statement scope.
@ FnTryCatchScope
This is the scope for a function-level C++ try or catch scope.
@ SEHExceptScope
This scope corresponds to an SEH except.
@ TryScope
This is the scope of a C++ try statement.
@ DeclScope
This is a scope that can contain a declaration.
@ PCC_ForInit
Code completion occurs at the beginning of the initialization statement (or expression) in a for loop...
@ PCC_Expression
Code completion occurs within an expression.
@ PCC_Statement
Code completion occurs within a statement, which may also be an expression or a declaration.
void CodeCompleteCase(Scope *S)
void CodeCompleteExpression(Scope *S, const CodeCompleteExpressionData &Data)
Perform code-completion in an expression context when we know what type we're looking for.
void CodeCompleteAfterIf(Scope *S, bool IsBracedThen)
void CodeCompleteOrdinaryName(Scope *S, ParserCompletionContext CompletionContext)
void CodeCompleteObjCForCollection(Scope *S, DeclGroupPtrTy IterationVar)
StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc, Stmt *First, Expr *collection, SourceLocation RParenLoc)
StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body)
FinishObjCForCollectionStmt - Attach the body to a objective-C foreach statement.
Helper type to restore the state of various 'loop' constructs when we run into a loop (for,...
void ActOnWhileStmt(SourceLocation WhileLoc)
void ActOnDoStmt(SourceLocation DoLoc)
void ActOnRangeForStmtBegin(SourceLocation ForLoc, const Stmt *OldRangeFor, const Stmt *RangeFor)
void ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body)
void ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *First, const Stmt *Second, const Stmt *Third)
void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init)
Check if the current region is an OpenMP loop region and if it is, mark loop control variable,...
A RAII object to enter scope of a compound statement.
std::pair< VarDecl *, Expr * > get() const
std::optional< bool > getKnownValue() const
Records and restores the CurFPFeatures state on entry/exit of compound statements.
StmtResult ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc, IdentifierInfo *Ident, ParsedAttributes &Attrs)
StmtResult ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope)
StmtResult ActOnForEachLValueExpr(Expr *E)
In an Objective C collection iteration statement: for (x in y) x can be an arbitrary l-value expressi...
void ActOnForEachDeclStmt(DeclGroupPtrTy Decl)
@ Boolean
A boolean condition, from 'if', 'while', 'for', or 'do'.
@ Switch
An integral condition for a 'switch' statement.
@ ConstexprIf
A constant boolean condition from 'if constexpr'.
StmtResult ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc, LabelDecl *TheDecl)
StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, Scope *CurScope)
StmtResult ActOnExprStmt(ExprResult Arg, bool DiscardedValue=true)
bool CheckCaseExpression(Expr *E)
ASTContext & getASTContext() const
StmtResult ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler)
StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, Stmt *Body)
ConditionResult ActOnCondition(Scope *S, SourceLocation Loc, Expr *SubExpr, ConditionKind CK, bool MissingOK=false)
StmtResult ActOnCoreturnStmt(Scope *S, SourceLocation KwLoc, Expr *E)
StmtResult ActOnWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc, ConditionResult Cond, SourceLocation RParenLoc, Stmt *Body)
SemaCodeCompletion & CodeCompletion()
void ProcessDeclAttributeList(Scope *S, Decl *D, const ParsedAttributesView &AttrList, const ProcessDeclAttributeOptions &Options=ProcessDeclAttributeOptions())
ProcessDeclAttributeList - Apply all the decl attributes in the specified attribute list to the speci...
StmtResult ActOnExprStmtError()
StmtResult ActOnNullStmt(SourceLocation SemiLoc, bool HasLeadingEmptyMacro=false)
StmtResult ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, Stmt *First, ConditionResult Second, FullExprArg Third, SourceLocation RParenLoc, Stmt *Body)
StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc, Expr *DestExp)
Decl * ActOnExceptionDeclarator(Scope *S, Declarator &D)
ActOnExceptionDeclarator - Parsed the exception-declarator in a C++ catch handler.
LabelDecl * LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc, SourceLocation GnuLabelLoc=SourceLocation())
LookupOrCreateLabel - Do a name lookup of a label with the specified name.
Decl * ActOnFinishFunctionBody(Decl *Decl, Stmt *Body)
StmtResult ActOnCXXForRangeStmt(Scope *S, SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *InitStmt, Stmt *LoopVar, SourceLocation ColonLoc, Expr *Collection, SourceLocation RParenLoc, BuildForRangeKind Kind, ArrayRef< MaterializeTemporaryExpr * > LifetimeExtendTemps={})
ActOnCXXForRangeStmt - Check and build a C++11 for-range statement.
void ActOnDefaultCtorInitializers(Decl *CDtorDecl)
DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, ArrayRef< Decl * > Group)
StmtResult ActOnFinishSEHFinallyBlock(SourceLocation Loc, Stmt *Block)
StmtResult ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope)
StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, SourceLocation WhileLoc, SourceLocation CondLParen, Expr *Cond, SourceLocation CondRParen)
StmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc)
StmtResult ActOnMSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists, CXXScopeSpec &SS, UnqualifiedId &Name, Stmt *Nested)
ExpressionEvaluationContext
Describes how the expressions currently being parsed are evaluated at run-time, if at all.
@ DiscardedStatement
The current expression occurs within a discarded statement.
@ ImmediateFunctionContext
In addition of being constant evaluated, the current expression occurs in an immediate function conte...
StmtResult ActOnSEHExceptBlock(SourceLocation Loc, Expr *FilterExpr, Stmt *Block)
void ActOnAfterCompoundStatementLeadingPragmas()
StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)
StmtResult ActOnAttributedStmt(const ParsedAttributes &AttrList, Stmt *SubStmt)
StmtResult ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope)
FullExprArg MakeFullDiscardedValueExpr(Expr *Arg)
void ActOnStartSEHFinallyBlock()
void ActOnAbortSEHFinallyBlock()
@ BFRK_Build
Initial building of a for-range statement.
StmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc, Decl *ExDecl, Stmt *HandlerBlock)
ActOnCXXCatchBlock - Takes an exception declaration and a handler block and creates a proper catch ha...
void ActOnCaseStmtBody(Stmt *CaseStmt, Stmt *SubStmt)
ActOnCaseStmtBody - This installs a statement as the body of a case.
ExprResult ActOnStmtExprResult(ExprResult E)
ExprResult CreateRecoveryExpr(SourceLocation Begin, SourceLocation End, ArrayRef< Expr * > SubExprs, QualType T=QualType())
Attempts to produce a RecoveryExpr after some AST node cannot be created.
StmtResult ActOnIfStmt(SourceLocation IfLoc, IfStatementKind StatementKind, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc, Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal)
QualType PreferredConditionType(ConditionKind K) const
static ConditionResult ConditionError()
StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, ArrayRef< Stmt * > Elts, bool isStmtExpr)
StmtResult ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl, SourceLocation ColonLoc, Stmt *SubStmt)
StmtResult ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, ArrayRef< Stmt * > Handlers)
ActOnCXXTryBlock - Takes a try compound-statement and a number of handlers and creates a try statemen...
StmtResult ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc, Stmt *SubStmt, Scope *CurScope)
StmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHS, SourceLocation DotDotDotLoc, ExprResult RHS, SourceLocation ColonLoc)
StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body)
FinishCXXForRangeStmt - Attach the body to a C++0x for-range statement.
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
void setBegin(SourceLocation b)
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
virtual bool supportSourceEvalMethod() const
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.
void setKind(tok::TokenKind K)
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)) {....
tok::TokenKind getKind() const
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
bool hasLeadingEmptyMacro() const
Return true if this token has an empty macro before it.
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
bool isNot(tok::TokenKind K) const
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
void setAnnotationValue(void *val)
Simple class containing the result of Sema::CorrectTypo.
DeclClass * getCorrectionDeclAs() const
NestedNameSpecifier * getCorrectionSpecifier() const
Gets the NestedNameSpecifier needed to use the typo correction.
Represents a variable declaration or definition.
Defines the clang::TargetInfo interface.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
The JSON file list parser is used to communicate input to InstallAPI.
IfStatementKind
In an if statement, this denotes whether the statement is a constexpr or consteval if statement.
llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion
A union of the various pointer types that can be passed to an ParsedAttr as an argument.
void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &Second, ParsedAttributes &Result)
Consumes the attributes from First and Second and concatenates them into Result.
@ Result
The result type of a method or function.
ActionResult< Stmt * > StmtResult
const FunctionProtoType * T
@ Braces
New-expression has a C++11 list-initializer.
Loop optimization hint for loop and unroll pragmas.
IdentifierLoc * OptionLoc
IdentifierLoc * PragmaNameLoc