brintos

brintos / llvm-project-archived public Read only

0
0
Text · 94.3 KiB · 7e73d89 Raw
2684 lines · cpp
1//===--- ParseStmt.cpp - Statement and Block Parser -----------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the Statement and Block portions of the Parser10// interface.11//12//===----------------------------------------------------------------------===//13 14#include "clang/AST/PrettyDeclStackTrace.h"15#include "clang/Basic/Attributes.h"16#include "clang/Basic/PrettyStackTrace.h"17#include "clang/Basic/TargetInfo.h"18#include "clang/Basic/TokenKinds.h"19#include "clang/Parse/LoopHint.h"20#include "clang/Parse/Parser.h"21#include "clang/Parse/RAIIObjectsForParser.h"22#include "clang/Sema/DeclSpec.h"23#include "clang/Sema/EnterExpressionEvaluationContext.h"24#include "clang/Sema/Scope.h"25#include "clang/Sema/SemaCodeCompletion.h"26#include "clang/Sema/SemaObjC.h"27#include "clang/Sema/SemaOpenACC.h"28#include "clang/Sema/SemaOpenMP.h"29#include "clang/Sema/TypoCorrection.h"30#include "llvm/ADT/STLExtras.h"31#include <optional>32 33using namespace clang;34 35//===----------------------------------------------------------------------===//36// C99 6.8: Statements and Blocks.37//===----------------------------------------------------------------------===//38 39StmtResult Parser::ParseStatement(SourceLocation *TrailingElseLoc,40                                  ParsedStmtContext StmtCtx,41                                  LabelDecl *PrecedingLabel) {42  StmtResult Res;43 44  // We may get back a null statement if we found a #pragma. Keep going until45  // we get an actual statement.46  StmtVector Stmts;47  do {48    Res = ParseStatementOrDeclaration(Stmts, StmtCtx, TrailingElseLoc,49                                      PrecedingLabel);50  } while (!Res.isInvalid() && !Res.get());51 52  return Res;53}54 55StmtResult Parser::ParseStatementOrDeclaration(StmtVector &Stmts,56                                               ParsedStmtContext StmtCtx,57                                               SourceLocation *TrailingElseLoc,58                                               LabelDecl *PrecedingLabel) {59 60  ParenBraceBracketBalancer BalancerRAIIObj(*this);61 62  // Because we're parsing either a statement or a declaration, the order of63  // attribute parsing is important. [[]] attributes at the start of a64  // statement are different from [[]] attributes that follow an __attribute__65  // at the start of the statement. Thus, we're not using MaybeParseAttributes66  // here because we don't want to allow arbitrary orderings.67  ParsedAttributes CXX11Attrs(AttrFactory);68  bool HasStdAttr =69      MaybeParseCXX11Attributes(CXX11Attrs, /*MightBeObjCMessageSend*/ true);70  ParsedAttributes GNUOrMSAttrs(AttrFactory);71  if (getLangOpts().OpenCL)72    MaybeParseGNUAttributes(GNUOrMSAttrs);73 74  if (getLangOpts().HLSL)75    MaybeParseMicrosoftAttributes(GNUOrMSAttrs);76 77  StmtResult Res = ParseStatementOrDeclarationAfterAttributes(78      Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs, GNUOrMSAttrs,79      PrecedingLabel);80  MaybeDestroyTemplateIds();81 82  takeAndConcatenateAttrs(CXX11Attrs, std::move(GNUOrMSAttrs));83 84  assert((CXX11Attrs.empty() || Res.isInvalid() || Res.isUsable()) &&85         "attributes on empty statement");86 87  if (HasStdAttr && getLangOpts().C23 &&88      (StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==89          ParsedStmtContext{} &&90      isa_and_present<NullStmt>(Res.get()))91    Diag(CXX11Attrs.Range.getBegin(), diag::warn_attr_in_secondary_block)92        << CXX11Attrs.Range;93 94  if (CXX11Attrs.empty() || Res.isInvalid())95    return Res;96 97  return Actions.ActOnAttributedStmt(CXX11Attrs, Res.get());98}99 100namespace {101class StatementFilterCCC final : public CorrectionCandidateCallback {102public:103  StatementFilterCCC(Token nextTok) : NextToken(nextTok) {104    WantTypeSpecifiers = nextTok.isOneOf(tok::l_paren, tok::less, tok::l_square,105                                         tok::identifier, tok::star, tok::amp);106    WantExpressionKeywords =107        nextTok.isOneOf(tok::l_paren, tok::identifier, tok::arrow, tok::period);108    WantRemainingKeywords =109        nextTok.isOneOf(tok::l_paren, tok::semi, tok::identifier, tok::l_brace);110    WantCXXNamedCasts = false;111  }112 113  bool ValidateCandidate(const TypoCorrection &candidate) override {114    if (FieldDecl *FD = candidate.getCorrectionDeclAs<FieldDecl>())115      return !candidate.getCorrectionSpecifier() || isa<ObjCIvarDecl>(FD);116    if (NextToken.is(tok::equal))117      return candidate.getCorrectionDeclAs<VarDecl>();118    if (NextToken.is(tok::period) &&119        candidate.getCorrectionDeclAs<NamespaceDecl>())120      return false;121    return CorrectionCandidateCallback::ValidateCandidate(candidate);122  }123 124  std::unique_ptr<CorrectionCandidateCallback> clone() override {125    return std::make_unique<StatementFilterCCC>(*this);126  }127 128private:129  Token NextToken;130};131}132 133StmtResult Parser::ParseStatementOrDeclarationAfterAttributes(134    StmtVector &Stmts, ParsedStmtContext StmtCtx,135    SourceLocation *TrailingElseLoc, ParsedAttributes &CXX11Attrs,136    ParsedAttributes &GNUAttrs, LabelDecl *PrecedingLabel) {137  const char *SemiError = nullptr;138  StmtResult Res;139  SourceLocation GNUAttributeLoc;140 141  // Cases in this switch statement should fall through if the parser expects142  // the token to end in a semicolon (in which case SemiError should be set),143  // or they directly 'return;' if not.144Retry:145  tok::TokenKind Kind  = Tok.getKind();146  SourceLocation AtLoc;147  switch (Kind) {148  case tok::at: // May be a @try or @throw statement149    {150      AtLoc = ConsumeToken();  // consume @151      return ParseObjCAtStatement(AtLoc, StmtCtx);152    }153 154  case tok::code_completion:155    cutOffParsing();156    Actions.CodeCompletion().CodeCompleteOrdinaryName(157        getCurScope(), SemaCodeCompletion::PCC_Statement);158    return StmtError();159 160  case tok::identifier:161  ParseIdentifier: {162    Token Next = NextToken();163    if (Next.is(tok::colon)) { // C99 6.8.1: labeled-statement164      // Both C++11 and GNU attributes preceding the label appertain to the165      // label, so put them in a single list to pass on to166      // ParseLabeledStatement().167      takeAndConcatenateAttrs(CXX11Attrs, std::move(GNUAttrs));168 169      // identifier ':' statement170      return ParseLabeledStatement(CXX11Attrs, StmtCtx);171    }172 173    // Look up the identifier, and typo-correct it to a keyword if it's not174    // found.175    if (Next.isNot(tok::coloncolon)) {176      // Try to limit which sets of keywords should be included in typo177      // correction based on what the next token is.178      StatementFilterCCC CCC(Next);179      if (TryAnnotateName(&CCC) == AnnotatedNameKind::Error) {180        // Handle errors here by skipping up to the next semicolon or '}', and181        // eat the semicolon if that's what stopped us.182        SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);183        if (Tok.is(tok::semi))184          ConsumeToken();185        return StmtError();186      }187 188      // If the identifier was annotated, try again.189      if (Tok.isNot(tok::identifier))190        goto Retry;191    }192 193    // Fall through194    [[fallthrough]];195  }196 197  default: {198    if (getLangOpts().CPlusPlus && MaybeParseCXX11Attributes(CXX11Attrs, true))199      goto Retry;200 201    bool HaveAttrs = !CXX11Attrs.empty() || !GNUAttrs.empty();202    auto IsStmtAttr = [](ParsedAttr &Attr) { return Attr.isStmtAttr(); };203    bool AllAttrsAreStmtAttrs = llvm::all_of(CXX11Attrs, IsStmtAttr) &&204                                llvm::all_of(GNUAttrs, IsStmtAttr);205    // In C, the grammar production for statement (C23 6.8.1p1) does not allow206    // for declarations, which is different from C++ (C++23 [stmt.pre]p1). So207    // in C++, we always allow a declaration, but in C we need to check whether208    // we're in a statement context that allows declarations. e.g., in C, the209    // following is invalid: if (1) int x;210    if ((getLangOpts().CPlusPlus || getLangOpts().MicrosoftExt ||211         (StmtCtx & ParsedStmtContext::AllowDeclarationsInC) !=212             ParsedStmtContext()) &&213        ((GNUAttributeLoc.isValid() && !(HaveAttrs && AllAttrsAreStmtAttrs)) ||214         isDeclarationStatement())) {215      SourceLocation DeclStart = Tok.getLocation(), DeclEnd;216      DeclGroupPtrTy Decl;217      if (GNUAttributeLoc.isValid()) {218        DeclStart = GNUAttributeLoc;219        Decl = ParseDeclaration(DeclaratorContext::Block, DeclEnd, CXX11Attrs,220                                GNUAttrs, &GNUAttributeLoc);221      } else {222        Decl = ParseDeclaration(DeclaratorContext::Block, DeclEnd, CXX11Attrs,223                                GNUAttrs);224      }225      if (CXX11Attrs.Range.getBegin().isValid()) {226        // Order of C++11 and GNU attributes is may be arbitrary.227        DeclStart = GNUAttrs.Range.getBegin().isInvalid()228                        ? CXX11Attrs.Range.getBegin()229                        : std::min(CXX11Attrs.Range.getBegin(),230                                   GNUAttrs.Range.getBegin());231      } else if (GNUAttrs.Range.getBegin().isValid())232        DeclStart = GNUAttrs.Range.getBegin();233      return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);234    }235 236    if (Tok.is(tok::r_brace)) {237      Diag(Tok, diag::err_expected_statement);238      return StmtError();239    }240 241    switch (Tok.getKind()) {242#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:243#include "clang/Basic/TransformTypeTraits.def"244      if (NextToken().is(tok::less)) {245        Tok.setKind(tok::identifier);246        Diag(Tok, diag::ext_keyword_as_ident)247            << Tok.getIdentifierInfo()->getName() << 0;248        goto ParseIdentifier;249      }250      [[fallthrough]];251    default:252      return ParseExprStatement(StmtCtx);253    }254  }255 256  case tok::kw___attribute: {257    GNUAttributeLoc = Tok.getLocation();258    ParseGNUAttributes(GNUAttrs);259    goto Retry;260  }261 262  case tok::kw_template: {263    SourceLocation DeclEnd;264    ParseTemplateDeclarationOrSpecialization(DeclaratorContext::Block, DeclEnd,265                                             getAccessSpecifierIfPresent());266    return StmtError();267  }268 269  case tok::kw_case:                // C99 6.8.1: labeled-statement270    return ParseCaseStatement(StmtCtx);271  case tok::kw_default:             // C99 6.8.1: labeled-statement272    return ParseDefaultStatement(StmtCtx);273 274  case tok::l_brace:                // C99 6.8.2: compound-statement275    return ParseCompoundStatement();276  case tok::semi: {                 // C99 6.8.3p3: expression[opt] ';'277    bool HasLeadingEmptyMacro = Tok.hasLeadingEmptyMacro();278    return Actions.ActOnNullStmt(ConsumeToken(), HasLeadingEmptyMacro);279  }280 281  case tok::kw_if:                  // C99 6.8.4.1: if-statement282    return ParseIfStatement(TrailingElseLoc);283  case tok::kw_switch:              // C99 6.8.4.2: switch-statement284    return ParseSwitchStatement(TrailingElseLoc, PrecedingLabel);285 286  case tok::kw_while:               // C99 6.8.5.1: while-statement287    return ParseWhileStatement(TrailingElseLoc, PrecedingLabel);288  case tok::kw_do:                  // C99 6.8.5.2: do-statement289    Res = ParseDoStatement(PrecedingLabel);290    SemiError = "do/while";291    break;292  case tok::kw_for:                 // C99 6.8.5.3: for-statement293    return ParseForStatement(TrailingElseLoc, PrecedingLabel);294 295  case tok::kw_goto:                // C99 6.8.6.1: goto-statement296    Res = ParseGotoStatement();297    SemiError = "goto";298    break;299  case tok::kw_continue:            // C99 6.8.6.2: continue-statement300    Res = ParseContinueStatement();301    SemiError = "continue";302    break;303  case tok::kw_break:               // C99 6.8.6.3: break-statement304    Res = ParseBreakStatement();305    SemiError = "break";306    break;307  case tok::kw_return:              // C99 6.8.6.4: return-statement308    Res = ParseReturnStatement();309    SemiError = "return";310    break;311  case tok::kw_co_return:            // C++ Coroutines: co_return statement312    Res = ParseReturnStatement();313    SemiError = "co_return";314    break;315 316  case tok::kw_asm: {317    for (const ParsedAttr &AL : CXX11Attrs)318      // Could be relaxed if asm-related regular keyword attributes are319      // added later.320      (AL.isRegularKeywordAttribute()321           ? Diag(AL.getRange().getBegin(), diag::err_keyword_not_allowed)322           : Diag(AL.getRange().getBegin(), diag::warn_attribute_ignored))323          << AL;324    // Prevent these from being interpreted as statement attributes later on.325    CXX11Attrs.clear();326    ProhibitAttributes(GNUAttrs);327    bool msAsm = false;328    Res = ParseAsmStatement(msAsm);329    if (msAsm) return Res;330    SemiError = "asm";331    break;332  }333 334  case tok::kw___if_exists:335  case tok::kw___if_not_exists:336    ProhibitAttributes(CXX11Attrs);337    ProhibitAttributes(GNUAttrs);338    ParseMicrosoftIfExistsStatement(Stmts);339    // An __if_exists block is like a compound statement, but it doesn't create340    // a new scope.341    return StmtEmpty();342 343  case tok::kw_try:                 // C++ 15: try-block344    return ParseCXXTryBlock();345 346  case tok::kw___try:347    ProhibitAttributes(CXX11Attrs);348    ProhibitAttributes(GNUAttrs);349    return ParseSEHTryBlock();350 351  case tok::kw___leave:352    Res = ParseSEHLeaveStatement();353    SemiError = "__leave";354    break;355 356  case tok::annot_pragma_vis:357    ProhibitAttributes(CXX11Attrs);358    ProhibitAttributes(GNUAttrs);359    HandlePragmaVisibility();360    return StmtEmpty();361 362  case tok::annot_pragma_pack:363    ProhibitAttributes(CXX11Attrs);364    ProhibitAttributes(GNUAttrs);365    HandlePragmaPack();366    return StmtEmpty();367 368  case tok::annot_pragma_msstruct:369    ProhibitAttributes(CXX11Attrs);370    ProhibitAttributes(GNUAttrs);371    HandlePragmaMSStruct();372    return StmtEmpty();373 374  case tok::annot_pragma_align:375    ProhibitAttributes(CXX11Attrs);376    ProhibitAttributes(GNUAttrs);377    HandlePragmaAlign();378    return StmtEmpty();379 380  case tok::annot_pragma_weak:381    ProhibitAttributes(CXX11Attrs);382    ProhibitAttributes(GNUAttrs);383    HandlePragmaWeak();384    return StmtEmpty();385 386  case tok::annot_pragma_weakalias:387    ProhibitAttributes(CXX11Attrs);388    ProhibitAttributes(GNUAttrs);389    HandlePragmaWeakAlias();390    return StmtEmpty();391 392  case tok::annot_pragma_redefine_extname:393    ProhibitAttributes(CXX11Attrs);394    ProhibitAttributes(GNUAttrs);395    HandlePragmaRedefineExtname();396    return StmtEmpty();397 398  case tok::annot_pragma_fp_contract:399    ProhibitAttributes(CXX11Attrs);400    ProhibitAttributes(GNUAttrs);401    Diag(Tok, diag::err_pragma_file_or_compound_scope) << "fp_contract";402    ConsumeAnnotationToken();403    return StmtError();404 405  case tok::annot_pragma_fp:406    ProhibitAttributes(CXX11Attrs);407    ProhibitAttributes(GNUAttrs);408    Diag(Tok, diag::err_pragma_file_or_compound_scope) << "clang fp";409    ConsumeAnnotationToken();410    return StmtError();411 412  case tok::annot_pragma_fenv_access:413  case tok::annot_pragma_fenv_access_ms:414    ProhibitAttributes(CXX11Attrs);415    ProhibitAttributes(GNUAttrs);416    Diag(Tok, diag::err_pragma_file_or_compound_scope)417        << (Kind == tok::annot_pragma_fenv_access ? "STDC FENV_ACCESS"418                                                    : "fenv_access");419    ConsumeAnnotationToken();420    return StmtEmpty();421 422  case tok::annot_pragma_fenv_round:423    ProhibitAttributes(CXX11Attrs);424    ProhibitAttributes(GNUAttrs);425    Diag(Tok, diag::err_pragma_file_or_compound_scope) << "STDC FENV_ROUND";426    ConsumeAnnotationToken();427    return StmtError();428 429  case tok::annot_pragma_cx_limited_range:430    ProhibitAttributes(CXX11Attrs);431    ProhibitAttributes(GNUAttrs);432    Diag(Tok, diag::err_pragma_file_or_compound_scope)433        << "STDC CX_LIMITED_RANGE";434    ConsumeAnnotationToken();435    return StmtError();436 437  case tok::annot_pragma_float_control:438    ProhibitAttributes(CXX11Attrs);439    ProhibitAttributes(GNUAttrs);440    Diag(Tok, diag::err_pragma_file_or_compound_scope) << "float_control";441    ConsumeAnnotationToken();442    return StmtError();443 444  case tok::annot_pragma_opencl_extension:445    ProhibitAttributes(CXX11Attrs);446    ProhibitAttributes(GNUAttrs);447    HandlePragmaOpenCLExtension();448    return StmtEmpty();449 450  case tok::annot_pragma_captured:451    ProhibitAttributes(CXX11Attrs);452    ProhibitAttributes(GNUAttrs);453    return HandlePragmaCaptured();454 455  case tok::annot_pragma_openmp:456    // Prohibit attributes that are not OpenMP attributes, but only before457    // processing a #pragma omp clause.458    ProhibitAttributes(CXX11Attrs);459    ProhibitAttributes(GNUAttrs);460    [[fallthrough]];461  case tok::annot_attr_openmp:462    // Do not prohibit attributes if they were OpenMP attributes.463    return ParseOpenMPDeclarativeOrExecutableDirective(StmtCtx);464 465  case tok::annot_pragma_openacc:466    return ParseOpenACCDirectiveStmt();467 468  case tok::annot_pragma_ms_pointers_to_members:469    ProhibitAttributes(CXX11Attrs);470    ProhibitAttributes(GNUAttrs);471    HandlePragmaMSPointersToMembers();472    return StmtEmpty();473 474  case tok::annot_pragma_ms_pragma:475    ProhibitAttributes(CXX11Attrs);476    ProhibitAttributes(GNUAttrs);477    HandlePragmaMSPragma();478    return StmtEmpty();479 480  case tok::annot_pragma_ms_vtordisp:481    ProhibitAttributes(CXX11Attrs);482    ProhibitAttributes(GNUAttrs);483    HandlePragmaMSVtorDisp();484    return StmtEmpty();485 486  case tok::annot_pragma_loop_hint:487    ProhibitAttributes(CXX11Attrs);488    ProhibitAttributes(GNUAttrs);489    return ParsePragmaLoopHint(Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs,490                               PrecedingLabel);491 492  case tok::annot_pragma_dump:493    ProhibitAttributes(CXX11Attrs);494    ProhibitAttributes(GNUAttrs);495    HandlePragmaDump();496    return StmtEmpty();497 498  case tok::annot_pragma_attribute:499    ProhibitAttributes(CXX11Attrs);500    ProhibitAttributes(GNUAttrs);501    HandlePragmaAttribute();502    return StmtEmpty();503  }504 505  // If we reached this code, the statement must end in a semicolon.506  if (!TryConsumeToken(tok::semi) && !Res.isInvalid()) {507    // If the result was valid, then we do want to diagnose this.  Use508    // ExpectAndConsume to emit the diagnostic, even though we know it won't509    // succeed.510    ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt, SemiError);511    // Skip until we see a } or ;, but don't eat it.512    SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);513  }514 515  return Res;516}517 518StmtResult Parser::ParseExprStatement(ParsedStmtContext StmtCtx) {519  // If a case keyword is missing, this is where it should be inserted.520  Token OldToken = Tok;521 522  ExprStatementTokLoc = Tok.getLocation();523 524  // expression[opt] ';'525  ExprResult Expr(ParseExpression());526  if (Expr.isInvalid()) {527    // If the expression is invalid, skip ahead to the next semicolon or '}'.528    // Not doing this opens us up to the possibility of infinite loops if529    // ParseExpression does not consume any tokens.530    SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);531    if (Tok.is(tok::semi))532      ConsumeToken();533    return Actions.ActOnExprStmtError();534  }535 536  if (Tok.is(tok::colon) && getCurScope()->isSwitchScope() &&537      Actions.CheckCaseExpression(Expr.get())) {538    // If a constant expression is followed by a colon inside a switch block,539    // suggest a missing case keyword.540    Diag(OldToken, diag::err_expected_case_before_expression)541      << FixItHint::CreateInsertion(OldToken.getLocation(), "case ");542 543    // Recover parsing as a case statement.544    return ParseCaseStatement(StmtCtx, /*MissingCase=*/true, Expr);545  }546 547  Token *CurTok = nullptr;548  // If the semicolon is missing at the end of REPL input, we want to print549  // the result. Note we shouldn't eat the token since the callback needs it.550  if (Tok.is(tok::annot_repl_input_end))551    CurTok = &Tok;552  else553    // Otherwise, eat the semicolon.554    ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);555 556  StmtResult R = handleExprStmt(Expr, StmtCtx);557  if (CurTok && !R.isInvalid())558    CurTok->setAnnotationValue(R.get());559 560  return R;561}562 563StmtResult Parser::ParseSEHTryBlock() {564  assert(Tok.is(tok::kw___try) && "Expected '__try'");565  SourceLocation TryLoc = ConsumeToken();566 567  if (Tok.isNot(tok::l_brace))568    return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);569 570  StmtResult TryBlock(ParseCompoundStatement(571      /*isStmtExpr=*/false,572      Scope::DeclScope | Scope::CompoundStmtScope | Scope::SEHTryScope));573  if (TryBlock.isInvalid())574    return TryBlock;575 576  StmtResult Handler;577  if (Tok.is(tok::identifier) &&578      Tok.getIdentifierInfo() == getSEHExceptKeyword()) {579    SourceLocation Loc = ConsumeToken();580    Handler = ParseSEHExceptBlock(Loc);581  } else if (Tok.is(tok::kw___finally)) {582    SourceLocation Loc = ConsumeToken();583    Handler = ParseSEHFinallyBlock(Loc);584  } else {585    return StmtError(Diag(Tok, diag::err_seh_expected_handler));586  }587 588  if(Handler.isInvalid())589    return Handler;590 591  return Actions.ActOnSEHTryBlock(false /* IsCXXTry */,592                                  TryLoc,593                                  TryBlock.get(),594                                  Handler.get());595}596 597StmtResult Parser::ParseSEHExceptBlock(SourceLocation ExceptLoc) {598  PoisonIdentifierRAIIObject raii(Ident__exception_code, false),599    raii2(Ident___exception_code, false),600    raii3(Ident_GetExceptionCode, false);601 602  if (ExpectAndConsume(tok::l_paren))603    return StmtError();604 605  ParseScope ExpectScope(this, Scope::DeclScope | Scope::ControlScope |606                                   Scope::SEHExceptScope);607 608  if (getLangOpts().Borland) {609    Ident__exception_info->setIsPoisoned(false);610    Ident___exception_info->setIsPoisoned(false);611    Ident_GetExceptionInfo->setIsPoisoned(false);612  }613 614  ExprResult FilterExpr;615  {616    ParseScopeFlags FilterScope(this, getCurScope()->getFlags() |617                                          Scope::SEHFilterScope);618    FilterExpr = ParseExpression();619  }620 621  if (getLangOpts().Borland) {622    Ident__exception_info->setIsPoisoned(true);623    Ident___exception_info->setIsPoisoned(true);624    Ident_GetExceptionInfo->setIsPoisoned(true);625  }626 627  if(FilterExpr.isInvalid())628    return StmtError();629 630  if (ExpectAndConsume(tok::r_paren))631    return StmtError();632 633  if (Tok.isNot(tok::l_brace))634    return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);635 636  StmtResult Block(ParseCompoundStatement());637 638  if(Block.isInvalid())639    return Block;640 641  return Actions.ActOnSEHExceptBlock(ExceptLoc, FilterExpr.get(), Block.get());642}643 644StmtResult Parser::ParseSEHFinallyBlock(SourceLocation FinallyLoc) {645  PoisonIdentifierRAIIObject raii(Ident__abnormal_termination, false),646    raii2(Ident___abnormal_termination, false),647    raii3(Ident_AbnormalTermination, false);648 649  if (Tok.isNot(tok::l_brace))650    return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);651 652  ParseScope FinallyScope(this, 0);653  Actions.ActOnStartSEHFinallyBlock();654 655  StmtResult Block(ParseCompoundStatement());656  if(Block.isInvalid()) {657    Actions.ActOnAbortSEHFinallyBlock();658    return Block;659  }660 661  return Actions.ActOnFinishSEHFinallyBlock(FinallyLoc, Block.get());662}663 664/// Handle __leave665///666/// seh-leave-statement:667///   '__leave' ';'668///669StmtResult Parser::ParseSEHLeaveStatement() {670  SourceLocation LeaveLoc = ConsumeToken();  // eat the '__leave'.671  return Actions.ActOnSEHLeaveStmt(LeaveLoc, getCurScope());672}673 674static void DiagnoseLabelFollowedByDecl(Parser &P, const Stmt *SubStmt) {675  // When in C mode (but not Microsoft extensions mode), diagnose use of a676  // label that is followed by a declaration rather than a statement.677  if (!P.getLangOpts().CPlusPlus && !P.getLangOpts().MicrosoftExt &&678      isa<DeclStmt>(SubStmt)) {679    P.Diag(SubStmt->getBeginLoc(),680           P.getLangOpts().C23681               ? diag::warn_c23_compat_label_followed_by_declaration682               : diag::ext_c_label_followed_by_declaration);683  }684}685 686StmtResult Parser::ParseLabeledStatement(ParsedAttributes &Attrs,687                                         ParsedStmtContext StmtCtx) {688  assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&689         "Not an identifier!");690 691  // [OpenMP 5.1] 2.1.3: A stand-alone directive may not be used in place of a692  // substatement in a selection statement, in place of the loop body in an693  // iteration statement, or in place of the statement that follows a label.694  StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;695 696  Token IdentTok = Tok;  // Save the whole token.697  ConsumeToken();  // eat the identifier.698 699  assert(Tok.is(tok::colon) && "Not a label!");700 701  // identifier ':' statement702  SourceLocation ColonLoc = ConsumeToken();703 704  LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),705                                              IdentTok.getLocation());706 707  // Read label attributes, if present.708  StmtResult SubStmt;709  if (Tok.is(tok::kw___attribute)) {710    ParsedAttributes TempAttrs(AttrFactory);711    ParseGNUAttributes(TempAttrs);712 713    // In C++, GNU attributes only apply to the label if they are followed by a714    // semicolon, to disambiguate label attributes from attributes on a labeled715    // declaration.716    //717    // This doesn't quite match what GCC does; if the attribute list is empty718    // and followed by a semicolon, GCC will reject (it appears to parse the719    // attributes as part of a statement in that case). That looks like a bug.720    if (!getLangOpts().CPlusPlus || Tok.is(tok::semi))721      Attrs.takeAllAppendingFrom(TempAttrs);722    else {723      StmtVector Stmts;724      ParsedAttributes EmptyCXX11Attrs(AttrFactory);725      SubStmt = ParseStatementOrDeclarationAfterAttributes(726          Stmts, StmtCtx, /*TrailingElseLoc=*/nullptr, EmptyCXX11Attrs,727          TempAttrs, LD);728      if (!TempAttrs.empty() && !SubStmt.isInvalid())729        SubStmt = Actions.ActOnAttributedStmt(TempAttrs, SubStmt.get());730    }731  }732 733  // The label may have no statement following it734  if (SubStmt.isUnset() && Tok.is(tok::r_brace)) {735    DiagnoseLabelAtEndOfCompoundStatement();736    SubStmt = Actions.ActOnNullStmt(ColonLoc);737  }738 739  // If we've not parsed a statement yet, parse one now.740  if (SubStmt.isUnset())741    SubStmt = ParseStatement(nullptr, StmtCtx, LD);742 743  // Broken substmt shouldn't prevent the label from being added to the AST.744  if (SubStmt.isInvalid())745    SubStmt = Actions.ActOnNullStmt(ColonLoc);746 747  DiagnoseLabelFollowedByDecl(*this, SubStmt.get());748 749  Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);750  Attrs.clear();751 752  return Actions.ActOnLabelStmt(IdentTok.getLocation(), LD, ColonLoc,753                                SubStmt.get());754}755 756StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx,757                                      bool MissingCase, ExprResult Expr) {758  assert((MissingCase || Tok.is(tok::kw_case)) && "Not a case stmt!");759 760  // [OpenMP 5.1] 2.1.3: A stand-alone directive may not be used in place of a761  // substatement in a selection statement, in place of the loop body in an762  // iteration statement, or in place of the statement that follows a label.763  StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;764 765  // It is very common for code to contain many case statements recursively766  // nested, as in (but usually without indentation):767  //  case 1:768  //    case 2:769  //      case 3:770  //         case 4:771  //           case 5: etc.772  //773  // Parsing this naively works, but is both inefficient and can cause us to run774  // out of stack space in our recursive descent parser.  As a special case,775  // flatten this recursion into an iterative loop.  This is complex and gross,776  // but all the grossness is constrained to ParseCaseStatement (and some777  // weirdness in the actions), so this is just local grossness :).778 779  // TopLevelCase - This is the highest level we have parsed.  'case 1' in the780  // example above.781  StmtResult TopLevelCase(true);782 783  // DeepestParsedCaseStmt - This is the deepest statement we have parsed, which784  // gets updated each time a new case is parsed, and whose body is unset so785  // far.  When parsing 'case 4', this is the 'case 3' node.786  Stmt *DeepestParsedCaseStmt = nullptr;787 788  // While we have case statements, eat and stack them.789  SourceLocation ColonLoc;790  do {791    SourceLocation CaseLoc = MissingCase ? Expr.get()->getExprLoc() :792                                           ConsumeToken();  // eat the 'case'.793    ColonLoc = SourceLocation();794 795    if (Tok.is(tok::code_completion)) {796      cutOffParsing();797      Actions.CodeCompletion().CodeCompleteCase(getCurScope());798      return StmtError();799    }800 801    /// We don't want to treat 'case x : y' as a potential typo for 'case x::y'.802    /// Disable this form of error recovery while we're parsing the case803    /// expression.804    ColonProtectionRAIIObject ColonProtection(*this);805 806    ExprResult LHS;807    if (!MissingCase) {808      LHS = ParseCaseExpression(CaseLoc);809      if (LHS.isInvalid()) {810        // If constant-expression is parsed unsuccessfully, recover by skipping811        // current case statement (moving to the colon that ends it).812        if (!SkipUntil(tok::colon, tok::r_brace, StopAtSemi | StopBeforeMatch))813          return StmtError();814      }815    } else {816      LHS = Actions.ActOnCaseExpr(CaseLoc, Expr);817      MissingCase = false;818    }819 820    // GNU case range extension.821    SourceLocation DotDotDotLoc;822    ExprResult RHS;823    if (TryConsumeToken(tok::ellipsis, DotDotDotLoc)) {824      // In C++, this is a GNU extension. In C, it's a C2y extension.825      unsigned DiagId;826      if (getLangOpts().CPlusPlus)827        DiagId = diag::ext_gnu_case_range;828      else if (getLangOpts().C2y)829        DiagId = diag::warn_c23_compat_case_range;830      else831        DiagId = diag::ext_c2y_case_range;832      Diag(DotDotDotLoc, DiagId);833      RHS = ParseCaseExpression(CaseLoc);834      if (RHS.isInvalid()) {835        if (!SkipUntil(tok::colon, tok::r_brace, StopAtSemi | StopBeforeMatch))836          return StmtError();837      }838    }839 840    ColonProtection.restore();841 842    if (TryConsumeToken(tok::colon, ColonLoc)) {843    } else if (TryConsumeToken(tok::semi, ColonLoc) ||844               TryConsumeToken(tok::coloncolon, ColonLoc)) {845      // Treat "case blah;" or "case blah::" as a typo for "case blah:".846      Diag(ColonLoc, diag::err_expected_after)847          << "'case'" << tok::colon848          << FixItHint::CreateReplacement(ColonLoc, ":");849    } else {850      SourceLocation ExpectedLoc = getEndOfPreviousToken();851 852      Diag(ExpectedLoc, diag::err_expected_after)853          << "'case'" << tok::colon854          << FixItHint::CreateInsertion(ExpectedLoc, ":");855 856      ColonLoc = ExpectedLoc;857    }858 859    StmtResult Case =860        Actions.ActOnCaseStmt(CaseLoc, LHS, DotDotDotLoc, RHS, ColonLoc);861 862    // If we had a sema error parsing this case, then just ignore it and863    // continue parsing the sub-stmt.864    if (Case.isInvalid()) {865      if (TopLevelCase.isInvalid())  // No parsed case stmts.866        return ParseStatement(/*TrailingElseLoc=*/nullptr, StmtCtx);867      // Otherwise, just don't add it as a nested case.868    } else {869      // If this is the first case statement we parsed, it becomes TopLevelCase.870      // Otherwise we link it into the current chain.871      Stmt *NextDeepest = Case.get();872      if (TopLevelCase.isInvalid())873        TopLevelCase = Case;874      else875        Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, Case.get());876      DeepestParsedCaseStmt = NextDeepest;877    }878 879    // Handle all case statements.880  } while (Tok.is(tok::kw_case));881 882  // If we found a non-case statement, start by parsing it.883  StmtResult SubStmt;884 885  if (Tok.is(tok::r_brace)) {886    // "switch (X) { case 4: }", is valid and is treated as if label was887    // followed by a null statement.888    DiagnoseLabelAtEndOfCompoundStatement();889    SubStmt = Actions.ActOnNullStmt(ColonLoc);890  } else {891    SubStmt = ParseStatement(/*TrailingElseLoc=*/nullptr, StmtCtx);892  }893 894  // Install the body into the most deeply-nested case.895  if (DeepestParsedCaseStmt) {896    // Broken sub-stmt shouldn't prevent forming the case statement properly.897    if (SubStmt.isInvalid())898      SubStmt = Actions.ActOnNullStmt(SourceLocation());899    DiagnoseLabelFollowedByDecl(*this, SubStmt.get());900    Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, SubStmt.get());901  }902 903  // Return the top level parsed statement tree.904  return TopLevelCase;905}906 907StmtResult Parser::ParseDefaultStatement(ParsedStmtContext StmtCtx) {908  assert(Tok.is(tok::kw_default) && "Not a default stmt!");909 910  // [OpenMP 5.1] 2.1.3: A stand-alone directive may not be used in place of a911  // substatement in a selection statement, in place of the loop body in an912  // iteration statement, or in place of the statement that follows a label.913  StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives;914 915  SourceLocation DefaultLoc = ConsumeToken();  // eat the 'default'.916 917  SourceLocation ColonLoc;918  if (TryConsumeToken(tok::colon, ColonLoc)) {919  } else if (TryConsumeToken(tok::semi, ColonLoc)) {920    // Treat "default;" as a typo for "default:".921    Diag(ColonLoc, diag::err_expected_after)922        << "'default'" << tok::colon923        << FixItHint::CreateReplacement(ColonLoc, ":");924  } else {925    SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation);926    Diag(ExpectedLoc, diag::err_expected_after)927        << "'default'" << tok::colon928        << FixItHint::CreateInsertion(ExpectedLoc, ":");929    ColonLoc = ExpectedLoc;930  }931 932  StmtResult SubStmt;933 934  if (Tok.is(tok::r_brace)) {935    // "switch (X) {... default: }", is valid and is treated as if label was936    // followed by a null statement.937    DiagnoseLabelAtEndOfCompoundStatement();938    SubStmt = Actions.ActOnNullStmt(ColonLoc);939  } else {940    SubStmt = ParseStatement(/*TrailingElseLoc=*/nullptr, StmtCtx);941  }942 943  // Broken sub-stmt shouldn't prevent forming the case statement properly.944  if (SubStmt.isInvalid())945    SubStmt = Actions.ActOnNullStmt(ColonLoc);946 947  DiagnoseLabelFollowedByDecl(*this, SubStmt.get());948  return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc,949                                  SubStmt.get(), getCurScope());950}951 952StmtResult Parser::ParseCompoundStatement(bool isStmtExpr) {953  return ParseCompoundStatement(isStmtExpr,954                                Scope::DeclScope | Scope::CompoundStmtScope);955}956 957StmtResult Parser::ParseCompoundStatement(bool isStmtExpr,958                                          unsigned ScopeFlags) {959  assert(Tok.is(tok::l_brace) && "Not a compound stmt!");960 961  // Enter a scope to hold everything within the compound stmt.  Compound962  // statements can always hold declarations.963  ParseScope CompoundScope(this, ScopeFlags);964 965  // Parse the statements in the body.966  StmtResult R;967  StackHandler.runWithSufficientStackSpace(Tok.getLocation(), [&, this]() {968    R = ParseCompoundStatementBody(isStmtExpr);969  });970  return R;971}972 973void Parser::ParseCompoundStatementLeadingPragmas() {974  bool checkForPragmas = true;975  while (checkForPragmas) {976    switch (Tok.getKind()) {977    case tok::annot_pragma_vis:978      HandlePragmaVisibility();979      break;980    case tok::annot_pragma_pack:981      HandlePragmaPack();982      break;983    case tok::annot_pragma_msstruct:984      HandlePragmaMSStruct();985      break;986    case tok::annot_pragma_align:987      HandlePragmaAlign();988      break;989    case tok::annot_pragma_weak:990      HandlePragmaWeak();991      break;992    case tok::annot_pragma_weakalias:993      HandlePragmaWeakAlias();994      break;995    case tok::annot_pragma_redefine_extname:996      HandlePragmaRedefineExtname();997      break;998    case tok::annot_pragma_opencl_extension:999      HandlePragmaOpenCLExtension();1000      break;1001    case tok::annot_pragma_fp_contract:1002      HandlePragmaFPContract();1003      break;1004    case tok::annot_pragma_fp:1005      HandlePragmaFP();1006      break;1007    case tok::annot_pragma_fenv_access:1008    case tok::annot_pragma_fenv_access_ms:1009      HandlePragmaFEnvAccess();1010      break;1011    case tok::annot_pragma_fenv_round:1012      HandlePragmaFEnvRound();1013      break;1014    case tok::annot_pragma_cx_limited_range:1015      HandlePragmaCXLimitedRange();1016      break;1017    case tok::annot_pragma_float_control:1018      HandlePragmaFloatControl();1019      break;1020    case tok::annot_pragma_ms_pointers_to_members:1021      HandlePragmaMSPointersToMembers();1022      break;1023    case tok::annot_pragma_ms_pragma:1024      HandlePragmaMSPragma();1025      break;1026    case tok::annot_pragma_ms_vtordisp:1027      HandlePragmaMSVtorDisp();1028      break;1029    case tok::annot_pragma_dump:1030      HandlePragmaDump();1031      break;1032    default:1033      checkForPragmas = false;1034      break;1035    }1036  }1037 1038}1039 1040void Parser::DiagnoseLabelAtEndOfCompoundStatement() {1041  if (getLangOpts().CPlusPlus) {1042    Diag(Tok, getLangOpts().CPlusPlus231043                  ? diag::warn_cxx20_compat_label_end_of_compound_statement1044                  : diag::ext_cxx_label_end_of_compound_statement);1045  } else {1046    Diag(Tok, getLangOpts().C231047                  ? diag::warn_c23_compat_label_end_of_compound_statement1048                  : diag::ext_c_label_end_of_compound_statement);1049  }1050}1051 1052bool Parser::ConsumeNullStmt(StmtVector &Stmts) {1053  if (!Tok.is(tok::semi))1054    return false;1055 1056  SourceLocation StartLoc = Tok.getLocation();1057  SourceLocation EndLoc;1058 1059  while (Tok.is(tok::semi) && !Tok.hasLeadingEmptyMacro() &&1060         Tok.getLocation().isValid() && !Tok.getLocation().isMacroID()) {1061    EndLoc = Tok.getLocation();1062 1063    // Don't just ConsumeToken() this tok::semi, do store it in AST.1064    StmtResult R =1065        ParseStatementOrDeclaration(Stmts, ParsedStmtContext::SubStmt);1066    if (R.isUsable())1067      Stmts.push_back(R.get());1068  }1069 1070  // Did not consume any extra semi.1071  if (EndLoc.isInvalid())1072    return false;1073 1074  Diag(StartLoc, diag::warn_null_statement)1075      << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc));1076  return true;1077}1078 1079StmtResult Parser::handleExprStmt(ExprResult E, ParsedStmtContext StmtCtx) {1080  bool IsStmtExprResult = false;1081  if ((StmtCtx & ParsedStmtContext::InStmtExpr) != ParsedStmtContext()) {1082    // Look ahead to see if the next two tokens close the statement expression;1083    // if so, this expression statement is the last statement in a1084    // statment expression.1085    IsStmtExprResult = Tok.is(tok::r_brace) && NextToken().is(tok::r_paren);1086  }1087 1088  if (IsStmtExprResult)1089    E = Actions.ActOnStmtExprResult(E);1090  return Actions.ActOnExprStmt(E, /*DiscardedValue=*/!IsStmtExprResult);1091}1092 1093StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {1094  PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),1095                                Tok.getLocation(),1096                                "in compound statement ('{}')");1097 1098  // Record the current FPFeatures, restore on leaving the1099  // compound statement.1100  Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);1101 1102  InMessageExpressionRAIIObject InMessage(*this, false);1103  BalancedDelimiterTracker T(*this, tok::l_brace);1104  if (T.consumeOpen())1105    return StmtError();1106 1107  Sema::CompoundScopeRAII CompoundScope(Actions, isStmtExpr);1108 1109  // Parse any pragmas at the beginning of the compound statement.1110  ParseCompoundStatementLeadingPragmas();1111  Actions.ActOnAfterCompoundStatementLeadingPragmas();1112 1113  StmtVector Stmts;1114 1115  // "__label__ X, Y, Z;" is the GNU "Local Label" extension.  These are1116  // only allowed at the start of a compound stmt regardless of the language.1117  while (Tok.is(tok::kw___label__)) {1118    SourceLocation LabelLoc = ConsumeToken();1119 1120    SmallVector<Decl *, 4> DeclsInGroup;1121    while (true) {1122      if (Tok.isNot(tok::identifier)) {1123        Diag(Tok, diag::err_expected) << tok::identifier;1124        break;1125      }1126 1127      IdentifierInfo *II = Tok.getIdentifierInfo();1128      SourceLocation IdLoc = ConsumeToken();1129      DeclsInGroup.push_back(Actions.LookupOrCreateLabel(II, IdLoc, LabelLoc));1130 1131      if (!TryConsumeToken(tok::comma))1132        break;1133    }1134 1135    DeclSpec DS(AttrFactory);1136    DeclGroupPtrTy Res =1137        Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup);1138    StmtResult R = Actions.ActOnDeclStmt(Res, LabelLoc, Tok.getLocation());1139 1140    ExpectAndConsumeSemi(diag::err_expected_semi_declaration);1141    if (R.isUsable())1142      Stmts.push_back(R.get());1143  }1144 1145  ParsedStmtContext SubStmtCtx =1146      ParsedStmtContext::Compound |1147      (isStmtExpr ? ParsedStmtContext::InStmtExpr : ParsedStmtContext());1148 1149  bool LastIsError = false;1150  while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&1151         Tok.isNot(tok::eof)) {1152    if (Tok.is(tok::annot_pragma_unused)) {1153      HandlePragmaUnused();1154      continue;1155    }1156 1157    if (ConsumeNullStmt(Stmts))1158      continue;1159 1160    StmtResult R;1161    if (Tok.isNot(tok::kw___extension__)) {1162      R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);1163    } else {1164      // __extension__ can start declarations and it can also be a unary1165      // operator for expressions.  Consume multiple __extension__ markers here1166      // until we can determine which is which.1167      // FIXME: This loses extension expressions in the AST!1168      SourceLocation ExtLoc = ConsumeToken();1169      while (Tok.is(tok::kw___extension__))1170        ConsumeToken();1171 1172      ParsedAttributes attrs(AttrFactory);1173      MaybeParseCXX11Attributes(attrs, /*MightBeObjCMessageSend*/ true);1174 1175      // If this is the start of a declaration, parse it as such.1176      if (isDeclarationStatement()) {1177        // __extension__ silences extension warnings in the subdeclaration.1178        // FIXME: Save the __extension__ on the decl as a node somehow?1179        ExtensionRAIIObject O(Diags);1180 1181        SourceLocation DeclStart = Tok.getLocation(), DeclEnd;1182        ParsedAttributes DeclSpecAttrs(AttrFactory);1183        DeclGroupPtrTy Res = ParseDeclaration(DeclaratorContext::Block, DeclEnd,1184                                              attrs, DeclSpecAttrs);1185        R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);1186      } else {1187        // Otherwise this was a unary __extension__ marker.1188        ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));1189 1190        if (Res.isInvalid()) {1191          SkipUntil(tok::semi);1192          continue;1193        }1194 1195        // Eat the semicolon at the end of stmt and convert the expr into a1196        // statement.1197        ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);1198        R = handleExprStmt(Res, SubStmtCtx);1199        if (R.isUsable())1200          R = Actions.ActOnAttributedStmt(attrs, R.get());1201      }1202    }1203 1204    if (R.isUsable())1205      Stmts.push_back(R.get());1206    LastIsError = R.isInvalid();1207  }1208  // StmtExpr needs to do copy initialization for last statement.1209  // If last statement is invalid, the last statement in `Stmts` will be1210  // incorrect. Then the whole compound statement should also be marked as1211  // invalid to prevent subsequent errors.1212  if (isStmtExpr && LastIsError && !Stmts.empty())1213    return StmtError();1214 1215  // Warn the user that using option `-ffp-eval-method=source` on a1216  // 32-bit target and feature `sse` disabled, or using1217  // `pragma clang fp eval_method=source` and feature `sse` disabled, is not1218  // supported.1219  if (!PP.getTargetInfo().supportSourceEvalMethod() &&1220      (PP.getLastFPEvalPragmaLocation().isValid() ||1221       PP.getCurrentFPEvalMethod() ==1222           LangOptions::FPEvalMethodKind::FEM_Source))1223    Diag(Tok.getLocation(),1224         diag::warn_no_support_for_eval_method_source_on_m32);1225 1226  SourceLocation CloseLoc = Tok.getLocation();1227 1228  // We broke out of the while loop because we found a '}' or EOF.1229  if (!T.consumeClose()) {1230    // If this is the '})' of a statement expression, check that it's written1231    // in a sensible way.1232    if (isStmtExpr && Tok.is(tok::r_paren))1233      checkCompoundToken(CloseLoc, tok::r_brace, CompoundToken::StmtExprEnd);1234  } else {1235    // Recover by creating a compound statement with what we parsed so far,1236    // instead of dropping everything and returning StmtError().1237  }1238 1239  if (T.getCloseLocation().isValid())1240    CloseLoc = T.getCloseLocation();1241 1242  return Actions.ActOnCompoundStmt(T.getOpenLocation(), CloseLoc,1243                                   Stmts, isStmtExpr);1244}1245 1246bool Parser::ParseParenExprOrCondition(StmtResult *InitStmt,1247                                       Sema::ConditionResult &Cond,1248                                       SourceLocation Loc,1249                                       Sema::ConditionKind CK,1250                                       SourceLocation &LParenLoc,1251                                       SourceLocation &RParenLoc) {1252  BalancedDelimiterTracker T(*this, tok::l_paren);1253  T.consumeOpen();1254  SourceLocation Start = Tok.getLocation();1255 1256  if (getLangOpts().CPlusPlus) {1257    Cond = ParseCXXCondition(InitStmt, Loc, CK, false);1258  } else {1259    ExprResult CondExpr = ParseExpression();1260 1261    // If required, convert to a boolean value.1262    if (CondExpr.isInvalid())1263      Cond = Sema::ConditionError();1264    else1265      Cond = Actions.ActOnCondition(getCurScope(), Loc, CondExpr.get(), CK,1266                                    /*MissingOK=*/false);1267  }1268 1269  // If the parser was confused by the condition and we don't have a ')', try to1270  // recover by skipping ahead to a semi and bailing out.  If condexp is1271  // semantically invalid but we have well formed code, keep going.1272  if (Cond.isInvalid() && Tok.isNot(tok::r_paren)) {1273    SkipUntil(tok::semi);1274    // Skipping may have stopped if it found the containing ')'.  If so, we can1275    // continue parsing the if statement.1276    if (Tok.isNot(tok::r_paren))1277      return true;1278  }1279 1280  if (Cond.isInvalid()) {1281    ExprResult CondExpr = Actions.CreateRecoveryExpr(1282        Start, Tok.getLocation() == Start ? Start : PrevTokLocation, {},1283        Actions.PreferredConditionType(CK));1284    if (!CondExpr.isInvalid())1285      Cond = Actions.ActOnCondition(getCurScope(), Loc, CondExpr.get(), CK,1286                                    /*MissingOK=*/false);1287  }1288 1289  // Either the condition is valid or the rparen is present.1290  T.consumeClose();1291  LParenLoc = T.getOpenLocation();1292  RParenLoc = T.getCloseLocation();1293 1294  // Check for extraneous ')'s to catch things like "if (foo())) {".  We know1295  // that all callers are looking for a statement after the condition, so ")"1296  // isn't valid.1297  while (Tok.is(tok::r_paren)) {1298    Diag(Tok, diag::err_extraneous_rparen_in_condition)1299      << FixItHint::CreateRemoval(Tok.getLocation());1300    ConsumeParen();1301  }1302 1303  return false;1304}1305 1306namespace {1307 1308enum MisleadingStatementKind { MSK_if, MSK_else, MSK_for, MSK_while };1309 1310struct MisleadingIndentationChecker {1311  Parser &P;1312  SourceLocation StmtLoc;1313  SourceLocation PrevLoc;1314  unsigned NumDirectives;1315  MisleadingStatementKind Kind;1316  bool ShouldSkip;1317  MisleadingIndentationChecker(Parser &P, MisleadingStatementKind K,1318                               SourceLocation SL)1319      : P(P), StmtLoc(SL), PrevLoc(P.getCurToken().getLocation()),1320        NumDirectives(P.getPreprocessor().getNumDirectives()), Kind(K),1321        ShouldSkip(P.getCurToken().is(tok::l_brace)) {1322    if (!P.MisleadingIndentationElseLoc.isInvalid()) {1323      StmtLoc = P.MisleadingIndentationElseLoc;1324      P.MisleadingIndentationElseLoc = SourceLocation();1325    }1326    if (Kind == MSK_else && !ShouldSkip)1327      P.MisleadingIndentationElseLoc = SL;1328  }1329 1330  /// Compute the column number will aligning tabs on TabStop (-ftabstop), this1331  /// gives the visual indentation of the SourceLocation.1332  static unsigned getVisualIndentation(SourceManager &SM, SourceLocation Loc) {1333    unsigned TabStop = SM.getDiagnostics().getDiagnosticOptions().TabStop;1334 1335    unsigned ColNo = SM.getSpellingColumnNumber(Loc);1336    if (ColNo == 0 || TabStop == 1)1337      return ColNo;1338 1339    FileIDAndOffset FIDAndOffset = SM.getDecomposedLoc(Loc);1340 1341    bool Invalid;1342    StringRef BufData = SM.getBufferData(FIDAndOffset.first, &Invalid);1343    if (Invalid)1344      return 0;1345 1346    const char *EndPos = BufData.data() + FIDAndOffset.second;1347    // FileOffset are 0-based and Column numbers are 1-based1348    assert(FIDAndOffset.second + 1 >= ColNo &&1349           "Column number smaller than file offset?");1350 1351    unsigned VisualColumn = 0; // Stored as 0-based column, here.1352    // Loop from beginning of line up to Loc's file position, counting columns,1353    // expanding tabs.1354    for (const char *CurPos = EndPos - (ColNo - 1); CurPos != EndPos;1355         ++CurPos) {1356      if (*CurPos == '\t')1357        // Advance visual column to next tabstop.1358        VisualColumn += (TabStop - VisualColumn % TabStop);1359      else1360        VisualColumn++;1361    }1362    return VisualColumn + 1;1363  }1364 1365  void Check() {1366    Token Tok = P.getCurToken();1367    if (P.getActions().getDiagnostics().isIgnored(1368            diag::warn_misleading_indentation, Tok.getLocation()) ||1369        ShouldSkip || NumDirectives != P.getPreprocessor().getNumDirectives() ||1370        Tok.isOneOf(tok::semi, tok::r_brace) || Tok.isAnnotation() ||1371        Tok.getLocation().isMacroID() || PrevLoc.isMacroID() ||1372        StmtLoc.isMacroID() ||1373        (Kind == MSK_else && P.MisleadingIndentationElseLoc.isInvalid())) {1374      P.MisleadingIndentationElseLoc = SourceLocation();1375      return;1376    }1377    if (Kind == MSK_else)1378      P.MisleadingIndentationElseLoc = SourceLocation();1379 1380    SourceManager &SM = P.getPreprocessor().getSourceManager();1381    unsigned PrevColNum = getVisualIndentation(SM, PrevLoc);1382    unsigned CurColNum = getVisualIndentation(SM, Tok.getLocation());1383    unsigned StmtColNum = getVisualIndentation(SM, StmtLoc);1384 1385    if (PrevColNum != 0 && CurColNum != 0 && StmtColNum != 0 &&1386        ((PrevColNum > StmtColNum && PrevColNum == CurColNum) ||1387         !Tok.isAtStartOfLine()) &&1388        SM.getPresumedLineNumber(StmtLoc) !=1389            SM.getPresumedLineNumber(Tok.getLocation()) &&1390        (Tok.isNot(tok::identifier) ||1391         P.getPreprocessor().LookAhead(0).isNot(tok::colon))) {1392      P.Diag(Tok.getLocation(), diag::warn_misleading_indentation) << Kind;1393      P.Diag(StmtLoc, diag::note_previous_statement);1394    }1395  }1396};1397 1398}1399 1400StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {1401  assert(Tok.is(tok::kw_if) && "Not an if stmt!");1402  SourceLocation IfLoc = ConsumeToken();  // eat the 'if'.1403 1404  bool IsConstexpr = false;1405  bool IsConsteval = false;1406  SourceLocation NotLocation;1407  SourceLocation ConstevalLoc;1408 1409  if (Tok.is(tok::kw_constexpr)) {1410    // C23 supports constexpr keyword, but only for object definitions.1411    if (getLangOpts().CPlusPlus) {1412      Diag(Tok, getLangOpts().CPlusPlus17 ? diag::warn_cxx14_compat_constexpr_if1413                                          : diag::ext_constexpr_if);1414      IsConstexpr = true;1415      ConsumeToken();1416    }1417  } else {1418    if (Tok.is(tok::exclaim)) {1419      NotLocation = ConsumeToken();1420    }1421 1422    if (Tok.is(tok::kw_consteval)) {1423      Diag(Tok, getLangOpts().CPlusPlus23 ? diag::warn_cxx20_compat_consteval_if1424                                          : diag::ext_consteval_if);1425      IsConsteval = true;1426      ConstevalLoc = ConsumeToken();1427    } else if (Tok.is(tok::code_completion)) {1428      cutOffParsing();1429      Actions.CodeCompletion().CodeCompleteKeywordAfterIf(1430          NotLocation.isValid());1431      return StmtError();1432    }1433  }1434  if (!IsConsteval && (NotLocation.isValid() || Tok.isNot(tok::l_paren))) {1435    Diag(Tok, diag::err_expected_lparen_after) << "if";1436    SkipUntil(tok::semi);1437    return StmtError();1438  }1439 1440  bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;1441 1442  // C99 6.8.4p3 - In C99, the if statement is a block.  This is not1443  // the case for C90.1444  //1445  // C++ 6.4p3:1446  // A name introduced by a declaration in a condition is in scope from its1447  // point of declaration until the end of the substatements controlled by the1448  // condition.1449  // C++ 3.3.2p4:1450  // Names declared in the for-init-statement, and in the condition of if,1451  // while, for, and switch statements are local to the if, while, for, or1452  // switch statement (including the controlled statement).1453  //1454  ParseScope IfScope(this, Scope::DeclScope | Scope::ControlScope, C99orCXX);1455 1456  // Parse the condition.1457  StmtResult InitStmt;1458  Sema::ConditionResult Cond;1459  SourceLocation LParen;1460  SourceLocation RParen;1461  std::optional<bool> ConstexprCondition;1462  if (!IsConsteval) {1463 1464    if (ParseParenExprOrCondition(&InitStmt, Cond, IfLoc,1465                                  IsConstexpr ? Sema::ConditionKind::ConstexprIf1466                                              : Sema::ConditionKind::Boolean,1467                                  LParen, RParen))1468      return StmtError();1469 1470    if (IsConstexpr)1471      ConstexprCondition = Cond.getKnownValue();1472  }1473 1474  bool IsBracedThen = Tok.is(tok::l_brace);1475 1476  // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if1477  // there is no compound stmt.  C90 does not have this clause.  We only do this1478  // if the body isn't a compound statement to avoid push/pop in common cases.1479  //1480  // C++ 6.4p1:1481  // The substatement in a selection-statement (each substatement, in the else1482  // form of the if statement) implicitly defines a local scope.1483  //1484  // For C++ we create a scope for the condition and a new scope for1485  // substatements because:1486  // -When the 'then' scope exits, we want the condition declaration to still be1487  //    active for the 'else' scope too.1488  // -Sema will detect name clashes by considering declarations of a1489  //    'ControlScope' as part of its direct subscope.1490  // -If we wanted the condition and substatement to be in the same scope, we1491  //    would have to notify ParseStatement not to create a new scope. It's1492  //    simpler to let it create a new scope.1493  //1494  ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, IsBracedThen);1495 1496  MisleadingIndentationChecker MIChecker(*this, MSK_if, IfLoc);1497 1498  // Read the 'then' stmt.1499  SourceLocation ThenStmtLoc = Tok.getLocation();1500 1501  SourceLocation InnerStatementTrailingElseLoc;1502  StmtResult ThenStmt;1503  {1504    bool ShouldEnter = ConstexprCondition && !*ConstexprCondition;1505    Sema::ExpressionEvaluationContext Context =1506        Sema::ExpressionEvaluationContext::DiscardedStatement;1507    if (NotLocation.isInvalid() && IsConsteval) {1508      Context = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;1509      ShouldEnter = true;1510    }1511 1512    EnterExpressionEvaluationContext PotentiallyDiscarded(1513        Actions, Context, nullptr,1514        Sema::ExpressionEvaluationContextRecord::EK_Other, ShouldEnter);1515    ThenStmt = ParseStatement(&InnerStatementTrailingElseLoc);1516  }1517 1518  if (Tok.isNot(tok::kw_else))1519    MIChecker.Check();1520 1521  // Pop the 'if' scope if needed.1522  InnerScope.Exit();1523 1524  // If it has an else, parse it.1525  SourceLocation ElseLoc;1526  SourceLocation ElseStmtLoc;1527  StmtResult ElseStmt;1528 1529  if (Tok.is(tok::kw_else)) {1530    if (TrailingElseLoc)1531      *TrailingElseLoc = Tok.getLocation();1532 1533    ElseLoc = ConsumeToken();1534    ElseStmtLoc = Tok.getLocation();1535 1536    // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if1537    // there is no compound stmt.  C90 does not have this clause.  We only do1538    // this if the body isn't a compound statement to avoid push/pop in common1539    // cases.1540    //1541    // C++ 6.4p1:1542    // The substatement in a selection-statement (each substatement, in the else1543    // form of the if statement) implicitly defines a local scope.1544    //1545    ParseScope InnerScope(this, Scope::DeclScope, C99orCXX,1546                          Tok.is(tok::l_brace));1547 1548    MisleadingIndentationChecker MIChecker(*this, MSK_else, ElseLoc);1549    bool ShouldEnter = ConstexprCondition && *ConstexprCondition;1550    Sema::ExpressionEvaluationContext Context =1551        Sema::ExpressionEvaluationContext::DiscardedStatement;1552    if (NotLocation.isValid() && IsConsteval) {1553      Context = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;1554      ShouldEnter = true;1555    }1556 1557    EnterExpressionEvaluationContext PotentiallyDiscarded(1558        Actions, Context, nullptr,1559        Sema::ExpressionEvaluationContextRecord::EK_Other, ShouldEnter);1560    ElseStmt = ParseStatement();1561 1562    if (ElseStmt.isUsable())1563      MIChecker.Check();1564 1565    // Pop the 'else' scope if needed.1566    InnerScope.Exit();1567  } else if (Tok.is(tok::code_completion)) {1568    cutOffParsing();1569    Actions.CodeCompletion().CodeCompleteAfterIf(getCurScope(), IsBracedThen);1570    return StmtError();1571  } else if (InnerStatementTrailingElseLoc.isValid()) {1572    Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else);1573  }1574 1575  IfScope.Exit();1576 1577  // If the then or else stmt is invalid and the other is valid (and present),1578  // turn the invalid one into a null stmt to avoid dropping the other1579  // part.  If both are invalid, return error.1580  if ((ThenStmt.isInvalid() && ElseStmt.isInvalid()) ||1581      (ThenStmt.isInvalid() && ElseStmt.get() == nullptr) ||1582      (ThenStmt.get() == nullptr && ElseStmt.isInvalid())) {1583    // Both invalid, or one is invalid and other is non-present: return error.1584    return StmtError();1585  }1586 1587  if (IsConsteval) {1588    auto IsCompoundStatement = [](const Stmt *S) {1589      if (const auto *Outer = dyn_cast_if_present<AttributedStmt>(S))1590        S = Outer->getSubStmt();1591      return isa_and_nonnull<clang::CompoundStmt>(S);1592    };1593 1594    if (!IsCompoundStatement(ThenStmt.get())) {1595      Diag(ConstevalLoc, diag::err_expected_after) << "consteval"1596                                                   << "{";1597      return StmtError();1598    }1599    if (!ElseStmt.isUnset() && !IsCompoundStatement(ElseStmt.get())) {1600      Diag(ElseLoc, diag::err_expected_after) << "else"1601                                              << "{";1602      return StmtError();1603    }1604  }1605 1606  // Now if either are invalid, replace with a ';'.1607  if (ThenStmt.isInvalid())1608    ThenStmt = Actions.ActOnNullStmt(ThenStmtLoc);1609  if (ElseStmt.isInvalid())1610    ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);1611 1612  IfStatementKind Kind = IfStatementKind::Ordinary;1613  if (IsConstexpr)1614    Kind = IfStatementKind::Constexpr;1615  else if (IsConsteval)1616    Kind = NotLocation.isValid() ? IfStatementKind::ConstevalNegated1617                                 : IfStatementKind::ConstevalNonNegated;1618 1619  return Actions.ActOnIfStmt(IfLoc, Kind, LParen, InitStmt.get(), Cond, RParen,1620                             ThenStmt.get(), ElseLoc, ElseStmt.get());1621}1622 1623StmtResult Parser::ParseSwitchStatement(SourceLocation *TrailingElseLoc,1624                                        LabelDecl *PrecedingLabel) {1625  assert(Tok.is(tok::kw_switch) && "Not a switch stmt!");1626  SourceLocation SwitchLoc = ConsumeToken();  // eat the 'switch'.1627 1628  if (Tok.isNot(tok::l_paren)) {1629    Diag(Tok, diag::err_expected_lparen_after) << "switch";1630    SkipUntil(tok::semi);1631    return StmtError();1632  }1633 1634  bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;1635 1636  // C99 6.8.4p3 - In C99, the switch statement is a block.  This is1637  // not the case for C90.  Start the switch scope.1638  //1639  // C++ 6.4p3:1640  // A name introduced by a declaration in a condition is in scope from its1641  // point of declaration until the end of the substatements controlled by the1642  // condition.1643  // C++ 3.3.2p4:1644  // Names declared in the for-init-statement, and in the condition of if,1645  // while, for, and switch statements are local to the if, while, for, or1646  // switch statement (including the controlled statement).1647  //1648  unsigned ScopeFlags = Scope::SwitchScope;1649  if (C99orCXX)1650    ScopeFlags |= Scope::DeclScope | Scope::ControlScope;1651  ParseScope SwitchScope(this, ScopeFlags);1652 1653  // Parse the condition.1654  StmtResult InitStmt;1655  Sema::ConditionResult Cond;1656  SourceLocation LParen;1657  SourceLocation RParen;1658  if (ParseParenExprOrCondition(&InitStmt, Cond, SwitchLoc,1659                                Sema::ConditionKind::Switch, LParen, RParen))1660    return StmtError();1661 1662  StmtResult Switch = Actions.ActOnStartOfSwitchStmt(1663      SwitchLoc, LParen, InitStmt.get(), Cond, RParen);1664 1665  if (Switch.isInvalid()) {1666    // Skip the switch body.1667    // FIXME: This is not optimal recovery, but parsing the body is more1668    // dangerous due to the presence of case and default statements, which1669    // will have no place to connect back with the switch.1670    if (Tok.is(tok::l_brace)) {1671      ConsumeBrace();1672      SkipUntil(tok::r_brace);1673    } else1674      SkipUntil(tok::semi);1675    return Switch;1676  }1677 1678  // C99 6.8.4p3 - In C99, the body of the switch statement is a scope, even if1679  // there is no compound stmt.  C90 does not have this clause.  We only do this1680  // if the body isn't a compound statement to avoid push/pop in common cases.1681  //1682  // C++ 6.4p1:1683  // The substatement in a selection-statement (each substatement, in the else1684  // form of the if statement) implicitly defines a local scope.1685  //1686  // See comments in ParseIfStatement for why we create a scope for the1687  // condition and a new scope for substatement in C++.1688  //1689  getCurScope()->AddFlags(Scope::BreakScope);1690  getCurScope()->setPrecedingLabel(PrecedingLabel);1691  ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));1692 1693  // We have incremented the mangling number for the SwitchScope and the1694  // InnerScope, which is one too many.1695  if (C99orCXX)1696    getCurScope()->decrementMSManglingNumber();1697 1698  // Read the body statement.1699  StmtResult Body(ParseStatement(TrailingElseLoc));1700 1701  // Pop the scopes.1702  InnerScope.Exit();1703  SwitchScope.Exit();1704 1705  return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.get(), Body.get());1706}1707 1708StmtResult Parser::ParseWhileStatement(SourceLocation *TrailingElseLoc,1709                                       LabelDecl *PrecedingLabel) {1710  assert(Tok.is(tok::kw_while) && "Not a while stmt!");1711  SourceLocation WhileLoc = Tok.getLocation();1712  ConsumeToken();  // eat the 'while'.1713 1714  if (Tok.isNot(tok::l_paren)) {1715    Diag(Tok, diag::err_expected_lparen_after) << "while";1716    SkipUntil(tok::semi);1717    return StmtError();1718  }1719 1720  bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;1721 1722  // C99 6.8.5p5 - In C99, the while statement is a block.  This is not1723  // the case for C90.  Start the loop scope.1724  //1725  // C++ 6.4p3:1726  // A name introduced by a declaration in a condition is in scope from its1727  // point of declaration until the end of the substatements controlled by the1728  // condition.1729  // C++ 3.3.2p4:1730  // Names declared in the for-init-statement, and in the condition of if,1731  // while, for, and switch statements are local to the if, while, for, or1732  // switch statement (including the controlled statement).1733  //1734  unsigned ScopeFlags;1735  if (C99orCXX)1736    ScopeFlags = Scope::BreakScope | Scope::ContinueScope |1737                 Scope::DeclScope  | Scope::ControlScope;1738  else1739    ScopeFlags = Scope::BreakScope | Scope::ContinueScope;1740  ParseScope WhileScope(this, ScopeFlags);1741 1742  // Parse the condition.1743  Sema::ConditionResult Cond;1744  SourceLocation LParen;1745  SourceLocation RParen;1746  if (ParseParenExprOrCondition(nullptr, Cond, WhileLoc,1747                                Sema::ConditionKind::Boolean, LParen, RParen))1748    return StmtError();1749 1750  // OpenACC Restricts a while-loop inside of certain construct/clause1751  // combinations, so diagnose that here in OpenACC mode.1752  SemaOpenACC::LoopInConstructRAII LCR{getActions().OpenACC()};1753  getActions().OpenACC().ActOnWhileStmt(WhileLoc);1754  getCurScope()->setPrecedingLabel(PrecedingLabel);1755 1756  // C99 6.8.5p5 - In C99, the body of the while statement is a scope, even if1757  // there is no compound stmt.  C90 does not have this clause.  We only do this1758  // if the body isn't a compound statement to avoid push/pop in common cases.1759  //1760  // C++ 6.5p2:1761  // The substatement in an iteration-statement implicitly defines a local scope1762  // which is entered and exited each time through the loop.1763  //1764  // See comments in ParseIfStatement for why we create a scope for the1765  // condition and a new scope for substatement in C++.1766  //1767  ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));1768 1769  MisleadingIndentationChecker MIChecker(*this, MSK_while, WhileLoc);1770 1771  // Read the body statement.1772  StmtResult Body(ParseStatement(TrailingElseLoc));1773 1774  if (Body.isUsable())1775    MIChecker.Check();1776  // Pop the body scope if needed.1777  InnerScope.Exit();1778  WhileScope.Exit();1779 1780  if (Cond.isInvalid() || Body.isInvalid())1781    return StmtError();1782 1783  return Actions.ActOnWhileStmt(WhileLoc, LParen, Cond, RParen, Body.get());1784}1785 1786StmtResult Parser::ParseDoStatement(LabelDecl *PrecedingLabel) {1787  assert(Tok.is(tok::kw_do) && "Not a do stmt!");1788  SourceLocation DoLoc = ConsumeToken();  // eat the 'do'.1789 1790  // C99 6.8.5p5 - In C99, the do statement is a block.  This is not1791  // the case for C90.  Start the loop scope.1792  unsigned ScopeFlags;1793  if (getLangOpts().C99)1794    ScopeFlags = Scope::BreakScope | Scope::ContinueScope | Scope::DeclScope;1795  else1796    ScopeFlags = Scope::BreakScope | Scope::ContinueScope;1797 1798  ParseScope DoScope(this, ScopeFlags);1799 1800  // OpenACC Restricts a do-while-loop inside of certain construct/clause1801  // combinations, so diagnose that here in OpenACC mode.1802  SemaOpenACC::LoopInConstructRAII LCR{getActions().OpenACC()};1803  getActions().OpenACC().ActOnDoStmt(DoLoc);1804  getCurScope()->setPrecedingLabel(PrecedingLabel);1805 1806  // C99 6.8.5p5 - In C99, the body of the do statement is a scope, even if1807  // there is no compound stmt.  C90 does not have this clause. We only do this1808  // if the body isn't a compound statement to avoid push/pop in common cases.1809  //1810  // C++ 6.5p2:1811  // The substatement in an iteration-statement implicitly defines a local scope1812  // which is entered and exited each time through the loop.1813  //1814  bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;1815  ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));1816 1817  // Read the body statement.1818  StmtResult Body(ParseStatement());1819 1820  // Pop the body scope if needed.1821  InnerScope.Exit();1822 1823  // Reset this to disallow break/continue out of the condition.1824  getCurScope()->setPrecedingLabel(nullptr);1825 1826  if (Tok.isNot(tok::kw_while)) {1827    if (!Body.isInvalid()) {1828      Diag(Tok, diag::err_expected_while);1829      Diag(DoLoc, diag::note_matching) << "'do'";1830      SkipUntil(tok::semi, StopBeforeMatch);1831    }1832    return StmtError();1833  }1834  SourceLocation WhileLoc = ConsumeToken();1835 1836  if (Tok.isNot(tok::l_paren)) {1837    Diag(Tok, diag::err_expected_lparen_after) << "do/while";1838    SkipUntil(tok::semi, StopBeforeMatch);1839    return StmtError();1840  }1841 1842  // Parse the parenthesized expression.1843  BalancedDelimiterTracker T(*this, tok::l_paren);1844  T.consumeOpen();1845 1846  // A do-while expression is not a condition, so can't have attributes.1847  DiagnoseAndSkipCXX11Attributes();1848 1849  SourceLocation Start = Tok.getLocation();1850  ExprResult Cond = ParseExpression();1851  if (!Cond.isUsable()) {1852    if (!Tok.isOneOf(tok::r_paren, tok::r_square, tok::r_brace))1853      SkipUntil(tok::semi);1854    Cond = Actions.CreateRecoveryExpr(1855        Start, Start == Tok.getLocation() ? Start : PrevTokLocation, {},1856        Actions.getASTContext().BoolTy);1857  }1858  T.consumeClose();1859  DoScope.Exit();1860 1861  if (Cond.isInvalid() || Body.isInvalid())1862    return StmtError();1863 1864  return Actions.ActOnDoStmt(DoLoc, Body.get(), WhileLoc, T.getOpenLocation(),1865                             Cond.get(), T.getCloseLocation());1866}1867 1868bool Parser::isForRangeIdentifier() {1869  assert(Tok.is(tok::identifier));1870 1871  const Token &Next = NextToken();1872  if (Next.is(tok::colon))1873    return true;1874 1875  if (Next.isOneOf(tok::l_square, tok::kw_alignas)) {1876    TentativeParsingAction PA(*this);1877    ConsumeToken();1878    SkipCXX11Attributes();1879    bool Result = Tok.is(tok::colon);1880    PA.Revert();1881    return Result;1882  }1883 1884  return false;1885}1886 1887StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc,1888                                     LabelDecl *PrecedingLabel) {1889  assert(Tok.is(tok::kw_for) && "Not a for stmt!");1890  SourceLocation ForLoc = ConsumeToken();  // eat the 'for'.1891 1892  SourceLocation CoawaitLoc;1893  if (Tok.is(tok::kw_co_await))1894    CoawaitLoc = ConsumeToken();1895 1896  if (Tok.isNot(tok::l_paren)) {1897    Diag(Tok, diag::err_expected_lparen_after) << "for";1898    SkipUntil(tok::semi);1899    return StmtError();1900  }1901 1902  bool C99orCXXorObjC = getLangOpts().C99 || getLangOpts().CPlusPlus ||1903    getLangOpts().ObjC;1904 1905  // C99 6.8.5p5 - In C99, the for statement is a block.  This is not1906  // the case for C90.  Start the loop scope.1907  //1908  // C++ 6.4p3:1909  // A name introduced by a declaration in a condition is in scope from its1910  // point of declaration until the end of the substatements controlled by the1911  // condition.1912  // C++ 3.3.2p4:1913  // Names declared in the for-init-statement, and in the condition of if,1914  // while, for, and switch statements are local to the if, while, for, or1915  // switch statement (including the controlled statement).1916  // C++ 6.5.3p1:1917  // Names declared in the for-init-statement are in the same declarative-region1918  // as those declared in the condition.1919  //1920  unsigned ScopeFlags = 0;1921  if (C99orCXXorObjC)1922    ScopeFlags = Scope::DeclScope | Scope::ControlScope;1923 1924  ParseScope ForScope(this, ScopeFlags);1925 1926  BalancedDelimiterTracker T(*this, tok::l_paren);1927  T.consumeOpen();1928 1929  ExprResult Value;1930 1931  bool ForEach = false;1932  StmtResult FirstPart;1933  Sema::ConditionResult SecondPart;1934  ExprResult Collection;1935  ForRangeInfo ForRangeInfo;1936  FullExprArg ThirdPart(Actions);1937 1938  if (Tok.is(tok::code_completion)) {1939    cutOffParsing();1940    Actions.CodeCompletion().CodeCompleteOrdinaryName(1941        getCurScope(), C99orCXXorObjC ? SemaCodeCompletion::PCC_ForInit1942                                      : SemaCodeCompletion::PCC_Expression);1943    return StmtError();1944  }1945 1946  ParsedAttributes attrs(AttrFactory);1947  MaybeParseCXX11Attributes(attrs);1948 1949  SourceLocation EmptyInitStmtSemiLoc;1950 1951  // Parse the first part of the for specifier.1952  if (Tok.is(tok::semi)) {  // for (;1953    ProhibitAttributes(attrs);1954    // no first part, eat the ';'.1955    SourceLocation SemiLoc = Tok.getLocation();1956    if (!Tok.hasLeadingEmptyMacro() && !SemiLoc.isMacroID())1957      EmptyInitStmtSemiLoc = SemiLoc;1958    ConsumeToken();1959  } else if (getLangOpts().CPlusPlus && Tok.is(tok::identifier) &&1960             isForRangeIdentifier()) {1961    ProhibitAttributes(attrs);1962    IdentifierInfo *Name = Tok.getIdentifierInfo();1963    SourceLocation Loc = ConsumeToken();1964    MaybeParseCXX11Attributes(attrs);1965 1966    ForRangeInfo.ColonLoc = ConsumeToken();1967    if (Tok.is(tok::l_brace))1968      ForRangeInfo.RangeExpr = ParseBraceInitializer();1969    else1970      ForRangeInfo.RangeExpr = ParseExpression();1971 1972    Diag(Loc, diag::err_for_range_identifier)1973      << ((getLangOpts().CPlusPlus11 && !getLangOpts().CPlusPlus17)1974              ? FixItHint::CreateInsertion(Loc, "auto &&")1975              : FixItHint());1976 1977    ForRangeInfo.LoopVar =1978        Actions.ActOnCXXForRangeIdentifier(getCurScope(), Loc, Name, attrs);1979  } else if (isForInitDeclaration()) {  // for (int X = 4;1980    ParenBraceBracketBalancer BalancerRAIIObj(*this);1981 1982    // Parse declaration, which eats the ';'.1983    if (!C99orCXXorObjC) {   // Use of C99-style for loops in C90 mode?1984      Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);1985      Diag(Tok, diag::warn_gcc_variable_decl_in_for_loop);1986    }1987    DeclGroupPtrTy DG;1988    SourceLocation DeclStart = Tok.getLocation(), DeclEnd;1989    if (!getLangOpts().CPlusPlus &&1990        Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {1991      ProhibitAttributes(attrs);1992      Decl *D = ParseStaticAssertDeclaration(DeclEnd);1993      DG = Actions.ConvertDeclToDeclGroup(D);1994      FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());1995    } else if (Tok.is(tok::kw_using)) {1996      DG = ParseAliasDeclarationInInitStatement(DeclaratorContext::ForInit,1997                                                attrs);1998      FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());1999    } else {2000      // In C++0x, "for (T NS:a" might not be a typo for ::2001      bool MightBeForRangeStmt = getLangOpts().CPlusPlus || getLangOpts().ObjC;2002      ColonProtectionRAIIObject ColonProtection(*this, MightBeForRangeStmt);2003      ParsedAttributes DeclSpecAttrs(AttrFactory);2004      DG = ParseSimpleDeclaration(2005          DeclaratorContext::ForInit, DeclEnd, attrs, DeclSpecAttrs, false,2006          MightBeForRangeStmt ? &ForRangeInfo : nullptr);2007      FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());2008      if (ForRangeInfo.ParsedForRangeDecl()) {2009        Diag(ForRangeInfo.ColonLoc, getLangOpts().CPlusPlus112010                                        ? diag::warn_cxx98_compat_for_range2011                                        : diag::ext_for_range);2012        ForRangeInfo.LoopVar = FirstPart;2013        FirstPart = StmtResult();2014      } else if (Tok.is(tok::semi)) { // for (int x = 4;2015        ConsumeToken();2016      } else if ((ForEach = isTokIdentifier_in())) {2017        Actions.ActOnForEachDeclStmt(DG);2018        // ObjC: for (id x in expr)2019        ConsumeToken(); // consume 'in'2020 2021        if (Tok.is(tok::code_completion)) {2022          cutOffParsing();2023          Actions.CodeCompletion().CodeCompleteObjCForCollection(getCurScope(),2024                                                                 DG);2025          return StmtError();2026        }2027        Collection = ParseExpression();2028      } else {2029        Diag(Tok, diag::err_expected_semi_for);2030      }2031    }2032  } else {2033    ProhibitAttributes(attrs);2034    Value = ParseExpression();2035 2036    ForEach = isTokIdentifier_in();2037 2038    // Turn the expression into a stmt.2039    if (!Value.isInvalid()) {2040      if (ForEach)2041        FirstPart = Actions.ActOnForEachLValueExpr(Value.get());2042      else {2043        // We already know this is not an init-statement within a for loop, so2044        // if we are parsing a C++11 range-based for loop, we should treat this2045        // expression statement as being a discarded value expression because2046        // we will err below. This way we do not warn on an unused expression2047        // that was an error in the first place, like with: for (expr : expr);2048        bool IsRangeBasedFor =2049            getLangOpts().CPlusPlus11 && !ForEach && Tok.is(tok::colon);2050        FirstPart = Actions.ActOnExprStmt(Value, !IsRangeBasedFor);2051      }2052    }2053 2054    if (Tok.is(tok::semi)) {2055      ConsumeToken();2056    } else if (ForEach) {2057      ConsumeToken(); // consume 'in'2058 2059      if (Tok.is(tok::code_completion)) {2060        cutOffParsing();2061        Actions.CodeCompletion().CodeCompleteObjCForCollection(getCurScope(),2062                                                               nullptr);2063        return StmtError();2064      }2065      Collection = ParseExpression();2066    } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::colon) && FirstPart.get()) {2067      // User tried to write the reasonable, but ill-formed, for-range-statement2068      //   for (expr : expr) { ... }2069      Diag(Tok, diag::err_for_range_expected_decl)2070        << FirstPart.get()->getSourceRange();2071      SkipUntil(tok::r_paren, StopBeforeMatch);2072      SecondPart = Sema::ConditionError();2073    } else {2074      if (!Value.isInvalid()) {2075        Diag(Tok, diag::err_expected_semi_for);2076      } else {2077        // Skip until semicolon or rparen, don't consume it.2078        SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch);2079        if (Tok.is(tok::semi))2080          ConsumeToken();2081      }2082    }2083  }2084 2085  // Parse the second part of the for specifier.2086  if (!ForEach && !ForRangeInfo.ParsedForRangeDecl() &&2087      !SecondPart.isInvalid()) {2088    // Parse the second part of the for specifier.2089    if (Tok.is(tok::semi)) {  // for (...;;2090      // no second part.2091    } else if (Tok.is(tok::r_paren)) {2092      // missing both semicolons.2093    } else {2094      if (getLangOpts().CPlusPlus) {2095        // C++2a: We've parsed an init-statement; we might have a2096        // for-range-declaration next.2097        bool MightBeForRangeStmt = !ForRangeInfo.ParsedForRangeDecl();2098        ColonProtectionRAIIObject ColonProtection(*this, MightBeForRangeStmt);2099        SourceLocation SecondPartStart = Tok.getLocation();2100        Sema::ConditionKind CK = Sema::ConditionKind::Boolean;2101        SecondPart = ParseCXXCondition(2102            /*InitStmt=*/nullptr, ForLoc, CK,2103            // FIXME: recovery if we don't see another semi!2104            /*MissingOK=*/true, MightBeForRangeStmt ? &ForRangeInfo : nullptr,2105            /*EnterForConditionScope=*/true);2106 2107        if (ForRangeInfo.ParsedForRangeDecl()) {2108          Diag(FirstPart.get() ? FirstPart.get()->getBeginLoc()2109                               : ForRangeInfo.ColonLoc,2110               getLangOpts().CPlusPlus202111                   ? diag::warn_cxx17_compat_for_range_init_stmt2112                   : diag::ext_for_range_init_stmt)2113              << (FirstPart.get() ? FirstPart.get()->getSourceRange()2114                                  : SourceRange());2115          if (EmptyInitStmtSemiLoc.isValid()) {2116            Diag(EmptyInitStmtSemiLoc, diag::warn_empty_init_statement)2117                << /*for-loop*/ 22118                << FixItHint::CreateRemoval(EmptyInitStmtSemiLoc);2119          }2120        }2121 2122        if (SecondPart.isInvalid()) {2123          ExprResult CondExpr = Actions.CreateRecoveryExpr(2124              SecondPartStart,2125              Tok.getLocation() == SecondPartStart ? SecondPartStart2126                                                   : PrevTokLocation,2127              {}, Actions.PreferredConditionType(CK));2128          if (!CondExpr.isInvalid())2129            SecondPart = Actions.ActOnCondition(getCurScope(), ForLoc,2130                                                CondExpr.get(), CK,2131                                                /*MissingOK=*/false);2132        }2133 2134      } else {2135        // We permit 'continue' and 'break' in the condition of a for loop.2136        getCurScope()->AddFlags(Scope::BreakScope | Scope::ContinueScope);2137 2138        ExprResult SecondExpr = ParseExpression();2139        if (SecondExpr.isInvalid())2140          SecondPart = Sema::ConditionError();2141        else2142          SecondPart = Actions.ActOnCondition(2143              getCurScope(), ForLoc, SecondExpr.get(),2144              Sema::ConditionKind::Boolean, /*MissingOK=*/true);2145      }2146    }2147  }2148 2149  // Enter a break / continue scope, if we didn't already enter one while2150  // parsing the second part.2151  if (!getCurScope()->isContinueScope())2152    getCurScope()->AddFlags(Scope::BreakScope | Scope::ContinueScope);2153 2154  // Parse the third part of the for statement.2155  if (!ForEach && !ForRangeInfo.ParsedForRangeDecl()) {2156    if (Tok.isNot(tok::semi)) {2157      if (!SecondPart.isInvalid())2158        Diag(Tok, diag::err_expected_semi_for);2159      SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch);2160    }2161 2162    if (Tok.is(tok::semi)) {2163      ConsumeToken();2164    }2165 2166    if (Tok.isNot(tok::r_paren)) {   // for (...;...;)2167      ExprResult Third = ParseExpression();2168      // FIXME: The C++11 standard doesn't actually say that this is a2169      // discarded-value expression, but it clearly should be.2170      ThirdPart = Actions.MakeFullDiscardedValueExpr(Third.get());2171    }2172  }2173  // Match the ')'.2174  T.consumeClose();2175 2176  // C++ Coroutines [stmt.iter]:2177  //   'co_await' can only be used for a range-based for statement.2178  if (CoawaitLoc.isValid() && !ForRangeInfo.ParsedForRangeDecl()) {2179    Diag(CoawaitLoc, diag::err_for_co_await_not_range_for);2180    CoawaitLoc = SourceLocation();2181  }2182 2183  if (CoawaitLoc.isValid() && getLangOpts().CPlusPlus20)2184    Diag(CoawaitLoc, diag::warn_deprecated_for_co_await);2185 2186  // We need to perform most of the semantic analysis for a C++0x for-range2187  // statememt before parsing the body, in order to be able to deduce the type2188  // of an auto-typed loop variable.2189  StmtResult ForRangeStmt;2190  StmtResult ForEachStmt;2191 2192  if (ForRangeInfo.ParsedForRangeDecl()) {2193    ForRangeStmt = Actions.ActOnCXXForRangeStmt(2194        getCurScope(), ForLoc, CoawaitLoc, FirstPart.get(),2195        ForRangeInfo.LoopVar.get(), ForRangeInfo.ColonLoc,2196        ForRangeInfo.RangeExpr.get(), T.getCloseLocation(), Sema::BFRK_Build,2197        ForRangeInfo.LifetimeExtendTemps);2198  } else if (ForEach) {2199    // Similarly, we need to do the semantic analysis for a for-range2200    // statement immediately in order to close over temporaries correctly.2201    ForEachStmt = Actions.ObjC().ActOnObjCForCollectionStmt(2202        ForLoc, FirstPart.get(), Collection.get(), T.getCloseLocation());2203  } else {2204    // In OpenMP loop region loop control variable must be captured and be2205    // private. Perform analysis of first part (if any).2206    if (getLangOpts().OpenMP && FirstPart.isUsable()) {2207      Actions.OpenMP().ActOnOpenMPLoopInitialization(ForLoc, FirstPart.get());2208    }2209  }2210 2211  // OpenACC Restricts a for-loop inside of certain construct/clause2212  // combinations, so diagnose that here in OpenACC mode.2213  SemaOpenACC::LoopInConstructRAII LCR{getActions().OpenACC()};2214  if (ForRangeInfo.ParsedForRangeDecl())2215    getActions().OpenACC().ActOnRangeForStmtBegin(ForLoc, ForRangeStmt.get());2216  else2217    getActions().OpenACC().ActOnForStmtBegin(2218        ForLoc, FirstPart.get(), SecondPart.get().second, ThirdPart.get());2219 2220  // Set this only right before parsing the body to disallow break/continue in2221  // the other parts.2222  getCurScope()->setPrecedingLabel(PrecedingLabel);2223 2224  // C99 6.8.5p5 - In C99, the body of the for statement is a scope, even if2225  // there is no compound stmt.  C90 does not have this clause.  We only do this2226  // if the body isn't a compound statement to avoid push/pop in common cases.2227  //2228  // C++ 6.5p2:2229  // The substatement in an iteration-statement implicitly defines a local scope2230  // which is entered and exited each time through the loop.2231  //2232  // See comments in ParseIfStatement for why we create a scope for2233  // for-init-statement/condition and a new scope for substatement in C++.2234  //2235  ParseScope InnerScope(this, Scope::DeclScope, C99orCXXorObjC,2236                        Tok.is(tok::l_brace));2237 2238  // The body of the for loop has the same local mangling number as the2239  // for-init-statement.2240  // It will only be incremented if the body contains other things that would2241  // normally increment the mangling number (like a compound statement).2242  if (C99orCXXorObjC)2243    getCurScope()->decrementMSManglingNumber();2244 2245  MisleadingIndentationChecker MIChecker(*this, MSK_for, ForLoc);2246 2247  // Read the body statement.2248  StmtResult Body(ParseStatement(TrailingElseLoc));2249 2250  if (Body.isUsable())2251    MIChecker.Check();2252 2253  // Pop the body scope if needed.2254  InnerScope.Exit();2255 2256  getActions().OpenACC().ActOnForStmtEnd(ForLoc, Body);2257 2258  // Leave the for-scope.2259  ForScope.Exit();2260 2261  if (Body.isInvalid())2262    return StmtError();2263 2264  if (ForEach)2265    return Actions.ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),2266                                                      Body.get());2267 2268  if (ForRangeInfo.ParsedForRangeDecl())2269    return Actions.FinishCXXForRangeStmt(ForRangeStmt.get(), Body.get());2270 2271  return Actions.ActOnForStmt(ForLoc, T.getOpenLocation(), FirstPart.get(),2272                              SecondPart, ThirdPart, T.getCloseLocation(),2273                              Body.get());2274}2275 2276StmtResult Parser::ParseGotoStatement() {2277  assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");2278  SourceLocation GotoLoc = ConsumeToken();  // eat the 'goto'.2279 2280  StmtResult Res;2281  if (Tok.is(tok::identifier)) {2282    LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(),2283                                                Tok.getLocation());2284    Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(), LD);2285    ConsumeToken();2286  } else if (Tok.is(tok::star)) {2287    // GNU indirect goto extension.2288    Diag(Tok, diag::ext_gnu_indirect_goto);2289    SourceLocation StarLoc = ConsumeToken();2290    ExprResult R(ParseExpression());2291    if (R.isInvalid()) {  // Skip to the semicolon, but don't consume it.2292      SkipUntil(tok::semi, StopBeforeMatch);2293      return StmtError();2294    }2295    Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.get());2296  } else {2297    Diag(Tok, diag::err_expected) << tok::identifier;2298    return StmtError();2299  }2300 2301  return Res;2302}2303 2304StmtResult Parser::ParseBreakOrContinueStatement(bool IsContinue) {2305  SourceLocation KwLoc = ConsumeToken(); // Eat the keyword.2306  SourceLocation LabelLoc;2307  LabelDecl *Target = nullptr;2308  if (Tok.is(tok::identifier)) {2309    Target =2310        Actions.LookupExistingLabel(Tok.getIdentifierInfo(), Tok.getLocation());2311    LabelLoc = ConsumeToken();2312    if (!getLangOpts().NamedLoops)2313      // TODO: Make this a compatibility/extension warning instead once the2314      // syntax of this feature is finalised.2315      Diag(LabelLoc, diag::err_c2y_labeled_break_continue) << IsContinue;2316    if (!Target) {2317      Diag(LabelLoc, diag::err_break_continue_label_not_found) << IsContinue;2318      return StmtError();2319    }2320  }2321 2322  if (IsContinue)2323    return Actions.ActOnContinueStmt(KwLoc, getCurScope(), Target, LabelLoc);2324  return Actions.ActOnBreakStmt(KwLoc, getCurScope(), Target, LabelLoc);2325}2326 2327StmtResult Parser::ParseContinueStatement() {2328  return ParseBreakOrContinueStatement(/*IsContinue=*/true);2329}2330 2331StmtResult Parser::ParseBreakStatement() {2332  return ParseBreakOrContinueStatement(/*IsContinue=*/false);2333}2334 2335StmtResult Parser::ParseReturnStatement() {2336  assert((Tok.is(tok::kw_return) || Tok.is(tok::kw_co_return)) &&2337         "Not a return stmt!");2338  bool IsCoreturn = Tok.is(tok::kw_co_return);2339  SourceLocation ReturnLoc = ConsumeToken();  // eat the 'return'.2340 2341  ExprResult R;2342  if (Tok.isNot(tok::semi)) {2343    if (!IsCoreturn)2344      PreferredType.enterReturn(Actions, Tok.getLocation());2345    // FIXME: Code completion for co_return.2346    if (Tok.is(tok::code_completion) && !IsCoreturn) {2347      cutOffParsing();2348      Actions.CodeCompletion().CodeCompleteExpression(2349          getCurScope(), PreferredType.get(Tok.getLocation()));2350      return StmtError();2351    }2352 2353    if (Tok.is(tok::l_brace) && getLangOpts().CPlusPlus) {2354      R = ParseInitializer();2355      if (R.isUsable())2356        Diag(R.get()->getBeginLoc(),2357             getLangOpts().CPlusPlus112358                 ? diag::warn_cxx98_compat_generalized_initializer_lists2359                 : diag::ext_generalized_initializer_lists)2360            << R.get()->getSourceRange();2361    } else2362      R = ParseExpression();2363    if (R.isInvalid()) {2364      SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);2365      return StmtError();2366    }2367  }2368  if (IsCoreturn)2369    return Actions.ActOnCoreturnStmt(getCurScope(), ReturnLoc, R.get());2370  return Actions.ActOnReturnStmt(ReturnLoc, R.get(), getCurScope());2371}2372 2373StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,2374                                       ParsedStmtContext StmtCtx,2375                                       SourceLocation *TrailingElseLoc,2376                                       ParsedAttributes &Attrs,2377                                       LabelDecl *PrecedingLabel) {2378  // Create temporary attribute list.2379  ParsedAttributes TempAttrs(AttrFactory);2380 2381  SourceLocation StartLoc = Tok.getLocation();2382 2383  // Get loop hints and consume annotated token.2384  while (Tok.is(tok::annot_pragma_loop_hint)) {2385    LoopHint Hint;2386    if (!HandlePragmaLoopHint(Hint))2387      continue;2388 2389    ArgsUnion ArgHints[] = {Hint.PragmaNameLoc, Hint.OptionLoc, Hint.StateLoc,2390                            ArgsUnion(Hint.ValueExpr)};2391    TempAttrs.addNew(Hint.PragmaNameLoc->getIdentifierInfo(), Hint.Range,2392                     AttributeScopeInfo(), ArgHints, /*numArgs=*/4,2393                     ParsedAttr::Form::Pragma());2394  }2395 2396  // Get the next statement.2397  MaybeParseCXX11Attributes(Attrs);2398 2399  ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);2400  StmtResult S = ParseStatementOrDeclarationAfterAttributes(2401      Stmts, StmtCtx, TrailingElseLoc, Attrs, EmptyDeclSpecAttrs,2402      PrecedingLabel);2403 2404  Attrs.takeAllPrependingFrom(TempAttrs);2405 2406  // Start of attribute range may already be set for some invalid input.2407  // See PR46336.2408  if (Attrs.Range.getBegin().isInvalid())2409    Attrs.Range.setBegin(StartLoc);2410 2411  return S;2412}2413 2414Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) {2415  assert(Tok.is(tok::l_brace));2416  SourceLocation LBraceLoc = Tok.getLocation();2417 2418  PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, LBraceLoc,2419                                      "parsing function body");2420 2421  // Save and reset current vtordisp stack if we have entered a C++ method body.2422  bool IsCXXMethod =2423      getLangOpts().CPlusPlus && Decl && isa<CXXMethodDecl>(Decl);2424  Sema::PragmaStackSentinelRAII2425    PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod);2426 2427  // Do not enter a scope for the brace, as the arguments are in the same scope2428  // (the function body) as the body itself.  Instead, just read the statement2429  // list and put it into a CompoundStmt for safe keeping.2430  StmtResult FnBody(ParseCompoundStatementBody());2431 2432  // If the function body could not be parsed, make a bogus compoundstmt.2433  if (FnBody.isInvalid()) {2434    Sema::CompoundScopeRAII CompoundScope(Actions);2435    FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, {}, false);2436  }2437 2438  BodyScope.Exit();2439  return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());2440}2441 2442Decl *Parser::ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope) {2443  assert(Tok.is(tok::kw_try) && "Expected 'try'");2444  SourceLocation TryLoc = ConsumeToken();2445 2446  PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, TryLoc,2447                                      "parsing function try block");2448 2449  // Constructor initializer list?2450  if (Tok.is(tok::colon))2451    ParseConstructorInitializer(Decl);2452  else2453    Actions.ActOnDefaultCtorInitializers(Decl);2454 2455  // Save and reset current vtordisp stack if we have entered a C++ method body.2456  bool IsCXXMethod =2457      getLangOpts().CPlusPlus && Decl && isa<CXXMethodDecl>(Decl);2458  Sema::PragmaStackSentinelRAII2459    PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod);2460 2461  SourceLocation LBraceLoc = Tok.getLocation();2462  StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc, /*FnTry*/true));2463  // If we failed to parse the try-catch, we just give the function an empty2464  // compound statement as the body.2465  if (FnBody.isInvalid()) {2466    Sema::CompoundScopeRAII CompoundScope(Actions);2467    FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, {}, false);2468  }2469 2470  BodyScope.Exit();2471  return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());2472}2473 2474bool Parser::trySkippingFunctionBody() {2475  assert(SkipFunctionBodies &&2476         "Should only be called when SkipFunctionBodies is enabled");2477  if (!PP.isCodeCompletionEnabled()) {2478    SkipFunctionBody();2479    return true;2480  }2481 2482  // We're in code-completion mode. Skip parsing for all function bodies unless2483  // the body contains the code-completion point.2484  TentativeParsingAction PA(*this);2485  bool IsTryCatch = Tok.is(tok::kw_try);2486  CachedTokens Toks;2487  bool ErrorInPrologue = ConsumeAndStoreFunctionPrologue(Toks);2488  if (llvm::any_of(Toks, [](const Token &Tok) {2489        return Tok.is(tok::code_completion);2490      })) {2491    PA.Revert();2492    return false;2493  }2494  if (ErrorInPrologue) {2495    PA.Commit();2496    SkipMalformedDecl();2497    return true;2498  }2499  if (!SkipUntil(tok::r_brace, StopAtCodeCompletion)) {2500    PA.Revert();2501    return false;2502  }2503  while (IsTryCatch && Tok.is(tok::kw_catch)) {2504    if (!SkipUntil(tok::l_brace, StopAtCodeCompletion) ||2505        !SkipUntil(tok::r_brace, StopAtCodeCompletion)) {2506      PA.Revert();2507      return false;2508    }2509  }2510  PA.Commit();2511  return true;2512}2513 2514StmtResult Parser::ParseCXXTryBlock() {2515  assert(Tok.is(tok::kw_try) && "Expected 'try'");2516 2517  SourceLocation TryLoc = ConsumeToken();2518  return ParseCXXTryBlockCommon(TryLoc);2519}2520 2521StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry) {2522  if (Tok.isNot(tok::l_brace))2523    return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);2524 2525  StmtResult TryBlock(ParseCompoundStatement(2526      /*isStmtExpr=*/false,2527      Scope::DeclScope | Scope::TryScope | Scope::CompoundStmtScope |2528          (FnTry ? Scope::FnTryCatchScope : Scope::NoScope)));2529  if (TryBlock.isInvalid())2530    return TryBlock;2531 2532  // Borland allows SEH-handlers with 'try'2533 2534  if ((Tok.is(tok::identifier) &&2535       Tok.getIdentifierInfo() == getSEHExceptKeyword()) ||2536      Tok.is(tok::kw___finally)) {2537    // TODO: Factor into common return ParseSEHHandlerCommon(...)2538    StmtResult Handler;2539    if(Tok.getIdentifierInfo() == getSEHExceptKeyword()) {2540      SourceLocation Loc = ConsumeToken();2541      Handler = ParseSEHExceptBlock(Loc);2542    }2543    else {2544      SourceLocation Loc = ConsumeToken();2545      Handler = ParseSEHFinallyBlock(Loc);2546    }2547    if(Handler.isInvalid())2548      return Handler;2549 2550    return Actions.ActOnSEHTryBlock(true /* IsCXXTry */,2551                                    TryLoc,2552                                    TryBlock.get(),2553                                    Handler.get());2554  }2555  else {2556    StmtVector Handlers;2557 2558    // C++11 attributes can't appear here, despite this context seeming2559    // statement-like.2560    DiagnoseAndSkipCXX11Attributes();2561 2562    if (Tok.isNot(tok::kw_catch))2563      return StmtError(Diag(Tok, diag::err_expected_catch));2564    while (Tok.is(tok::kw_catch)) {2565      StmtResult Handler(ParseCXXCatchBlock(FnTry));2566      if (!Handler.isInvalid())2567        Handlers.push_back(Handler.get());2568    }2569    // Don't bother creating the full statement if we don't have any usable2570    // handlers.2571    if (Handlers.empty())2572      return StmtError();2573 2574    return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.get(), Handlers);2575  }2576}2577 2578StmtResult Parser::ParseCXXCatchBlock(bool FnCatch) {2579  assert(Tok.is(tok::kw_catch) && "Expected 'catch'");2580 2581  SourceLocation CatchLoc = ConsumeToken();2582 2583  BalancedDelimiterTracker T(*this, tok::l_paren);2584  if (T.expectAndConsume())2585    return StmtError();2586 2587  // C++ 3.3.2p3:2588  // The name in a catch exception-declaration is local to the handler and2589  // shall not be redeclared in the outermost block of the handler.2590  ParseScope CatchScope(2591      this, Scope::DeclScope | Scope::ControlScope | Scope::CatchScope |2592                (FnCatch ? Scope::FnTryCatchScope : Scope::NoScope));2593 2594  // exception-declaration is equivalent to '...' or a parameter-declaration2595  // without default arguments.2596  Decl *ExceptionDecl = nullptr;2597  if (Tok.isNot(tok::ellipsis)) {2598    ParsedAttributes Attributes(AttrFactory);2599    MaybeParseCXX11Attributes(Attributes);2600 2601    DeclSpec DS(AttrFactory);2602 2603    if (ParseCXXTypeSpecifierSeq(DS))2604      return StmtError();2605 2606    Declarator ExDecl(DS, Attributes, DeclaratorContext::CXXCatch);2607    ParseDeclarator(ExDecl);2608    ExceptionDecl = Actions.ActOnExceptionDeclarator(getCurScope(), ExDecl);2609  } else2610    ConsumeToken();2611 2612  T.consumeClose();2613  if (T.getCloseLocation().isInvalid())2614    return StmtError();2615 2616  if (Tok.isNot(tok::l_brace))2617    return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);2618 2619  // FIXME: Possible draft standard bug: attribute-specifier should be allowed?2620  StmtResult Block(ParseCompoundStatement());2621  if (Block.isInvalid())2622    return Block;2623 2624  return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl, Block.get());2625}2626 2627void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {2628  IfExistsCondition Result;2629  if (ParseMicrosoftIfExistsCondition(Result))2630    return;2631 2632  // Handle dependent statements by parsing the braces as a compound statement.2633  // This is not the same behavior as Visual C++, which don't treat this as a2634  // compound statement, but for Clang's type checking we can't have anything2635  // inside these braces escaping to the surrounding code.2636  if (Result.Behavior == IfExistsBehavior::Dependent) {2637    if (!Tok.is(tok::l_brace)) {2638      Diag(Tok, diag::err_expected) << tok::l_brace;2639      return;2640    }2641 2642    StmtResult Compound = ParseCompoundStatement();2643    if (Compound.isInvalid())2644      return;2645 2646    StmtResult DepResult = Actions.ActOnMSDependentExistsStmt(Result.KeywordLoc,2647                                                              Result.IsIfExists,2648                                                              Result.SS,2649                                                              Result.Name,2650                                                              Compound.get());2651    if (DepResult.isUsable())2652      Stmts.push_back(DepResult.get());2653    return;2654  }2655 2656  BalancedDelimiterTracker Braces(*this, tok::l_brace);2657  if (Braces.consumeOpen()) {2658    Diag(Tok, diag::err_expected) << tok::l_brace;2659    return;2660  }2661 2662  switch (Result.Behavior) {2663  case IfExistsBehavior::Parse:2664    // Parse the statements below.2665    break;2666 2667  case IfExistsBehavior::Dependent:2668    llvm_unreachable("Dependent case handled above");2669 2670  case IfExistsBehavior::Skip:2671    Braces.skipToEnd();2672    return;2673  }2674 2675  // Condition is true, parse the statements.2676  while (Tok.isNot(tok::r_brace)) {2677    StmtResult R =2678        ParseStatementOrDeclaration(Stmts, ParsedStmtContext::Compound);2679    if (R.isUsable())2680      Stmts.push_back(R.get());2681  }2682  Braces.consumeClose();2683}2684