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";
1748 Sema::ConditionResult
Cond;
1749 SourceLocation LParen;
1750 SourceLocation RParen;
1751 if (ParseParenExprOrCondition(
nullptr,
Cond, WhileLoc,
1774 MisleadingIndentationChecker MIChecker(*
this, MSK_while, WhileLoc);
1777 StmtResult Body(ParseStatement(TrailingElseLoc));
1779 if (Body.isUsable())
1785 if (
Cond.isInvalid() || Body.isInvalid())
1788 return Actions.ActOnWhileStmt(WhileLoc, LParen,
Cond, RParen, Body.get());
1792 assert(Tok.is(tok::kw_do) &&
"Not a do stmt!");
1826 if (Tok.isNot(tok::kw_while)) {
1827 if (!Body.isInvalid()) {
1828 Diag(Tok, diag::err_expected_while);
1829 Diag(DoLoc, diag::note_matching) <<
"'do'";
1836 if (Tok.isNot(tok::l_paren)) {
1837 Diag(Tok, diag::err_expected_lparen_after) <<
"do/while";
1847 DiagnoseAndSkipCXX11Attributes();
1849 SourceLocation Start = Tok.getLocation();
1851 if (!
Cond.isUsable()) {
1852 if (!Tok.isOneOf(tok::r_paren, tok::r_square, tok::r_brace))
1854 Cond = Actions.CreateRecoveryExpr(
1855 Start, Start == Tok.getLocation() ? Start : PrevTokLocation, {},
1856 Actions.getASTContext().BoolTy);
1861 if (
Cond.isInvalid() || Body.isInvalid())
1864 return Actions.ActOnDoStmt(DoLoc, Body.get(), WhileLoc, T.getOpenLocation(),
1865 Cond.get(), T.getCloseLocation());
1868bool Parser::isForRangeIdentifier() {
1869 assert(Tok.is(tok::identifier));
1872 if (
Next.is(tok::colon))
1875 if (
Next.isOneOf(tok::l_square, tok::kw_alignas)) {
1876 TentativeParsingAction PA(*
this);
1878 SkipCXX11Attributes();
1879 bool Result = Tok.is(tok::colon);
1889 assert(Tok.is(tok::kw_for) &&
"Not a for stmt!");
1892 SourceLocation CoawaitLoc;
1893 if (Tok.is(tok::kw_co_await))
1896 if (Tok.isNot(tok::l_paren)) {
1897 Diag(Tok, diag::err_expected_lparen_after) <<
"for";
1924 unsigned ScopeFlags =
1933 bool ForEach =
false;
1935 Sema::ConditionResult SecondPart;
1937 ForRangeInfo ForRangeInfo;
1940 if (Tok.is(tok::code_completion)) {
1942 Actions.CodeCompletion().CodeCompleteOrdinaryName(
1948 ParsedAttributes attrs(AttrFactory);
1949 MaybeParseCXX11Attributes(attrs);
1951 SourceLocation EmptyInitStmtSemiLoc;
1954 if (Tok.is(tok::semi)) {
1955 ProhibitAttributes(attrs);
1957 SourceLocation SemiLoc = Tok.getLocation();
1958 if (!Tok.hasLeadingEmptyMacro() && !SemiLoc.
isMacroID())
1959 EmptyInitStmtSemiLoc = SemiLoc;
1962 isForRangeIdentifier()) {
1963 ProhibitAttributes(attrs);
1964 IdentifierInfo *Name = Tok.getIdentifierInfo();
1966 MaybeParseCXX11Attributes(attrs);
1969 if (Tok.is(tok::l_brace))
1970 ForRangeInfo.RangeExpr = ParseBraceInitializer();
1974 Diag(Loc, diag::err_for_range_identifier)
1979 ForRangeInfo.LoopVar =
1980 Actions.ActOnCXXForRangeIdentifier(
getCurScope(), Loc, Name, attrs);
1981 }
else if (isForInitDeclaration()) {
1985 if (!C99orCXXorObjC) {
1986 Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
1987 Diag(Tok, diag::warn_gcc_variable_decl_in_for_loop);
1990 SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
1992 Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
1993 ProhibitAttributes(attrs);
1994 Decl *D = ParseStaticAssertDeclaration(DeclEnd);
1995 DG = Actions.ConvertDeclToDeclGroup(D);
1996 FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
1997 }
else if (Tok.is(tok::kw_using)) {
2000 FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
2005 ParsedAttributes DeclSpecAttrs(AttrFactory);
2006 DG = ParseSimpleDeclaration(
2008 MightBeForRangeStmt ? &ForRangeInfo :
nullptr);
2009 FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
2010 if (ForRangeInfo.ParsedForRangeDecl()) {
2012 ? diag::warn_cxx98_compat_for_range
2013 : diag::ext_for_range);
2014 ForRangeInfo.LoopVar = FirstPart;
2016 }
else if (Tok.is(tok::semi)) {
2018 }
else if ((ForEach = isTokIdentifier_in())) {
2019 Actions.ActOnForEachDeclStmt(DG);
2023 if (Tok.is(tok::code_completion)) {
2025 Actions.CodeCompletion().CodeCompleteObjCForCollection(
getCurScope(),
2031 Diag(Tok, diag::err_expected_semi_for);
2035 ProhibitAttributes(attrs);
2038 ForEach = isTokIdentifier_in();
2041 if (!
Value.isInvalid()) {
2043 FirstPart = Actions.ActOnForEachLValueExpr(
Value.get());
2050 bool IsRangeBasedFor =
2051 getLangOpts().CPlusPlus11 && !ForEach && Tok.is(tok::colon);
2052 FirstPart = Actions.ActOnExprStmt(
Value, !IsRangeBasedFor);
2056 if (Tok.is(tok::semi)) {
2058 }
else if (ForEach) {
2061 if (Tok.is(tok::code_completion)) {
2063 Actions.CodeCompletion().CodeCompleteObjCForCollection(
getCurScope(),
2071 Diag(Tok, diag::err_for_range_expected_decl)
2072 << FirstPart.get()->getSourceRange();
2076 if (!
Value.isInvalid()) {
2077 Diag(Tok, diag::err_expected_semi_for);
2081 if (Tok.is(tok::semi))
2088 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl() &&
2091 if (Tok.is(tok::semi)) {
2093 }
else if (Tok.is(tok::r_paren)) {
2099 bool MightBeForRangeStmt = !ForRangeInfo.ParsedForRangeDecl();
2101 SourceLocation SecondPartStart = Tok.getLocation();
2103 SecondPart = ParseCXXCondition(
2104 nullptr, ForLoc, CK,
2106 true, MightBeForRangeStmt ? &ForRangeInfo :
nullptr);
2108 if (ForRangeInfo.ParsedForRangeDecl()) {
2109 Diag(FirstPart.get() ? FirstPart.get()->getBeginLoc()
2110 : ForRangeInfo.ColonLoc,
2112 ? diag::warn_cxx17_compat_for_range_init_stmt
2113 : diag::ext_for_range_init_stmt)
2114 << (FirstPart.get() ? FirstPart.get()->getSourceRange()
2116 if (EmptyInitStmtSemiLoc.
isValid()) {
2117 Diag(EmptyInitStmtSemiLoc, diag::warn_empty_init_statement)
2124 ExprResult CondExpr = Actions.CreateRecoveryExpr(
2126 Tok.getLocation() == SecondPartStart ? SecondPartStart
2128 {}, Actions.PreferredConditionType(CK));
2130 SecondPart = Actions.ActOnCondition(
getCurScope(), ForLoc,
2140 SecondPart = Actions.ActOnCondition(
2148 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl()) {
2149 if (Tok.isNot(tok::semi)) {
2151 Diag(Tok, diag::err_expected_semi_for);
2155 if (Tok.is(tok::semi)) {
2159 if (Tok.isNot(tok::r_paren)) {
2163 ThirdPart = Actions.MakeFullDiscardedValueExpr(Third.
get());
2171 if (CoawaitLoc.
isValid() && !ForRangeInfo.ParsedForRangeDecl()) {
2172 Diag(CoawaitLoc, diag::err_for_co_await_not_range_for);
2173 CoawaitLoc = SourceLocation();
2177 Diag(CoawaitLoc, diag::warn_deprecated_for_co_await);
2185 if (ForRangeInfo.ParsedForRangeDecl()) {
2186 ForRangeStmt = Actions.ActOnCXXForRangeStmt(
2187 getCurScope(), ForLoc, CoawaitLoc, FirstPart.get(),
2188 ForRangeInfo.LoopVar.get(), ForRangeInfo.ColonLoc,
2190 ForRangeInfo.LifetimeExtendTemps);
2191 }
else if (ForEach) {
2194 ForEachStmt = Actions.ObjC().ActOnObjCForCollectionStmt(
2195 ForLoc, FirstPart.get(), Collection.
get(), T.getCloseLocation());
2199 if (
getLangOpts().OpenMP && FirstPart.isUsable()) {
2200 Actions.OpenMP().ActOnOpenMPLoopInitialization(ForLoc, FirstPart.get());
2207 if (ForRangeInfo.ParsedForRangeDecl())
2211 ForLoc, FirstPart.get(), SecondPart.
get().second, ThirdPart.get());
2229 Tok.is(tok::l_brace));
2238 MisleadingIndentationChecker MIChecker(*
this, MSK_for, ForLoc);
2241 StmtResult Body(ParseStatement(TrailingElseLoc));
2243 if (Body.isUsable())
2254 if (Body.isInvalid())
2258 return Actions.ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2261 if (ForRangeInfo.ParsedForRangeDecl())
2262 return Actions.FinishCXXForRangeStmt(ForRangeStmt.get(), Body.get());
2264 return Actions.ActOnForStmt(ForLoc, T.getOpenLocation(), FirstPart.get(),
2265 SecondPart, ThirdPart, T.getCloseLocation(),
2270 assert(Tok.is(tok::kw_goto) &&
"Not a goto stmt!");
2274 if (Tok.is(tok::identifier)) {
2275 LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(),
2277 Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(), LD);
2279 }
else if (Tok.is(tok::star)) {
2281 Diag(Tok, diag::ext_gnu_indirect_goto);
2284 if (
R.isInvalid()) {
2288 Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc,
R.get());
2290 Diag(Tok, diag::err_expected) << tok::identifier;
2297StmtResult Parser::ParseBreakOrContinueStatement(
bool IsContinue) {
2299 SourceLocation LabelLoc;
2300 LabelDecl *
Target =
nullptr;
2301 if (Tok.is(tok::identifier)) {
2303 Actions.LookupExistingLabel(Tok.getIdentifierInfo(), Tok.getLocation());
2308 Diag(LabelLoc, diag::err_c2y_labeled_break_continue) << IsContinue;
2310 Diag(LabelLoc, diag::err_break_continue_label_not_found) << IsContinue;
2321 return ParseBreakOrContinueStatement(
true);
2325 return ParseBreakOrContinueStatement(
false);
2329 assert((Tok.is(tok::kw_return) || Tok.is(tok::kw_co_return)) &&
2330 "Not a return stmt!");
2331 bool IsCoreturn = Tok.is(tok::kw_co_return);
2335 if (Tok.isNot(tok::semi)) {
2337 PreferredType.enterReturn(Actions, Tok.getLocation());
2339 if (Tok.is(tok::code_completion) && !IsCoreturn) {
2341 Actions.CodeCompletion().CodeCompleteExpression(
2342 getCurScope(), PreferredType.get(Tok.getLocation()));
2347 R = ParseInitializer();
2349 Diag(
R.get()->getBeginLoc(),
2351 ? diag::warn_cxx98_compat_generalized_initializer_lists
2352 : diag::ext_generalized_initializer_lists)
2353 <<
R.get()->getSourceRange();
2356 if (
R.isInvalid()) {
2362 return Actions.ActOnCoreturnStmt(
getCurScope(), ReturnLoc,
R.get());
2363 return Actions.ActOnReturnStmt(ReturnLoc,
R.get(),
getCurScope());
2367 assert(Tok.is(tok::kw__Defer));
2370 Actions.ActOnStartOfDeferStmt(DeferLoc,
getCurScope());
2372 llvm::scope_exit OnError([&] { Actions.ActOnDeferStmtError(
getCurScope()); });
2374 StmtResult Res = ParseStatement(TrailingElseLoc);
2375 if (!Res.isUsable())
2379 if (
auto *L = dyn_cast<LabelStmt>(Res.get())) {
2380 Diag(L->getIdentLoc(), diag::err_defer_ts_labeled_stmt);
2385 return Actions.ActOnEndOfDeferStmt(Res.get(),
getCurScope());
2388StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
2389 ParsedStmtContext StmtCtx,
2394 ParsedAttributes TempAttrs(AttrFactory);
2396 SourceLocation StartLoc = Tok.getLocation();
2399 while (Tok.is(tok::annot_pragma_loop_hint)) {
2401 if (!HandlePragmaLoopHint(Hint))
2407 AttributeScopeInfo(), ArgHints, 4,
2408 ParsedAttr::Form::Pragma());
2412 MaybeParseCXX11Attributes(Attrs);
2414 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2415 StmtResult S = ParseStatementOrDeclarationAfterAttributes(
2416 Stmts, StmtCtx, TrailingElseLoc, Attrs, EmptyDeclSpecAttrs,
2429Decl *Parser::ParseFunctionStatementBody(
Decl *
Decl, ParseScope &BodyScope) {
2430 assert(Tok.is(tok::l_brace));
2431 SourceLocation LBraceLoc = Tok.getLocation();
2433 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, LBraceLoc,
2434 "parsing function body");
2439 Sema::PragmaStackSentinelRAII
2440 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2445 StmtResult FnBody(ParseCompoundStatementBody());
2448 if (FnBody.isInvalid()) {
2449 Sema::CompoundScopeRAII CompoundScope(Actions);
2450 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, {},
false);
2454 return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
2457Decl *Parser::ParseFunctionTryBlock(
Decl *
Decl, ParseScope &BodyScope) {
2458 assert(Tok.is(tok::kw_try) &&
"Expected 'try'");
2461 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, TryLoc,
2462 "parsing function try block");
2465 if (Tok.is(tok::colon))
2466 ParseConstructorInitializer(Decl);
2468 Actions.ActOnDefaultCtorInitializers(Decl);
2473 Sema::PragmaStackSentinelRAII
2474 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2476 SourceLocation LBraceLoc = Tok.getLocation();
2477 StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc,
true));
2480 if (FnBody.isInvalid()) {
2481 Sema::CompoundScopeRAII CompoundScope(Actions);
2482 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, {},
false);
2486 return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
2489bool Parser::trySkippingFunctionBody() {
2490 assert(SkipFunctionBodies &&
2491 "Should only be called when SkipFunctionBodies is enabled");
2492 if (!PP.isCodeCompletionEnabled()) {
2499 TentativeParsingAction PA(*
this);
2500 bool IsTryCatch = Tok.is(tok::kw_try);
2502 bool ErrorInPrologue = ConsumeAndStoreFunctionPrologue(Toks);
2503 if (llvm::any_of(Toks, [](
const Token &Tok) {
2504 return Tok.is(tok::code_completion);
2509 if (ErrorInPrologue) {
2518 while (IsTryCatch && Tok.is(tok::kw_catch)) {
2530 assert(Tok.is(tok::kw_try) &&
"Expected 'try'");
2533 return ParseCXXTryBlockCommon(TryLoc);
2537 if (Tok.isNot(tok::l_brace))
2538 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2544 if (TryBlock.isInvalid())
2549 if ((Tok.is(tok::identifier) &&
2550 Tok.getIdentifierInfo() == getSEHExceptKeyword()) ||
2551 Tok.is(tok::kw___finally)) {
2554 if(Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
2556 Handler = ParseSEHExceptBlock(Loc);
2560 Handler = ParseSEHFinallyBlock(Loc);
2562 if(Handler.isInvalid())
2565 return Actions.ActOnSEHTryBlock(
true ,
2575 DiagnoseAndSkipCXX11Attributes();
2577 if (Tok.isNot(tok::kw_catch))
2579 while (Tok.is(tok::kw_catch)) {
2580 StmtResult Handler(ParseCXXCatchBlock(FnTry));
2581 if (!Handler.isInvalid())
2582 Handlers.push_back(Handler.get());
2586 if (Handlers.empty())
2589 return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.get(), Handlers);
2593StmtResult Parser::ParseCXXCatchBlock(
bool FnCatch) {
2594 assert(Tok.is(tok::kw_catch) &&
"Expected 'catch'");
2599 if (T.expectAndConsume())
2611 Decl *ExceptionDecl =
nullptr;
2612 if (Tok.isNot(tok::ellipsis)) {
2613 ParsedAttributes Attributes(AttrFactory);
2614 MaybeParseCXX11Attributes(Attributes);
2616 DeclSpec DS(AttrFactory);
2618 if (ParseCXXTypeSpecifierSeq(DS))
2622 ParseDeclarator(ExDecl);
2623 ExceptionDecl = Actions.ActOnExceptionDeclarator(
getCurScope(), ExDecl);
2628 if (T.getCloseLocation().isInvalid())
2631 if (Tok.isNot(tok::l_brace))
2632 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2636 if (
Block.isInvalid())
2639 return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl,
Block.get());
2642void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
2643 IfExistsCondition
Result;
2644 if (ParseMicrosoftIfExistsCondition(
Result))
2652 if (!Tok.is(tok::l_brace)) {
2653 Diag(Tok, diag::err_expected) << tok::l_brace;
2657 StmtResult Compound = ParseCompoundStatement();
2658 if (Compound.isInvalid())
2661 StmtResult DepResult = Actions.ActOnMSDependentExistsStmt(
Result.KeywordLoc,
2666 if (DepResult.isUsable())
2667 Stmts.push_back(DepResult.get());
2672 if (
Braces.consumeOpen()) {
2673 Diag(Tok, diag::err_expected) << tok::l_brace;
2677 switch (
Result.Behavior) {
2683 llvm_unreachable(
"Dependent case handled above");
2691 while (Tok.isNot(tok::r_brace)) {
2693 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::Compound);
2695 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