30#include "llvm/ADT/STLExtras.h"
31#include "llvm/ADT/ScopeExit.h"
41 ParsedStmtContext StmtCtx,
49 Res = ParseStatementOrDeclaration(Stmts, StmtCtx, TrailingElseLoc,
51 }
while (!Res.isInvalid() && !Res.get());
56StmtResult Parser::ParseStatementOrDeclaration(StmtVector &Stmts,
57 ParsedStmtContext StmtCtx,
68 ParsedAttributes CXX11Attrs(AttrFactory);
70 MaybeParseCXX11Attributes(CXX11Attrs,
true);
71 ParsedAttributes GNUOrMSAttrs(AttrFactory);
73 MaybeParseGNUAttributes(GNUOrMSAttrs);
76 MaybeParseMicrosoftAttributes(GNUOrMSAttrs);
78 StmtResult Res = ParseStatementOrDeclarationAfterAttributes(
79 Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs, GNUOrMSAttrs,
81 MaybeDestroyTemplateIds();
85 assert((CXX11Attrs.empty() || Res.isInvalid() || Res.isUsable()) &&
86 "attributes on empty statement");
89 (StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
90 ParsedStmtContext{} &&
91 isa_and_present<NullStmt>(Res.get()))
92 Diag(CXX11Attrs.Range.getBegin(), diag::warn_attr_in_secondary_block)
95 if (CXX11Attrs.empty() || Res.isInvalid())
98 return Actions.ActOnAttributedStmt(CXX11Attrs, Res.get());
104 StatementFilterCCC(Token nextTok) : NextToken(nextTok) {
105 WantTypeSpecifiers = nextTok.
isOneOf(tok::l_paren, tok::less, tok::l_square,
106 tok::identifier, tok::star, tok::amp);
107 WantExpressionKeywords =
108 nextTok.
isOneOf(tok::l_paren, tok::identifier, tok::arrow, tok::period);
109 WantRemainingKeywords =
110 nextTok.
isOneOf(tok::l_paren, tok::semi, tok::identifier, tok::l_brace);
111 WantCXXNamedCasts =
false;
114 bool ValidateCandidate(
const TypoCorrection &candidate)
override {
117 if (NextToken.is(tok::equal))
119 if (NextToken.is(tok::period) &&
125 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
126 return std::make_unique<StatementFilterCCC>(*
this);
134StmtResult Parser::ParseStatementOrDeclarationAfterAttributes(
135 StmtVector &Stmts, ParsedStmtContext StmtCtx,
138 const char *SemiError =
nullptr;
140 SourceLocation GNUAttributeLoc;
147 SourceLocation AtLoc;
152 return ParseObjCAtStatement(AtLoc, StmtCtx);
155 case tok::code_completion:
157 Actions.CodeCompletion().CodeCompleteOrdinaryName(
161 case tok::identifier:
164 if (
Next.is(tok::colon)) {
171 return ParseLabeledStatement(CXX11Attrs, StmtCtx);
176 if (
Next.isNot(tok::coloncolon)) {
179 StatementFilterCCC CCC(
Next);
184 if (Tok.is(tok::semi))
190 if (Tok.isNot(tok::identifier))
202 bool HaveAttrs = !CXX11Attrs.
empty() || !GNUAttrs.
empty();
203 auto IsStmtAttr = [](ParsedAttr &Attr) {
return Attr.isStmtAttr(); };
204 bool AllAttrsAreStmtAttrs = llvm::all_of(CXX11Attrs, IsStmtAttr) &&
205 llvm::all_of(GNUAttrs, IsStmtAttr);
212 (StmtCtx & ParsedStmtContext::AllowDeclarationsInC) !=
213 ParsedStmtContext()) &&
214 ((GNUAttributeLoc.
isValid() && !(HaveAttrs && AllAttrsAreStmtAttrs)) ||
215 isDeclarationStatement())) {
216 SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
218 if (GNUAttributeLoc.
isValid()) {
219 DeclStart = GNUAttributeLoc;
221 GNUAttrs, &GNUAttributeLoc);
234 return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
237 if (Tok.is(tok::r_brace)) {
238 Diag(Tok, diag::err_expected_statement);
242 switch (Tok.getKind()) {
243#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
244#include "clang/Basic/BuiltinTraits.inc"
246 Tok.setKind(tok::identifier);
247 Diag(Tok, diag::ext_keyword_as_ident)
248 << Tok.getIdentifierInfo()->getName() << 0;
249 goto ParseIdentifier;
253 return ParseExprStatement(StmtCtx);
257 case tok::kw___attribute: {
258 GNUAttributeLoc = Tok.getLocation();
259 ParseGNUAttributes(GNUAttrs);
263 case tok::kw_template: {
267 Diag(Tok.getLocation(), diag::err_expansion_stmt_requires_cxx2c);
272 return ParseForStatement(TrailingElseLoc, PrecedingLabel);
276 return ParseExpansionStatement(TrailingElseLoc, PrecedingLabel,
280 SourceLocation DeclEnd;
282 getAccessSpecifierIfPresent());
287 return ParseCaseStatement(StmtCtx);
288 case tok::kw_default:
289 return ParseDefaultStatement(StmtCtx);
292 return ParseCompoundStatement();
294 bool HasLeadingEmptyMacro = Tok.hasLeadingEmptyMacro();
295 return Actions.ActOnNullStmt(
ConsumeToken(), HasLeadingEmptyMacro);
299 return ParseIfStatement(TrailingElseLoc);
301 return ParseSwitchStatement(TrailingElseLoc, PrecedingLabel);
304 return ParseWhileStatement(TrailingElseLoc, PrecedingLabel);
306 Res = ParseDoStatement(PrecedingLabel);
307 SemiError =
"do/while";
312 Diag(Tok.getLocation(), diag::err_for_template)
314 SourceRange(Tok.getLocation(),
NextToken().getEndLoc()),
316 Tok.setKind(tok::kw_template);
318 Tok.setKind(tok::kw_for);
319 return ParseExpansionStatement(TrailingElseLoc, PrecedingLabel,
323 return ParseForStatement(TrailingElseLoc, PrecedingLabel);
326 Res = ParseGotoStatement();
329 case tok::kw_continue:
330 Res = ParseContinueStatement();
331 SemiError =
"continue";
334 Res = ParseBreakStatement();
338 Res = ParseReturnStatement();
339 SemiError =
"return";
341 case tok::kw_co_return:
342 Res = ParseReturnStatement();
343 SemiError =
"co_return";
346 return ParseDeferStatement(TrailingElseLoc);
349 for (
const ParsedAttr &AL : CXX11Attrs)
352 (AL.isRegularKeywordAttribute()
353 ?
Diag(AL.getRange().getBegin(), diag::err_keyword_not_allowed)
354 :
Diag(AL.getRange().getBegin(), diag::warn_attribute_ignored))
358 ProhibitAttributes(GNUAttrs);
360 Res = ParseAsmStatement(msAsm);
361 if (msAsm)
return Res;
366 case tok::kw___if_exists:
367 case tok::kw___if_not_exists:
368 ProhibitAttributes(CXX11Attrs);
369 ProhibitAttributes(GNUAttrs);
370 ParseMicrosoftIfExistsStatement(Stmts);
376 return ParseCXXTryBlock();
379 ProhibitAttributes(CXX11Attrs);
380 ProhibitAttributes(GNUAttrs);
381 return ParseSEHTryBlock();
383 case tok::kw___leave:
384 Res = ParseSEHLeaveStatement();
385 SemiError =
"__leave";
388 case tok::annot_pragma_vis:
389 ProhibitAttributes(CXX11Attrs);
390 ProhibitAttributes(GNUAttrs);
391 HandlePragmaVisibility();
394 case tok::annot_pragma_pack:
395 ProhibitAttributes(CXX11Attrs);
396 ProhibitAttributes(GNUAttrs);
400 case tok::annot_pragma_msstruct:
401 ProhibitAttributes(CXX11Attrs);
402 ProhibitAttributes(GNUAttrs);
403 HandlePragmaMSStruct();
406 case tok::annot_pragma_align:
407 ProhibitAttributes(CXX11Attrs);
408 ProhibitAttributes(GNUAttrs);
412 case tok::annot_pragma_weak:
413 ProhibitAttributes(CXX11Attrs);
414 ProhibitAttributes(GNUAttrs);
418 case tok::annot_pragma_weakalias:
419 ProhibitAttributes(CXX11Attrs);
420 ProhibitAttributes(GNUAttrs);
421 HandlePragmaWeakAlias();
424 case tok::annot_pragma_redefine_extname:
425 ProhibitAttributes(CXX11Attrs);
426 ProhibitAttributes(GNUAttrs);
427 HandlePragmaRedefineExtname();
430 case tok::annot_pragma_fp_contract:
431 ProhibitAttributes(CXX11Attrs);
432 ProhibitAttributes(GNUAttrs);
433 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"fp_contract";
434 ConsumeAnnotationToken();
437 case tok::annot_pragma_fp:
438 ProhibitAttributes(CXX11Attrs);
439 ProhibitAttributes(GNUAttrs);
440 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"clang fp";
441 ConsumeAnnotationToken();
444 case tok::annot_pragma_fenv_access:
445 case tok::annot_pragma_fenv_access_ms:
446 ProhibitAttributes(CXX11Attrs);
447 ProhibitAttributes(GNUAttrs);
448 Diag(Tok, diag::err_pragma_file_or_compound_scope)
449 << (
Kind == tok::annot_pragma_fenv_access ?
"STDC FENV_ACCESS"
451 ConsumeAnnotationToken();
454 case tok::annot_pragma_fenv_round:
455 ProhibitAttributes(CXX11Attrs);
456 ProhibitAttributes(GNUAttrs);
457 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"STDC FENV_ROUND";
458 ConsumeAnnotationToken();
461 case tok::annot_pragma_cx_limited_range:
462 ProhibitAttributes(CXX11Attrs);
463 ProhibitAttributes(GNUAttrs);
464 Diag(Tok, diag::err_pragma_file_or_compound_scope)
465 <<
"STDC CX_LIMITED_RANGE";
466 ConsumeAnnotationToken();
469 case tok::annot_pragma_float_control:
470 ProhibitAttributes(CXX11Attrs);
471 ProhibitAttributes(GNUAttrs);
472 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"float_control";
473 ConsumeAnnotationToken();
476 case tok::annot_pragma_opencl_extension:
477 ProhibitAttributes(CXX11Attrs);
478 ProhibitAttributes(GNUAttrs);
479 HandlePragmaOpenCLExtension();
482 case tok::annot_pragma_captured:
483 ProhibitAttributes(CXX11Attrs);
484 ProhibitAttributes(GNUAttrs);
485 return HandlePragmaCaptured();
487 case tok::annot_pragma_openmp:
490 ProhibitAttributes(CXX11Attrs);
491 ProhibitAttributes(GNUAttrs);
493 case tok::annot_attr_openmp:
495 return ParseOpenMPDeclarativeOrExecutableDirective(StmtCtx);
497 case tok::annot_pragma_openacc:
500 case tok::annot_pragma_ms_pointers_to_members:
501 ProhibitAttributes(CXX11Attrs);
502 ProhibitAttributes(GNUAttrs);
503 HandlePragmaMSPointersToMembers();
506 case tok::annot_pragma_ms_pragma:
507 ProhibitAttributes(CXX11Attrs);
508 ProhibitAttributes(GNUAttrs);
509 HandlePragmaMSPragma();
512 case tok::annot_pragma_ms_vtordisp:
513 ProhibitAttributes(CXX11Attrs);
514 ProhibitAttributes(GNUAttrs);
515 HandlePragmaMSVtorDisp();
518 case tok::annot_pragma_loop_hint:
519 ProhibitAttributes(CXX11Attrs);
520 ProhibitAttributes(GNUAttrs);
521 return ParsePragmaLoopHint(Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs,
524 case tok::annot_pragma_dump:
525 ProhibitAttributes(CXX11Attrs);
526 ProhibitAttributes(GNUAttrs);
530 case tok::annot_pragma_attribute:
531 ProhibitAttributes(CXX11Attrs);
532 ProhibitAttributes(GNUAttrs);
533 HandlePragmaAttribute();
535 case tok::annot_pragma_export:
536 ProhibitAttributes(CXX11Attrs);
537 ProhibitAttributes(GNUAttrs);
538 HandlePragmaExport();
547 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt, SemiError);
555StmtResult Parser::ParseExprStatement(ParsedStmtContext StmtCtx) {
557 Token OldToken = Tok;
559 ExprStatementTokLoc = Tok.getLocation();
563 if (Expr.isInvalid()) {
568 if (Tok.is(tok::semi))
570 return Actions.ActOnExprStmtError();
573 if (Tok.is(tok::colon) &&
getCurScope()->isSwitchScope() &&
574 Actions.CheckCaseExpression(Expr.get())) {
577 Diag(OldToken, diag::err_expected_case_before_expression)
581 return ParseCaseStatement(StmtCtx,
true, Expr);
584 Token *CurTok =
nullptr;
587 if (Tok.is(tok::annot_repl_input_end))
591 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
594 if (CurTok && !
R.isInvalid())
601 assert(Tok.is(tok::kw___try) &&
"Expected '__try'");
604 if (Tok.isNot(tok::l_brace))
605 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
610 if (TryBlock.isInvalid())
614 if (isTokenSEHExcept()) {
616 Handler = ParseSEHExceptBlock(Loc);
617 }
else if (Tok.is(tok::kw___finally)) {
619 Handler = ParseSEHFinallyBlock(Loc);
624 if(Handler.isInvalid())
627 return Actions.ActOnSEHTryBlock(
false ,
634 PoisonIdentifierRAIIObject raii(Ident__exception_code,
false),
635 raii2(Ident___exception_code,
false),
636 raii3(Ident_GetExceptionCode,
false);
638 if (ExpectAndConsume(tok::l_paren))
645 Ident__exception_info->setIsPoisoned(
false);
646 Ident___exception_info->setIsPoisoned(
false);
647 Ident_GetExceptionInfo->setIsPoisoned(
false);
652 ParseScopeFlags FilterScope(
this,
getCurScope()->getFlags() |
658 Ident__exception_info->setIsPoisoned(
true);
659 Ident___exception_info->setIsPoisoned(
true);
660 Ident_GetExceptionInfo->setIsPoisoned(
true);
666 if (ExpectAndConsume(tok::r_paren))
669 if (Tok.isNot(tok::l_brace))
670 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
674 if(
Block.isInvalid())
677 return Actions.ActOnSEHExceptBlock(ExceptLoc, FilterExpr.
get(),
Block.get());
681 PoisonIdentifierRAIIObject raii(Ident__abnormal_termination,
false),
682 raii2(Ident___abnormal_termination,
false),
683 raii3(Ident_AbnormalTermination,
false);
685 if (Tok.isNot(tok::l_brace))
686 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
689 Actions.ActOnStartSEHFinallyBlock();
692 if(
Block.isInvalid()) {
693 Actions.ActOnAbortSEHFinallyBlock();
697 return Actions.ActOnFinishSEHFinallyBlock(FinallyLoc,
Block.get());
707 return Actions.ActOnSEHLeaveStmt(LeaveLoc,
getCurScope());
716 diag_compat::label_followed_by_declaration);
721 ParsedStmtContext StmtCtx) {
722 assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
723 "Not an identifier!");
728 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
730 Token IdentTok = Tok;
733 assert(Tok.is(tok::colon) &&
"Not a label!");
738 LabelDecl *LD = Actions.LookupOrCreateLabel(
744 if (Tok.is(tok::kw___attribute)) {
745 ParsedAttributes TempAttrs(AttrFactory);
746 ParseGNUAttributes(TempAttrs);
759 ParsedAttributes EmptyCXX11Attrs(AttrFactory);
760 SubStmt = ParseStatementOrDeclarationAfterAttributes(
761 Stmts, StmtCtx,
nullptr, EmptyCXX11Attrs,
763 if (!TempAttrs.empty() && !SubStmt.isInvalid())
764 SubStmt = Actions.ActOnAttributedStmt(TempAttrs, SubStmt.get());
769 if (SubStmt.isUnset() && Tok.is(tok::r_brace)) {
770 DiagnoseLabelAtEndOfCompoundStatement();
771 SubStmt = Actions.ActOnNullStmt(ColonLoc);
775 if (SubStmt.isUnset())
776 SubStmt = ParseStatement(
nullptr, StmtCtx, LD);
779 if (SubStmt.isInvalid())
780 SubStmt = Actions.ActOnNullStmt(ColonLoc);
788 return SubStmt.get();
791 Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
794 return Actions.ActOnLabelStmt(IdentTok.
getLocation(), LD, ColonLoc,
798StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx,
800 assert((MissingCase || Tok.is(tok::kw_case)) &&
"Not a case stmt!");
805 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
828 Stmt *DeepestParsedCaseStmt =
nullptr;
831 SourceLocation ColonLoc;
833 SourceLocation CaseLoc = MissingCase ? Expr.
get()->
getExprLoc() :
835 ColonLoc = SourceLocation();
837 if (Tok.is(tok::code_completion)) {
839 Actions.CodeCompletion().CodeCompleteCase(
getCurScope());
858 LHS = Actions.ActOnCaseExpr(CaseLoc, Expr);
863 SourceLocation DotDotDotLoc;
869 DiagId = diag::ext_gnu_case_range;
871 DiagId = diag::warn_c23_compat_case_range;
873 DiagId = diag::ext_c2y_case_range;
874 Diag(DotDotDotLoc, DiagId);
882 ColonProtection.restore();
888 Diag(ColonLoc, diag::err_expected_after)
889 <<
"'case'" << tok::colon
894 Diag(ExpectedLoc, diag::err_expected_after)
895 <<
"'case'" << tok::colon
898 ColonLoc = ExpectedLoc;
902 Actions.ActOnCaseStmt(CaseLoc, LHS, DotDotDotLoc, RHS, ColonLoc);
906 if (Case.isInvalid()) {
907 if (TopLevelCase.isInvalid())
908 return ParseStatement(
nullptr, StmtCtx);
913 Stmt *NextDeepest = Case.get();
914 if (TopLevelCase.isInvalid())
917 Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, Case.get());
918 DeepestParsedCaseStmt = NextDeepest;
922 }
while (Tok.is(tok::kw_case));
927 if (Tok.is(tok::r_brace)) {
930 DiagnoseLabelAtEndOfCompoundStatement();
931 SubStmt = Actions.ActOnNullStmt(ColonLoc);
933 SubStmt = ParseStatement(
nullptr, StmtCtx);
937 if (DeepestParsedCaseStmt) {
939 if (SubStmt.isInvalid())
940 SubStmt = Actions.ActOnNullStmt(SourceLocation());
942 Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, SubStmt.get());
949StmtResult Parser::ParseDefaultStatement(ParsedStmtContext StmtCtx) {
950 assert(Tok.is(tok::kw_default) &&
"Not a default stmt!");
955 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
959 SourceLocation ColonLoc;
963 Diag(ColonLoc, diag::err_expected_after)
964 <<
"'default'" << tok::colon
967 SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation);
968 Diag(ExpectedLoc, diag::err_expected_after)
969 <<
"'default'" << tok::colon
971 ColonLoc = ExpectedLoc;
976 if (Tok.is(tok::r_brace)) {
979 DiagnoseLabelAtEndOfCompoundStatement();
980 SubStmt = Actions.ActOnNullStmt(ColonLoc);
982 SubStmt = ParseStatement(
nullptr, StmtCtx);
986 if (SubStmt.isInvalid())
987 SubStmt = Actions.ActOnNullStmt(ColonLoc);
990 return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc,
994StmtResult Parser::ParseCompoundStatement(
bool isStmtExpr) {
995 return ParseCompoundStatement(isStmtExpr,
999StmtResult Parser::ParseCompoundStatement(
bool isStmtExpr,
1000 unsigned ScopeFlags) {
1001 assert(Tok.is(tok::l_brace) &&
"Not a compound stmt!");
1009 StackHandler.runWithSufficientStackSpace(Tok.getLocation(), [&,
this]() {
1010 R = ParseCompoundStatementBody(isStmtExpr);
1015void Parser::ParseCompoundStatementLeadingPragmas() {
1016 bool checkForPragmas =
true;
1017 while (checkForPragmas) {
1018 switch (Tok.getKind()) {
1019 case tok::annot_pragma_vis:
1020 HandlePragmaVisibility();
1022 case tok::annot_pragma_pack:
1025 case tok::annot_pragma_msstruct:
1026 HandlePragmaMSStruct();
1028 case tok::annot_pragma_align:
1029 HandlePragmaAlign();
1031 case tok::annot_pragma_weak:
1034 case tok::annot_pragma_weakalias:
1035 HandlePragmaWeakAlias();
1037 case tok::annot_pragma_redefine_extname:
1038 HandlePragmaRedefineExtname();
1040 case tok::annot_pragma_opencl_extension:
1041 HandlePragmaOpenCLExtension();
1043 case tok::annot_pragma_fp_contract:
1044 HandlePragmaFPContract();
1046 case tok::annot_pragma_fp:
1049 case tok::annot_pragma_fenv_access:
1050 case tok::annot_pragma_fenv_access_ms:
1051 HandlePragmaFEnvAccess();
1053 case tok::annot_pragma_fenv_round:
1054 HandlePragmaFEnvRound();
1056 case tok::annot_pragma_cx_limited_range:
1057 HandlePragmaCXLimitedRange();
1059 case tok::annot_pragma_float_control:
1060 HandlePragmaFloatControl();
1062 case tok::annot_pragma_ms_pointers_to_members:
1063 HandlePragmaMSPointersToMembers();
1065 case tok::annot_pragma_ms_pragma:
1066 HandlePragmaMSPragma();
1068 case tok::annot_pragma_ms_vtordisp:
1069 HandlePragmaMSVtorDisp();
1071 case tok::annot_pragma_dump:
1074 case tok::annot_pragma_export:
1075 HandlePragmaExport();
1078 checkForPragmas =
false;
1085void Parser::DiagnoseLabelAtEndOfCompoundStatement() {
1087 ? diag_compat::cxx_label_at_end_of_compound_statement
1088 : diag_compat::c_label_at_end_of_compound_statement);
1091bool Parser::ConsumeNullStmt(StmtVector &Stmts) {
1092 if (!Tok.is(tok::semi))
1095 SourceLocation StartLoc = Tok.getLocation();
1096 SourceLocation EndLoc;
1098 while (Tok.is(tok::semi) && !Tok.hasLeadingEmptyMacro() &&
1099 Tok.getLocation().isValid() && !Tok.getLocation().isMacroID()) {
1100 EndLoc = Tok.getLocation();
1104 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::SubStmt);
1106 Stmts.push_back(
R.get());
1113 Diag(StartLoc, diag::warn_null_statement)
1119 bool IsStmtExprResult =
false;
1120 if ((StmtCtx & ParsedStmtContext::InStmtExpr) != ParsedStmtContext()) {
1124 IsStmtExprResult = Tok.is(tok::r_brace) &&
NextToken().
is(tok::r_paren);
1127 if (IsStmtExprResult)
1128 E = Actions.ActOnStmtExprResult(E);
1129 return Actions.ActOnExprStmt(E, !IsStmtExprResult);
1132StmtResult Parser::ParseCompoundStatementBody(
bool isStmtExpr) {
1133 PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),
1135 "in compound statement ('{}')");
1139 Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);
1143 if (
T.consumeOpen())
1146 Sema::CompoundScopeRAII CompoundScope(Actions, isStmtExpr);
1149 ParseCompoundStatementLeadingPragmas();
1150 Actions.ActOnAfterCompoundStatementLeadingPragmas();
1156 while (Tok.is(tok::kw___label__)) {
1159 SmallVector<Decl *, 4> DeclsInGroup;
1161 if (Tok.isNot(tok::identifier)) {
1162 Diag(Tok, diag::err_expected) << tok::identifier;
1166 IdentifierInfo *II = Tok.getIdentifierInfo();
1168 DeclsInGroup.push_back(Actions.LookupOrCreateLabel(II, IdLoc, LabelLoc));
1174 DeclSpec DS(AttrFactory);
1176 Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, DeclsInGroup);
1177 StmtResult R = Actions.ActOnDeclStmt(Res, LabelLoc, Tok.getLocation());
1179 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
1181 Stmts.push_back(
R.get());
1184 ParsedStmtContext SubStmtCtx =
1185 ParsedStmtContext::Compound |
1186 (isStmtExpr ? ParsedStmtContext::InStmtExpr : ParsedStmtContext());
1188 bool LastIsError =
false;
1189 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
1190 Tok.isNot(tok::eof)) {
1191 if (Tok.is(tok::annot_pragma_unused)) {
1192 HandlePragmaUnused();
1196 if (ConsumeNullStmt(Stmts))
1200 if (Tok.isNot(tok::kw___extension__)) {
1201 R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
1208 while (Tok.is(tok::kw___extension__))
1211 ParsedAttributes attrs(AttrFactory);
1212 MaybeParseCXX11Attributes(attrs,
true);
1215 if (isDeclarationStatement()) {
1218 ExtensionRAIIObject O(Diags);
1220 SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
1221 ParsedAttributes DeclSpecAttrs(AttrFactory);
1223 attrs, DeclSpecAttrs);
1224 R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);
1227 ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
1229 if (Res.isInvalid()) {
1236 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
1237 R = handleExprStmt(Res, SubStmtCtx);
1239 R = Actions.ActOnAttributedStmt(attrs,
R.get());
1244 Stmts.push_back(
R.get());
1245 LastIsError =
R.isInvalid();
1251 if (isStmtExpr && LastIsError && !Stmts.empty())
1258 if (!PP.getTargetInfo().supportSourceEvalMethod() &&
1259 (PP.getLastFPEvalPragmaLocation().isValid() ||
1260 PP.getCurrentFPEvalMethod() ==
1262 Diag(Tok.getLocation(),
1263 diag::warn_no_support_for_eval_method_source_on_m32);
1265 SourceLocation CloseLoc = Tok.getLocation();
1268 if (!
T.consumeClose()) {
1271 if (isStmtExpr && Tok.is(tok::r_paren))
1272 checkCompoundToken(CloseLoc, tok::r_brace, CompoundToken::StmtExprEnd);
1278 if (
T.getCloseLocation().isValid())
1279 CloseLoc =
T.getCloseLocation();
1281 return Actions.ActOnCompoundStmt(
T.getOpenLocation(), CloseLoc,
1285bool Parser::ParseParenExprOrCondition(
StmtResult *InitStmt,
1293 SourceLocation Start = Tok.getLocation();
1295 Cond = ParseCondition(InitStmt, Loc, CK,
false);
1300 if (Cond.
isInvalid() && Tok.isNot(tok::r_paren)) {
1304 if (Tok.isNot(tok::r_paren))
1309 ExprResult CondExpr = Actions.CreateRecoveryExpr(
1310 Start, Tok.getLocation() == Start ? Start : PrevTokLocation, {},
1311 Actions.PreferredConditionType(CK));
1313 Cond = Actions.ActOnCondition(
getCurScope(), Loc, CondExpr.
get(), CK,
1318 if (InitStmt !=
nullptr && InitStmt->isUsable()) {
1324 Diag(InitStmt->get()->getBeginLoc(),
1325 diag::err_c2y_first_condition_clause_is_not_declaration)
1326 << InitStmt->get()->getSourceRange();
1328 if (Cond.
get().first !=
nullptr)
1330 Diag(Cond.
get().first->getBeginLoc(), diag::err_expected_expression)
1331 << Cond.
get().first->getSourceRange();
1332 }
else if (Cond.
get().first !=
nullptr)
1334 DiagCompat(Cond.
get().first->getBeginLoc(), diag_compat::decl_statement)
1338 if (Tok.is(tok::comma)) {
1339 Diag(Tok, diag::err_c2y_multiple_declarations);
1341 while (Tok.isNot(tok::r_paren) && !Tok.is(tok::eof))
1346 LParenLoc =
T.getOpenLocation();
1347 RParenLoc =
T.getCloseLocation();
1352 while (Tok.is(tok::r_paren)) {
1353 Diag(Tok, diag::err_extraneous_rparen_in_condition)
1363enum MisleadingStatementKind { MSK_if, MSK_else, MSK_for, MSK_while };
1365struct MisleadingIndentationChecker {
1367 SourceLocation StmtLoc;
1368 SourceLocation PrevLoc;
1369 unsigned NumDirectives;
1370 MisleadingStatementKind
Kind;
1372 MisleadingIndentationChecker(Parser &P, MisleadingStatementKind K,
1374 : P(P), StmtLoc(SL), PrevLoc(P.getCurToken().getLocation()),
1375 NumDirectives(P.getPreprocessor().getNumDirectives()),
Kind(K),
1376 ShouldSkip(P.getCurToken().
is(tok::l_brace)) {
1378 StmtLoc = P.MisleadingIndentationElseLoc;
1379 P.MisleadingIndentationElseLoc = SourceLocation();
1381 if (Kind == MSK_else && !ShouldSkip)
1387 static unsigned getVisualIndentation(SourceManager &SM, SourceLocation Loc) {
1391 if (ColNo == 0 || TabStop == 1)
1401 const char *EndPos = BufData.data() + FIDAndOffset.second;
1403 assert(FIDAndOffset.second + 1 >= ColNo &&
1404 "Column number smaller than file offset?");
1406 unsigned VisualColumn = 0;
1409 for (
const char *CurPos = EndPos - (ColNo - 1); CurPos != EndPos;
1411 if (*CurPos ==
'\t')
1413 VisualColumn += (TabStop - VisualColumn % TabStop);
1417 return VisualColumn + 1;
1432 if (Kind == MSK_else)
1436 unsigned PrevColNum = getVisualIndentation(SM, PrevLoc);
1437 unsigned CurColNum = getVisualIndentation(SM,
Tok.
getLocation());
1438 unsigned StmtColNum = getVisualIndentation(SM, StmtLoc);
1440 if (PrevColNum != 0 && CurColNum != 0 && StmtColNum != 0 &&
1441 ((PrevColNum > StmtColNum && PrevColNum == CurColNum) ||
1448 P.
Diag(StmtLoc, diag::note_previous_statement);
1456 assert(Tok.is(tok::kw_if) &&
"Not an if stmt!");
1459 bool IsConstexpr =
false;
1460 bool IsConsteval =
false;
1461 SourceLocation NotLocation;
1462 SourceLocation ConstevalLoc;
1464 if (Tok.is(tok::kw_constexpr)) {
1472 if (Tok.is(tok::exclaim)) {
1476 if (Tok.is(tok::kw_consteval)) {
1480 }
else if (Tok.is(tok::code_completion)) {
1482 Actions.CodeCompletion().CodeCompleteKeywordAfterIf(
1487 if (!IsConsteval && (NotLocation.
isValid() || Tok.isNot(tok::l_paren))) {
1488 Diag(Tok, diag::err_expected_lparen_after) <<
"if";
1511 Sema::ConditionResult Cond;
1512 SourceLocation LParen;
1513 SourceLocation RParen;
1514 std::optional<bool> ConstexprCondition;
1517 if (ParseParenExprOrCondition(&InitStmt, Cond, IfLoc,
1527 bool IsBracedThen = Tok.is(tok::l_brace);
1549 MisleadingIndentationChecker MIChecker(*
this, MSK_if, IfLoc);
1552 SourceLocation ThenStmtLoc = Tok.getLocation();
1554 SourceLocation InnerStatementTrailingElseLoc;
1557 bool ShouldEnter = ConstexprCondition && !*ConstexprCondition;
1560 if (NotLocation.
isInvalid() && IsConsteval) {
1565 EnterExpressionEvaluationContext PotentiallyDiscarded(
1566 Actions, Context,
nullptr,
1568 ThenStmt = ParseStatement(&InnerStatementTrailingElseLoc);
1571 if (Tok.isNot(tok::kw_else))
1578 SourceLocation ElseLoc;
1579 SourceLocation ElseStmtLoc;
1582 if (Tok.is(tok::kw_else)) {
1583 if (TrailingElseLoc)
1584 *TrailingElseLoc = Tok.getLocation();
1587 ElseStmtLoc = Tok.getLocation();
1599 Tok.is(tok::l_brace));
1601 MisleadingIndentationChecker MIChecker(*
this, MSK_else, ElseLoc);
1602 bool ShouldEnter = ConstexprCondition && *ConstexprCondition;
1605 if (NotLocation.
isValid() && IsConsteval) {
1610 EnterExpressionEvaluationContext PotentiallyDiscarded(
1611 Actions, Context,
nullptr,
1613 ElseStmt = ParseStatement();
1615 if (ElseStmt.isUsable())
1620 }
else if (Tok.is(tok::code_completion)) {
1622 Actions.CodeCompletion().CodeCompleteAfterIf(
getCurScope(), IsBracedThen);
1624 }
else if (InnerStatementTrailingElseLoc.
isValid()) {
1625 Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else);
1633 if ((ThenStmt.isInvalid() && ElseStmt.isInvalid()) ||
1634 (ThenStmt.isInvalid() && ElseStmt.get() ==
nullptr) ||
1635 (ThenStmt.get() ==
nullptr && ElseStmt.isInvalid())) {
1641 auto IsCompoundStatement = [](
const Stmt *S) {
1642 if (
const auto *Outer = dyn_cast_if_present<AttributedStmt>(S))
1643 S = Outer->getSubStmt();
1644 return isa_and_nonnull<clang::CompoundStmt>(S);
1647 if (!IsCompoundStatement(ThenStmt.get())) {
1648 Diag(ConstevalLoc, diag::err_expected_after) <<
"consteval"
1652 if (!ElseStmt.isUnset() && !IsCompoundStatement(ElseStmt.get())) {
1653 Diag(ElseLoc, diag::err_expected_after) <<
"else"
1660 if (ThenStmt.isInvalid())
1661 ThenStmt = Actions.ActOnNullStmt(ThenStmtLoc);
1662 if (ElseStmt.isInvalid())
1663 ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);
1668 else if (IsConsteval)
1672 return Actions.ActOnIfStmt(IfLoc, Kind, LParen, InitStmt.get(), Cond, RParen,
1673 ThenStmt.get(), ElseLoc, ElseStmt.get());
1678 assert(Tok.is(tok::kw_switch) &&
"Not a switch stmt!");
1681 if (Tok.isNot(tok::l_paren)) {
1682 Diag(Tok, diag::err_expected_lparen_after) <<
"switch";
1708 Sema::ConditionResult Cond;
1709 SourceLocation LParen;
1710 SourceLocation RParen;
1711 if (ParseParenExprOrCondition(&InitStmt, Cond, SwitchLoc,
1716 SwitchLoc, LParen, InitStmt.get(), Cond, RParen);
1718 if (
Switch.isInvalid()) {
1723 if (Tok.is(tok::l_brace)) {
1751 StmtResult Body(ParseStatement(TrailingElseLoc));
1757 return Actions.ActOnFinishSwitchStmt(SwitchLoc,
Switch.get(), Body.get());
1762 assert(Tok.is(tok::kw_while) &&
"Not a while stmt!");
1763 SourceLocation WhileLoc = Tok.getLocation();
1766 if (Tok.isNot(tok::l_paren)) {
1767 Diag(Tok, diag::err_expected_lparen_after) <<
"while";
1786 unsigned ScopeFlags =
1791 Sema::ConditionResult Cond;
1792 SourceLocation LParen;
1793 SourceLocation RParen;
1794 if (ParseParenExprOrCondition(
nullptr, Cond, WhileLoc,
1817 MisleadingIndentationChecker MIChecker(*
this, MSK_while, WhileLoc);
1820 StmtResult Body(ParseStatement(TrailingElseLoc));
1822 if (Body.isUsable())
1828 if (Cond.
isInvalid() || Body.isInvalid())
1831 return Actions.ActOnWhileStmt(WhileLoc, LParen, Cond, RParen, Body.get());
1835 assert(Tok.is(tok::kw_do) &&
"Not a do stmt!");
1869 if (Tok.isNot(tok::kw_while)) {
1870 if (!Body.isInvalid()) {
1871 Diag(Tok, diag::err_expected_while);
1872 Diag(DoLoc, diag::note_matching) <<
"'do'";
1879 if (Tok.isNot(tok::l_paren)) {
1880 Diag(Tok, diag::err_expected_lparen_after) <<
"do/while";
1890 DiagnoseAndSkipCXX11Attributes();
1892 SourceLocation Start = Tok.getLocation();
1895 if (!Tok.isOneOf(tok::r_paren, tok::r_square, tok::r_brace))
1897 Cond = Actions.CreateRecoveryExpr(
1898 Start, Start == Tok.getLocation() ? Start : PrevTokLocation, {},
1899 Actions.getASTContext().BoolTy);
1904 if (Cond.
isInvalid() || Body.isInvalid())
1907 return Actions.ActOnDoStmt(DoLoc, Body.get(), WhileLoc,
T.getOpenLocation(),
1908 Cond.
get(),
T.getCloseLocation());
1911bool Parser::isForRangeIdentifier() {
1912 assert(Tok.is(tok::identifier));
1915 if (
Next.is(tok::colon))
1918 if (
Next.isOneOf(tok::l_square, tok::kw_alignas)) {
1919 TentativeParsingAction PA(*
this);
1921 SkipCXX11Attributes();
1922 bool Result = Tok.is(tok::colon);
1930void Parser::ParseForRangeInitializerAfterColon(ForRangeInit &FRI,
1938 EnterExpressionEvaluationContext InitContext(
1946 auto &LastRecord = Actions.currentEvaluationContext();
1947 LastRecord.InLifetimeExtendingContext =
true;
1948 LastRecord.RebuildDefaultArgOrDefaultInit =
true;
1951 if (FRI.ExpansionStmt) {
1954 assert(Actions.CurContext->isExpansionStmt());
1955 Sema::ContextRAII CtxGuard(Actions, Actions.CurContext->getParent(),
1959 FRI.RangeExpr = Actions.MaybeCreateExprWithCleanups(FRI.RangeExpr);
1960 }
else if (Tok.is(tok::l_brace)) {
1961 FRI.RangeExpr = ParseBraceInitializer();
1968 Actions.ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
1972 FRI.LifetimeExtendTemps =
1973 std::move(Actions.ExprEvalContexts.back().ForRangeLifetimeExtendTemps);
1979 assert(Tok.is(tok::kw_for) &&
"Not a for stmt!");
1982 SourceLocation CoawaitLoc;
1983 if (Tok.is(tok::kw_co_await))
1986 if (Tok.isNot(tok::l_paren)) {
1987 Diag(Tok, diag::err_expected_lparen_after) <<
"for";
2024 bool ForEach =
false;
2026 Sema::ConditionResult SecondPart;
2028 ForRangeInfo ForRangeInfo;
2030 ForRangeInfo.ExpansionStmt = ESD;
2037 struct [[nodiscard]] ExpansionStmtContextRAII : Sema::ContextRAII {
2038 ExpansionStmtContextRAII(Sema &S,
struct ForRangeInfo &Info,
2040 : ContextRAII(S, Info.ExpansionStmt ? Ctx : S.CurContext,
2044 assert(!ESD || Actions.CurContext->isExpansionStmt());
2045 if (Tok.is(tok::code_completion)) {
2047 Actions.CodeCompletion().CodeCompleteOrdinaryName(
2053 ParsedAttributes attrs(AttrFactory);
2054 MaybeParseCXX11Attributes(attrs);
2056 SourceLocation EmptyInitStmtSemiLoc;
2059 if (Tok.is(tok::semi)) {
2060 ProhibitAttributes(attrs);
2062 SourceLocation SemiLoc = Tok.getLocation();
2063 if (!Tok.hasLeadingEmptyMacro() && !SemiLoc.
isMacroID())
2064 EmptyInitStmtSemiLoc = SemiLoc;
2067 isForRangeIdentifier()) {
2071 ProhibitAttributes(attrs);
2072 IdentifierInfo *Name = Tok.getIdentifierInfo();
2074 MaybeParseCXX11Attributes(attrs);
2077 ParseForRangeInitializerAfterColon(ForRangeInfo,
nullptr);
2079 Diag(Loc, diag::err_for_range_identifier)
2080 << (ForRangeInfo.ExpansionStmt !=
nullptr)
2085 if (!ForRangeInfo.ExpansionStmt)
2086 ForRangeInfo.LoopVar =
2087 Actions.ActOnCXXForRangeIdentifier(
getCurScope(), Loc, Name, attrs);
2088 }
else if (isForInitDeclaration()) {
2090 ExpansionStmtContextRAII EnterParentContext{
2091 Actions, ForRangeInfo, Actions.CurContext->getParent()};
2094 if (!C99orCXXorObjC) {
2095 Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
2096 Diag(Tok, diag::warn_gcc_variable_decl_in_for_loop);
2099 SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
2101 Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
2102 ProhibitAttributes(attrs);
2103 Decl *D = ParseStaticAssertDeclaration(DeclEnd);
2104 DG = Actions.ConvertDeclToDeclGroup(D);
2105 FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
2106 }
else if (Tok.is(tok::kw_using)) {
2109 FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
2114 ParsedAttributes DeclSpecAttrs(AttrFactory);
2115 DG = ParseSimpleDeclaration(
2117 MightBeForRangeStmt ? &ForRangeInfo :
nullptr);
2118 FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
2119 if (ForRangeInfo.ParsedForRangeDecl()) {
2120 DiagCompat(ForRangeInfo.ColonLoc, diag_compat::for_range);
2121 ForRangeInfo.LoopVar = FirstPart;
2123 }
else if (Tok.is(tok::semi)) {
2125 }
else if ((ForEach = isTokIdentifier_in())) {
2126 Actions.ActOnForEachDeclStmt(DG);
2130 if (Tok.is(tok::code_completion)) {
2132 Actions.CodeCompletion().CodeCompleteObjCForCollection(
getCurScope(),
2138 Diag(Tok, diag::err_expected_semi_for);
2143 ExpansionStmtContextRAII EnterParentContext{
2144 Actions, ForRangeInfo, Actions.CurContext->getParent()};
2145 ProhibitAttributes(attrs);
2148 ForEach = isTokIdentifier_in();
2151 if (!
Value.isInvalid()) {
2153 FirstPart = Actions.ActOnForEachLValueExpr(
Value.get());
2160 bool IsRangeBasedFor =
2161 getLangOpts().CPlusPlus11 && !ForEach && Tok.is(tok::colon);
2162 FirstPart = Actions.ActOnExprStmt(
Value, !IsRangeBasedFor);
2166 if (Tok.is(tok::semi)) {
2168 }
else if (ForEach) {
2171 if (Tok.is(tok::code_completion)) {
2173 Actions.CodeCompletion().CodeCompleteObjCForCollection(
getCurScope(),
2181 Diag(Tok, diag::err_for_range_expected_decl)
2182 << (ESD !=
nullptr) << FirstPart.get()->getSourceRange();
2186 if (!
Value.isInvalid()) {
2187 Diag(Tok, diag::err_expected_semi_for);
2191 if (Tok.is(tok::semi))
2198 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl() &&
2201 if (Tok.is(tok::semi)) {
2203 }
else if (Tok.is(tok::r_paren)) {
2209 bool MightBeForRangeStmt = !ForRangeInfo.ParsedForRangeDecl();
2211 SourceLocation SecondPartStart = Tok.getLocation();
2213 SecondPart = ParseCondition(
2214 nullptr, ForLoc, CK,
2216 true, MightBeForRangeStmt ? &ForRangeInfo :
nullptr);
2218 if (ForRangeInfo.ParsedForRangeDecl()) {
2219 DiagCompat(FirstPart.get() ? FirstPart.get()->getBeginLoc()
2220 : ForRangeInfo.ColonLoc,
2221 diag_compat::for_range_init_stmt)
2222 << (FirstPart.get() ? FirstPart.get()->getSourceRange()
2224 if (EmptyInitStmtSemiLoc.
isValid()) {
2225 Diag(EmptyInitStmtSemiLoc, diag::warn_empty_init_statement)
2232 ExprResult CondExpr = Actions.CreateRecoveryExpr(
2234 Tok.getLocation() == SecondPartStart ? SecondPartStart
2236 {}, Actions.PreferredConditionType(CK));
2238 SecondPart = Actions.ActOnCondition(
getCurScope(), ForLoc,
2248 SecondPart = Actions.ActOnCondition(
2256 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl()) {
2257 if (Tok.isNot(tok::semi)) {
2259 Diag(Tok, diag::err_expected_semi_for);
2263 if (Tok.is(tok::semi)) {
2267 if (Tok.isNot(tok::r_paren)) {
2271 ThirdPart = Actions.MakeFullDiscardedValueExpr(Third.
get());
2279 if (CoawaitLoc.
isValid() && !ForRangeInfo.ParsedForRangeDecl()) {
2280 Diag(CoawaitLoc, diag::err_for_co_await_not_range_for);
2281 CoawaitLoc = SourceLocation();
2285 Diag(CoawaitLoc, diag::warn_deprecated_for_co_await);
2294 ForRangeStmt = Actions.ActOnCXXExpansionStmtPattern(
2295 ESD, FirstPart.get(), ForRangeInfo.LoopVar.get(),
2296 ForRangeInfo.RangeExpr.get(),
T.getOpenLocation(),
2297 ForRangeInfo.ColonLoc,
T.getCloseLocation(),
2298 ForRangeInfo.LifetimeExtendTemps);
2299 }
else if (ForRangeInfo.ParsedForRangeDecl()) {
2300 ForRangeStmt = Actions.ActOnCXXForRangeStmt(
2301 getCurScope(), ForLoc, CoawaitLoc, FirstPart.get(),
2302 ForRangeInfo.LoopVar.get(), ForRangeInfo.ColonLoc,
2304 ForRangeInfo.LifetimeExtendTemps);
2305 }
else if (ForEach) {
2308 ForEachStmt = Actions.ObjC().ActOnObjCForCollectionStmt(
2309 ForLoc, FirstPart.get(), Collection.
get(),
T.getCloseLocation());
2313 if (
getLangOpts().OpenMP && FirstPart.isUsable()) {
2314 Actions.OpenMP().ActOnOpenMPLoopInitialization(ForLoc, FirstPart.get());
2323 else if (ForRangeInfo.ParsedForRangeDecl())
2327 ForLoc, FirstPart.get(), SecondPart.
get().second, ThirdPart.get());
2333 bool BodyStartsWithAttr = Tok.isOneOf(tok::l_square, tok::kw___attribute);
2334 SourceLocation BodyBeginLoc = Tok.getLocation();
2348 Tok.is(tok::l_brace));
2357 MisleadingIndentationChecker MIChecker(*
this, MSK_for, ForLoc);
2360 StmtResult Body(ParseStatement(TrailingElseLoc));
2362 if (Body.isUsable())
2373 if (Body.isInvalid())
2377 return Actions.ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2381 if (!ForRangeInfo.ParsedForRangeDecl()) {
2382 Diag(ForLoc, diag::err_expansion_stmt_requires_range);
2391 ? diag::ext_expansion_stmt_body_attr
2392 : diag::ext_expansion_stmt_body_not_compound_stmt);
2394 return Actions.FinishCXXExpansionStmt(ForRangeStmt.get(), Body.get());
2397 if (ForRangeInfo.ParsedForRangeDecl())
2398 return Actions.FinishCXXForRangeStmt(ForRangeStmt.get(), Body.get());
2400 return Actions.ActOnForStmt(ForLoc,
T.getOpenLocation(), FirstPart.get(),
2401 SecondPart, ThirdPart,
T.getCloseLocation(),
2406 assert(Tok.is(tok::kw_goto) &&
"Not a goto stmt!");
2410 if (Tok.is(tok::identifier)) {
2411 LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(),
2413 Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(), LD);
2415 }
else if (Tok.is(tok::star)) {
2417 Diag(Tok, diag::ext_gnu_indirect_goto);
2420 if (
R.isInvalid()) {
2424 Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc,
R.get());
2426 Diag(Tok, diag::err_expected) << tok::identifier;
2433StmtResult Parser::ParseBreakOrContinueStatement(
bool IsContinue) {
2435 SourceLocation LabelLoc;
2436 LabelDecl *
Target =
nullptr;
2437 if (Tok.is(tok::identifier)) {
2439 Actions.LookupExistingLabel(Tok.getIdentifierInfo(), Tok.getLocation());
2444 Diag(LabelLoc, diag::err_c2y_labeled_break_continue) << IsContinue;
2446 Diag(LabelLoc, diag::err_break_continue_label_not_found) << IsContinue;
2457 return ParseBreakOrContinueStatement(
true);
2461 return ParseBreakOrContinueStatement(
false);
2465 assert((Tok.is(tok::kw_return) || Tok.is(tok::kw_co_return)) &&
2466 "Not a return stmt!");
2467 bool IsCoreturn = Tok.is(tok::kw_co_return);
2471 if (Tok.isNot(tok::semi)) {
2473 PreferredType.enterReturn(Actions, Tok.getLocation());
2475 if (Tok.is(tok::code_completion) && !IsCoreturn) {
2477 Actions.CodeCompletion().CodeCompleteExpression(
2478 getCurScope(), PreferredType.get(Tok.getLocation()));
2483 R = ParseInitializer();
2486 diag_compat::generalized_initializer_lists);
2489 if (
R.isInvalid()) {
2495 return Actions.ActOnCoreturnStmt(
getCurScope(), ReturnLoc,
R.get());
2496 return Actions.ActOnReturnStmt(ReturnLoc,
R.get(),
getCurScope());
2500 assert(Tok.is(tok::kw__Defer));
2503 Actions.ActOnStartOfDeferStmt(DeferLoc,
getCurScope());
2505 llvm::scope_exit OnError([&] { Actions.ActOnDeferStmtError(
getCurScope()); });
2507 StmtResult Res = ParseStatement(TrailingElseLoc);
2508 if (!Res.isUsable())
2512 if (
auto *L = dyn_cast<LabelStmt>(Res.get())) {
2513 Diag(L->getIdentLoc(), diag::err_defer_ts_labeled_stmt);
2518 return Actions.ActOnEndOfDeferStmt(Res.get(),
getCurScope());
2521StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
2522 ParsedStmtContext StmtCtx,
2527 ParsedAttributes TempAttrs(AttrFactory);
2529 SourceLocation StartLoc = Tok.getLocation();
2532 while (Tok.is(tok::annot_pragma_loop_hint)) {
2534 if (!HandlePragmaLoopHint(Hint))
2540 AttributeScopeInfo(), ArgHints, 4,
2541 ParsedAttr::Form::Pragma());
2545 MaybeParseCXX11Attributes(Attrs);
2547 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2548 StmtResult S = ParseStatementOrDeclarationAfterAttributes(
2549 Stmts, StmtCtx, TrailingElseLoc, Attrs, EmptyDeclSpecAttrs,
2562Decl *Parser::ParseFunctionStatementBody(
Decl *
Decl, ParseScope &BodyScope) {
2563 assert(Tok.is(tok::l_brace));
2564 SourceLocation LBraceLoc = Tok.getLocation();
2566 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, LBraceLoc,
2567 "parsing function body");
2572 Sema::PragmaStackSentinelRAII
2573 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2578 StmtResult FnBody(ParseCompoundStatementBody());
2581 if (FnBody.isInvalid()) {
2582 Sema::CompoundScopeRAII CompoundScope(Actions);
2583 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, {},
false);
2587 return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
2590Decl *Parser::ParseFunctionTryBlock(
Decl *
Decl, ParseScope &BodyScope) {
2591 assert(Tok.is(tok::kw_try) &&
"Expected 'try'");
2594 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, TryLoc,
2595 "parsing function try block");
2598 if (Tok.is(tok::colon))
2599 ParseConstructorInitializer(Decl);
2601 Actions.ActOnDefaultCtorInitializers(Decl);
2606 Sema::PragmaStackSentinelRAII
2607 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2609 SourceLocation LBraceLoc = Tok.getLocation();
2610 StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc,
true));
2613 if (FnBody.isInvalid()) {
2614 Sema::CompoundScopeRAII CompoundScope(Actions);
2615 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, {},
false);
2619 return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
2622bool Parser::trySkippingFunctionBody() {
2623 assert(SkipFunctionBodies &&
2624 "Should only be called when SkipFunctionBodies is enabled");
2625 if (!PP.isCodeCompletionEnabled()) {
2632 TentativeParsingAction PA(*
this);
2633 bool IsTryCatch = Tok.is(tok::kw_try);
2635 bool ErrorInPrologue = ConsumeAndStoreFunctionPrologue(Toks);
2636 if (llvm::any_of(Toks, [](
const Token &Tok) {
2637 return Tok.is(tok::code_completion);
2642 if (ErrorInPrologue) {
2651 while (IsTryCatch && Tok.is(tok::kw_catch)) {
2663 assert(Tok.is(tok::kw_try) &&
"Expected 'try'");
2666 return ParseCXXTryBlockCommon(TryLoc);
2670 if (Tok.isNot(tok::l_brace))
2671 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2677 if (TryBlock.isInvalid())
2682 if (isTokenSEHExcept() || Tok.is(tok::kw___finally)) {
2685 if (isTokenSEHExcept()) {
2687 Handler = ParseSEHExceptBlock(Loc);
2690 Handler = ParseSEHFinallyBlock(Loc);
2692 if(Handler.isInvalid())
2695 return Actions.ActOnSEHTryBlock(
true ,
2704 DiagnoseAndSkipCXX11Attributes();
2706 if (Tok.isNot(tok::kw_catch))
2708 while (Tok.is(tok::kw_catch)) {
2709 StmtResult Handler(ParseCXXCatchBlock(FnTry));
2710 if (!Handler.isInvalid())
2711 Handlers.push_back(Handler.get());
2715 if (Handlers.empty())
2718 return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.get(), Handlers);
2722StmtResult Parser::ParseCXXCatchBlock(
bool FnCatch) {
2723 assert(Tok.is(tok::kw_catch) &&
"Expected 'catch'");
2728 if (
T.expectAndConsume())
2740 Decl *ExceptionDecl =
nullptr;
2741 if (Tok.isNot(tok::ellipsis)) {
2742 ParsedAttributes Attributes(AttrFactory);
2743 MaybeParseCXX11Attributes(Attributes);
2745 DeclSpec DS(AttrFactory);
2747 if (ParseCXXTypeSpecifierSeq(DS))
2751 ParseDeclarator(ExDecl);
2752 ExceptionDecl = Actions.ActOnExceptionDeclarator(
getCurScope(), ExDecl);
2757 if (
T.getCloseLocation().isInvalid())
2760 if (Tok.isNot(tok::l_brace))
2761 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2765 if (
Block.isInvalid())
2768 return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl,
Block.get());
2774 assert(Tok.is(tok::kw_for));
2776 CXXExpansionStmtDecl *ExpansionDecl =
2777 Actions.ActOnCXXExpansionStmtDecl(TemplateParameterDepth, TemplateLoc);
2779 CXXExpansionStmtPattern *Expansion;
2781 Sema::ContextRAII CtxGuard(Actions, ExpansionDecl,
false);
2782 TemplateParameterDepthRAII TParamDepthGuard(TemplateParameterDepth);
2786 ParseForStatement(TrailingElseLoc, PrecedingLabel, ExpansionDecl);
2794 DeclSpec DS(AttrFactory);
2796 Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, {ExpansionDecl});
2798 return Actions.ActOnDeclStmt(DeclGroupPtr, Expansion->
getBeginLoc(),
2802void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
2803 IfExistsCondition
Result;
2804 if (ParseMicrosoftIfExistsCondition(
Result))
2812 if (!Tok.is(tok::l_brace)) {
2813 Diag(Tok, diag::err_expected) << tok::l_brace;
2817 StmtResult Compound = ParseCompoundStatement();
2818 if (Compound.isInvalid())
2821 StmtResult DepResult = Actions.ActOnMSDependentExistsStmt(
Result.KeywordLoc,
2826 if (DepResult.isUsable())
2827 Stmts.push_back(DepResult.get());
2832 if (
Braces.consumeOpen()) {
2833 Diag(Tok, diag::err_expected) << tok::l_brace;
2837 switch (
Result.Behavior) {
2843 llvm_unreachable(
"Dependent case handled above");
2851 while (Tok.isNot(tok::r_brace)) {
2853 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::Compound);
2855 Stmts.push_back(
R.get());
This file defines the classes used to store parsed information about declaration-specifiers and decla...
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.
Defines the clang::TokenKind enum and support functions.
Represents a C++26 expansion statement declaration.
void setExpansionPattern(CXXExpansionStmtPattern *S)
SourceLocation getEndLoc() const
SourceLocation getBeginLoc() const
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...
bool hasConstexprSpecifier() const
Decl - This represents one declaration (or definition), e.g.
DiagnosticOptions & getDiagnosticOptions() const
Retrieve the diagnostic options.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
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...
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.
IdentifierInfo * getIdentifierInfo() const
Represents the declaration of a label.
@ FEM_Source
Use the declared type for fp arithmetic.
ParsedAttributes - A collection of parsed attributes.
void takeAllPrependingFrom(ParsedAttributes &Other)
void takeAllAppendingFrom(ParsedAttributes &Other)
ParseScope - Introduces a new scope for parsing.
Parser - This implements a parser for the C family of languages.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation getEndOfPreviousToken() const
DiagnosticBuilder DiagCompat(SourceLocation Loc, unsigned CompatDiagId)
Preprocessor & getPreprocessor() const
Sema::FullExprArg FullExprArg
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Sema & getActions() const
ExprResult ParseCaseExpression(SourceLocation CaseLoc)
SmallVector< Stmt *, 24 > StmtVector
A SmallVector of statements.
friend class ColonProtectionRAIIObject
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
StmtResult ParseOpenACCDirectiveStmt()
bool TryConsumeToken(tok::TokenKind Expected)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Scope * getCurScope() const
friend class InMessageExpressionRAIIObject
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 Token & getCurToken() const
SourceLocation MisleadingIndentationElseLoc
The location of the first statement inside an else that might have a missleading indentation.
const LangOptions & getLangOpts() const
friend class ParenBraceBracketBalancer
ExprResult ParseExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Simple precedence-based parser for binary/ternary operators.
@ 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.
friend class BalancedDelimiterTracker
A class for parsing a DeclSpec.
unsigned getNumDirectives() const
Retrieve the number of Directives that have been processed by the Preprocessor.
const Token & LookAhead(unsigned N)
Peeks ahead N tokens and returns that token without consuming any tokens.
SourceManager & getSourceManager() const
void EnterSwitchBody(LabelDecl *PrecedingLabel)
Mark that we're entering the body of a switch statement.
void LeaveLoopBody()
Mark that we're leaving the body of a loop; this is only needed for do loops where the condition foll...
void decrementMSManglingNumber()
void EnterLoopBody(LabelDecl *PrecedingLabel)
Mark that we're entering the body of a loop (for, while, do).
@ SEHTryScope
This scope corresponds to an SEH try.
@ ControlScope
The controlling scope in a if/switch/while/for statement.
@ ExpansionStmtScope
This is the scope of a C++26 expansion statement.
@ TemplateParamScope
This is a scope that corresponds to the template parameters of a C++ template.
@ SEHFilterScope
We are currently in the filter expression of an SEH except block.
@ SwitchScope
This is a scope that corresponds to a switch statement.
@ 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 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)
std::pair< VarDecl *, Expr * > get() const
std::optional< bool > getKnownValue() const
@ 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'.
DiagnosticsEngine & getDiagnostics() const
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.
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
@ ImmediateFunctionContext
In addition of being constant evaluated, the current expression occurs in an immediate function conte...
@ BFRK_Build
Initial building of a for-range statement.
static ConditionResult ConditionError()
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
FileIDAndOffset getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
DiagnosticsEngine & getDiagnostics() const
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
void setBegin(SourceLocation b)
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceLocation getBeginLoc() const LLVM_READONLY
IdentifierInfo * getIdentifierInfo() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
bool isOneOf(Ts... Ks) 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)
DeclClass * getCorrectionDeclAs() const
NestedNameSpecifier getCorrectionSpecifier() const
Gets the NestedNameSpecifier needed to use the typo correction.
Defines the clang::TargetInfo interface.
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
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.
@ Error
Annotation has failed and emitted an error.
std::pair< FileID, unsigned > FileIDAndOffset
@ Dependent
Parse the block as a dependent block, which may be used in some template instantiations but not other...
@ Skip
Skip the block entirely; this code is never used.
@ Parse
Parse the block; this code is always used.
@ Result
The result type of a method or function.
const FunctionProtoType * T
void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &&Second)
Consumes the attributes from Second and concatenates them at the end of First.
U cast(CodeGen::Address addr)
SmallVector< Token, 4 > CachedTokens
A set of tokens that has been cached for later parsing.
ActionResult< Expr * > ExprResult
@ Braces
New-expression has a C++11 list-initializer.
ActionResult< Stmt * > StmtResult
IdentifierLoc * OptionLoc
IdentifierLoc * PragmaNameLoc