xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/Parse/ParseStmt.cpp (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
17330f729Sjoerg //===--- ParseStmt.cpp - Statement and Block Parser -----------------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This file implements the Statement and Block portions of the Parser
107330f729Sjoerg // interface.
117330f729Sjoerg //
127330f729Sjoerg //===----------------------------------------------------------------------===//
137330f729Sjoerg 
147330f729Sjoerg #include "clang/AST/PrettyDeclStackTrace.h"
157330f729Sjoerg #include "clang/Basic/Attributes.h"
167330f729Sjoerg #include "clang/Basic/PrettyStackTrace.h"
177330f729Sjoerg #include "clang/Parse/LoopHint.h"
187330f729Sjoerg #include "clang/Parse/Parser.h"
197330f729Sjoerg #include "clang/Parse/RAIIObjectsForParser.h"
207330f729Sjoerg #include "clang/Sema/DeclSpec.h"
217330f729Sjoerg #include "clang/Sema/Scope.h"
227330f729Sjoerg #include "clang/Sema/TypoCorrection.h"
23*e038c9c4Sjoerg #include "llvm/ADT/STLExtras.h"
24*e038c9c4Sjoerg 
257330f729Sjoerg using namespace clang;
267330f729Sjoerg 
277330f729Sjoerg //===----------------------------------------------------------------------===//
287330f729Sjoerg // C99 6.8: Statements and Blocks.
297330f729Sjoerg //===----------------------------------------------------------------------===//
307330f729Sjoerg 
317330f729Sjoerg /// Parse a standalone statement (for instance, as the body of an 'if',
327330f729Sjoerg /// 'while', or 'for').
ParseStatement(SourceLocation * TrailingElseLoc,ParsedStmtContext StmtCtx)337330f729Sjoerg StmtResult Parser::ParseStatement(SourceLocation *TrailingElseLoc,
347330f729Sjoerg                                   ParsedStmtContext StmtCtx) {
357330f729Sjoerg   StmtResult Res;
367330f729Sjoerg 
377330f729Sjoerg   // We may get back a null statement if we found a #pragma. Keep going until
387330f729Sjoerg   // we get an actual statement.
397330f729Sjoerg   do {
407330f729Sjoerg     StmtVector Stmts;
417330f729Sjoerg     Res = ParseStatementOrDeclaration(Stmts, StmtCtx, TrailingElseLoc);
427330f729Sjoerg   } while (!Res.isInvalid() && !Res.get());
437330f729Sjoerg 
447330f729Sjoerg   return Res;
457330f729Sjoerg }
467330f729Sjoerg 
477330f729Sjoerg /// ParseStatementOrDeclaration - Read 'statement' or 'declaration'.
487330f729Sjoerg ///       StatementOrDeclaration:
497330f729Sjoerg ///         statement
507330f729Sjoerg ///         declaration
517330f729Sjoerg ///
527330f729Sjoerg ///       statement:
537330f729Sjoerg ///         labeled-statement
547330f729Sjoerg ///         compound-statement
557330f729Sjoerg ///         expression-statement
567330f729Sjoerg ///         selection-statement
577330f729Sjoerg ///         iteration-statement
587330f729Sjoerg ///         jump-statement
597330f729Sjoerg /// [C++]   declaration-statement
607330f729Sjoerg /// [C++]   try-block
617330f729Sjoerg /// [MS]    seh-try-block
627330f729Sjoerg /// [OBC]   objc-throw-statement
637330f729Sjoerg /// [OBC]   objc-try-catch-statement
647330f729Sjoerg /// [OBC]   objc-synchronized-statement
657330f729Sjoerg /// [GNU]   asm-statement
667330f729Sjoerg /// [OMP]   openmp-construct             [TODO]
677330f729Sjoerg ///
687330f729Sjoerg ///       labeled-statement:
697330f729Sjoerg ///         identifier ':' statement
707330f729Sjoerg ///         'case' constant-expression ':' statement
717330f729Sjoerg ///         'default' ':' statement
727330f729Sjoerg ///
737330f729Sjoerg ///       selection-statement:
747330f729Sjoerg ///         if-statement
757330f729Sjoerg ///         switch-statement
767330f729Sjoerg ///
777330f729Sjoerg ///       iteration-statement:
787330f729Sjoerg ///         while-statement
797330f729Sjoerg ///         do-statement
807330f729Sjoerg ///         for-statement
817330f729Sjoerg ///
827330f729Sjoerg ///       expression-statement:
837330f729Sjoerg ///         expression[opt] ';'
847330f729Sjoerg ///
857330f729Sjoerg ///       jump-statement:
867330f729Sjoerg ///         'goto' identifier ';'
877330f729Sjoerg ///         'continue' ';'
887330f729Sjoerg ///         'break' ';'
897330f729Sjoerg ///         'return' expression[opt] ';'
907330f729Sjoerg /// [GNU]   'goto' '*' expression ';'
917330f729Sjoerg ///
927330f729Sjoerg /// [OBC] objc-throw-statement:
937330f729Sjoerg /// [OBC]   '@' 'throw' expression ';'
947330f729Sjoerg /// [OBC]   '@' 'throw' ';'
957330f729Sjoerg ///
967330f729Sjoerg StmtResult
ParseStatementOrDeclaration(StmtVector & Stmts,ParsedStmtContext StmtCtx,SourceLocation * TrailingElseLoc)977330f729Sjoerg Parser::ParseStatementOrDeclaration(StmtVector &Stmts,
987330f729Sjoerg                                     ParsedStmtContext StmtCtx,
997330f729Sjoerg                                     SourceLocation *TrailingElseLoc) {
1007330f729Sjoerg 
1017330f729Sjoerg   ParenBraceBracketBalancer BalancerRAIIObj(*this);
1027330f729Sjoerg 
103*e038c9c4Sjoerg   // Because we're parsing either a statement or a declaration, the order of
104*e038c9c4Sjoerg   // attribute parsing is important. [[]] attributes at the start of a
105*e038c9c4Sjoerg   // statement are different from [[]] attributes that follow an __attribute__
106*e038c9c4Sjoerg   // at the start of the statement. Thus, we're not using MaybeParseAttributes
107*e038c9c4Sjoerg   // here because we don't want to allow arbitrary orderings.
1087330f729Sjoerg   ParsedAttributesWithRange Attrs(AttrFactory);
1097330f729Sjoerg   MaybeParseCXX11Attributes(Attrs, nullptr, /*MightBeObjCMessageSend*/ true);
110*e038c9c4Sjoerg   if (getLangOpts().OpenCL)
111*e038c9c4Sjoerg     MaybeParseGNUAttributes(Attrs);
1127330f729Sjoerg 
1137330f729Sjoerg   StmtResult Res = ParseStatementOrDeclarationAfterAttributes(
1147330f729Sjoerg       Stmts, StmtCtx, TrailingElseLoc, Attrs);
115*e038c9c4Sjoerg   MaybeDestroyTemplateIds();
1167330f729Sjoerg 
1177330f729Sjoerg   assert((Attrs.empty() || Res.isInvalid() || Res.isUsable()) &&
1187330f729Sjoerg          "attributes on empty statement");
1197330f729Sjoerg 
1207330f729Sjoerg   if (Attrs.empty() || Res.isInvalid())
1217330f729Sjoerg     return Res;
1227330f729Sjoerg 
123*e038c9c4Sjoerg   return Actions.ActOnAttributedStmt(Attrs, Res.get());
1247330f729Sjoerg }
1257330f729Sjoerg 
1267330f729Sjoerg namespace {
1277330f729Sjoerg class StatementFilterCCC final : public CorrectionCandidateCallback {
1287330f729Sjoerg public:
StatementFilterCCC(Token nextTok)1297330f729Sjoerg   StatementFilterCCC(Token nextTok) : NextToken(nextTok) {
1307330f729Sjoerg     WantTypeSpecifiers = nextTok.isOneOf(tok::l_paren, tok::less, tok::l_square,
1317330f729Sjoerg                                          tok::identifier, tok::star, tok::amp);
1327330f729Sjoerg     WantExpressionKeywords =
1337330f729Sjoerg         nextTok.isOneOf(tok::l_paren, tok::identifier, tok::arrow, tok::period);
1347330f729Sjoerg     WantRemainingKeywords =
1357330f729Sjoerg         nextTok.isOneOf(tok::l_paren, tok::semi, tok::identifier, tok::l_brace);
1367330f729Sjoerg     WantCXXNamedCasts = false;
1377330f729Sjoerg   }
1387330f729Sjoerg 
ValidateCandidate(const TypoCorrection & candidate)1397330f729Sjoerg   bool ValidateCandidate(const TypoCorrection &candidate) override {
1407330f729Sjoerg     if (FieldDecl *FD = candidate.getCorrectionDeclAs<FieldDecl>())
1417330f729Sjoerg       return !candidate.getCorrectionSpecifier() || isa<ObjCIvarDecl>(FD);
1427330f729Sjoerg     if (NextToken.is(tok::equal))
1437330f729Sjoerg       return candidate.getCorrectionDeclAs<VarDecl>();
1447330f729Sjoerg     if (NextToken.is(tok::period) &&
1457330f729Sjoerg         candidate.getCorrectionDeclAs<NamespaceDecl>())
1467330f729Sjoerg       return false;
1477330f729Sjoerg     return CorrectionCandidateCallback::ValidateCandidate(candidate);
1487330f729Sjoerg   }
1497330f729Sjoerg 
clone()1507330f729Sjoerg   std::unique_ptr<CorrectionCandidateCallback> clone() override {
1517330f729Sjoerg     return std::make_unique<StatementFilterCCC>(*this);
1527330f729Sjoerg   }
1537330f729Sjoerg 
1547330f729Sjoerg private:
1557330f729Sjoerg   Token NextToken;
1567330f729Sjoerg };
1577330f729Sjoerg }
1587330f729Sjoerg 
ParseStatementOrDeclarationAfterAttributes(StmtVector & Stmts,ParsedStmtContext StmtCtx,SourceLocation * TrailingElseLoc,ParsedAttributesWithRange & Attrs)1597330f729Sjoerg StmtResult Parser::ParseStatementOrDeclarationAfterAttributes(
1607330f729Sjoerg     StmtVector &Stmts, ParsedStmtContext StmtCtx,
1617330f729Sjoerg     SourceLocation *TrailingElseLoc, ParsedAttributesWithRange &Attrs) {
1627330f729Sjoerg   const char *SemiError = nullptr;
1637330f729Sjoerg   StmtResult Res;
1647330f729Sjoerg   SourceLocation GNUAttributeLoc;
1657330f729Sjoerg 
1667330f729Sjoerg   // Cases in this switch statement should fall through if the parser expects
1677330f729Sjoerg   // the token to end in a semicolon (in which case SemiError should be set),
1687330f729Sjoerg   // or they directly 'return;' if not.
1697330f729Sjoerg Retry:
1707330f729Sjoerg   tok::TokenKind Kind  = Tok.getKind();
1717330f729Sjoerg   SourceLocation AtLoc;
1727330f729Sjoerg   switch (Kind) {
1737330f729Sjoerg   case tok::at: // May be a @try or @throw statement
1747330f729Sjoerg     {
1757330f729Sjoerg       AtLoc = ConsumeToken();  // consume @
1767330f729Sjoerg       return ParseObjCAtStatement(AtLoc, StmtCtx);
1777330f729Sjoerg     }
1787330f729Sjoerg 
1797330f729Sjoerg   case tok::code_completion:
1807330f729Sjoerg     cutOffParsing();
181*e038c9c4Sjoerg     Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Statement);
1827330f729Sjoerg     return StmtError();
1837330f729Sjoerg 
1847330f729Sjoerg   case tok::identifier: {
1857330f729Sjoerg     Token Next = NextToken();
1867330f729Sjoerg     if (Next.is(tok::colon)) { // C99 6.8.1: labeled-statement
1877330f729Sjoerg       // identifier ':' statement
1887330f729Sjoerg       return ParseLabeledStatement(Attrs, StmtCtx);
1897330f729Sjoerg     }
1907330f729Sjoerg 
1917330f729Sjoerg     // Look up the identifier, and typo-correct it to a keyword if it's not
1927330f729Sjoerg     // found.
1937330f729Sjoerg     if (Next.isNot(tok::coloncolon)) {
1947330f729Sjoerg       // Try to limit which sets of keywords should be included in typo
1957330f729Sjoerg       // correction based on what the next token is.
1967330f729Sjoerg       StatementFilterCCC CCC(Next);
1977330f729Sjoerg       if (TryAnnotateName(&CCC) == ANK_Error) {
1987330f729Sjoerg         // Handle errors here by skipping up to the next semicolon or '}', and
1997330f729Sjoerg         // eat the semicolon if that's what stopped us.
2007330f729Sjoerg         SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
2017330f729Sjoerg         if (Tok.is(tok::semi))
2027330f729Sjoerg           ConsumeToken();
2037330f729Sjoerg         return StmtError();
2047330f729Sjoerg       }
2057330f729Sjoerg 
2067330f729Sjoerg       // If the identifier was typo-corrected, try again.
2077330f729Sjoerg       if (Tok.isNot(tok::identifier))
2087330f729Sjoerg         goto Retry;
2097330f729Sjoerg     }
2107330f729Sjoerg 
2117330f729Sjoerg     // Fall through
2127330f729Sjoerg     LLVM_FALLTHROUGH;
2137330f729Sjoerg   }
2147330f729Sjoerg 
2157330f729Sjoerg   default: {
2167330f729Sjoerg     if ((getLangOpts().CPlusPlus || getLangOpts().MicrosoftExt ||
2177330f729Sjoerg          (StmtCtx & ParsedStmtContext::AllowDeclarationsInC) !=
2187330f729Sjoerg              ParsedStmtContext()) &&
219*e038c9c4Sjoerg         ((GNUAttributeLoc.isValid() &&
220*e038c9c4Sjoerg           !(!Attrs.empty() &&
221*e038c9c4Sjoerg             llvm::all_of(
222*e038c9c4Sjoerg                 Attrs, [](ParsedAttr &Attr) { return Attr.isStmtAttr(); }))) ||
223*e038c9c4Sjoerg          isDeclarationStatement())) {
2247330f729Sjoerg       SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
2257330f729Sjoerg       DeclGroupPtrTy Decl;
2267330f729Sjoerg       if (GNUAttributeLoc.isValid()) {
2277330f729Sjoerg         DeclStart = GNUAttributeLoc;
228*e038c9c4Sjoerg         Decl = ParseDeclaration(DeclaratorContext::Block, DeclEnd, Attrs,
2297330f729Sjoerg                                 &GNUAttributeLoc);
2307330f729Sjoerg       } else {
231*e038c9c4Sjoerg         Decl = ParseDeclaration(DeclaratorContext::Block, DeclEnd, Attrs);
2327330f729Sjoerg       }
2337330f729Sjoerg       if (Attrs.Range.getBegin().isValid())
2347330f729Sjoerg         DeclStart = Attrs.Range.getBegin();
2357330f729Sjoerg       return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
2367330f729Sjoerg     }
2377330f729Sjoerg 
2387330f729Sjoerg     if (Tok.is(tok::r_brace)) {
2397330f729Sjoerg       Diag(Tok, diag::err_expected_statement);
2407330f729Sjoerg       return StmtError();
2417330f729Sjoerg     }
2427330f729Sjoerg 
2437330f729Sjoerg     return ParseExprStatement(StmtCtx);
2447330f729Sjoerg   }
2457330f729Sjoerg 
2467330f729Sjoerg   case tok::kw___attribute: {
2477330f729Sjoerg     GNUAttributeLoc = Tok.getLocation();
2487330f729Sjoerg     ParseGNUAttributes(Attrs);
2497330f729Sjoerg     goto Retry;
2507330f729Sjoerg   }
2517330f729Sjoerg 
2527330f729Sjoerg   case tok::kw_case:                // C99 6.8.1: labeled-statement
2537330f729Sjoerg     return ParseCaseStatement(StmtCtx);
2547330f729Sjoerg   case tok::kw_default:             // C99 6.8.1: labeled-statement
2557330f729Sjoerg     return ParseDefaultStatement(StmtCtx);
2567330f729Sjoerg 
2577330f729Sjoerg   case tok::l_brace:                // C99 6.8.2: compound-statement
2587330f729Sjoerg     return ParseCompoundStatement();
2597330f729Sjoerg   case tok::semi: {                 // C99 6.8.3p3: expression[opt] ';'
2607330f729Sjoerg     bool HasLeadingEmptyMacro = Tok.hasLeadingEmptyMacro();
2617330f729Sjoerg     return Actions.ActOnNullStmt(ConsumeToken(), HasLeadingEmptyMacro);
2627330f729Sjoerg   }
2637330f729Sjoerg 
2647330f729Sjoerg   case tok::kw_if:                  // C99 6.8.4.1: if-statement
2657330f729Sjoerg     return ParseIfStatement(TrailingElseLoc);
2667330f729Sjoerg   case tok::kw_switch:              // C99 6.8.4.2: switch-statement
2677330f729Sjoerg     return ParseSwitchStatement(TrailingElseLoc);
2687330f729Sjoerg 
2697330f729Sjoerg   case tok::kw_while:               // C99 6.8.5.1: while-statement
2707330f729Sjoerg     return ParseWhileStatement(TrailingElseLoc);
2717330f729Sjoerg   case tok::kw_do:                  // C99 6.8.5.2: do-statement
2727330f729Sjoerg     Res = ParseDoStatement();
2737330f729Sjoerg     SemiError = "do/while";
2747330f729Sjoerg     break;
2757330f729Sjoerg   case tok::kw_for:                 // C99 6.8.5.3: for-statement
2767330f729Sjoerg     return ParseForStatement(TrailingElseLoc);
2777330f729Sjoerg 
2787330f729Sjoerg   case tok::kw_goto:                // C99 6.8.6.1: goto-statement
2797330f729Sjoerg     Res = ParseGotoStatement();
2807330f729Sjoerg     SemiError = "goto";
2817330f729Sjoerg     break;
2827330f729Sjoerg   case tok::kw_continue:            // C99 6.8.6.2: continue-statement
2837330f729Sjoerg     Res = ParseContinueStatement();
2847330f729Sjoerg     SemiError = "continue";
2857330f729Sjoerg     break;
2867330f729Sjoerg   case tok::kw_break:               // C99 6.8.6.3: break-statement
2877330f729Sjoerg     Res = ParseBreakStatement();
2887330f729Sjoerg     SemiError = "break";
2897330f729Sjoerg     break;
2907330f729Sjoerg   case tok::kw_return:              // C99 6.8.6.4: return-statement
2917330f729Sjoerg     Res = ParseReturnStatement();
2927330f729Sjoerg     SemiError = "return";
2937330f729Sjoerg     break;
2947330f729Sjoerg   case tok::kw_co_return:            // C++ Coroutines: co_return statement
2957330f729Sjoerg     Res = ParseReturnStatement();
2967330f729Sjoerg     SemiError = "co_return";
2977330f729Sjoerg     break;
2987330f729Sjoerg 
2997330f729Sjoerg   case tok::kw_asm: {
3007330f729Sjoerg     ProhibitAttributes(Attrs);
3017330f729Sjoerg     bool msAsm = false;
3027330f729Sjoerg     Res = ParseAsmStatement(msAsm);
3037330f729Sjoerg     Res = Actions.ActOnFinishFullStmt(Res.get());
3047330f729Sjoerg     if (msAsm) return Res;
3057330f729Sjoerg     SemiError = "asm";
3067330f729Sjoerg     break;
3077330f729Sjoerg   }
3087330f729Sjoerg 
3097330f729Sjoerg   case tok::kw___if_exists:
3107330f729Sjoerg   case tok::kw___if_not_exists:
3117330f729Sjoerg     ProhibitAttributes(Attrs);
3127330f729Sjoerg     ParseMicrosoftIfExistsStatement(Stmts);
3137330f729Sjoerg     // An __if_exists block is like a compound statement, but it doesn't create
3147330f729Sjoerg     // a new scope.
3157330f729Sjoerg     return StmtEmpty();
3167330f729Sjoerg 
3177330f729Sjoerg   case tok::kw_try:                 // C++ 15: try-block
3187330f729Sjoerg     return ParseCXXTryBlock();
3197330f729Sjoerg 
3207330f729Sjoerg   case tok::kw___try:
3217330f729Sjoerg     ProhibitAttributes(Attrs); // TODO: is it correct?
3227330f729Sjoerg     return ParseSEHTryBlock();
3237330f729Sjoerg 
3247330f729Sjoerg   case tok::kw___leave:
3257330f729Sjoerg     Res = ParseSEHLeaveStatement();
3267330f729Sjoerg     SemiError = "__leave";
3277330f729Sjoerg     break;
3287330f729Sjoerg 
3297330f729Sjoerg   case tok::annot_pragma_vis:
3307330f729Sjoerg     ProhibitAttributes(Attrs);
3317330f729Sjoerg     HandlePragmaVisibility();
3327330f729Sjoerg     return StmtEmpty();
3337330f729Sjoerg 
3347330f729Sjoerg   case tok::annot_pragma_pack:
3357330f729Sjoerg     ProhibitAttributes(Attrs);
3367330f729Sjoerg     HandlePragmaPack();
3377330f729Sjoerg     return StmtEmpty();
3387330f729Sjoerg 
3397330f729Sjoerg   case tok::annot_pragma_msstruct:
3407330f729Sjoerg     ProhibitAttributes(Attrs);
3417330f729Sjoerg     HandlePragmaMSStruct();
3427330f729Sjoerg     return StmtEmpty();
3437330f729Sjoerg 
3447330f729Sjoerg   case tok::annot_pragma_align:
3457330f729Sjoerg     ProhibitAttributes(Attrs);
3467330f729Sjoerg     HandlePragmaAlign();
3477330f729Sjoerg     return StmtEmpty();
3487330f729Sjoerg 
3497330f729Sjoerg   case tok::annot_pragma_weak:
3507330f729Sjoerg     ProhibitAttributes(Attrs);
3517330f729Sjoerg     HandlePragmaWeak();
3527330f729Sjoerg     return StmtEmpty();
3537330f729Sjoerg 
3547330f729Sjoerg   case tok::annot_pragma_weakalias:
3557330f729Sjoerg     ProhibitAttributes(Attrs);
3567330f729Sjoerg     HandlePragmaWeakAlias();
3577330f729Sjoerg     return StmtEmpty();
3587330f729Sjoerg 
3597330f729Sjoerg   case tok::annot_pragma_redefine_extname:
3607330f729Sjoerg     ProhibitAttributes(Attrs);
3617330f729Sjoerg     HandlePragmaRedefineExtname();
3627330f729Sjoerg     return StmtEmpty();
3637330f729Sjoerg 
3647330f729Sjoerg   case tok::annot_pragma_fp_contract:
3657330f729Sjoerg     ProhibitAttributes(Attrs);
366*e038c9c4Sjoerg     Diag(Tok, diag::err_pragma_file_or_compound_scope) << "fp_contract";
3677330f729Sjoerg     ConsumeAnnotationToken();
3687330f729Sjoerg     return StmtError();
3697330f729Sjoerg 
3707330f729Sjoerg   case tok::annot_pragma_fp:
3717330f729Sjoerg     ProhibitAttributes(Attrs);
372*e038c9c4Sjoerg     Diag(Tok, diag::err_pragma_file_or_compound_scope) << "clang fp";
3737330f729Sjoerg     ConsumeAnnotationToken();
3747330f729Sjoerg     return StmtError();
3757330f729Sjoerg 
3767330f729Sjoerg   case tok::annot_pragma_fenv_access:
3777330f729Sjoerg     ProhibitAttributes(Attrs);
378*e038c9c4Sjoerg     Diag(Tok, diag::err_pragma_stdc_fenv_access_scope);
379*e038c9c4Sjoerg     ConsumeAnnotationToken();
3807330f729Sjoerg     return StmtEmpty();
3817330f729Sjoerg 
382*e038c9c4Sjoerg   case tok::annot_pragma_fenv_round:
383*e038c9c4Sjoerg     ProhibitAttributes(Attrs);
384*e038c9c4Sjoerg     Diag(Tok, diag::err_pragma_file_or_compound_scope) << "STDC FENV_ROUND";
385*e038c9c4Sjoerg     ConsumeAnnotationToken();
386*e038c9c4Sjoerg     return StmtError();
387*e038c9c4Sjoerg 
388*e038c9c4Sjoerg   case tok::annot_pragma_float_control:
389*e038c9c4Sjoerg     ProhibitAttributes(Attrs);
390*e038c9c4Sjoerg     Diag(Tok, diag::err_pragma_file_or_compound_scope) << "float_control";
391*e038c9c4Sjoerg     ConsumeAnnotationToken();
392*e038c9c4Sjoerg     return StmtError();
393*e038c9c4Sjoerg 
3947330f729Sjoerg   case tok::annot_pragma_opencl_extension:
3957330f729Sjoerg     ProhibitAttributes(Attrs);
3967330f729Sjoerg     HandlePragmaOpenCLExtension();
3977330f729Sjoerg     return StmtEmpty();
3987330f729Sjoerg 
3997330f729Sjoerg   case tok::annot_pragma_captured:
4007330f729Sjoerg     ProhibitAttributes(Attrs);
4017330f729Sjoerg     return HandlePragmaCaptured();
4027330f729Sjoerg 
4037330f729Sjoerg   case tok::annot_pragma_openmp:
4047330f729Sjoerg     ProhibitAttributes(Attrs);
4057330f729Sjoerg     return ParseOpenMPDeclarativeOrExecutableDirective(StmtCtx);
4067330f729Sjoerg 
4077330f729Sjoerg   case tok::annot_pragma_ms_pointers_to_members:
4087330f729Sjoerg     ProhibitAttributes(Attrs);
4097330f729Sjoerg     HandlePragmaMSPointersToMembers();
4107330f729Sjoerg     return StmtEmpty();
4117330f729Sjoerg 
4127330f729Sjoerg   case tok::annot_pragma_ms_pragma:
4137330f729Sjoerg     ProhibitAttributes(Attrs);
4147330f729Sjoerg     HandlePragmaMSPragma();
4157330f729Sjoerg     return StmtEmpty();
4167330f729Sjoerg 
4177330f729Sjoerg   case tok::annot_pragma_ms_vtordisp:
4187330f729Sjoerg     ProhibitAttributes(Attrs);
4197330f729Sjoerg     HandlePragmaMSVtorDisp();
4207330f729Sjoerg     return StmtEmpty();
4217330f729Sjoerg 
4227330f729Sjoerg   case tok::annot_pragma_loop_hint:
4237330f729Sjoerg     ProhibitAttributes(Attrs);
4247330f729Sjoerg     return ParsePragmaLoopHint(Stmts, StmtCtx, TrailingElseLoc, Attrs);
4257330f729Sjoerg 
4267330f729Sjoerg   case tok::annot_pragma_dump:
4277330f729Sjoerg     HandlePragmaDump();
4287330f729Sjoerg     return StmtEmpty();
4297330f729Sjoerg 
4307330f729Sjoerg   case tok::annot_pragma_attribute:
4317330f729Sjoerg     HandlePragmaAttribute();
4327330f729Sjoerg     return StmtEmpty();
4337330f729Sjoerg   }
4347330f729Sjoerg 
4357330f729Sjoerg   // If we reached this code, the statement must end in a semicolon.
4367330f729Sjoerg   if (!TryConsumeToken(tok::semi) && !Res.isInvalid()) {
4377330f729Sjoerg     // If the result was valid, then we do want to diagnose this.  Use
4387330f729Sjoerg     // ExpectAndConsume to emit the diagnostic, even though we know it won't
4397330f729Sjoerg     // succeed.
4407330f729Sjoerg     ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt, SemiError);
4417330f729Sjoerg     // Skip until we see a } or ;, but don't eat it.
4427330f729Sjoerg     SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
4437330f729Sjoerg   }
4447330f729Sjoerg 
4457330f729Sjoerg   return Res;
4467330f729Sjoerg }
4477330f729Sjoerg 
4487330f729Sjoerg /// Parse an expression statement.
ParseExprStatement(ParsedStmtContext StmtCtx)4497330f729Sjoerg StmtResult Parser::ParseExprStatement(ParsedStmtContext StmtCtx) {
4507330f729Sjoerg   // If a case keyword is missing, this is where it should be inserted.
4517330f729Sjoerg   Token OldToken = Tok;
4527330f729Sjoerg 
4537330f729Sjoerg   ExprStatementTokLoc = Tok.getLocation();
4547330f729Sjoerg 
4557330f729Sjoerg   // expression[opt] ';'
4567330f729Sjoerg   ExprResult Expr(ParseExpression());
4577330f729Sjoerg   if (Expr.isInvalid()) {
4587330f729Sjoerg     // If the expression is invalid, skip ahead to the next semicolon or '}'.
4597330f729Sjoerg     // Not doing this opens us up to the possibility of infinite loops if
4607330f729Sjoerg     // ParseExpression does not consume any tokens.
4617330f729Sjoerg     SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
4627330f729Sjoerg     if (Tok.is(tok::semi))
4637330f729Sjoerg       ConsumeToken();
4647330f729Sjoerg     return Actions.ActOnExprStmtError();
4657330f729Sjoerg   }
4667330f729Sjoerg 
4677330f729Sjoerg   if (Tok.is(tok::colon) && getCurScope()->isSwitchScope() &&
4687330f729Sjoerg       Actions.CheckCaseExpression(Expr.get())) {
4697330f729Sjoerg     // If a constant expression is followed by a colon inside a switch block,
4707330f729Sjoerg     // suggest a missing case keyword.
4717330f729Sjoerg     Diag(OldToken, diag::err_expected_case_before_expression)
4727330f729Sjoerg       << FixItHint::CreateInsertion(OldToken.getLocation(), "case ");
4737330f729Sjoerg 
4747330f729Sjoerg     // Recover parsing as a case statement.
4757330f729Sjoerg     return ParseCaseStatement(StmtCtx, /*MissingCase=*/true, Expr);
4767330f729Sjoerg   }
4777330f729Sjoerg 
4787330f729Sjoerg   // Otherwise, eat the semicolon.
4797330f729Sjoerg   ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
4807330f729Sjoerg   return handleExprStmt(Expr, StmtCtx);
4817330f729Sjoerg }
4827330f729Sjoerg 
4837330f729Sjoerg /// ParseSEHTryBlockCommon
4847330f729Sjoerg ///
4857330f729Sjoerg /// seh-try-block:
4867330f729Sjoerg ///   '__try' compound-statement seh-handler
4877330f729Sjoerg ///
4887330f729Sjoerg /// seh-handler:
4897330f729Sjoerg ///   seh-except-block
4907330f729Sjoerg ///   seh-finally-block
4917330f729Sjoerg ///
ParseSEHTryBlock()4927330f729Sjoerg StmtResult Parser::ParseSEHTryBlock() {
4937330f729Sjoerg   assert(Tok.is(tok::kw___try) && "Expected '__try'");
4947330f729Sjoerg   SourceLocation TryLoc = ConsumeToken();
4957330f729Sjoerg 
4967330f729Sjoerg   if (Tok.isNot(tok::l_brace))
4977330f729Sjoerg     return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
4987330f729Sjoerg 
4997330f729Sjoerg   StmtResult TryBlock(ParseCompoundStatement(
5007330f729Sjoerg       /*isStmtExpr=*/false,
5017330f729Sjoerg       Scope::DeclScope | Scope::CompoundStmtScope | Scope::SEHTryScope));
5027330f729Sjoerg   if (TryBlock.isInvalid())
5037330f729Sjoerg     return TryBlock;
5047330f729Sjoerg 
5057330f729Sjoerg   StmtResult Handler;
5067330f729Sjoerg   if (Tok.is(tok::identifier) &&
5077330f729Sjoerg       Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
5087330f729Sjoerg     SourceLocation Loc = ConsumeToken();
5097330f729Sjoerg     Handler = ParseSEHExceptBlock(Loc);
5107330f729Sjoerg   } else if (Tok.is(tok::kw___finally)) {
5117330f729Sjoerg     SourceLocation Loc = ConsumeToken();
5127330f729Sjoerg     Handler = ParseSEHFinallyBlock(Loc);
5137330f729Sjoerg   } else {
5147330f729Sjoerg     return StmtError(Diag(Tok, diag::err_seh_expected_handler));
5157330f729Sjoerg   }
5167330f729Sjoerg 
5177330f729Sjoerg   if(Handler.isInvalid())
5187330f729Sjoerg     return Handler;
5197330f729Sjoerg 
5207330f729Sjoerg   return Actions.ActOnSEHTryBlock(false /* IsCXXTry */,
5217330f729Sjoerg                                   TryLoc,
5227330f729Sjoerg                                   TryBlock.get(),
5237330f729Sjoerg                                   Handler.get());
5247330f729Sjoerg }
5257330f729Sjoerg 
5267330f729Sjoerg /// ParseSEHExceptBlock - Handle __except
5277330f729Sjoerg ///
5287330f729Sjoerg /// seh-except-block:
5297330f729Sjoerg ///   '__except' '(' seh-filter-expression ')' compound-statement
5307330f729Sjoerg ///
ParseSEHExceptBlock(SourceLocation ExceptLoc)5317330f729Sjoerg StmtResult Parser::ParseSEHExceptBlock(SourceLocation ExceptLoc) {
5327330f729Sjoerg   PoisonIdentifierRAIIObject raii(Ident__exception_code, false),
5337330f729Sjoerg     raii2(Ident___exception_code, false),
5347330f729Sjoerg     raii3(Ident_GetExceptionCode, false);
5357330f729Sjoerg 
5367330f729Sjoerg   if (ExpectAndConsume(tok::l_paren))
5377330f729Sjoerg     return StmtError();
5387330f729Sjoerg 
5397330f729Sjoerg   ParseScope ExpectScope(this, Scope::DeclScope | Scope::ControlScope |
5407330f729Sjoerg                                    Scope::SEHExceptScope);
5417330f729Sjoerg 
5427330f729Sjoerg   if (getLangOpts().Borland) {
5437330f729Sjoerg     Ident__exception_info->setIsPoisoned(false);
5447330f729Sjoerg     Ident___exception_info->setIsPoisoned(false);
5457330f729Sjoerg     Ident_GetExceptionInfo->setIsPoisoned(false);
5467330f729Sjoerg   }
5477330f729Sjoerg 
5487330f729Sjoerg   ExprResult FilterExpr;
5497330f729Sjoerg   {
5507330f729Sjoerg     ParseScopeFlags FilterScope(this, getCurScope()->getFlags() |
5517330f729Sjoerg                                           Scope::SEHFilterScope);
5527330f729Sjoerg     FilterExpr = Actions.CorrectDelayedTyposInExpr(ParseExpression());
5537330f729Sjoerg   }
5547330f729Sjoerg 
5557330f729Sjoerg   if (getLangOpts().Borland) {
5567330f729Sjoerg     Ident__exception_info->setIsPoisoned(true);
5577330f729Sjoerg     Ident___exception_info->setIsPoisoned(true);
5587330f729Sjoerg     Ident_GetExceptionInfo->setIsPoisoned(true);
5597330f729Sjoerg   }
5607330f729Sjoerg 
5617330f729Sjoerg   if(FilterExpr.isInvalid())
5627330f729Sjoerg     return StmtError();
5637330f729Sjoerg 
5647330f729Sjoerg   if (ExpectAndConsume(tok::r_paren))
5657330f729Sjoerg     return StmtError();
5667330f729Sjoerg 
5677330f729Sjoerg   if (Tok.isNot(tok::l_brace))
5687330f729Sjoerg     return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
5697330f729Sjoerg 
5707330f729Sjoerg   StmtResult Block(ParseCompoundStatement());
5717330f729Sjoerg 
5727330f729Sjoerg   if(Block.isInvalid())
5737330f729Sjoerg     return Block;
5747330f729Sjoerg 
5757330f729Sjoerg   return Actions.ActOnSEHExceptBlock(ExceptLoc, FilterExpr.get(), Block.get());
5767330f729Sjoerg }
5777330f729Sjoerg 
5787330f729Sjoerg /// ParseSEHFinallyBlock - Handle __finally
5797330f729Sjoerg ///
5807330f729Sjoerg /// seh-finally-block:
5817330f729Sjoerg ///   '__finally' compound-statement
5827330f729Sjoerg ///
ParseSEHFinallyBlock(SourceLocation FinallyLoc)5837330f729Sjoerg StmtResult Parser::ParseSEHFinallyBlock(SourceLocation FinallyLoc) {
5847330f729Sjoerg   PoisonIdentifierRAIIObject raii(Ident__abnormal_termination, false),
5857330f729Sjoerg     raii2(Ident___abnormal_termination, false),
5867330f729Sjoerg     raii3(Ident_AbnormalTermination, false);
5877330f729Sjoerg 
5887330f729Sjoerg   if (Tok.isNot(tok::l_brace))
5897330f729Sjoerg     return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
5907330f729Sjoerg 
5917330f729Sjoerg   ParseScope FinallyScope(this, 0);
5927330f729Sjoerg   Actions.ActOnStartSEHFinallyBlock();
5937330f729Sjoerg 
5947330f729Sjoerg   StmtResult Block(ParseCompoundStatement());
5957330f729Sjoerg   if(Block.isInvalid()) {
5967330f729Sjoerg     Actions.ActOnAbortSEHFinallyBlock();
5977330f729Sjoerg     return Block;
5987330f729Sjoerg   }
5997330f729Sjoerg 
6007330f729Sjoerg   return Actions.ActOnFinishSEHFinallyBlock(FinallyLoc, Block.get());
6017330f729Sjoerg }
6027330f729Sjoerg 
6037330f729Sjoerg /// Handle __leave
6047330f729Sjoerg ///
6057330f729Sjoerg /// seh-leave-statement:
6067330f729Sjoerg ///   '__leave' ';'
6077330f729Sjoerg ///
ParseSEHLeaveStatement()6087330f729Sjoerg StmtResult Parser::ParseSEHLeaveStatement() {
6097330f729Sjoerg   SourceLocation LeaveLoc = ConsumeToken();  // eat the '__leave'.
6107330f729Sjoerg   return Actions.ActOnSEHLeaveStmt(LeaveLoc, getCurScope());
6117330f729Sjoerg }
6127330f729Sjoerg 
6137330f729Sjoerg /// ParseLabeledStatement - We have an identifier and a ':' after it.
6147330f729Sjoerg ///
6157330f729Sjoerg ///       labeled-statement:
6167330f729Sjoerg ///         identifier ':' statement
6177330f729Sjoerg /// [GNU]   identifier ':' attributes[opt] statement
6187330f729Sjoerg ///
ParseLabeledStatement(ParsedAttributesWithRange & attrs,ParsedStmtContext StmtCtx)6197330f729Sjoerg StmtResult Parser::ParseLabeledStatement(ParsedAttributesWithRange &attrs,
6207330f729Sjoerg                                          ParsedStmtContext StmtCtx) {
6217330f729Sjoerg   assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
6227330f729Sjoerg          "Not an identifier!");
6237330f729Sjoerg 
6247330f729Sjoerg   // The substatement is always a 'statement', not a 'declaration', but is
6257330f729Sjoerg   // otherwise in the same context as the labeled-statement.
6267330f729Sjoerg   StmtCtx &= ~ParsedStmtContext::AllowDeclarationsInC;
6277330f729Sjoerg 
6287330f729Sjoerg   Token IdentTok = Tok;  // Save the whole token.
6297330f729Sjoerg   ConsumeToken();  // eat the identifier.
6307330f729Sjoerg 
6317330f729Sjoerg   assert(Tok.is(tok::colon) && "Not a label!");
6327330f729Sjoerg 
6337330f729Sjoerg   // identifier ':' statement
6347330f729Sjoerg   SourceLocation ColonLoc = ConsumeToken();
6357330f729Sjoerg 
6367330f729Sjoerg   // Read label attributes, if present.
6377330f729Sjoerg   StmtResult SubStmt;
6387330f729Sjoerg   if (Tok.is(tok::kw___attribute)) {
6397330f729Sjoerg     ParsedAttributesWithRange TempAttrs(AttrFactory);
6407330f729Sjoerg     ParseGNUAttributes(TempAttrs);
6417330f729Sjoerg 
6427330f729Sjoerg     // In C++, GNU attributes only apply to the label if they are followed by a
6437330f729Sjoerg     // semicolon, to disambiguate label attributes from attributes on a labeled
6447330f729Sjoerg     // declaration.
6457330f729Sjoerg     //
6467330f729Sjoerg     // This doesn't quite match what GCC does; if the attribute list is empty
6477330f729Sjoerg     // and followed by a semicolon, GCC will reject (it appears to parse the
6487330f729Sjoerg     // attributes as part of a statement in that case). That looks like a bug.
6497330f729Sjoerg     if (!getLangOpts().CPlusPlus || Tok.is(tok::semi))
6507330f729Sjoerg       attrs.takeAllFrom(TempAttrs);
651*e038c9c4Sjoerg     else {
6527330f729Sjoerg       StmtVector Stmts;
6537330f729Sjoerg       SubStmt = ParseStatementOrDeclarationAfterAttributes(Stmts, StmtCtx,
6547330f729Sjoerg                                                            nullptr, TempAttrs);
6557330f729Sjoerg       if (!TempAttrs.empty() && !SubStmt.isInvalid())
656*e038c9c4Sjoerg         SubStmt = Actions.ActOnAttributedStmt(TempAttrs, SubStmt.get());
6577330f729Sjoerg     }
6587330f729Sjoerg   }
6597330f729Sjoerg 
6607330f729Sjoerg   // If we've not parsed a statement yet, parse one now.
6617330f729Sjoerg   if (!SubStmt.isInvalid() && !SubStmt.isUsable())
6627330f729Sjoerg     SubStmt = ParseStatement(nullptr, StmtCtx);
6637330f729Sjoerg 
6647330f729Sjoerg   // Broken substmt shouldn't prevent the label from being added to the AST.
6657330f729Sjoerg   if (SubStmt.isInvalid())
6667330f729Sjoerg     SubStmt = Actions.ActOnNullStmt(ColonLoc);
6677330f729Sjoerg 
6687330f729Sjoerg   LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
6697330f729Sjoerg                                               IdentTok.getLocation());
6707330f729Sjoerg   Actions.ProcessDeclAttributeList(Actions.CurScope, LD, attrs);
6717330f729Sjoerg   attrs.clear();
6727330f729Sjoerg 
6737330f729Sjoerg   return Actions.ActOnLabelStmt(IdentTok.getLocation(), LD, ColonLoc,
6747330f729Sjoerg                                 SubStmt.get());
6757330f729Sjoerg }
6767330f729Sjoerg 
6777330f729Sjoerg /// ParseCaseStatement
6787330f729Sjoerg ///       labeled-statement:
6797330f729Sjoerg ///         'case' constant-expression ':' statement
6807330f729Sjoerg /// [GNU]   'case' constant-expression '...' constant-expression ':' statement
6817330f729Sjoerg ///
ParseCaseStatement(ParsedStmtContext StmtCtx,bool MissingCase,ExprResult Expr)6827330f729Sjoerg StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx,
6837330f729Sjoerg                                       bool MissingCase, ExprResult Expr) {
6847330f729Sjoerg   assert((MissingCase || Tok.is(tok::kw_case)) && "Not a case stmt!");
6857330f729Sjoerg 
6867330f729Sjoerg   // The substatement is always a 'statement', not a 'declaration', but is
6877330f729Sjoerg   // otherwise in the same context as the labeled-statement.
6887330f729Sjoerg   StmtCtx &= ~ParsedStmtContext::AllowDeclarationsInC;
6897330f729Sjoerg 
6907330f729Sjoerg   // It is very very common for code to contain many case statements recursively
6917330f729Sjoerg   // nested, as in (but usually without indentation):
6927330f729Sjoerg   //  case 1:
6937330f729Sjoerg   //    case 2:
6947330f729Sjoerg   //      case 3:
6957330f729Sjoerg   //         case 4:
6967330f729Sjoerg   //           case 5: etc.
6977330f729Sjoerg   //
6987330f729Sjoerg   // Parsing this naively works, but is both inefficient and can cause us to run
6997330f729Sjoerg   // out of stack space in our recursive descent parser.  As a special case,
7007330f729Sjoerg   // flatten this recursion into an iterative loop.  This is complex and gross,
7017330f729Sjoerg   // but all the grossness is constrained to ParseCaseStatement (and some
7027330f729Sjoerg   // weirdness in the actions), so this is just local grossness :).
7037330f729Sjoerg 
7047330f729Sjoerg   // TopLevelCase - This is the highest level we have parsed.  'case 1' in the
7057330f729Sjoerg   // example above.
7067330f729Sjoerg   StmtResult TopLevelCase(true);
7077330f729Sjoerg 
7087330f729Sjoerg   // DeepestParsedCaseStmt - This is the deepest statement we have parsed, which
7097330f729Sjoerg   // gets updated each time a new case is parsed, and whose body is unset so
7107330f729Sjoerg   // far.  When parsing 'case 4', this is the 'case 3' node.
7117330f729Sjoerg   Stmt *DeepestParsedCaseStmt = nullptr;
7127330f729Sjoerg 
7137330f729Sjoerg   // While we have case statements, eat and stack them.
7147330f729Sjoerg   SourceLocation ColonLoc;
7157330f729Sjoerg   do {
7167330f729Sjoerg     SourceLocation CaseLoc = MissingCase ? Expr.get()->getExprLoc() :
7177330f729Sjoerg                                            ConsumeToken();  // eat the 'case'.
7187330f729Sjoerg     ColonLoc = SourceLocation();
7197330f729Sjoerg 
7207330f729Sjoerg     if (Tok.is(tok::code_completion)) {
7217330f729Sjoerg       cutOffParsing();
722*e038c9c4Sjoerg       Actions.CodeCompleteCase(getCurScope());
7237330f729Sjoerg       return StmtError();
7247330f729Sjoerg     }
7257330f729Sjoerg 
7267330f729Sjoerg     /// We don't want to treat 'case x : y' as a potential typo for 'case x::y'.
7277330f729Sjoerg     /// Disable this form of error recovery while we're parsing the case
7287330f729Sjoerg     /// expression.
7297330f729Sjoerg     ColonProtectionRAIIObject ColonProtection(*this);
7307330f729Sjoerg 
7317330f729Sjoerg     ExprResult LHS;
7327330f729Sjoerg     if (!MissingCase) {
7337330f729Sjoerg       LHS = ParseCaseExpression(CaseLoc);
7347330f729Sjoerg       if (LHS.isInvalid()) {
7357330f729Sjoerg         // If constant-expression is parsed unsuccessfully, recover by skipping
7367330f729Sjoerg         // current case statement (moving to the colon that ends it).
7377330f729Sjoerg         if (!SkipUntil(tok::colon, tok::r_brace, StopAtSemi | StopBeforeMatch))
7387330f729Sjoerg           return StmtError();
7397330f729Sjoerg       }
7407330f729Sjoerg     } else {
7417330f729Sjoerg       LHS = Expr;
7427330f729Sjoerg       MissingCase = false;
7437330f729Sjoerg     }
7447330f729Sjoerg 
7457330f729Sjoerg     // GNU case range extension.
7467330f729Sjoerg     SourceLocation DotDotDotLoc;
7477330f729Sjoerg     ExprResult RHS;
7487330f729Sjoerg     if (TryConsumeToken(tok::ellipsis, DotDotDotLoc)) {
7497330f729Sjoerg       Diag(DotDotDotLoc, diag::ext_gnu_case_range);
7507330f729Sjoerg       RHS = ParseCaseExpression(CaseLoc);
7517330f729Sjoerg       if (RHS.isInvalid()) {
7527330f729Sjoerg         if (!SkipUntil(tok::colon, tok::r_brace, StopAtSemi | StopBeforeMatch))
7537330f729Sjoerg           return StmtError();
7547330f729Sjoerg       }
7557330f729Sjoerg     }
7567330f729Sjoerg 
7577330f729Sjoerg     ColonProtection.restore();
7587330f729Sjoerg 
7597330f729Sjoerg     if (TryConsumeToken(tok::colon, ColonLoc)) {
7607330f729Sjoerg     } else if (TryConsumeToken(tok::semi, ColonLoc) ||
7617330f729Sjoerg                TryConsumeToken(tok::coloncolon, ColonLoc)) {
7627330f729Sjoerg       // Treat "case blah;" or "case blah::" as a typo for "case blah:".
7637330f729Sjoerg       Diag(ColonLoc, diag::err_expected_after)
7647330f729Sjoerg           << "'case'" << tok::colon
7657330f729Sjoerg           << FixItHint::CreateReplacement(ColonLoc, ":");
7667330f729Sjoerg     } else {
7677330f729Sjoerg       SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation);
7687330f729Sjoerg       Diag(ExpectedLoc, diag::err_expected_after)
7697330f729Sjoerg           << "'case'" << tok::colon
7707330f729Sjoerg           << FixItHint::CreateInsertion(ExpectedLoc, ":");
7717330f729Sjoerg       ColonLoc = ExpectedLoc;
7727330f729Sjoerg     }
7737330f729Sjoerg 
7747330f729Sjoerg     StmtResult Case =
7757330f729Sjoerg         Actions.ActOnCaseStmt(CaseLoc, LHS, DotDotDotLoc, RHS, ColonLoc);
7767330f729Sjoerg 
7777330f729Sjoerg     // If we had a sema error parsing this case, then just ignore it and
7787330f729Sjoerg     // continue parsing the sub-stmt.
7797330f729Sjoerg     if (Case.isInvalid()) {
7807330f729Sjoerg       if (TopLevelCase.isInvalid())  // No parsed case stmts.
7817330f729Sjoerg         return ParseStatement(/*TrailingElseLoc=*/nullptr, StmtCtx);
7827330f729Sjoerg       // Otherwise, just don't add it as a nested case.
7837330f729Sjoerg     } else {
7847330f729Sjoerg       // If this is the first case statement we parsed, it becomes TopLevelCase.
7857330f729Sjoerg       // Otherwise we link it into the current chain.
7867330f729Sjoerg       Stmt *NextDeepest = Case.get();
7877330f729Sjoerg       if (TopLevelCase.isInvalid())
7887330f729Sjoerg         TopLevelCase = Case;
7897330f729Sjoerg       else
7907330f729Sjoerg         Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, Case.get());
7917330f729Sjoerg       DeepestParsedCaseStmt = NextDeepest;
7927330f729Sjoerg     }
7937330f729Sjoerg 
7947330f729Sjoerg     // Handle all case statements.
7957330f729Sjoerg   } while (Tok.is(tok::kw_case));
7967330f729Sjoerg 
7977330f729Sjoerg   // If we found a non-case statement, start by parsing it.
7987330f729Sjoerg   StmtResult SubStmt;
7997330f729Sjoerg 
8007330f729Sjoerg   if (Tok.isNot(tok::r_brace)) {
8017330f729Sjoerg     SubStmt = ParseStatement(/*TrailingElseLoc=*/nullptr, StmtCtx);
8027330f729Sjoerg   } else {
8037330f729Sjoerg     // Nicely diagnose the common error "switch (X) { case 4: }", which is
8047330f729Sjoerg     // not valid.  If ColonLoc doesn't point to a valid text location, there was
8057330f729Sjoerg     // another parsing error, so avoid producing extra diagnostics.
8067330f729Sjoerg     if (ColonLoc.isValid()) {
8077330f729Sjoerg       SourceLocation AfterColonLoc = PP.getLocForEndOfToken(ColonLoc);
8087330f729Sjoerg       Diag(AfterColonLoc, diag::err_label_end_of_compound_statement)
8097330f729Sjoerg         << FixItHint::CreateInsertion(AfterColonLoc, " ;");
8107330f729Sjoerg     }
8117330f729Sjoerg     SubStmt = StmtError();
8127330f729Sjoerg   }
8137330f729Sjoerg 
8147330f729Sjoerg   // Install the body into the most deeply-nested case.
8157330f729Sjoerg   if (DeepestParsedCaseStmt) {
8167330f729Sjoerg     // Broken sub-stmt shouldn't prevent forming the case statement properly.
8177330f729Sjoerg     if (SubStmt.isInvalid())
8187330f729Sjoerg       SubStmt = Actions.ActOnNullStmt(SourceLocation());
8197330f729Sjoerg     Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, SubStmt.get());
8207330f729Sjoerg   }
8217330f729Sjoerg 
8227330f729Sjoerg   // Return the top level parsed statement tree.
8237330f729Sjoerg   return TopLevelCase;
8247330f729Sjoerg }
8257330f729Sjoerg 
8267330f729Sjoerg /// ParseDefaultStatement
8277330f729Sjoerg ///       labeled-statement:
8287330f729Sjoerg ///         'default' ':' statement
8297330f729Sjoerg /// Note that this does not parse the 'statement' at the end.
8307330f729Sjoerg ///
ParseDefaultStatement(ParsedStmtContext StmtCtx)8317330f729Sjoerg StmtResult Parser::ParseDefaultStatement(ParsedStmtContext StmtCtx) {
8327330f729Sjoerg   assert(Tok.is(tok::kw_default) && "Not a default stmt!");
8337330f729Sjoerg 
8347330f729Sjoerg   // The substatement is always a 'statement', not a 'declaration', but is
8357330f729Sjoerg   // otherwise in the same context as the labeled-statement.
8367330f729Sjoerg   StmtCtx &= ~ParsedStmtContext::AllowDeclarationsInC;
8377330f729Sjoerg 
8387330f729Sjoerg   SourceLocation DefaultLoc = ConsumeToken();  // eat the 'default'.
8397330f729Sjoerg 
8407330f729Sjoerg   SourceLocation ColonLoc;
8417330f729Sjoerg   if (TryConsumeToken(tok::colon, ColonLoc)) {
8427330f729Sjoerg   } else if (TryConsumeToken(tok::semi, ColonLoc)) {
8437330f729Sjoerg     // Treat "default;" as a typo for "default:".
8447330f729Sjoerg     Diag(ColonLoc, diag::err_expected_after)
8457330f729Sjoerg         << "'default'" << tok::colon
8467330f729Sjoerg         << FixItHint::CreateReplacement(ColonLoc, ":");
8477330f729Sjoerg   } else {
8487330f729Sjoerg     SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation);
8497330f729Sjoerg     Diag(ExpectedLoc, diag::err_expected_after)
8507330f729Sjoerg         << "'default'" << tok::colon
8517330f729Sjoerg         << FixItHint::CreateInsertion(ExpectedLoc, ":");
8527330f729Sjoerg     ColonLoc = ExpectedLoc;
8537330f729Sjoerg   }
8547330f729Sjoerg 
8557330f729Sjoerg   StmtResult SubStmt;
8567330f729Sjoerg 
8577330f729Sjoerg   if (Tok.isNot(tok::r_brace)) {
8587330f729Sjoerg     SubStmt = ParseStatement(/*TrailingElseLoc=*/nullptr, StmtCtx);
8597330f729Sjoerg   } else {
8607330f729Sjoerg     // Diagnose the common error "switch (X) {... default: }", which is
8617330f729Sjoerg     // not valid.
8627330f729Sjoerg     SourceLocation AfterColonLoc = PP.getLocForEndOfToken(ColonLoc);
8637330f729Sjoerg     Diag(AfterColonLoc, diag::err_label_end_of_compound_statement)
8647330f729Sjoerg       << FixItHint::CreateInsertion(AfterColonLoc, " ;");
8657330f729Sjoerg     SubStmt = true;
8667330f729Sjoerg   }
8677330f729Sjoerg 
8687330f729Sjoerg   // Broken sub-stmt shouldn't prevent forming the case statement properly.
8697330f729Sjoerg   if (SubStmt.isInvalid())
8707330f729Sjoerg     SubStmt = Actions.ActOnNullStmt(ColonLoc);
8717330f729Sjoerg 
8727330f729Sjoerg   return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc,
8737330f729Sjoerg                                   SubStmt.get(), getCurScope());
8747330f729Sjoerg }
8757330f729Sjoerg 
ParseCompoundStatement(bool isStmtExpr)8767330f729Sjoerg StmtResult Parser::ParseCompoundStatement(bool isStmtExpr) {
8777330f729Sjoerg   return ParseCompoundStatement(isStmtExpr,
8787330f729Sjoerg                                 Scope::DeclScope | Scope::CompoundStmtScope);
8797330f729Sjoerg }
8807330f729Sjoerg 
8817330f729Sjoerg /// ParseCompoundStatement - Parse a "{}" block.
8827330f729Sjoerg ///
8837330f729Sjoerg ///       compound-statement: [C99 6.8.2]
8847330f729Sjoerg ///         { block-item-list[opt] }
8857330f729Sjoerg /// [GNU]   { label-declarations block-item-list } [TODO]
8867330f729Sjoerg ///
8877330f729Sjoerg ///       block-item-list:
8887330f729Sjoerg ///         block-item
8897330f729Sjoerg ///         block-item-list block-item
8907330f729Sjoerg ///
8917330f729Sjoerg ///       block-item:
8927330f729Sjoerg ///         declaration
8937330f729Sjoerg /// [GNU]   '__extension__' declaration
8947330f729Sjoerg ///         statement
8957330f729Sjoerg ///
8967330f729Sjoerg /// [GNU] label-declarations:
8977330f729Sjoerg /// [GNU]   label-declaration
8987330f729Sjoerg /// [GNU]   label-declarations label-declaration
8997330f729Sjoerg ///
9007330f729Sjoerg /// [GNU] label-declaration:
9017330f729Sjoerg /// [GNU]   '__label__' identifier-list ';'
9027330f729Sjoerg ///
ParseCompoundStatement(bool isStmtExpr,unsigned ScopeFlags)9037330f729Sjoerg StmtResult Parser::ParseCompoundStatement(bool isStmtExpr,
9047330f729Sjoerg                                           unsigned ScopeFlags) {
9057330f729Sjoerg   assert(Tok.is(tok::l_brace) && "Not a compount stmt!");
9067330f729Sjoerg 
9077330f729Sjoerg   // Enter a scope to hold everything within the compound stmt.  Compound
9087330f729Sjoerg   // statements can always hold declarations.
9097330f729Sjoerg   ParseScope CompoundScope(this, ScopeFlags);
9107330f729Sjoerg 
9117330f729Sjoerg   // Parse the statements in the body.
9127330f729Sjoerg   return ParseCompoundStatementBody(isStmtExpr);
9137330f729Sjoerg }
9147330f729Sjoerg 
9157330f729Sjoerg /// Parse any pragmas at the start of the compound expression. We handle these
9167330f729Sjoerg /// separately since some pragmas (FP_CONTRACT) must appear before any C
9177330f729Sjoerg /// statement in the compound, but may be intermingled with other pragmas.
ParseCompoundStatementLeadingPragmas()9187330f729Sjoerg void Parser::ParseCompoundStatementLeadingPragmas() {
9197330f729Sjoerg   bool checkForPragmas = true;
9207330f729Sjoerg   while (checkForPragmas) {
9217330f729Sjoerg     switch (Tok.getKind()) {
9227330f729Sjoerg     case tok::annot_pragma_vis:
9237330f729Sjoerg       HandlePragmaVisibility();
9247330f729Sjoerg       break;
9257330f729Sjoerg     case tok::annot_pragma_pack:
9267330f729Sjoerg       HandlePragmaPack();
9277330f729Sjoerg       break;
9287330f729Sjoerg     case tok::annot_pragma_msstruct:
9297330f729Sjoerg       HandlePragmaMSStruct();
9307330f729Sjoerg       break;
9317330f729Sjoerg     case tok::annot_pragma_align:
9327330f729Sjoerg       HandlePragmaAlign();
9337330f729Sjoerg       break;
9347330f729Sjoerg     case tok::annot_pragma_weak:
9357330f729Sjoerg       HandlePragmaWeak();
9367330f729Sjoerg       break;
9377330f729Sjoerg     case tok::annot_pragma_weakalias:
9387330f729Sjoerg       HandlePragmaWeakAlias();
9397330f729Sjoerg       break;
9407330f729Sjoerg     case tok::annot_pragma_redefine_extname:
9417330f729Sjoerg       HandlePragmaRedefineExtname();
9427330f729Sjoerg       break;
9437330f729Sjoerg     case tok::annot_pragma_opencl_extension:
9447330f729Sjoerg       HandlePragmaOpenCLExtension();
9457330f729Sjoerg       break;
9467330f729Sjoerg     case tok::annot_pragma_fp_contract:
9477330f729Sjoerg       HandlePragmaFPContract();
9487330f729Sjoerg       break;
9497330f729Sjoerg     case tok::annot_pragma_fp:
9507330f729Sjoerg       HandlePragmaFP();
9517330f729Sjoerg       break;
9527330f729Sjoerg     case tok::annot_pragma_fenv_access:
9537330f729Sjoerg       HandlePragmaFEnvAccess();
9547330f729Sjoerg       break;
955*e038c9c4Sjoerg     case tok::annot_pragma_fenv_round:
956*e038c9c4Sjoerg       HandlePragmaFEnvRound();
957*e038c9c4Sjoerg       break;
958*e038c9c4Sjoerg     case tok::annot_pragma_float_control:
959*e038c9c4Sjoerg       HandlePragmaFloatControl();
960*e038c9c4Sjoerg       break;
9617330f729Sjoerg     case tok::annot_pragma_ms_pointers_to_members:
9627330f729Sjoerg       HandlePragmaMSPointersToMembers();
9637330f729Sjoerg       break;
9647330f729Sjoerg     case tok::annot_pragma_ms_pragma:
9657330f729Sjoerg       HandlePragmaMSPragma();
9667330f729Sjoerg       break;
9677330f729Sjoerg     case tok::annot_pragma_ms_vtordisp:
9687330f729Sjoerg       HandlePragmaMSVtorDisp();
9697330f729Sjoerg       break;
9707330f729Sjoerg     case tok::annot_pragma_dump:
9717330f729Sjoerg       HandlePragmaDump();
9727330f729Sjoerg       break;
9737330f729Sjoerg     default:
9747330f729Sjoerg       checkForPragmas = false;
9757330f729Sjoerg       break;
9767330f729Sjoerg     }
9777330f729Sjoerg   }
9787330f729Sjoerg 
9797330f729Sjoerg }
9807330f729Sjoerg 
9817330f729Sjoerg /// Consume any extra semi-colons resulting in null statements,
9827330f729Sjoerg /// returning true if any tok::semi were consumed.
ConsumeNullStmt(StmtVector & Stmts)9837330f729Sjoerg bool Parser::ConsumeNullStmt(StmtVector &Stmts) {
9847330f729Sjoerg   if (!Tok.is(tok::semi))
9857330f729Sjoerg     return false;
9867330f729Sjoerg 
9877330f729Sjoerg   SourceLocation StartLoc = Tok.getLocation();
9887330f729Sjoerg   SourceLocation EndLoc;
9897330f729Sjoerg 
9907330f729Sjoerg   while (Tok.is(tok::semi) && !Tok.hasLeadingEmptyMacro() &&
9917330f729Sjoerg          Tok.getLocation().isValid() && !Tok.getLocation().isMacroID()) {
9927330f729Sjoerg     EndLoc = Tok.getLocation();
9937330f729Sjoerg 
9947330f729Sjoerg     // Don't just ConsumeToken() this tok::semi, do store it in AST.
9957330f729Sjoerg     StmtResult R =
9967330f729Sjoerg         ParseStatementOrDeclaration(Stmts, ParsedStmtContext::SubStmt);
9977330f729Sjoerg     if (R.isUsable())
9987330f729Sjoerg       Stmts.push_back(R.get());
9997330f729Sjoerg   }
10007330f729Sjoerg 
10017330f729Sjoerg   // Did not consume any extra semi.
10027330f729Sjoerg   if (EndLoc.isInvalid())
10037330f729Sjoerg     return false;
10047330f729Sjoerg 
10057330f729Sjoerg   Diag(StartLoc, diag::warn_null_statement)
10067330f729Sjoerg       << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc));
10077330f729Sjoerg   return true;
10087330f729Sjoerg }
10097330f729Sjoerg 
handleExprStmt(ExprResult E,ParsedStmtContext StmtCtx)10107330f729Sjoerg StmtResult Parser::handleExprStmt(ExprResult E, ParsedStmtContext StmtCtx) {
10117330f729Sjoerg   bool IsStmtExprResult = false;
10127330f729Sjoerg   if ((StmtCtx & ParsedStmtContext::InStmtExpr) != ParsedStmtContext()) {
10137330f729Sjoerg     // For GCC compatibility we skip past NullStmts.
10147330f729Sjoerg     unsigned LookAhead = 0;
10157330f729Sjoerg     while (GetLookAheadToken(LookAhead).is(tok::semi)) {
10167330f729Sjoerg       ++LookAhead;
10177330f729Sjoerg     }
10187330f729Sjoerg     // Then look to see if the next two tokens close the statement expression;
10197330f729Sjoerg     // if so, this expression statement is the last statement in a statment
10207330f729Sjoerg     // expression.
10217330f729Sjoerg     IsStmtExprResult = GetLookAheadToken(LookAhead).is(tok::r_brace) &&
10227330f729Sjoerg                        GetLookAheadToken(LookAhead + 1).is(tok::r_paren);
10237330f729Sjoerg   }
10247330f729Sjoerg 
10257330f729Sjoerg   if (IsStmtExprResult)
10267330f729Sjoerg     E = Actions.ActOnStmtExprResult(E);
10277330f729Sjoerg   return Actions.ActOnExprStmt(E, /*DiscardedValue=*/!IsStmtExprResult);
10287330f729Sjoerg }
10297330f729Sjoerg 
10307330f729Sjoerg /// ParseCompoundStatementBody - Parse a sequence of statements and invoke the
10317330f729Sjoerg /// ActOnCompoundStmt action.  This expects the '{' to be the current token, and
10327330f729Sjoerg /// consume the '}' at the end of the block.  It does not manipulate the scope
10337330f729Sjoerg /// stack.
ParseCompoundStatementBody(bool isStmtExpr)10347330f729Sjoerg StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
10357330f729Sjoerg   PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),
10367330f729Sjoerg                                 Tok.getLocation(),
10377330f729Sjoerg                                 "in compound statement ('{}')");
10387330f729Sjoerg 
1039*e038c9c4Sjoerg   // Record the current FPFeatures, restore on leaving the
10407330f729Sjoerg   // compound statement.
1041*e038c9c4Sjoerg   Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);
10427330f729Sjoerg 
10437330f729Sjoerg   InMessageExpressionRAIIObject InMessage(*this, false);
10447330f729Sjoerg   BalancedDelimiterTracker T(*this, tok::l_brace);
10457330f729Sjoerg   if (T.consumeOpen())
10467330f729Sjoerg     return StmtError();
10477330f729Sjoerg 
10487330f729Sjoerg   Sema::CompoundScopeRAII CompoundScope(Actions, isStmtExpr);
10497330f729Sjoerg 
10507330f729Sjoerg   // Parse any pragmas at the beginning of the compound statement.
10517330f729Sjoerg   ParseCompoundStatementLeadingPragmas();
1052*e038c9c4Sjoerg   Actions.ActOnAfterCompoundStatementLeadingPragmas();
10537330f729Sjoerg 
10547330f729Sjoerg   StmtVector Stmts;
10557330f729Sjoerg 
10567330f729Sjoerg   // "__label__ X, Y, Z;" is the GNU "Local Label" extension.  These are
10577330f729Sjoerg   // only allowed at the start of a compound stmt regardless of the language.
10587330f729Sjoerg   while (Tok.is(tok::kw___label__)) {
10597330f729Sjoerg     SourceLocation LabelLoc = ConsumeToken();
10607330f729Sjoerg 
10617330f729Sjoerg     SmallVector<Decl *, 8> DeclsInGroup;
10627330f729Sjoerg     while (1) {
10637330f729Sjoerg       if (Tok.isNot(tok::identifier)) {
10647330f729Sjoerg         Diag(Tok, diag::err_expected) << tok::identifier;
10657330f729Sjoerg         break;
10667330f729Sjoerg       }
10677330f729Sjoerg 
10687330f729Sjoerg       IdentifierInfo *II = Tok.getIdentifierInfo();
10697330f729Sjoerg       SourceLocation IdLoc = ConsumeToken();
10707330f729Sjoerg       DeclsInGroup.push_back(Actions.LookupOrCreateLabel(II, IdLoc, LabelLoc));
10717330f729Sjoerg 
10727330f729Sjoerg       if (!TryConsumeToken(tok::comma))
10737330f729Sjoerg         break;
10747330f729Sjoerg     }
10757330f729Sjoerg 
10767330f729Sjoerg     DeclSpec DS(AttrFactory);
10777330f729Sjoerg     DeclGroupPtrTy Res =
10787330f729Sjoerg         Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup);
10797330f729Sjoerg     StmtResult R = Actions.ActOnDeclStmt(Res, LabelLoc, Tok.getLocation());
10807330f729Sjoerg 
10817330f729Sjoerg     ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
10827330f729Sjoerg     if (R.isUsable())
10837330f729Sjoerg       Stmts.push_back(R.get());
10847330f729Sjoerg   }
10857330f729Sjoerg 
10867330f729Sjoerg   ParsedStmtContext SubStmtCtx =
10877330f729Sjoerg       ParsedStmtContext::Compound |
10887330f729Sjoerg       (isStmtExpr ? ParsedStmtContext::InStmtExpr : ParsedStmtContext());
10897330f729Sjoerg 
10907330f729Sjoerg   while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
10917330f729Sjoerg          Tok.isNot(tok::eof)) {
10927330f729Sjoerg     if (Tok.is(tok::annot_pragma_unused)) {
10937330f729Sjoerg       HandlePragmaUnused();
10947330f729Sjoerg       continue;
10957330f729Sjoerg     }
10967330f729Sjoerg 
10977330f729Sjoerg     if (ConsumeNullStmt(Stmts))
10987330f729Sjoerg       continue;
10997330f729Sjoerg 
11007330f729Sjoerg     StmtResult R;
11017330f729Sjoerg     if (Tok.isNot(tok::kw___extension__)) {
11027330f729Sjoerg       R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
11037330f729Sjoerg     } else {
11047330f729Sjoerg       // __extension__ can start declarations and it can also be a unary
11057330f729Sjoerg       // operator for expressions.  Consume multiple __extension__ markers here
11067330f729Sjoerg       // until we can determine which is which.
11077330f729Sjoerg       // FIXME: This loses extension expressions in the AST!
11087330f729Sjoerg       SourceLocation ExtLoc = ConsumeToken();
11097330f729Sjoerg       while (Tok.is(tok::kw___extension__))
11107330f729Sjoerg         ConsumeToken();
11117330f729Sjoerg 
11127330f729Sjoerg       ParsedAttributesWithRange attrs(AttrFactory);
11137330f729Sjoerg       MaybeParseCXX11Attributes(attrs, nullptr,
11147330f729Sjoerg                                 /*MightBeObjCMessageSend*/ true);
11157330f729Sjoerg 
11167330f729Sjoerg       // If this is the start of a declaration, parse it as such.
11177330f729Sjoerg       if (isDeclarationStatement()) {
11187330f729Sjoerg         // __extension__ silences extension warnings in the subdeclaration.
11197330f729Sjoerg         // FIXME: Save the __extension__ on the decl as a node somehow?
11207330f729Sjoerg         ExtensionRAIIObject O(Diags);
11217330f729Sjoerg 
11227330f729Sjoerg         SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
11237330f729Sjoerg         DeclGroupPtrTy Res =
1124*e038c9c4Sjoerg             ParseDeclaration(DeclaratorContext::Block, DeclEnd, attrs);
11257330f729Sjoerg         R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);
11267330f729Sjoerg       } else {
11277330f729Sjoerg         // Otherwise this was a unary __extension__ marker.
11287330f729Sjoerg         ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
11297330f729Sjoerg 
11307330f729Sjoerg         if (Res.isInvalid()) {
11317330f729Sjoerg           SkipUntil(tok::semi);
11327330f729Sjoerg           continue;
11337330f729Sjoerg         }
11347330f729Sjoerg 
11357330f729Sjoerg         // Eat the semicolon at the end of stmt and convert the expr into a
11367330f729Sjoerg         // statement.
11377330f729Sjoerg         ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
11387330f729Sjoerg         R = handleExprStmt(Res, SubStmtCtx);
11397330f729Sjoerg         if (R.isUsable())
1140*e038c9c4Sjoerg           R = Actions.ActOnAttributedStmt(attrs, R.get());
11417330f729Sjoerg       }
11427330f729Sjoerg     }
11437330f729Sjoerg 
11447330f729Sjoerg     if (R.isUsable())
11457330f729Sjoerg       Stmts.push_back(R.get());
11467330f729Sjoerg   }
11477330f729Sjoerg 
11487330f729Sjoerg   SourceLocation CloseLoc = Tok.getLocation();
11497330f729Sjoerg 
11507330f729Sjoerg   // We broke out of the while loop because we found a '}' or EOF.
1151*e038c9c4Sjoerg   if (!T.consumeClose()) {
1152*e038c9c4Sjoerg     // If this is the '})' of a statement expression, check that it's written
1153*e038c9c4Sjoerg     // in a sensible way.
1154*e038c9c4Sjoerg     if (isStmtExpr && Tok.is(tok::r_paren))
1155*e038c9c4Sjoerg       checkCompoundToken(CloseLoc, tok::r_brace, CompoundToken::StmtExprEnd);
1156*e038c9c4Sjoerg   } else {
11577330f729Sjoerg     // Recover by creating a compound statement with what we parsed so far,
1158*e038c9c4Sjoerg     // instead of dropping everything and returning StmtError().
1159*e038c9c4Sjoerg   }
1160*e038c9c4Sjoerg 
1161*e038c9c4Sjoerg   if (T.getCloseLocation().isValid())
11627330f729Sjoerg     CloseLoc = T.getCloseLocation();
11637330f729Sjoerg 
11647330f729Sjoerg   return Actions.ActOnCompoundStmt(T.getOpenLocation(), CloseLoc,
11657330f729Sjoerg                                    Stmts, isStmtExpr);
11667330f729Sjoerg }
11677330f729Sjoerg 
11687330f729Sjoerg /// ParseParenExprOrCondition:
11697330f729Sjoerg /// [C  ]     '(' expression ')'
11707330f729Sjoerg /// [C++]     '(' condition ')'
11717330f729Sjoerg /// [C++1z]   '(' init-statement[opt] condition ')'
11727330f729Sjoerg ///
11737330f729Sjoerg /// This function parses and performs error recovery on the specified condition
11747330f729Sjoerg /// or expression (depending on whether we're in C++ or C mode).  This function
11757330f729Sjoerg /// goes out of its way to recover well.  It returns true if there was a parser
11767330f729Sjoerg /// error (the right paren couldn't be found), which indicates that the caller
11777330f729Sjoerg /// should try to recover harder.  It returns false if the condition is
11787330f729Sjoerg /// successfully parsed.  Note that a successful parse can still have semantic
11797330f729Sjoerg /// errors in the condition.
1180*e038c9c4Sjoerg /// Additionally, if LParenLoc and RParenLoc are non-null, it will assign
1181*e038c9c4Sjoerg /// the location of the outer-most '(' and ')', respectively, to them.
ParseParenExprOrCondition(StmtResult * InitStmt,Sema::ConditionResult & Cond,SourceLocation Loc,Sema::ConditionKind CK,SourceLocation * LParenLoc,SourceLocation * RParenLoc)11827330f729Sjoerg bool Parser::ParseParenExprOrCondition(StmtResult *InitStmt,
11837330f729Sjoerg                                        Sema::ConditionResult &Cond,
11847330f729Sjoerg                                        SourceLocation Loc,
1185*e038c9c4Sjoerg                                        Sema::ConditionKind CK,
1186*e038c9c4Sjoerg                                        SourceLocation *LParenLoc,
1187*e038c9c4Sjoerg                                        SourceLocation *RParenLoc) {
11887330f729Sjoerg   BalancedDelimiterTracker T(*this, tok::l_paren);
11897330f729Sjoerg   T.consumeOpen();
11907330f729Sjoerg 
11917330f729Sjoerg   if (getLangOpts().CPlusPlus)
11927330f729Sjoerg     Cond = ParseCXXCondition(InitStmt, Loc, CK);
11937330f729Sjoerg   else {
11947330f729Sjoerg     ExprResult CondExpr = ParseExpression();
11957330f729Sjoerg 
11967330f729Sjoerg     // If required, convert to a boolean value.
11977330f729Sjoerg     if (CondExpr.isInvalid())
11987330f729Sjoerg       Cond = Sema::ConditionError();
11997330f729Sjoerg     else
12007330f729Sjoerg       Cond = Actions.ActOnCondition(getCurScope(), Loc, CondExpr.get(), CK);
12017330f729Sjoerg   }
12027330f729Sjoerg 
12037330f729Sjoerg   // If the parser was confused by the condition and we don't have a ')', try to
12047330f729Sjoerg   // recover by skipping ahead to a semi and bailing out.  If condexp is
12057330f729Sjoerg   // semantically invalid but we have well formed code, keep going.
12067330f729Sjoerg   if (Cond.isInvalid() && Tok.isNot(tok::r_paren)) {
12077330f729Sjoerg     SkipUntil(tok::semi);
12087330f729Sjoerg     // Skipping may have stopped if it found the containing ')'.  If so, we can
12097330f729Sjoerg     // continue parsing the if statement.
12107330f729Sjoerg     if (Tok.isNot(tok::r_paren))
12117330f729Sjoerg       return true;
12127330f729Sjoerg   }
12137330f729Sjoerg 
12147330f729Sjoerg   // Otherwise the condition is valid or the rparen is present.
12157330f729Sjoerg   T.consumeClose();
12167330f729Sjoerg 
1217*e038c9c4Sjoerg   if (LParenLoc != nullptr) {
1218*e038c9c4Sjoerg     *LParenLoc = T.getOpenLocation();
1219*e038c9c4Sjoerg   }
1220*e038c9c4Sjoerg   if (RParenLoc != nullptr) {
1221*e038c9c4Sjoerg     *RParenLoc = T.getCloseLocation();
1222*e038c9c4Sjoerg   }
1223*e038c9c4Sjoerg 
12247330f729Sjoerg   // Check for extraneous ')'s to catch things like "if (foo())) {".  We know
12257330f729Sjoerg   // that all callers are looking for a statement after the condition, so ")"
12267330f729Sjoerg   // isn't valid.
12277330f729Sjoerg   while (Tok.is(tok::r_paren)) {
12287330f729Sjoerg     Diag(Tok, diag::err_extraneous_rparen_in_condition)
12297330f729Sjoerg       << FixItHint::CreateRemoval(Tok.getLocation());
12307330f729Sjoerg     ConsumeParen();
12317330f729Sjoerg   }
12327330f729Sjoerg 
12337330f729Sjoerg   return false;
12347330f729Sjoerg }
12357330f729Sjoerg 
1236*e038c9c4Sjoerg namespace {
1237*e038c9c4Sjoerg 
1238*e038c9c4Sjoerg enum MisleadingStatementKind { MSK_if, MSK_else, MSK_for, MSK_while };
1239*e038c9c4Sjoerg 
1240*e038c9c4Sjoerg struct MisleadingIndentationChecker {
1241*e038c9c4Sjoerg   Parser &P;
1242*e038c9c4Sjoerg   SourceLocation StmtLoc;
1243*e038c9c4Sjoerg   SourceLocation PrevLoc;
1244*e038c9c4Sjoerg   unsigned NumDirectives;
1245*e038c9c4Sjoerg   MisleadingStatementKind Kind;
1246*e038c9c4Sjoerg   bool ShouldSkip;
MisleadingIndentationChecker__anon81a834f20311::MisleadingIndentationChecker1247*e038c9c4Sjoerg   MisleadingIndentationChecker(Parser &P, MisleadingStatementKind K,
1248*e038c9c4Sjoerg                                SourceLocation SL)
1249*e038c9c4Sjoerg       : P(P), StmtLoc(SL), PrevLoc(P.getCurToken().getLocation()),
1250*e038c9c4Sjoerg         NumDirectives(P.getPreprocessor().getNumDirectives()), Kind(K),
1251*e038c9c4Sjoerg         ShouldSkip(P.getCurToken().is(tok::l_brace)) {
1252*e038c9c4Sjoerg     if (!P.MisleadingIndentationElseLoc.isInvalid()) {
1253*e038c9c4Sjoerg       StmtLoc = P.MisleadingIndentationElseLoc;
1254*e038c9c4Sjoerg       P.MisleadingIndentationElseLoc = SourceLocation();
1255*e038c9c4Sjoerg     }
1256*e038c9c4Sjoerg     if (Kind == MSK_else && !ShouldSkip)
1257*e038c9c4Sjoerg       P.MisleadingIndentationElseLoc = SL;
1258*e038c9c4Sjoerg   }
1259*e038c9c4Sjoerg 
1260*e038c9c4Sjoerg   /// Compute the column number will aligning tabs on TabStop (-ftabstop), this
1261*e038c9c4Sjoerg   /// gives the visual indentation of the SourceLocation.
getVisualIndentation__anon81a834f20311::MisleadingIndentationChecker1262*e038c9c4Sjoerg   static unsigned getVisualIndentation(SourceManager &SM, SourceLocation Loc) {
1263*e038c9c4Sjoerg     unsigned TabStop = SM.getDiagnostics().getDiagnosticOptions().TabStop;
1264*e038c9c4Sjoerg 
1265*e038c9c4Sjoerg     unsigned ColNo = SM.getSpellingColumnNumber(Loc);
1266*e038c9c4Sjoerg     if (ColNo == 0 || TabStop == 1)
1267*e038c9c4Sjoerg       return ColNo;
1268*e038c9c4Sjoerg 
1269*e038c9c4Sjoerg     std::pair<FileID, unsigned> FIDAndOffset = SM.getDecomposedLoc(Loc);
1270*e038c9c4Sjoerg 
1271*e038c9c4Sjoerg     bool Invalid;
1272*e038c9c4Sjoerg     StringRef BufData = SM.getBufferData(FIDAndOffset.first, &Invalid);
1273*e038c9c4Sjoerg     if (Invalid)
1274*e038c9c4Sjoerg       return 0;
1275*e038c9c4Sjoerg 
1276*e038c9c4Sjoerg     const char *EndPos = BufData.data() + FIDAndOffset.second;
1277*e038c9c4Sjoerg     // FileOffset are 0-based and Column numbers are 1-based
1278*e038c9c4Sjoerg     assert(FIDAndOffset.second + 1 >= ColNo &&
1279*e038c9c4Sjoerg            "Column number smaller than file offset?");
1280*e038c9c4Sjoerg 
1281*e038c9c4Sjoerg     unsigned VisualColumn = 0; // Stored as 0-based column, here.
1282*e038c9c4Sjoerg     // Loop from beginning of line up to Loc's file position, counting columns,
1283*e038c9c4Sjoerg     // expanding tabs.
1284*e038c9c4Sjoerg     for (const char *CurPos = EndPos - (ColNo - 1); CurPos != EndPos;
1285*e038c9c4Sjoerg          ++CurPos) {
1286*e038c9c4Sjoerg       if (*CurPos == '\t')
1287*e038c9c4Sjoerg         // Advance visual column to next tabstop.
1288*e038c9c4Sjoerg         VisualColumn += (TabStop - VisualColumn % TabStop);
1289*e038c9c4Sjoerg       else
1290*e038c9c4Sjoerg         VisualColumn++;
1291*e038c9c4Sjoerg     }
1292*e038c9c4Sjoerg     return VisualColumn + 1;
1293*e038c9c4Sjoerg   }
1294*e038c9c4Sjoerg 
Check__anon81a834f20311::MisleadingIndentationChecker1295*e038c9c4Sjoerg   void Check() {
1296*e038c9c4Sjoerg     Token Tok = P.getCurToken();
1297*e038c9c4Sjoerg     if (P.getActions().getDiagnostics().isIgnored(
1298*e038c9c4Sjoerg             diag::warn_misleading_indentation, Tok.getLocation()) ||
1299*e038c9c4Sjoerg         ShouldSkip || NumDirectives != P.getPreprocessor().getNumDirectives() ||
1300*e038c9c4Sjoerg         Tok.isOneOf(tok::semi, tok::r_brace) || Tok.isAnnotation() ||
1301*e038c9c4Sjoerg         Tok.getLocation().isMacroID() || PrevLoc.isMacroID() ||
1302*e038c9c4Sjoerg         StmtLoc.isMacroID() ||
1303*e038c9c4Sjoerg         (Kind == MSK_else && P.MisleadingIndentationElseLoc.isInvalid())) {
1304*e038c9c4Sjoerg       P.MisleadingIndentationElseLoc = SourceLocation();
1305*e038c9c4Sjoerg       return;
1306*e038c9c4Sjoerg     }
1307*e038c9c4Sjoerg     if (Kind == MSK_else)
1308*e038c9c4Sjoerg       P.MisleadingIndentationElseLoc = SourceLocation();
1309*e038c9c4Sjoerg 
1310*e038c9c4Sjoerg     SourceManager &SM = P.getPreprocessor().getSourceManager();
1311*e038c9c4Sjoerg     unsigned PrevColNum = getVisualIndentation(SM, PrevLoc);
1312*e038c9c4Sjoerg     unsigned CurColNum = getVisualIndentation(SM, Tok.getLocation());
1313*e038c9c4Sjoerg     unsigned StmtColNum = getVisualIndentation(SM, StmtLoc);
1314*e038c9c4Sjoerg 
1315*e038c9c4Sjoerg     if (PrevColNum != 0 && CurColNum != 0 && StmtColNum != 0 &&
1316*e038c9c4Sjoerg         ((PrevColNum > StmtColNum && PrevColNum == CurColNum) ||
1317*e038c9c4Sjoerg          !Tok.isAtStartOfLine()) &&
1318*e038c9c4Sjoerg         SM.getPresumedLineNumber(StmtLoc) !=
1319*e038c9c4Sjoerg             SM.getPresumedLineNumber(Tok.getLocation()) &&
1320*e038c9c4Sjoerg         (Tok.isNot(tok::identifier) ||
1321*e038c9c4Sjoerg          P.getPreprocessor().LookAhead(0).isNot(tok::colon))) {
1322*e038c9c4Sjoerg       P.Diag(Tok.getLocation(), diag::warn_misleading_indentation) << Kind;
1323*e038c9c4Sjoerg       P.Diag(StmtLoc, diag::note_previous_statement);
1324*e038c9c4Sjoerg     }
1325*e038c9c4Sjoerg   }
1326*e038c9c4Sjoerg };
1327*e038c9c4Sjoerg 
1328*e038c9c4Sjoerg }
13297330f729Sjoerg 
13307330f729Sjoerg /// ParseIfStatement
13317330f729Sjoerg ///       if-statement: [C99 6.8.4.1]
13327330f729Sjoerg ///         'if' '(' expression ')' statement
13337330f729Sjoerg ///         'if' '(' expression ')' statement 'else' statement
13347330f729Sjoerg /// [C++]   'if' '(' condition ')' statement
13357330f729Sjoerg /// [C++]   'if' '(' condition ')' statement 'else' statement
13367330f729Sjoerg ///
ParseIfStatement(SourceLocation * TrailingElseLoc)13377330f729Sjoerg StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
13387330f729Sjoerg   assert(Tok.is(tok::kw_if) && "Not an if stmt!");
13397330f729Sjoerg   SourceLocation IfLoc = ConsumeToken();  // eat the 'if'.
13407330f729Sjoerg 
13417330f729Sjoerg   bool IsConstexpr = false;
13427330f729Sjoerg   if (Tok.is(tok::kw_constexpr)) {
13437330f729Sjoerg     Diag(Tok, getLangOpts().CPlusPlus17 ? diag::warn_cxx14_compat_constexpr_if
13447330f729Sjoerg                                         : diag::ext_constexpr_if);
13457330f729Sjoerg     IsConstexpr = true;
13467330f729Sjoerg     ConsumeToken();
13477330f729Sjoerg   }
13487330f729Sjoerg 
13497330f729Sjoerg   if (Tok.isNot(tok::l_paren)) {
13507330f729Sjoerg     Diag(Tok, diag::err_expected_lparen_after) << "if";
13517330f729Sjoerg     SkipUntil(tok::semi);
13527330f729Sjoerg     return StmtError();
13537330f729Sjoerg   }
13547330f729Sjoerg 
13557330f729Sjoerg   bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
13567330f729Sjoerg 
13577330f729Sjoerg   // C99 6.8.4p3 - In C99, the if statement is a block.  This is not
13587330f729Sjoerg   // the case for C90.
13597330f729Sjoerg   //
13607330f729Sjoerg   // C++ 6.4p3:
13617330f729Sjoerg   // A name introduced by a declaration in a condition is in scope from its
13627330f729Sjoerg   // point of declaration until the end of the substatements controlled by the
13637330f729Sjoerg   // condition.
13647330f729Sjoerg   // C++ 3.3.2p4:
13657330f729Sjoerg   // Names declared in the for-init-statement, and in the condition of if,
13667330f729Sjoerg   // while, for, and switch statements are local to the if, while, for, or
13677330f729Sjoerg   // switch statement (including the controlled statement).
13687330f729Sjoerg   //
13697330f729Sjoerg   ParseScope IfScope(this, Scope::DeclScope | Scope::ControlScope, C99orCXX);
13707330f729Sjoerg 
13717330f729Sjoerg   // Parse the condition.
13727330f729Sjoerg   StmtResult InitStmt;
13737330f729Sjoerg   Sema::ConditionResult Cond;
1374*e038c9c4Sjoerg   SourceLocation LParen;
1375*e038c9c4Sjoerg   SourceLocation RParen;
13767330f729Sjoerg   if (ParseParenExprOrCondition(&InitStmt, Cond, IfLoc,
13777330f729Sjoerg                                 IsConstexpr ? Sema::ConditionKind::ConstexprIf
1378*e038c9c4Sjoerg                                             : Sema::ConditionKind::Boolean,
1379*e038c9c4Sjoerg                                 &LParen, &RParen))
13807330f729Sjoerg     return StmtError();
13817330f729Sjoerg 
13827330f729Sjoerg   llvm::Optional<bool> ConstexprCondition;
13837330f729Sjoerg   if (IsConstexpr)
13847330f729Sjoerg     ConstexprCondition = Cond.getKnownValue();
13857330f729Sjoerg 
1386*e038c9c4Sjoerg   bool IsBracedThen = Tok.is(tok::l_brace);
1387*e038c9c4Sjoerg 
13887330f729Sjoerg   // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
13897330f729Sjoerg   // there is no compound stmt.  C90 does not have this clause.  We only do this
13907330f729Sjoerg   // if the body isn't a compound statement to avoid push/pop in common cases.
13917330f729Sjoerg   //
13927330f729Sjoerg   // C++ 6.4p1:
13937330f729Sjoerg   // The substatement in a selection-statement (each substatement, in the else
13947330f729Sjoerg   // form of the if statement) implicitly defines a local scope.
13957330f729Sjoerg   //
13967330f729Sjoerg   // For C++ we create a scope for the condition and a new scope for
13977330f729Sjoerg   // substatements because:
13987330f729Sjoerg   // -When the 'then' scope exits, we want the condition declaration to still be
13997330f729Sjoerg   //    active for the 'else' scope too.
14007330f729Sjoerg   // -Sema will detect name clashes by considering declarations of a
14017330f729Sjoerg   //    'ControlScope' as part of its direct subscope.
14027330f729Sjoerg   // -If we wanted the condition and substatement to be in the same scope, we
14037330f729Sjoerg   //    would have to notify ParseStatement not to create a new scope. It's
14047330f729Sjoerg   //    simpler to let it create a new scope.
14057330f729Sjoerg   //
1406*e038c9c4Sjoerg   ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, IsBracedThen);
1407*e038c9c4Sjoerg 
1408*e038c9c4Sjoerg   MisleadingIndentationChecker MIChecker(*this, MSK_if, IfLoc);
14097330f729Sjoerg 
14107330f729Sjoerg   // Read the 'then' stmt.
14117330f729Sjoerg   SourceLocation ThenStmtLoc = Tok.getLocation();
14127330f729Sjoerg 
14137330f729Sjoerg   SourceLocation InnerStatementTrailingElseLoc;
14147330f729Sjoerg   StmtResult ThenStmt;
14157330f729Sjoerg   {
14167330f729Sjoerg     EnterExpressionEvaluationContext PotentiallyDiscarded(
14177330f729Sjoerg         Actions, Sema::ExpressionEvaluationContext::DiscardedStatement, nullptr,
14187330f729Sjoerg         Sema::ExpressionEvaluationContextRecord::EK_Other,
14197330f729Sjoerg         /*ShouldEnter=*/ConstexprCondition && !*ConstexprCondition);
14207330f729Sjoerg     ThenStmt = ParseStatement(&InnerStatementTrailingElseLoc);
14217330f729Sjoerg   }
14227330f729Sjoerg 
1423*e038c9c4Sjoerg   if (Tok.isNot(tok::kw_else))
1424*e038c9c4Sjoerg     MIChecker.Check();
1425*e038c9c4Sjoerg 
14267330f729Sjoerg   // Pop the 'if' scope if needed.
14277330f729Sjoerg   InnerScope.Exit();
14287330f729Sjoerg 
14297330f729Sjoerg   // If it has an else, parse it.
14307330f729Sjoerg   SourceLocation ElseLoc;
14317330f729Sjoerg   SourceLocation ElseStmtLoc;
14327330f729Sjoerg   StmtResult ElseStmt;
14337330f729Sjoerg 
14347330f729Sjoerg   if (Tok.is(tok::kw_else)) {
14357330f729Sjoerg     if (TrailingElseLoc)
14367330f729Sjoerg       *TrailingElseLoc = Tok.getLocation();
14377330f729Sjoerg 
14387330f729Sjoerg     ElseLoc = ConsumeToken();
14397330f729Sjoerg     ElseStmtLoc = Tok.getLocation();
14407330f729Sjoerg 
14417330f729Sjoerg     // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
14427330f729Sjoerg     // there is no compound stmt.  C90 does not have this clause.  We only do
14437330f729Sjoerg     // this if the body isn't a compound statement to avoid push/pop in common
14447330f729Sjoerg     // cases.
14457330f729Sjoerg     //
14467330f729Sjoerg     // C++ 6.4p1:
14477330f729Sjoerg     // The substatement in a selection-statement (each substatement, in the else
14487330f729Sjoerg     // form of the if statement) implicitly defines a local scope.
14497330f729Sjoerg     //
14507330f729Sjoerg     ParseScope InnerScope(this, Scope::DeclScope, C99orCXX,
14517330f729Sjoerg                           Tok.is(tok::l_brace));
14527330f729Sjoerg 
1453*e038c9c4Sjoerg     MisleadingIndentationChecker MIChecker(*this, MSK_else, ElseLoc);
1454*e038c9c4Sjoerg 
14557330f729Sjoerg     EnterExpressionEvaluationContext PotentiallyDiscarded(
14567330f729Sjoerg         Actions, Sema::ExpressionEvaluationContext::DiscardedStatement, nullptr,
14577330f729Sjoerg         Sema::ExpressionEvaluationContextRecord::EK_Other,
14587330f729Sjoerg         /*ShouldEnter=*/ConstexprCondition && *ConstexprCondition);
14597330f729Sjoerg     ElseStmt = ParseStatement();
14607330f729Sjoerg 
1461*e038c9c4Sjoerg     if (ElseStmt.isUsable())
1462*e038c9c4Sjoerg       MIChecker.Check();
1463*e038c9c4Sjoerg 
14647330f729Sjoerg     // Pop the 'else' scope if needed.
14657330f729Sjoerg     InnerScope.Exit();
14667330f729Sjoerg   } else if (Tok.is(tok::code_completion)) {
14677330f729Sjoerg     cutOffParsing();
1468*e038c9c4Sjoerg     Actions.CodeCompleteAfterIf(getCurScope(), IsBracedThen);
14697330f729Sjoerg     return StmtError();
14707330f729Sjoerg   } else if (InnerStatementTrailingElseLoc.isValid()) {
14717330f729Sjoerg     Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else);
14727330f729Sjoerg   }
14737330f729Sjoerg 
14747330f729Sjoerg   IfScope.Exit();
14757330f729Sjoerg 
14767330f729Sjoerg   // If the then or else stmt is invalid and the other is valid (and present),
14777330f729Sjoerg   // make turn the invalid one into a null stmt to avoid dropping the other
14787330f729Sjoerg   // part.  If both are invalid, return error.
14797330f729Sjoerg   if ((ThenStmt.isInvalid() && ElseStmt.isInvalid()) ||
14807330f729Sjoerg       (ThenStmt.isInvalid() && ElseStmt.get() == nullptr) ||
14817330f729Sjoerg       (ThenStmt.get() == nullptr && ElseStmt.isInvalid())) {
14827330f729Sjoerg     // Both invalid, or one is invalid and other is non-present: return error.
14837330f729Sjoerg     return StmtError();
14847330f729Sjoerg   }
14857330f729Sjoerg 
14867330f729Sjoerg   // Now if either are invalid, replace with a ';'.
14877330f729Sjoerg   if (ThenStmt.isInvalid())
14887330f729Sjoerg     ThenStmt = Actions.ActOnNullStmt(ThenStmtLoc);
14897330f729Sjoerg   if (ElseStmt.isInvalid())
14907330f729Sjoerg     ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);
14917330f729Sjoerg 
1492*e038c9c4Sjoerg   return Actions.ActOnIfStmt(IfLoc, IsConstexpr, LParen, InitStmt.get(), Cond,
1493*e038c9c4Sjoerg                              RParen, ThenStmt.get(), ElseLoc, ElseStmt.get());
14947330f729Sjoerg }
14957330f729Sjoerg 
14967330f729Sjoerg /// ParseSwitchStatement
14977330f729Sjoerg ///       switch-statement:
14987330f729Sjoerg ///         'switch' '(' expression ')' statement
14997330f729Sjoerg /// [C++]   'switch' '(' condition ')' statement
ParseSwitchStatement(SourceLocation * TrailingElseLoc)15007330f729Sjoerg StmtResult Parser::ParseSwitchStatement(SourceLocation *TrailingElseLoc) {
15017330f729Sjoerg   assert(Tok.is(tok::kw_switch) && "Not a switch stmt!");
15027330f729Sjoerg   SourceLocation SwitchLoc = ConsumeToken();  // eat the 'switch'.
15037330f729Sjoerg 
15047330f729Sjoerg   if (Tok.isNot(tok::l_paren)) {
15057330f729Sjoerg     Diag(Tok, diag::err_expected_lparen_after) << "switch";
15067330f729Sjoerg     SkipUntil(tok::semi);
15077330f729Sjoerg     return StmtError();
15087330f729Sjoerg   }
15097330f729Sjoerg 
15107330f729Sjoerg   bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
15117330f729Sjoerg 
15127330f729Sjoerg   // C99 6.8.4p3 - In C99, the switch statement is a block.  This is
15137330f729Sjoerg   // not the case for C90.  Start the switch scope.
15147330f729Sjoerg   //
15157330f729Sjoerg   // C++ 6.4p3:
15167330f729Sjoerg   // A name introduced by a declaration in a condition is in scope from its
15177330f729Sjoerg   // point of declaration until the end of the substatements controlled by the
15187330f729Sjoerg   // condition.
15197330f729Sjoerg   // C++ 3.3.2p4:
15207330f729Sjoerg   // Names declared in the for-init-statement, and in the condition of if,
15217330f729Sjoerg   // while, for, and switch statements are local to the if, while, for, or
15227330f729Sjoerg   // switch statement (including the controlled statement).
15237330f729Sjoerg   //
15247330f729Sjoerg   unsigned ScopeFlags = Scope::SwitchScope;
15257330f729Sjoerg   if (C99orCXX)
15267330f729Sjoerg     ScopeFlags |= Scope::DeclScope | Scope::ControlScope;
15277330f729Sjoerg   ParseScope SwitchScope(this, ScopeFlags);
15287330f729Sjoerg 
15297330f729Sjoerg   // Parse the condition.
15307330f729Sjoerg   StmtResult InitStmt;
15317330f729Sjoerg   Sema::ConditionResult Cond;
1532*e038c9c4Sjoerg   SourceLocation LParen;
1533*e038c9c4Sjoerg   SourceLocation RParen;
15347330f729Sjoerg   if (ParseParenExprOrCondition(&InitStmt, Cond, SwitchLoc,
1535*e038c9c4Sjoerg                                 Sema::ConditionKind::Switch, &LParen, &RParen))
15367330f729Sjoerg     return StmtError();
15377330f729Sjoerg 
1538*e038c9c4Sjoerg   StmtResult Switch = Actions.ActOnStartOfSwitchStmt(
1539*e038c9c4Sjoerg       SwitchLoc, LParen, InitStmt.get(), Cond, RParen);
15407330f729Sjoerg 
15417330f729Sjoerg   if (Switch.isInvalid()) {
15427330f729Sjoerg     // Skip the switch body.
15437330f729Sjoerg     // FIXME: This is not optimal recovery, but parsing the body is more
15447330f729Sjoerg     // dangerous due to the presence of case and default statements, which
15457330f729Sjoerg     // will have no place to connect back with the switch.
15467330f729Sjoerg     if (Tok.is(tok::l_brace)) {
15477330f729Sjoerg       ConsumeBrace();
15487330f729Sjoerg       SkipUntil(tok::r_brace);
15497330f729Sjoerg     } else
15507330f729Sjoerg       SkipUntil(tok::semi);
15517330f729Sjoerg     return Switch;
15527330f729Sjoerg   }
15537330f729Sjoerg 
15547330f729Sjoerg   // C99 6.8.4p3 - In C99, the body of the switch statement is a scope, even if
15557330f729Sjoerg   // there is no compound stmt.  C90 does not have this clause.  We only do this
15567330f729Sjoerg   // if the body isn't a compound statement to avoid push/pop in common cases.
15577330f729Sjoerg   //
15587330f729Sjoerg   // C++ 6.4p1:
15597330f729Sjoerg   // The substatement in a selection-statement (each substatement, in the else
15607330f729Sjoerg   // form of the if statement) implicitly defines a local scope.
15617330f729Sjoerg   //
15627330f729Sjoerg   // See comments in ParseIfStatement for why we create a scope for the
15637330f729Sjoerg   // condition and a new scope for substatement in C++.
15647330f729Sjoerg   //
15657330f729Sjoerg   getCurScope()->AddFlags(Scope::BreakScope);
15667330f729Sjoerg   ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
15677330f729Sjoerg 
15687330f729Sjoerg   // We have incremented the mangling number for the SwitchScope and the
15697330f729Sjoerg   // InnerScope, which is one too many.
15707330f729Sjoerg   if (C99orCXX)
15717330f729Sjoerg     getCurScope()->decrementMSManglingNumber();
15727330f729Sjoerg 
15737330f729Sjoerg   // Read the body statement.
15747330f729Sjoerg   StmtResult Body(ParseStatement(TrailingElseLoc));
15757330f729Sjoerg 
15767330f729Sjoerg   // Pop the scopes.
15777330f729Sjoerg   InnerScope.Exit();
15787330f729Sjoerg   SwitchScope.Exit();
15797330f729Sjoerg 
15807330f729Sjoerg   return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.get(), Body.get());
15817330f729Sjoerg }
15827330f729Sjoerg 
15837330f729Sjoerg /// ParseWhileStatement
15847330f729Sjoerg ///       while-statement: [C99 6.8.5.1]
15857330f729Sjoerg ///         'while' '(' expression ')' statement
15867330f729Sjoerg /// [C++]   'while' '(' condition ')' statement
ParseWhileStatement(SourceLocation * TrailingElseLoc)15877330f729Sjoerg StmtResult Parser::ParseWhileStatement(SourceLocation *TrailingElseLoc) {
15887330f729Sjoerg   assert(Tok.is(tok::kw_while) && "Not a while stmt!");
15897330f729Sjoerg   SourceLocation WhileLoc = Tok.getLocation();
15907330f729Sjoerg   ConsumeToken();  // eat the 'while'.
15917330f729Sjoerg 
15927330f729Sjoerg   if (Tok.isNot(tok::l_paren)) {
15937330f729Sjoerg     Diag(Tok, diag::err_expected_lparen_after) << "while";
15947330f729Sjoerg     SkipUntil(tok::semi);
15957330f729Sjoerg     return StmtError();
15967330f729Sjoerg   }
15977330f729Sjoerg 
15987330f729Sjoerg   bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
15997330f729Sjoerg 
16007330f729Sjoerg   // C99 6.8.5p5 - In C99, the while statement is a block.  This is not
16017330f729Sjoerg   // the case for C90.  Start the loop scope.
16027330f729Sjoerg   //
16037330f729Sjoerg   // C++ 6.4p3:
16047330f729Sjoerg   // A name introduced by a declaration in a condition is in scope from its
16057330f729Sjoerg   // point of declaration until the end of the substatements controlled by the
16067330f729Sjoerg   // condition.
16077330f729Sjoerg   // C++ 3.3.2p4:
16087330f729Sjoerg   // Names declared in the for-init-statement, and in the condition of if,
16097330f729Sjoerg   // while, for, and switch statements are local to the if, while, for, or
16107330f729Sjoerg   // switch statement (including the controlled statement).
16117330f729Sjoerg   //
16127330f729Sjoerg   unsigned ScopeFlags;
16137330f729Sjoerg   if (C99orCXX)
16147330f729Sjoerg     ScopeFlags = Scope::BreakScope | Scope::ContinueScope |
16157330f729Sjoerg                  Scope::DeclScope  | Scope::ControlScope;
16167330f729Sjoerg   else
16177330f729Sjoerg     ScopeFlags = Scope::BreakScope | Scope::ContinueScope;
16187330f729Sjoerg   ParseScope WhileScope(this, ScopeFlags);
16197330f729Sjoerg 
16207330f729Sjoerg   // Parse the condition.
16217330f729Sjoerg   Sema::ConditionResult Cond;
1622*e038c9c4Sjoerg   SourceLocation LParen;
1623*e038c9c4Sjoerg   SourceLocation RParen;
16247330f729Sjoerg   if (ParseParenExprOrCondition(nullptr, Cond, WhileLoc,
1625*e038c9c4Sjoerg                                 Sema::ConditionKind::Boolean, &LParen, &RParen))
16267330f729Sjoerg     return StmtError();
16277330f729Sjoerg 
16287330f729Sjoerg   // C99 6.8.5p5 - In C99, the body of the while statement is a scope, even if
16297330f729Sjoerg   // there is no compound stmt.  C90 does not have this clause.  We only do this
16307330f729Sjoerg   // if the body isn't a compound statement to avoid push/pop in common cases.
16317330f729Sjoerg   //
16327330f729Sjoerg   // C++ 6.5p2:
16337330f729Sjoerg   // The substatement in an iteration-statement implicitly defines a local scope
16347330f729Sjoerg   // which is entered and exited each time through the loop.
16357330f729Sjoerg   //
16367330f729Sjoerg   // See comments in ParseIfStatement for why we create a scope for the
16377330f729Sjoerg   // condition and a new scope for substatement in C++.
16387330f729Sjoerg   //
16397330f729Sjoerg   ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
16407330f729Sjoerg 
1641*e038c9c4Sjoerg   MisleadingIndentationChecker MIChecker(*this, MSK_while, WhileLoc);
1642*e038c9c4Sjoerg 
16437330f729Sjoerg   // Read the body statement.
16447330f729Sjoerg   StmtResult Body(ParseStatement(TrailingElseLoc));
16457330f729Sjoerg 
1646*e038c9c4Sjoerg   if (Body.isUsable())
1647*e038c9c4Sjoerg     MIChecker.Check();
16487330f729Sjoerg   // Pop the body scope if needed.
16497330f729Sjoerg   InnerScope.Exit();
16507330f729Sjoerg   WhileScope.Exit();
16517330f729Sjoerg 
16527330f729Sjoerg   if (Cond.isInvalid() || Body.isInvalid())
16537330f729Sjoerg     return StmtError();
16547330f729Sjoerg 
1655*e038c9c4Sjoerg   return Actions.ActOnWhileStmt(WhileLoc, LParen, Cond, RParen, Body.get());
16567330f729Sjoerg }
16577330f729Sjoerg 
16587330f729Sjoerg /// ParseDoStatement
16597330f729Sjoerg ///       do-statement: [C99 6.8.5.2]
16607330f729Sjoerg ///         'do' statement 'while' '(' expression ')' ';'
16617330f729Sjoerg /// Note: this lets the caller parse the end ';'.
ParseDoStatement()16627330f729Sjoerg StmtResult Parser::ParseDoStatement() {
16637330f729Sjoerg   assert(Tok.is(tok::kw_do) && "Not a do stmt!");
16647330f729Sjoerg   SourceLocation DoLoc = ConsumeToken();  // eat the 'do'.
16657330f729Sjoerg 
16667330f729Sjoerg   // C99 6.8.5p5 - In C99, the do statement is a block.  This is not
16677330f729Sjoerg   // the case for C90.  Start the loop scope.
16687330f729Sjoerg   unsigned ScopeFlags;
16697330f729Sjoerg   if (getLangOpts().C99)
16707330f729Sjoerg     ScopeFlags = Scope::BreakScope | Scope::ContinueScope | Scope::DeclScope;
16717330f729Sjoerg   else
16727330f729Sjoerg     ScopeFlags = Scope::BreakScope | Scope::ContinueScope;
16737330f729Sjoerg 
16747330f729Sjoerg   ParseScope DoScope(this, ScopeFlags);
16757330f729Sjoerg 
16767330f729Sjoerg   // C99 6.8.5p5 - In C99, the body of the do statement is a scope, even if
16777330f729Sjoerg   // there is no compound stmt.  C90 does not have this clause. We only do this
16787330f729Sjoerg   // if the body isn't a compound statement to avoid push/pop in common cases.
16797330f729Sjoerg   //
16807330f729Sjoerg   // C++ 6.5p2:
16817330f729Sjoerg   // The substatement in an iteration-statement implicitly defines a local scope
16827330f729Sjoerg   // which is entered and exited each time through the loop.
16837330f729Sjoerg   //
16847330f729Sjoerg   bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
16857330f729Sjoerg   ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
16867330f729Sjoerg 
16877330f729Sjoerg   // Read the body statement.
16887330f729Sjoerg   StmtResult Body(ParseStatement());
16897330f729Sjoerg 
16907330f729Sjoerg   // Pop the body scope if needed.
16917330f729Sjoerg   InnerScope.Exit();
16927330f729Sjoerg 
16937330f729Sjoerg   if (Tok.isNot(tok::kw_while)) {
16947330f729Sjoerg     if (!Body.isInvalid()) {
16957330f729Sjoerg       Diag(Tok, diag::err_expected_while);
16967330f729Sjoerg       Diag(DoLoc, diag::note_matching) << "'do'";
16977330f729Sjoerg       SkipUntil(tok::semi, StopBeforeMatch);
16987330f729Sjoerg     }
16997330f729Sjoerg     return StmtError();
17007330f729Sjoerg   }
17017330f729Sjoerg   SourceLocation WhileLoc = ConsumeToken();
17027330f729Sjoerg 
17037330f729Sjoerg   if (Tok.isNot(tok::l_paren)) {
17047330f729Sjoerg     Diag(Tok, diag::err_expected_lparen_after) << "do/while";
17057330f729Sjoerg     SkipUntil(tok::semi, StopBeforeMatch);
17067330f729Sjoerg     return StmtError();
17077330f729Sjoerg   }
17087330f729Sjoerg 
17097330f729Sjoerg   // Parse the parenthesized expression.
17107330f729Sjoerg   BalancedDelimiterTracker T(*this, tok::l_paren);
17117330f729Sjoerg   T.consumeOpen();
17127330f729Sjoerg 
17137330f729Sjoerg   // A do-while expression is not a condition, so can't have attributes.
17147330f729Sjoerg   DiagnoseAndSkipCXX11Attributes();
17157330f729Sjoerg 
17167330f729Sjoerg   ExprResult Cond = ParseExpression();
17177330f729Sjoerg   // Correct the typos in condition before closing the scope.
17187330f729Sjoerg   if (Cond.isUsable())
17197330f729Sjoerg     Cond = Actions.CorrectDelayedTyposInExpr(Cond);
17207330f729Sjoerg   T.consumeClose();
17217330f729Sjoerg   DoScope.Exit();
17227330f729Sjoerg 
17237330f729Sjoerg   if (Cond.isInvalid() || Body.isInvalid())
17247330f729Sjoerg     return StmtError();
17257330f729Sjoerg 
17267330f729Sjoerg   return Actions.ActOnDoStmt(DoLoc, Body.get(), WhileLoc, T.getOpenLocation(),
17277330f729Sjoerg                              Cond.get(), T.getCloseLocation());
17287330f729Sjoerg }
17297330f729Sjoerg 
isForRangeIdentifier()17307330f729Sjoerg bool Parser::isForRangeIdentifier() {
17317330f729Sjoerg   assert(Tok.is(tok::identifier));
17327330f729Sjoerg 
17337330f729Sjoerg   const Token &Next = NextToken();
17347330f729Sjoerg   if (Next.is(tok::colon))
17357330f729Sjoerg     return true;
17367330f729Sjoerg 
17377330f729Sjoerg   if (Next.isOneOf(tok::l_square, tok::kw_alignas)) {
17387330f729Sjoerg     TentativeParsingAction PA(*this);
17397330f729Sjoerg     ConsumeToken();
17407330f729Sjoerg     SkipCXX11Attributes();
17417330f729Sjoerg     bool Result = Tok.is(tok::colon);
17427330f729Sjoerg     PA.Revert();
17437330f729Sjoerg     return Result;
17447330f729Sjoerg   }
17457330f729Sjoerg 
17467330f729Sjoerg   return false;
17477330f729Sjoerg }
17487330f729Sjoerg 
17497330f729Sjoerg /// ParseForStatement
17507330f729Sjoerg ///       for-statement: [C99 6.8.5.3]
17517330f729Sjoerg ///         'for' '(' expr[opt] ';' expr[opt] ';' expr[opt] ')' statement
17527330f729Sjoerg ///         'for' '(' declaration expr[opt] ';' expr[opt] ')' statement
17537330f729Sjoerg /// [C++]   'for' '(' for-init-statement condition[opt] ';' expression[opt] ')'
17547330f729Sjoerg /// [C++]       statement
17557330f729Sjoerg /// [C++0x] 'for'
17567330f729Sjoerg ///             'co_await'[opt]    [Coroutines]
17577330f729Sjoerg ///             '(' for-range-declaration ':' for-range-initializer ')'
17587330f729Sjoerg ///             statement
17597330f729Sjoerg /// [OBJC2] 'for' '(' declaration 'in' expr ')' statement
17607330f729Sjoerg /// [OBJC2] 'for' '(' expr 'in' expr ')' statement
17617330f729Sjoerg ///
17627330f729Sjoerg /// [C++] for-init-statement:
17637330f729Sjoerg /// [C++]   expression-statement
17647330f729Sjoerg /// [C++]   simple-declaration
17657330f729Sjoerg ///
17667330f729Sjoerg /// [C++0x] for-range-declaration:
17677330f729Sjoerg /// [C++0x]   attribute-specifier-seq[opt] type-specifier-seq declarator
17687330f729Sjoerg /// [C++0x] for-range-initializer:
17697330f729Sjoerg /// [C++0x]   expression
17707330f729Sjoerg /// [C++0x]   braced-init-list            [TODO]
ParseForStatement(SourceLocation * TrailingElseLoc)17717330f729Sjoerg StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
17727330f729Sjoerg   assert(Tok.is(tok::kw_for) && "Not a for stmt!");
17737330f729Sjoerg   SourceLocation ForLoc = ConsumeToken();  // eat the 'for'.
17747330f729Sjoerg 
17757330f729Sjoerg   SourceLocation CoawaitLoc;
17767330f729Sjoerg   if (Tok.is(tok::kw_co_await))
17777330f729Sjoerg     CoawaitLoc = ConsumeToken();
17787330f729Sjoerg 
17797330f729Sjoerg   if (Tok.isNot(tok::l_paren)) {
17807330f729Sjoerg     Diag(Tok, diag::err_expected_lparen_after) << "for";
17817330f729Sjoerg     SkipUntil(tok::semi);
17827330f729Sjoerg     return StmtError();
17837330f729Sjoerg   }
17847330f729Sjoerg 
17857330f729Sjoerg   bool C99orCXXorObjC = getLangOpts().C99 || getLangOpts().CPlusPlus ||
17867330f729Sjoerg     getLangOpts().ObjC;
17877330f729Sjoerg 
17887330f729Sjoerg   // C99 6.8.5p5 - In C99, the for statement is a block.  This is not
17897330f729Sjoerg   // the case for C90.  Start the loop scope.
17907330f729Sjoerg   //
17917330f729Sjoerg   // C++ 6.4p3:
17927330f729Sjoerg   // A name introduced by a declaration in a condition is in scope from its
17937330f729Sjoerg   // point of declaration until the end of the substatements controlled by the
17947330f729Sjoerg   // condition.
17957330f729Sjoerg   // C++ 3.3.2p4:
17967330f729Sjoerg   // Names declared in the for-init-statement, and in the condition of if,
17977330f729Sjoerg   // while, for, and switch statements are local to the if, while, for, or
17987330f729Sjoerg   // switch statement (including the controlled statement).
17997330f729Sjoerg   // C++ 6.5.3p1:
18007330f729Sjoerg   // Names declared in the for-init-statement are in the same declarative-region
18017330f729Sjoerg   // as those declared in the condition.
18027330f729Sjoerg   //
18037330f729Sjoerg   unsigned ScopeFlags = 0;
18047330f729Sjoerg   if (C99orCXXorObjC)
18057330f729Sjoerg     ScopeFlags = Scope::DeclScope | Scope::ControlScope;
18067330f729Sjoerg 
18077330f729Sjoerg   ParseScope ForScope(this, ScopeFlags);
18087330f729Sjoerg 
18097330f729Sjoerg   BalancedDelimiterTracker T(*this, tok::l_paren);
18107330f729Sjoerg   T.consumeOpen();
18117330f729Sjoerg 
18127330f729Sjoerg   ExprResult Value;
18137330f729Sjoerg 
18147330f729Sjoerg   bool ForEach = false;
18157330f729Sjoerg   StmtResult FirstPart;
18167330f729Sjoerg   Sema::ConditionResult SecondPart;
18177330f729Sjoerg   ExprResult Collection;
18187330f729Sjoerg   ForRangeInfo ForRangeInfo;
18197330f729Sjoerg   FullExprArg ThirdPart(Actions);
18207330f729Sjoerg 
18217330f729Sjoerg   if (Tok.is(tok::code_completion)) {
1822*e038c9c4Sjoerg     cutOffParsing();
18237330f729Sjoerg     Actions.CodeCompleteOrdinaryName(getCurScope(),
18247330f729Sjoerg                                      C99orCXXorObjC? Sema::PCC_ForInit
18257330f729Sjoerg                                                    : Sema::PCC_Expression);
18267330f729Sjoerg     return StmtError();
18277330f729Sjoerg   }
18287330f729Sjoerg 
18297330f729Sjoerg   ParsedAttributesWithRange attrs(AttrFactory);
18307330f729Sjoerg   MaybeParseCXX11Attributes(attrs);
18317330f729Sjoerg 
18327330f729Sjoerg   SourceLocation EmptyInitStmtSemiLoc;
18337330f729Sjoerg 
18347330f729Sjoerg   // Parse the first part of the for specifier.
18357330f729Sjoerg   if (Tok.is(tok::semi)) {  // for (;
18367330f729Sjoerg     ProhibitAttributes(attrs);
18377330f729Sjoerg     // no first part, eat the ';'.
18387330f729Sjoerg     SourceLocation SemiLoc = Tok.getLocation();
18397330f729Sjoerg     if (!Tok.hasLeadingEmptyMacro() && !SemiLoc.isMacroID())
18407330f729Sjoerg       EmptyInitStmtSemiLoc = SemiLoc;
18417330f729Sjoerg     ConsumeToken();
18427330f729Sjoerg   } else if (getLangOpts().CPlusPlus && Tok.is(tok::identifier) &&
18437330f729Sjoerg              isForRangeIdentifier()) {
18447330f729Sjoerg     ProhibitAttributes(attrs);
18457330f729Sjoerg     IdentifierInfo *Name = Tok.getIdentifierInfo();
18467330f729Sjoerg     SourceLocation Loc = ConsumeToken();
18477330f729Sjoerg     MaybeParseCXX11Attributes(attrs);
18487330f729Sjoerg 
18497330f729Sjoerg     ForRangeInfo.ColonLoc = ConsumeToken();
18507330f729Sjoerg     if (Tok.is(tok::l_brace))
18517330f729Sjoerg       ForRangeInfo.RangeExpr = ParseBraceInitializer();
18527330f729Sjoerg     else
18537330f729Sjoerg       ForRangeInfo.RangeExpr = ParseExpression();
18547330f729Sjoerg 
18557330f729Sjoerg     Diag(Loc, diag::err_for_range_identifier)
18567330f729Sjoerg       << ((getLangOpts().CPlusPlus11 && !getLangOpts().CPlusPlus17)
18577330f729Sjoerg               ? FixItHint::CreateInsertion(Loc, "auto &&")
18587330f729Sjoerg               : FixItHint());
18597330f729Sjoerg 
18607330f729Sjoerg     ForRangeInfo.LoopVar = Actions.ActOnCXXForRangeIdentifier(
18617330f729Sjoerg         getCurScope(), Loc, Name, attrs, attrs.Range.getEnd());
18627330f729Sjoerg   } else if (isForInitDeclaration()) {  // for (int X = 4;
18637330f729Sjoerg     ParenBraceBracketBalancer BalancerRAIIObj(*this);
18647330f729Sjoerg 
18657330f729Sjoerg     // Parse declaration, which eats the ';'.
18667330f729Sjoerg     if (!C99orCXXorObjC) {   // Use of C99-style for loops in C90 mode?
18677330f729Sjoerg       Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
18687330f729Sjoerg       Diag(Tok, diag::warn_gcc_variable_decl_in_for_loop);
18697330f729Sjoerg     }
18707330f729Sjoerg 
18717330f729Sjoerg     // In C++0x, "for (T NS:a" might not be a typo for ::
18727330f729Sjoerg     bool MightBeForRangeStmt = getLangOpts().CPlusPlus;
18737330f729Sjoerg     ColonProtectionRAIIObject ColonProtection(*this, MightBeForRangeStmt);
18747330f729Sjoerg 
18757330f729Sjoerg     SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
18767330f729Sjoerg     DeclGroupPtrTy DG = ParseSimpleDeclaration(
1877*e038c9c4Sjoerg         DeclaratorContext::ForInit, DeclEnd, attrs, false,
18787330f729Sjoerg         MightBeForRangeStmt ? &ForRangeInfo : nullptr);
18797330f729Sjoerg     FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
18807330f729Sjoerg     if (ForRangeInfo.ParsedForRangeDecl()) {
18817330f729Sjoerg       Diag(ForRangeInfo.ColonLoc, getLangOpts().CPlusPlus11 ?
18827330f729Sjoerg            diag::warn_cxx98_compat_for_range : diag::ext_for_range);
18837330f729Sjoerg       ForRangeInfo.LoopVar = FirstPart;
18847330f729Sjoerg       FirstPart = StmtResult();
18857330f729Sjoerg     } else if (Tok.is(tok::semi)) {  // for (int x = 4;
18867330f729Sjoerg       ConsumeToken();
18877330f729Sjoerg     } else if ((ForEach = isTokIdentifier_in())) {
18887330f729Sjoerg       Actions.ActOnForEachDeclStmt(DG);
18897330f729Sjoerg       // ObjC: for (id x in expr)
18907330f729Sjoerg       ConsumeToken(); // consume 'in'
18917330f729Sjoerg 
18927330f729Sjoerg       if (Tok.is(tok::code_completion)) {
18937330f729Sjoerg         cutOffParsing();
1894*e038c9c4Sjoerg         Actions.CodeCompleteObjCForCollection(getCurScope(), DG);
18957330f729Sjoerg         return StmtError();
18967330f729Sjoerg       }
18977330f729Sjoerg       Collection = ParseExpression();
18987330f729Sjoerg     } else {
18997330f729Sjoerg       Diag(Tok, diag::err_expected_semi_for);
19007330f729Sjoerg     }
19017330f729Sjoerg   } else {
19027330f729Sjoerg     ProhibitAttributes(attrs);
19037330f729Sjoerg     Value = Actions.CorrectDelayedTyposInExpr(ParseExpression());
19047330f729Sjoerg 
19057330f729Sjoerg     ForEach = isTokIdentifier_in();
19067330f729Sjoerg 
19077330f729Sjoerg     // Turn the expression into a stmt.
19087330f729Sjoerg     if (!Value.isInvalid()) {
19097330f729Sjoerg       if (ForEach)
19107330f729Sjoerg         FirstPart = Actions.ActOnForEachLValueExpr(Value.get());
19117330f729Sjoerg       else {
19127330f729Sjoerg         // We already know this is not an init-statement within a for loop, so
19137330f729Sjoerg         // if we are parsing a C++11 range-based for loop, we should treat this
19147330f729Sjoerg         // expression statement as being a discarded value expression because
19157330f729Sjoerg         // we will err below. This way we do not warn on an unused expression
19167330f729Sjoerg         // that was an error in the first place, like with: for (expr : expr);
19177330f729Sjoerg         bool IsRangeBasedFor =
19187330f729Sjoerg             getLangOpts().CPlusPlus11 && !ForEach && Tok.is(tok::colon);
19197330f729Sjoerg         FirstPart = Actions.ActOnExprStmt(Value, !IsRangeBasedFor);
19207330f729Sjoerg       }
19217330f729Sjoerg     }
19227330f729Sjoerg 
19237330f729Sjoerg     if (Tok.is(tok::semi)) {
19247330f729Sjoerg       ConsumeToken();
19257330f729Sjoerg     } else if (ForEach) {
19267330f729Sjoerg       ConsumeToken(); // consume 'in'
19277330f729Sjoerg 
19287330f729Sjoerg       if (Tok.is(tok::code_completion)) {
19297330f729Sjoerg         cutOffParsing();
1930*e038c9c4Sjoerg         Actions.CodeCompleteObjCForCollection(getCurScope(), nullptr);
19317330f729Sjoerg         return StmtError();
19327330f729Sjoerg       }
19337330f729Sjoerg       Collection = ParseExpression();
19347330f729Sjoerg     } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::colon) && FirstPart.get()) {
19357330f729Sjoerg       // User tried to write the reasonable, but ill-formed, for-range-statement
19367330f729Sjoerg       //   for (expr : expr) { ... }
19377330f729Sjoerg       Diag(Tok, diag::err_for_range_expected_decl)
19387330f729Sjoerg         << FirstPart.get()->getSourceRange();
19397330f729Sjoerg       SkipUntil(tok::r_paren, StopBeforeMatch);
19407330f729Sjoerg       SecondPart = Sema::ConditionError();
19417330f729Sjoerg     } else {
19427330f729Sjoerg       if (!Value.isInvalid()) {
19437330f729Sjoerg         Diag(Tok, diag::err_expected_semi_for);
19447330f729Sjoerg       } else {
19457330f729Sjoerg         // Skip until semicolon or rparen, don't consume it.
19467330f729Sjoerg         SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch);
19477330f729Sjoerg         if (Tok.is(tok::semi))
19487330f729Sjoerg           ConsumeToken();
19497330f729Sjoerg       }
19507330f729Sjoerg     }
19517330f729Sjoerg   }
19527330f729Sjoerg 
19537330f729Sjoerg   // Parse the second part of the for specifier.
19547330f729Sjoerg   if (!ForEach && !ForRangeInfo.ParsedForRangeDecl() &&
19557330f729Sjoerg       !SecondPart.isInvalid()) {
19567330f729Sjoerg     // Parse the second part of the for specifier.
19577330f729Sjoerg     if (Tok.is(tok::semi)) {  // for (...;;
19587330f729Sjoerg       // no second part.
19597330f729Sjoerg     } else if (Tok.is(tok::r_paren)) {
19607330f729Sjoerg       // missing both semicolons.
19617330f729Sjoerg     } else {
19627330f729Sjoerg       if (getLangOpts().CPlusPlus) {
19637330f729Sjoerg         // C++2a: We've parsed an init-statement; we might have a
19647330f729Sjoerg         // for-range-declaration next.
19657330f729Sjoerg         bool MightBeForRangeStmt = !ForRangeInfo.ParsedForRangeDecl();
19667330f729Sjoerg         ColonProtectionRAIIObject ColonProtection(*this, MightBeForRangeStmt);
19677330f729Sjoerg         SecondPart =
19687330f729Sjoerg             ParseCXXCondition(nullptr, ForLoc, Sema::ConditionKind::Boolean,
1969*e038c9c4Sjoerg                               MightBeForRangeStmt ? &ForRangeInfo : nullptr,
1970*e038c9c4Sjoerg                               /*EnterForConditionScope*/ true);
19717330f729Sjoerg 
19727330f729Sjoerg         if (ForRangeInfo.ParsedForRangeDecl()) {
19737330f729Sjoerg           Diag(FirstPart.get() ? FirstPart.get()->getBeginLoc()
19747330f729Sjoerg                                : ForRangeInfo.ColonLoc,
1975*e038c9c4Sjoerg                getLangOpts().CPlusPlus20
19767330f729Sjoerg                    ? diag::warn_cxx17_compat_for_range_init_stmt
19777330f729Sjoerg                    : diag::ext_for_range_init_stmt)
19787330f729Sjoerg               << (FirstPart.get() ? FirstPart.get()->getSourceRange()
19797330f729Sjoerg                                   : SourceRange());
19807330f729Sjoerg           if (EmptyInitStmtSemiLoc.isValid()) {
19817330f729Sjoerg             Diag(EmptyInitStmtSemiLoc, diag::warn_empty_init_statement)
19827330f729Sjoerg                 << /*for-loop*/ 2
19837330f729Sjoerg                 << FixItHint::CreateRemoval(EmptyInitStmtSemiLoc);
19847330f729Sjoerg           }
19857330f729Sjoerg         }
19867330f729Sjoerg       } else {
1987*e038c9c4Sjoerg         // We permit 'continue' and 'break' in the condition of a for loop.
1988*e038c9c4Sjoerg         getCurScope()->AddFlags(Scope::BreakScope | Scope::ContinueScope);
1989*e038c9c4Sjoerg 
19907330f729Sjoerg         ExprResult SecondExpr = ParseExpression();
19917330f729Sjoerg         if (SecondExpr.isInvalid())
19927330f729Sjoerg           SecondPart = Sema::ConditionError();
19937330f729Sjoerg         else
19947330f729Sjoerg           SecondPart =
19957330f729Sjoerg               Actions.ActOnCondition(getCurScope(), ForLoc, SecondExpr.get(),
19967330f729Sjoerg                                      Sema::ConditionKind::Boolean);
19977330f729Sjoerg       }
19987330f729Sjoerg     }
19997330f729Sjoerg   }
20007330f729Sjoerg 
2001*e038c9c4Sjoerg   // Enter a break / continue scope, if we didn't already enter one while
2002*e038c9c4Sjoerg   // parsing the second part.
2003*e038c9c4Sjoerg   if (!(getCurScope()->getFlags() & Scope::ContinueScope))
2004*e038c9c4Sjoerg     getCurScope()->AddFlags(Scope::BreakScope | Scope::ContinueScope);
2005*e038c9c4Sjoerg 
20067330f729Sjoerg   // Parse the third part of the for statement.
20077330f729Sjoerg   if (!ForEach && !ForRangeInfo.ParsedForRangeDecl()) {
20087330f729Sjoerg     if (Tok.isNot(tok::semi)) {
20097330f729Sjoerg       if (!SecondPart.isInvalid())
20107330f729Sjoerg         Diag(Tok, diag::err_expected_semi_for);
20117330f729Sjoerg       else
20127330f729Sjoerg         // Skip until semicolon or rparen, don't consume it.
20137330f729Sjoerg         SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch);
20147330f729Sjoerg     }
20157330f729Sjoerg 
20167330f729Sjoerg     if (Tok.is(tok::semi)) {
20177330f729Sjoerg       ConsumeToken();
20187330f729Sjoerg     }
20197330f729Sjoerg 
20207330f729Sjoerg     if (Tok.isNot(tok::r_paren)) {   // for (...;...;)
20217330f729Sjoerg       ExprResult Third = ParseExpression();
20227330f729Sjoerg       // FIXME: The C++11 standard doesn't actually say that this is a
20237330f729Sjoerg       // discarded-value expression, but it clearly should be.
20247330f729Sjoerg       ThirdPart = Actions.MakeFullDiscardedValueExpr(Third.get());
20257330f729Sjoerg     }
20267330f729Sjoerg   }
20277330f729Sjoerg   // Match the ')'.
20287330f729Sjoerg   T.consumeClose();
20297330f729Sjoerg 
20307330f729Sjoerg   // C++ Coroutines [stmt.iter]:
20317330f729Sjoerg   //   'co_await' can only be used for a range-based for statement.
20327330f729Sjoerg   if (CoawaitLoc.isValid() && !ForRangeInfo.ParsedForRangeDecl()) {
20337330f729Sjoerg     Diag(CoawaitLoc, diag::err_for_co_await_not_range_for);
20347330f729Sjoerg     CoawaitLoc = SourceLocation();
20357330f729Sjoerg   }
20367330f729Sjoerg 
20377330f729Sjoerg   // We need to perform most of the semantic analysis for a C++0x for-range
20387330f729Sjoerg   // statememt before parsing the body, in order to be able to deduce the type
20397330f729Sjoerg   // of an auto-typed loop variable.
20407330f729Sjoerg   StmtResult ForRangeStmt;
20417330f729Sjoerg   StmtResult ForEachStmt;
20427330f729Sjoerg 
20437330f729Sjoerg   if (ForRangeInfo.ParsedForRangeDecl()) {
20447330f729Sjoerg     ExprResult CorrectedRange =
20457330f729Sjoerg         Actions.CorrectDelayedTyposInExpr(ForRangeInfo.RangeExpr.get());
20467330f729Sjoerg     ForRangeStmt = Actions.ActOnCXXForRangeStmt(
20477330f729Sjoerg         getCurScope(), ForLoc, CoawaitLoc, FirstPart.get(),
20487330f729Sjoerg         ForRangeInfo.LoopVar.get(), ForRangeInfo.ColonLoc, CorrectedRange.get(),
20497330f729Sjoerg         T.getCloseLocation(), Sema::BFRK_Build);
20507330f729Sjoerg 
20517330f729Sjoerg   // Similarly, we need to do the semantic analysis for a for-range
20527330f729Sjoerg   // statement immediately in order to close over temporaries correctly.
20537330f729Sjoerg   } else if (ForEach) {
20547330f729Sjoerg     ForEachStmt = Actions.ActOnObjCForCollectionStmt(ForLoc,
20557330f729Sjoerg                                                      FirstPart.get(),
20567330f729Sjoerg                                                      Collection.get(),
20577330f729Sjoerg                                                      T.getCloseLocation());
20587330f729Sjoerg   } else {
20597330f729Sjoerg     // In OpenMP loop region loop control variable must be captured and be
20607330f729Sjoerg     // private. Perform analysis of first part (if any).
20617330f729Sjoerg     if (getLangOpts().OpenMP && FirstPart.isUsable()) {
20627330f729Sjoerg       Actions.ActOnOpenMPLoopInitialization(ForLoc, FirstPart.get());
20637330f729Sjoerg     }
20647330f729Sjoerg   }
20657330f729Sjoerg 
20667330f729Sjoerg   // C99 6.8.5p5 - In C99, the body of the for statement is a scope, even if
20677330f729Sjoerg   // there is no compound stmt.  C90 does not have this clause.  We only do this
20687330f729Sjoerg   // if the body isn't a compound statement to avoid push/pop in common cases.
20697330f729Sjoerg   //
20707330f729Sjoerg   // C++ 6.5p2:
20717330f729Sjoerg   // The substatement in an iteration-statement implicitly defines a local scope
20727330f729Sjoerg   // which is entered and exited each time through the loop.
20737330f729Sjoerg   //
20747330f729Sjoerg   // See comments in ParseIfStatement for why we create a scope for
20757330f729Sjoerg   // for-init-statement/condition and a new scope for substatement in C++.
20767330f729Sjoerg   //
20777330f729Sjoerg   ParseScope InnerScope(this, Scope::DeclScope, C99orCXXorObjC,
20787330f729Sjoerg                         Tok.is(tok::l_brace));
20797330f729Sjoerg 
20807330f729Sjoerg   // The body of the for loop has the same local mangling number as the
20817330f729Sjoerg   // for-init-statement.
20827330f729Sjoerg   // It will only be incremented if the body contains other things that would
20837330f729Sjoerg   // normally increment the mangling number (like a compound statement).
20847330f729Sjoerg   if (C99orCXXorObjC)
20857330f729Sjoerg     getCurScope()->decrementMSManglingNumber();
20867330f729Sjoerg 
2087*e038c9c4Sjoerg   MisleadingIndentationChecker MIChecker(*this, MSK_for, ForLoc);
2088*e038c9c4Sjoerg 
20897330f729Sjoerg   // Read the body statement.
20907330f729Sjoerg   StmtResult Body(ParseStatement(TrailingElseLoc));
20917330f729Sjoerg 
2092*e038c9c4Sjoerg   if (Body.isUsable())
2093*e038c9c4Sjoerg     MIChecker.Check();
2094*e038c9c4Sjoerg 
20957330f729Sjoerg   // Pop the body scope if needed.
20967330f729Sjoerg   InnerScope.Exit();
20977330f729Sjoerg 
20987330f729Sjoerg   // Leave the for-scope.
20997330f729Sjoerg   ForScope.Exit();
21007330f729Sjoerg 
21017330f729Sjoerg   if (Body.isInvalid())
21027330f729Sjoerg     return StmtError();
21037330f729Sjoerg 
21047330f729Sjoerg   if (ForEach)
21057330f729Sjoerg    return Actions.FinishObjCForCollectionStmt(ForEachStmt.get(),
21067330f729Sjoerg                                               Body.get());
21077330f729Sjoerg 
21087330f729Sjoerg   if (ForRangeInfo.ParsedForRangeDecl())
21097330f729Sjoerg     return Actions.FinishCXXForRangeStmt(ForRangeStmt.get(), Body.get());
21107330f729Sjoerg 
21117330f729Sjoerg   return Actions.ActOnForStmt(ForLoc, T.getOpenLocation(), FirstPart.get(),
21127330f729Sjoerg                               SecondPart, ThirdPart, T.getCloseLocation(),
21137330f729Sjoerg                               Body.get());
21147330f729Sjoerg }
21157330f729Sjoerg 
21167330f729Sjoerg /// ParseGotoStatement
21177330f729Sjoerg ///       jump-statement:
21187330f729Sjoerg ///         'goto' identifier ';'
21197330f729Sjoerg /// [GNU]   'goto' '*' expression ';'
21207330f729Sjoerg ///
21217330f729Sjoerg /// Note: this lets the caller parse the end ';'.
21227330f729Sjoerg ///
ParseGotoStatement()21237330f729Sjoerg StmtResult Parser::ParseGotoStatement() {
21247330f729Sjoerg   assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");
21257330f729Sjoerg   SourceLocation GotoLoc = ConsumeToken();  // eat the 'goto'.
21267330f729Sjoerg 
21277330f729Sjoerg   StmtResult Res;
21287330f729Sjoerg   if (Tok.is(tok::identifier)) {
21297330f729Sjoerg     LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(),
21307330f729Sjoerg                                                 Tok.getLocation());
21317330f729Sjoerg     Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(), LD);
21327330f729Sjoerg     ConsumeToken();
21337330f729Sjoerg   } else if (Tok.is(tok::star)) {
21347330f729Sjoerg     // GNU indirect goto extension.
21357330f729Sjoerg     Diag(Tok, diag::ext_gnu_indirect_goto);
21367330f729Sjoerg     SourceLocation StarLoc = ConsumeToken();
21377330f729Sjoerg     ExprResult R(ParseExpression());
21387330f729Sjoerg     if (R.isInvalid()) {  // Skip to the semicolon, but don't consume it.
21397330f729Sjoerg       SkipUntil(tok::semi, StopBeforeMatch);
21407330f729Sjoerg       return StmtError();
21417330f729Sjoerg     }
21427330f729Sjoerg     Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.get());
21437330f729Sjoerg   } else {
21447330f729Sjoerg     Diag(Tok, diag::err_expected) << tok::identifier;
21457330f729Sjoerg     return StmtError();
21467330f729Sjoerg   }
21477330f729Sjoerg 
21487330f729Sjoerg   return Res;
21497330f729Sjoerg }
21507330f729Sjoerg 
21517330f729Sjoerg /// ParseContinueStatement
21527330f729Sjoerg ///       jump-statement:
21537330f729Sjoerg ///         'continue' ';'
21547330f729Sjoerg ///
21557330f729Sjoerg /// Note: this lets the caller parse the end ';'.
21567330f729Sjoerg ///
ParseContinueStatement()21577330f729Sjoerg StmtResult Parser::ParseContinueStatement() {
21587330f729Sjoerg   SourceLocation ContinueLoc = ConsumeToken();  // eat the 'continue'.
21597330f729Sjoerg   return Actions.ActOnContinueStmt(ContinueLoc, getCurScope());
21607330f729Sjoerg }
21617330f729Sjoerg 
21627330f729Sjoerg /// ParseBreakStatement
21637330f729Sjoerg ///       jump-statement:
21647330f729Sjoerg ///         'break' ';'
21657330f729Sjoerg ///
21667330f729Sjoerg /// Note: this lets the caller parse the end ';'.
21677330f729Sjoerg ///
ParseBreakStatement()21687330f729Sjoerg StmtResult Parser::ParseBreakStatement() {
21697330f729Sjoerg   SourceLocation BreakLoc = ConsumeToken();  // eat the 'break'.
21707330f729Sjoerg   return Actions.ActOnBreakStmt(BreakLoc, getCurScope());
21717330f729Sjoerg }
21727330f729Sjoerg 
21737330f729Sjoerg /// ParseReturnStatement
21747330f729Sjoerg ///       jump-statement:
21757330f729Sjoerg ///         'return' expression[opt] ';'
21767330f729Sjoerg ///         'return' braced-init-list ';'
21777330f729Sjoerg ///         'co_return' expression[opt] ';'
21787330f729Sjoerg ///         'co_return' braced-init-list ';'
ParseReturnStatement()21797330f729Sjoerg StmtResult Parser::ParseReturnStatement() {
21807330f729Sjoerg   assert((Tok.is(tok::kw_return) || Tok.is(tok::kw_co_return)) &&
21817330f729Sjoerg          "Not a return stmt!");
21827330f729Sjoerg   bool IsCoreturn = Tok.is(tok::kw_co_return);
21837330f729Sjoerg   SourceLocation ReturnLoc = ConsumeToken();  // eat the 'return'.
21847330f729Sjoerg 
21857330f729Sjoerg   ExprResult R;
21867330f729Sjoerg   if (Tok.isNot(tok::semi)) {
21877330f729Sjoerg     if (!IsCoreturn)
21887330f729Sjoerg       PreferredType.enterReturn(Actions, Tok.getLocation());
21897330f729Sjoerg     // FIXME: Code completion for co_return.
21907330f729Sjoerg     if (Tok.is(tok::code_completion) && !IsCoreturn) {
2191*e038c9c4Sjoerg       cutOffParsing();
21927330f729Sjoerg       Actions.CodeCompleteExpression(getCurScope(),
21937330f729Sjoerg                                      PreferredType.get(Tok.getLocation()));
21947330f729Sjoerg       return StmtError();
21957330f729Sjoerg     }
21967330f729Sjoerg 
21977330f729Sjoerg     if (Tok.is(tok::l_brace) && getLangOpts().CPlusPlus) {
21987330f729Sjoerg       R = ParseInitializer();
21997330f729Sjoerg       if (R.isUsable())
22007330f729Sjoerg         Diag(R.get()->getBeginLoc(),
22017330f729Sjoerg              getLangOpts().CPlusPlus11
22027330f729Sjoerg                  ? diag::warn_cxx98_compat_generalized_initializer_lists
22037330f729Sjoerg                  : diag::ext_generalized_initializer_lists)
22047330f729Sjoerg             << R.get()->getSourceRange();
22057330f729Sjoerg     } else
22067330f729Sjoerg       R = ParseExpression();
22077330f729Sjoerg     if (R.isInvalid()) {
22087330f729Sjoerg       SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
22097330f729Sjoerg       return StmtError();
22107330f729Sjoerg     }
22117330f729Sjoerg   }
22127330f729Sjoerg   if (IsCoreturn)
22137330f729Sjoerg     return Actions.ActOnCoreturnStmt(getCurScope(), ReturnLoc, R.get());
22147330f729Sjoerg   return Actions.ActOnReturnStmt(ReturnLoc, R.get(), getCurScope());
22157330f729Sjoerg }
22167330f729Sjoerg 
ParsePragmaLoopHint(StmtVector & Stmts,ParsedStmtContext StmtCtx,SourceLocation * TrailingElseLoc,ParsedAttributesWithRange & Attrs)22177330f729Sjoerg StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
22187330f729Sjoerg                                        ParsedStmtContext StmtCtx,
22197330f729Sjoerg                                        SourceLocation *TrailingElseLoc,
22207330f729Sjoerg                                        ParsedAttributesWithRange &Attrs) {
22217330f729Sjoerg   // Create temporary attribute list.
22227330f729Sjoerg   ParsedAttributesWithRange TempAttrs(AttrFactory);
22237330f729Sjoerg 
2224*e038c9c4Sjoerg   SourceLocation StartLoc = Tok.getLocation();
2225*e038c9c4Sjoerg 
22267330f729Sjoerg   // Get loop hints and consume annotated token.
22277330f729Sjoerg   while (Tok.is(tok::annot_pragma_loop_hint)) {
22287330f729Sjoerg     LoopHint Hint;
22297330f729Sjoerg     if (!HandlePragmaLoopHint(Hint))
22307330f729Sjoerg       continue;
22317330f729Sjoerg 
22327330f729Sjoerg     ArgsUnion ArgHints[] = {Hint.PragmaNameLoc, Hint.OptionLoc, Hint.StateLoc,
22337330f729Sjoerg                             ArgsUnion(Hint.ValueExpr)};
22347330f729Sjoerg     TempAttrs.addNew(Hint.PragmaNameLoc->Ident, Hint.Range, nullptr,
22357330f729Sjoerg                      Hint.PragmaNameLoc->Loc, ArgHints, 4,
22367330f729Sjoerg                      ParsedAttr::AS_Pragma);
22377330f729Sjoerg   }
22387330f729Sjoerg 
22397330f729Sjoerg   // Get the next statement.
22407330f729Sjoerg   MaybeParseCXX11Attributes(Attrs);
22417330f729Sjoerg 
22427330f729Sjoerg   StmtResult S = ParseStatementOrDeclarationAfterAttributes(
22437330f729Sjoerg       Stmts, StmtCtx, TrailingElseLoc, Attrs);
22447330f729Sjoerg 
22457330f729Sjoerg   Attrs.takeAllFrom(TempAttrs);
2246*e038c9c4Sjoerg 
2247*e038c9c4Sjoerg   // Start of attribute range may already be set for some invalid input.
2248*e038c9c4Sjoerg   // See PR46336.
2249*e038c9c4Sjoerg   if (Attrs.Range.getBegin().isInvalid())
2250*e038c9c4Sjoerg     Attrs.Range.setBegin(StartLoc);
2251*e038c9c4Sjoerg 
22527330f729Sjoerg   return S;
22537330f729Sjoerg }
22547330f729Sjoerg 
ParseFunctionStatementBody(Decl * Decl,ParseScope & BodyScope)22557330f729Sjoerg Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) {
22567330f729Sjoerg   assert(Tok.is(tok::l_brace));
22577330f729Sjoerg   SourceLocation LBraceLoc = Tok.getLocation();
22587330f729Sjoerg 
22597330f729Sjoerg   PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, LBraceLoc,
22607330f729Sjoerg                                       "parsing function body");
22617330f729Sjoerg 
22627330f729Sjoerg   // Save and reset current vtordisp stack if we have entered a C++ method body.
22637330f729Sjoerg   bool IsCXXMethod =
22647330f729Sjoerg       getLangOpts().CPlusPlus && Decl && isa<CXXMethodDecl>(Decl);
22657330f729Sjoerg   Sema::PragmaStackSentinelRAII
22667330f729Sjoerg     PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod);
22677330f729Sjoerg 
22687330f729Sjoerg   // Do not enter a scope for the brace, as the arguments are in the same scope
22697330f729Sjoerg   // (the function body) as the body itself.  Instead, just read the statement
22707330f729Sjoerg   // list and put it into a CompoundStmt for safe keeping.
22717330f729Sjoerg   StmtResult FnBody(ParseCompoundStatementBody());
22727330f729Sjoerg 
22737330f729Sjoerg   // If the function body could not be parsed, make a bogus compoundstmt.
22747330f729Sjoerg   if (FnBody.isInvalid()) {
22757330f729Sjoerg     Sema::CompoundScopeRAII CompoundScope(Actions);
22767330f729Sjoerg     FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, None, false);
22777330f729Sjoerg   }
22787330f729Sjoerg 
22797330f729Sjoerg   BodyScope.Exit();
22807330f729Sjoerg   return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
22817330f729Sjoerg }
22827330f729Sjoerg 
22837330f729Sjoerg /// ParseFunctionTryBlock - Parse a C++ function-try-block.
22847330f729Sjoerg ///
22857330f729Sjoerg ///       function-try-block:
22867330f729Sjoerg ///         'try' ctor-initializer[opt] compound-statement handler-seq
22877330f729Sjoerg ///
ParseFunctionTryBlock(Decl * Decl,ParseScope & BodyScope)22887330f729Sjoerg Decl *Parser::ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope) {
22897330f729Sjoerg   assert(Tok.is(tok::kw_try) && "Expected 'try'");
22907330f729Sjoerg   SourceLocation TryLoc = ConsumeToken();
22917330f729Sjoerg 
22927330f729Sjoerg   PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, TryLoc,
22937330f729Sjoerg                                       "parsing function try block");
22947330f729Sjoerg 
22957330f729Sjoerg   // Constructor initializer list?
22967330f729Sjoerg   if (Tok.is(tok::colon))
22977330f729Sjoerg     ParseConstructorInitializer(Decl);
22987330f729Sjoerg   else
22997330f729Sjoerg     Actions.ActOnDefaultCtorInitializers(Decl);
23007330f729Sjoerg 
23017330f729Sjoerg   // Save and reset current vtordisp stack if we have entered a C++ method body.
23027330f729Sjoerg   bool IsCXXMethod =
23037330f729Sjoerg       getLangOpts().CPlusPlus && Decl && isa<CXXMethodDecl>(Decl);
23047330f729Sjoerg   Sema::PragmaStackSentinelRAII
23057330f729Sjoerg     PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod);
23067330f729Sjoerg 
23077330f729Sjoerg   SourceLocation LBraceLoc = Tok.getLocation();
23087330f729Sjoerg   StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc, /*FnTry*/true));
23097330f729Sjoerg   // If we failed to parse the try-catch, we just give the function an empty
23107330f729Sjoerg   // compound statement as the body.
23117330f729Sjoerg   if (FnBody.isInvalid()) {
23127330f729Sjoerg     Sema::CompoundScopeRAII CompoundScope(Actions);
23137330f729Sjoerg     FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, None, false);
23147330f729Sjoerg   }
23157330f729Sjoerg 
23167330f729Sjoerg   BodyScope.Exit();
23177330f729Sjoerg   return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
23187330f729Sjoerg }
23197330f729Sjoerg 
trySkippingFunctionBody()23207330f729Sjoerg bool Parser::trySkippingFunctionBody() {
23217330f729Sjoerg   assert(SkipFunctionBodies &&
23227330f729Sjoerg          "Should only be called when SkipFunctionBodies is enabled");
23237330f729Sjoerg   if (!PP.isCodeCompletionEnabled()) {
23247330f729Sjoerg     SkipFunctionBody();
23257330f729Sjoerg     return true;
23267330f729Sjoerg   }
23277330f729Sjoerg 
23287330f729Sjoerg   // We're in code-completion mode. Skip parsing for all function bodies unless
23297330f729Sjoerg   // the body contains the code-completion point.
23307330f729Sjoerg   TentativeParsingAction PA(*this);
23317330f729Sjoerg   bool IsTryCatch = Tok.is(tok::kw_try);
23327330f729Sjoerg   CachedTokens Toks;
23337330f729Sjoerg   bool ErrorInPrologue = ConsumeAndStoreFunctionPrologue(Toks);
23347330f729Sjoerg   if (llvm::any_of(Toks, [](const Token &Tok) {
23357330f729Sjoerg         return Tok.is(tok::code_completion);
23367330f729Sjoerg       })) {
23377330f729Sjoerg     PA.Revert();
23387330f729Sjoerg     return false;
23397330f729Sjoerg   }
23407330f729Sjoerg   if (ErrorInPrologue) {
23417330f729Sjoerg     PA.Commit();
23427330f729Sjoerg     SkipMalformedDecl();
23437330f729Sjoerg     return true;
23447330f729Sjoerg   }
23457330f729Sjoerg   if (!SkipUntil(tok::r_brace, StopAtCodeCompletion)) {
23467330f729Sjoerg     PA.Revert();
23477330f729Sjoerg     return false;
23487330f729Sjoerg   }
23497330f729Sjoerg   while (IsTryCatch && Tok.is(tok::kw_catch)) {
23507330f729Sjoerg     if (!SkipUntil(tok::l_brace, StopAtCodeCompletion) ||
23517330f729Sjoerg         !SkipUntil(tok::r_brace, StopAtCodeCompletion)) {
23527330f729Sjoerg       PA.Revert();
23537330f729Sjoerg       return false;
23547330f729Sjoerg     }
23557330f729Sjoerg   }
23567330f729Sjoerg   PA.Commit();
23577330f729Sjoerg   return true;
23587330f729Sjoerg }
23597330f729Sjoerg 
23607330f729Sjoerg /// ParseCXXTryBlock - Parse a C++ try-block.
23617330f729Sjoerg ///
23627330f729Sjoerg ///       try-block:
23637330f729Sjoerg ///         'try' compound-statement handler-seq
23647330f729Sjoerg ///
ParseCXXTryBlock()23657330f729Sjoerg StmtResult Parser::ParseCXXTryBlock() {
23667330f729Sjoerg   assert(Tok.is(tok::kw_try) && "Expected 'try'");
23677330f729Sjoerg 
23687330f729Sjoerg   SourceLocation TryLoc = ConsumeToken();
23697330f729Sjoerg   return ParseCXXTryBlockCommon(TryLoc);
23707330f729Sjoerg }
23717330f729Sjoerg 
23727330f729Sjoerg /// ParseCXXTryBlockCommon - Parse the common part of try-block and
23737330f729Sjoerg /// function-try-block.
23747330f729Sjoerg ///
23757330f729Sjoerg ///       try-block:
23767330f729Sjoerg ///         'try' compound-statement handler-seq
23777330f729Sjoerg ///
23787330f729Sjoerg ///       function-try-block:
23797330f729Sjoerg ///         'try' ctor-initializer[opt] compound-statement handler-seq
23807330f729Sjoerg ///
23817330f729Sjoerg ///       handler-seq:
23827330f729Sjoerg ///         handler handler-seq[opt]
23837330f729Sjoerg ///
23847330f729Sjoerg ///       [Borland] try-block:
23857330f729Sjoerg ///         'try' compound-statement seh-except-block
23867330f729Sjoerg ///         'try' compound-statement seh-finally-block
23877330f729Sjoerg ///
ParseCXXTryBlockCommon(SourceLocation TryLoc,bool FnTry)23887330f729Sjoerg StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry) {
23897330f729Sjoerg   if (Tok.isNot(tok::l_brace))
23907330f729Sjoerg     return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
23917330f729Sjoerg 
23927330f729Sjoerg   StmtResult TryBlock(ParseCompoundStatement(
23937330f729Sjoerg       /*isStmtExpr=*/false, Scope::DeclScope | Scope::TryScope |
23947330f729Sjoerg                                 Scope::CompoundStmtScope |
23957330f729Sjoerg                                 (FnTry ? Scope::FnTryCatchScope : 0)));
23967330f729Sjoerg   if (TryBlock.isInvalid())
23977330f729Sjoerg     return TryBlock;
23987330f729Sjoerg 
23997330f729Sjoerg   // Borland allows SEH-handlers with 'try'
24007330f729Sjoerg 
24017330f729Sjoerg   if ((Tok.is(tok::identifier) &&
24027330f729Sjoerg        Tok.getIdentifierInfo() == getSEHExceptKeyword()) ||
24037330f729Sjoerg       Tok.is(tok::kw___finally)) {
24047330f729Sjoerg     // TODO: Factor into common return ParseSEHHandlerCommon(...)
24057330f729Sjoerg     StmtResult Handler;
24067330f729Sjoerg     if(Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
24077330f729Sjoerg       SourceLocation Loc = ConsumeToken();
24087330f729Sjoerg       Handler = ParseSEHExceptBlock(Loc);
24097330f729Sjoerg     }
24107330f729Sjoerg     else {
24117330f729Sjoerg       SourceLocation Loc = ConsumeToken();
24127330f729Sjoerg       Handler = ParseSEHFinallyBlock(Loc);
24137330f729Sjoerg     }
24147330f729Sjoerg     if(Handler.isInvalid())
24157330f729Sjoerg       return Handler;
24167330f729Sjoerg 
24177330f729Sjoerg     return Actions.ActOnSEHTryBlock(true /* IsCXXTry */,
24187330f729Sjoerg                                     TryLoc,
24197330f729Sjoerg                                     TryBlock.get(),
24207330f729Sjoerg                                     Handler.get());
24217330f729Sjoerg   }
24227330f729Sjoerg   else {
24237330f729Sjoerg     StmtVector Handlers;
24247330f729Sjoerg 
24257330f729Sjoerg     // C++11 attributes can't appear here, despite this context seeming
24267330f729Sjoerg     // statement-like.
24277330f729Sjoerg     DiagnoseAndSkipCXX11Attributes();
24287330f729Sjoerg 
24297330f729Sjoerg     if (Tok.isNot(tok::kw_catch))
24307330f729Sjoerg       return StmtError(Diag(Tok, diag::err_expected_catch));
24317330f729Sjoerg     while (Tok.is(tok::kw_catch)) {
24327330f729Sjoerg       StmtResult Handler(ParseCXXCatchBlock(FnTry));
24337330f729Sjoerg       if (!Handler.isInvalid())
24347330f729Sjoerg         Handlers.push_back(Handler.get());
24357330f729Sjoerg     }
24367330f729Sjoerg     // Don't bother creating the full statement if we don't have any usable
24377330f729Sjoerg     // handlers.
24387330f729Sjoerg     if (Handlers.empty())
24397330f729Sjoerg       return StmtError();
24407330f729Sjoerg 
24417330f729Sjoerg     return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.get(), Handlers);
24427330f729Sjoerg   }
24437330f729Sjoerg }
24447330f729Sjoerg 
24457330f729Sjoerg /// ParseCXXCatchBlock - Parse a C++ catch block, called handler in the standard
24467330f729Sjoerg ///
24477330f729Sjoerg ///   handler:
24487330f729Sjoerg ///     'catch' '(' exception-declaration ')' compound-statement
24497330f729Sjoerg ///
24507330f729Sjoerg ///   exception-declaration:
24517330f729Sjoerg ///     attribute-specifier-seq[opt] type-specifier-seq declarator
24527330f729Sjoerg ///     attribute-specifier-seq[opt] type-specifier-seq abstract-declarator[opt]
24537330f729Sjoerg ///     '...'
24547330f729Sjoerg ///
ParseCXXCatchBlock(bool FnCatch)24557330f729Sjoerg StmtResult Parser::ParseCXXCatchBlock(bool FnCatch) {
24567330f729Sjoerg   assert(Tok.is(tok::kw_catch) && "Expected 'catch'");
24577330f729Sjoerg 
24587330f729Sjoerg   SourceLocation CatchLoc = ConsumeToken();
24597330f729Sjoerg 
24607330f729Sjoerg   BalancedDelimiterTracker T(*this, tok::l_paren);
24617330f729Sjoerg   if (T.expectAndConsume())
24627330f729Sjoerg     return StmtError();
24637330f729Sjoerg 
24647330f729Sjoerg   // C++ 3.3.2p3:
24657330f729Sjoerg   // The name in a catch exception-declaration is local to the handler and
24667330f729Sjoerg   // shall not be redeclared in the outermost block of the handler.
24677330f729Sjoerg   ParseScope CatchScope(this, Scope::DeclScope | Scope::ControlScope |
24687330f729Sjoerg                                   Scope::CatchScope |
24697330f729Sjoerg                                   (FnCatch ? Scope::FnTryCatchScope : 0));
24707330f729Sjoerg 
24717330f729Sjoerg   // exception-declaration is equivalent to '...' or a parameter-declaration
24727330f729Sjoerg   // without default arguments.
24737330f729Sjoerg   Decl *ExceptionDecl = nullptr;
24747330f729Sjoerg   if (Tok.isNot(tok::ellipsis)) {
24757330f729Sjoerg     ParsedAttributesWithRange Attributes(AttrFactory);
24767330f729Sjoerg     MaybeParseCXX11Attributes(Attributes);
24777330f729Sjoerg 
24787330f729Sjoerg     DeclSpec DS(AttrFactory);
24797330f729Sjoerg     DS.takeAttributesFrom(Attributes);
24807330f729Sjoerg 
24817330f729Sjoerg     if (ParseCXXTypeSpecifierSeq(DS))
24827330f729Sjoerg       return StmtError();
24837330f729Sjoerg 
2484*e038c9c4Sjoerg     Declarator ExDecl(DS, DeclaratorContext::CXXCatch);
24857330f729Sjoerg     ParseDeclarator(ExDecl);
24867330f729Sjoerg     ExceptionDecl = Actions.ActOnExceptionDeclarator(getCurScope(), ExDecl);
24877330f729Sjoerg   } else
24887330f729Sjoerg     ConsumeToken();
24897330f729Sjoerg 
24907330f729Sjoerg   T.consumeClose();
24917330f729Sjoerg   if (T.getCloseLocation().isInvalid())
24927330f729Sjoerg     return StmtError();
24937330f729Sjoerg 
24947330f729Sjoerg   if (Tok.isNot(tok::l_brace))
24957330f729Sjoerg     return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
24967330f729Sjoerg 
24977330f729Sjoerg   // FIXME: Possible draft standard bug: attribute-specifier should be allowed?
24987330f729Sjoerg   StmtResult Block(ParseCompoundStatement());
24997330f729Sjoerg   if (Block.isInvalid())
25007330f729Sjoerg     return Block;
25017330f729Sjoerg 
25027330f729Sjoerg   return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl, Block.get());
25037330f729Sjoerg }
25047330f729Sjoerg 
ParseMicrosoftIfExistsStatement(StmtVector & Stmts)25057330f729Sjoerg void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
25067330f729Sjoerg   IfExistsCondition Result;
25077330f729Sjoerg   if (ParseMicrosoftIfExistsCondition(Result))
25087330f729Sjoerg     return;
25097330f729Sjoerg 
25107330f729Sjoerg   // Handle dependent statements by parsing the braces as a compound statement.
25117330f729Sjoerg   // This is not the same behavior as Visual C++, which don't treat this as a
25127330f729Sjoerg   // compound statement, but for Clang's type checking we can't have anything
25137330f729Sjoerg   // inside these braces escaping to the surrounding code.
25147330f729Sjoerg   if (Result.Behavior == IEB_Dependent) {
25157330f729Sjoerg     if (!Tok.is(tok::l_brace)) {
25167330f729Sjoerg       Diag(Tok, diag::err_expected) << tok::l_brace;
25177330f729Sjoerg       return;
25187330f729Sjoerg     }
25197330f729Sjoerg 
25207330f729Sjoerg     StmtResult Compound = ParseCompoundStatement();
25217330f729Sjoerg     if (Compound.isInvalid())
25227330f729Sjoerg       return;
25237330f729Sjoerg 
25247330f729Sjoerg     StmtResult DepResult = Actions.ActOnMSDependentExistsStmt(Result.KeywordLoc,
25257330f729Sjoerg                                                               Result.IsIfExists,
25267330f729Sjoerg                                                               Result.SS,
25277330f729Sjoerg                                                               Result.Name,
25287330f729Sjoerg                                                               Compound.get());
25297330f729Sjoerg     if (DepResult.isUsable())
25307330f729Sjoerg       Stmts.push_back(DepResult.get());
25317330f729Sjoerg     return;
25327330f729Sjoerg   }
25337330f729Sjoerg 
25347330f729Sjoerg   BalancedDelimiterTracker Braces(*this, tok::l_brace);
25357330f729Sjoerg   if (Braces.consumeOpen()) {
25367330f729Sjoerg     Diag(Tok, diag::err_expected) << tok::l_brace;
25377330f729Sjoerg     return;
25387330f729Sjoerg   }
25397330f729Sjoerg 
25407330f729Sjoerg   switch (Result.Behavior) {
25417330f729Sjoerg   case IEB_Parse:
25427330f729Sjoerg     // Parse the statements below.
25437330f729Sjoerg     break;
25447330f729Sjoerg 
25457330f729Sjoerg   case IEB_Dependent:
25467330f729Sjoerg     llvm_unreachable("Dependent case handled above");
25477330f729Sjoerg 
25487330f729Sjoerg   case IEB_Skip:
25497330f729Sjoerg     Braces.skipToEnd();
25507330f729Sjoerg     return;
25517330f729Sjoerg   }
25527330f729Sjoerg 
25537330f729Sjoerg   // Condition is true, parse the statements.
25547330f729Sjoerg   while (Tok.isNot(tok::r_brace)) {
25557330f729Sjoerg     StmtResult R =
25567330f729Sjoerg         ParseStatementOrDeclaration(Stmts, ParsedStmtContext::Compound);
25577330f729Sjoerg     if (R.isUsable())
25587330f729Sjoerg       Stmts.push_back(R.get());
25597330f729Sjoerg   }
25607330f729Sjoerg   Braces.consumeClose();
25617330f729Sjoerg }
2562