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 std::make_unique<StatementFilterCCC>(*this);
151 StmtResult Parser::ParseStatementOrDeclarationAfterAttributes(
152 StmtVector &Stmts, ParsedStmtContext StmtCtx,
153 SourceLocation *TrailingElseLoc, ParsedAttributesWithRange &Attrs) {
154 const char *SemiError =
nullptr;
167 ProhibitAttributes(Attrs);
169 return ParseObjCAtStatement(AtLoc, StmtCtx);
172 case tok::code_completion:
177 case tok::identifier: {
179 if (Next.
is(tok::colon)) {
181 return ParseLabeledStatement(Attrs, StmtCtx);
186 if (Next.
isNot(tok::coloncolon)) {
189 StatementFilterCCC CCC(Next);
190 if (TryAnnotateName(&CCC) == ANK_Error) {
194 if (
Tok.
is(tok::semi))
210 (StmtCtx & ParsedStmtContext::AllowDeclarationsInC) !=
211 ParsedStmtContext()) &&
212 (GNUAttributeLoc.
isValid() || isDeclarationStatement())) {
215 if (GNUAttributeLoc.
isValid()) {
216 DeclStart = GNUAttributeLoc;
223 if (Attrs.Range.getBegin().isValid())
224 DeclStart = Attrs.Range.getBegin();
225 return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
228 if (
Tok.
is(tok::r_brace)) {
229 Diag(Tok, diag::err_expected_statement);
233 return ParseExprStatement(StmtCtx);
236 case tok::kw___attribute: {
237 GNUAttributeLoc =
Tok.getLocation();
238 ParseGNUAttributes(Attrs);
243 return ParseCaseStatement(StmtCtx);
244 case tok::kw_default:
245 return ParseDefaultStatement(StmtCtx);
248 return ParseCompoundStatement();
250 bool HasLeadingEmptyMacro =
Tok.hasLeadingEmptyMacro();
251 return Actions.ActOnNullStmt(
ConsumeToken(), HasLeadingEmptyMacro);
255 return ParseIfStatement(TrailingElseLoc);
257 return ParseSwitchStatement(TrailingElseLoc);
260 return ParseWhileStatement(TrailingElseLoc);
262 Res = ParseDoStatement();
263 SemiError =
"do/while";
266 return ParseForStatement(TrailingElseLoc);
269 Res = ParseGotoStatement();
272 case tok::kw_continue:
273 Res = ParseContinueStatement();
274 SemiError =
"continue";
277 Res = ParseBreakStatement();
281 Res = ParseReturnStatement();
282 SemiError =
"return";
284 case tok::kw_co_return:
285 Res = ParseReturnStatement();
286 SemiError =
"co_return";
290 ProhibitAttributes(Attrs);
292 Res = ParseAsmStatement(msAsm);
293 Res = Actions.ActOnFinishFullStmt(Res.get());
294 if (msAsm)
return Res;
299 case tok::kw___if_exists:
300 case tok::kw___if_not_exists:
301 ProhibitAttributes(Attrs);
302 ParseMicrosoftIfExistsStatement(Stmts);
308 return ParseCXXTryBlock();
311 ProhibitAttributes(Attrs);
312 return ParseSEHTryBlock();
314 case tok::kw___leave:
315 Res = ParseSEHLeaveStatement();
316 SemiError =
"__leave";
319 case tok::annot_pragma_vis:
320 ProhibitAttributes(Attrs);
321 HandlePragmaVisibility();
324 case tok::annot_pragma_pack:
325 ProhibitAttributes(Attrs);
329 case tok::annot_pragma_msstruct:
330 ProhibitAttributes(Attrs);
331 HandlePragmaMSStruct();
334 case tok::annot_pragma_align:
335 ProhibitAttributes(Attrs);
339 case tok::annot_pragma_weak:
340 ProhibitAttributes(Attrs);
344 case tok::annot_pragma_weakalias:
345 ProhibitAttributes(Attrs);
346 HandlePragmaWeakAlias();
349 case tok::annot_pragma_redefine_extname:
350 ProhibitAttributes(Attrs);
351 HandlePragmaRedefineExtname();
354 case tok::annot_pragma_fp_contract:
355 ProhibitAttributes(Attrs);
356 Diag(Tok, diag::err_pragma_fp_contract_scope);
357 ConsumeAnnotationToken();
360 case tok::annot_pragma_fp:
361 ProhibitAttributes(Attrs);
362 Diag(Tok, diag::err_pragma_fp_scope);
363 ConsumeAnnotationToken();
366 case tok::annot_pragma_fenv_access:
367 ProhibitAttributes(Attrs);
368 HandlePragmaFEnvAccess();
371 case tok::annot_pragma_opencl_extension:
372 ProhibitAttributes(Attrs);
373 HandlePragmaOpenCLExtension();
376 case tok::annot_pragma_captured:
377 ProhibitAttributes(Attrs);
378 return HandlePragmaCaptured();
380 case tok::annot_pragma_openmp:
381 ProhibitAttributes(Attrs);
382 return ParseOpenMPDeclarativeOrExecutableDirective(StmtCtx);
384 case tok::annot_pragma_ms_pointers_to_members:
385 ProhibitAttributes(Attrs);
386 HandlePragmaMSPointersToMembers();
389 case tok::annot_pragma_ms_pragma:
390 ProhibitAttributes(Attrs);
391 HandlePragmaMSPragma();
394 case tok::annot_pragma_ms_vtordisp:
395 ProhibitAttributes(Attrs);
396 HandlePragmaMSVtorDisp();
399 case tok::annot_pragma_loop_hint:
400 ProhibitAttributes(Attrs);
401 return ParsePragmaLoopHint(Stmts, StmtCtx, TrailingElseLoc, Attrs);
403 case tok::annot_pragma_dump:
407 case tok::annot_pragma_attribute:
408 HandlePragmaAttribute();
417 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt, SemiError);
426 StmtResult Parser::ParseExprStatement(ParsedStmtContext StmtCtx) {
430 ExprStatementTokLoc =
Tok.getLocation();
434 if (
Expr.isInvalid()) {
439 if (
Tok.
is(tok::semi))
441 return Actions.ActOnExprStmtError();
445 Actions.CheckCaseExpression(
Expr.get())) {
448 Diag(OldToken, diag::err_expected_case_before_expression)
452 return ParseCaseStatement(StmtCtx,
true,
Expr);
456 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
457 return handleExprStmt(
Expr, StmtCtx);
470 assert(
Tok.
is(tok::kw___try) &&
"Expected '__try'");
474 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
479 if (TryBlock.isInvalid())
483 if (
Tok.
is(tok::identifier) &&
484 Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
486 Handler = ParseSEHExceptBlock(Loc);
487 }
else if (
Tok.
is(tok::kw___finally)) {
489 Handler = ParseSEHFinallyBlock(Loc);
494 if(Handler.isInvalid())
497 return Actions.ActOnSEHTryBlock(
false ,
510 raii2(Ident___exception_code,
false),
511 raii3(Ident_GetExceptionCode,
false);
513 if (ExpectAndConsume(tok::l_paren))
520 Ident__exception_info->setIsPoisoned(
false);
521 Ident___exception_info->setIsPoisoned(
false);
522 Ident_GetExceptionInfo->setIsPoisoned(
false);
527 ParseScopeFlags FilterScope(
this,
getCurScope()->getFlags() |
533 Ident__exception_info->setIsPoisoned(
true);
534 Ident___exception_info->setIsPoisoned(
true);
535 Ident_GetExceptionInfo->setIsPoisoned(
true);
541 if (ExpectAndConsume(tok::r_paren))
545 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
549 if(Block.isInvalid())
552 return Actions.ActOnSEHExceptBlock(ExceptLoc, FilterExpr.
get(), Block.get());
562 raii2(Ident___abnormal_termination,
false),
563 raii3(Ident_AbnormalTermination,
false);
566 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
568 ParseScope FinallyScope(
this, 0);
569 Actions.ActOnStartSEHFinallyBlock();
572 if(Block.isInvalid()) {
573 Actions.ActOnAbortSEHFinallyBlock();
577 return Actions.ActOnFinishSEHFinallyBlock(FinallyLoc, Block.get());
587 return Actions.ActOnSEHLeaveStmt(LeaveLoc,
getCurScope());
596 StmtResult Parser::ParseLabeledStatement(ParsedAttributesWithRange &attrs,
597 ParsedStmtContext StmtCtx) {
598 assert(
Tok.
is(tok::identifier) &&
Tok.getIdentifierInfo() &&
599 "Not an identifier!");
603 StmtCtx &= ~ParsedStmtContext::AllowDeclarationsInC;
608 assert(
Tok.
is(tok::colon) &&
"Not a label!");
615 if (
Tok.
is(tok::kw___attribute)) {
616 ParsedAttributesWithRange TempAttrs(AttrFactory);
617 ParseGNUAttributes(TempAttrs);
627 attrs.takeAllFrom(TempAttrs);
628 else if (isDeclarationStatement()) {
634 SubStmt = ParseStatementOrDeclarationAfterAttributes(Stmts, StmtCtx,
636 if (!TempAttrs.empty() && !SubStmt.isInvalid())
637 SubStmt = Actions.ProcessStmtAttributes(SubStmt.get(), TempAttrs,
640 Diag(Tok, diag::err_expected_after) <<
"__attribute__" << tok::semi;
645 if (!SubStmt.isInvalid() && !SubStmt.isUsable())
646 SubStmt = ParseStatement(
nullptr, StmtCtx);
649 if (SubStmt.isInvalid())
650 SubStmt = Actions.ActOnNullStmt(ColonLoc);
654 Actions.ProcessDeclAttributeList(Actions.CurScope, LD, attrs);
666 StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx,
668 assert((MissingCase ||
Tok.
is(tok::kw_case)) &&
"Not a case stmt!");
672 StmtCtx &= ~ParsedStmtContext::AllowDeclarationsInC;
695 Stmt *DeepestParsedCaseStmt =
nullptr;
704 if (
Tok.
is(tok::code_completion)) {
733 Diag(DotDotDotLoc, diag::ext_gnu_case_range);
741 ColonProtection.restore();
747 Diag(ColonLoc, diag::err_expected_after)
748 <<
"'case'" << tok::colon
751 SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation);
752 Diag(ExpectedLoc, diag::err_expected_after)
753 <<
"'case'" << tok::colon
755 ColonLoc = ExpectedLoc;
759 Actions.ActOnCaseStmt(CaseLoc, LHS, DotDotDotLoc, RHS, ColonLoc);
763 if (Case.isInvalid()) {
764 if (TopLevelCase.isInvalid())
765 return ParseStatement(
nullptr, StmtCtx);
770 Stmt *NextDeepest = Case.get();
771 if (TopLevelCase.isInvalid())
774 Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, Case.get());
775 DeepestParsedCaseStmt = NextDeepest;
779 }
while (
Tok.
is(tok::kw_case));
785 SubStmt = ParseStatement(
nullptr, StmtCtx);
792 Diag(AfterColonLoc, diag::err_label_end_of_compound_statement)
799 if (DeepestParsedCaseStmt) {
801 if (SubStmt.isInvalid())
803 Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, SubStmt.get());
815 StmtResult Parser::ParseDefaultStatement(ParsedStmtContext StmtCtx) {
816 assert(
Tok.
is(tok::kw_default) &&
"Not a default stmt!");
820 StmtCtx &= ~ParsedStmtContext::AllowDeclarationsInC;
828 Diag(ColonLoc, diag::err_expected_after)
829 <<
"'default'" << tok::colon
832 SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation);
833 Diag(ExpectedLoc, diag::err_expected_after)
834 <<
"'default'" << tok::colon
836 ColonLoc = ExpectedLoc;
842 SubStmt = ParseStatement(
nullptr, StmtCtx);
847 Diag(AfterColonLoc, diag::err_label_end_of_compound_statement)
853 if (SubStmt.isInvalid())
854 SubStmt = Actions.ActOnNullStmt(ColonLoc);
856 return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc,
860 StmtResult Parser::ParseCompoundStatement(
bool isStmtExpr) {
861 return ParseCompoundStatement(isStmtExpr,
887 StmtResult Parser::ParseCompoundStatement(
bool isStmtExpr,
888 unsigned ScopeFlags) {
889 assert(
Tok.
is(tok::l_brace) &&
"Not a compount stmt!");
893 ParseScope CompoundScope(
this, ScopeFlags);
896 return ParseCompoundStatementBody(isStmtExpr);
902 void Parser::ParseCompoundStatementLeadingPragmas() {
903 bool checkForPragmas =
true;
904 while (checkForPragmas) {
905 switch (
Tok.getKind()) {
906 case tok::annot_pragma_vis:
907 HandlePragmaVisibility();
909 case tok::annot_pragma_pack:
912 case tok::annot_pragma_msstruct:
913 HandlePragmaMSStruct();
915 case tok::annot_pragma_align:
918 case tok::annot_pragma_weak:
921 case tok::annot_pragma_weakalias:
922 HandlePragmaWeakAlias();
924 case tok::annot_pragma_redefine_extname:
925 HandlePragmaRedefineExtname();
927 case tok::annot_pragma_opencl_extension:
928 HandlePragmaOpenCLExtension();
930 case tok::annot_pragma_fp_contract:
931 HandlePragmaFPContract();
933 case tok::annot_pragma_fp:
936 case tok::annot_pragma_fenv_access:
937 HandlePragmaFEnvAccess();
939 case tok::annot_pragma_ms_pointers_to_members:
940 HandlePragmaMSPointersToMembers();
942 case tok::annot_pragma_ms_pragma:
943 HandlePragmaMSPragma();
945 case tok::annot_pragma_ms_vtordisp:
946 HandlePragmaMSVtorDisp();
948 case tok::annot_pragma_dump:
952 checkForPragmas =
false;
961 bool Parser::ConsumeNullStmt(StmtVector &Stmts) {
962 if (!
Tok.
is(tok::semi))
968 while (
Tok.
is(tok::semi) && !
Tok.hasLeadingEmptyMacro() &&
969 Tok.getLocation().isValid() && !
Tok.getLocation().isMacroID()) {
970 EndLoc =
Tok.getLocation();
974 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::SubStmt);
976 Stmts.push_back(R.get());
983 Diag(StartLoc, diag::warn_null_statement)
989 bool IsStmtExprResult =
false;
990 if ((StmtCtx & ParsedStmtContext::InStmtExpr) != ParsedStmtContext()) {
992 unsigned LookAhead = 0;
993 while (GetLookAheadToken(LookAhead).is(tok::semi)) {
999 IsStmtExprResult = GetLookAheadToken(LookAhead).is(tok::r_brace) &&
1000 GetLookAheadToken(LookAhead + 1).is(tok::r_paren);
1003 if (IsStmtExprResult)
1004 E = Actions.ActOnStmtExprResult(E);
1005 return Actions.ActOnExprStmt(E, !IsStmtExprResult);
1012 StmtResult Parser::ParseCompoundStatementBody(
bool isStmtExpr) {
1015 "in compound statement ('{}')");
1023 if (T.consumeOpen())
1029 ParseCompoundStatementLeadingPragmas();
1035 while (
Tok.
is(tok::kw___label__)) {
1041 Diag(Tok, diag::err_expected) << tok::identifier;
1047 DeclsInGroup.push_back(Actions.LookupOrCreateLabel(II, IdLoc, LabelLoc));
1055 Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, DeclsInGroup);
1056 StmtResult R = Actions.ActOnDeclStmt(Res, LabelLoc,
Tok.getLocation());
1058 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
1060 Stmts.push_back(R.get());
1063 ParsedStmtContext SubStmtCtx =
1064 ParsedStmtContext::Compound |
1065 (isStmtExpr ? ParsedStmtContext::InStmtExpr : ParsedStmtContext());
1067 while (!tryParseMisplacedModuleImport() &&
Tok.
isNot(tok::r_brace) &&
1069 if (
Tok.
is(tok::annot_pragma_unused)) {
1070 HandlePragmaUnused();
1074 if (ConsumeNullStmt(Stmts))
1078 if (
Tok.
isNot(tok::kw___extension__)) {
1079 R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
1086 while (
Tok.
is(tok::kw___extension__))
1089 ParsedAttributesWithRange attrs(AttrFactory);
1090 MaybeParseCXX11Attributes(attrs,
nullptr,
1094 if (isDeclarationStatement()) {
1102 R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);
1105 ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
1107 if (Res.isInvalid()) {
1114 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
1115 R = handleExprStmt(Res, SubStmtCtx);
1117 R = Actions.ProcessStmtAttributes(R.get(), attrs, attrs.Range);
1122 Stmts.push_back(R.get());
1128 if (!T.consumeClose())
1131 CloseLoc = T.getCloseLocation();
1133 return Actions.ActOnCompoundStmt(T.getOpenLocation(), CloseLoc,
1149 bool Parser::ParseParenExprOrCondition(
StmtResult *InitStmt,
1157 Cond = ParseCXXCondition(InitStmt, Loc, CK);
1165 Cond = Actions.ActOnCondition(
getCurScope(), Loc, CondExpr.
get(), CK);
1185 while (
Tok.
is(tok::r_paren)) {
1186 Diag(Tok, diag::err_extraneous_rparen_in_condition)
1198 struct MisleadingIndentationChecker {
1202 unsigned NumDirectives;
1214 if (Kind == MSK_else && !ShouldSkip)
1224 if (ColNo == 0 || TabStop == 1)
1230 StringRef BufData = SM.
getBufferData(FIDAndOffset.first, &Invalid);
1234 const char *EndPos = BufData.data() + FIDAndOffset.second;
1236 assert(FIDAndOffset.second + 1 >= ColNo &&
1237 "Column number smaller than file offset?");
1239 unsigned VisualColumn = 0;
1242 for (
const char *CurPos = EndPos - (ColNo - 1); CurPos != EndPos;
1244 if (*CurPos ==
'\t')
1246 VisualColumn += (TabStop - VisualColumn % TabStop);
1250 return VisualColumn + 1;
1256 diag::warn_misleading_indentation, Tok.
getLocation()) ||
1265 if (Kind == MSK_else)
1269 unsigned PrevColNum = getVisualIndentation(SM, PrevLoc);
1270 unsigned CurColNum = getVisualIndentation(SM, Tok.
getLocation());
1271 unsigned StmtColNum = getVisualIndentation(SM, StmtLoc);
1273 if (PrevColNum != 0 && CurColNum != 0 && StmtColNum != 0 &&
1274 ((PrevColNum > StmtColNum && PrevColNum == CurColNum) ||
1278 (Tok.
isNot(tok::identifier) ||
1281 P.
Diag(StmtLoc, diag::note_previous_statement);
1296 assert(Tok.
is(tok::kw_if) &&
"Not an if stmt!");
1299 bool IsConstexpr =
false;
1300 if (Tok.
is(tok::kw_constexpr)) {
1302 : diag::ext_constexpr_if);
1307 if (Tok.
isNot(tok::l_paren)) {
1308 Diag(Tok, diag::err_expected_lparen_after) <<
"if";
1332 if (ParseParenExprOrCondition(&InitStmt, Cond, IfLoc,
1361 MisleadingIndentationChecker MIChecker(*
this, MSK_if, IfLoc);
1372 ConstexprCondition && !*ConstexprCondition);
1373 ThenStmt = ParseStatement(&InnerStatementTrailingElseLoc);
1376 if (Tok.
isNot(tok::kw_else))
1387 if (Tok.
is(tok::kw_else)) {
1388 if (TrailingElseLoc)
1389 *TrailingElseLoc = Tok.getLocation();
1392 ElseStmtLoc = Tok.getLocation();
1404 Tok.
is(tok::l_brace));
1406 MisleadingIndentationChecker MIChecker(*
this, MSK_else, ElseLoc);
1411 ConstexprCondition && *ConstexprCondition);
1412 ElseStmt = ParseStatement();
1414 if (ElseStmt.isUsable())
1419 }
else if (Tok.
is(tok::code_completion)) {
1423 }
else if (InnerStatementTrailingElseLoc.
isValid()) {
1424 Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else);
1432 if ((ThenStmt.isInvalid() && ElseStmt.isInvalid()) ||
1433 (ThenStmt.isInvalid() && ElseStmt.get() ==
nullptr) ||
1434 (ThenStmt.get() ==
nullptr && ElseStmt.isInvalid())) {
1440 if (ThenStmt.isInvalid())
1441 ThenStmt = Actions.ActOnNullStmt(ThenStmtLoc);
1442 if (ElseStmt.isInvalid())
1443 ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);
1445 return Actions.ActOnIfStmt(IfLoc, IsConstexpr, InitStmt.get(), Cond,
1446 ThenStmt.
get(), ElseLoc, ElseStmt.get());
1454 assert(Tok.
is(tok::kw_switch) &&
"Not a switch stmt!");
1457 if (Tok.
isNot(tok::l_paren)) {
1458 Diag(Tok, diag::err_expected_lparen_after) <<
"switch";
1480 ParseScope SwitchScope(
this, ScopeFlags);
1485 if (ParseParenExprOrCondition(&InitStmt, Cond, SwitchLoc,
1490 Actions.ActOnStartOfSwitchStmt(SwitchLoc, InitStmt.get(), Cond);
1492 if (Switch.isInvalid()) {
1497 if (Tok.
is(tok::l_brace)) {
1525 StmtResult Body(ParseStatement(TrailingElseLoc));
1531 return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.get(), Body.get());
1539 assert(Tok.
is(tok::kw_while) &&
"Not a while stmt!");
1543 if (Tok.
isNot(tok::l_paren)) {
1544 Diag(Tok, diag::err_expected_lparen_after) <<
"while";
1563 unsigned ScopeFlags;
1569 ParseScope WhileScope(
this, ScopeFlags);
1573 if (ParseParenExprOrCondition(
nullptr, Cond, WhileLoc,
1590 MisleadingIndentationChecker MIChecker(*
this, MSK_while, WhileLoc);
1593 StmtResult Body(ParseStatement(TrailingElseLoc));
1595 if (Body.isUsable())
1601 if (Cond.
isInvalid() || Body.isInvalid())
1604 return Actions.ActOnWhileStmt(WhileLoc, Cond, Body.
get());
1612 assert(Tok.
is(tok::kw_do) &&
"Not a do stmt!");
1617 unsigned ScopeFlags;
1623 ParseScope DoScope(
this, ScopeFlags);
1642 if (Tok.
isNot(tok::kw_while)) {
1643 if (!Body.isInvalid()) {
1644 Diag(Tok, diag::err_expected_while);
1645 Diag(DoLoc, diag::note_matching) <<
"'do'";
1652 if (Tok.
isNot(tok::l_paren)) {
1653 Diag(Tok, diag::err_expected_lparen_after) <<
"do/while";
1663 DiagnoseAndSkipCXX11Attributes();
1668 Cond = Actions.CorrectDelayedTyposInExpr(Cond);
1672 if (Cond.
isInvalid() || Body.isInvalid())
1675 return Actions.ActOnDoStmt(DoLoc, Body.get(), WhileLoc, T.
getOpenLocation(),
1679 bool Parser::isForRangeIdentifier() {
1680 assert(Tok.
is(tok::identifier));
1683 if (Next.is(tok::colon))
1686 if (Next.isOneOf(tok::l_square, tok::kw_alignas)) {
1687 TentativeParsingAction PA(*
this);
1689 SkipCXX11Attributes();
1721 assert(Tok.
is(tok::kw_for) &&
"Not a for stmt!");
1725 if (Tok.
is(tok::kw_co_await))
1728 if (Tok.
isNot(tok::l_paren)) {
1729 Diag(Tok, diag::err_expected_lparen_after) <<
"for";
1752 unsigned ScopeFlags = 0;
1756 ParseScope ForScope(
this, ScopeFlags);
1763 bool ForEach =
false;
1767 ForRangeInfo ForRangeInfo;
1770 if (Tok.
is(tok::code_completion)) {
1778 ParsedAttributesWithRange attrs(AttrFactory);
1779 MaybeParseCXX11Attributes(attrs);
1784 if (Tok.
is(tok::semi)) {
1785 ProhibitAttributes(attrs);
1788 if (!Tok.hasLeadingEmptyMacro() && !SemiLoc.
isMacroID())
1789 EmptyInitStmtSemiLoc = SemiLoc;
1792 isForRangeIdentifier()) {
1793 ProhibitAttributes(attrs);
1796 MaybeParseCXX11Attributes(attrs);
1799 if (Tok.
is(tok::l_brace))
1800 ForRangeInfo.RangeExpr = ParseBraceInitializer();
1804 Diag(Loc, diag::err_for_range_identifier)
1809 ForRangeInfo.LoopVar = Actions.ActOnCXXForRangeIdentifier(
1810 getCurScope(), Loc, Name, attrs, attrs.Range.getEnd());
1811 }
else if (isForInitDeclaration()) {
1815 if (!C99orCXXorObjC) {
1816 Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
1817 Diag(Tok, diag::warn_gcc_variable_decl_in_for_loop);
1821 bool MightBeForRangeStmt =
getLangOpts().CPlusPlus;
1827 MightBeForRangeStmt ? &ForRangeInfo :
nullptr);
1828 FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
1829 if (ForRangeInfo.ParsedForRangeDecl()) {
1831 diag::warn_cxx98_compat_for_range : diag::ext_for_range);
1832 ForRangeInfo.LoopVar = FirstPart;
1834 }
else if (Tok.
is(tok::semi)) {
1836 }
else if ((ForEach = isTokIdentifier_in())) {
1837 Actions.ActOnForEachDeclStmt(DG);
1841 if (Tok.
is(tok::code_completion)) {
1842 Actions.CodeCompleteObjCForCollection(
getCurScope(), DG);
1848 Diag(Tok, diag::err_expected_semi_for);
1851 ProhibitAttributes(attrs);
1854 ForEach = isTokIdentifier_in();
1859 FirstPart = Actions.ActOnForEachLValueExpr(Value.
get());
1866 bool IsRangeBasedFor =
1867 getLangOpts().CPlusPlus11 && !ForEach && Tok.
is(tok::colon);
1868 FirstPart = Actions.ActOnExprStmt(Value, !IsRangeBasedFor);
1872 if (Tok.
is(tok::semi)) {
1874 }
else if (ForEach) {
1877 if (Tok.
is(tok::code_completion)) {
1878 Actions.CodeCompleteObjCForCollection(
getCurScope(),
nullptr);
1886 Diag(Tok, diag::err_for_range_expected_decl)
1887 << FirstPart.get()->getSourceRange();
1892 Diag(Tok, diag::err_expected_semi_for);
1896 if (Tok.
is(tok::semi))
1904 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl() &&
1907 if (Tok.
is(tok::semi)) {
1909 }
else if (Tok.
is(tok::r_paren)) {
1915 bool MightBeForRangeStmt = !ForRangeInfo.ParsedForRangeDecl();
1919 MightBeForRangeStmt ? &ForRangeInfo :
nullptr);
1921 if (ForRangeInfo.ParsedForRangeDecl()) {
1922 Diag(FirstPart.get() ? FirstPart.get()->getBeginLoc()
1923 : ForRangeInfo.ColonLoc,
1925 ? diag::warn_cxx17_compat_for_range_init_stmt
1926 : diag::ext_for_range_init_stmt)
1927 << (FirstPart.get() ? FirstPart.get()->getSourceRange()
1929 if (EmptyInitStmtSemiLoc.
isValid()) {
1930 Diag(EmptyInitStmtSemiLoc, diag::warn_empty_init_statement)
1948 if (!ForEach && !ForRangeInfo.ParsedForRangeDecl()) {
1949 if (Tok.
isNot(tok::semi)) {
1951 Diag(Tok, diag::err_expected_semi_for);
1957 if (Tok.
is(tok::semi)) {
1961 if (Tok.
isNot(tok::r_paren)) {
1965 ThirdPart = Actions.MakeFullDiscardedValueExpr(Third.
get());
1973 if (CoawaitLoc.
isValid() && !ForRangeInfo.ParsedForRangeDecl()) {
1974 Diag(CoawaitLoc, diag::err_for_co_await_not_range_for);
1984 if (ForRangeInfo.ParsedForRangeDecl()) {
1986 Actions.CorrectDelayedTyposInExpr(ForRangeInfo.RangeExpr.get());
1987 ForRangeStmt = Actions.ActOnCXXForRangeStmt(
1988 getCurScope(), ForLoc, CoawaitLoc, FirstPart.get(),
1989 ForRangeInfo.LoopVar.get(), ForRangeInfo.ColonLoc, CorrectedRange.
get(),
1994 }
else if (ForEach) {
1995 ForEachStmt = Actions.ActOnObjCForCollectionStmt(ForLoc,
2002 if (
getLangOpts().OpenMP && FirstPart.isUsable()) {
2003 Actions.ActOnOpenMPLoopInitialization(ForLoc, FirstPart.get());
2019 Tok.
is(tok::l_brace));
2028 MisleadingIndentationChecker MIChecker(*
this, MSK_for, ForLoc);
2031 StmtResult Body(ParseStatement(TrailingElseLoc));
2033 if (Body.isUsable())
2042 if (Body.isInvalid())
2046 return Actions.FinishObjCForCollectionStmt(ForEachStmt.get(),
2049 if (ForRangeInfo.ParsedForRangeDecl())
2050 return Actions.FinishCXXForRangeStmt(ForRangeStmt.get(), Body.get());
2052 return Actions.ActOnForStmt(ForLoc, T.
getOpenLocation(), FirstPart.get(),
2065 assert(Tok.
is(tok::kw_goto) &&
"Not a goto stmt!");
2069 if (Tok.
is(tok::identifier)) {
2070 LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(),
2072 Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(), LD);
2074 }
else if (Tok.
is(tok::star)) {
2076 Diag(Tok, diag::ext_gnu_indirect_goto);
2083 Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.
get());
2085 Diag(Tok, diag::err_expected) << tok::identifier;
2098 StmtResult Parser::ParseContinueStatement() {
2100 return Actions.ActOnContinueStmt(ContinueLoc,
getCurScope());
2111 return Actions.ActOnBreakStmt(BreakLoc,
getCurScope());
2121 assert((Tok.
is(tok::kw_return) || Tok.
is(tok::kw_co_return)) &&
2122 "Not a return stmt!");
2123 bool IsCoreturn = Tok.
is(tok::kw_co_return);
2127 if (Tok.
isNot(tok::semi)) {
2129 PreferredType.enterReturn(Actions, Tok.getLocation());
2131 if (Tok.
is(tok::code_completion) && !IsCoreturn) {
2133 PreferredType.get(Tok.getLocation()));
2139 R = ParseInitializer();
2143 ? diag::warn_cxx98_compat_generalized_initializer_lists
2144 : diag::ext_generalized_initializer_lists)
2145 << R.
get()->getSourceRange();
2154 return Actions.ActOnCoreturnStmt(
getCurScope(), ReturnLoc, R.
get());
2155 return Actions.ActOnReturnStmt(ReturnLoc, R.
get(),
getCurScope());
2158 StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
2159 ParsedStmtContext StmtCtx,
2161 ParsedAttributesWithRange &Attrs) {
2163 ParsedAttributesWithRange TempAttrs(AttrFactory);
2166 while (Tok.
is(tok::annot_pragma_loop_hint)) {
2168 if (!HandlePragmaLoopHint(Hint))
2179 MaybeParseCXX11Attributes(Attrs);
2181 StmtResult S = ParseStatementOrDeclarationAfterAttributes(
2182 Stmts, StmtCtx, TrailingElseLoc, Attrs);
2184 Attrs.takeAllFrom(TempAttrs);
2188 Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) {
2189 assert(Tok.
is(tok::l_brace));
2193 "parsing function body");
2197 getLangOpts().CPlusPlus && Decl && isa<CXXMethodDecl>(Decl);
2199 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2204 StmtResult FnBody(ParseCompoundStatementBody());
2207 if (FnBody.isInvalid()) {
2209 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc,
None,
false);
2213 return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
2221 Decl *Parser::ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope) {
2222 assert(Tok.
is(tok::kw_try) &&
"Expected 'try'");
2226 "parsing function try block");
2229 if (Tok.
is(tok::colon))
2230 ParseConstructorInitializer(Decl);
2232 Actions.ActOnDefaultCtorInitializers(Decl);
2236 getLangOpts().CPlusPlus && Decl && isa<CXXMethodDecl>(Decl);
2238 PragmaStackSentinel(Actions,
"InternalPragmaState", IsCXXMethod);
2241 StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc,
true));
2244 if (FnBody.isInvalid()) {
2246 FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc,
None,
false);
2250 return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
2253 bool Parser::trySkippingFunctionBody() {
2254 assert(SkipFunctionBodies &&
2255 "Should only be called when SkipFunctionBodies is enabled");
2256 if (!PP.isCodeCompletionEnabled()) {
2263 TentativeParsingAction PA(*
this);
2264 bool IsTryCatch = Tok.
is(tok::kw_try);
2266 bool ErrorInPrologue = ConsumeAndStoreFunctionPrologue(Toks);
2267 if (llvm::any_of(Toks, [](
const Token &Tok) {
2268 return Tok.
is(tok::code_completion);
2273 if (ErrorInPrologue) {
2282 while (IsTryCatch && Tok.
is(tok::kw_catch)) {
2299 assert(Tok.
is(tok::kw_try) &&
"Expected 'try'");
2302 return ParseCXXTryBlockCommon(TryLoc);
2322 if (Tok.
isNot(tok::l_brace))
2323 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2329 if (TryBlock.isInvalid())
2334 if ((Tok.
is(tok::identifier) &&
2335 Tok.getIdentifierInfo() == getSEHExceptKeyword()) ||
2336 Tok.
is(tok::kw___finally)) {
2339 if(Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
2341 Handler = ParseSEHExceptBlock(Loc);
2345 Handler = ParseSEHFinallyBlock(Loc);
2347 if(Handler.isInvalid())
2350 return Actions.ActOnSEHTryBlock(
true ,
2356 StmtVector Handlers;
2360 DiagnoseAndSkipCXX11Attributes();
2362 if (Tok.
isNot(tok::kw_catch))
2364 while (Tok.
is(tok::kw_catch)) {
2365 StmtResult Handler(ParseCXXCatchBlock(FnTry));
2366 if (!Handler.isInvalid())
2367 Handlers.push_back(Handler.get());
2371 if (Handlers.empty())
2374 return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.get(), Handlers);
2388 StmtResult Parser::ParseCXXCatchBlock(
bool FnCatch) {
2389 assert(Tok.
is(tok::kw_catch) &&
"Expected 'catch'");
2406 Decl *ExceptionDecl =
nullptr;
2407 if (Tok.
isNot(tok::ellipsis)) {
2408 ParsedAttributesWithRange Attributes(AttrFactory);
2409 MaybeParseCXX11Attributes(Attributes);
2414 if (ParseCXXTypeSpecifierSeq(DS))
2418 ParseDeclarator(ExDecl);
2419 ExceptionDecl = Actions.ActOnExceptionDeclarator(
getCurScope(), ExDecl);
2427 if (Tok.
isNot(tok::l_brace))
2428 return StmtError(
Diag(Tok, diag::err_expected) << tok::l_brace);
2432 if (Block.isInvalid())
2435 return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl, Block.get());
2438 void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
2439 IfExistsCondition
Result;
2440 if (ParseMicrosoftIfExistsCondition(Result))
2447 if (Result.Behavior == IEB_Dependent) {
2448 if (!Tok.
is(tok::l_brace)) {
2449 Diag(Tok, diag::err_expected) << tok::l_brace;
2453 StmtResult Compound = ParseCompoundStatement();
2454 if (Compound.isInvalid())
2457 StmtResult DepResult = Actions.ActOnMSDependentExistsStmt(Result.KeywordLoc,
2462 if (DepResult.isUsable())
2463 Stmts.push_back(DepResult.get());
2469 Diag(Tok, diag::err_expected) << tok::l_brace;
2473 switch (Result.Behavior) {
2479 llvm_unreachable(
"Dependent case handled above");
2487 while (Tok.
isNot(tok::r_brace)) {
2489 ParseStatementOrDeclaration(Stmts, ParsedStmtContext::Compound);
2491 Stmts.push_back(R.get());
2497 MaybeParseGNUAttributes(Attrs);
2502 if (Attrs.
begin()->getKind() != ParsedAttr::AT_OpenCLUnrollHint)
2505 if (!(Tok.
is(tok::kw_for) || Tok.
is(tok::kw_while) || Tok.
is(tok::kw_do))) {
2506 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()
const Token & LookAhead(unsigned N)
Peeks ahead N tokens and returns that token without consuming any tokens.
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...
SourceLocation getCloseLocation() const
Represent a C++ namespace.
Parser - This implements a parser for the C family of languages.
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
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...
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
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
SourceLocation MisleadingIndentationElseLoc
The location of the first statement inside an else that might have a missleading indentation.
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...
DiagnosticsEngine & getDiagnostics() const
The current expression occurs within a discarded statement.
DiagnosticsEngine & getDiagnostics() const
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...
Sema & getActions() const
void SkipMalformedDecl()
SkipMalformedDecl - Read tokens until we get to some likely good stopping point for skipping past a s...
const Token & getCurToken() const
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.
Preprocessor & getPreprocessor() const
A boolean condition, from 'if', 'while', 'for', or 'do'.
SourceLocation getOpenLocation() const
unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
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
SourceManager & getSourceManager() 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...
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
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.
unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
bool isNot(tok::TokenKind K) const
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
bool expectAndConsume(unsigned DiagID=diag::err_expected, const char *Msg="", tok::TokenKind SkipToTok=tok::unknown)
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
DiagnosticOptions & getDiagnosticOptions() const
Retrieve the diagnostic options.
This is the scope for a function-level C++ try or catch scope.
void takeAttributesFrom(ParsedAttributes &attrs)
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...
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
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 ':'.
This class handles loading and caching of source files into memory.
An RAII object for [un]poisoning an identifier within a scope.
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
Stop skipping at specified token, but don't skip the token itself.
unsigned getNumDirectives() const
Retrieve the number of Directives that have been processed by the Preprocessor.