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)) {
1709 StmtResult Body(ParseStatement(TrailingElseLoc));
1715 return Actions.ActOnFinishSwitchStmt(SwitchLoc,
Switch.get(), Body.get());
1720 assert(Tok.is(tok::kw_while) &&
"Not a while stmt!");
1721 SourceLocation WhileLoc = Tok.getLocation();
1724 if (Tok.isNot(tok::l_paren)) {
1725 Diag(Tok, diag::err_expected_lparen_after) <<
"while";
1744 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!");
1827 if (Tok.isNot(tok::kw_while)) {
1828 if (!Body.isInvalid()) {
1829 Diag(Tok, diag::err_expected_while);
1830 Diag(DoLoc, diag::note_matching) <<
"'do'";
1837 if (Tok.isNot(tok::l_paren)) {
1838 Diag(Tok, diag::err_expected_lparen_after) <<
"do/while";
1848 DiagnoseAndSkipCXX11Attributes();
1850 SourceLocation Start = Tok.getLocation();
1852 if (!
Cond.isUsable()) {
1853 if (!Tok.isOneOf(tok::r_paren, tok::r_square, tok::r_brace))
1855 Cond = Actions.CreateRecoveryExpr(
1856 Start, Start == Tok.getLocation() ? Start : PrevTokLocation, {},
1857 Actions.getASTContext().BoolTy);
1862 if (
Cond.isInvalid() || Body.isInvalid())
1865 return Actions.ActOnDoStmt(DoLoc, Body.get(), WhileLoc, T.getOpenLocation(),
1866 Cond.get(), T.getCloseLocation());
1869bool Parser::isForRangeIdentifier() {
1870 assert(Tok.is(tok::identifier));
1873 if (
Next.is(tok::colon))
1876 if (
Next.isOneOf(tok::l_square, tok::kw_alignas)) {
1877 TentativeParsingAction PA(*
this);
1879 SkipCXX11Attributes();
1880 bool Result = Tok.is(tok::colon);
1890 assert(Tok.is(tok::kw_for) &&
"Not a for stmt!");
1893 SourceLocation CoawaitLoc;
1894 if (Tok.is(tok::kw_co_await))
1897 if (Tok.isNot(tok::l_paren)) {
1898 Diag(Tok, diag::err_expected_lparen_after) <<
"for";
1925 unsigned ScopeFlags =
1934 bool ForEach =
false;
1936 Sema::ConditionResult SecondPart;
1938 ForRangeInfo ForRangeInfo;
1941 if (Tok.is(tok::code_completion)) {
1943 Actions.CodeCompletion().CodeCompleteOrdinaryName(
1949 ParsedAttributes attrs(AttrFactory);
1950 MaybeParseCXX11Attributes(attrs);
1952 SourceLocation EmptyInitStmtSemiLoc;
1955 if (Tok.is(tok::semi)) {
1956 ProhibitAttributes(attrs);
1958 SourceLocation SemiLoc = Tok.getLocation();
1959 if (!Tok.hasLeadingEmptyMacro() && !SemiLoc.
isMacroID())
1960 EmptyInitStmtSemiLoc = SemiLoc;
1963 isForRangeIdentifier()) {
1964 ProhibitAttributes(attrs);
1965 IdentifierInfo *Name = Tok.getIdentifierInfo();
1967 MaybeParseCXX11Attributes(attrs);
1970 if (Tok.is(tok::l_brace))
1971 ForRangeInfo.RangeExpr = ParseBraceInitializer();
1975 Diag(Loc, diag::err_for_range_identifier)
1980 ForRangeInfo.LoopVar =
1981 Actions.ActOnCXXForRangeIdentifier(
getCurScope(), Loc, Name, attrs);
1982 }
else if (isForInitDeclaration()) {
1986 if (!C99orCXXorObjC) {
1987 Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
1988 Diag(Tok, diag::warn_gcc_variable_decl_in_for_loop);
1991 SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
1993 Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
1994 ProhibitAttributes(attrs);
1995 Decl *D = ParseStaticAssertDeclaration(DeclEnd);
1996 DG = Actions.ConvertDeclToDeclGroup(D);
1997 FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
1998 }
else if (Tok.is(tok::kw_using)) {
2001 FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
2006 ParsedAttributes DeclSpecAttrs(AttrFactory);
2007 DG = ParseSimpleDeclaration(
2009 MightBeForRangeStmt ? &ForRangeInfo :
nullptr);
2010 FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
2011 if (ForRangeInfo.ParsedForRangeDecl()) {
2013 ? diag::warn_cxx98_compat_for_range
2014 : diag::ext_for_range);
2015 ForRangeInfo.LoopVar = FirstPart;
2017 }
else if (Tok.is(tok::semi)) {
2019 }
else if ((ForEach = isTokIdentifier_in())) {
2020 Actions.ActOnForEachDeclStmt(DG);
2024 if (Tok.is(tok::code_completion)) {
2026 Actions.CodeCompletion().CodeCompleteObjCForCollection(
getCurScope(),
2032 Diag(Tok, diag::err_expected_semi_for);
2036 ProhibitAttributes(attrs);
2039 ForEach = isTokIdentifier_in();
2042 if (!
Value.isInvalid()) {
2044 FirstPart = Actions.ActOnForEachLValueExpr(
Value.get());
2051 bool IsRangeBasedFor =
2052 getLangOpts().CPlusPlus11 && !ForEach && Tok.is(tok::colon);
2053 FirstPart = Actions.ActOnExprStmt(
Value, !IsRangeBasedFor);
2057 if (Tok.is(tok::semi)) {
2059 }
else if (ForEach) {
2062 if (Tok.is(tok::code_completion)) {
2064 Actions.CodeCompletion().CodeCompleteObjCForCollection(
getCurScope(),
2072 Diag(Tok, diag::err_for_range_expected_decl)
2073 << FirstPart.get()->getSourceRange();
2077 if (!
Value.isInvalid()) {
2078 Diag(Tok, diag::err_expected_semi_for);
2082 if (Tok.is(tok::semi))
2089 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl() &&
2092 if (Tok.is(tok::semi)) {
2094 }
else if (Tok.is(tok::r_paren)) {
2100 bool MightBeForRangeStmt = !ForRangeInfo.ParsedForRangeDecl();
2102 SourceLocation SecondPartStart = Tok.getLocation();
2104 SecondPart = ParseCXXCondition(
2105 nullptr, ForLoc, CK,
2107 true, MightBeForRangeStmt ? &ForRangeInfo :
nullptr);
2109 if (ForRangeInfo.ParsedForRangeDecl()) {
2110 Diag(FirstPart.get() ? FirstPart.get()->getBeginLoc()
2111 : ForRangeInfo.ColonLoc,
2113 ? diag::warn_cxx17_compat_for_range_init_stmt
2114 : diag::ext_for_range_init_stmt)
2115 << (FirstPart.get() ? FirstPart.get()->getSourceRange()
2117 if (EmptyInitStmtSemiLoc.
isValid()) {
2118 Diag(EmptyInitStmtSemiLoc, diag::warn_empty_init_statement)
2125 ExprResult CondExpr = Actions.CreateRecoveryExpr(
2127 Tok.getLocation() == SecondPartStart ? SecondPartStart
2129 {}, Actions.PreferredConditionType(CK));
2131 SecondPart = Actions.ActOnCondition(
getCurScope(), ForLoc,
2141 SecondPart = Actions.ActOnCondition(
2149 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl()) {
2150 if (Tok.isNot(tok::semi)) {
2152 Diag(Tok, diag::err_expected_semi_for);
2156 if (Tok.is(tok::semi)) {
2160 if (Tok.isNot(tok::r_paren)) {
2164 ThirdPart = Actions.MakeFullDiscardedValueExpr(Third.
get());
2172 if (CoawaitLoc.
isValid() && !ForRangeInfo.ParsedForRangeDecl()) {
2173 Diag(CoawaitLoc, diag::err_for_co_await_not_range_for);
2174 CoawaitLoc = SourceLocation();
2178 Diag(CoawaitLoc, diag::warn_deprecated_for_co_await);
2186 if (ForRangeInfo.ParsedForRangeDecl()) {
2187 ForRangeStmt = Actions.ActOnCXXForRangeStmt(
2188 getCurScope(), ForLoc, CoawaitLoc, FirstPart.get(),
2189 ForRangeInfo.LoopVar.get(), ForRangeInfo.ColonLoc,
2191 ForRangeInfo.LifetimeExtendTemps);
2192 }
else if (ForEach) {
2195 ForEachStmt = Actions.ObjC().ActOnObjCForCollectionStmt(
2196 ForLoc, FirstPart.get(), Collection.
get(), T.getCloseLocation());
2200 if (
getLangOpts().OpenMP && FirstPart.isUsable()) {
2201 Actions.OpenMP().ActOnOpenMPLoopInitialization(ForLoc, FirstPart.get());
2208 if (ForRangeInfo.ParsedForRangeDecl())
2212 ForLoc, FirstPart.get(), SecondPart.
get().second, ThirdPart.get());
2230 Tok.is(tok::l_brace));
2239 MisleadingIndentationChecker MIChecker(*
this, MSK_for, ForLoc);
2242 StmtResult Body(ParseStatement(TrailingElseLoc));
2244 if (Body.isUsable())
2255 if (Body.isInvalid())
2259 return Actions.ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2262 if (ForRangeInfo.ParsedForRangeDecl())
2263 return Actions.FinishCXXForRangeStmt(ForRangeStmt.get(), Body.get());
2265 return Actions.ActOnForStmt(ForLoc, T.getOpenLocation(), FirstPart.get(),
2266 SecondPart, ThirdPart, T.getCloseLocation(),
2271 assert(Tok.is(tok::kw_goto) &&
"Not a goto stmt!");
2275 if (Tok.is(tok::identifier)) {
2276 LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(),
2278 Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(), LD);
2280 }
else if (Tok.is(tok::star)) {
2282 Diag(Tok, diag::ext_gnu_indirect_goto);
2285 if (
R.isInvalid()) {
2289 Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc,
R.get());
2291 Diag(Tok, diag::err_expected) << tok::identifier;
2298StmtResult Parser::ParseBreakOrContinueStatement(
bool IsContinue) {
2300 SourceLocation LabelLoc;
2301 LabelDecl *
Target =
nullptr;
2302 if (Tok.is(tok::identifier)) {
2304 Actions.LookupExistingLabel(Tok.getIdentifierInfo(), Tok.getLocation());
2309 Diag(LabelLoc, diag::err_c2y_labeled_break_continue) << IsContinue;
2311 Diag(LabelLoc, diag::err_break_continue_label_not_found) << IsContinue;
2322 return ParseBreakOrContinueStatement(
true);
2326 return ParseBreakOrContinueStatement(
false);
2330 assert((Tok.is(tok::kw_return) || Tok.is(tok::kw_co_return)) &&
2331 "Not a return stmt!");
2332 bool IsCoreturn = Tok.is(tok::kw_co_return);
2336 if (Tok.isNot(tok::semi)) {
2338 PreferredType.enterReturn(Actions, Tok.getLocation());
2340 if (Tok.is(tok::code_completion) && !IsCoreturn) {
2342 Actions.CodeCompletion().CodeCompleteExpression(
2343 getCurScope(), PreferredType.get(Tok.getLocation()));
2348 R = ParseInitializer();
2350 Diag(
R.get()->getBeginLoc(),
2352 ? diag::warn_cxx98_compat_generalized_initializer_lists
2353 : diag::ext_generalized_initializer_lists)
2354 <<
R.get()->getSourceRange();
2357 if (
R.isInvalid()) {
2363 return Actions.ActOnCoreturnStmt(
getCurScope(), ReturnLoc,
R.get());
2364 return Actions.ActOnReturnStmt(ReturnLoc,
R.get(),
getCurScope());
2368 assert(Tok.is(tok::kw__Defer));
2371 Actions.ActOnStartOfDeferStmt(DeferLoc,
getCurScope());
2373 llvm::scope_exit OnError([&] { Actions.ActOnDeferStmtError(
getCurScope()); });
2375 StmtResult Res = ParseStatement(TrailingElseLoc);
2376 if (!Res.isUsable())
2380 if (
auto *L = dyn_cast<LabelStmt>(Res.get())) {
2381 Diag(L->getIdentLoc(), diag::err_defer_ts_labeled_stmt);
2386 return Actions.ActOnEndOfDeferStmt(Res.get(),
getCurScope());
2389StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
2390 ParsedStmtContext StmtCtx,
2395 ParsedAttributes TempAttrs(AttrFactory);
2397 SourceLocation StartLoc = Tok.getLocation();
2400 while (Tok.is(tok::annot_pragma_loop_hint)) {
2402 if (!HandlePragmaLoopHint(Hint))
2408 AttributeScopeInfo(), ArgHints, 4,
2409 ParsedAttr::Form::Pragma());
2413 MaybeParseCXX11Attributes(Attrs);
2415 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2416 StmtResult S = ParseStatementOrDeclarationAfterAttributes(
2417 Stmts, StmtCtx, TrailingElseLoc, Attrs, EmptyDeclSpecAttrs,
2430Decl *Parser::ParseFunctionStatementBody(
Decl *
Decl, ParseScope &BodyScope) {
2431 assert(Tok.is(tok::l_brace));
2432 SourceLocation LBraceLoc = Tok.getLocation();
2434 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, LBraceLoc,
2435 "parsing function body");
2440 Sema::PragmaStackSentinelRAII
2441 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2446 StmtResult FnBody(ParseCompoundStatementBody());
2449 if (FnBody.isInvalid()) {
2450 Sema::CompoundScopeRAII CompoundScope(Actions);
2451 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, {},
false);
2455 return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
2458Decl *Parser::ParseFunctionTryBlock(
Decl *
Decl, ParseScope &BodyScope) {
2459 assert(Tok.is(tok::kw_try) &&
"Expected 'try'");
2462 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, TryLoc,
2463 "parsing function try block");
2466 if (Tok.is(tok::colon))
2467 ParseConstructorInitializer(Decl);
2469 Actions.ActOnDefaultCtorInitializers(Decl);
2474 Sema::PragmaStackSentinelRAII
2475 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2477 SourceLocation LBraceLoc = Tok.getLocation();
2478 StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc,
true));
2481 if (FnBody.isInvalid()) {
2482 Sema::CompoundScopeRAII CompoundScope(Actions);
2483 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, {},
false);
2487 return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
2490bool Parser::trySkippingFunctionBody() {
2491 assert(SkipFunctionBodies &&
2492 "Should only be called when SkipFunctionBodies is enabled");
2493 if (!PP.isCodeCompletionEnabled()) {
2500 TentativeParsingAction PA(*
this);
2501 bool IsTryCatch = Tok.is(tok::kw_try);
2503 bool ErrorInPrologue = ConsumeAndStoreFunctionPrologue(Toks);
2504 if (llvm::any_of(Toks, [](
const Token &Tok) {
2505 return Tok.is(tok::code_completion);
2510 if (ErrorInPrologue) {
2519 while (IsTryCatch && Tok.is(tok::kw_catch)) {
2531 assert(Tok.is(tok::kw_try) &&
"Expected 'try'");
2534 return ParseCXXTryBlockCommon(TryLoc);
2538 if (Tok.isNot(tok::l_brace))
2539 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2545 if (TryBlock.isInvalid())
2550 if ((Tok.is(tok::identifier) &&
2551 Tok.getIdentifierInfo() == getSEHExceptKeyword()) ||
2552 Tok.is(tok::kw___finally)) {
2555 if(Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
2557 Handler = ParseSEHExceptBlock(Loc);
2561 Handler = ParseSEHFinallyBlock(Loc);
2563 if(Handler.isInvalid())
2566 return Actions.ActOnSEHTryBlock(
true ,
2576 DiagnoseAndSkipCXX11Attributes();
2578 if (Tok.isNot(tok::kw_catch))
2580 while (Tok.is(tok::kw_catch)) {
2581 StmtResult Handler(ParseCXXCatchBlock(FnTry));
2582 if (!Handler.isInvalid())
2583 Handlers.push_back(Handler.get());
2587 if (Handlers.empty())
2590 return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.get(), Handlers);
2594StmtResult Parser::ParseCXXCatchBlock(
bool FnCatch) {
2595 assert(Tok.is(tok::kw_catch) &&
"Expected 'catch'");
2600 if (T.expectAndConsume())
2612 Decl *ExceptionDecl =
nullptr;
2613 if (Tok.isNot(tok::ellipsis)) {
2614 ParsedAttributes Attributes(AttrFactory);
2615 MaybeParseCXX11Attributes(Attributes);
2617 DeclSpec DS(AttrFactory);
2619 if (ParseCXXTypeSpecifierSeq(DS))
2623 ParseDeclarator(ExDecl);
2624 ExceptionDecl = Actions.ActOnExceptionDeclarator(
getCurScope(), ExDecl);
2629 if (T.getCloseLocation().isInvalid())
2632 if (Tok.isNot(tok::l_brace))
2633 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2637 if (
Block.isInvalid())
2640 return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl,
Block.get());
2643void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
2644 IfExistsCondition
Result;
2645 if (ParseMicrosoftIfExistsCondition(
Result))
2653 if (!Tok.is(tok::l_brace)) {
2654 Diag(Tok, diag::err_expected) << tok::l_brace;
2658 StmtResult Compound = ParseCompoundStatement();
2659 if (Compound.isInvalid())
2662 StmtResult DepResult = Actions.ActOnMSDependentExistsStmt(
Result.KeywordLoc,
2667 if (DepResult.isUsable())
2668 Stmts.push_back(DepResult.get());
2673 if (
Braces.consumeOpen()) {
2674 Diag(Tok, diag::err_expected) << tok::l_brace;
2678 switch (
Result.Behavior) {
2684 llvm_unreachable(
"Dependent case handled above");
2692 while (Tok.isNot(tok::r_brace)) {
2694 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::Compound);
2696 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 EnterSwitchBody(LabelDecl *PrecedingLabel)
Mark that we're entering the body of a switch statement.
void LeaveLoopBody()
Mark that we're leaving the body of a loop; this is only needed for do loops where the condition foll...
void decrementMSManglingNumber()
void EnterLoopBody(LabelDecl *PrecedingLabel)
Mark that we're entering the body of a loop (for, while, do).
@ SEHTryScope
This scope corresponds to an SEH try.
@ ControlScope
The controlling scope in a if/switch/while/for statement.
@ SEHFilterScope
We are currently in the filter expression of an SEH except block.
@ SwitchScope
This is a scope that corresponds to a switch statement.
@ CatchScope
This is the scope of a C++ catch statement.
@ CompoundStmtScope
This is a compound statement scope.
@ FnTryCatchScope
This is the scope for a function-level C++ try or catch scope.
@ SEHExceptScope
This scope corresponds to an SEH except.
@ TryScope
This is the scope of a C++ try statement.
@ DeclScope
This is a scope that can contain a declaration.
@ PCC_ForInit
Code completion occurs at the beginning of the initialization statement (or expression) in a for loop...
@ PCC_Expression
Code completion occurs within an expression.
@ PCC_Statement
Code completion occurs within a statement, which may also be an expression or a declaration.
void ActOnWhileStmt(SourceLocation WhileLoc)
void ActOnDoStmt(SourceLocation DoLoc)
void ActOnRangeForStmtBegin(SourceLocation ForLoc, const Stmt *OldRangeFor, const Stmt *RangeFor)
void ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body)
void ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *First, const Stmt *Second, const Stmt *Third)
std::pair< VarDecl *, Expr * > get() const
@ Boolean
A boolean condition, from 'if', 'while', 'for', or 'do'.
@ Switch
An integral condition for a 'switch' statement.
@ ConstexprIf
A constant boolean condition from 'if constexpr'.
DiagnosticsEngine & getDiagnostics() const
ExpressionEvaluationContext
Describes how the expressions currently being parsed are evaluated at run-time, if at all.
@ DiscardedStatement
The current expression occurs within a discarded statement.
@ 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.
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.
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