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