30#include "llvm/ADT/STLExtras.h"
40 ParsedStmtContext StmtCtx,
48 Res = ParseStatementOrDeclaration(Stmts, StmtCtx, TrailingElseLoc,
50 }
while (!Res.isInvalid() && !Res.get());
55StmtResult Parser::ParseStatementOrDeclaration(StmtVector &Stmts,
56 ParsedStmtContext StmtCtx,
67 ParsedAttributes CXX11Attrs(AttrFactory);
69 MaybeParseCXX11Attributes(CXX11Attrs,
true);
70 ParsedAttributes GNUOrMSAttrs(AttrFactory);
72 MaybeParseGNUAttributes(GNUOrMSAttrs);
75 MaybeParseMicrosoftAttributes(GNUOrMSAttrs);
77 StmtResult Res = ParseStatementOrDeclarationAfterAttributes(
78 Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs, GNUOrMSAttrs,
80 MaybeDestroyTemplateIds();
84 assert((CXX11Attrs.empty() || Res.isInvalid() || Res.isUsable()) &&
85 "attributes on empty statement");
88 (StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
89 ParsedStmtContext{} &&
90 isa_and_present<NullStmt>(Res.get()))
91 Diag(CXX11Attrs.Range.getBegin(), diag::warn_attr_in_secondary_block)
94 if (CXX11Attrs.empty() || Res.isInvalid())
97 return Actions.ActOnAttributedStmt(CXX11Attrs, Res.get());
103 StatementFilterCCC(Token nextTok) : NextToken(nextTok) {
104 WantTypeSpecifiers = nextTok.
isOneOf(tok::l_paren, tok::less, tok::l_square,
105 tok::identifier, tok::star, tok::amp);
106 WantExpressionKeywords =
107 nextTok.
isOneOf(tok::l_paren, tok::identifier, tok::arrow, tok::period);
108 WantRemainingKeywords =
109 nextTok.
isOneOf(tok::l_paren, tok::semi, tok::identifier, tok::l_brace);
110 WantCXXNamedCasts =
false;
113 bool ValidateCandidate(
const TypoCorrection &candidate)
override {
116 if (NextToken.is(tok::equal))
118 if (NextToken.is(tok::period) &&
124 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
125 return std::make_unique<StatementFilterCCC>(*
this);
133StmtResult Parser::ParseStatementOrDeclarationAfterAttributes(
134 StmtVector &Stmts, ParsedStmtContext StmtCtx,
137 const char *SemiError =
nullptr;
139 SourceLocation GNUAttributeLoc;
146 SourceLocation AtLoc;
151 return ParseObjCAtStatement(AtLoc, StmtCtx);
154 case tok::code_completion:
156 Actions.CodeCompletion().CodeCompleteOrdinaryName(
160 case tok::identifier:
163 if (
Next.is(tok::colon)) {
170 return ParseLabeledStatement(CXX11Attrs, StmtCtx);
175 if (
Next.isNot(tok::coloncolon)) {
178 StatementFilterCCC CCC(
Next);
183 if (Tok.is(tok::semi))
189 if (Tok.isNot(tok::identifier))
201 bool HaveAttrs = !CXX11Attrs.
empty() || !GNUAttrs.
empty();
202 auto IsStmtAttr = [](ParsedAttr &Attr) {
return Attr.isStmtAttr(); };
203 bool AllAttrsAreStmtAttrs = llvm::all_of(CXX11Attrs, IsStmtAttr) &&
204 llvm::all_of(GNUAttrs, IsStmtAttr);
211 (StmtCtx & ParsedStmtContext::AllowDeclarationsInC) !=
212 ParsedStmtContext()) &&
213 ((GNUAttributeLoc.
isValid() && !(HaveAttrs && AllAttrsAreStmtAttrs)) ||
214 isDeclarationStatement())) {
215 SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
217 if (GNUAttributeLoc.
isValid()) {
218 DeclStart = GNUAttributeLoc;
220 GNUAttrs, &GNUAttributeLoc);
233 return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
236 if (Tok.is(tok::r_brace)) {
237 Diag(Tok, diag::err_expected_statement);
241 switch (Tok.getKind()) {
242#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
243#include "clang/Basic/TransformTypeTraits.def"
245 Tok.setKind(tok::identifier);
246 Diag(Tok, diag::ext_keyword_as_ident)
247 << Tok.getIdentifierInfo()->getName() << 0;
248 goto ParseIdentifier;
252 return ParseExprStatement(StmtCtx);
256 case tok::kw___attribute: {
257 GNUAttributeLoc = Tok.getLocation();
258 ParseGNUAttributes(GNUAttrs);
262 case tok::kw_template: {
263 SourceLocation DeclEnd;
265 getAccessSpecifierIfPresent());
270 return ParseCaseStatement(StmtCtx);
271 case tok::kw_default:
272 return ParseDefaultStatement(StmtCtx);
275 return ParseCompoundStatement();
277 bool HasLeadingEmptyMacro = Tok.hasLeadingEmptyMacro();
278 return Actions.ActOnNullStmt(
ConsumeToken(), HasLeadingEmptyMacro);
282 return ParseIfStatement(TrailingElseLoc);
284 return ParseSwitchStatement(TrailingElseLoc, PrecedingLabel);
287 return ParseWhileStatement(TrailingElseLoc, PrecedingLabel);
289 Res = ParseDoStatement(PrecedingLabel);
290 SemiError =
"do/while";
293 return ParseForStatement(TrailingElseLoc, PrecedingLabel);
296 Res = ParseGotoStatement();
299 case tok::kw_continue:
300 Res = ParseContinueStatement();
301 SemiError =
"continue";
304 Res = ParseBreakStatement();
308 Res = ParseReturnStatement();
309 SemiError =
"return";
311 case tok::kw_co_return:
312 Res = ParseReturnStatement();
313 SemiError =
"co_return";
317 for (
const ParsedAttr &AL : CXX11Attrs)
320 (AL.isRegularKeywordAttribute()
321 ?
Diag(AL.getRange().getBegin(), diag::err_keyword_not_allowed)
322 :
Diag(AL.getRange().getBegin(), diag::warn_attribute_ignored))
326 ProhibitAttributes(GNUAttrs);
328 Res = ParseAsmStatement(msAsm);
329 if (msAsm)
return Res;
334 case tok::kw___if_exists:
335 case tok::kw___if_not_exists:
336 ProhibitAttributes(CXX11Attrs);
337 ProhibitAttributes(GNUAttrs);
338 ParseMicrosoftIfExistsStatement(Stmts);
344 return ParseCXXTryBlock();
347 ProhibitAttributes(CXX11Attrs);
348 ProhibitAttributes(GNUAttrs);
349 return ParseSEHTryBlock();
351 case tok::kw___leave:
352 Res = ParseSEHLeaveStatement();
353 SemiError =
"__leave";
356 case tok::annot_pragma_vis:
357 ProhibitAttributes(CXX11Attrs);
358 ProhibitAttributes(GNUAttrs);
359 HandlePragmaVisibility();
362 case tok::annot_pragma_pack:
363 ProhibitAttributes(CXX11Attrs);
364 ProhibitAttributes(GNUAttrs);
368 case tok::annot_pragma_msstruct:
369 ProhibitAttributes(CXX11Attrs);
370 ProhibitAttributes(GNUAttrs);
371 HandlePragmaMSStruct();
374 case tok::annot_pragma_align:
375 ProhibitAttributes(CXX11Attrs);
376 ProhibitAttributes(GNUAttrs);
380 case tok::annot_pragma_weak:
381 ProhibitAttributes(CXX11Attrs);
382 ProhibitAttributes(GNUAttrs);
386 case tok::annot_pragma_weakalias:
387 ProhibitAttributes(CXX11Attrs);
388 ProhibitAttributes(GNUAttrs);
389 HandlePragmaWeakAlias();
392 case tok::annot_pragma_redefine_extname:
393 ProhibitAttributes(CXX11Attrs);
394 ProhibitAttributes(GNUAttrs);
395 HandlePragmaRedefineExtname();
398 case tok::annot_pragma_fp_contract:
399 ProhibitAttributes(CXX11Attrs);
400 ProhibitAttributes(GNUAttrs);
401 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"fp_contract";
402 ConsumeAnnotationToken();
405 case tok::annot_pragma_fp:
406 ProhibitAttributes(CXX11Attrs);
407 ProhibitAttributes(GNUAttrs);
408 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"clang fp";
409 ConsumeAnnotationToken();
412 case tok::annot_pragma_fenv_access:
413 case tok::annot_pragma_fenv_access_ms:
414 ProhibitAttributes(CXX11Attrs);
415 ProhibitAttributes(GNUAttrs);
416 Diag(Tok, diag::err_pragma_file_or_compound_scope)
417 << (
Kind == tok::annot_pragma_fenv_access ?
"STDC FENV_ACCESS"
419 ConsumeAnnotationToken();
422 case tok::annot_pragma_fenv_round:
423 ProhibitAttributes(CXX11Attrs);
424 ProhibitAttributes(GNUAttrs);
425 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"STDC FENV_ROUND";
426 ConsumeAnnotationToken();
429 case tok::annot_pragma_cx_limited_range:
430 ProhibitAttributes(CXX11Attrs);
431 ProhibitAttributes(GNUAttrs);
432 Diag(Tok, diag::err_pragma_file_or_compound_scope)
433 <<
"STDC CX_LIMITED_RANGE";
434 ConsumeAnnotationToken();
437 case tok::annot_pragma_float_control:
438 ProhibitAttributes(CXX11Attrs);
439 ProhibitAttributes(GNUAttrs);
440 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"float_control";
441 ConsumeAnnotationToken();
444 case tok::annot_pragma_opencl_extension:
445 ProhibitAttributes(CXX11Attrs);
446 ProhibitAttributes(GNUAttrs);
447 HandlePragmaOpenCLExtension();
450 case tok::annot_pragma_captured:
451 ProhibitAttributes(CXX11Attrs);
452 ProhibitAttributes(GNUAttrs);
453 return HandlePragmaCaptured();
455 case tok::annot_pragma_openmp:
458 ProhibitAttributes(CXX11Attrs);
459 ProhibitAttributes(GNUAttrs);
461 case tok::annot_attr_openmp:
463 return ParseOpenMPDeclarativeOrExecutableDirective(StmtCtx);
465 case tok::annot_pragma_openacc:
468 case tok::annot_pragma_ms_pointers_to_members:
469 ProhibitAttributes(CXX11Attrs);
470 ProhibitAttributes(GNUAttrs);
471 HandlePragmaMSPointersToMembers();
474 case tok::annot_pragma_ms_pragma:
475 ProhibitAttributes(CXX11Attrs);
476 ProhibitAttributes(GNUAttrs);
477 HandlePragmaMSPragma();
480 case tok::annot_pragma_ms_vtordisp:
481 ProhibitAttributes(CXX11Attrs);
482 ProhibitAttributes(GNUAttrs);
483 HandlePragmaMSVtorDisp();
486 case tok::annot_pragma_loop_hint:
487 ProhibitAttributes(CXX11Attrs);
488 ProhibitAttributes(GNUAttrs);
489 return ParsePragmaLoopHint(Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs,
492 case tok::annot_pragma_dump:
493 ProhibitAttributes(CXX11Attrs);
494 ProhibitAttributes(GNUAttrs);
498 case tok::annot_pragma_attribute:
499 ProhibitAttributes(CXX11Attrs);
500 ProhibitAttributes(GNUAttrs);
501 HandlePragmaAttribute();
510 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt, SemiError);
518StmtResult Parser::ParseExprStatement(ParsedStmtContext StmtCtx) {
520 Token OldToken = Tok;
522 ExprStatementTokLoc = Tok.getLocation();
526 if (Expr.isInvalid()) {
531 if (Tok.is(tok::semi))
533 return Actions.ActOnExprStmtError();
536 if (Tok.is(tok::colon) &&
getCurScope()->isSwitchScope() &&
537 Actions.CheckCaseExpression(Expr.get())) {
540 Diag(OldToken, diag::err_expected_case_before_expression)
544 return ParseCaseStatement(StmtCtx,
true, Expr);
547 Token *CurTok =
nullptr;
550 if (Tok.is(tok::annot_repl_input_end))
554 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
557 if (CurTok && !R.isInvalid())
564 assert(Tok.is(tok::kw___try) &&
"Expected '__try'");
567 if (Tok.isNot(tok::l_brace))
568 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
573 if (TryBlock.isInvalid())
577 if (Tok.is(tok::identifier) &&
578 Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
580 Handler = ParseSEHExceptBlock(Loc);
581 }
else if (Tok.is(tok::kw___finally)) {
583 Handler = ParseSEHFinallyBlock(Loc);
588 if(Handler.isInvalid())
591 return Actions.ActOnSEHTryBlock(
false ,
598 PoisonIdentifierRAIIObject raii(Ident__exception_code,
false),
599 raii2(Ident___exception_code,
false),
600 raii3(Ident_GetExceptionCode,
false);
602 if (ExpectAndConsume(tok::l_paren))
609 Ident__exception_info->setIsPoisoned(
false);
610 Ident___exception_info->setIsPoisoned(
false);
611 Ident_GetExceptionInfo->setIsPoisoned(
false);
616 ParseScopeFlags FilterScope(
this,
getCurScope()->getFlags() |
622 Ident__exception_info->setIsPoisoned(
true);
623 Ident___exception_info->setIsPoisoned(
true);
624 Ident_GetExceptionInfo->setIsPoisoned(
true);
630 if (ExpectAndConsume(tok::r_paren))
633 if (Tok.isNot(tok::l_brace))
634 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
638 if(
Block.isInvalid())
641 return Actions.ActOnSEHExceptBlock(ExceptLoc, FilterExpr.
get(),
Block.get());
645 PoisonIdentifierRAIIObject raii(Ident__abnormal_termination,
false),
646 raii2(Ident___abnormal_termination,
false),
647 raii3(Ident_AbnormalTermination,
false);
649 if (Tok.isNot(tok::l_brace))
650 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
653 Actions.ActOnStartSEHFinallyBlock();
656 if(
Block.isInvalid()) {
657 Actions.ActOnAbortSEHFinallyBlock();
661 return Actions.ActOnFinishSEHFinallyBlock(FinallyLoc,
Block.get());
671 return Actions.ActOnSEHLeaveStmt(LeaveLoc,
getCurScope());
681 ? diag::warn_c23_compat_label_followed_by_declaration
682 : diag::ext_c_label_followed_by_declaration);
687 ParsedStmtContext StmtCtx) {
688 assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
689 "Not an identifier!");
694 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
696 Token IdentTok = Tok;
699 assert(Tok.is(tok::colon) &&
"Not a label!");
709 if (Tok.is(tok::kw___attribute)) {
710 ParsedAttributes TempAttrs(AttrFactory);
711 ParseGNUAttributes(TempAttrs);
724 ParsedAttributes EmptyCXX11Attrs(AttrFactory);
725 SubStmt = ParseStatementOrDeclarationAfterAttributes(
726 Stmts, StmtCtx,
nullptr, EmptyCXX11Attrs,
728 if (!TempAttrs.empty() && !SubStmt.isInvalid())
729 SubStmt = Actions.ActOnAttributedStmt(TempAttrs, SubStmt.get());
734 if (SubStmt.isUnset() && Tok.is(tok::r_brace)) {
735 DiagnoseLabelAtEndOfCompoundStatement();
736 SubStmt = Actions.ActOnNullStmt(ColonLoc);
740 if (SubStmt.isUnset())
741 SubStmt = ParseStatement(
nullptr, StmtCtx, LD);
744 if (SubStmt.isInvalid())
745 SubStmt = Actions.ActOnNullStmt(ColonLoc);
749 Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
752 return Actions.ActOnLabelStmt(IdentTok.
getLocation(), LD, ColonLoc,
756StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx,
758 assert((MissingCase || Tok.is(tok::kw_case)) &&
"Not a case stmt!");
763 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
786 Stmt *DeepestParsedCaseStmt =
nullptr;
789 SourceLocation ColonLoc;
791 SourceLocation CaseLoc = MissingCase ? Expr.
get()->
getExprLoc() :
793 ColonLoc = SourceLocation();
795 if (Tok.is(tok::code_completion)) {
797 Actions.CodeCompletion().CodeCompleteCase(
getCurScope());
816 LHS = Actions.ActOnCaseExpr(CaseLoc, Expr);
821 SourceLocation DotDotDotLoc;
827 DiagId = diag::ext_gnu_case_range;
829 DiagId = diag::warn_c23_compat_case_range;
831 DiagId = diag::ext_c2y_case_range;
832 Diag(DotDotDotLoc, DiagId);
840 ColonProtection.restore();
846 Diag(ColonLoc, diag::err_expected_after)
847 <<
"'case'" << tok::colon
852 Diag(ExpectedLoc, diag::err_expected_after)
853 <<
"'case'" << tok::colon
856 ColonLoc = ExpectedLoc;
860 Actions.ActOnCaseStmt(CaseLoc, LHS, DotDotDotLoc, RHS, ColonLoc);
864 if (Case.isInvalid()) {
865 if (TopLevelCase.isInvalid())
866 return ParseStatement(
nullptr, StmtCtx);
871 Stmt *NextDeepest = Case.get();
872 if (TopLevelCase.isInvalid())
875 Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, Case.get());
876 DeepestParsedCaseStmt = NextDeepest;
880 }
while (Tok.is(tok::kw_case));
885 if (Tok.is(tok::r_brace)) {
888 DiagnoseLabelAtEndOfCompoundStatement();
889 SubStmt = Actions.ActOnNullStmt(ColonLoc);
891 SubStmt = ParseStatement(
nullptr, StmtCtx);
895 if (DeepestParsedCaseStmt) {
897 if (SubStmt.isInvalid())
898 SubStmt = Actions.ActOnNullStmt(SourceLocation());
900 Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, SubStmt.get());
907StmtResult Parser::ParseDefaultStatement(ParsedStmtContext StmtCtx) {
908 assert(Tok.is(tok::kw_default) &&
"Not a default stmt!");
913 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
917 SourceLocation ColonLoc;
921 Diag(ColonLoc, diag::err_expected_after)
922 <<
"'default'" << tok::colon
925 SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation);
926 Diag(ExpectedLoc, diag::err_expected_after)
927 <<
"'default'" << tok::colon
929 ColonLoc = ExpectedLoc;
934 if (Tok.is(tok::r_brace)) {
937 DiagnoseLabelAtEndOfCompoundStatement();
938 SubStmt = Actions.ActOnNullStmt(ColonLoc);
940 SubStmt = ParseStatement(
nullptr, StmtCtx);
944 if (SubStmt.isInvalid())
945 SubStmt = Actions.ActOnNullStmt(ColonLoc);
948 return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc,
952StmtResult Parser::ParseCompoundStatement(
bool isStmtExpr) {
953 return ParseCompoundStatement(isStmtExpr,
957StmtResult Parser::ParseCompoundStatement(
bool isStmtExpr,
958 unsigned ScopeFlags) {
959 assert(Tok.is(tok::l_brace) &&
"Not a compound stmt!");
967 StackHandler.runWithSufficientStackSpace(Tok.getLocation(), [&,
this]() {
968 R = ParseCompoundStatementBody(isStmtExpr);
973void Parser::ParseCompoundStatementLeadingPragmas() {
974 bool checkForPragmas =
true;
975 while (checkForPragmas) {
976 switch (Tok.getKind()) {
977 case tok::annot_pragma_vis:
978 HandlePragmaVisibility();
980 case tok::annot_pragma_pack:
983 case tok::annot_pragma_msstruct:
984 HandlePragmaMSStruct();
986 case tok::annot_pragma_align:
989 case tok::annot_pragma_weak:
992 case tok::annot_pragma_weakalias:
993 HandlePragmaWeakAlias();
995 case tok::annot_pragma_redefine_extname:
996 HandlePragmaRedefineExtname();
998 case tok::annot_pragma_opencl_extension:
999 HandlePragmaOpenCLExtension();
1001 case tok::annot_pragma_fp_contract:
1002 HandlePragmaFPContract();
1004 case tok::annot_pragma_fp:
1007 case tok::annot_pragma_fenv_access:
1008 case tok::annot_pragma_fenv_access_ms:
1009 HandlePragmaFEnvAccess();
1011 case tok::annot_pragma_fenv_round:
1012 HandlePragmaFEnvRound();
1014 case tok::annot_pragma_cx_limited_range:
1015 HandlePragmaCXLimitedRange();
1017 case tok::annot_pragma_float_control:
1018 HandlePragmaFloatControl();
1020 case tok::annot_pragma_ms_pointers_to_members:
1021 HandlePragmaMSPointersToMembers();
1023 case tok::annot_pragma_ms_pragma:
1024 HandlePragmaMSPragma();
1026 case tok::annot_pragma_ms_vtordisp:
1027 HandlePragmaMSVtorDisp();
1029 case tok::annot_pragma_dump:
1033 checkForPragmas =
false;
1040void Parser::DiagnoseLabelAtEndOfCompoundStatement() {
1043 ? diag::warn_cxx20_compat_label_end_of_compound_statement
1044 : diag::ext_cxx_label_end_of_compound_statement);
1047 ? diag::warn_c23_compat_label_end_of_compound_statement
1048 : diag::ext_c_label_end_of_compound_statement);
1052bool Parser::ConsumeNullStmt(StmtVector &Stmts) {
1053 if (!Tok.is(tok::semi))
1056 SourceLocation StartLoc = Tok.getLocation();
1057 SourceLocation EndLoc;
1059 while (Tok.is(tok::semi) && !Tok.hasLeadingEmptyMacro() &&
1060 Tok.getLocation().isValid() && !Tok.getLocation().isMacroID()) {
1061 EndLoc = Tok.getLocation();
1065 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::SubStmt);
1067 Stmts.push_back(R.get());
1074 Diag(StartLoc, diag::warn_null_statement)
1080 bool IsStmtExprResult =
false;
1081 if ((StmtCtx & ParsedStmtContext::InStmtExpr) != ParsedStmtContext()) {
1085 IsStmtExprResult = Tok.is(tok::r_brace) &&
NextToken().
is(tok::r_paren);
1088 if (IsStmtExprResult)
1089 E = Actions.ActOnStmtExprResult(E);
1090 return Actions.ActOnExprStmt(E, !IsStmtExprResult);
1093StmtResult Parser::ParseCompoundStatementBody(
bool isStmtExpr) {
1094 PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),
1096 "in compound statement ('{}')");
1100 Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);
1104 if (
T.consumeOpen())
1107 Sema::CompoundScopeRAII CompoundScope(Actions, isStmtExpr);
1110 ParseCompoundStatementLeadingPragmas();
1111 Actions.ActOnAfterCompoundStatementLeadingPragmas();
1117 while (Tok.is(tok::kw___label__)) {
1120 SmallVector<Decl *, 4> DeclsInGroup;
1122 if (Tok.isNot(tok::identifier)) {
1123 Diag(Tok, diag::err_expected) << tok::identifier;
1127 IdentifierInfo *II = Tok.getIdentifierInfo();
1129 DeclsInGroup.push_back(Actions.LookupOrCreateLabel(II, IdLoc, LabelLoc));
1135 DeclSpec DS(AttrFactory);
1137 Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, DeclsInGroup);
1138 StmtResult R = Actions.ActOnDeclStmt(Res, LabelLoc, Tok.getLocation());
1140 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
1142 Stmts.push_back(R.get());
1145 ParsedStmtContext SubStmtCtx =
1146 ParsedStmtContext::Compound |
1147 (isStmtExpr ? ParsedStmtContext::InStmtExpr : ParsedStmtContext());
1149 bool LastIsError =
false;
1150 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
1151 Tok.isNot(tok::eof)) {
1152 if (Tok.is(tok::annot_pragma_unused)) {
1153 HandlePragmaUnused();
1157 if (ConsumeNullStmt(Stmts))
1161 if (Tok.isNot(tok::kw___extension__)) {
1162 R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
1169 while (Tok.is(tok::kw___extension__))
1172 ParsedAttributes attrs(AttrFactory);
1173 MaybeParseCXX11Attributes(attrs,
true);
1176 if (isDeclarationStatement()) {
1179 ExtensionRAIIObject O(Diags);
1181 SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
1182 ParsedAttributes DeclSpecAttrs(AttrFactory);
1184 attrs, DeclSpecAttrs);
1185 R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);
1188 ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
1190 if (Res.isInvalid()) {
1197 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
1198 R = handleExprStmt(Res, SubStmtCtx);
1200 R = Actions.ActOnAttributedStmt(attrs, R.get());
1205 Stmts.push_back(R.get());
1206 LastIsError = R.isInvalid();
1212 if (isStmtExpr && LastIsError && !Stmts.empty())
1219 if (!PP.getTargetInfo().supportSourceEvalMethod() &&
1220 (PP.getLastFPEvalPragmaLocation().isValid() ||
1221 PP.getCurrentFPEvalMethod() ==
1223 Diag(Tok.getLocation(),
1224 diag::warn_no_support_for_eval_method_source_on_m32);
1226 SourceLocation CloseLoc = Tok.getLocation();
1229 if (!
T.consumeClose()) {
1232 if (isStmtExpr && Tok.is(tok::r_paren))
1233 checkCompoundToken(CloseLoc, tok::r_brace, CompoundToken::StmtExprEnd);
1239 if (
T.getCloseLocation().isValid())
1240 CloseLoc =
T.getCloseLocation();
1242 return Actions.ActOnCompoundStmt(
T.getOpenLocation(), CloseLoc,
1246bool Parser::ParseParenExprOrCondition(
StmtResult *InitStmt,
1254 SourceLocation Start = Tok.getLocation();
1257 Cond = ParseCXXCondition(InitStmt, Loc, CK,
false);
1272 if (
Cond.isInvalid() && Tok.isNot(tok::r_paren)) {
1276 if (Tok.isNot(tok::r_paren))
1280 if (
Cond.isInvalid()) {
1281 ExprResult CondExpr = Actions.CreateRecoveryExpr(
1282 Start, Tok.getLocation() == Start ? Start : PrevTokLocation, {},
1283 Actions.PreferredConditionType(CK));
1291 LParenLoc =
T.getOpenLocation();
1292 RParenLoc =
T.getCloseLocation();
1297 while (Tok.is(tok::r_paren)) {
1298 Diag(Tok, diag::err_extraneous_rparen_in_condition)
1308enum MisleadingStatementKind { MSK_if, MSK_else, MSK_for, MSK_while };
1310struct MisleadingIndentationChecker {
1312 SourceLocation StmtLoc;
1313 SourceLocation PrevLoc;
1314 unsigned NumDirectives;
1315 MisleadingStatementKind
Kind;
1317 MisleadingIndentationChecker(Parser &P, MisleadingStatementKind K,
1319 : P(P), StmtLoc(SL), PrevLoc(P.getCurToken().getLocation()),
1320 NumDirectives(P.getPreprocessor().getNumDirectives()),
Kind(K),
1321 ShouldSkip(P.getCurToken().
is(tok::l_brace)) {
1323 StmtLoc = P.MisleadingIndentationElseLoc;
1324 P.MisleadingIndentationElseLoc = SourceLocation();
1326 if (Kind == MSK_else && !ShouldSkip)
1332 static unsigned getVisualIndentation(SourceManager &
SM, SourceLocation Loc) {
1333 unsigned TabStop =
SM.getDiagnostics().getDiagnosticOptions().TabStop;
1335 unsigned ColNo =
SM.getSpellingColumnNumber(Loc);
1336 if (ColNo == 0 || TabStop == 1)
1342 StringRef BufData =
SM.getBufferData(FIDAndOffset.first, &
Invalid);
1346 const char *EndPos = BufData.data() + FIDAndOffset.second;
1348 assert(FIDAndOffset.second + 1 >= ColNo &&
1349 "Column number smaller than file offset?");
1351 unsigned VisualColumn = 0;
1354 for (
const char *CurPos = EndPos - (ColNo - 1); CurPos != EndPos;
1356 if (*CurPos ==
'\t')
1358 VisualColumn += (TabStop - VisualColumn % TabStop);
1362 return VisualColumn + 1;
1377 if (Kind == MSK_else)
1381 unsigned PrevColNum = getVisualIndentation(
SM, PrevLoc);
1383 unsigned StmtColNum = getVisualIndentation(
SM, StmtLoc);
1385 if (PrevColNum != 0 && CurColNum != 0 && StmtColNum != 0 &&
1386 ((PrevColNum > StmtColNum && PrevColNum == CurColNum) ||
1388 SM.getPresumedLineNumber(StmtLoc) !=
1393 P.
Diag(StmtLoc, diag::note_previous_statement);
1401 assert(Tok.is(tok::kw_if) &&
"Not an if stmt!");
1404 bool IsConstexpr =
false;
1405 bool IsConsteval =
false;
1406 SourceLocation NotLocation;
1407 SourceLocation ConstevalLoc;
1409 if (Tok.is(tok::kw_constexpr)) {
1413 : diag::ext_constexpr_if);
1418 if (Tok.is(tok::exclaim)) {
1422 if (Tok.is(tok::kw_consteval)) {
1424 : diag::ext_consteval_if);
1427 }
else if (Tok.is(tok::code_completion)) {
1429 Actions.CodeCompletion().CodeCompleteKeywordAfterIf(
1434 if (!IsConsteval && (NotLocation.
isValid() || Tok.isNot(tok::l_paren))) {
1435 Diag(Tok, diag::err_expected_lparen_after) <<
"if";
1458 Sema::ConditionResult
Cond;
1459 SourceLocation LParen;
1460 SourceLocation RParen;
1461 std::optional<bool> ConstexprCondition;
1464 if (ParseParenExprOrCondition(&InitStmt,
Cond, IfLoc,
1471 ConstexprCondition =
Cond.getKnownValue();
1474 bool IsBracedThen = Tok.is(tok::l_brace);
1496 MisleadingIndentationChecker MIChecker(*
this, MSK_if, IfLoc);
1499 SourceLocation ThenStmtLoc = Tok.getLocation();
1501 SourceLocation InnerStatementTrailingElseLoc;
1504 bool ShouldEnter = ConstexprCondition && !*ConstexprCondition;
1507 if (NotLocation.
isInvalid() && IsConsteval) {
1512 EnterExpressionEvaluationContext PotentiallyDiscarded(
1513 Actions, Context,
nullptr,
1515 ThenStmt = ParseStatement(&InnerStatementTrailingElseLoc);
1518 if (Tok.isNot(tok::kw_else))
1525 SourceLocation ElseLoc;
1526 SourceLocation ElseStmtLoc;
1529 if (Tok.is(tok::kw_else)) {
1530 if (TrailingElseLoc)
1531 *TrailingElseLoc = Tok.getLocation();
1534 ElseStmtLoc = Tok.getLocation();
1546 Tok.is(tok::l_brace));
1548 MisleadingIndentationChecker MIChecker(*
this, MSK_else, ElseLoc);
1549 bool ShouldEnter = ConstexprCondition && *ConstexprCondition;
1552 if (NotLocation.
isValid() && IsConsteval) {
1557 EnterExpressionEvaluationContext PotentiallyDiscarded(
1558 Actions, Context,
nullptr,
1560 ElseStmt = ParseStatement();
1562 if (ElseStmt.isUsable())
1567 }
else if (Tok.is(tok::code_completion)) {
1569 Actions.CodeCompletion().CodeCompleteAfterIf(
getCurScope(), IsBracedThen);
1571 }
else if (InnerStatementTrailingElseLoc.
isValid()) {
1572 Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else);
1580 if ((ThenStmt.isInvalid() && ElseStmt.isInvalid()) ||
1581 (ThenStmt.isInvalid() && ElseStmt.get() ==
nullptr) ||
1582 (ThenStmt.get() ==
nullptr && ElseStmt.isInvalid())) {
1588 auto IsCompoundStatement = [](
const Stmt *S) {
1589 if (
const auto *Outer = dyn_cast_if_present<AttributedStmt>(S))
1590 S = Outer->getSubStmt();
1591 return isa_and_nonnull<clang::CompoundStmt>(S);
1594 if (!IsCompoundStatement(ThenStmt.get())) {
1595 Diag(ConstevalLoc, diag::err_expected_after) <<
"consteval"
1599 if (!ElseStmt.isUnset() && !IsCompoundStatement(ElseStmt.get())) {
1600 Diag(ElseLoc, diag::err_expected_after) <<
"else"
1607 if (ThenStmt.isInvalid())
1608 ThenStmt = Actions.ActOnNullStmt(ThenStmtLoc);
1609 if (ElseStmt.isInvalid())
1610 ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);
1615 else if (IsConsteval)
1619 return Actions.ActOnIfStmt(IfLoc, Kind, LParen, InitStmt.get(),
Cond, RParen,
1620 ThenStmt.get(), ElseLoc, ElseStmt.get());
1625 assert(Tok.is(tok::kw_switch) &&
"Not a switch stmt!");
1628 if (Tok.isNot(tok::l_paren)) {
1629 Diag(Tok, diag::err_expected_lparen_after) <<
"switch";
1655 Sema::ConditionResult
Cond;
1656 SourceLocation LParen;
1657 SourceLocation RParen;
1658 if (ParseParenExprOrCondition(&InitStmt,
Cond, SwitchLoc,
1663 SwitchLoc, LParen, InitStmt.get(),
Cond, RParen);
1665 if (
Switch.isInvalid()) {
1670 if (Tok.is(tok::l_brace)) {
1699 StmtResult Body(ParseStatement(TrailingElseLoc));
1705 return Actions.ActOnFinishSwitchStmt(SwitchLoc,
Switch.get(), Body.get());
1710 assert(Tok.is(tok::kw_while) &&
"Not a while stmt!");
1711 SourceLocation WhileLoc = Tok.getLocation();
1714 if (Tok.isNot(tok::l_paren)) {
1715 Diag(Tok, diag::err_expected_lparen_after) <<
"while";
1734 unsigned ScopeFlags;
1743 Sema::ConditionResult
Cond;
1744 SourceLocation LParen;
1745 SourceLocation RParen;
1746 if (ParseParenExprOrCondition(
nullptr,
Cond, WhileLoc,
1769 MisleadingIndentationChecker MIChecker(*
this, MSK_while, WhileLoc);
1772 StmtResult Body(ParseStatement(TrailingElseLoc));
1774 if (Body.isUsable())
1780 if (
Cond.isInvalid() || Body.isInvalid())
1783 return Actions.ActOnWhileStmt(WhileLoc, LParen,
Cond, RParen, Body.get());
1787 assert(Tok.is(tok::kw_do) &&
"Not a do stmt!");
1792 unsigned ScopeFlags;
1826 if (Tok.isNot(tok::kw_while)) {
1827 if (!Body.isInvalid()) {
1828 Diag(Tok, diag::err_expected_while);
1829 Diag(DoLoc, diag::note_matching) <<
"'do'";
1836 if (Tok.isNot(tok::l_paren)) {
1837 Diag(Tok, diag::err_expected_lparen_after) <<
"do/while";
1847 DiagnoseAndSkipCXX11Attributes();
1849 SourceLocation Start = Tok.getLocation();
1851 if (!
Cond.isUsable()) {
1852 if (!Tok.isOneOf(tok::r_paren, tok::r_square, tok::r_brace))
1854 Cond = Actions.CreateRecoveryExpr(
1855 Start, Start == Tok.getLocation() ? Start : PrevTokLocation, {},
1856 Actions.getASTContext().BoolTy);
1861 if (
Cond.isInvalid() || Body.isInvalid())
1864 return Actions.ActOnDoStmt(DoLoc, Body.get(), WhileLoc,
T.getOpenLocation(),
1865 Cond.get(),
T.getCloseLocation());
1868bool Parser::isForRangeIdentifier() {
1869 assert(Tok.is(tok::identifier));
1872 if (
Next.is(tok::colon))
1875 if (
Next.isOneOf(tok::l_square, tok::kw_alignas)) {
1876 TentativeParsingAction PA(*
this);
1878 SkipCXX11Attributes();
1879 bool Result = Tok.is(tok::colon);
1889 assert(Tok.is(tok::kw_for) &&
"Not a for stmt!");
1892 SourceLocation CoawaitLoc;
1893 if (Tok.is(tok::kw_co_await))
1896 if (Tok.isNot(tok::l_paren)) {
1897 Diag(Tok, diag::err_expected_lparen_after) <<
"for";
1920 unsigned ScopeFlags = 0;
1931 bool ForEach =
false;
1933 Sema::ConditionResult SecondPart;
1935 ForRangeInfo ForRangeInfo;
1938 if (Tok.is(tok::code_completion)) {
1940 Actions.CodeCompletion().CodeCompleteOrdinaryName(
1946 ParsedAttributes attrs(AttrFactory);
1947 MaybeParseCXX11Attributes(attrs);
1949 SourceLocation EmptyInitStmtSemiLoc;
1952 if (Tok.is(tok::semi)) {
1953 ProhibitAttributes(attrs);
1955 SourceLocation SemiLoc = Tok.getLocation();
1956 if (!Tok.hasLeadingEmptyMacro() && !SemiLoc.
isMacroID())
1957 EmptyInitStmtSemiLoc = SemiLoc;
1960 isForRangeIdentifier()) {
1961 ProhibitAttributes(attrs);
1962 IdentifierInfo *Name = Tok.getIdentifierInfo();
1964 MaybeParseCXX11Attributes(attrs);
1967 if (Tok.is(tok::l_brace))
1968 ForRangeInfo.RangeExpr = ParseBraceInitializer();
1972 Diag(Loc, diag::err_for_range_identifier)
1977 ForRangeInfo.LoopVar =
1978 Actions.ActOnCXXForRangeIdentifier(
getCurScope(), Loc, Name, attrs);
1979 }
else if (isForInitDeclaration()) {
1983 if (!C99orCXXorObjC) {
1984 Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
1985 Diag(Tok, diag::warn_gcc_variable_decl_in_for_loop);
1988 SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
1990 Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
1991 ProhibitAttributes(attrs);
1992 Decl *D = ParseStaticAssertDeclaration(DeclEnd);
1993 DG = Actions.ConvertDeclToDeclGroup(D);
1994 FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
1995 }
else if (Tok.is(tok::kw_using)) {
1998 FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
2003 ParsedAttributes DeclSpecAttrs(AttrFactory);
2004 DG = ParseSimpleDeclaration(
2006 MightBeForRangeStmt ? &ForRangeInfo :
nullptr);
2007 FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
2008 if (ForRangeInfo.ParsedForRangeDecl()) {
2010 ? diag::warn_cxx98_compat_for_range
2011 : diag::ext_for_range);
2012 ForRangeInfo.LoopVar = FirstPart;
2014 }
else if (Tok.is(tok::semi)) {
2016 }
else if ((ForEach = isTokIdentifier_in())) {
2017 Actions.ActOnForEachDeclStmt(DG);
2021 if (Tok.is(tok::code_completion)) {
2023 Actions.CodeCompletion().CodeCompleteObjCForCollection(
getCurScope(),
2029 Diag(Tok, diag::err_expected_semi_for);
2033 ProhibitAttributes(attrs);
2036 ForEach = isTokIdentifier_in();
2039 if (!
Value.isInvalid()) {
2041 FirstPart = Actions.ActOnForEachLValueExpr(
Value.get());
2048 bool IsRangeBasedFor =
2049 getLangOpts().CPlusPlus11 && !ForEach && Tok.is(tok::colon);
2050 FirstPart = Actions.ActOnExprStmt(
Value, !IsRangeBasedFor);
2054 if (Tok.is(tok::semi)) {
2056 }
else if (ForEach) {
2059 if (Tok.is(tok::code_completion)) {
2061 Actions.CodeCompletion().CodeCompleteObjCForCollection(
getCurScope(),
2069 Diag(Tok, diag::err_for_range_expected_decl)
2070 << FirstPart.get()->getSourceRange();
2074 if (!
Value.isInvalid()) {
2075 Diag(Tok, diag::err_expected_semi_for);
2079 if (Tok.is(tok::semi))
2086 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl() &&
2089 if (Tok.is(tok::semi)) {
2091 }
else if (Tok.is(tok::r_paren)) {
2097 bool MightBeForRangeStmt = !ForRangeInfo.ParsedForRangeDecl();
2099 SourceLocation SecondPartStart = Tok.getLocation();
2101 SecondPart = ParseCXXCondition(
2102 nullptr, ForLoc, CK,
2104 true, MightBeForRangeStmt ? &ForRangeInfo :
nullptr,
2107 if (ForRangeInfo.ParsedForRangeDecl()) {
2108 Diag(FirstPart.get() ? FirstPart.get()->getBeginLoc()
2109 : ForRangeInfo.ColonLoc,
2111 ? diag::warn_cxx17_compat_for_range_init_stmt
2112 : diag::ext_for_range_init_stmt)
2113 << (FirstPart.get() ? FirstPart.get()->getSourceRange()
2115 if (EmptyInitStmtSemiLoc.
isValid()) {
2116 Diag(EmptyInitStmtSemiLoc, diag::warn_empty_init_statement)
2123 ExprResult CondExpr = Actions.CreateRecoveryExpr(
2125 Tok.getLocation() == SecondPartStart ? SecondPartStart
2127 {}, Actions.PreferredConditionType(CK));
2129 SecondPart = Actions.ActOnCondition(
getCurScope(), ForLoc,
2142 SecondPart = Actions.ActOnCondition(
2155 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl()) {
2156 if (Tok.isNot(tok::semi)) {
2158 Diag(Tok, diag::err_expected_semi_for);
2162 if (Tok.is(tok::semi)) {
2166 if (Tok.isNot(tok::r_paren)) {
2170 ThirdPart = Actions.MakeFullDiscardedValueExpr(Third.
get());
2178 if (CoawaitLoc.
isValid() && !ForRangeInfo.ParsedForRangeDecl()) {
2179 Diag(CoawaitLoc, diag::err_for_co_await_not_range_for);
2180 CoawaitLoc = SourceLocation();
2184 Diag(CoawaitLoc, diag::warn_deprecated_for_co_await);
2192 if (ForRangeInfo.ParsedForRangeDecl()) {
2193 ForRangeStmt = Actions.ActOnCXXForRangeStmt(
2194 getCurScope(), ForLoc, CoawaitLoc, FirstPart.get(),
2195 ForRangeInfo.LoopVar.get(), ForRangeInfo.ColonLoc,
2197 ForRangeInfo.LifetimeExtendTemps);
2198 }
else if (ForEach) {
2201 ForEachStmt = Actions.ObjC().ActOnObjCForCollectionStmt(
2202 ForLoc, FirstPart.get(), Collection.
get(),
T.getCloseLocation());
2206 if (
getLangOpts().OpenMP && FirstPart.isUsable()) {
2207 Actions.OpenMP().ActOnOpenMPLoopInitialization(ForLoc, FirstPart.get());
2214 if (ForRangeInfo.ParsedForRangeDecl())
2218 ForLoc, FirstPart.get(), SecondPart.
get().second, ThirdPart.get());
2236 Tok.is(tok::l_brace));
2245 MisleadingIndentationChecker MIChecker(*
this, MSK_for, ForLoc);
2248 StmtResult Body(ParseStatement(TrailingElseLoc));
2250 if (Body.isUsable())
2261 if (Body.isInvalid())
2265 return Actions.ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2268 if (ForRangeInfo.ParsedForRangeDecl())
2269 return Actions.FinishCXXForRangeStmt(ForRangeStmt.get(), Body.get());
2271 return Actions.ActOnForStmt(ForLoc,
T.getOpenLocation(), FirstPart.get(),
2272 SecondPart, ThirdPart,
T.getCloseLocation(),
2277 assert(Tok.is(tok::kw_goto) &&
"Not a goto stmt!");
2281 if (Tok.is(tok::identifier)) {
2282 LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(),
2284 Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(), LD);
2286 }
else if (Tok.is(tok::star)) {
2288 Diag(Tok, diag::ext_gnu_indirect_goto);
2291 if (R.isInvalid()) {
2295 Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.get());
2297 Diag(Tok, diag::err_expected) << tok::identifier;
2304StmtResult Parser::ParseBreakOrContinueStatement(
bool IsContinue) {
2306 SourceLocation LabelLoc;
2307 LabelDecl *
Target =
nullptr;
2308 if (Tok.is(tok::identifier)) {
2310 Actions.LookupExistingLabel(Tok.getIdentifierInfo(), Tok.getLocation());
2315 Diag(LabelLoc, diag::err_c2y_labeled_break_continue) << IsContinue;
2317 Diag(LabelLoc, diag::err_break_continue_label_not_found) << IsContinue;
2328 return ParseBreakOrContinueStatement(
true);
2332 return ParseBreakOrContinueStatement(
false);
2336 assert((Tok.is(tok::kw_return) || Tok.is(tok::kw_co_return)) &&
2337 "Not a return stmt!");
2338 bool IsCoreturn = Tok.is(tok::kw_co_return);
2342 if (Tok.isNot(tok::semi)) {
2344 PreferredType.enterReturn(Actions, Tok.getLocation());
2346 if (Tok.is(tok::code_completion) && !IsCoreturn) {
2348 Actions.CodeCompletion().CodeCompleteExpression(
2349 getCurScope(), PreferredType.get(Tok.getLocation()));
2354 R = ParseInitializer();
2358 ? diag::warn_cxx98_compat_generalized_initializer_lists
2359 : diag::ext_generalized_initializer_lists)
2369 return Actions.ActOnCoreturnStmt(
getCurScope(), ReturnLoc, R.
get());
2370 return Actions.ActOnReturnStmt(ReturnLoc, R.
get(),
getCurScope());
2373StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
2374 ParsedStmtContext StmtCtx,
2379 ParsedAttributes TempAttrs(AttrFactory);
2381 SourceLocation StartLoc = Tok.getLocation();
2384 while (Tok.is(tok::annot_pragma_loop_hint)) {
2386 if (!HandlePragmaLoopHint(Hint))
2392 AttributeScopeInfo(), ArgHints, 4,
2393 ParsedAttr::Form::Pragma());
2397 MaybeParseCXX11Attributes(Attrs);
2399 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2400 StmtResult S = ParseStatementOrDeclarationAfterAttributes(
2401 Stmts, StmtCtx, TrailingElseLoc, Attrs, EmptyDeclSpecAttrs,
2414Decl *Parser::ParseFunctionStatementBody(
Decl *
Decl, ParseScope &BodyScope) {
2415 assert(Tok.is(tok::l_brace));
2416 SourceLocation LBraceLoc = Tok.getLocation();
2418 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, LBraceLoc,
2419 "parsing function body");
2424 Sema::PragmaStackSentinelRAII
2425 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2430 StmtResult FnBody(ParseCompoundStatementBody());
2433 if (FnBody.isInvalid()) {
2434 Sema::CompoundScopeRAII CompoundScope(Actions);
2435 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, {},
false);
2439 return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
2442Decl *Parser::ParseFunctionTryBlock(
Decl *
Decl, ParseScope &BodyScope) {
2443 assert(Tok.is(tok::kw_try) &&
"Expected 'try'");
2446 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, TryLoc,
2447 "parsing function try block");
2450 if (Tok.is(tok::colon))
2451 ParseConstructorInitializer(Decl);
2453 Actions.ActOnDefaultCtorInitializers(Decl);
2458 Sema::PragmaStackSentinelRAII
2459 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2461 SourceLocation LBraceLoc = Tok.getLocation();
2462 StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc,
true));
2465 if (FnBody.isInvalid()) {
2466 Sema::CompoundScopeRAII CompoundScope(Actions);
2467 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, {},
false);
2471 return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
2474bool Parser::trySkippingFunctionBody() {
2475 assert(SkipFunctionBodies &&
2476 "Should only be called when SkipFunctionBodies is enabled");
2477 if (!PP.isCodeCompletionEnabled()) {
2484 TentativeParsingAction PA(*
this);
2485 bool IsTryCatch = Tok.is(tok::kw_try);
2487 bool ErrorInPrologue = ConsumeAndStoreFunctionPrologue(Toks);
2488 if (llvm::any_of(Toks, [](
const Token &Tok) {
2489 return Tok.is(tok::code_completion);
2494 if (ErrorInPrologue) {
2503 while (IsTryCatch && Tok.is(tok::kw_catch)) {
2515 assert(Tok.is(tok::kw_try) &&
"Expected 'try'");
2518 return ParseCXXTryBlockCommon(TryLoc);
2522 if (Tok.isNot(tok::l_brace))
2523 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2529 if (TryBlock.isInvalid())
2534 if ((Tok.is(tok::identifier) &&
2535 Tok.getIdentifierInfo() == getSEHExceptKeyword()) ||
2536 Tok.is(tok::kw___finally)) {
2539 if(Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
2541 Handler = ParseSEHExceptBlock(Loc);
2545 Handler = ParseSEHFinallyBlock(Loc);
2547 if(Handler.isInvalid())
2550 return Actions.ActOnSEHTryBlock(
true ,
2560 DiagnoseAndSkipCXX11Attributes();
2562 if (Tok.isNot(tok::kw_catch))
2564 while (Tok.is(tok::kw_catch)) {
2565 StmtResult Handler(ParseCXXCatchBlock(FnTry));
2566 if (!Handler.isInvalid())
2567 Handlers.push_back(Handler.get());
2571 if (Handlers.empty())
2574 return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.get(), Handlers);
2578StmtResult Parser::ParseCXXCatchBlock(
bool FnCatch) {
2579 assert(Tok.is(tok::kw_catch) &&
"Expected 'catch'");
2584 if (
T.expectAndConsume())
2596 Decl *ExceptionDecl =
nullptr;
2597 if (Tok.isNot(tok::ellipsis)) {
2598 ParsedAttributes Attributes(AttrFactory);
2599 MaybeParseCXX11Attributes(Attributes);
2601 DeclSpec DS(AttrFactory);
2603 if (ParseCXXTypeSpecifierSeq(DS))
2607 ParseDeclarator(ExDecl);
2608 ExceptionDecl = Actions.ActOnExceptionDeclarator(
getCurScope(), ExDecl);
2613 if (
T.getCloseLocation().isInvalid())
2616 if (Tok.isNot(tok::l_brace))
2617 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2621 if (
Block.isInvalid())
2624 return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl,
Block.get());
2627void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
2628 IfExistsCondition
Result;
2629 if (ParseMicrosoftIfExistsCondition(
Result))
2637 if (!Tok.is(tok::l_brace)) {
2638 Diag(Tok, diag::err_expected) << tok::l_brace;
2642 StmtResult Compound = ParseCompoundStatement();
2643 if (Compound.isInvalid())
2646 StmtResult DepResult = Actions.ActOnMSDependentExistsStmt(
Result.KeywordLoc,
2651 if (DepResult.isUsable())
2652 Stmts.push_back(DepResult.get());
2657 if (
Braces.consumeOpen()) {
2658 Diag(Tok, diag::err_expected) << tok::l_brace;
2662 switch (
Result.Behavior) {
2668 llvm_unreachable(
"Dependent case handled above");
2676 while (Tok.isNot(tok::r_brace)) {
2678 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::Compound);
2680 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.
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...
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
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
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
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 AddFlags(unsigned Flags)
Sets up the specified scope flags and adjusts the scope state variables accordingly.
void setPrecedingLabel(LabelDecl *LD)
void decrementMSManglingNumber()
@ SEHTryScope
This scope corresponds to an SEH try.
@ ContinueScope
This is a while, do, for, which can have continue statements embedded into it.
@ ControlScope
The controlling scope in a if/switch/while/for statement.
@ SEHFilterScope
We are currently in the filter expression of an SEH except block.
@ SwitchScope
This is a scope that corresponds to a switch statement.
@ BreakScope
This is a while, do, switch, for, etc that can have break statements embedded into it.
@ CatchScope
This is the scope of a C++ catch statement.
@ CompoundStmtScope
This is a compound statement scope.
@ FnTryCatchScope
This is the scope for a function-level C++ try or catch scope.
@ SEHExceptScope
This scope corresponds to an SEH except.
@ TryScope
This is the scope of a C++ try statement.
@ DeclScope
This is a scope that can contain a declaration.
@ PCC_ForInit
Code completion occurs at the beginning of the initialization statement (or expression) in a for loop...
@ PCC_Expression
Code completion occurs within an expression.
@ PCC_Statement
Code completion occurs within a statement, which may also be an expression or a declaration.
void 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.
@ 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.
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