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();
513 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt, SemiError);
521StmtResult Parser::ParseExprStatement(ParsedStmtContext StmtCtx) {
523 Token OldToken = Tok;
525 ExprStatementTokLoc = Tok.getLocation();
529 if (Expr.isInvalid()) {
534 if (Tok.is(tok::semi))
536 return Actions.ActOnExprStmtError();
539 if (Tok.is(tok::colon) &&
getCurScope()->isSwitchScope() &&
540 Actions.CheckCaseExpression(Expr.get())) {
543 Diag(OldToken, diag::err_expected_case_before_expression)
547 return ParseCaseStatement(StmtCtx,
true, Expr);
550 Token *CurTok =
nullptr;
553 if (Tok.is(tok::annot_repl_input_end))
557 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
560 if (CurTok && !R.isInvalid())
567 assert(Tok.is(tok::kw___try) &&
"Expected '__try'");
570 if (Tok.isNot(tok::l_brace))
571 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
576 if (TryBlock.isInvalid())
580 if (Tok.is(tok::identifier) &&
581 Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
583 Handler = ParseSEHExceptBlock(Loc);
584 }
else if (Tok.is(tok::kw___finally)) {
586 Handler = ParseSEHFinallyBlock(Loc);
591 if(Handler.isInvalid())
594 return Actions.ActOnSEHTryBlock(
false ,
601 PoisonIdentifierRAIIObject raii(Ident__exception_code,
false),
602 raii2(Ident___exception_code,
false),
603 raii3(Ident_GetExceptionCode,
false);
605 if (ExpectAndConsume(tok::l_paren))
612 Ident__exception_info->setIsPoisoned(
false);
613 Ident___exception_info->setIsPoisoned(
false);
614 Ident_GetExceptionInfo->setIsPoisoned(
false);
619 ParseScopeFlags FilterScope(
this,
getCurScope()->getFlags() |
625 Ident__exception_info->setIsPoisoned(
true);
626 Ident___exception_info->setIsPoisoned(
true);
627 Ident_GetExceptionInfo->setIsPoisoned(
true);
633 if (ExpectAndConsume(tok::r_paren))
636 if (Tok.isNot(tok::l_brace))
637 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
641 if(
Block.isInvalid())
644 return Actions.ActOnSEHExceptBlock(ExceptLoc, FilterExpr.
get(),
Block.get());
648 PoisonIdentifierRAIIObject raii(Ident__abnormal_termination,
false),
649 raii2(Ident___abnormal_termination,
false),
650 raii3(Ident_AbnormalTermination,
false);
652 if (Tok.isNot(tok::l_brace))
653 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
656 Actions.ActOnStartSEHFinallyBlock();
659 if(
Block.isInvalid()) {
660 Actions.ActOnAbortSEHFinallyBlock();
664 return Actions.ActOnFinishSEHFinallyBlock(FinallyLoc,
Block.get());
674 return Actions.ActOnSEHLeaveStmt(LeaveLoc,
getCurScope());
684 ? diag::warn_c23_compat_label_followed_by_declaration
685 : diag::ext_c_label_followed_by_declaration);
690 ParsedStmtContext StmtCtx) {
691 assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
692 "Not an identifier!");
697 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
699 Token IdentTok = Tok;
702 assert(Tok.is(tok::colon) &&
"Not a label!");
712 if (Tok.is(tok::kw___attribute)) {
713 ParsedAttributes TempAttrs(AttrFactory);
714 ParseGNUAttributes(TempAttrs);
727 ParsedAttributes EmptyCXX11Attrs(AttrFactory);
728 SubStmt = ParseStatementOrDeclarationAfterAttributes(
729 Stmts, StmtCtx,
nullptr, EmptyCXX11Attrs,
731 if (!TempAttrs.empty() && !SubStmt.isInvalid())
732 SubStmt = Actions.ActOnAttributedStmt(TempAttrs, SubStmt.get());
737 if (SubStmt.isUnset() && Tok.is(tok::r_brace)) {
738 DiagnoseLabelAtEndOfCompoundStatement();
739 SubStmt = Actions.ActOnNullStmt(ColonLoc);
743 if (SubStmt.isUnset())
744 SubStmt = ParseStatement(
nullptr, StmtCtx, LD);
747 if (SubStmt.isInvalid())
748 SubStmt = Actions.ActOnNullStmt(ColonLoc);
752 Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
755 return Actions.ActOnLabelStmt(IdentTok.
getLocation(), LD, ColonLoc,
759StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx,
761 assert((MissingCase || Tok.is(tok::kw_case)) &&
"Not a case stmt!");
766 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
789 Stmt *DeepestParsedCaseStmt =
nullptr;
792 SourceLocation ColonLoc;
794 SourceLocation CaseLoc = MissingCase ? Expr.
get()->
getExprLoc() :
796 ColonLoc = SourceLocation();
798 if (Tok.is(tok::code_completion)) {
800 Actions.CodeCompletion().CodeCompleteCase(
getCurScope());
819 LHS = Actions.ActOnCaseExpr(CaseLoc, Expr);
824 SourceLocation DotDotDotLoc;
830 DiagId = diag::ext_gnu_case_range;
832 DiagId = diag::warn_c23_compat_case_range;
834 DiagId = diag::ext_c2y_case_range;
835 Diag(DotDotDotLoc, DiagId);
843 ColonProtection.restore();
849 Diag(ColonLoc, diag::err_expected_after)
850 <<
"'case'" << tok::colon
855 Diag(ExpectedLoc, diag::err_expected_after)
856 <<
"'case'" << tok::colon
859 ColonLoc = ExpectedLoc;
863 Actions.ActOnCaseStmt(CaseLoc, LHS, DotDotDotLoc, RHS, ColonLoc);
867 if (Case.isInvalid()) {
868 if (TopLevelCase.isInvalid())
869 return ParseStatement(
nullptr, StmtCtx);
874 Stmt *NextDeepest = Case.get();
875 if (TopLevelCase.isInvalid())
878 Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, Case.get());
879 DeepestParsedCaseStmt = NextDeepest;
883 }
while (Tok.is(tok::kw_case));
888 if (Tok.is(tok::r_brace)) {
891 DiagnoseLabelAtEndOfCompoundStatement();
892 SubStmt = Actions.ActOnNullStmt(ColonLoc);
894 SubStmt = ParseStatement(
nullptr, StmtCtx);
898 if (DeepestParsedCaseStmt) {
900 if (SubStmt.isInvalid())
901 SubStmt = Actions.ActOnNullStmt(SourceLocation());
903 Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, SubStmt.get());
910StmtResult Parser::ParseDefaultStatement(ParsedStmtContext StmtCtx) {
911 assert(Tok.is(tok::kw_default) &&
"Not a default stmt!");
916 StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;
920 SourceLocation ColonLoc;
924 Diag(ColonLoc, diag::err_expected_after)
925 <<
"'default'" << tok::colon
928 SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation);
929 Diag(ExpectedLoc, diag::err_expected_after)
930 <<
"'default'" << tok::colon
932 ColonLoc = ExpectedLoc;
937 if (Tok.is(tok::r_brace)) {
940 DiagnoseLabelAtEndOfCompoundStatement();
941 SubStmt = Actions.ActOnNullStmt(ColonLoc);
943 SubStmt = ParseStatement(
nullptr, StmtCtx);
947 if (SubStmt.isInvalid())
948 SubStmt = Actions.ActOnNullStmt(ColonLoc);
951 return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc,
955StmtResult Parser::ParseCompoundStatement(
bool isStmtExpr) {
956 return ParseCompoundStatement(isStmtExpr,
960StmtResult Parser::ParseCompoundStatement(
bool isStmtExpr,
961 unsigned ScopeFlags) {
962 assert(Tok.is(tok::l_brace) &&
"Not a compound stmt!");
970 StackHandler.runWithSufficientStackSpace(Tok.getLocation(), [&,
this]() {
971 R = ParseCompoundStatementBody(isStmtExpr);
976void Parser::ParseCompoundStatementLeadingPragmas() {
977 bool checkForPragmas =
true;
978 while (checkForPragmas) {
979 switch (Tok.getKind()) {
980 case tok::annot_pragma_vis:
981 HandlePragmaVisibility();
983 case tok::annot_pragma_pack:
986 case tok::annot_pragma_msstruct:
987 HandlePragmaMSStruct();
989 case tok::annot_pragma_align:
992 case tok::annot_pragma_weak:
995 case tok::annot_pragma_weakalias:
996 HandlePragmaWeakAlias();
998 case tok::annot_pragma_redefine_extname:
999 HandlePragmaRedefineExtname();
1001 case tok::annot_pragma_opencl_extension:
1002 HandlePragmaOpenCLExtension();
1004 case tok::annot_pragma_fp_contract:
1005 HandlePragmaFPContract();
1007 case tok::annot_pragma_fp:
1010 case tok::annot_pragma_fenv_access:
1011 case tok::annot_pragma_fenv_access_ms:
1012 HandlePragmaFEnvAccess();
1014 case tok::annot_pragma_fenv_round:
1015 HandlePragmaFEnvRound();
1017 case tok::annot_pragma_cx_limited_range:
1018 HandlePragmaCXLimitedRange();
1020 case tok::annot_pragma_float_control:
1021 HandlePragmaFloatControl();
1023 case tok::annot_pragma_ms_pointers_to_members:
1024 HandlePragmaMSPointersToMembers();
1026 case tok::annot_pragma_ms_pragma:
1027 HandlePragmaMSPragma();
1029 case tok::annot_pragma_ms_vtordisp:
1030 HandlePragmaMSVtorDisp();
1032 case tok::annot_pragma_dump:
1036 checkForPragmas =
false;
1043void Parser::DiagnoseLabelAtEndOfCompoundStatement() {
1046 ? diag::warn_cxx20_compat_label_end_of_compound_statement
1047 : diag::ext_cxx_label_end_of_compound_statement);
1050 ? diag::warn_c23_compat_label_end_of_compound_statement
1051 : diag::ext_c_label_end_of_compound_statement);
1055bool Parser::ConsumeNullStmt(StmtVector &Stmts) {
1056 if (!Tok.is(tok::semi))
1059 SourceLocation StartLoc = Tok.getLocation();
1060 SourceLocation EndLoc;
1062 while (Tok.is(tok::semi) && !Tok.hasLeadingEmptyMacro() &&
1063 Tok.getLocation().isValid() && !Tok.getLocation().isMacroID()) {
1064 EndLoc = Tok.getLocation();
1068 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::SubStmt);
1070 Stmts.push_back(R.get());
1077 Diag(StartLoc, diag::warn_null_statement)
1083 bool IsStmtExprResult =
false;
1084 if ((StmtCtx & ParsedStmtContext::InStmtExpr) != ParsedStmtContext()) {
1088 IsStmtExprResult = Tok.is(tok::r_brace) &&
NextToken().
is(tok::r_paren);
1091 if (IsStmtExprResult)
1092 E = Actions.ActOnStmtExprResult(E);
1093 return Actions.ActOnExprStmt(E, !IsStmtExprResult);
1096StmtResult Parser::ParseCompoundStatementBody(
bool isStmtExpr) {
1097 PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),
1099 "in compound statement ('{}')");
1103 Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);
1107 if (
T.consumeOpen())
1110 Sema::CompoundScopeRAII CompoundScope(Actions, isStmtExpr);
1113 ParseCompoundStatementLeadingPragmas();
1114 Actions.ActOnAfterCompoundStatementLeadingPragmas();
1120 while (Tok.is(tok::kw___label__)) {
1123 SmallVector<Decl *, 4> DeclsInGroup;
1125 if (Tok.isNot(tok::identifier)) {
1126 Diag(Tok, diag::err_expected) << tok::identifier;
1130 IdentifierInfo *II = Tok.getIdentifierInfo();
1132 DeclsInGroup.push_back(Actions.LookupOrCreateLabel(II, IdLoc, LabelLoc));
1138 DeclSpec DS(AttrFactory);
1140 Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, DeclsInGroup);
1141 StmtResult R = Actions.ActOnDeclStmt(Res, LabelLoc, Tok.getLocation());
1143 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
1145 Stmts.push_back(R.get());
1148 ParsedStmtContext SubStmtCtx =
1149 ParsedStmtContext::Compound |
1150 (isStmtExpr ? ParsedStmtContext::InStmtExpr : ParsedStmtContext());
1152 bool LastIsError =
false;
1153 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
1154 Tok.isNot(tok::eof)) {
1155 if (Tok.is(tok::annot_pragma_unused)) {
1156 HandlePragmaUnused();
1160 if (ConsumeNullStmt(Stmts))
1164 if (Tok.isNot(tok::kw___extension__)) {
1165 R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
1172 while (Tok.is(tok::kw___extension__))
1175 ParsedAttributes attrs(AttrFactory);
1176 MaybeParseCXX11Attributes(attrs,
true);
1179 if (isDeclarationStatement()) {
1182 ExtensionRAIIObject O(Diags);
1184 SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
1185 ParsedAttributes DeclSpecAttrs(AttrFactory);
1187 attrs, DeclSpecAttrs);
1188 R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);
1191 ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
1193 if (Res.isInvalid()) {
1200 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
1201 R = handleExprStmt(Res, SubStmtCtx);
1203 R = Actions.ActOnAttributedStmt(attrs, R.get());
1208 Stmts.push_back(R.get());
1209 LastIsError = R.isInvalid();
1215 if (isStmtExpr && LastIsError && !Stmts.empty())
1222 if (!PP.getTargetInfo().supportSourceEvalMethod() &&
1223 (PP.getLastFPEvalPragmaLocation().isValid() ||
1224 PP.getCurrentFPEvalMethod() ==
1226 Diag(Tok.getLocation(),
1227 diag::warn_no_support_for_eval_method_source_on_m32);
1229 SourceLocation CloseLoc = Tok.getLocation();
1232 if (!
T.consumeClose()) {
1235 if (isStmtExpr && Tok.is(tok::r_paren))
1236 checkCompoundToken(CloseLoc, tok::r_brace, CompoundToken::StmtExprEnd);
1242 if (
T.getCloseLocation().isValid())
1243 CloseLoc =
T.getCloseLocation();
1245 return Actions.ActOnCompoundStmt(
T.getOpenLocation(), CloseLoc,
1249bool Parser::ParseParenExprOrCondition(
StmtResult *InitStmt,
1257 SourceLocation Start = Tok.getLocation();
1260 Cond = ParseCXXCondition(InitStmt, Loc, CK,
false);
1275 if (
Cond.isInvalid() && Tok.isNot(tok::r_paren)) {
1279 if (Tok.isNot(tok::r_paren))
1283 if (
Cond.isInvalid()) {
1284 ExprResult CondExpr = Actions.CreateRecoveryExpr(
1285 Start, Tok.getLocation() == Start ? Start : PrevTokLocation, {},
1286 Actions.PreferredConditionType(CK));
1294 LParenLoc =
T.getOpenLocation();
1295 RParenLoc =
T.getCloseLocation();
1300 while (Tok.is(tok::r_paren)) {
1301 Diag(Tok, diag::err_extraneous_rparen_in_condition)
1311enum MisleadingStatementKind { MSK_if, MSK_else, MSK_for, MSK_while };
1313struct MisleadingIndentationChecker {
1315 SourceLocation StmtLoc;
1316 SourceLocation PrevLoc;
1317 unsigned NumDirectives;
1318 MisleadingStatementKind
Kind;
1320 MisleadingIndentationChecker(Parser &P, MisleadingStatementKind K,
1322 : P(P), StmtLoc(SL), PrevLoc(P.getCurToken().getLocation()),
1323 NumDirectives(P.getPreprocessor().getNumDirectives()),
Kind(K),
1324 ShouldSkip(P.getCurToken().
is(tok::l_brace)) {
1326 StmtLoc = P.MisleadingIndentationElseLoc;
1327 P.MisleadingIndentationElseLoc = SourceLocation();
1329 if (Kind == MSK_else && !ShouldSkip)
1335 static unsigned getVisualIndentation(SourceManager &
SM, SourceLocation Loc) {
1336 unsigned TabStop =
SM.getDiagnostics().getDiagnosticOptions().TabStop;
1338 unsigned ColNo =
SM.getSpellingColumnNumber(Loc);
1339 if (ColNo == 0 || TabStop == 1)
1345 StringRef BufData =
SM.getBufferData(FIDAndOffset.first, &
Invalid);
1349 const char *EndPos = BufData.data() + FIDAndOffset.second;
1351 assert(FIDAndOffset.second + 1 >= ColNo &&
1352 "Column number smaller than file offset?");
1354 unsigned VisualColumn = 0;
1357 for (
const char *CurPos = EndPos - (ColNo - 1); CurPos != EndPos;
1359 if (*CurPos ==
'\t')
1361 VisualColumn += (TabStop - VisualColumn % TabStop);
1365 return VisualColumn + 1;
1380 if (Kind == MSK_else)
1384 unsigned PrevColNum = getVisualIndentation(
SM, PrevLoc);
1386 unsigned StmtColNum = getVisualIndentation(
SM, StmtLoc);
1388 if (PrevColNum != 0 && CurColNum != 0 && StmtColNum != 0 &&
1389 ((PrevColNum > StmtColNum && PrevColNum == CurColNum) ||
1391 SM.getPresumedLineNumber(StmtLoc) !=
1396 P.
Diag(StmtLoc, diag::note_previous_statement);
1404 assert(Tok.is(tok::kw_if) &&
"Not an if stmt!");
1407 bool IsConstexpr =
false;
1408 bool IsConsteval =
false;
1409 SourceLocation NotLocation;
1410 SourceLocation ConstevalLoc;
1412 if (Tok.is(tok::kw_constexpr)) {
1416 : diag::ext_constexpr_if);
1421 if (Tok.is(tok::exclaim)) {
1425 if (Tok.is(tok::kw_consteval)) {
1427 : diag::ext_consteval_if);
1430 }
else if (Tok.is(tok::code_completion)) {
1432 Actions.CodeCompletion().CodeCompleteKeywordAfterIf(
1437 if (!IsConsteval && (NotLocation.
isValid() || Tok.isNot(tok::l_paren))) {
1438 Diag(Tok, diag::err_expected_lparen_after) <<
"if";
1461 Sema::ConditionResult
Cond;
1462 SourceLocation LParen;
1463 SourceLocation RParen;
1464 std::optional<bool> ConstexprCondition;
1467 if (ParseParenExprOrCondition(&InitStmt,
Cond, IfLoc,
1474 ConstexprCondition =
Cond.getKnownValue();
1477 bool IsBracedThen = Tok.is(tok::l_brace);
1499 MisleadingIndentationChecker MIChecker(*
this, MSK_if, IfLoc);
1502 SourceLocation ThenStmtLoc = Tok.getLocation();
1504 SourceLocation InnerStatementTrailingElseLoc;
1507 bool ShouldEnter = ConstexprCondition && !*ConstexprCondition;
1510 if (NotLocation.
isInvalid() && IsConsteval) {
1515 EnterExpressionEvaluationContext PotentiallyDiscarded(
1516 Actions, Context,
nullptr,
1518 ThenStmt = ParseStatement(&InnerStatementTrailingElseLoc);
1521 if (Tok.isNot(tok::kw_else))
1528 SourceLocation ElseLoc;
1529 SourceLocation ElseStmtLoc;
1532 if (Tok.is(tok::kw_else)) {
1533 if (TrailingElseLoc)
1534 *TrailingElseLoc = Tok.getLocation();
1537 ElseStmtLoc = Tok.getLocation();
1549 Tok.is(tok::l_brace));
1551 MisleadingIndentationChecker MIChecker(*
this, MSK_else, ElseLoc);
1552 bool ShouldEnter = ConstexprCondition && *ConstexprCondition;
1555 if (NotLocation.
isValid() && IsConsteval) {
1560 EnterExpressionEvaluationContext PotentiallyDiscarded(
1561 Actions, Context,
nullptr,
1563 ElseStmt = ParseStatement();
1565 if (ElseStmt.isUsable())
1570 }
else if (Tok.is(tok::code_completion)) {
1572 Actions.CodeCompletion().CodeCompleteAfterIf(
getCurScope(), IsBracedThen);
1574 }
else if (InnerStatementTrailingElseLoc.
isValid()) {
1575 Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else);
1583 if ((ThenStmt.isInvalid() && ElseStmt.isInvalid()) ||
1584 (ThenStmt.isInvalid() && ElseStmt.get() ==
nullptr) ||
1585 (ThenStmt.get() ==
nullptr && ElseStmt.isInvalid())) {
1591 auto IsCompoundStatement = [](
const Stmt *S) {
1592 if (
const auto *Outer = dyn_cast_if_present<AttributedStmt>(S))
1593 S = Outer->getSubStmt();
1594 return isa_and_nonnull<clang::CompoundStmt>(S);
1597 if (!IsCompoundStatement(ThenStmt.get())) {
1598 Diag(ConstevalLoc, diag::err_expected_after) <<
"consteval"
1602 if (!ElseStmt.isUnset() && !IsCompoundStatement(ElseStmt.get())) {
1603 Diag(ElseLoc, diag::err_expected_after) <<
"else"
1610 if (ThenStmt.isInvalid())
1611 ThenStmt = Actions.ActOnNullStmt(ThenStmtLoc);
1612 if (ElseStmt.isInvalid())
1613 ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);
1618 else if (IsConsteval)
1622 return Actions.ActOnIfStmt(IfLoc, Kind, LParen, InitStmt.get(),
Cond, RParen,
1623 ThenStmt.get(), ElseLoc, ElseStmt.get());
1628 assert(Tok.is(tok::kw_switch) &&
"Not a switch stmt!");
1631 if (Tok.isNot(tok::l_paren)) {
1632 Diag(Tok, diag::err_expected_lparen_after) <<
"switch";
1658 Sema::ConditionResult
Cond;
1659 SourceLocation LParen;
1660 SourceLocation RParen;
1661 if (ParseParenExprOrCondition(&InitStmt,
Cond, SwitchLoc,
1666 SwitchLoc, LParen, InitStmt.get(),
Cond, RParen);
1668 if (
Switch.isInvalid()) {
1673 if (Tok.is(tok::l_brace)) {
1702 StmtResult Body(ParseStatement(TrailingElseLoc));
1708 return Actions.ActOnFinishSwitchStmt(SwitchLoc,
Switch.get(), Body.get());
1713 assert(Tok.is(tok::kw_while) &&
"Not a while stmt!");
1714 SourceLocation WhileLoc = Tok.getLocation();
1717 if (Tok.isNot(tok::l_paren)) {
1718 Diag(Tok, diag::err_expected_lparen_after) <<
"while";
1737 unsigned ScopeFlags;
1746 Sema::ConditionResult
Cond;
1747 SourceLocation LParen;
1748 SourceLocation RParen;
1749 if (ParseParenExprOrCondition(
nullptr,
Cond, WhileLoc,
1772 MisleadingIndentationChecker MIChecker(*
this, MSK_while, WhileLoc);
1775 StmtResult Body(ParseStatement(TrailingElseLoc));
1777 if (Body.isUsable())
1783 if (
Cond.isInvalid() || Body.isInvalid())
1786 return Actions.ActOnWhileStmt(WhileLoc, LParen,
Cond, RParen, Body.get());
1790 assert(Tok.is(tok::kw_do) &&
"Not a do stmt!");
1795 unsigned ScopeFlags;
1829 if (Tok.isNot(tok::kw_while)) {
1830 if (!Body.isInvalid()) {
1831 Diag(Tok, diag::err_expected_while);
1832 Diag(DoLoc, diag::note_matching) <<
"'do'";
1839 if (Tok.isNot(tok::l_paren)) {
1840 Diag(Tok, diag::err_expected_lparen_after) <<
"do/while";
1850 DiagnoseAndSkipCXX11Attributes();
1852 SourceLocation Start = Tok.getLocation();
1854 if (!
Cond.isUsable()) {
1855 if (!Tok.isOneOf(tok::r_paren, tok::r_square, tok::r_brace))
1857 Cond = Actions.CreateRecoveryExpr(
1858 Start, Start == Tok.getLocation() ? Start : PrevTokLocation, {},
1859 Actions.getASTContext().BoolTy);
1864 if (
Cond.isInvalid() || Body.isInvalid())
1867 return Actions.ActOnDoStmt(DoLoc, Body.get(), WhileLoc,
T.getOpenLocation(),
1868 Cond.get(),
T.getCloseLocation());
1871bool Parser::isForRangeIdentifier() {
1872 assert(Tok.is(tok::identifier));
1875 if (
Next.is(tok::colon))
1878 if (
Next.isOneOf(tok::l_square, tok::kw_alignas)) {
1879 TentativeParsingAction PA(*
this);
1881 SkipCXX11Attributes();
1882 bool Result = Tok.is(tok::colon);
1892 assert(Tok.is(tok::kw_for) &&
"Not a for stmt!");
1895 SourceLocation CoawaitLoc;
1896 if (Tok.is(tok::kw_co_await))
1899 if (Tok.isNot(tok::l_paren)) {
1900 Diag(Tok, diag::err_expected_lparen_after) <<
"for";
1923 unsigned ScopeFlags = 0;
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,
2110 if (ForRangeInfo.ParsedForRangeDecl()) {
2111 Diag(FirstPart.get() ? FirstPart.get()->getBeginLoc()
2112 : ForRangeInfo.ColonLoc,
2114 ? diag::warn_cxx17_compat_for_range_init_stmt
2115 : diag::ext_for_range_init_stmt)
2116 << (FirstPart.get() ? FirstPart.get()->getSourceRange()
2118 if (EmptyInitStmtSemiLoc.
isValid()) {
2119 Diag(EmptyInitStmtSemiLoc, diag::warn_empty_init_statement)
2126 ExprResult CondExpr = Actions.CreateRecoveryExpr(
2128 Tok.getLocation() == SecondPartStart ? SecondPartStart
2130 {}, Actions.PreferredConditionType(CK));
2132 SecondPart = Actions.ActOnCondition(
getCurScope(), ForLoc,
2145 SecondPart = Actions.ActOnCondition(
2158 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl()) {
2159 if (Tok.isNot(tok::semi)) {
2161 Diag(Tok, diag::err_expected_semi_for);
2165 if (Tok.is(tok::semi)) {
2169 if (Tok.isNot(tok::r_paren)) {
2173 ThirdPart = Actions.MakeFullDiscardedValueExpr(Third.
get());
2181 if (CoawaitLoc.
isValid() && !ForRangeInfo.ParsedForRangeDecl()) {
2182 Diag(CoawaitLoc, diag::err_for_co_await_not_range_for);
2183 CoawaitLoc = SourceLocation();
2187 Diag(CoawaitLoc, diag::warn_deprecated_for_co_await);
2195 if (ForRangeInfo.ParsedForRangeDecl()) {
2196 ForRangeStmt = Actions.ActOnCXXForRangeStmt(
2197 getCurScope(), ForLoc, CoawaitLoc, FirstPart.get(),
2198 ForRangeInfo.LoopVar.get(), ForRangeInfo.ColonLoc,
2200 ForRangeInfo.LifetimeExtendTemps);
2201 }
else if (ForEach) {
2204 ForEachStmt = Actions.ObjC().ActOnObjCForCollectionStmt(
2205 ForLoc, FirstPart.get(), Collection.
get(),
T.getCloseLocation());
2209 if (
getLangOpts().OpenMP && FirstPart.isUsable()) {
2210 Actions.OpenMP().ActOnOpenMPLoopInitialization(ForLoc, FirstPart.get());
2217 if (ForRangeInfo.ParsedForRangeDecl())
2221 ForLoc, FirstPart.get(), SecondPart.
get().second, ThirdPart.get());
2239 Tok.is(tok::l_brace));
2248 MisleadingIndentationChecker MIChecker(*
this, MSK_for, ForLoc);
2251 StmtResult Body(ParseStatement(TrailingElseLoc));
2253 if (Body.isUsable())
2264 if (Body.isInvalid())
2268 return Actions.ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2271 if (ForRangeInfo.ParsedForRangeDecl())
2272 return Actions.FinishCXXForRangeStmt(ForRangeStmt.get(), Body.get());
2274 return Actions.ActOnForStmt(ForLoc,
T.getOpenLocation(), FirstPart.get(),
2275 SecondPart, ThirdPart,
T.getCloseLocation(),
2280 assert(Tok.is(tok::kw_goto) &&
"Not a goto stmt!");
2284 if (Tok.is(tok::identifier)) {
2285 LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(),
2287 Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(), LD);
2289 }
else if (Tok.is(tok::star)) {
2291 Diag(Tok, diag::ext_gnu_indirect_goto);
2294 if (R.isInvalid()) {
2298 Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.get());
2300 Diag(Tok, diag::err_expected) << tok::identifier;
2307StmtResult Parser::ParseBreakOrContinueStatement(
bool IsContinue) {
2309 SourceLocation LabelLoc;
2310 LabelDecl *
Target =
nullptr;
2311 if (Tok.is(tok::identifier)) {
2313 Actions.LookupExistingLabel(Tok.getIdentifierInfo(), Tok.getLocation());
2318 Diag(LabelLoc, diag::err_c2y_labeled_break_continue) << IsContinue;
2320 Diag(LabelLoc, diag::err_break_continue_label_not_found) << IsContinue;
2331 return ParseBreakOrContinueStatement(
true);
2335 return ParseBreakOrContinueStatement(
false);
2339 assert((Tok.is(tok::kw_return) || Tok.is(tok::kw_co_return)) &&
2340 "Not a return stmt!");
2341 bool IsCoreturn = Tok.is(tok::kw_co_return);
2345 if (Tok.isNot(tok::semi)) {
2347 PreferredType.enterReturn(Actions, Tok.getLocation());
2349 if (Tok.is(tok::code_completion) && !IsCoreturn) {
2351 Actions.CodeCompletion().CodeCompleteExpression(
2352 getCurScope(), PreferredType.get(Tok.getLocation()));
2357 R = ParseInitializer();
2361 ? diag::warn_cxx98_compat_generalized_initializer_lists
2362 : diag::ext_generalized_initializer_lists)
2372 return Actions.ActOnCoreturnStmt(
getCurScope(), ReturnLoc, R.
get());
2373 return Actions.ActOnReturnStmt(ReturnLoc, R.
get(),
getCurScope());
2377 assert(Tok.is(tok::kw__Defer));
2380 Actions.ActOnStartOfDeferStmt(DeferLoc,
getCurScope());
2382 auto OnError = llvm::make_scope_exit(
2383 [&] { Actions.ActOnDeferStmtError(
getCurScope()); });
2385 StmtResult Res = ParseStatement(TrailingElseLoc);
2386 if (!Res.isUsable())
2390 if (
auto *L = dyn_cast<LabelStmt>(Res.get())) {
2391 Diag(L->getIdentLoc(), diag::err_defer_ts_labeled_stmt);
2396 return Actions.ActOnEndOfDeferStmt(Res.get(),
getCurScope());
2399StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
2400 ParsedStmtContext StmtCtx,
2405 ParsedAttributes TempAttrs(AttrFactory);
2407 SourceLocation StartLoc = Tok.getLocation();
2410 while (Tok.is(tok::annot_pragma_loop_hint)) {
2412 if (!HandlePragmaLoopHint(Hint))
2418 AttributeScopeInfo(), ArgHints, 4,
2419 ParsedAttr::Form::Pragma());
2423 MaybeParseCXX11Attributes(Attrs);
2425 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2426 StmtResult S = ParseStatementOrDeclarationAfterAttributes(
2427 Stmts, StmtCtx, TrailingElseLoc, Attrs, EmptyDeclSpecAttrs,
2440Decl *Parser::ParseFunctionStatementBody(
Decl *
Decl, ParseScope &BodyScope) {
2441 assert(Tok.is(tok::l_brace));
2442 SourceLocation LBraceLoc = Tok.getLocation();
2444 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, LBraceLoc,
2445 "parsing function body");
2450 Sema::PragmaStackSentinelRAII
2451 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2456 StmtResult FnBody(ParseCompoundStatementBody());
2459 if (FnBody.isInvalid()) {
2460 Sema::CompoundScopeRAII CompoundScope(Actions);
2461 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, {},
false);
2465 return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
2468Decl *Parser::ParseFunctionTryBlock(
Decl *
Decl, ParseScope &BodyScope) {
2469 assert(Tok.is(tok::kw_try) &&
"Expected 'try'");
2472 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, TryLoc,
2473 "parsing function try block");
2476 if (Tok.is(tok::colon))
2477 ParseConstructorInitializer(Decl);
2479 Actions.ActOnDefaultCtorInitializers(Decl);
2484 Sema::PragmaStackSentinelRAII
2485 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2487 SourceLocation LBraceLoc = Tok.getLocation();
2488 StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc,
true));
2491 if (FnBody.isInvalid()) {
2492 Sema::CompoundScopeRAII CompoundScope(Actions);
2493 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, {},
false);
2497 return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
2500bool Parser::trySkippingFunctionBody() {
2501 assert(SkipFunctionBodies &&
2502 "Should only be called when SkipFunctionBodies is enabled");
2503 if (!PP.isCodeCompletionEnabled()) {
2510 TentativeParsingAction PA(*
this);
2511 bool IsTryCatch = Tok.is(tok::kw_try);
2513 bool ErrorInPrologue = ConsumeAndStoreFunctionPrologue(Toks);
2514 if (llvm::any_of(Toks, [](
const Token &Tok) {
2515 return Tok.is(tok::code_completion);
2520 if (ErrorInPrologue) {
2529 while (IsTryCatch && Tok.is(tok::kw_catch)) {
2541 assert(Tok.is(tok::kw_try) &&
"Expected 'try'");
2544 return ParseCXXTryBlockCommon(TryLoc);
2548 if (Tok.isNot(tok::l_brace))
2549 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2555 if (TryBlock.isInvalid())
2560 if ((Tok.is(tok::identifier) &&
2561 Tok.getIdentifierInfo() == getSEHExceptKeyword()) ||
2562 Tok.is(tok::kw___finally)) {
2565 if(Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
2567 Handler = ParseSEHExceptBlock(Loc);
2571 Handler = ParseSEHFinallyBlock(Loc);
2573 if(Handler.isInvalid())
2576 return Actions.ActOnSEHTryBlock(
true ,
2586 DiagnoseAndSkipCXX11Attributes();
2588 if (Tok.isNot(tok::kw_catch))
2590 while (Tok.is(tok::kw_catch)) {
2591 StmtResult Handler(ParseCXXCatchBlock(FnTry));
2592 if (!Handler.isInvalid())
2593 Handlers.push_back(Handler.get());
2597 if (Handlers.empty())
2600 return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.get(), Handlers);
2604StmtResult Parser::ParseCXXCatchBlock(
bool FnCatch) {
2605 assert(Tok.is(tok::kw_catch) &&
"Expected 'catch'");
2610 if (
T.expectAndConsume())
2622 Decl *ExceptionDecl =
nullptr;
2623 if (Tok.isNot(tok::ellipsis)) {
2624 ParsedAttributes Attributes(AttrFactory);
2625 MaybeParseCXX11Attributes(Attributes);
2627 DeclSpec DS(AttrFactory);
2629 if (ParseCXXTypeSpecifierSeq(DS))
2633 ParseDeclarator(ExDecl);
2634 ExceptionDecl = Actions.ActOnExceptionDeclarator(
getCurScope(), ExDecl);
2639 if (
T.getCloseLocation().isInvalid())
2642 if (Tok.isNot(tok::l_brace))
2643 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2647 if (
Block.isInvalid())
2650 return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl,
Block.get());
2653void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
2654 IfExistsCondition
Result;
2655 if (ParseMicrosoftIfExistsCondition(
Result))
2663 if (!Tok.is(tok::l_brace)) {
2664 Diag(Tok, diag::err_expected) << tok::l_brace;
2668 StmtResult Compound = ParseCompoundStatement();
2669 if (Compound.isInvalid())
2672 StmtResult DepResult = Actions.ActOnMSDependentExistsStmt(
Result.KeywordLoc,
2677 if (DepResult.isUsable())
2678 Stmts.push_back(DepResult.get());
2683 if (
Braces.consumeOpen()) {
2684 Diag(Tok, diag::err_expected) << tok::l_brace;
2688 switch (
Result.Behavior) {
2694 llvm_unreachable(
"Dependent case handled above");
2702 while (Tok.isNot(tok::r_brace)) {
2704 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::Compound);
2706 Stmts.push_back(R.get());
This file defines the classes used to store parsed information about declaration-specifiers and decla...
static void DiagnoseLabelFollowedByDecl(Parser &P, const Stmt *SubStmt)
Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...
This file declares facilities that support code completion.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis for OpenACC constructs and clauses.
This file declares semantic analysis for OpenMP constructs and clauses.
Defines the clang::TokenKind enum and support functions.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
virtual bool ValidateCandidate(const TypoCorrection &candidate)
Simple predicate used by the default RankCandidate to determine whether to return an edit distance of...
Decl - This represents one declaration (or definition), e.g.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
IdentifierInfo * getIdentifierInfo() const
Represents the declaration of a label.
@ FEM_Source
Use the declared type for fp arithmetic.
ParsedAttributes - A collection of parsed attributes.
void takeAllPrependingFrom(ParsedAttributes &Other)
void takeAllAppendingFrom(ParsedAttributes &Other)
ParseScope - Introduces a new scope for parsing.
Parser - This implements a parser for the C family of languages.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation getEndOfPreviousToken() const
Preprocessor & getPreprocessor() const
Sema::FullExprArg FullExprArg
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Sema & getActions() const
ExprResult ParseCaseExpression(SourceLocation CaseLoc)
SmallVector< Stmt *, 24 > StmtVector
A SmallVector of statements.
friend class ColonProtectionRAIIObject
StmtResult ParseOpenACCDirectiveStmt()
bool TryConsumeToken(tok::TokenKind Expected)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Scope * getCurScope() const
friend class InMessageExpressionRAIIObject
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
void SkipMalformedDecl()
SkipMalformedDecl - Read tokens until we get to some likely good stopping point for skipping past a s...
const Token & getCurToken() const
SourceLocation MisleadingIndentationElseLoc
The location of the first statement inside an else that might have a missleading indentation.
const LangOptions & getLangOpts() const
friend class ParenBraceBracketBalancer
ExprResult ParseExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Simple precedence-based parser for binary/ternary operators.
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtCodeCompletion
Stop at code completion.
@ StopAtSemi
Stop skipping at semicolon.
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
friend class BalancedDelimiterTracker
unsigned getNumDirectives() const
Retrieve the number of Directives that have been processed by the Preprocessor.
const Token & LookAhead(unsigned N)
Peeks ahead N tokens and returns that token without consuming any tokens.
SourceManager & getSourceManager() const
void AddFlags(unsigned Flags)
Sets up the specified scope flags and adjusts the scope state variables accordingly.
void setPrecedingLabel(LabelDecl *LD)
void decrementMSManglingNumber()
@ SEHTryScope
This scope corresponds to an SEH try.
@ ContinueScope
This is a while, do, for, which can have continue statements embedded into it.
@ ControlScope
The controlling scope in a if/switch/while/for statement.
@ SEHFilterScope
We are currently in the filter expression of an SEH except block.
@ SwitchScope
This is a scope that corresponds to a switch statement.
@ BreakScope
This is a while, do, switch, for, etc that can have break statements embedded into it.
@ CatchScope
This is the scope of a C++ catch statement.
@ CompoundStmtScope
This is a compound statement scope.
@ FnTryCatchScope
This is the scope for a function-level C++ try or catch scope.
@ SEHExceptScope
This scope corresponds to an SEH except.
@ TryScope
This is the scope of a C++ try statement.
@ DeclScope
This is a scope that can contain a declaration.
@ PCC_ForInit
Code completion occurs at the beginning of the initialization statement (or expression) in a for loop...
@ PCC_Expression
Code completion occurs within an expression.
@ PCC_Statement
Code completion occurs within a statement, which may also be an expression or a declaration.
void ActOnWhileStmt(SourceLocation WhileLoc)
void ActOnDoStmt(SourceLocation DoLoc)
void ActOnRangeForStmtBegin(SourceLocation ForLoc, const Stmt *OldRangeFor, const Stmt *RangeFor)
void ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body)
void ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *First, const Stmt *Second, const Stmt *Third)
std::pair< VarDecl *, Expr * > get() const
@ Boolean
A boolean condition, from 'if', 'while', 'for', or 'do'.
@ Switch
An integral condition for a 'switch' statement.
@ ConstexprIf
A constant boolean condition from 'if constexpr'.
DiagnosticsEngine & getDiagnostics() const
ExpressionEvaluationContext
Describes how the expressions currently being parsed are evaluated at run-time, if at all.
@ DiscardedStatement
The current expression occurs within a discarded statement.
@ ImmediateFunctionContext
In addition of being constant evaluated, the current expression occurs in an immediate function conte...
@ BFRK_Build
Initial building of a for-range statement.
static ConditionResult ConditionError()
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
void setBegin(SourceLocation b)
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
IdentifierInfo * getIdentifierInfo() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
bool isOneOf(Ts... Ks) const
bool isNot(tok::TokenKind K) const
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
void setAnnotationValue(void *val)
DeclClass * getCorrectionDeclAs() const
NestedNameSpecifier getCorrectionSpecifier() const
Gets the NestedNameSpecifier needed to use the typo correction.
Defines the clang::TargetInfo interface.
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
IfStatementKind
In an if statement, this denotes whether the statement is a constexpr or consteval if statement.
llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion
A union of the various pointer types that can be passed to an ParsedAttr as an argument.
@ Error
Annotation has failed and emitted an error.
std::pair< FileID, unsigned > FileIDAndOffset
@ Dependent
Parse the block as a dependent block, which may be used in some template instantiations but not other...
@ Skip
Skip the block entirely; this code is never used.
@ Parse
Parse the block; this code is always used.
@ Result
The result type of a method or function.
const FunctionProtoType * T
void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &&Second)
Consumes the attributes from Second and concatenates them at the end of First.
SmallVector< Token, 4 > CachedTokens
A set of tokens that has been cached for later parsing.
ActionResult< Expr * > ExprResult
@ Braces
New-expression has a C++11 list-initializer.
ActionResult< Stmt * > StmtResult
IdentifierLoc * OptionLoc
IdentifierLoc * PragmaNameLoc