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/Traits.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 (Tok.is(tok::identifier) &&
615 Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
617 Handler = ParseSEHExceptBlock(Loc);
618 }
else if (Tok.is(tok::kw___finally)) {
620 Handler = ParseSEHFinallyBlock(Loc);
625 if(Handler.isInvalid())
628 return Actions.ActOnSEHTryBlock(
false ,
635 PoisonIdentifierRAIIObject raii(Ident__exception_code,
false),
636 raii2(Ident___exception_code,
false),
637 raii3(Ident_GetExceptionCode,
false);
639 if (ExpectAndConsume(tok::l_paren))
646 Ident__exception_info->setIsPoisoned(
false);
647 Ident___exception_info->setIsPoisoned(
false);
648 Ident_GetExceptionInfo->setIsPoisoned(
false);
653 ParseScopeFlags FilterScope(
this,
getCurScope()->getFlags() |
659 Ident__exception_info->setIsPoisoned(
true);
660 Ident___exception_info->setIsPoisoned(
true);
661 Ident_GetExceptionInfo->setIsPoisoned(
true);
667 if (ExpectAndConsume(tok::r_paren))
670 if (Tok.isNot(tok::l_brace))
671 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
675 if(
Block.isInvalid())
678 return Actions.ActOnSEHExceptBlock(ExceptLoc, FilterExpr.
get(),
Block.get());
682 PoisonIdentifierRAIIObject raii(Ident__abnormal_termination,
false),
683 raii2(Ident___abnormal_termination,
false),
684 raii3(Ident_AbnormalTermination,
false);
686 if (Tok.isNot(tok::l_brace))
687 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
690 Actions.ActOnStartSEHFinallyBlock();
693 if(
Block.isInvalid()) {
694 Actions.ActOnAbortSEHFinallyBlock();
698 return Actions.ActOnFinishSEHFinallyBlock(FinallyLoc,
Block.get());
708 return Actions.ActOnSEHLeaveStmt(LeaveLoc,
getCurScope());
718 ? diag::warn_c23_compat_label_followed_by_declaration
719 : diag::ext_c_label_followed_by_declaration);
724 ParsedStmtContext StmtCtx) {
725 assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
726 "Not an identifier!");
731 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
733 Token IdentTok = Tok;
736 assert(Tok.is(tok::colon) &&
"Not a label!");
741 LabelDecl *LD = Actions.LookupOrCreateLabel(
747 if (Tok.is(tok::kw___attribute)) {
748 ParsedAttributes TempAttrs(AttrFactory);
749 ParseGNUAttributes(TempAttrs);
762 ParsedAttributes EmptyCXX11Attrs(AttrFactory);
763 SubStmt = ParseStatementOrDeclarationAfterAttributes(
764 Stmts, StmtCtx,
nullptr, EmptyCXX11Attrs,
766 if (!TempAttrs.empty() && !SubStmt.isInvalid())
767 SubStmt = Actions.ActOnAttributedStmt(TempAttrs, SubStmt.get());
772 if (SubStmt.isUnset() && Tok.is(tok::r_brace)) {
773 DiagnoseLabelAtEndOfCompoundStatement();
774 SubStmt = Actions.ActOnNullStmt(ColonLoc);
778 if (SubStmt.isUnset())
779 SubStmt = ParseStatement(
nullptr, StmtCtx, LD);
782 if (SubStmt.isInvalid())
783 SubStmt = Actions.ActOnNullStmt(ColonLoc);
791 return SubStmt.get();
794 Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
797 return Actions.ActOnLabelStmt(IdentTok.
getLocation(), LD, ColonLoc,
801StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx,
803 assert((MissingCase || Tok.is(tok::kw_case)) &&
"Not a case stmt!");
808 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
831 Stmt *DeepestParsedCaseStmt =
nullptr;
834 SourceLocation ColonLoc;
836 SourceLocation CaseLoc = MissingCase ? Expr.
get()->
getExprLoc() :
838 ColonLoc = SourceLocation();
840 if (Tok.is(tok::code_completion)) {
842 Actions.CodeCompletion().CodeCompleteCase(
getCurScope());
861 LHS = Actions.ActOnCaseExpr(CaseLoc, Expr);
866 SourceLocation DotDotDotLoc;
872 DiagId = diag::ext_gnu_case_range;
874 DiagId = diag::warn_c23_compat_case_range;
876 DiagId = diag::ext_c2y_case_range;
877 Diag(DotDotDotLoc, DiagId);
885 ColonProtection.restore();
891 Diag(ColonLoc, diag::err_expected_after)
892 <<
"'case'" << tok::colon
897 Diag(ExpectedLoc, diag::err_expected_after)
898 <<
"'case'" << tok::colon
901 ColonLoc = ExpectedLoc;
905 Actions.ActOnCaseStmt(CaseLoc, LHS, DotDotDotLoc, RHS, ColonLoc);
909 if (Case.isInvalid()) {
910 if (TopLevelCase.isInvalid())
911 return ParseStatement(
nullptr, StmtCtx);
916 Stmt *NextDeepest = Case.get();
917 if (TopLevelCase.isInvalid())
920 Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, Case.get());
921 DeepestParsedCaseStmt = NextDeepest;
925 }
while (Tok.is(tok::kw_case));
930 if (Tok.is(tok::r_brace)) {
933 DiagnoseLabelAtEndOfCompoundStatement();
934 SubStmt = Actions.ActOnNullStmt(ColonLoc);
936 SubStmt = ParseStatement(
nullptr, StmtCtx);
940 if (DeepestParsedCaseStmt) {
942 if (SubStmt.isInvalid())
943 SubStmt = Actions.ActOnNullStmt(SourceLocation());
945 Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, SubStmt.get());
952StmtResult Parser::ParseDefaultStatement(ParsedStmtContext StmtCtx) {
953 assert(Tok.is(tok::kw_default) &&
"Not a default stmt!");
958 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
962 SourceLocation ColonLoc;
966 Diag(ColonLoc, diag::err_expected_after)
967 <<
"'default'" << tok::colon
970 SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation);
971 Diag(ExpectedLoc, diag::err_expected_after)
972 <<
"'default'" << tok::colon
974 ColonLoc = ExpectedLoc;
979 if (Tok.is(tok::r_brace)) {
982 DiagnoseLabelAtEndOfCompoundStatement();
983 SubStmt = Actions.ActOnNullStmt(ColonLoc);
985 SubStmt = ParseStatement(
nullptr, StmtCtx);
989 if (SubStmt.isInvalid())
990 SubStmt = Actions.ActOnNullStmt(ColonLoc);
993 return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc,
997StmtResult Parser::ParseCompoundStatement(
bool isStmtExpr) {
998 return ParseCompoundStatement(isStmtExpr,
1002StmtResult Parser::ParseCompoundStatement(
bool isStmtExpr,
1003 unsigned ScopeFlags) {
1004 assert(Tok.is(tok::l_brace) &&
"Not a compound stmt!");
1012 StackHandler.runWithSufficientStackSpace(Tok.getLocation(), [&,
this]() {
1013 R = ParseCompoundStatementBody(isStmtExpr);
1018void Parser::ParseCompoundStatementLeadingPragmas() {
1019 bool checkForPragmas =
true;
1020 while (checkForPragmas) {
1021 switch (Tok.getKind()) {
1022 case tok::annot_pragma_vis:
1023 HandlePragmaVisibility();
1025 case tok::annot_pragma_pack:
1028 case tok::annot_pragma_msstruct:
1029 HandlePragmaMSStruct();
1031 case tok::annot_pragma_align:
1032 HandlePragmaAlign();
1034 case tok::annot_pragma_weak:
1037 case tok::annot_pragma_weakalias:
1038 HandlePragmaWeakAlias();
1040 case tok::annot_pragma_redefine_extname:
1041 HandlePragmaRedefineExtname();
1043 case tok::annot_pragma_opencl_extension:
1044 HandlePragmaOpenCLExtension();
1046 case tok::annot_pragma_fp_contract:
1047 HandlePragmaFPContract();
1049 case tok::annot_pragma_fp:
1052 case tok::annot_pragma_fenv_access:
1053 case tok::annot_pragma_fenv_access_ms:
1054 HandlePragmaFEnvAccess();
1056 case tok::annot_pragma_fenv_round:
1057 HandlePragmaFEnvRound();
1059 case tok::annot_pragma_cx_limited_range:
1060 HandlePragmaCXLimitedRange();
1062 case tok::annot_pragma_float_control:
1063 HandlePragmaFloatControl();
1065 case tok::annot_pragma_ms_pointers_to_members:
1066 HandlePragmaMSPointersToMembers();
1068 case tok::annot_pragma_ms_pragma:
1069 HandlePragmaMSPragma();
1071 case tok::annot_pragma_ms_vtordisp:
1072 HandlePragmaMSVtorDisp();
1074 case tok::annot_pragma_dump:
1077 case tok::annot_pragma_export:
1078 HandlePragmaExport();
1081 checkForPragmas =
false;
1088void Parser::DiagnoseLabelAtEndOfCompoundStatement() {
1091 ? diag::warn_cxx20_compat_label_end_of_compound_statement
1092 : diag::ext_cxx_label_end_of_compound_statement);
1095 ? diag::warn_c23_compat_label_end_of_compound_statement
1096 : diag::ext_c_label_end_of_compound_statement);
1100bool Parser::ConsumeNullStmt(StmtVector &Stmts) {
1101 if (!Tok.is(tok::semi))
1104 SourceLocation StartLoc = Tok.getLocation();
1105 SourceLocation EndLoc;
1107 while (Tok.is(tok::semi) && !Tok.hasLeadingEmptyMacro() &&
1108 Tok.getLocation().isValid() && !Tok.getLocation().isMacroID()) {
1109 EndLoc = Tok.getLocation();
1113 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::SubStmt);
1115 Stmts.push_back(
R.get());
1122 Diag(StartLoc, diag::warn_null_statement)
1128 bool IsStmtExprResult =
false;
1129 if ((StmtCtx & ParsedStmtContext::InStmtExpr) != ParsedStmtContext()) {
1133 IsStmtExprResult = Tok.is(tok::r_brace) &&
NextToken().
is(tok::r_paren);
1136 if (IsStmtExprResult)
1137 E = Actions.ActOnStmtExprResult(E);
1138 return Actions.ActOnExprStmt(E, !IsStmtExprResult);
1141StmtResult Parser::ParseCompoundStatementBody(
bool isStmtExpr) {
1142 PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),
1144 "in compound statement ('{}')");
1148 Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);
1152 if (
T.consumeOpen())
1155 Sema::CompoundScopeRAII CompoundScope(Actions, isStmtExpr);
1158 ParseCompoundStatementLeadingPragmas();
1159 Actions.ActOnAfterCompoundStatementLeadingPragmas();
1165 while (Tok.is(tok::kw___label__)) {
1168 SmallVector<Decl *, 4> DeclsInGroup;
1170 if (Tok.isNot(tok::identifier)) {
1171 Diag(Tok, diag::err_expected) << tok::identifier;
1175 IdentifierInfo *II = Tok.getIdentifierInfo();
1177 DeclsInGroup.push_back(Actions.LookupOrCreateLabel(II, IdLoc, LabelLoc));
1183 DeclSpec DS(AttrFactory);
1185 Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, DeclsInGroup);
1186 StmtResult R = Actions.ActOnDeclStmt(Res, LabelLoc, Tok.getLocation());
1188 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
1190 Stmts.push_back(
R.get());
1193 ParsedStmtContext SubStmtCtx =
1194 ParsedStmtContext::Compound |
1195 (isStmtExpr ? ParsedStmtContext::InStmtExpr : ParsedStmtContext());
1197 bool LastIsError =
false;
1198 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
1199 Tok.isNot(tok::eof)) {
1200 if (Tok.is(tok::annot_pragma_unused)) {
1201 HandlePragmaUnused();
1205 if (ConsumeNullStmt(Stmts))
1209 if (Tok.isNot(tok::kw___extension__)) {
1210 R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
1217 while (Tok.is(tok::kw___extension__))
1220 ParsedAttributes attrs(AttrFactory);
1221 MaybeParseCXX11Attributes(attrs,
true);
1224 if (isDeclarationStatement()) {
1227 ExtensionRAIIObject O(Diags);
1229 SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
1230 ParsedAttributes DeclSpecAttrs(AttrFactory);
1232 attrs, DeclSpecAttrs);
1233 R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);
1236 ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
1238 if (Res.isInvalid()) {
1245 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
1246 R = handleExprStmt(Res, SubStmtCtx);
1248 R = Actions.ActOnAttributedStmt(attrs,
R.get());
1253 Stmts.push_back(
R.get());
1254 LastIsError =
R.isInvalid();
1260 if (isStmtExpr && LastIsError && !Stmts.empty())
1267 if (!PP.getTargetInfo().supportSourceEvalMethod() &&
1268 (PP.getLastFPEvalPragmaLocation().isValid() ||
1269 PP.getCurrentFPEvalMethod() ==
1271 Diag(Tok.getLocation(),
1272 diag::warn_no_support_for_eval_method_source_on_m32);
1274 SourceLocation CloseLoc = Tok.getLocation();
1277 if (!
T.consumeClose()) {
1280 if (isStmtExpr && Tok.is(tok::r_paren))
1281 checkCompoundToken(CloseLoc, tok::r_brace, CompoundToken::StmtExprEnd);
1287 if (
T.getCloseLocation().isValid())
1288 CloseLoc =
T.getCloseLocation();
1290 return Actions.ActOnCompoundStmt(
T.getOpenLocation(), CloseLoc,
1294bool Parser::ParseParenExprOrCondition(
StmtResult *InitStmt,
1302 SourceLocation Start = Tok.getLocation();
1304 Cond = ParseCondition(InitStmt, Loc, CK,
false);
1309 if (
Cond.isInvalid() && Tok.isNot(tok::r_paren)) {
1313 if (Tok.isNot(tok::r_paren))
1317 if (
Cond.isInvalid()) {
1318 ExprResult CondExpr = Actions.CreateRecoveryExpr(
1319 Start, Tok.getLocation() == Start ? Start : PrevTokLocation, {},
1320 Actions.PreferredConditionType(CK));
1327 if (InitStmt !=
nullptr && InitStmt->isUsable()) {
1333 Diag(InitStmt->get()->getBeginLoc(),
1334 diag::err_c2y_first_condition_clause_is_not_declaration)
1335 << InitStmt->get()->getSourceRange();
1337 if (
Cond.get().first !=
nullptr)
1341 }
else if (
Cond.get().first !=
nullptr)
1347 if (Tok.is(tok::comma)) {
1348 Diag(Tok, diag::err_c2y_multiple_declarations);
1350 while (Tok.isNot(tok::r_paren) && !Tok.is(tok::eof))
1355 LParenLoc =
T.getOpenLocation();
1356 RParenLoc =
T.getCloseLocation();
1361 while (Tok.is(tok::r_paren)) {
1362 Diag(Tok, diag::err_extraneous_rparen_in_condition)
1372enum MisleadingStatementKind { MSK_if, MSK_else, MSK_for, MSK_while };
1374struct MisleadingIndentationChecker {
1376 SourceLocation StmtLoc;
1377 SourceLocation PrevLoc;
1378 unsigned NumDirectives;
1379 MisleadingStatementKind
Kind;
1381 MisleadingIndentationChecker(Parser &P, MisleadingStatementKind K,
1383 : P(P), StmtLoc(SL), PrevLoc(P.getCurToken().getLocation()),
1384 NumDirectives(P.getPreprocessor().getNumDirectives()),
Kind(K),
1385 ShouldSkip(P.getCurToken().
is(tok::l_brace)) {
1387 StmtLoc = P.MisleadingIndentationElseLoc;
1388 P.MisleadingIndentationElseLoc = SourceLocation();
1390 if (Kind == MSK_else && !ShouldSkip)
1396 static unsigned getVisualIndentation(SourceManager &
SM, SourceLocation Loc) {
1397 unsigned TabStop =
SM.getDiagnostics().getDiagnosticOptions().TabStop;
1399 unsigned ColNo =
SM.getSpellingColumnNumber(Loc);
1400 if (ColNo == 0 || TabStop == 1)
1406 StringRef BufData =
SM.getBufferData(FIDAndOffset.first, &
Invalid);
1410 const char *EndPos = BufData.data() + FIDAndOffset.second;
1412 assert(FIDAndOffset.second + 1 >= ColNo &&
1413 "Column number smaller than file offset?");
1415 unsigned VisualColumn = 0;
1418 for (
const char *CurPos = EndPos - (ColNo - 1); CurPos != EndPos;
1420 if (*CurPos ==
'\t')
1422 VisualColumn += (TabStop - VisualColumn % TabStop);
1426 return VisualColumn + 1;
1441 if (Kind == MSK_else)
1445 unsigned PrevColNum = getVisualIndentation(
SM, PrevLoc);
1447 unsigned StmtColNum = getVisualIndentation(
SM, StmtLoc);
1449 if (PrevColNum != 0 && CurColNum != 0 && StmtColNum != 0 &&
1450 ((PrevColNum > StmtColNum && PrevColNum == CurColNum) ||
1452 SM.getPresumedLineNumber(StmtLoc) !=
1457 P.
Diag(StmtLoc, diag::note_previous_statement);
1465 assert(Tok.is(tok::kw_if) &&
"Not an if stmt!");
1468 bool IsConstexpr =
false;
1469 bool IsConsteval =
false;
1470 SourceLocation NotLocation;
1471 SourceLocation ConstevalLoc;
1473 if (Tok.is(tok::kw_constexpr)) {
1477 : diag::ext_constexpr_if);
1482 if (Tok.is(tok::exclaim)) {
1486 if (Tok.is(tok::kw_consteval)) {
1488 : diag::ext_consteval_if);
1491 }
else if (Tok.is(tok::code_completion)) {
1493 Actions.CodeCompletion().CodeCompleteKeywordAfterIf(
1498 if (!IsConsteval && (NotLocation.
isValid() || Tok.isNot(tok::l_paren))) {
1499 Diag(Tok, diag::err_expected_lparen_after) <<
"if";
1522 Sema::ConditionResult
Cond;
1523 SourceLocation LParen;
1524 SourceLocation RParen;
1525 std::optional<bool> ConstexprCondition;
1528 if (ParseParenExprOrCondition(&InitStmt,
Cond, IfLoc,
1535 ConstexprCondition =
Cond.getKnownValue();
1538 bool IsBracedThen = Tok.is(tok::l_brace);
1560 MisleadingIndentationChecker MIChecker(*
this, MSK_if, IfLoc);
1563 SourceLocation ThenStmtLoc = Tok.getLocation();
1565 SourceLocation InnerStatementTrailingElseLoc;
1568 bool ShouldEnter = ConstexprCondition && !*ConstexprCondition;
1571 if (NotLocation.
isInvalid() && IsConsteval) {
1576 EnterExpressionEvaluationContext PotentiallyDiscarded(
1577 Actions, Context,
nullptr,
1579 ThenStmt = ParseStatement(&InnerStatementTrailingElseLoc);
1582 if (Tok.isNot(tok::kw_else))
1589 SourceLocation ElseLoc;
1590 SourceLocation ElseStmtLoc;
1593 if (Tok.is(tok::kw_else)) {
1594 if (TrailingElseLoc)
1595 *TrailingElseLoc = Tok.getLocation();
1598 ElseStmtLoc = Tok.getLocation();
1610 Tok.is(tok::l_brace));
1612 MisleadingIndentationChecker MIChecker(*
this, MSK_else, ElseLoc);
1613 bool ShouldEnter = ConstexprCondition && *ConstexprCondition;
1616 if (NotLocation.
isValid() && IsConsteval) {
1621 EnterExpressionEvaluationContext PotentiallyDiscarded(
1622 Actions, Context,
nullptr,
1624 ElseStmt = ParseStatement();
1626 if (ElseStmt.isUsable())
1631 }
else if (Tok.is(tok::code_completion)) {
1633 Actions.CodeCompletion().CodeCompleteAfterIf(
getCurScope(), IsBracedThen);
1635 }
else if (InnerStatementTrailingElseLoc.
isValid()) {
1636 Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else);
1644 if ((ThenStmt.isInvalid() && ElseStmt.isInvalid()) ||
1645 (ThenStmt.isInvalid() && ElseStmt.get() ==
nullptr) ||
1646 (ThenStmt.get() ==
nullptr && ElseStmt.isInvalid())) {
1652 auto IsCompoundStatement = [](
const Stmt *S) {
1653 if (
const auto *Outer = dyn_cast_if_present<AttributedStmt>(S))
1654 S = Outer->getSubStmt();
1655 return isa_and_nonnull<clang::CompoundStmt>(S);
1658 if (!IsCompoundStatement(ThenStmt.get())) {
1659 Diag(ConstevalLoc, diag::err_expected_after) <<
"consteval"
1663 if (!ElseStmt.isUnset() && !IsCompoundStatement(ElseStmt.get())) {
1664 Diag(ElseLoc, diag::err_expected_after) <<
"else"
1671 if (ThenStmt.isInvalid())
1672 ThenStmt = Actions.ActOnNullStmt(ThenStmtLoc);
1673 if (ElseStmt.isInvalid())
1674 ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);
1679 else if (IsConsteval)
1683 return Actions.ActOnIfStmt(IfLoc, Kind, LParen, InitStmt.get(),
Cond, RParen,
1684 ThenStmt.get(), ElseLoc, ElseStmt.get());
1689 assert(Tok.is(tok::kw_switch) &&
"Not a switch stmt!");
1692 if (Tok.isNot(tok::l_paren)) {
1693 Diag(Tok, diag::err_expected_lparen_after) <<
"switch";
1719 Sema::ConditionResult
Cond;
1720 SourceLocation LParen;
1721 SourceLocation RParen;
1722 if (ParseParenExprOrCondition(&InitStmt,
Cond, SwitchLoc,
1727 SwitchLoc, LParen, InitStmt.get(),
Cond, RParen);
1729 if (
Switch.isInvalid()) {
1734 if (Tok.is(tok::l_brace)) {
1762 StmtResult Body(ParseStatement(TrailingElseLoc));
1768 return Actions.ActOnFinishSwitchStmt(SwitchLoc,
Switch.get(), Body.get());
1773 assert(Tok.is(tok::kw_while) &&
"Not a while stmt!");
1774 SourceLocation WhileLoc = Tok.getLocation();
1777 if (Tok.isNot(tok::l_paren)) {
1778 Diag(Tok, diag::err_expected_lparen_after) <<
"while";
1797 unsigned ScopeFlags =
1802 Sema::ConditionResult
Cond;
1803 SourceLocation LParen;
1804 SourceLocation RParen;
1805 if (ParseParenExprOrCondition(
nullptr,
Cond, WhileLoc,
1828 MisleadingIndentationChecker MIChecker(*
this, MSK_while, WhileLoc);
1831 StmtResult Body(ParseStatement(TrailingElseLoc));
1833 if (Body.isUsable())
1839 if (
Cond.isInvalid() || Body.isInvalid())
1842 return Actions.ActOnWhileStmt(WhileLoc, LParen,
Cond, RParen, Body.get());
1846 assert(Tok.is(tok::kw_do) &&
"Not a do stmt!");
1880 if (Tok.isNot(tok::kw_while)) {
1881 if (!Body.isInvalid()) {
1882 Diag(Tok, diag::err_expected_while);
1883 Diag(DoLoc, diag::note_matching) <<
"'do'";
1890 if (Tok.isNot(tok::l_paren)) {
1891 Diag(Tok, diag::err_expected_lparen_after) <<
"do/while";
1901 DiagnoseAndSkipCXX11Attributes();
1903 SourceLocation Start = Tok.getLocation();
1905 if (!
Cond.isUsable()) {
1906 if (!Tok.isOneOf(tok::r_paren, tok::r_square, tok::r_brace))
1908 Cond = Actions.CreateRecoveryExpr(
1909 Start, Start == Tok.getLocation() ? Start : PrevTokLocation, {},
1910 Actions.getASTContext().BoolTy);
1915 if (
Cond.isInvalid() || Body.isInvalid())
1918 return Actions.ActOnDoStmt(DoLoc, Body.get(), WhileLoc,
T.getOpenLocation(),
1919 Cond.get(),
T.getCloseLocation());
1922bool Parser::isForRangeIdentifier() {
1923 assert(Tok.is(tok::identifier));
1926 if (
Next.is(tok::colon))
1929 if (
Next.isOneOf(tok::l_square, tok::kw_alignas)) {
1930 TentativeParsingAction PA(*
this);
1932 SkipCXX11Attributes();
1933 bool Result = Tok.is(tok::colon);
1941void Parser::ParseForRangeInitializerAfterColon(ForRangeInit &FRI,
1949 EnterExpressionEvaluationContext InitContext(
1957 auto &LastRecord = Actions.currentEvaluationContext();
1958 LastRecord.InLifetimeExtendingContext =
true;
1959 LastRecord.RebuildDefaultArgOrDefaultInit =
true;
1962 if (FRI.ExpansionStmt) {
1965 assert(Actions.CurContext->isExpansionStmt());
1966 Sema::ContextRAII CtxGuard(Actions, Actions.CurContext->getParent(),
1970 FRI.RangeExpr = Actions.MaybeCreateExprWithCleanups(FRI.RangeExpr);
1971 }
else if (Tok.is(tok::l_brace)) {
1972 FRI.RangeExpr = ParseBraceInitializer();
1979 Actions.ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
1983 FRI.LifetimeExtendTemps =
1984 std::move(Actions.ExprEvalContexts.back().ForRangeLifetimeExtendTemps);
1990 assert(Tok.is(tok::kw_for) &&
"Not a for stmt!");
1993 SourceLocation CoawaitLoc;
1994 if (Tok.is(tok::kw_co_await))
1997 if (Tok.isNot(tok::l_paren)) {
1998 Diag(Tok, diag::err_expected_lparen_after) <<
"for";
2035 bool ForEach =
false;
2037 Sema::ConditionResult SecondPart;
2039 ForRangeInfo ForRangeInfo;
2041 ForRangeInfo.ExpansionStmt = ESD;
2048 struct [[nodiscard]] ExpansionStmtContextRAII : Sema::ContextRAII {
2049 ExpansionStmtContextRAII(Sema &S,
struct ForRangeInfo &Info,
2051 : ContextRAII(S, Info.ExpansionStmt ? Ctx : S.CurContext,
2055 assert(!ESD || Actions.CurContext->isExpansionStmt());
2056 if (Tok.is(tok::code_completion)) {
2058 Actions.CodeCompletion().CodeCompleteOrdinaryName(
2064 ParsedAttributes attrs(AttrFactory);
2065 MaybeParseCXX11Attributes(attrs);
2067 SourceLocation EmptyInitStmtSemiLoc;
2070 if (Tok.is(tok::semi)) {
2071 ProhibitAttributes(attrs);
2073 SourceLocation SemiLoc = Tok.getLocation();
2074 if (!Tok.hasLeadingEmptyMacro() && !SemiLoc.
isMacroID())
2075 EmptyInitStmtSemiLoc = SemiLoc;
2078 isForRangeIdentifier()) {
2082 ProhibitAttributes(attrs);
2083 IdentifierInfo *Name = Tok.getIdentifierInfo();
2085 MaybeParseCXX11Attributes(attrs);
2088 ParseForRangeInitializerAfterColon(ForRangeInfo,
nullptr);
2090 Diag(Loc, diag::err_for_range_identifier)
2091 << (ForRangeInfo.ExpansionStmt !=
nullptr)
2096 if (!ForRangeInfo.ExpansionStmt)
2097 ForRangeInfo.LoopVar =
2098 Actions.ActOnCXXForRangeIdentifier(
getCurScope(), Loc, Name, attrs);
2099 }
else if (isForInitDeclaration()) {
2101 ExpansionStmtContextRAII EnterParentContext{
2102 Actions, ForRangeInfo, Actions.CurContext->getParent()};
2105 if (!C99orCXXorObjC) {
2106 Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
2107 Diag(Tok, diag::warn_gcc_variable_decl_in_for_loop);
2110 SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
2112 Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
2113 ProhibitAttributes(attrs);
2114 Decl *D = ParseStaticAssertDeclaration(DeclEnd);
2115 DG = Actions.ConvertDeclToDeclGroup(D);
2116 FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
2117 }
else if (Tok.is(tok::kw_using)) {
2120 FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
2125 ParsedAttributes DeclSpecAttrs(AttrFactory);
2126 DG = ParseSimpleDeclaration(
2128 MightBeForRangeStmt ? &ForRangeInfo :
nullptr);
2129 FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
2130 if (ForRangeInfo.ParsedForRangeDecl()) {
2132 ? diag::warn_cxx98_compat_for_range
2133 : diag::ext_for_range);
2134 ForRangeInfo.LoopVar = FirstPart;
2136 }
else if (Tok.is(tok::semi)) {
2138 }
else if ((ForEach = isTokIdentifier_in())) {
2139 Actions.ActOnForEachDeclStmt(DG);
2143 if (Tok.is(tok::code_completion)) {
2145 Actions.CodeCompletion().CodeCompleteObjCForCollection(
getCurScope(),
2151 Diag(Tok, diag::err_expected_semi_for);
2156 ExpansionStmtContextRAII EnterParentContext{
2157 Actions, ForRangeInfo, Actions.CurContext->getParent()};
2158 ProhibitAttributes(attrs);
2161 ForEach = isTokIdentifier_in();
2164 if (!
Value.isInvalid()) {
2166 FirstPart = Actions.ActOnForEachLValueExpr(
Value.get());
2173 bool IsRangeBasedFor =
2174 getLangOpts().CPlusPlus11 && !ForEach && Tok.is(tok::colon);
2175 FirstPart = Actions.ActOnExprStmt(
Value, !IsRangeBasedFor);
2179 if (Tok.is(tok::semi)) {
2181 }
else if (ForEach) {
2184 if (Tok.is(tok::code_completion)) {
2186 Actions.CodeCompletion().CodeCompleteObjCForCollection(
getCurScope(),
2194 Diag(Tok, diag::err_for_range_expected_decl)
2195 << (ESD !=
nullptr) << FirstPart.get()->getSourceRange();
2199 if (!
Value.isInvalid()) {
2200 Diag(Tok, diag::err_expected_semi_for);
2204 if (Tok.is(tok::semi))
2211 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl() &&
2214 if (Tok.is(tok::semi)) {
2216 }
else if (Tok.is(tok::r_paren)) {
2222 bool MightBeForRangeStmt = !ForRangeInfo.ParsedForRangeDecl();
2224 SourceLocation SecondPartStart = Tok.getLocation();
2226 SecondPart = ParseCondition(
2227 nullptr, ForLoc, CK,
2229 true, MightBeForRangeStmt ? &ForRangeInfo :
nullptr);
2231 if (ForRangeInfo.ParsedForRangeDecl()) {
2232 Diag(FirstPart.get() ? FirstPart.get()->getBeginLoc()
2233 : ForRangeInfo.ColonLoc,
2235 ? diag::warn_cxx17_compat_for_range_init_stmt
2236 : diag::ext_for_range_init_stmt)
2237 << (FirstPart.get() ? FirstPart.get()->getSourceRange()
2239 if (EmptyInitStmtSemiLoc.
isValid()) {
2240 Diag(EmptyInitStmtSemiLoc, diag::warn_empty_init_statement)
2247 ExprResult CondExpr = Actions.CreateRecoveryExpr(
2249 Tok.getLocation() == SecondPartStart ? SecondPartStart
2251 {}, Actions.PreferredConditionType(CK));
2253 SecondPart = Actions.ActOnCondition(
getCurScope(), ForLoc,
2263 SecondPart = Actions.ActOnCondition(
2271 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl()) {
2272 if (Tok.isNot(tok::semi)) {
2274 Diag(Tok, diag::err_expected_semi_for);
2278 if (Tok.is(tok::semi)) {
2282 if (Tok.isNot(tok::r_paren)) {
2286 ThirdPart = Actions.MakeFullDiscardedValueExpr(Third.
get());
2294 if (CoawaitLoc.
isValid() && !ForRangeInfo.ParsedForRangeDecl()) {
2295 Diag(CoawaitLoc, diag::err_for_co_await_not_range_for);
2296 CoawaitLoc = SourceLocation();
2300 Diag(CoawaitLoc, diag::warn_deprecated_for_co_await);
2309 ForRangeStmt = Actions.ActOnCXXExpansionStmtPattern(
2310 ESD, FirstPart.get(), ForRangeInfo.LoopVar.get(),
2311 ForRangeInfo.RangeExpr.get(),
T.getOpenLocation(),
2312 ForRangeInfo.ColonLoc,
T.getCloseLocation(),
2313 ForRangeInfo.LifetimeExtendTemps);
2314 }
else if (ForRangeInfo.ParsedForRangeDecl()) {
2315 ForRangeStmt = Actions.ActOnCXXForRangeStmt(
2316 getCurScope(), ForLoc, CoawaitLoc, FirstPart.get(),
2317 ForRangeInfo.LoopVar.get(), ForRangeInfo.ColonLoc,
2319 ForRangeInfo.LifetimeExtendTemps);
2320 }
else if (ForEach) {
2323 ForEachStmt = Actions.ObjC().ActOnObjCForCollectionStmt(
2324 ForLoc, FirstPart.get(), Collection.
get(),
T.getCloseLocation());
2328 if (
getLangOpts().OpenMP && FirstPart.isUsable()) {
2329 Actions.OpenMP().ActOnOpenMPLoopInitialization(ForLoc, FirstPart.get());
2338 else if (ForRangeInfo.ParsedForRangeDecl())
2342 ForLoc, FirstPart.get(), SecondPart.
get().second, ThirdPart.get());
2348 bool BodyStartsWithAttr = Tok.isOneOf(tok::l_square, tok::kw___attribute);
2349 SourceLocation BodyBeginLoc = Tok.getLocation();
2363 Tok.is(tok::l_brace));
2372 MisleadingIndentationChecker MIChecker(*
this, MSK_for, ForLoc);
2375 StmtResult Body(ParseStatement(TrailingElseLoc));
2377 if (Body.isUsable())
2388 if (Body.isInvalid())
2392 return Actions.ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2396 if (!ForRangeInfo.ParsedForRangeDecl()) {
2397 Diag(ForLoc, diag::err_expansion_stmt_requires_range);
2406 ? diag::ext_expansion_stmt_body_attr
2407 : diag::ext_expansion_stmt_body_not_compound_stmt);
2409 return Actions.FinishCXXExpansionStmt(ForRangeStmt.get(), Body.get());
2412 if (ForRangeInfo.ParsedForRangeDecl())
2413 return Actions.FinishCXXForRangeStmt(ForRangeStmt.get(), Body.get());
2415 return Actions.ActOnForStmt(ForLoc,
T.getOpenLocation(), FirstPart.get(),
2416 SecondPart, ThirdPart,
T.getCloseLocation(),
2421 assert(Tok.is(tok::kw_goto) &&
"Not a goto stmt!");
2425 if (Tok.is(tok::identifier)) {
2426 LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(),
2428 Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(), LD);
2430 }
else if (Tok.is(tok::star)) {
2432 Diag(Tok, diag::ext_gnu_indirect_goto);
2435 if (
R.isInvalid()) {
2439 Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc,
R.get());
2441 Diag(Tok, diag::err_expected) << tok::identifier;
2448StmtResult Parser::ParseBreakOrContinueStatement(
bool IsContinue) {
2450 SourceLocation LabelLoc;
2451 LabelDecl *
Target =
nullptr;
2452 if (Tok.is(tok::identifier)) {
2454 Actions.LookupExistingLabel(Tok.getIdentifierInfo(), Tok.getLocation());
2459 Diag(LabelLoc, diag::err_c2y_labeled_break_continue) << IsContinue;
2461 Diag(LabelLoc, diag::err_break_continue_label_not_found) << IsContinue;
2472 return ParseBreakOrContinueStatement(
true);
2476 return ParseBreakOrContinueStatement(
false);
2480 assert((Tok.is(tok::kw_return) || Tok.is(tok::kw_co_return)) &&
2481 "Not a return stmt!");
2482 bool IsCoreturn = Tok.is(tok::kw_co_return);
2486 if (Tok.isNot(tok::semi)) {
2488 PreferredType.enterReturn(Actions, Tok.getLocation());
2490 if (Tok.is(tok::code_completion) && !IsCoreturn) {
2492 Actions.CodeCompletion().CodeCompleteExpression(
2493 getCurScope(), PreferredType.get(Tok.getLocation()));
2498 R = ParseInitializer();
2500 Diag(
R.get()->getBeginLoc(),
2502 ? diag::warn_cxx98_compat_generalized_initializer_lists
2503 : diag::ext_generalized_initializer_lists)
2504 <<
R.get()->getSourceRange();
2507 if (
R.isInvalid()) {
2513 return Actions.ActOnCoreturnStmt(
getCurScope(), ReturnLoc,
R.get());
2514 return Actions.ActOnReturnStmt(ReturnLoc,
R.get(),
getCurScope());
2518 assert(Tok.is(tok::kw__Defer));
2521 Actions.ActOnStartOfDeferStmt(DeferLoc,
getCurScope());
2523 llvm::scope_exit OnError([&] { Actions.ActOnDeferStmtError(
getCurScope()); });
2525 StmtResult Res = ParseStatement(TrailingElseLoc);
2526 if (!Res.isUsable())
2530 if (
auto *L = dyn_cast<LabelStmt>(Res.get())) {
2531 Diag(L->getIdentLoc(), diag::err_defer_ts_labeled_stmt);
2536 return Actions.ActOnEndOfDeferStmt(Res.get(),
getCurScope());
2539StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
2540 ParsedStmtContext StmtCtx,
2545 ParsedAttributes TempAttrs(AttrFactory);
2547 SourceLocation StartLoc = Tok.getLocation();
2550 while (Tok.is(tok::annot_pragma_loop_hint)) {
2552 if (!HandlePragmaLoopHint(Hint))
2558 AttributeScopeInfo(), ArgHints, 4,
2559 ParsedAttr::Form::Pragma());
2563 MaybeParseCXX11Attributes(Attrs);
2565 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2566 StmtResult S = ParseStatementOrDeclarationAfterAttributes(
2567 Stmts, StmtCtx, TrailingElseLoc, Attrs, EmptyDeclSpecAttrs,
2580Decl *Parser::ParseFunctionStatementBody(
Decl *
Decl, ParseScope &BodyScope) {
2581 assert(Tok.is(tok::l_brace));
2582 SourceLocation LBraceLoc = Tok.getLocation();
2584 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, LBraceLoc,
2585 "parsing function body");
2590 Sema::PragmaStackSentinelRAII
2591 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2596 StmtResult FnBody(ParseCompoundStatementBody());
2599 if (FnBody.isInvalid()) {
2600 Sema::CompoundScopeRAII CompoundScope(Actions);
2601 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, {},
false);
2605 return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
2608Decl *Parser::ParseFunctionTryBlock(
Decl *
Decl, ParseScope &BodyScope) {
2609 assert(Tok.is(tok::kw_try) &&
"Expected 'try'");
2612 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, TryLoc,
2613 "parsing function try block");
2616 if (Tok.is(tok::colon))
2617 ParseConstructorInitializer(Decl);
2619 Actions.ActOnDefaultCtorInitializers(Decl);
2624 Sema::PragmaStackSentinelRAII
2625 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2627 SourceLocation LBraceLoc = Tok.getLocation();
2628 StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc,
true));
2631 if (FnBody.isInvalid()) {
2632 Sema::CompoundScopeRAII CompoundScope(Actions);
2633 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, {},
false);
2637 return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
2640bool Parser::trySkippingFunctionBody() {
2641 assert(SkipFunctionBodies &&
2642 "Should only be called when SkipFunctionBodies is enabled");
2643 if (!PP.isCodeCompletionEnabled()) {
2650 TentativeParsingAction PA(*
this);
2651 bool IsTryCatch = Tok.is(tok::kw_try);
2653 bool ErrorInPrologue = ConsumeAndStoreFunctionPrologue(Toks);
2654 if (llvm::any_of(Toks, [](
const Token &Tok) {
2655 return Tok.is(tok::code_completion);
2660 if (ErrorInPrologue) {
2669 while (IsTryCatch && Tok.is(tok::kw_catch)) {
2681 assert(Tok.is(tok::kw_try) &&
"Expected 'try'");
2684 return ParseCXXTryBlockCommon(TryLoc);
2688 if (Tok.isNot(tok::l_brace))
2689 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2695 if (TryBlock.isInvalid())
2700 if ((Tok.is(tok::identifier) &&
2701 Tok.getIdentifierInfo() == getSEHExceptKeyword()) ||
2702 Tok.is(tok::kw___finally)) {
2705 if(Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
2707 Handler = ParseSEHExceptBlock(Loc);
2711 Handler = ParseSEHFinallyBlock(Loc);
2713 if(Handler.isInvalid())
2716 return Actions.ActOnSEHTryBlock(
true ,
2726 DiagnoseAndSkipCXX11Attributes();
2728 if (Tok.isNot(tok::kw_catch))
2730 while (Tok.is(tok::kw_catch)) {
2731 StmtResult Handler(ParseCXXCatchBlock(FnTry));
2732 if (!Handler.isInvalid())
2733 Handlers.push_back(Handler.get());
2737 if (Handlers.empty())
2740 return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.get(), Handlers);
2744StmtResult Parser::ParseCXXCatchBlock(
bool FnCatch) {
2745 assert(Tok.is(tok::kw_catch) &&
"Expected 'catch'");
2750 if (
T.expectAndConsume())
2762 Decl *ExceptionDecl =
nullptr;
2763 if (Tok.isNot(tok::ellipsis)) {
2764 ParsedAttributes Attributes(AttrFactory);
2765 MaybeParseCXX11Attributes(Attributes);
2767 DeclSpec DS(AttrFactory);
2769 if (ParseCXXTypeSpecifierSeq(DS))
2773 ParseDeclarator(ExDecl);
2774 ExceptionDecl = Actions.ActOnExceptionDeclarator(
getCurScope(), ExDecl);
2779 if (
T.getCloseLocation().isInvalid())
2782 if (Tok.isNot(tok::l_brace))
2783 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2787 if (
Block.isInvalid())
2790 return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl,
Block.get());
2796 assert(Tok.is(tok::kw_for));
2798 CXXExpansionStmtDecl *ExpansionDecl =
2799 Actions.ActOnCXXExpansionStmtDecl(TemplateParameterDepth, TemplateLoc);
2801 CXXExpansionStmtPattern *Expansion;
2803 Sema::ContextRAII CtxGuard(Actions, ExpansionDecl,
false);
2804 TemplateParameterDepthRAII TParamDepthGuard(TemplateParameterDepth);
2808 ParseForStatement(TrailingElseLoc, PrecedingLabel, ExpansionDecl);
2816 DeclSpec DS(AttrFactory);
2818 Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, {ExpansionDecl});
2820 return Actions.ActOnDeclStmt(DeclGroupPtr, Expansion->
getBeginLoc(),
2824void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
2825 IfExistsCondition
Result;
2826 if (ParseMicrosoftIfExistsCondition(
Result))
2834 if (!Tok.is(tok::l_brace)) {
2835 Diag(Tok, diag::err_expected) << tok::l_brace;
2839 StmtResult Compound = ParseCompoundStatement();
2840 if (Compound.isInvalid())
2843 StmtResult DepResult = Actions.ActOnMSDependentExistsStmt(
Result.KeywordLoc,
2848 if (DepResult.isUsable())
2849 Stmts.push_back(DepResult.get());
2854 if (
Braces.consumeOpen()) {
2855 Diag(Tok, diag::err_expected) << tok::l_brace;
2859 switch (
Result.Behavior) {
2865 llvm_unreachable(
"Dependent case handled above");
2873 while (Tok.isNot(tok::r_brace)) {
2875 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::Compound);
2877 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.
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
@ 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.
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
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.
The JSON file list parser is used to communicate input to InstallAPI.
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