23 using namespace clang;
32 ParsedStmtContext StmtCtx) {
39 Res = ParseStatementOrDeclaration(Stmts, StmtCtx, TrailingElseLoc);
40 }
while (!Res.isInvalid() && !Res.get());
95 Parser::ParseStatementOrDeclaration(StmtVector &Stmts,
96 ParsedStmtContext StmtCtx,
101 ParsedAttributesWithRange Attrs(AttrFactory);
102 MaybeParseCXX11Attributes(Attrs,
nullptr,
true);
103 if (!MaybeParseOpenCLUnrollHintAttribute(Attrs))
106 StmtResult Res = ParseStatementOrDeclarationAfterAttributes(
107 Stmts, StmtCtx, TrailingElseLoc, Attrs);
109 assert((Attrs.empty() || Res.isInvalid() || Res.isUsable()) &&
110 "attributes on empty statement");
112 if (Attrs.empty() || Res.isInvalid())
122 WantTypeSpecifiers = nextTok.
isOneOf(tok::l_paren, tok::less, tok::l_square,
123 tok::identifier, tok::star, tok::amp);
124 WantExpressionKeywords =
125 nextTok.
isOneOf(tok::l_paren, tok::identifier, tok::arrow, tok::period);
126 WantRemainingKeywords =
127 nextTok.
isOneOf(tok::l_paren, tok::semi, tok::identifier, tok::l_brace);
128 WantCXXNamedCasts =
false;
131 bool ValidateCandidate(
const TypoCorrection &candidate)
override {
142 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
143 return llvm::make_unique<StatementFilterCCC>(*this);
151 StmtResult Parser::ParseStatementOrDeclarationAfterAttributes(
152 StmtVector &Stmts, ParsedStmtContext StmtCtx,
153 SourceLocation *TrailingElseLoc, ParsedAttributesWithRange &Attrs) {
154 const char *SemiError =
nullptr;
166 ProhibitAttributes(Attrs);
168 return ParseObjCAtStatement(AtLoc, StmtCtx);
171 case tok::code_completion:
176 case tok::identifier: {
178 if (Next.
is(tok::colon)) {
180 return ParseLabeledStatement(Attrs, StmtCtx);
185 if (Next.
isNot(tok::coloncolon)) {
188 StatementFilterCCC CCC(Next);
189 if (TryAnnotateName(
false, &CCC) == ANK_Error) {
193 if (
Tok.
is(tok::semi))
209 (StmtCtx & ParsedStmtContext::AllowDeclarationsInC) !=
210 ParsedStmtContext()) &&
211 isDeclarationStatement()) {
215 return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
218 if (
Tok.
is(tok::r_brace)) {
219 Diag(Tok, diag::err_expected_statement);
223 return ParseExprStatement(StmtCtx);
227 return ParseCaseStatement(StmtCtx);
228 case tok::kw_default:
229 return ParseDefaultStatement(StmtCtx);
232 return ParseCompoundStatement();
234 bool HasLeadingEmptyMacro =
Tok.hasLeadingEmptyMacro();
235 return Actions.ActOnNullStmt(
ConsumeToken(), HasLeadingEmptyMacro);
239 return ParseIfStatement(TrailingElseLoc);
241 return ParseSwitchStatement(TrailingElseLoc);
244 return ParseWhileStatement(TrailingElseLoc);
246 Res = ParseDoStatement();
247 SemiError =
"do/while";
250 return ParseForStatement(TrailingElseLoc);
253 Res = ParseGotoStatement();
256 case tok::kw_continue:
257 Res = ParseContinueStatement();
258 SemiError =
"continue";
261 Res = ParseBreakStatement();
265 Res = ParseReturnStatement();
266 SemiError =
"return";
268 case tok::kw_co_return:
269 Res = ParseReturnStatement();
270 SemiError =
"co_return";
274 ProhibitAttributes(Attrs);
276 Res = ParseAsmStatement(msAsm);
277 Res = Actions.ActOnFinishFullStmt(Res.get());
278 if (msAsm)
return Res;
283 case tok::kw___if_exists:
284 case tok::kw___if_not_exists:
285 ProhibitAttributes(Attrs);
286 ParseMicrosoftIfExistsStatement(Stmts);
292 return ParseCXXTryBlock();
295 ProhibitAttributes(Attrs);
296 return ParseSEHTryBlock();
298 case tok::kw___leave:
299 Res = ParseSEHLeaveStatement();
300 SemiError =
"__leave";
303 case tok::annot_pragma_vis:
304 ProhibitAttributes(Attrs);
305 HandlePragmaVisibility();
308 case tok::annot_pragma_pack:
309 ProhibitAttributes(Attrs);
313 case tok::annot_pragma_msstruct:
314 ProhibitAttributes(Attrs);
315 HandlePragmaMSStruct();
318 case tok::annot_pragma_align:
319 ProhibitAttributes(Attrs);
323 case tok::annot_pragma_weak:
324 ProhibitAttributes(Attrs);
328 case tok::annot_pragma_weakalias:
329 ProhibitAttributes(Attrs);
330 HandlePragmaWeakAlias();
333 case tok::annot_pragma_redefine_extname:
334 ProhibitAttributes(Attrs);
335 HandlePragmaRedefineExtname();
338 case tok::annot_pragma_fp_contract:
339 ProhibitAttributes(Attrs);
340 Diag(Tok, diag::err_pragma_fp_contract_scope);
341 ConsumeAnnotationToken();
344 case tok::annot_pragma_fp:
345 ProhibitAttributes(Attrs);
346 Diag(Tok, diag::err_pragma_fp_scope);
347 ConsumeAnnotationToken();
350 case tok::annot_pragma_fenv_access:
351 ProhibitAttributes(Attrs);
352 HandlePragmaFEnvAccess();
355 case tok::annot_pragma_opencl_extension:
356 ProhibitAttributes(Attrs);
357 HandlePragmaOpenCLExtension();
360 case tok::annot_pragma_captured:
361 ProhibitAttributes(Attrs);
362 return HandlePragmaCaptured();
364 case tok::annot_pragma_openmp:
365 ProhibitAttributes(Attrs);
366 return ParseOpenMPDeclarativeOrExecutableDirective(StmtCtx);
368 case tok::annot_pragma_ms_pointers_to_members:
369 ProhibitAttributes(Attrs);
370 HandlePragmaMSPointersToMembers();
373 case tok::annot_pragma_ms_pragma:
374 ProhibitAttributes(Attrs);
375 HandlePragmaMSPragma();
378 case tok::annot_pragma_ms_vtordisp:
379 ProhibitAttributes(Attrs);
380 HandlePragmaMSVtorDisp();
383 case tok::annot_pragma_loop_hint:
384 ProhibitAttributes(Attrs);
385 return ParsePragmaLoopHint(Stmts, StmtCtx, TrailingElseLoc, Attrs);
387 case tok::annot_pragma_dump:
391 case tok::annot_pragma_attribute:
392 HandlePragmaAttribute();
401 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt, SemiError);
410 StmtResult Parser::ParseExprStatement(ParsedStmtContext StmtCtx) {
414 ExprStatementTokLoc =
Tok.getLocation();
418 if (
Expr.isInvalid()) {
423 if (
Tok.
is(tok::semi))
425 return Actions.ActOnExprStmtError();
429 Actions.CheckCaseExpression(
Expr.get())) {
432 Diag(OldToken, diag::err_expected_case_before_expression)
436 return ParseCaseStatement(StmtCtx,
true,
Expr);
440 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
441 return handleExprStmt(
Expr, StmtCtx);
454 assert(
Tok.
is(tok::kw___try) &&
"Expected '__try'");
458 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
463 if (TryBlock.isInvalid())
467 if (
Tok.
is(tok::identifier) &&
468 Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
470 Handler = ParseSEHExceptBlock(Loc);
471 }
else if (
Tok.
is(tok::kw___finally)) {
473 Handler = ParseSEHFinallyBlock(Loc);
478 if(Handler.isInvalid())
481 return Actions.ActOnSEHTryBlock(
false ,
494 raii2(Ident___exception_code,
false),
495 raii3(Ident_GetExceptionCode,
false);
497 if (ExpectAndConsume(tok::l_paren))
504 Ident__exception_info->setIsPoisoned(
false);
505 Ident___exception_info->setIsPoisoned(
false);
506 Ident_GetExceptionInfo->setIsPoisoned(
false);
511 ParseScopeFlags FilterScope(
this,
getCurScope()->getFlags() |
517 Ident__exception_info->setIsPoisoned(
true);
518 Ident___exception_info->setIsPoisoned(
true);
519 Ident_GetExceptionInfo->setIsPoisoned(
true);
525 if (ExpectAndConsume(tok::r_paren))
529 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
533 if(Block.isInvalid())
536 return Actions.ActOnSEHExceptBlock(ExceptLoc, FilterExpr.
get(), Block.get());
546 raii2(Ident___abnormal_termination,
false),
547 raii3(Ident_AbnormalTermination,
false);
550 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
552 ParseScope FinallyScope(
this, 0);
553 Actions.ActOnStartSEHFinallyBlock();
556 if(Block.isInvalid()) {
557 Actions.ActOnAbortSEHFinallyBlock();
561 return Actions.ActOnFinishSEHFinallyBlock(FinallyLoc, Block.get());
571 return Actions.ActOnSEHLeaveStmt(LeaveLoc,
getCurScope());
580 StmtResult Parser::ParseLabeledStatement(ParsedAttributesWithRange &attrs,
581 ParsedStmtContext StmtCtx) {
582 assert(
Tok.
is(tok::identifier) &&
Tok.getIdentifierInfo() &&
583 "Not an identifier!");
587 StmtCtx &= ~ParsedStmtContext::AllowDeclarationsInC;
592 assert(
Tok.
is(tok::colon) &&
"Not a label!");
599 if (
Tok.
is(tok::kw___attribute)) {
600 ParsedAttributesWithRange TempAttrs(AttrFactory);
601 ParseGNUAttributes(TempAttrs);
611 attrs.takeAllFrom(TempAttrs);
612 else if (isDeclarationStatement()) {
618 SubStmt = ParseStatementOrDeclarationAfterAttributes(Stmts, StmtCtx,
620 if (!TempAttrs.empty() && !SubStmt.isInvalid())
621 SubStmt = Actions.ProcessStmtAttributes(SubStmt.get(), TempAttrs,
624 Diag(Tok, diag::err_expected_after) <<
"__attribute__" << tok::semi;
629 if (!SubStmt.isInvalid() && !SubStmt.isUsable())
630 SubStmt = ParseStatement(
nullptr, StmtCtx);
633 if (SubStmt.isInvalid())
634 SubStmt = Actions.ActOnNullStmt(ColonLoc);
638 Actions.ProcessDeclAttributeList(Actions.CurScope, LD, attrs);
650 StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx,
652 assert((MissingCase ||
Tok.
is(tok::kw_case)) &&
"Not a case stmt!");
656 StmtCtx &= ~ParsedStmtContext::AllowDeclarationsInC;
679 Stmt *DeepestParsedCaseStmt =
nullptr;
688 if (
Tok.
is(tok::code_completion)) {
717 Diag(DotDotDotLoc, diag::ext_gnu_case_range);
725 ColonProtection.restore();
731 Diag(ColonLoc, diag::err_expected_after)
732 <<
"'case'" << tok::colon
735 SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation);
736 Diag(ExpectedLoc, diag::err_expected_after)
737 <<
"'case'" << tok::colon
739 ColonLoc = ExpectedLoc;
743 Actions.ActOnCaseStmt(CaseLoc, LHS, DotDotDotLoc, RHS, ColonLoc);
747 if (Case.isInvalid()) {
748 if (TopLevelCase.isInvalid())
749 return ParseStatement(
nullptr, StmtCtx);
754 Stmt *NextDeepest = Case.get();
755 if (TopLevelCase.isInvalid())
758 Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, Case.get());
759 DeepestParsedCaseStmt = NextDeepest;
763 }
while (
Tok.
is(tok::kw_case));
769 SubStmt = ParseStatement(
nullptr, StmtCtx);
776 Diag(AfterColonLoc, diag::err_label_end_of_compound_statement)
783 if (DeepestParsedCaseStmt) {
785 if (SubStmt.isInvalid())
787 Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, SubStmt.get());
799 StmtResult Parser::ParseDefaultStatement(ParsedStmtContext StmtCtx) {
800 assert(
Tok.
is(tok::kw_default) &&
"Not a default stmt!");
804 StmtCtx &= ~ParsedStmtContext::AllowDeclarationsInC;
812 Diag(ColonLoc, diag::err_expected_after)
813 <<
"'default'" << tok::colon
816 SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation);
817 Diag(ExpectedLoc, diag::err_expected_after)
818 <<
"'default'" << tok::colon
820 ColonLoc = ExpectedLoc;
826 SubStmt = ParseStatement(
nullptr, StmtCtx);
831 Diag(AfterColonLoc, diag::err_label_end_of_compound_statement)
837 if (SubStmt.isInvalid())
838 SubStmt = Actions.ActOnNullStmt(ColonLoc);
840 return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc,
844 StmtResult Parser::ParseCompoundStatement(
bool isStmtExpr) {
845 return ParseCompoundStatement(isStmtExpr,
871 StmtResult Parser::ParseCompoundStatement(
bool isStmtExpr,
872 unsigned ScopeFlags) {
873 assert(
Tok.
is(tok::l_brace) &&
"Not a compount stmt!");
877 ParseScope CompoundScope(
this, ScopeFlags);
880 return ParseCompoundStatementBody(isStmtExpr);
886 void Parser::ParseCompoundStatementLeadingPragmas() {
887 bool checkForPragmas =
true;
888 while (checkForPragmas) {
889 switch (
Tok.getKind()) {
890 case tok::annot_pragma_vis:
891 HandlePragmaVisibility();
893 case tok::annot_pragma_pack:
896 case tok::annot_pragma_msstruct:
897 HandlePragmaMSStruct();
899 case tok::annot_pragma_align:
902 case tok::annot_pragma_weak:
905 case tok::annot_pragma_weakalias:
906 HandlePragmaWeakAlias();
908 case tok::annot_pragma_redefine_extname:
909 HandlePragmaRedefineExtname();
911 case tok::annot_pragma_opencl_extension:
912 HandlePragmaOpenCLExtension();
914 case tok::annot_pragma_fp_contract:
915 HandlePragmaFPContract();
917 case tok::annot_pragma_fp:
920 case tok::annot_pragma_fenv_access:
921 HandlePragmaFEnvAccess();
923 case tok::annot_pragma_ms_pointers_to_members:
924 HandlePragmaMSPointersToMembers();
926 case tok::annot_pragma_ms_pragma:
927 HandlePragmaMSPragma();
929 case tok::annot_pragma_ms_vtordisp:
930 HandlePragmaMSVtorDisp();
932 case tok::annot_pragma_dump:
936 checkForPragmas =
false;
945 bool Parser::ConsumeNullStmt(StmtVector &Stmts) {
946 if (!
Tok.
is(tok::semi))
952 while (
Tok.
is(tok::semi) && !
Tok.hasLeadingEmptyMacro() &&
953 Tok.getLocation().isValid() && !
Tok.getLocation().isMacroID()) {
954 EndLoc =
Tok.getLocation();
958 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::SubStmt);
960 Stmts.push_back(R.get());
967 Diag(StartLoc, diag::warn_null_statement)
973 bool IsStmtExprResult =
false;
974 if ((StmtCtx & ParsedStmtContext::InStmtExpr) != ParsedStmtContext()) {
976 unsigned LookAhead = 0;
977 while (GetLookAheadToken(LookAhead).is(tok::semi)) {
983 IsStmtExprResult = GetLookAheadToken(LookAhead).is(tok::r_brace) &&
984 GetLookAheadToken(LookAhead + 1).is(tok::r_paren);
987 if (IsStmtExprResult)
988 E = Actions.ActOnStmtExprResult(E);
989 return Actions.ActOnExprStmt(E, !IsStmtExprResult);
996 StmtResult Parser::ParseCompoundStatementBody(
bool isStmtExpr) {
999 "in compound statement ('{}')");
1007 if (T.consumeOpen())
1013 ParseCompoundStatementLeadingPragmas();
1019 while (
Tok.
is(tok::kw___label__)) {
1025 Diag(Tok, diag::err_expected) << tok::identifier;
1031 DeclsInGroup.push_back(Actions.LookupOrCreateLabel(II, IdLoc, LabelLoc));
1039 Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, DeclsInGroup);
1040 StmtResult R = Actions.ActOnDeclStmt(Res, LabelLoc,
Tok.getLocation());
1042 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
1044 Stmts.push_back(R.get());
1047 ParsedStmtContext SubStmtCtx =
1048 ParsedStmtContext::Compound |
1049 (isStmtExpr ? ParsedStmtContext::InStmtExpr : ParsedStmtContext());
1051 while (!tryParseMisplacedModuleImport() &&
Tok.
isNot(tok::r_brace) &&
1053 if (
Tok.
is(tok::annot_pragma_unused)) {
1054 HandlePragmaUnused();
1058 if (ConsumeNullStmt(Stmts))
1062 if (
Tok.
isNot(tok::kw___extension__)) {
1063 R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
1070 while (
Tok.
is(tok::kw___extension__))
1073 ParsedAttributesWithRange attrs(AttrFactory);
1074 MaybeParseCXX11Attributes(attrs,
nullptr,
1078 if (isDeclarationStatement()) {
1086 R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);
1089 ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
1091 if (Res.isInvalid()) {
1098 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
1099 R = handleExprStmt(Res, SubStmtCtx);
1101 R = Actions.ProcessStmtAttributes(R.get(), attrs, attrs.Range);
1106 Stmts.push_back(R.get());
1112 if (!T.consumeClose())
1115 CloseLoc = T.getCloseLocation();
1117 return Actions.ActOnCompoundStmt(T.getOpenLocation(), CloseLoc,
1133 bool Parser::ParseParenExprOrCondition(
StmtResult *InitStmt,
1141 Cond = ParseCXXCondition(InitStmt, Loc, CK);
1149 Cond = Actions.ActOnCondition(
getCurScope(), Loc, CondExpr.
get(), CK);
1169 while (
Tok.
is(tok::r_paren)) {
1170 Diag(Tok, diag::err_extraneous_rparen_in_condition)
1187 assert(
Tok.
is(tok::kw_if) &&
"Not an if stmt!");
1190 bool IsConstexpr =
false;
1191 if (
Tok.
is(tok::kw_constexpr)) {
1193 : diag::ext_constexpr_if);
1199 Diag(Tok, diag::err_expected_lparen_after) <<
"if";
1223 if (ParseParenExprOrCondition(&InitStmt, Cond, IfLoc,
1261 ConstexprCondition && !*ConstexprCondition);
1262 ThenStmt = ParseStatement(&InnerStatementTrailingElseLoc);
1273 if (
Tok.
is(tok::kw_else)) {
1274 if (TrailingElseLoc)
1275 *TrailingElseLoc =
Tok.getLocation();
1278 ElseStmtLoc =
Tok.getLocation();
1290 Tok.
is(tok::l_brace));
1295 ConstexprCondition && *ConstexprCondition);
1296 ElseStmt = ParseStatement();
1300 }
else if (
Tok.
is(tok::code_completion)) {
1304 }
else if (InnerStatementTrailingElseLoc.
isValid()) {
1305 Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else);
1313 if ((ThenStmt.isInvalid() && ElseStmt.isInvalid()) ||
1314 (ThenStmt.isInvalid() && ElseStmt.get() ==
nullptr) ||
1315 (ThenStmt.get() ==
nullptr && ElseStmt.isInvalid())) {
1321 if (ThenStmt.isInvalid())
1322 ThenStmt = Actions.ActOnNullStmt(ThenStmtLoc);
1323 if (ElseStmt.isInvalid())
1324 ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);
1326 return Actions.ActOnIfStmt(IfLoc, IsConstexpr, InitStmt.get(), Cond,
1327 ThenStmt.
get(), ElseLoc, ElseStmt.get());
1335 assert(
Tok.
is(tok::kw_switch) &&
"Not a switch stmt!");
1339 Diag(Tok, diag::err_expected_lparen_after) <<
"switch";
1361 ParseScope SwitchScope(
this, ScopeFlags);
1366 if (ParseParenExprOrCondition(&InitStmt, Cond, SwitchLoc,
1371 Actions.ActOnStartOfSwitchStmt(SwitchLoc, InitStmt.get(), Cond);
1373 if (Switch.isInvalid()) {
1378 if (
Tok.
is(tok::l_brace)) {
1406 StmtResult Body(ParseStatement(TrailingElseLoc));
1412 return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.get(), Body.get());
1420 assert(
Tok.
is(tok::kw_while) &&
"Not a while stmt!");
1425 Diag(Tok, diag::err_expected_lparen_after) <<
"while";
1444 unsigned ScopeFlags;
1450 ParseScope WhileScope(
this, ScopeFlags);
1454 if (ParseParenExprOrCondition(
nullptr, Cond, WhileLoc,
1455 Sema::ConditionKind::Boolean))
1472 StmtResult Body(ParseStatement(TrailingElseLoc));
1478 if (Cond.
isInvalid() || Body.isInvalid())
1481 return Actions.ActOnWhileStmt(WhileLoc, Cond, Body.
get());
1489 assert(
Tok.
is(tok::kw_do) &&
"Not a do stmt!");
1494 unsigned ScopeFlags;
1500 ParseScope DoScope(
this, ScopeFlags);
1520 if (!Body.isInvalid()) {
1521 Diag(Tok, diag::err_expected_while);
1522 Diag(DoLoc, diag::note_matching) <<
"'do'";
1530 Diag(Tok, diag::err_expected_lparen_after) <<
"do/while";
1540 DiagnoseAndSkipCXX11Attributes();
1545 Cond = Actions.CorrectDelayedTyposInExpr(Cond);
1549 if (Cond.
isInvalid() || Body.isInvalid())
1552 return Actions.ActOnDoStmt(DoLoc, Body.get(), WhileLoc, T.getOpenLocation(),
1553 Cond.
get(), T.getCloseLocation());
1556 bool Parser::isForRangeIdentifier() {
1557 assert(
Tok.
is(tok::identifier));
1560 if (Next.is(tok::colon))
1563 if (Next.isOneOf(tok::l_square, tok::kw_alignas)) {
1564 TentativeParsingAction PA(*
this);
1566 SkipCXX11Attributes();
1598 assert(
Tok.
is(tok::kw_for) &&
"Not a for stmt!");
1602 if (
Tok.
is(tok::kw_co_await))
1606 Diag(Tok, diag::err_expected_lparen_after) <<
"for";
1629 unsigned ScopeFlags = 0;
1633 ParseScope ForScope(
this, ScopeFlags);
1640 bool ForEach =
false;
1644 ForRangeInfo ForRangeInfo;
1647 if (
Tok.
is(tok::code_completion)) {
1655 ParsedAttributesWithRange attrs(AttrFactory);
1656 MaybeParseCXX11Attributes(attrs);
1661 if (
Tok.
is(tok::semi)) {
1662 ProhibitAttributes(attrs);
1665 if (!
Tok.hasLeadingEmptyMacro() && !SemiLoc.
isMacroID())
1666 EmptyInitStmtSemiLoc = SemiLoc;
1669 isForRangeIdentifier()) {
1670 ProhibitAttributes(attrs);
1673 MaybeParseCXX11Attributes(attrs);
1676 if (
Tok.
is(tok::l_brace))
1677 ForRangeInfo.RangeExpr = ParseBraceInitializer();
1681 Diag(Loc, diag::err_for_range_identifier)
1686 ForRangeInfo.LoopVar = Actions.ActOnCXXForRangeIdentifier(
1687 getCurScope(), Loc, Name, attrs, attrs.Range.getEnd());
1688 }
else if (isForInitDeclaration()) {
1692 if (!C99orCXXorObjC) {
1693 Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
1694 Diag(Tok, diag::warn_gcc_variable_decl_in_for_loop);
1698 bool MightBeForRangeStmt =
getLangOpts().CPlusPlus;
1704 MightBeForRangeStmt ? &ForRangeInfo :
nullptr);
1705 FirstPart = Actions.ActOnDeclStmt(DG, DeclStart,
Tok.getLocation());
1706 if (ForRangeInfo.ParsedForRangeDecl()) {
1708 diag::warn_cxx98_compat_for_range : diag::ext_for_range);
1709 ForRangeInfo.LoopVar = FirstPart;
1711 }
else if (
Tok.
is(tok::semi)) {
1713 }
else if ((ForEach = isTokIdentifier_in())) {
1714 Actions.ActOnForEachDeclStmt(DG);
1718 if (
Tok.
is(tok::code_completion)) {
1719 Actions.CodeCompleteObjCForCollection(
getCurScope(), DG);
1725 Diag(Tok, diag::err_expected_semi_for);
1728 ProhibitAttributes(attrs);
1731 ForEach = isTokIdentifier_in();
1736 FirstPart = Actions.ActOnForEachLValueExpr(Value.
get());
1743 bool IsRangeBasedFor =
1745 FirstPart = Actions.ActOnExprStmt(Value, !IsRangeBasedFor);
1749 if (
Tok.
is(tok::semi)) {
1751 }
else if (ForEach) {
1754 if (
Tok.
is(tok::code_completion)) {
1755 Actions.CodeCompleteObjCForCollection(
getCurScope(),
nullptr);
1763 Diag(Tok, diag::err_for_range_expected_decl)
1764 << FirstPart.get()->getSourceRange();
1769 Diag(Tok, diag::err_expected_semi_for);
1773 if (
Tok.
is(tok::semi))
1781 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl() &&
1784 if (
Tok.
is(tok::semi)) {
1786 }
else if (
Tok.
is(tok::r_paren)) {
1792 bool MightBeForRangeStmt = !ForRangeInfo.ParsedForRangeDecl();
1795 ParseCXXCondition(
nullptr, ForLoc, Sema::ConditionKind::Boolean,
1796 MightBeForRangeStmt ? &ForRangeInfo :
nullptr);
1798 if (ForRangeInfo.ParsedForRangeDecl()) {
1799 Diag(FirstPart.get() ? FirstPart.get()->getBeginLoc()
1800 : ForRangeInfo.ColonLoc,
1802 ? diag::warn_cxx17_compat_for_range_init_stmt
1803 : diag::ext_for_range_init_stmt)
1804 << (FirstPart.get() ? FirstPart.get()->getSourceRange()
1806 if (EmptyInitStmtSemiLoc.
isValid()) {
1807 Diag(EmptyInitStmtSemiLoc, diag::warn_empty_init_statement)
1825 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl()) {
1828 Diag(Tok, diag::err_expected_semi_for);
1834 if (
Tok.
is(tok::semi)) {
1842 ThirdPart = Actions.MakeFullDiscardedValueExpr(Third.
get());
1850 if (CoawaitLoc.
isValid() && !ForRangeInfo.ParsedForRangeDecl()) {
1851 Diag(CoawaitLoc, diag::err_for_co_await_not_range_for);
1861 if (ForRangeInfo.ParsedForRangeDecl()) {
1863 Actions.CorrectDelayedTyposInExpr(ForRangeInfo.RangeExpr.get());
1864 ForRangeStmt = Actions.ActOnCXXForRangeStmt(
1865 getCurScope(), ForLoc, CoawaitLoc, FirstPart.get(),
1866 ForRangeInfo.LoopVar.get(), ForRangeInfo.ColonLoc, CorrectedRange.
get(),
1871 }
else if (ForEach) {
1872 ForEachStmt = Actions.ActOnObjCForCollectionStmt(ForLoc,
1875 T.getCloseLocation());
1879 if (
getLangOpts().OpenMP && FirstPart.isUsable()) {
1880 Actions.ActOnOpenMPLoopInitialization(ForLoc, FirstPart.get());
1896 Tok.
is(tok::l_brace));
1906 StmtResult Body(ParseStatement(TrailingElseLoc));
1914 if (Body.isInvalid())
1918 return Actions.FinishObjCForCollectionStmt(ForEachStmt.get(),
1921 if (ForRangeInfo.ParsedForRangeDecl())
1922 return Actions.FinishCXXForRangeStmt(ForRangeStmt.get(), Body.get());
1924 return Actions.ActOnForStmt(ForLoc, T.getOpenLocation(), FirstPart.get(),
1925 SecondPart, ThirdPart, T.getCloseLocation(),
1937 assert(
Tok.
is(tok::kw_goto) &&
"Not a goto stmt!");
1941 if (
Tok.
is(tok::identifier)) {
1942 LabelDecl *LD = Actions.LookupOrCreateLabel(
Tok.getIdentifierInfo(),
1944 Res = Actions.ActOnGotoStmt(GotoLoc,
Tok.getLocation(), LD);
1946 }
else if (
Tok.
is(tok::star)) {
1948 Diag(Tok, diag::ext_gnu_indirect_goto);
1951 if (R.isInvalid()) {
1955 Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.get());
1957 Diag(Tok, diag::err_expected) << tok::identifier;
1970 StmtResult Parser::ParseContinueStatement() {
1972 return Actions.ActOnContinueStmt(ContinueLoc,
getCurScope());
1983 return Actions.ActOnBreakStmt(BreakLoc,
getCurScope());
1993 assert((
Tok.
is(tok::kw_return) ||
Tok.
is(tok::kw_co_return)) &&
1994 "Not a return stmt!");
1995 bool IsCoreturn =
Tok.
is(tok::kw_co_return);
2001 PreferredType.enterReturn(Actions,
Tok.getLocation());
2003 if (
Tok.
is(tok::code_completion) && !IsCoreturn) {
2005 PreferredType.get(
Tok.getLocation()));
2011 R = ParseInitializer();
2015 ? diag::warn_cxx98_compat_generalized_initializer_lists
2016 : diag::ext_generalized_initializer_lists)
2017 << R.
get()->getSourceRange();
2026 return Actions.ActOnCoreturnStmt(
getCurScope(), ReturnLoc, R.
get());
2027 return Actions.ActOnReturnStmt(ReturnLoc, R.
get(),
getCurScope());
2030 StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
2031 ParsedStmtContext StmtCtx,
2033 ParsedAttributesWithRange &Attrs) {
2035 ParsedAttributesWithRange TempAttrs(AttrFactory);
2038 while (
Tok.
is(tok::annot_pragma_loop_hint)) {
2040 if (!HandlePragmaLoopHint(Hint))
2051 MaybeParseCXX11Attributes(Attrs);
2053 StmtResult S = ParseStatementOrDeclarationAfterAttributes(
2054 Stmts, StmtCtx, TrailingElseLoc, Attrs);
2056 Attrs.takeAllFrom(TempAttrs);
2060 Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) {
2061 assert(
Tok.
is(tok::l_brace));
2065 "parsing function body");
2069 getLangOpts().CPlusPlus && Decl && isa<CXXMethodDecl>(Decl);
2071 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2076 StmtResult FnBody(ParseCompoundStatementBody());
2079 if (FnBody.isInvalid()) {
2081 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc,
None,
false);
2085 return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
2093 Decl *Parser::ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope) {
2094 assert(
Tok.
is(tok::kw_try) &&
"Expected 'try'");
2098 "parsing function try block");
2101 if (
Tok.
is(tok::colon))
2102 ParseConstructorInitializer(Decl);
2104 Actions.ActOnDefaultCtorInitializers(Decl);
2108 getLangOpts().CPlusPlus && Decl && isa<CXXMethodDecl>(Decl);
2110 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2113 StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc,
true));
2116 if (FnBody.isInvalid()) {
2118 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc,
None,
false);
2122 return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
2125 bool Parser::trySkippingFunctionBody() {
2126 assert(SkipFunctionBodies &&
2127 "Should only be called when SkipFunctionBodies is enabled");
2128 if (!PP.isCodeCompletionEnabled()) {
2135 TentativeParsingAction PA(*
this);
2136 bool IsTryCatch =
Tok.
is(tok::kw_try);
2138 bool ErrorInPrologue = ConsumeAndStoreFunctionPrologue(Toks);
2139 if (llvm::any_of(Toks, [](
const Token &Tok) {
2140 return Tok.
is(tok::code_completion);
2145 if (ErrorInPrologue) {
2154 while (IsTryCatch && Tok.
is(tok::kw_catch)) {
2171 assert(Tok.
is(tok::kw_try) &&
"Expected 'try'");
2174 return ParseCXXTryBlockCommon(TryLoc);
2194 if (Tok.
isNot(tok::l_brace))
2195 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2201 if (TryBlock.isInvalid())
2206 if ((Tok.
is(tok::identifier) &&
2208 Tok.
is(tok::kw___finally)) {
2213 Handler = ParseSEHExceptBlock(Loc);
2217 Handler = ParseSEHFinallyBlock(Loc);
2219 if(Handler.isInvalid())
2222 return Actions.ActOnSEHTryBlock(
true ,
2228 StmtVector Handlers;
2232 DiagnoseAndSkipCXX11Attributes();
2234 if (Tok.
isNot(tok::kw_catch))
2236 while (Tok.
is(tok::kw_catch)) {
2237 StmtResult Handler(ParseCXXCatchBlock(FnTry));
2238 if (!Handler.isInvalid())
2239 Handlers.push_back(Handler.get());
2243 if (Handlers.empty())
2246 return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.get(), Handlers);
2260 StmtResult Parser::ParseCXXCatchBlock(
bool FnCatch) {
2261 assert(Tok.
is(tok::kw_catch) &&
"Expected 'catch'");
2266 if (T.expectAndConsume())
2278 Decl *ExceptionDecl =
nullptr;
2279 if (Tok.
isNot(tok::ellipsis)) {
2280 ParsedAttributesWithRange Attributes(AttrFactory);
2281 MaybeParseCXX11Attributes(Attributes);
2284 DS.takeAttributesFrom(Attributes);
2286 if (ParseCXXTypeSpecifierSeq(DS))
2290 ParseDeclarator(ExDecl);
2291 ExceptionDecl = Actions.ActOnExceptionDeclarator(
getCurScope(), ExDecl);
2296 if (T.getCloseLocation().isInvalid())
2299 if (Tok.
isNot(tok::l_brace))
2300 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2304 if (Block.isInvalid())
2307 return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl, Block.get());
2310 void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
2311 IfExistsCondition
Result;
2312 if (ParseMicrosoftIfExistsCondition(Result))
2319 if (Result.Behavior == IEB_Dependent) {
2320 if (!Tok.
is(tok::l_brace)) {
2321 Diag(Tok, diag::err_expected) << tok::l_brace;
2325 StmtResult Compound = ParseCompoundStatement();
2326 if (Compound.isInvalid())
2329 StmtResult DepResult = Actions.ActOnMSDependentExistsStmt(Result.KeywordLoc,
2334 if (DepResult.isUsable())
2335 Stmts.push_back(DepResult.get());
2340 if (Braces.consumeOpen()) {
2341 Diag(Tok, diag::err_expected) << tok::l_brace;
2345 switch (Result.Behavior) {
2351 llvm_unreachable(
"Dependent case handled above");
2359 while (Tok.
isNot(tok::r_brace)) {
2361 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::Compound);
2363 Stmts.push_back(R.get());
2365 Braces.consumeClose();
2369 MaybeParseGNUAttributes(Attrs);
2374 if (Attrs.
begin()->getKind() != ParsedAttr::AT_OpenCLUnrollHint)
2377 if (!(Tok.
is(tok::kw_for) || Tok.
is(tok::kw_while) || Tok.
is(tok::kw_do))) {
2378 Diag(Tok, diag::err_opencl_unroll_hint_on_non_loop);
void AddFlags(unsigned Flags)
Sets up the specified scope flags and adjusts the scope state variables accordingly.
IdentifierLoc * PragmaNameLoc
This is the scope of a C++ try statement.
Sema::FullExprArg FullExprArg
ExprResult ParseExpression(TypeCastState isTypeCast=NotTypeCast)
Simple precedence-based parser for binary/ternary operators.
Simple class containing the result of Sema::CorrectTypo.
llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion
A union of the various pointer types that can be passed to an ParsedAttr as an argument.
static ConditionResult ConditionError()
Stmt - This represents one statement.
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)) {...
Decl - This represents one declaration (or definition), e.g.
Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...
This is a while, do, switch, for, etc that can have break statements embedded into it...
Represent a C++ namespace.
RAII object that enters a new expression evaluation context.
Represents a variable declaration or definition.
ActionResult< Stmt * > StmtResult
Information about one declarator, including the parsed type information and the identifier.
IdentifierLoc * OptionLoc
Records and restores the FP_CONTRACT state on entry/exit of compound statements.
NestedNameSpecifier * getCorrectionSpecifier() const
Gets the NestedNameSpecifier needed to use the typo correction.
DeclClass * getCorrectionDeclAs() const
RAII object that makes sure paren/bracket/brace count is correct after declaration/statement parsing...
ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and restores it when destroyed...
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 ...
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
bool TryConsumeToken(tok::TokenKind Expected)
One of these records is kept for each identifier that is lexed.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
Represents a member of a struct/union/class.
void decrementMSManglingNumber()
Token - This structure provides full information about a lexed token.
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ...
std::pair< VarDecl *, Expr * > get() const
The controlling scope in a if/switch/while/for statement.
This is a scope that corresponds to a switch statement.
This is a while, do, for, which can have continue statements embedded into it.
Code completion occurs within an expression.
If a crash happens while one of these objects are live, the message is printed out along with the spe...
The current expression occurs within a discarded statement.
llvm::Optional< bool > getKnownValue() const
A RAII object to enter scope of a compound statement.
virtual bool ValidateCandidate(const TypoCorrection &candidate)
Simple predicate used by the default RankCandidate to determine whether to return an edit distance of...
This represents one expression.
This scope corresponds to an SEH try.
This file defines the classes used to store parsed information about declaration-specifiers and decla...
void SkipMalformedDecl()
SkipMalformedDecl - Read tokens until we get to some likely good stopping point for skipping past a s...
This scope corresponds to an SEH except.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
Initial building of a for-range statement.
This is a compound statement scope.
Code completion occurs within a statement, which may also be an expression or a declaration.
A boolean condition, from 'if', 'while', 'for', or 'do'.
The result type of a method or function.
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
PrettyDeclStackTraceEntry - If a crash occurs in the parser while parsing something related to a decl...
const LangOptions & getLangOpts() const
Stop skipping at semicolon.
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
Encodes a location in the source.
IdentifierInfo * getIdentifierInfo() const
Represents the declaration of a label.
ExtensionRAIIObject - This saves the state of extension warnings when constructed and disables them...
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
Scope * getCurScope() const
We are currently in the filter expression of an SEH except block.
bool isNot(tok::TokenKind K) const
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
ExprResult ParseCaseExpression(SourceLocation CaseLoc)
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
A constant boolean condition from 'if constexpr'.
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
This is the scope for a function-level C++ try or catch scope.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
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.
This is a scope that can contain a declaration.
StmtResult ProcessStmtAttributes(Stmt *Stmt, const ParsedAttributesView &Attrs, SourceRange Range)
Stmt attributes - this routine is the top level dispatcher.
An integral condition for a 'switch' statement.
Captures information about "declaration specifiers".
Code completion occurs at the beginning of the initialization statement (or expression) in a for loop...
bool isSwitchScope() const
isSwitchScope - Return true if this scope is a switch scope.
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
Loop optimization hint for loop and unroll pragmas.
A trivial tuple used to represent a source range.
This is the scope of a C++ catch statement.
ParsedAttributes - A collection of parsed attributes.
SourceLocation ColonLoc
Location of ':'.
An RAII object for [un]poisoning an identifier within a scope.
Stop skipping at specified token, but don't skip the token itself.