30#include "llvm/ADT/STLExtras.h"
31#include "llvm/ADT/ScopeExit.h"
41 ParsedStmtContext StmtCtx,
49 Res = ParseStatementOrDeclaration(Stmts, StmtCtx, TrailingElseLoc,
51 }
while (!Res.isInvalid() && !Res.get());
56StmtResult Parser::ParseStatementOrDeclaration(StmtVector &Stmts,
57 ParsedStmtContext StmtCtx,
68 ParsedAttributes CXX11Attrs(AttrFactory);
70 MaybeParseCXX11Attributes(CXX11Attrs,
true);
71 ParsedAttributes GNUOrMSAttrs(AttrFactory);
73 MaybeParseGNUAttributes(GNUOrMSAttrs);
76 MaybeParseMicrosoftAttributes(GNUOrMSAttrs);
78 StmtResult Res = ParseStatementOrDeclarationAfterAttributes(
79 Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs, GNUOrMSAttrs,
81 MaybeDestroyTemplateIds();
85 assert((CXX11Attrs.empty() || Res.isInvalid() || Res.isUsable()) &&
86 "attributes on empty statement");
89 (StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
90 ParsedStmtContext{} &&
91 isa_and_present<NullStmt>(Res.get()))
92 Diag(CXX11Attrs.Range.getBegin(), diag::warn_attr_in_secondary_block)
95 if (CXX11Attrs.empty() || Res.isInvalid())
98 return Actions.ActOnAttributedStmt(CXX11Attrs, Res.get());
104 StatementFilterCCC(Token nextTok) : NextToken(nextTok) {
105 WantTypeSpecifiers = nextTok.
isOneOf(tok::l_paren, tok::less, tok::l_square,
106 tok::identifier, tok::star, tok::amp);
107 WantExpressionKeywords =
108 nextTok.
isOneOf(tok::l_paren, tok::identifier, tok::arrow, tok::period);
109 WantRemainingKeywords =
110 nextTok.
isOneOf(tok::l_paren, tok::semi, tok::identifier, tok::l_brace);
111 WantCXXNamedCasts =
false;
114 bool ValidateCandidate(
const TypoCorrection &candidate)
override {
117 if (NextToken.is(tok::equal))
119 if (NextToken.is(tok::period) &&
125 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
126 return std::make_unique<StatementFilterCCC>(*
this);
134StmtResult Parser::ParseStatementOrDeclarationAfterAttributes(
135 StmtVector &Stmts, ParsedStmtContext StmtCtx,
138 const char *SemiError =
nullptr;
140 SourceLocation GNUAttributeLoc;
147 SourceLocation AtLoc;
152 return ParseObjCAtStatement(AtLoc, StmtCtx);
155 case tok::code_completion:
157 Actions.CodeCompletion().CodeCompleteOrdinaryName(
161 case tok::identifier:
164 if (
Next.is(tok::colon)) {
171 return ParseLabeledStatement(CXX11Attrs, StmtCtx);
176 if (
Next.isNot(tok::coloncolon)) {
179 StatementFilterCCC CCC(
Next);
184 if (Tok.is(tok::semi))
190 if (Tok.isNot(tok::identifier))
202 bool HaveAttrs = !CXX11Attrs.
empty() || !GNUAttrs.
empty();
203 auto IsStmtAttr = [](ParsedAttr &Attr) {
return Attr.isStmtAttr(); };
204 bool AllAttrsAreStmtAttrs = llvm::all_of(CXX11Attrs, IsStmtAttr) &&
205 llvm::all_of(GNUAttrs, IsStmtAttr);
212 (StmtCtx & ParsedStmtContext::AllowDeclarationsInC) !=
213 ParsedStmtContext()) &&
214 ((GNUAttributeLoc.
isValid() && !(HaveAttrs && AllAttrsAreStmtAttrs)) ||
215 isDeclarationStatement())) {
216 SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
218 if (GNUAttributeLoc.
isValid()) {
219 DeclStart = GNUAttributeLoc;
221 GNUAttrs, &GNUAttributeLoc);
234 return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
237 if (Tok.is(tok::r_brace)) {
238 Diag(Tok, diag::err_expected_statement);
242 switch (Tok.getKind()) {
243#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
244#include "clang/Basic/TransformTypeTraits.def"
246 Tok.setKind(tok::identifier);
247 Diag(Tok, diag::ext_keyword_as_ident)
248 << Tok.getIdentifierInfo()->getName() << 0;
249 goto ParseIdentifier;
253 return ParseExprStatement(StmtCtx);
257 case tok::kw___attribute: {
258 GNUAttributeLoc = Tok.getLocation();
259 ParseGNUAttributes(GNUAttrs);
263 case tok::kw_template: {
264 SourceLocation DeclEnd;
266 getAccessSpecifierIfPresent());
271 return ParseCaseStatement(StmtCtx);
272 case tok::kw_default:
273 return ParseDefaultStatement(StmtCtx);
276 return ParseCompoundStatement();
278 bool HasLeadingEmptyMacro = Tok.hasLeadingEmptyMacro();
279 return Actions.ActOnNullStmt(
ConsumeToken(), HasLeadingEmptyMacro);
283 return ParseIfStatement(TrailingElseLoc);
285 return ParseSwitchStatement(TrailingElseLoc, PrecedingLabel);
288 return ParseWhileStatement(TrailingElseLoc, PrecedingLabel);
290 Res = ParseDoStatement(PrecedingLabel);
291 SemiError =
"do/while";
294 return ParseForStatement(TrailingElseLoc, PrecedingLabel);
297 Res = ParseGotoStatement();
300 case tok::kw_continue:
301 Res = ParseContinueStatement();
302 SemiError =
"continue";
305 Res = ParseBreakStatement();
309 Res = ParseReturnStatement();
310 SemiError =
"return";
312 case tok::kw_co_return:
313 Res = ParseReturnStatement();
314 SemiError =
"co_return";
317 return ParseDeferStatement(TrailingElseLoc);
320 for (
const ParsedAttr &AL : CXX11Attrs)
323 (AL.isRegularKeywordAttribute()
324 ?
Diag(AL.getRange().getBegin(), diag::err_keyword_not_allowed)
325 :
Diag(AL.getRange().getBegin(), diag::warn_attribute_ignored))
329 ProhibitAttributes(GNUAttrs);
331 Res = ParseAsmStatement(msAsm);
332 if (msAsm)
return Res;
337 case tok::kw___if_exists:
338 case tok::kw___if_not_exists:
339 ProhibitAttributes(CXX11Attrs);
340 ProhibitAttributes(GNUAttrs);
341 ParseMicrosoftIfExistsStatement(Stmts);
347 return ParseCXXTryBlock();
350 ProhibitAttributes(CXX11Attrs);
351 ProhibitAttributes(GNUAttrs);
352 return ParseSEHTryBlock();
354 case tok::kw___leave:
355 Res = ParseSEHLeaveStatement();
356 SemiError =
"__leave";
359 case tok::annot_pragma_vis:
360 ProhibitAttributes(CXX11Attrs);
361 ProhibitAttributes(GNUAttrs);
362 HandlePragmaVisibility();
365 case tok::annot_pragma_pack:
366 ProhibitAttributes(CXX11Attrs);
367 ProhibitAttributes(GNUAttrs);
371 case tok::annot_pragma_msstruct:
372 ProhibitAttributes(CXX11Attrs);
373 ProhibitAttributes(GNUAttrs);
374 HandlePragmaMSStruct();
377 case tok::annot_pragma_align:
378 ProhibitAttributes(CXX11Attrs);
379 ProhibitAttributes(GNUAttrs);
383 case tok::annot_pragma_weak:
384 ProhibitAttributes(CXX11Attrs);
385 ProhibitAttributes(GNUAttrs);
389 case tok::annot_pragma_weakalias:
390 ProhibitAttributes(CXX11Attrs);
391 ProhibitAttributes(GNUAttrs);
392 HandlePragmaWeakAlias();
395 case tok::annot_pragma_redefine_extname:
396 ProhibitAttributes(CXX11Attrs);
397 ProhibitAttributes(GNUAttrs);
398 HandlePragmaRedefineExtname();
401 case tok::annot_pragma_fp_contract:
402 ProhibitAttributes(CXX11Attrs);
403 ProhibitAttributes(GNUAttrs);
404 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"fp_contract";
405 ConsumeAnnotationToken();
408 case tok::annot_pragma_fp:
409 ProhibitAttributes(CXX11Attrs);
410 ProhibitAttributes(GNUAttrs);
411 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"clang fp";
412 ConsumeAnnotationToken();
415 case tok::annot_pragma_fenv_access:
416 case tok::annot_pragma_fenv_access_ms:
417 ProhibitAttributes(CXX11Attrs);
418 ProhibitAttributes(GNUAttrs);
419 Diag(Tok, diag::err_pragma_file_or_compound_scope)
420 << (
Kind == tok::annot_pragma_fenv_access ?
"STDC FENV_ACCESS"
422 ConsumeAnnotationToken();
425 case tok::annot_pragma_fenv_round:
426 ProhibitAttributes(CXX11Attrs);
427 ProhibitAttributes(GNUAttrs);
428 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"STDC FENV_ROUND";
429 ConsumeAnnotationToken();
432 case tok::annot_pragma_cx_limited_range:
433 ProhibitAttributes(CXX11Attrs);
434 ProhibitAttributes(GNUAttrs);
435 Diag(Tok, diag::err_pragma_file_or_compound_scope)
436 <<
"STDC CX_LIMITED_RANGE";
437 ConsumeAnnotationToken();
440 case tok::annot_pragma_float_control:
441 ProhibitAttributes(CXX11Attrs);
442 ProhibitAttributes(GNUAttrs);
443 Diag(Tok, diag::err_pragma_file_or_compound_scope) <<
"float_control";
444 ConsumeAnnotationToken();
447 case tok::annot_pragma_opencl_extension:
448 ProhibitAttributes(CXX11Attrs);
449 ProhibitAttributes(GNUAttrs);
450 HandlePragmaOpenCLExtension();
453 case tok::annot_pragma_captured:
454 ProhibitAttributes(CXX11Attrs);
455 ProhibitAttributes(GNUAttrs);
456 return HandlePragmaCaptured();
458 case tok::annot_pragma_openmp:
461 ProhibitAttributes(CXX11Attrs);
462 ProhibitAttributes(GNUAttrs);
464 case tok::annot_attr_openmp:
466 return ParseOpenMPDeclarativeOrExecutableDirective(StmtCtx);
468 case tok::annot_pragma_openacc:
471 case tok::annot_pragma_ms_pointers_to_members:
472 ProhibitAttributes(CXX11Attrs);
473 ProhibitAttributes(GNUAttrs);
474 HandlePragmaMSPointersToMembers();
477 case tok::annot_pragma_ms_pragma:
478 ProhibitAttributes(CXX11Attrs);
479 ProhibitAttributes(GNUAttrs);
480 HandlePragmaMSPragma();
483 case tok::annot_pragma_ms_vtordisp:
484 ProhibitAttributes(CXX11Attrs);
485 ProhibitAttributes(GNUAttrs);
486 HandlePragmaMSVtorDisp();
489 case tok::annot_pragma_loop_hint:
490 ProhibitAttributes(CXX11Attrs);
491 ProhibitAttributes(GNUAttrs);
492 return ParsePragmaLoopHint(Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs,
495 case tok::annot_pragma_dump:
496 ProhibitAttributes(CXX11Attrs);
497 ProhibitAttributes(GNUAttrs);
501 case tok::annot_pragma_attribute:
502 ProhibitAttributes(CXX11Attrs);
503 ProhibitAttributes(GNUAttrs);
504 HandlePragmaAttribute();
506 case tok::annot_pragma_export:
507 ProhibitAttributes(CXX11Attrs);
508 ProhibitAttributes(GNUAttrs);
509 HandlePragmaExport();
518 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt, SemiError);
526StmtResult Parser::ParseExprStatement(ParsedStmtContext StmtCtx) {
528 Token OldToken = Tok;
530 ExprStatementTokLoc = Tok.getLocation();
534 if (Expr.isInvalid()) {
539 if (Tok.is(tok::semi))
541 return Actions.ActOnExprStmtError();
544 if (Tok.is(tok::colon) &&
getCurScope()->isSwitchScope() &&
545 Actions.CheckCaseExpression(Expr.get())) {
548 Diag(OldToken, diag::err_expected_case_before_expression)
552 return ParseCaseStatement(StmtCtx,
true, Expr);
555 Token *CurTok =
nullptr;
558 if (Tok.is(tok::annot_repl_input_end))
562 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
565 if (CurTok && !R.isInvalid())
572 assert(Tok.is(tok::kw___try) &&
"Expected '__try'");
575 if (Tok.isNot(tok::l_brace))
576 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
581 if (TryBlock.isInvalid())
585 if (Tok.is(tok::identifier) &&
586 Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
588 Handler = ParseSEHExceptBlock(Loc);
589 }
else if (Tok.is(tok::kw___finally)) {
591 Handler = ParseSEHFinallyBlock(Loc);
596 if(Handler.isInvalid())
599 return Actions.ActOnSEHTryBlock(
false ,
606 PoisonIdentifierRAIIObject raii(Ident__exception_code,
false),
607 raii2(Ident___exception_code,
false),
608 raii3(Ident_GetExceptionCode,
false);
610 if (ExpectAndConsume(tok::l_paren))
617 Ident__exception_info->setIsPoisoned(
false);
618 Ident___exception_info->setIsPoisoned(
false);
619 Ident_GetExceptionInfo->setIsPoisoned(
false);
624 ParseScopeFlags FilterScope(
this,
getCurScope()->getFlags() |
630 Ident__exception_info->setIsPoisoned(
true);
631 Ident___exception_info->setIsPoisoned(
true);
632 Ident_GetExceptionInfo->setIsPoisoned(
true);
638 if (ExpectAndConsume(tok::r_paren))
641 if (Tok.isNot(tok::l_brace))
642 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
646 if(
Block.isInvalid())
649 return Actions.ActOnSEHExceptBlock(ExceptLoc, FilterExpr.
get(),
Block.get());
653 PoisonIdentifierRAIIObject raii(Ident__abnormal_termination,
false),
654 raii2(Ident___abnormal_termination,
false),
655 raii3(Ident_AbnormalTermination,
false);
657 if (Tok.isNot(tok::l_brace))
658 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
661 Actions.ActOnStartSEHFinallyBlock();
664 if(
Block.isInvalid()) {
665 Actions.ActOnAbortSEHFinallyBlock();
669 return Actions.ActOnFinishSEHFinallyBlock(FinallyLoc,
Block.get());
679 return Actions.ActOnSEHLeaveStmt(LeaveLoc,
getCurScope());
689 ? diag::warn_c23_compat_label_followed_by_declaration
690 : diag::ext_c_label_followed_by_declaration);
695 ParsedStmtContext StmtCtx) {
696 assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
697 "Not an identifier!");
702 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
704 Token IdentTok = Tok;
707 assert(Tok.is(tok::colon) &&
"Not a label!");
717 if (Tok.is(tok::kw___attribute)) {
718 ParsedAttributes TempAttrs(AttrFactory);
719 ParseGNUAttributes(TempAttrs);
732 ParsedAttributes EmptyCXX11Attrs(AttrFactory);
733 SubStmt = ParseStatementOrDeclarationAfterAttributes(
734 Stmts, StmtCtx,
nullptr, EmptyCXX11Attrs,
736 if (!TempAttrs.empty() && !SubStmt.isInvalid())
737 SubStmt = Actions.ActOnAttributedStmt(TempAttrs, SubStmt.get());
742 if (SubStmt.isUnset() && Tok.is(tok::r_brace)) {
743 DiagnoseLabelAtEndOfCompoundStatement();
744 SubStmt = Actions.ActOnNullStmt(ColonLoc);
748 if (SubStmt.isUnset())
749 SubStmt = ParseStatement(
nullptr, StmtCtx, LD);
752 if (SubStmt.isInvalid())
753 SubStmt = Actions.ActOnNullStmt(ColonLoc);
757 Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
760 return Actions.ActOnLabelStmt(IdentTok.
getLocation(), LD, ColonLoc,
764StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx,
766 assert((MissingCase || Tok.is(tok::kw_case)) &&
"Not a case stmt!");
771 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
794 Stmt *DeepestParsedCaseStmt =
nullptr;
797 SourceLocation ColonLoc;
799 SourceLocation CaseLoc = MissingCase ? Expr.
get()->
getExprLoc() :
801 ColonLoc = SourceLocation();
803 if (Tok.is(tok::code_completion)) {
805 Actions.CodeCompletion().CodeCompleteCase(
getCurScope());
824 LHS = Actions.ActOnCaseExpr(CaseLoc, Expr);
829 SourceLocation DotDotDotLoc;
835 DiagId = diag::ext_gnu_case_range;
837 DiagId = diag::warn_c23_compat_case_range;
839 DiagId = diag::ext_c2y_case_range;
840 Diag(DotDotDotLoc, DiagId);
848 ColonProtection.restore();
854 Diag(ColonLoc, diag::err_expected_after)
855 <<
"'case'" << tok::colon
860 Diag(ExpectedLoc, diag::err_expected_after)
861 <<
"'case'" << tok::colon
864 ColonLoc = ExpectedLoc;
868 Actions.ActOnCaseStmt(CaseLoc, LHS, DotDotDotLoc, RHS, ColonLoc);
872 if (Case.isInvalid()) {
873 if (TopLevelCase.isInvalid())
874 return ParseStatement(
nullptr, StmtCtx);
879 Stmt *NextDeepest = Case.get();
880 if (TopLevelCase.isInvalid())
883 Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, Case.get());
884 DeepestParsedCaseStmt = NextDeepest;
888 }
while (Tok.is(tok::kw_case));
893 if (Tok.is(tok::r_brace)) {
896 DiagnoseLabelAtEndOfCompoundStatement();
897 SubStmt = Actions.ActOnNullStmt(ColonLoc);
899 SubStmt = ParseStatement(
nullptr, StmtCtx);
903 if (DeepestParsedCaseStmt) {
905 if (SubStmt.isInvalid())
906 SubStmt = Actions.ActOnNullStmt(SourceLocation());
908 Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, SubStmt.get());
915StmtResult Parser::ParseDefaultStatement(ParsedStmtContext StmtCtx) {
916 assert(Tok.is(tok::kw_default) &&
"Not a default stmt!");
921 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
925 SourceLocation ColonLoc;
929 Diag(ColonLoc, diag::err_expected_after)
930 <<
"'default'" << tok::colon
933 SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation);
934 Diag(ExpectedLoc, diag::err_expected_after)
935 <<
"'default'" << tok::colon
937 ColonLoc = ExpectedLoc;
942 if (Tok.is(tok::r_brace)) {
945 DiagnoseLabelAtEndOfCompoundStatement();
946 SubStmt = Actions.ActOnNullStmt(ColonLoc);
948 SubStmt = ParseStatement(
nullptr, StmtCtx);
952 if (SubStmt.isInvalid())
953 SubStmt = Actions.ActOnNullStmt(ColonLoc);
956 return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc,
960StmtResult Parser::ParseCompoundStatement(
bool isStmtExpr) {
961 return ParseCompoundStatement(isStmtExpr,
965StmtResult Parser::ParseCompoundStatement(
bool isStmtExpr,
966 unsigned ScopeFlags) {
967 assert(Tok.is(tok::l_brace) &&
"Not a compound stmt!");
975 StackHandler.runWithSufficientStackSpace(Tok.getLocation(), [&,
this]() {
976 R = ParseCompoundStatementBody(isStmtExpr);
981void Parser::ParseCompoundStatementLeadingPragmas() {
982 bool checkForPragmas =
true;
983 while (checkForPragmas) {
984 switch (Tok.getKind()) {
985 case tok::annot_pragma_vis:
986 HandlePragmaVisibility();
988 case tok::annot_pragma_pack:
991 case tok::annot_pragma_msstruct:
992 HandlePragmaMSStruct();
994 case tok::annot_pragma_align:
997 case tok::annot_pragma_weak:
1000 case tok::annot_pragma_weakalias:
1001 HandlePragmaWeakAlias();
1003 case tok::annot_pragma_redefine_extname:
1004 HandlePragmaRedefineExtname();
1006 case tok::annot_pragma_opencl_extension:
1007 HandlePragmaOpenCLExtension();
1009 case tok::annot_pragma_fp_contract:
1010 HandlePragmaFPContract();
1012 case tok::annot_pragma_fp:
1015 case tok::annot_pragma_fenv_access:
1016 case tok::annot_pragma_fenv_access_ms:
1017 HandlePragmaFEnvAccess();
1019 case tok::annot_pragma_fenv_round:
1020 HandlePragmaFEnvRound();
1022 case tok::annot_pragma_cx_limited_range:
1023 HandlePragmaCXLimitedRange();
1025 case tok::annot_pragma_float_control:
1026 HandlePragmaFloatControl();
1028 case tok::annot_pragma_ms_pointers_to_members:
1029 HandlePragmaMSPointersToMembers();
1031 case tok::annot_pragma_ms_pragma:
1032 HandlePragmaMSPragma();
1034 case tok::annot_pragma_ms_vtordisp:
1035 HandlePragmaMSVtorDisp();
1037 case tok::annot_pragma_dump:
1040 case tok::annot_pragma_export:
1041 HandlePragmaExport();
1044 checkForPragmas =
false;
1051void Parser::DiagnoseLabelAtEndOfCompoundStatement() {
1054 ? diag::warn_cxx20_compat_label_end_of_compound_statement
1055 : diag::ext_cxx_label_end_of_compound_statement);
1058 ? diag::warn_c23_compat_label_end_of_compound_statement
1059 : diag::ext_c_label_end_of_compound_statement);
1063bool Parser::ConsumeNullStmt(StmtVector &Stmts) {
1064 if (!Tok.is(tok::semi))
1067 SourceLocation StartLoc = Tok.getLocation();
1068 SourceLocation EndLoc;
1070 while (Tok.is(tok::semi) && !Tok.hasLeadingEmptyMacro() &&
1071 Tok.getLocation().isValid() && !Tok.getLocation().isMacroID()) {
1072 EndLoc = Tok.getLocation();
1076 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::SubStmt);
1078 Stmts.push_back(R.get());
1085 Diag(StartLoc, diag::warn_null_statement)
1091 bool IsStmtExprResult =
false;
1092 if ((StmtCtx & ParsedStmtContext::InStmtExpr) != ParsedStmtContext()) {
1096 IsStmtExprResult = Tok.is(tok::r_brace) &&
NextToken().
is(tok::r_paren);
1099 if (IsStmtExprResult)
1100 E = Actions.ActOnStmtExprResult(E);
1101 return Actions.ActOnExprStmt(E, !IsStmtExprResult);
1104StmtResult Parser::ParseCompoundStatementBody(
bool isStmtExpr) {
1105 PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),
1107 "in compound statement ('{}')");
1111 Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);
1115 if (
T.consumeOpen())
1118 Sema::CompoundScopeRAII CompoundScope(Actions, isStmtExpr);
1121 ParseCompoundStatementLeadingPragmas();
1122 Actions.ActOnAfterCompoundStatementLeadingPragmas();
1128 while (Tok.is(tok::kw___label__)) {
1131 SmallVector<Decl *, 4> DeclsInGroup;
1133 if (Tok.isNot(tok::identifier)) {
1134 Diag(Tok, diag::err_expected) << tok::identifier;
1138 IdentifierInfo *II = Tok.getIdentifierInfo();
1140 DeclsInGroup.push_back(Actions.LookupOrCreateLabel(II, IdLoc, LabelLoc));
1146 DeclSpec DS(AttrFactory);
1148 Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, DeclsInGroup);
1149 StmtResult R = Actions.ActOnDeclStmt(Res, LabelLoc, Tok.getLocation());
1151 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
1153 Stmts.push_back(R.get());
1156 ParsedStmtContext SubStmtCtx =
1157 ParsedStmtContext::Compound |
1158 (isStmtExpr ? ParsedStmtContext::InStmtExpr : ParsedStmtContext());
1160 bool LastIsError =
false;
1161 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
1162 Tok.isNot(tok::eof)) {
1163 if (Tok.is(tok::annot_pragma_unused)) {
1164 HandlePragmaUnused();
1168 if (ConsumeNullStmt(Stmts))
1172 if (Tok.isNot(tok::kw___extension__)) {
1173 R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
1180 while (Tok.is(tok::kw___extension__))
1183 ParsedAttributes attrs(AttrFactory);
1184 MaybeParseCXX11Attributes(attrs,
true);
1187 if (isDeclarationStatement()) {
1190 ExtensionRAIIObject O(Diags);
1192 SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
1193 ParsedAttributes DeclSpecAttrs(AttrFactory);
1195 attrs, DeclSpecAttrs);
1196 R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);
1199 ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
1201 if (Res.isInvalid()) {
1208 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
1209 R = handleExprStmt(Res, SubStmtCtx);
1211 R = Actions.ActOnAttributedStmt(attrs, R.get());
1216 Stmts.push_back(R.get());
1217 LastIsError = R.isInvalid();
1223 if (isStmtExpr && LastIsError && !Stmts.empty())
1230 if (!PP.getTargetInfo().supportSourceEvalMethod() &&
1231 (PP.getLastFPEvalPragmaLocation().isValid() ||
1232 PP.getCurrentFPEvalMethod() ==
1234 Diag(Tok.getLocation(),
1235 diag::warn_no_support_for_eval_method_source_on_m32);
1237 SourceLocation CloseLoc = Tok.getLocation();
1240 if (!
T.consumeClose()) {
1243 if (isStmtExpr && Tok.is(tok::r_paren))
1244 checkCompoundToken(CloseLoc, tok::r_brace, CompoundToken::StmtExprEnd);
1250 if (
T.getCloseLocation().isValid())
1251 CloseLoc =
T.getCloseLocation();
1253 return Actions.ActOnCompoundStmt(
T.getOpenLocation(), CloseLoc,
1257bool Parser::ParseParenExprOrCondition(
StmtResult *InitStmt,
1265 SourceLocation Start = Tok.getLocation();
1268 Cond = ParseCXXCondition(InitStmt, Loc, CK,
false);
1283 if (
Cond.isInvalid() && Tok.isNot(tok::r_paren)) {
1287 if (Tok.isNot(tok::r_paren))
1291 if (
Cond.isInvalid()) {
1292 ExprResult CondExpr = Actions.CreateRecoveryExpr(
1293 Start, Tok.getLocation() == Start ? Start : PrevTokLocation, {},
1294 Actions.PreferredConditionType(CK));
1302 LParenLoc =
T.getOpenLocation();
1303 RParenLoc =
T.getCloseLocation();
1308 while (Tok.is(tok::r_paren)) {
1309 Diag(Tok, diag::err_extraneous_rparen_in_condition)
1319enum MisleadingStatementKind { MSK_if, MSK_else, MSK_for, MSK_while };
1321struct MisleadingIndentationChecker {
1323 SourceLocation StmtLoc;
1324 SourceLocation PrevLoc;
1325 unsigned NumDirectives;
1326 MisleadingStatementKind
Kind;
1328 MisleadingIndentationChecker(Parser &P, MisleadingStatementKind K,
1330 : P(P), StmtLoc(SL), PrevLoc(P.getCurToken().getLocation()),
1331 NumDirectives(P.getPreprocessor().getNumDirectives()),
Kind(K),
1332 ShouldSkip(P.getCurToken().
is(tok::l_brace)) {
1334 StmtLoc = P.MisleadingIndentationElseLoc;
1335 P.MisleadingIndentationElseLoc = SourceLocation();
1337 if (Kind == MSK_else && !ShouldSkip)
1343 static unsigned getVisualIndentation(SourceManager &
SM, SourceLocation Loc) {
1344 unsigned TabStop =
SM.getDiagnostics().getDiagnosticOptions().TabStop;
1346 unsigned ColNo =
SM.getSpellingColumnNumber(Loc);
1347 if (ColNo == 0 || TabStop == 1)
1353 StringRef BufData =
SM.getBufferData(FIDAndOffset.first, &
Invalid);
1357 const char *EndPos = BufData.data() + FIDAndOffset.second;
1359 assert(FIDAndOffset.second + 1 >= ColNo &&
1360 "Column number smaller than file offset?");
1362 unsigned VisualColumn = 0;
1365 for (
const char *CurPos = EndPos - (ColNo - 1); CurPos != EndPos;
1367 if (*CurPos ==
'\t')
1369 VisualColumn += (TabStop - VisualColumn % TabStop);
1373 return VisualColumn + 1;
1388 if (Kind == MSK_else)
1392 unsigned PrevColNum = getVisualIndentation(
SM, PrevLoc);
1394 unsigned StmtColNum = getVisualIndentation(
SM, StmtLoc);
1396 if (PrevColNum != 0 && CurColNum != 0 && StmtColNum != 0 &&
1397 ((PrevColNum > StmtColNum && PrevColNum == CurColNum) ||
1399 SM.getPresumedLineNumber(StmtLoc) !=
1404 P.
Diag(StmtLoc, diag::note_previous_statement);
1412 assert(Tok.is(tok::kw_if) &&
"Not an if stmt!");
1415 bool IsConstexpr =
false;
1416 bool IsConsteval =
false;
1417 SourceLocation NotLocation;
1418 SourceLocation ConstevalLoc;
1420 if (Tok.is(tok::kw_constexpr)) {
1424 : diag::ext_constexpr_if);
1429 if (Tok.is(tok::exclaim)) {
1433 if (Tok.is(tok::kw_consteval)) {
1435 : diag::ext_consteval_if);
1438 }
else if (Tok.is(tok::code_completion)) {
1440 Actions.CodeCompletion().CodeCompleteKeywordAfterIf(
1445 if (!IsConsteval && (NotLocation.
isValid() || Tok.isNot(tok::l_paren))) {
1446 Diag(Tok, diag::err_expected_lparen_after) <<
"if";
1469 Sema::ConditionResult
Cond;
1470 SourceLocation LParen;
1471 SourceLocation RParen;
1472 std::optional<bool> ConstexprCondition;
1475 if (ParseParenExprOrCondition(&InitStmt,
Cond, IfLoc,
1482 ConstexprCondition =
Cond.getKnownValue();
1485 bool IsBracedThen = Tok.is(tok::l_brace);
1507 MisleadingIndentationChecker MIChecker(*
this, MSK_if, IfLoc);
1510 SourceLocation ThenStmtLoc = Tok.getLocation();
1512 SourceLocation InnerStatementTrailingElseLoc;
1515 bool ShouldEnter = ConstexprCondition && !*ConstexprCondition;
1518 if (NotLocation.
isInvalid() && IsConsteval) {
1523 EnterExpressionEvaluationContext PotentiallyDiscarded(
1524 Actions, Context,
nullptr,
1526 ThenStmt = ParseStatement(&InnerStatementTrailingElseLoc);
1529 if (Tok.isNot(tok::kw_else))
1536 SourceLocation ElseLoc;
1537 SourceLocation ElseStmtLoc;
1540 if (Tok.is(tok::kw_else)) {
1541 if (TrailingElseLoc)
1542 *TrailingElseLoc = Tok.getLocation();
1545 ElseStmtLoc = Tok.getLocation();
1557 Tok.is(tok::l_brace));
1559 MisleadingIndentationChecker MIChecker(*
this, MSK_else, ElseLoc);
1560 bool ShouldEnter = ConstexprCondition && *ConstexprCondition;
1563 if (NotLocation.
isValid() && IsConsteval) {
1568 EnterExpressionEvaluationContext PotentiallyDiscarded(
1569 Actions, Context,
nullptr,
1571 ElseStmt = ParseStatement();
1573 if (ElseStmt.isUsable())
1578 }
else if (Tok.is(tok::code_completion)) {
1580 Actions.CodeCompletion().CodeCompleteAfterIf(
getCurScope(), IsBracedThen);
1582 }
else if (InnerStatementTrailingElseLoc.
isValid()) {
1583 Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else);
1591 if ((ThenStmt.isInvalid() && ElseStmt.isInvalid()) ||
1592 (ThenStmt.isInvalid() && ElseStmt.get() ==
nullptr) ||
1593 (ThenStmt.get() ==
nullptr && ElseStmt.isInvalid())) {
1599 auto IsCompoundStatement = [](
const Stmt *S) {
1600 if (
const auto *Outer = dyn_cast_if_present<AttributedStmt>(S))
1601 S = Outer->getSubStmt();
1602 return isa_and_nonnull<clang::CompoundStmt>(S);
1605 if (!IsCompoundStatement(ThenStmt.get())) {
1606 Diag(ConstevalLoc, diag::err_expected_after) <<
"consteval"
1610 if (!ElseStmt.isUnset() && !IsCompoundStatement(ElseStmt.get())) {
1611 Diag(ElseLoc, diag::err_expected_after) <<
"else"
1618 if (ThenStmt.isInvalid())
1619 ThenStmt = Actions.ActOnNullStmt(ThenStmtLoc);
1620 if (ElseStmt.isInvalid())
1621 ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);
1626 else if (IsConsteval)
1630 return Actions.ActOnIfStmt(IfLoc, Kind, LParen, InitStmt.get(),
Cond, RParen,
1631 ThenStmt.get(), ElseLoc, ElseStmt.get());
1636 assert(Tok.is(tok::kw_switch) &&
"Not a switch stmt!");
1639 if (Tok.isNot(tok::l_paren)) {
1640 Diag(Tok, diag::err_expected_lparen_after) <<
"switch";
1666 Sema::ConditionResult
Cond;
1667 SourceLocation LParen;
1668 SourceLocation RParen;
1669 if (ParseParenExprOrCondition(&InitStmt,
Cond, SwitchLoc,
1674 SwitchLoc, LParen, InitStmt.get(),
Cond, RParen);
1676 if (
Switch.isInvalid()) {
1681 if (Tok.is(tok::l_brace)) {
1710 StmtResult Body(ParseStatement(TrailingElseLoc));
1716 return Actions.ActOnFinishSwitchStmt(SwitchLoc,
Switch.get(), Body.get());
1721 assert(Tok.is(tok::kw_while) &&
"Not a while stmt!");
1722 SourceLocation WhileLoc = Tok.getLocation();
1725 if (Tok.isNot(tok::l_paren)) {
1726 Diag(Tok, diag::err_expected_lparen_after) <<
"while";
1745 unsigned ScopeFlags;
1754 Sema::ConditionResult
Cond;
1755 SourceLocation LParen;
1756 SourceLocation RParen;
1757 if (ParseParenExprOrCondition(
nullptr,
Cond, WhileLoc,
1780 MisleadingIndentationChecker MIChecker(*
this, MSK_while, WhileLoc);
1783 StmtResult Body(ParseStatement(TrailingElseLoc));
1785 if (Body.isUsable())
1791 if (
Cond.isInvalid() || Body.isInvalid())
1794 return Actions.ActOnWhileStmt(WhileLoc, LParen,
Cond, RParen, Body.get());
1798 assert(Tok.is(tok::kw_do) &&
"Not a do stmt!");
1803 unsigned ScopeFlags;
1837 if (Tok.isNot(tok::kw_while)) {
1838 if (!Body.isInvalid()) {
1839 Diag(Tok, diag::err_expected_while);
1840 Diag(DoLoc, diag::note_matching) <<
"'do'";
1847 if (Tok.isNot(tok::l_paren)) {
1848 Diag(Tok, diag::err_expected_lparen_after) <<
"do/while";
1858 DiagnoseAndSkipCXX11Attributes();
1860 SourceLocation Start = Tok.getLocation();
1862 if (!
Cond.isUsable()) {
1863 if (!Tok.isOneOf(tok::r_paren, tok::r_square, tok::r_brace))
1865 Cond = Actions.CreateRecoveryExpr(
1866 Start, Start == Tok.getLocation() ? Start : PrevTokLocation, {},
1867 Actions.getASTContext().BoolTy);
1872 if (
Cond.isInvalid() || Body.isInvalid())
1875 return Actions.ActOnDoStmt(DoLoc, Body.get(), WhileLoc,
T.getOpenLocation(),
1876 Cond.get(),
T.getCloseLocation());
1879bool Parser::isForRangeIdentifier() {
1880 assert(Tok.is(tok::identifier));
1883 if (
Next.is(tok::colon))
1886 if (
Next.isOneOf(tok::l_square, tok::kw_alignas)) {
1887 TentativeParsingAction PA(*
this);
1889 SkipCXX11Attributes();
1890 bool Result = Tok.is(tok::colon);
1900 assert(Tok.is(tok::kw_for) &&
"Not a for stmt!");
1903 SourceLocation CoawaitLoc;
1904 if (Tok.is(tok::kw_co_await))
1907 if (Tok.isNot(tok::l_paren)) {
1908 Diag(Tok, diag::err_expected_lparen_after) <<
"for";
1931 unsigned ScopeFlags = 0;
1942 bool ForEach =
false;
1944 Sema::ConditionResult SecondPart;
1946 ForRangeInfo ForRangeInfo;
1949 if (Tok.is(tok::code_completion)) {
1951 Actions.CodeCompletion().CodeCompleteOrdinaryName(
1957 ParsedAttributes attrs(AttrFactory);
1958 MaybeParseCXX11Attributes(attrs);
1960 SourceLocation EmptyInitStmtSemiLoc;
1963 if (Tok.is(tok::semi)) {
1964 ProhibitAttributes(attrs);
1966 SourceLocation SemiLoc = Tok.getLocation();
1967 if (!Tok.hasLeadingEmptyMacro() && !SemiLoc.
isMacroID())
1968 EmptyInitStmtSemiLoc = SemiLoc;
1971 isForRangeIdentifier()) {
1972 ProhibitAttributes(attrs);
1973 IdentifierInfo *Name = Tok.getIdentifierInfo();
1975 MaybeParseCXX11Attributes(attrs);
1978 if (Tok.is(tok::l_brace))
1979 ForRangeInfo.RangeExpr = ParseBraceInitializer();
1983 Diag(Loc, diag::err_for_range_identifier)
1988 ForRangeInfo.LoopVar =
1989 Actions.ActOnCXXForRangeIdentifier(
getCurScope(), Loc, Name, attrs);
1990 }
else if (isForInitDeclaration()) {
1994 if (!C99orCXXorObjC) {
1995 Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
1996 Diag(Tok, diag::warn_gcc_variable_decl_in_for_loop);
1999 SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
2001 Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
2002 ProhibitAttributes(attrs);
2003 Decl *D = ParseStaticAssertDeclaration(DeclEnd);
2004 DG = Actions.ConvertDeclToDeclGroup(D);
2005 FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
2006 }
else if (Tok.is(tok::kw_using)) {
2009 FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
2014 ParsedAttributes DeclSpecAttrs(AttrFactory);
2015 DG = ParseSimpleDeclaration(
2017 MightBeForRangeStmt ? &ForRangeInfo :
nullptr);
2018 FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
2019 if (ForRangeInfo.ParsedForRangeDecl()) {
2021 ? diag::warn_cxx98_compat_for_range
2022 : diag::ext_for_range);
2023 ForRangeInfo.LoopVar = FirstPart;
2025 }
else if (Tok.is(tok::semi)) {
2027 }
else if ((ForEach = isTokIdentifier_in())) {
2028 Actions.ActOnForEachDeclStmt(DG);
2032 if (Tok.is(tok::code_completion)) {
2034 Actions.CodeCompletion().CodeCompleteObjCForCollection(
getCurScope(),
2040 Diag(Tok, diag::err_expected_semi_for);
2044 ProhibitAttributes(attrs);
2047 ForEach = isTokIdentifier_in();
2050 if (!
Value.isInvalid()) {
2052 FirstPart = Actions.ActOnForEachLValueExpr(
Value.get());
2059 bool IsRangeBasedFor =
2060 getLangOpts().CPlusPlus11 && !ForEach && Tok.is(tok::colon);
2061 FirstPart = Actions.ActOnExprStmt(
Value, !IsRangeBasedFor);
2065 if (Tok.is(tok::semi)) {
2067 }
else if (ForEach) {
2070 if (Tok.is(tok::code_completion)) {
2072 Actions.CodeCompletion().CodeCompleteObjCForCollection(
getCurScope(),
2080 Diag(Tok, diag::err_for_range_expected_decl)
2081 << FirstPart.get()->getSourceRange();
2085 if (!
Value.isInvalid()) {
2086 Diag(Tok, diag::err_expected_semi_for);
2090 if (Tok.is(tok::semi))
2097 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl() &&
2100 if (Tok.is(tok::semi)) {
2102 }
else if (Tok.is(tok::r_paren)) {
2108 bool MightBeForRangeStmt = !ForRangeInfo.ParsedForRangeDecl();
2110 SourceLocation SecondPartStart = Tok.getLocation();
2112 SecondPart = ParseCXXCondition(
2113 nullptr, ForLoc, CK,
2115 true, MightBeForRangeStmt ? &ForRangeInfo :
nullptr,
2118 if (ForRangeInfo.ParsedForRangeDecl()) {
2119 Diag(FirstPart.get() ? FirstPart.get()->getBeginLoc()
2120 : ForRangeInfo.ColonLoc,
2122 ? diag::warn_cxx17_compat_for_range_init_stmt
2123 : diag::ext_for_range_init_stmt)
2124 << (FirstPart.get() ? FirstPart.get()->getSourceRange()
2126 if (EmptyInitStmtSemiLoc.
isValid()) {
2127 Diag(EmptyInitStmtSemiLoc, diag::warn_empty_init_statement)
2134 ExprResult CondExpr = Actions.CreateRecoveryExpr(
2136 Tok.getLocation() == SecondPartStart ? SecondPartStart
2138 {}, Actions.PreferredConditionType(CK));
2140 SecondPart = Actions.ActOnCondition(
getCurScope(), ForLoc,
2153 SecondPart = Actions.ActOnCondition(
2166 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl()) {
2167 if (Tok.isNot(tok::semi)) {
2169 Diag(Tok, diag::err_expected_semi_for);
2173 if (Tok.is(tok::semi)) {
2177 if (Tok.isNot(tok::r_paren)) {
2181 ThirdPart = Actions.MakeFullDiscardedValueExpr(Third.
get());
2189 if (CoawaitLoc.
isValid() && !ForRangeInfo.ParsedForRangeDecl()) {
2190 Diag(CoawaitLoc, diag::err_for_co_await_not_range_for);
2191 CoawaitLoc = SourceLocation();
2195 Diag(CoawaitLoc, diag::warn_deprecated_for_co_await);
2203 if (ForRangeInfo.ParsedForRangeDecl()) {
2204 ForRangeStmt = Actions.ActOnCXXForRangeStmt(
2205 getCurScope(), ForLoc, CoawaitLoc, FirstPart.get(),
2206 ForRangeInfo.LoopVar.get(), ForRangeInfo.ColonLoc,
2208 ForRangeInfo.LifetimeExtendTemps);
2209 }
else if (ForEach) {
2212 ForEachStmt = Actions.ObjC().ActOnObjCForCollectionStmt(
2213 ForLoc, FirstPart.get(), Collection.
get(),
T.getCloseLocation());
2217 if (
getLangOpts().OpenMP && FirstPart.isUsable()) {
2218 Actions.OpenMP().ActOnOpenMPLoopInitialization(ForLoc, FirstPart.get());
2225 if (ForRangeInfo.ParsedForRangeDecl())
2229 ForLoc, FirstPart.get(), SecondPart.
get().second, ThirdPart.get());
2247 Tok.is(tok::l_brace));
2256 MisleadingIndentationChecker MIChecker(*
this, MSK_for, ForLoc);
2259 StmtResult Body(ParseStatement(TrailingElseLoc));
2261 if (Body.isUsable())
2272 if (Body.isInvalid())
2276 return Actions.ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2279 if (ForRangeInfo.ParsedForRangeDecl())
2280 return Actions.FinishCXXForRangeStmt(ForRangeStmt.get(), Body.get());
2282 return Actions.ActOnForStmt(ForLoc,
T.getOpenLocation(), FirstPart.get(),
2283 SecondPart, ThirdPart,
T.getCloseLocation(),
2288 assert(Tok.is(tok::kw_goto) &&
"Not a goto stmt!");
2292 if (Tok.is(tok::identifier)) {
2293 LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(),
2295 Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(), LD);
2297 }
else if (Tok.is(tok::star)) {
2299 Diag(Tok, diag::ext_gnu_indirect_goto);
2302 if (R.isInvalid()) {
2306 Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.get());
2308 Diag(Tok, diag::err_expected) << tok::identifier;
2315StmtResult Parser::ParseBreakOrContinueStatement(
bool IsContinue) {
2317 SourceLocation LabelLoc;
2318 LabelDecl *
Target =
nullptr;
2319 if (Tok.is(tok::identifier)) {
2321 Actions.LookupExistingLabel(Tok.getIdentifierInfo(), Tok.getLocation());
2326 Diag(LabelLoc, diag::err_c2y_labeled_break_continue) << IsContinue;
2328 Diag(LabelLoc, diag::err_break_continue_label_not_found) << IsContinue;
2339 return ParseBreakOrContinueStatement(
true);
2343 return ParseBreakOrContinueStatement(
false);
2347 assert((Tok.is(tok::kw_return) || Tok.is(tok::kw_co_return)) &&
2348 "Not a return stmt!");
2349 bool IsCoreturn = Tok.is(tok::kw_co_return);
2353 if (Tok.isNot(tok::semi)) {
2355 PreferredType.enterReturn(Actions, Tok.getLocation());
2357 if (Tok.is(tok::code_completion) && !IsCoreturn) {
2359 Actions.CodeCompletion().CodeCompleteExpression(
2360 getCurScope(), PreferredType.get(Tok.getLocation()));
2365 R = ParseInitializer();
2369 ? diag::warn_cxx98_compat_generalized_initializer_lists
2370 : diag::ext_generalized_initializer_lists)
2380 return Actions.ActOnCoreturnStmt(
getCurScope(), ReturnLoc, R.
get());
2381 return Actions.ActOnReturnStmt(ReturnLoc, R.
get(),
getCurScope());
2385 assert(Tok.is(tok::kw__Defer));
2388 Actions.ActOnStartOfDeferStmt(DeferLoc,
getCurScope());
2390 llvm::scope_exit OnError([&] { Actions.ActOnDeferStmtError(
getCurScope()); });
2392 StmtResult Res = ParseStatement(TrailingElseLoc);
2393 if (!Res.isUsable())
2397 if (
auto *L = dyn_cast<LabelStmt>(Res.get())) {
2398 Diag(L->getIdentLoc(), diag::err_defer_ts_labeled_stmt);
2403 return Actions.ActOnEndOfDeferStmt(Res.get(),
getCurScope());
2406StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
2407 ParsedStmtContext StmtCtx,
2412 ParsedAttributes TempAttrs(AttrFactory);
2414 SourceLocation StartLoc = Tok.getLocation();
2417 while (Tok.is(tok::annot_pragma_loop_hint)) {
2419 if (!HandlePragmaLoopHint(Hint))
2425 AttributeScopeInfo(), ArgHints, 4,
2426 ParsedAttr::Form::Pragma());
2430 MaybeParseCXX11Attributes(Attrs);
2432 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2433 StmtResult S = ParseStatementOrDeclarationAfterAttributes(
2434 Stmts, StmtCtx, TrailingElseLoc, Attrs, EmptyDeclSpecAttrs,
2447Decl *Parser::ParseFunctionStatementBody(
Decl *
Decl, ParseScope &BodyScope) {
2448 assert(Tok.is(tok::l_brace));
2449 SourceLocation LBraceLoc = Tok.getLocation();
2451 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, LBraceLoc,
2452 "parsing function body");
2457 Sema::PragmaStackSentinelRAII
2458 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2463 StmtResult FnBody(ParseCompoundStatementBody());
2466 if (FnBody.isInvalid()) {
2467 Sema::CompoundScopeRAII CompoundScope(Actions);
2468 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, {},
false);
2472 return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
2475Decl *Parser::ParseFunctionTryBlock(
Decl *
Decl, ParseScope &BodyScope) {
2476 assert(Tok.is(tok::kw_try) &&
"Expected 'try'");
2479 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, TryLoc,
2480 "parsing function try block");
2483 if (Tok.is(tok::colon))
2484 ParseConstructorInitializer(Decl);
2486 Actions.ActOnDefaultCtorInitializers(Decl);
2491 Sema::PragmaStackSentinelRAII
2492 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2494 SourceLocation LBraceLoc = Tok.getLocation();
2495 StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc,
true));
2498 if (FnBody.isInvalid()) {
2499 Sema::CompoundScopeRAII CompoundScope(Actions);
2500 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, {},
false);
2504 return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
2507bool Parser::trySkippingFunctionBody() {
2508 assert(SkipFunctionBodies &&
2509 "Should only be called when SkipFunctionBodies is enabled");
2510 if (!PP.isCodeCompletionEnabled()) {
2517 TentativeParsingAction PA(*
this);
2518 bool IsTryCatch = Tok.is(tok::kw_try);
2520 bool ErrorInPrologue = ConsumeAndStoreFunctionPrologue(Toks);
2521 if (llvm::any_of(Toks, [](
const Token &Tok) {
2522 return Tok.is(tok::code_completion);
2527 if (ErrorInPrologue) {
2536 while (IsTryCatch && Tok.is(tok::kw_catch)) {
2548 assert(Tok.is(tok::kw_try) &&
"Expected 'try'");
2551 return ParseCXXTryBlockCommon(TryLoc);
2555 if (Tok.isNot(tok::l_brace))
2556 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2562 if (TryBlock.isInvalid())
2567 if ((Tok.is(tok::identifier) &&
2568 Tok.getIdentifierInfo() == getSEHExceptKeyword()) ||
2569 Tok.is(tok::kw___finally)) {
2572 if(Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
2574 Handler = ParseSEHExceptBlock(Loc);
2578 Handler = ParseSEHFinallyBlock(Loc);
2580 if(Handler.isInvalid())
2583 return Actions.ActOnSEHTryBlock(
true ,
2593 DiagnoseAndSkipCXX11Attributes();
2595 if (Tok.isNot(tok::kw_catch))
2597 while (Tok.is(tok::kw_catch)) {
2598 StmtResult Handler(ParseCXXCatchBlock(FnTry));
2599 if (!Handler.isInvalid())
2600 Handlers.push_back(Handler.get());
2604 if (Handlers.empty())
2607 return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.get(), Handlers);
2611StmtResult Parser::ParseCXXCatchBlock(
bool FnCatch) {
2612 assert(Tok.is(tok::kw_catch) &&
"Expected 'catch'");
2617 if (
T.expectAndConsume())
2629 Decl *ExceptionDecl =
nullptr;
2630 if (Tok.isNot(tok::ellipsis)) {
2631 ParsedAttributes Attributes(AttrFactory);
2632 MaybeParseCXX11Attributes(Attributes);
2634 DeclSpec DS(AttrFactory);
2636 if (ParseCXXTypeSpecifierSeq(DS))
2640 ParseDeclarator(ExDecl);
2641 ExceptionDecl = Actions.ActOnExceptionDeclarator(
getCurScope(), ExDecl);
2646 if (
T.getCloseLocation().isInvalid())
2649 if (Tok.isNot(tok::l_brace))
2650 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2654 if (
Block.isInvalid())
2657 return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl,
Block.get());
2660void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
2661 IfExistsCondition
Result;
2662 if (ParseMicrosoftIfExistsCondition(
Result))
2670 if (!Tok.is(tok::l_brace)) {
2671 Diag(Tok, diag::err_expected) << tok::l_brace;
2675 StmtResult Compound = ParseCompoundStatement();
2676 if (Compound.isInvalid())
2679 StmtResult DepResult = Actions.ActOnMSDependentExistsStmt(
Result.KeywordLoc,
2684 if (DepResult.isUsable())
2685 Stmts.push_back(DepResult.get());
2690 if (
Braces.consumeOpen()) {
2691 Diag(Tok, diag::err_expected) << tok::l_brace;
2695 switch (
Result.Behavior) {
2701 llvm_unreachable(
"Dependent case handled above");
2709 while (Tok.isNot(tok::r_brace)) {
2711 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::Compound);
2713 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