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());
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()) {
1083 unsigned LookAhead = 0;
1094 if (IsStmtExprResult)
1095 E = Actions.ActOnStmtExprResult(E);
1096 return Actions.ActOnExprStmt(E, !IsStmtExprResult);
1099StmtResult Parser::ParseCompoundStatementBody(
bool isStmtExpr) {
1100 PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),
1102 "in compound statement ('{}')");
1106 Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);
1110 if (
T.consumeOpen())
1113 Sema::CompoundScopeRAII CompoundScope(Actions, isStmtExpr);
1116 ParseCompoundStatementLeadingPragmas();
1117 Actions.ActOnAfterCompoundStatementLeadingPragmas();
1123 while (Tok.is(tok::kw___label__)) {
1126 SmallVector<Decl *, 4> DeclsInGroup;
1128 if (Tok.isNot(tok::identifier)) {
1129 Diag(Tok, diag::err_expected) << tok::identifier;
1133 IdentifierInfo *II = Tok.getIdentifierInfo();
1135 DeclsInGroup.push_back(Actions.LookupOrCreateLabel(II, IdLoc, LabelLoc));
1141 DeclSpec DS(AttrFactory);
1143 Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, DeclsInGroup);
1144 StmtResult R = Actions.ActOnDeclStmt(Res, LabelLoc, Tok.getLocation());
1146 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
1148 Stmts.push_back(R.get());
1151 ParsedStmtContext SubStmtCtx =
1152 ParsedStmtContext::Compound |
1153 (isStmtExpr ? ParsedStmtContext::InStmtExpr : ParsedStmtContext());
1155 bool LastIsError =
false;
1156 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
1157 Tok.isNot(tok::eof)) {
1158 if (Tok.is(tok::annot_pragma_unused)) {
1159 HandlePragmaUnused();
1163 if (ConsumeNullStmt(Stmts))
1167 if (Tok.isNot(tok::kw___extension__)) {
1168 R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
1175 while (Tok.is(tok::kw___extension__))
1178 ParsedAttributes attrs(AttrFactory);
1179 MaybeParseCXX11Attributes(attrs,
true);
1182 if (isDeclarationStatement()) {
1185 ExtensionRAIIObject O(Diags);
1187 SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
1188 ParsedAttributes DeclSpecAttrs(AttrFactory);
1190 attrs, DeclSpecAttrs);
1191 R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);
1194 ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
1196 if (Res.isInvalid()) {
1203 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
1204 R = handleExprStmt(Res, SubStmtCtx);
1206 R = Actions.ActOnAttributedStmt(attrs, R.get());
1211 Stmts.push_back(R.get());
1212 LastIsError = R.isInvalid();
1218 if (isStmtExpr && LastIsError && !Stmts.empty())
1225 if (!PP.getTargetInfo().supportSourceEvalMethod() &&
1226 (PP.getLastFPEvalPragmaLocation().isValid() ||
1227 PP.getCurrentFPEvalMethod() ==
1229 Diag(Tok.getLocation(),
1230 diag::warn_no_support_for_eval_method_source_on_m32);
1232 SourceLocation CloseLoc = Tok.getLocation();
1235 if (!
T.consumeClose()) {
1238 if (isStmtExpr && Tok.is(tok::r_paren))
1239 checkCompoundToken(CloseLoc, tok::r_brace, CompoundToken::StmtExprEnd);
1245 if (
T.getCloseLocation().isValid())
1246 CloseLoc =
T.getCloseLocation();
1248 return Actions.ActOnCompoundStmt(
T.getOpenLocation(), CloseLoc,
1252bool Parser::ParseParenExprOrCondition(
StmtResult *InitStmt,
1260 SourceLocation Start = Tok.getLocation();
1263 Cond = ParseCXXCondition(InitStmt, Loc, CK,
false);
1278 if (
Cond.isInvalid() && Tok.isNot(tok::r_paren)) {
1282 if (Tok.isNot(tok::r_paren))
1286 if (
Cond.isInvalid()) {
1287 ExprResult CondExpr = Actions.CreateRecoveryExpr(
1288 Start, Tok.getLocation() == Start ? Start : PrevTokLocation, {},
1289 Actions.PreferredConditionType(CK));
1297 LParenLoc =
T.getOpenLocation();
1298 RParenLoc =
T.getCloseLocation();
1303 while (Tok.is(tok::r_paren)) {
1304 Diag(Tok, diag::err_extraneous_rparen_in_condition)
1314enum MisleadingStatementKind { MSK_if, MSK_else, MSK_for, MSK_while };
1316struct MisleadingIndentationChecker {
1318 SourceLocation StmtLoc;
1319 SourceLocation PrevLoc;
1320 unsigned NumDirectives;
1321 MisleadingStatementKind
Kind;
1323 MisleadingIndentationChecker(Parser &P, MisleadingStatementKind K,
1325 : P(P), StmtLoc(SL), PrevLoc(P.getCurToken().getLocation()),
1326 NumDirectives(P.getPreprocessor().getNumDirectives()),
Kind(K),
1327 ShouldSkip(P.getCurToken().
is(tok::l_brace)) {
1329 StmtLoc = P.MisleadingIndentationElseLoc;
1330 P.MisleadingIndentationElseLoc = SourceLocation();
1332 if (Kind == MSK_else && !ShouldSkip)
1338 static unsigned getVisualIndentation(SourceManager &
SM, SourceLocation Loc) {
1339 unsigned TabStop =
SM.getDiagnostics().getDiagnosticOptions().TabStop;
1341 unsigned ColNo =
SM.getSpellingColumnNumber(Loc);
1342 if (ColNo == 0 || TabStop == 1)
1348 StringRef BufData =
SM.getBufferData(FIDAndOffset.first, &
Invalid);
1352 const char *EndPos = BufData.data() + FIDAndOffset.second;
1354 assert(FIDAndOffset.second + 1 >= ColNo &&
1355 "Column number smaller than file offset?");
1357 unsigned VisualColumn = 0;
1360 for (
const char *CurPos = EndPos - (ColNo - 1); CurPos != EndPos;
1362 if (*CurPos ==
'\t')
1364 VisualColumn += (TabStop - VisualColumn % TabStop);
1368 return VisualColumn + 1;
1383 if (Kind == MSK_else)
1387 unsigned PrevColNum = getVisualIndentation(
SM, PrevLoc);
1389 unsigned StmtColNum = getVisualIndentation(
SM, StmtLoc);
1391 if (PrevColNum != 0 && CurColNum != 0 && StmtColNum != 0 &&
1392 ((PrevColNum > StmtColNum && PrevColNum == CurColNum) ||
1394 SM.getPresumedLineNumber(StmtLoc) !=
1399 P.
Diag(StmtLoc, diag::note_previous_statement);
1407 assert(Tok.is(tok::kw_if) &&
"Not an if stmt!");
1410 bool IsConstexpr =
false;
1411 bool IsConsteval =
false;
1412 SourceLocation NotLocation;
1413 SourceLocation ConstevalLoc;
1415 if (Tok.is(tok::kw_constexpr)) {
1419 : diag::ext_constexpr_if);
1424 if (Tok.is(tok::exclaim)) {
1428 if (Tok.is(tok::kw_consteval)) {
1430 : diag::ext_consteval_if);
1433 }
else if (Tok.is(tok::code_completion)) {
1435 Actions.CodeCompletion().CodeCompleteKeywordAfterIf(
1440 if (!IsConsteval && (NotLocation.
isValid() || Tok.isNot(tok::l_paren))) {
1441 Diag(Tok, diag::err_expected_lparen_after) <<
"if";
1464 Sema::ConditionResult
Cond;
1465 SourceLocation LParen;
1466 SourceLocation RParen;
1467 std::optional<bool> ConstexprCondition;
1470 if (ParseParenExprOrCondition(&InitStmt,
Cond, IfLoc,
1477 ConstexprCondition =
Cond.getKnownValue();
1480 bool IsBracedThen = Tok.is(tok::l_brace);
1502 MisleadingIndentationChecker MIChecker(*
this, MSK_if, IfLoc);
1505 SourceLocation ThenStmtLoc = Tok.getLocation();
1507 SourceLocation InnerStatementTrailingElseLoc;
1510 bool ShouldEnter = ConstexprCondition && !*ConstexprCondition;
1513 if (NotLocation.
isInvalid() && IsConsteval) {
1518 EnterExpressionEvaluationContext PotentiallyDiscarded(
1519 Actions, Context,
nullptr,
1521 ThenStmt = ParseStatement(&InnerStatementTrailingElseLoc);
1524 if (Tok.isNot(tok::kw_else))
1531 SourceLocation ElseLoc;
1532 SourceLocation ElseStmtLoc;
1535 if (Tok.is(tok::kw_else)) {
1536 if (TrailingElseLoc)
1537 *TrailingElseLoc = Tok.getLocation();
1540 ElseStmtLoc = Tok.getLocation();
1552 Tok.is(tok::l_brace));
1554 MisleadingIndentationChecker MIChecker(*
this, MSK_else, ElseLoc);
1555 bool ShouldEnter = ConstexprCondition && *ConstexprCondition;
1558 if (NotLocation.
isValid() && IsConsteval) {
1563 EnterExpressionEvaluationContext PotentiallyDiscarded(
1564 Actions, Context,
nullptr,
1566 ElseStmt = ParseStatement();
1568 if (ElseStmt.isUsable())
1573 }
else if (Tok.is(tok::code_completion)) {
1575 Actions.CodeCompletion().CodeCompleteAfterIf(
getCurScope(), IsBracedThen);
1577 }
else if (InnerStatementTrailingElseLoc.
isValid()) {
1578 Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else);
1586 if ((ThenStmt.isInvalid() && ElseStmt.isInvalid()) ||
1587 (ThenStmt.isInvalid() && ElseStmt.get() ==
nullptr) ||
1588 (ThenStmt.get() ==
nullptr && ElseStmt.isInvalid())) {
1594 auto IsCompoundStatement = [](
const Stmt *S) {
1595 if (
const auto *Outer = dyn_cast_if_present<AttributedStmt>(S))
1596 S = Outer->getSubStmt();
1597 return isa_and_nonnull<clang::CompoundStmt>(S);
1600 if (!IsCompoundStatement(ThenStmt.get())) {
1601 Diag(ConstevalLoc, diag::err_expected_after) <<
"consteval"
1605 if (!ElseStmt.isUnset() && !IsCompoundStatement(ElseStmt.get())) {
1606 Diag(ElseLoc, diag::err_expected_after) <<
"else"
1613 if (ThenStmt.isInvalid())
1614 ThenStmt = Actions.ActOnNullStmt(ThenStmtLoc);
1615 if (ElseStmt.isInvalid())
1616 ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);
1621 else if (IsConsteval)
1625 return Actions.ActOnIfStmt(IfLoc, Kind, LParen, InitStmt.get(),
Cond, RParen,
1626 ThenStmt.get(), ElseLoc, ElseStmt.get());
1631 assert(Tok.is(tok::kw_switch) &&
"Not a switch stmt!");
1634 if (Tok.isNot(tok::l_paren)) {
1635 Diag(Tok, diag::err_expected_lparen_after) <<
"switch";
1661 Sema::ConditionResult
Cond;
1662 SourceLocation LParen;
1663 SourceLocation RParen;
1664 if (ParseParenExprOrCondition(&InitStmt,
Cond, SwitchLoc,
1669 SwitchLoc, LParen, InitStmt.get(),
Cond, RParen);
1671 if (
Switch.isInvalid()) {
1676 if (Tok.is(tok::l_brace)) {
1705 StmtResult Body(ParseStatement(TrailingElseLoc));
1711 return Actions.ActOnFinishSwitchStmt(SwitchLoc,
Switch.get(), Body.get());
1716 assert(Tok.is(tok::kw_while) &&
"Not a while stmt!");
1717 SourceLocation WhileLoc = Tok.getLocation();
1720 if (Tok.isNot(tok::l_paren)) {
1721 Diag(Tok, diag::err_expected_lparen_after) <<
"while";
1740 unsigned ScopeFlags;
1749 Sema::ConditionResult
Cond;
1750 SourceLocation LParen;
1751 SourceLocation RParen;
1752 if (ParseParenExprOrCondition(
nullptr,
Cond, WhileLoc,
1775 MisleadingIndentationChecker MIChecker(*
this, MSK_while, WhileLoc);
1778 StmtResult Body(ParseStatement(TrailingElseLoc));
1780 if (Body.isUsable())
1786 if (
Cond.isInvalid() || Body.isInvalid())
1789 return Actions.ActOnWhileStmt(WhileLoc, LParen,
Cond, RParen, Body.get());
1793 assert(Tok.is(tok::kw_do) &&
"Not a do stmt!");
1798 unsigned ScopeFlags;
1832 if (Tok.isNot(tok::kw_while)) {
1833 if (!Body.isInvalid()) {
1834 Diag(Tok, diag::err_expected_while);
1835 Diag(DoLoc, diag::note_matching) <<
"'do'";
1842 if (Tok.isNot(tok::l_paren)) {
1843 Diag(Tok, diag::err_expected_lparen_after) <<
"do/while";
1853 DiagnoseAndSkipCXX11Attributes();
1855 SourceLocation Start = Tok.getLocation();
1857 if (!
Cond.isUsable()) {
1858 if (!Tok.isOneOf(tok::r_paren, tok::r_square, tok::r_brace))
1860 Cond = Actions.CreateRecoveryExpr(
1861 Start, Start == Tok.getLocation() ? Start : PrevTokLocation, {},
1862 Actions.getASTContext().BoolTy);
1867 if (
Cond.isInvalid() || Body.isInvalid())
1870 return Actions.ActOnDoStmt(DoLoc, Body.get(), WhileLoc,
T.getOpenLocation(),
1871 Cond.get(),
T.getCloseLocation());
1874bool Parser::isForRangeIdentifier() {
1875 assert(Tok.is(tok::identifier));
1878 if (
Next.is(tok::colon))
1881 if (
Next.isOneOf(tok::l_square, tok::kw_alignas)) {
1882 TentativeParsingAction PA(*
this);
1884 SkipCXX11Attributes();
1885 bool Result = Tok.is(tok::colon);
1895 assert(Tok.is(tok::kw_for) &&
"Not a for stmt!");
1898 SourceLocation CoawaitLoc;
1899 if (Tok.is(tok::kw_co_await))
1902 if (Tok.isNot(tok::l_paren)) {
1903 Diag(Tok, diag::err_expected_lparen_after) <<
"for";
1926 unsigned ScopeFlags = 0;
1937 bool ForEach =
false;
1939 Sema::ConditionResult SecondPart;
1941 ForRangeInfo ForRangeInfo;
1944 if (Tok.is(tok::code_completion)) {
1946 Actions.CodeCompletion().CodeCompleteOrdinaryName(
1952 ParsedAttributes attrs(AttrFactory);
1953 MaybeParseCXX11Attributes(attrs);
1955 SourceLocation EmptyInitStmtSemiLoc;
1958 if (Tok.is(tok::semi)) {
1959 ProhibitAttributes(attrs);
1961 SourceLocation SemiLoc = Tok.getLocation();
1962 if (!Tok.hasLeadingEmptyMacro() && !SemiLoc.
isMacroID())
1963 EmptyInitStmtSemiLoc = SemiLoc;
1966 isForRangeIdentifier()) {
1967 ProhibitAttributes(attrs);
1968 IdentifierInfo *Name = Tok.getIdentifierInfo();
1970 MaybeParseCXX11Attributes(attrs);
1973 if (Tok.is(tok::l_brace))
1974 ForRangeInfo.RangeExpr = ParseBraceInitializer();
1978 Diag(Loc, diag::err_for_range_identifier)
1983 ForRangeInfo.LoopVar =
1984 Actions.ActOnCXXForRangeIdentifier(
getCurScope(), Loc, Name, attrs);
1985 }
else if (isForInitDeclaration()) {
1989 if (!C99orCXXorObjC) {
1990 Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
1991 Diag(Tok, diag::warn_gcc_variable_decl_in_for_loop);
1994 SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
1996 Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
1997 ProhibitAttributes(attrs);
1998 Decl *D = ParseStaticAssertDeclaration(DeclEnd);
1999 DG = Actions.ConvertDeclToDeclGroup(D);
2000 FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
2001 }
else if (Tok.is(tok::kw_using)) {
2004 FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
2009 ParsedAttributes DeclSpecAttrs(AttrFactory);
2010 DG = ParseSimpleDeclaration(
2012 MightBeForRangeStmt ? &ForRangeInfo :
nullptr);
2013 FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
2014 if (ForRangeInfo.ParsedForRangeDecl()) {
2016 ? diag::warn_cxx98_compat_for_range
2017 : diag::ext_for_range);
2018 ForRangeInfo.LoopVar = FirstPart;
2020 }
else if (Tok.is(tok::semi)) {
2022 }
else if ((ForEach = isTokIdentifier_in())) {
2023 Actions.ActOnForEachDeclStmt(DG);
2027 if (Tok.is(tok::code_completion)) {
2029 Actions.CodeCompletion().CodeCompleteObjCForCollection(
getCurScope(),
2035 Diag(Tok, diag::err_expected_semi_for);
2039 ProhibitAttributes(attrs);
2042 ForEach = isTokIdentifier_in();
2045 if (!
Value.isInvalid()) {
2047 FirstPart = Actions.ActOnForEachLValueExpr(
Value.get());
2054 bool IsRangeBasedFor =
2055 getLangOpts().CPlusPlus11 && !ForEach && Tok.is(tok::colon);
2056 FirstPart = Actions.ActOnExprStmt(
Value, !IsRangeBasedFor);
2060 if (Tok.is(tok::semi)) {
2062 }
else if (ForEach) {
2065 if (Tok.is(tok::code_completion)) {
2067 Actions.CodeCompletion().CodeCompleteObjCForCollection(
getCurScope(),
2075 Diag(Tok, diag::err_for_range_expected_decl)
2076 << FirstPart.get()->getSourceRange();
2080 if (!
Value.isInvalid()) {
2081 Diag(Tok, diag::err_expected_semi_for);
2085 if (Tok.is(tok::semi))
2092 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl() &&
2095 if (Tok.is(tok::semi)) {
2097 }
else if (Tok.is(tok::r_paren)) {
2103 bool MightBeForRangeStmt = !ForRangeInfo.ParsedForRangeDecl();
2105 SourceLocation SecondPartStart = Tok.getLocation();
2107 SecondPart = ParseCXXCondition(
2108 nullptr, ForLoc, CK,
2110 true, MightBeForRangeStmt ? &ForRangeInfo :
nullptr,
2113 if (ForRangeInfo.ParsedForRangeDecl()) {
2114 Diag(FirstPart.get() ? FirstPart.get()->getBeginLoc()
2115 : ForRangeInfo.ColonLoc,
2117 ? diag::warn_cxx17_compat_for_range_init_stmt
2118 : diag::ext_for_range_init_stmt)
2119 << (FirstPart.get() ? FirstPart.get()->getSourceRange()
2121 if (EmptyInitStmtSemiLoc.
isValid()) {
2122 Diag(EmptyInitStmtSemiLoc, diag::warn_empty_init_statement)
2129 ExprResult CondExpr = Actions.CreateRecoveryExpr(
2131 Tok.getLocation() == SecondPartStart ? SecondPartStart
2133 {}, Actions.PreferredConditionType(CK));
2135 SecondPart = Actions.ActOnCondition(
getCurScope(), ForLoc,
2148 SecondPart = Actions.ActOnCondition(
2161 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl()) {
2162 if (Tok.isNot(tok::semi)) {
2164 Diag(Tok, diag::err_expected_semi_for);
2168 if (Tok.is(tok::semi)) {
2172 if (Tok.isNot(tok::r_paren)) {
2176 ThirdPart = Actions.MakeFullDiscardedValueExpr(Third.
get());
2184 if (CoawaitLoc.
isValid() && !ForRangeInfo.ParsedForRangeDecl()) {
2185 Diag(CoawaitLoc, diag::err_for_co_await_not_range_for);
2186 CoawaitLoc = SourceLocation();
2190 Diag(CoawaitLoc, diag::warn_deprecated_for_co_await);
2198 if (ForRangeInfo.ParsedForRangeDecl()) {
2199 ForRangeStmt = Actions.ActOnCXXForRangeStmt(
2200 getCurScope(), ForLoc, CoawaitLoc, FirstPart.get(),
2201 ForRangeInfo.LoopVar.get(), ForRangeInfo.ColonLoc,
2203 ForRangeInfo.LifetimeExtendTemps);
2204 }
else if (ForEach) {
2207 ForEachStmt = Actions.ObjC().ActOnObjCForCollectionStmt(
2208 ForLoc, FirstPart.get(), Collection.
get(),
T.getCloseLocation());
2212 if (
getLangOpts().OpenMP && FirstPart.isUsable()) {
2213 Actions.OpenMP().ActOnOpenMPLoopInitialization(ForLoc, FirstPart.get());
2220 if (ForRangeInfo.ParsedForRangeDecl())
2224 ForLoc, FirstPart.get(), SecondPart.
get().second, ThirdPart.get());
2242 Tok.is(tok::l_brace));
2251 MisleadingIndentationChecker MIChecker(*
this, MSK_for, ForLoc);
2254 StmtResult Body(ParseStatement(TrailingElseLoc));
2256 if (Body.isUsable())
2267 if (Body.isInvalid())
2271 return Actions.ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2274 if (ForRangeInfo.ParsedForRangeDecl())
2275 return Actions.FinishCXXForRangeStmt(ForRangeStmt.get(), Body.get());
2277 return Actions.ActOnForStmt(ForLoc,
T.getOpenLocation(), FirstPart.get(),
2278 SecondPart, ThirdPart,
T.getCloseLocation(),
2283 assert(Tok.is(tok::kw_goto) &&
"Not a goto stmt!");
2287 if (Tok.is(tok::identifier)) {
2288 LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(),
2290 Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(), LD);
2292 }
else if (Tok.is(tok::star)) {
2294 Diag(Tok, diag::ext_gnu_indirect_goto);
2297 if (R.isInvalid()) {
2301 Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.get());
2303 Diag(Tok, diag::err_expected) << tok::identifier;
2310StmtResult Parser::ParseBreakOrContinueStatement(
bool IsContinue) {
2312 SourceLocation LabelLoc;
2313 LabelDecl *
Target =
nullptr;
2314 if (Tok.is(tok::identifier)) {
2316 Actions.LookupExistingLabel(Tok.getIdentifierInfo(), Tok.getLocation());
2321 Diag(LabelLoc, diag::err_c2y_labeled_break_continue) << IsContinue;
2323 Diag(LabelLoc, diag::err_break_continue_label_not_found) << IsContinue;
2334 return ParseBreakOrContinueStatement(
true);
2338 return ParseBreakOrContinueStatement(
false);
2342 assert((Tok.is(tok::kw_return) || Tok.is(tok::kw_co_return)) &&
2343 "Not a return stmt!");
2344 bool IsCoreturn = Tok.is(tok::kw_co_return);
2348 if (Tok.isNot(tok::semi)) {
2350 PreferredType.enterReturn(Actions, Tok.getLocation());
2352 if (Tok.is(tok::code_completion) && !IsCoreturn) {
2354 Actions.CodeCompletion().CodeCompleteExpression(
2355 getCurScope(), PreferredType.get(Tok.getLocation()));
2360 R = ParseInitializer();
2364 ? diag::warn_cxx98_compat_generalized_initializer_lists
2365 : diag::ext_generalized_initializer_lists)
2375 return Actions.ActOnCoreturnStmt(
getCurScope(), ReturnLoc, R.
get());
2376 return Actions.ActOnReturnStmt(ReturnLoc, R.
get(),
getCurScope());
2379StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
2380 ParsedStmtContext StmtCtx,
2385 ParsedAttributes TempAttrs(AttrFactory);
2387 SourceLocation StartLoc = Tok.getLocation();
2390 while (Tok.is(tok::annot_pragma_loop_hint)) {
2392 if (!HandlePragmaLoopHint(Hint))
2398 AttributeScopeInfo(), ArgHints, 4,
2399 ParsedAttr::Form::Pragma());
2403 MaybeParseCXX11Attributes(Attrs);
2405 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2406 StmtResult S = ParseStatementOrDeclarationAfterAttributes(
2407 Stmts, StmtCtx, TrailingElseLoc, Attrs, EmptyDeclSpecAttrs,
2420Decl *Parser::ParseFunctionStatementBody(
Decl *
Decl, ParseScope &BodyScope) {
2421 assert(Tok.is(tok::l_brace));
2422 SourceLocation LBraceLoc = Tok.getLocation();
2424 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, LBraceLoc,
2425 "parsing function body");
2430 Sema::PragmaStackSentinelRAII
2431 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2436 StmtResult FnBody(ParseCompoundStatementBody());
2439 if (FnBody.isInvalid()) {
2440 Sema::CompoundScopeRAII CompoundScope(Actions);
2441 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, {},
false);
2445 return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
2448Decl *Parser::ParseFunctionTryBlock(
Decl *
Decl, ParseScope &BodyScope) {
2449 assert(Tok.is(tok::kw_try) &&
"Expected 'try'");
2452 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, TryLoc,
2453 "parsing function try block");
2456 if (Tok.is(tok::colon))
2457 ParseConstructorInitializer(Decl);
2459 Actions.ActOnDefaultCtorInitializers(Decl);
2464 Sema::PragmaStackSentinelRAII
2465 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2467 SourceLocation LBraceLoc = Tok.getLocation();
2468 StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc,
true));
2471 if (FnBody.isInvalid()) {
2472 Sema::CompoundScopeRAII CompoundScope(Actions);
2473 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, {},
false);
2477 return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
2480bool Parser::trySkippingFunctionBody() {
2481 assert(SkipFunctionBodies &&
2482 "Should only be called when SkipFunctionBodies is enabled");
2483 if (!PP.isCodeCompletionEnabled()) {
2490 TentativeParsingAction PA(*
this);
2491 bool IsTryCatch = Tok.is(tok::kw_try);
2493 bool ErrorInPrologue = ConsumeAndStoreFunctionPrologue(Toks);
2494 if (llvm::any_of(Toks, [](
const Token &Tok) {
2495 return Tok.is(tok::code_completion);
2500 if (ErrorInPrologue) {
2509 while (IsTryCatch && Tok.is(tok::kw_catch)) {
2521 assert(Tok.is(tok::kw_try) &&
"Expected 'try'");
2524 return ParseCXXTryBlockCommon(TryLoc);
2528 if (Tok.isNot(tok::l_brace))
2529 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2535 if (TryBlock.isInvalid())
2540 if ((Tok.is(tok::identifier) &&
2541 Tok.getIdentifierInfo() == getSEHExceptKeyword()) ||
2542 Tok.is(tok::kw___finally)) {
2545 if(Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
2547 Handler = ParseSEHExceptBlock(Loc);
2551 Handler = ParseSEHFinallyBlock(Loc);
2553 if(Handler.isInvalid())
2556 return Actions.ActOnSEHTryBlock(
true ,
2566 DiagnoseAndSkipCXX11Attributes();
2568 if (Tok.isNot(tok::kw_catch))
2570 while (Tok.is(tok::kw_catch)) {
2571 StmtResult Handler(ParseCXXCatchBlock(FnTry));
2572 if (!Handler.isInvalid())
2573 Handlers.push_back(Handler.get());
2577 if (Handlers.empty())
2580 return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.get(), Handlers);
2584StmtResult Parser::ParseCXXCatchBlock(
bool FnCatch) {
2585 assert(Tok.is(tok::kw_catch) &&
"Expected 'catch'");
2590 if (
T.expectAndConsume())
2602 Decl *ExceptionDecl =
nullptr;
2603 if (Tok.isNot(tok::ellipsis)) {
2604 ParsedAttributes Attributes(AttrFactory);
2605 MaybeParseCXX11Attributes(Attributes);
2607 DeclSpec DS(AttrFactory);
2609 if (ParseCXXTypeSpecifierSeq(DS))
2613 ParseDeclarator(ExDecl);
2614 ExceptionDecl = Actions.ActOnExceptionDeclarator(
getCurScope(), ExDecl);
2619 if (
T.getCloseLocation().isInvalid())
2622 if (Tok.isNot(tok::l_brace))
2623 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2627 if (
Block.isInvalid())
2630 return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl,
Block.get());
2633void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
2634 IfExistsCondition
Result;
2635 if (ParseMicrosoftIfExistsCondition(
Result))
2643 if (!Tok.is(tok::l_brace)) {
2644 Diag(Tok, diag::err_expected) << tok::l_brace;
2648 StmtResult Compound = ParseCompoundStatement();
2649 if (Compound.isInvalid())
2652 StmtResult DepResult = Actions.ActOnMSDependentExistsStmt(
Result.KeywordLoc,
2657 if (DepResult.isUsable())
2658 Stmts.push_back(DepResult.get());
2663 if (
Braces.consumeOpen()) {
2664 Diag(Tok, diag::err_expected) << tok::l_brace;
2668 switch (
Result.Behavior) {
2674 llvm_unreachable(
"Dependent case handled above");
2682 while (Tok.isNot(tok::r_brace)) {
2684 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::Compound);
2686 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 takeAllFrom(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
const Token & GetLookAheadToken(unsigned N)
GetLookAheadToken - This peeks ahead N tokens and returns that token without consuming any tokens.
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