15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- ParseStmt.cpp - Statement and Block Parser -----------------------===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file implements the Statement and Block portions of the Parser
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// interface.
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Parse/Parser.h"
16d167ca0d26e43292b8b9e8d5300d92784ae0e27dChris Lattner#include "RAIIObjectsForParser.h"
17aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall#include "clang/AST/ASTContext.h"
18ef8225444452a1486bd721f3285301fe84643b00Stephen Hines#include "clang/Basic/Attributes.h"
1955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/Diagnostic.h"
2055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/PrettyStackTrace.h"
2119510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h"
22ef8225444452a1486bd721f3285301fe84643b00Stephen Hines#include "clang/Sema/LoopHint.h"
23f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall#include "clang/Sema/PrettyDeclStackTrace.h"
2419510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/Scope.h"
250576681bac125be07f77f66b02a3dba2c3a24557Richard Smith#include "clang/Sema/TypoCorrection.h"
26651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/ADT/SmallString.h"
275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang;
285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// C99 6.8: Statements and Blocks.
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
33961d0573487933199cb287ce8c472121812b3c78Richard Smith/// \brief Parse a standalone statement (for instance, as the body of an 'if',
34961d0573487933199cb287ce8c472121812b3c78Richard Smith/// 'while', or 'for').
35961d0573487933199cb287ce8c472121812b3c78Richard SmithStmtResult Parser::ParseStatement(SourceLocation *TrailingElseLoc) {
36961d0573487933199cb287ce8c472121812b3c78Richard Smith  StmtResult Res;
37961d0573487933199cb287ce8c472121812b3c78Richard Smith
38961d0573487933199cb287ce8c472121812b3c78Richard Smith  // We may get back a null statement if we found a #pragma. Keep going until
39961d0573487933199cb287ce8c472121812b3c78Richard Smith  // we get an actual statement.
40961d0573487933199cb287ce8c472121812b3c78Richard Smith  do {
41961d0573487933199cb287ce8c472121812b3c78Richard Smith    StmtVector Stmts;
42961d0573487933199cb287ce8c472121812b3c78Richard Smith    Res = ParseStatementOrDeclaration(Stmts, true, TrailingElseLoc);
43961d0573487933199cb287ce8c472121812b3c78Richard Smith  } while (!Res.isInvalid() && !Res.get());
44961d0573487933199cb287ce8c472121812b3c78Richard Smith
45961d0573487933199cb287ce8c472121812b3c78Richard Smith  return Res;
46961d0573487933199cb287ce8c472121812b3c78Richard Smith}
47961d0573487933199cb287ce8c472121812b3c78Richard Smith
485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseStatementOrDeclaration - Read 'statement' or 'declaration'.
495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       StatementOrDeclaration:
505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         statement
515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         declaration
525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       statement:
545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         labeled-statement
555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         compound-statement
565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         expression-statement
575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         selection-statement
585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         iteration-statement
595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         jump-statement
60dcdd55fb4d28de8c314d6c6c1a38aa6aba76d431Argyrios Kyrtzidis/// [C++]   declaration-statement
61a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl/// [C++]   try-block
6228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// [MS]    seh-try-block
63b384d329e0b727d4f2effa28fbb9aba2ac420e7bFariborz Jahanian/// [OBC]   objc-throw-statement
64b384d329e0b727d4f2effa28fbb9aba2ac420e7bFariborz Jahanian/// [OBC]   objc-try-catch-statement
65c385c90c68dfa376650e2facfbb444b2ec9bd110Fariborz Jahanian/// [OBC]   objc-synchronized-statement
665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU]   asm-statement
675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [OMP]   openmp-construct             [TODO]
685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       labeled-statement:
705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         identifier ':' statement
715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'case' constant-expression ':' statement
725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'default' ':' statement
735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       selection-statement:
755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         if-statement
765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         switch-statement
775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       iteration-statement:
795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         while-statement
805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         do-statement
815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         for-statement
825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       expression-statement:
845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         expression[opt] ';'
855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       jump-statement:
875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'goto' identifier ';'
885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'continue' ';'
895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'break' ';'
905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'return' expression[opt] ';'
915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU]   'goto' '*' expression ';'
925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
93b384d329e0b727d4f2effa28fbb9aba2ac420e7bFariborz Jahanian/// [OBC] objc-throw-statement:
94b384d329e0b727d4f2effa28fbb9aba2ac420e7bFariborz Jahanian/// [OBC]   '@' 'throw' expression ';'
951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [OBC]   '@' 'throw' ';'
961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
9760d7b3a319d84d688752be3870615ac0f111fb16John McCallStmtResult
985cb94a78202ccb1007df0be86884297761f4a53aNico WeberParser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement,
995cb94a78202ccb1007df0be86884297761f4a53aNico Weber                                    SourceLocation *TrailingElseLoc) {
100a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
10136d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis  ParenBraceBracketBalancer BalancerRAIIObj(*this);
1020e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
103534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  ParsedAttributesWithRange Attrs(AttrFactory);
1046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  MaybeParseCXX11Attributes(Attrs, nullptr, /*MightBeObjCMessageSend*/ true);
105534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith
106534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  StmtResult Res = ParseStatementOrDeclarationAfterAttributes(Stmts,
107534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith                                 OnlyStatement, TrailingElseLoc, Attrs);
108534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith
109534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  assert((Attrs.empty() || Res.isInvalid() || Res.isUsable()) &&
110534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith         "attributes on empty statement");
111534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith
112534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  if (Attrs.empty() || Res.isInvalid())
113534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return Res;
114534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith
115534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  return Actions.ProcessStmtAttributes(Res.get(), Attrs.getList(), Attrs.Range);
116534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith}
117534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith
1186243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrainnamespace {
1196243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrainclass StatementFilterCCC : public CorrectionCandidateCallback {
1206243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrainpublic:
1216243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrain  StatementFilterCCC(Token nextTok) : NextToken(nextTok) {
1226243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrain    WantTypeSpecifiers = nextTok.is(tok::l_paren) || nextTok.is(tok::less) ||
1236243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrain                         nextTok.is(tok::identifier) || nextTok.is(tok::star) ||
1246243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrain                         nextTok.is(tok::amp) || nextTok.is(tok::l_square);
1256243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrain    WantExpressionKeywords = nextTok.is(tok::l_paren) ||
1266243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrain                             nextTok.is(tok::identifier) ||
1276243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrain                             nextTok.is(tok::arrow) || nextTok.is(tok::period);
1286243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrain    WantRemainingKeywords = nextTok.is(tok::l_paren) || nextTok.is(tok::semi) ||
1296243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrain                            nextTok.is(tok::identifier) ||
1306243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrain                            nextTok.is(tok::l_brace);
1316243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrain    WantCXXNamedCasts = false;
1326243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrain  }
1336243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrain
134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool ValidateCandidate(const TypoCorrection &candidate) override {
1356243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrain    if (FieldDecl *FD = candidate.getCorrectionDeclAs<FieldDecl>())
136a89ee579e86912302251dd9b06a472b4531f864fKaelyn Uhrain      return !candidate.getCorrectionSpecifier() || isa<ObjCIvarDecl>(FD);
1370f90ee0939ae785f412da07e94afdf8053681b39Kaelyn Uhrain    if (NextToken.is(tok::equal))
1380f90ee0939ae785f412da07e94afdf8053681b39Kaelyn Uhrain      return candidate.getCorrectionDeclAs<VarDecl>();
1392ceb67a5345ef711468a32dbf17769828b5fbaddKaelyn Uhrain    if (NextToken.is(tok::period) &&
1402ceb67a5345ef711468a32dbf17769828b5fbaddKaelyn Uhrain        candidate.getCorrectionDeclAs<NamespaceDecl>())
1412ceb67a5345ef711468a32dbf17769828b5fbaddKaelyn Uhrain      return false;
1426243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrain    return CorrectionCandidateCallback::ValidateCandidate(candidate);
1436243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrain  }
1446243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrain
1456243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrainprivate:
1466243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrain  Token NextToken;
1476243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrain};
1486243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrain}
1496243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrain
150534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult
151534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithParser::ParseStatementOrDeclarationAfterAttributes(StmtVector &Stmts,
152534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith          bool OnlyStatement, SourceLocation *TrailingElseLoc,
153534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith          ParsedAttributesWithRange &Attrs) {
1546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  const char *SemiError = nullptr;
155534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  StmtResult Res;
156bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Cases in this switch statement should fall through if the parser expects
1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // the token to end in a semicolon (in which case SemiError should be set),
1595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // or they directly 'return;' if not.
160312eadb832cab4497a069409954500d8192b8f0dDouglas GregorRetry:
161397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian  tok::TokenKind Kind  = Tok.getKind();
162397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian  SourceLocation AtLoc;
163397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian  switch (Kind) {
164397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian  case tok::at: // May be a @try or @throw statement
165397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian    {
166534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith      ProhibitAttributes(Attrs); // TODO: is it correct?
167397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian      AtLoc = ConsumeToken();  // consume @
16843bc2a0973ffe404fabba6f8280cd6bad2c69fcbSebastian Redl      return ParseObjCAtStatement(AtLoc);
169397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian    }
170397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian
171791215b7a24666912c0b71175d2ca5ba082f666eDouglas Gregor  case tok::code_completion:
172f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Statement);
1737d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
1747d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return StmtError();
175a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
176312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor  case tok::identifier: {
177312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    Token Next = NextToken();
178312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    if (Next.is(tok::colon)) { // C99 6.8.1: labeled-statement
179b9f930d7bdb911be8420e044876221bf8a39f45fArgyrios Kyrtzidis      // identifier ':' statement
180534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith      return ParseLabeledStatement(Attrs);
181b9f930d7bdb911be8420e044876221bf8a39f45fArgyrios Kyrtzidis    }
182a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
1830576681bac125be07f77f66b02a3dba2c3a24557Richard Smith    // Look up the identifier, and typo-correct it to a keyword if it's not
1840576681bac125be07f77f66b02a3dba2c3a24557Richard Smith    // found.
1853b887354b1b667c97d070ddc67b5354353c4c07bDouglas Gregor    if (Next.isNot(tok::coloncolon)) {
1860576681bac125be07f77f66b02a3dba2c3a24557Richard Smith      // Try to limit which sets of keywords should be included in typo
1870576681bac125be07f77f66b02a3dba2c3a24557Richard Smith      // correction based on what the next token is.
1886243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrain      StatementFilterCCC Validator(Next);
1896243f627680fbf7c5bf2f339967d806f47153746Kaelyn Uhrain      if (TryAnnotateName(/*IsAddressOfOperand*/false, &Validator)
1900576681bac125be07f77f66b02a3dba2c3a24557Richard Smith            == ANK_Error) {
191312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor        // Handle errors here by skipping up to the next semicolon or '}', and
192312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor        // eat the semicolon if that's what stopped us.
1938fe2475a4b4c00475709c13d43eb9a57cce87cbcAlexey Bataev        SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
194312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor        if (Tok.is(tok::semi))
195312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor          ConsumeToken();
196312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor        return StmtError();
197312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor      }
198a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
1990576681bac125be07f77f66b02a3dba2c3a24557Richard Smith      // If the identifier was typo-corrected, try again.
2000576681bac125be07f77f66b02a3dba2c3a24557Richard Smith      if (Tok.isNot(tok::identifier))
2010576681bac125be07f77f66b02a3dba2c3a24557Richard Smith        goto Retry;
202312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    }
203a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
204312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    // Fall through
205312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor  }
206a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
207f919bfe282b8a94d956290dc9812b456fa2b447eChris Lattner  default: {
2084e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if ((getLangOpts().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) {
20997144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner      SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
2108113ecfa4e41e2c888b1794389dfe3bce6386493Ted Kremenek      DeclGroupPtrTy Decl = ParseDeclaration(Stmts, Declarator::BlockContext,
211534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith                                             DeclEnd, Attrs);
21297144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner      return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
213f919bfe282b8a94d956290dc9812b456fa2b447eChris Lattner    }
214f919bfe282b8a94d956290dc9812b456fa2b447eChris Lattner
215f919bfe282b8a94d956290dc9812b456fa2b447eChris Lattner    if (Tok.is(tok::r_brace)) {
2165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Diag(Tok, diag::err_expected_statement);
21761364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl      return StmtError();
2185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
2191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
220534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return ParseExprStatement();
221f919bfe282b8a94d956290dc9812b456fa2b447eChris Lattner  }
22261364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
2235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::kw_case:                // C99 6.8.1: labeled-statement
224534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return ParseCaseStatement();
2255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::kw_default:             // C99 6.8.1: labeled-statement
226534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return ParseDefaultStatement();
22761364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
2285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::l_brace:                // C99 6.8.2: compound-statement
229534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return ParseCompoundStatement();
23044aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis  case tok::semi: {                 // C99 6.8.3p3: expression[opt] ';'
231e2ca828119b8bff4a5c25c6db8ee4fec558451e7Argyrios Kyrtzidis    bool HasLeadingEmptyMacro = Tok.hasLeadingEmptyMacro();
232e2ca828119b8bff4a5c25c6db8ee4fec558451e7Argyrios Kyrtzidis    return Actions.ActOnNullStmt(ConsumeToken(), HasLeadingEmptyMacro);
23344aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis  }
23461364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
2355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::kw_if:                  // C99 6.8.4.1: if-statement
236534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return ParseIfStatement(TrailingElseLoc);
2375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::kw_switch:              // C99 6.8.4.2: switch-statement
238534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return ParseSwitchStatement(TrailingElseLoc);
23961364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
2405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::kw_while:               // C99 6.8.5.1: while-statement
241534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return ParseWhileStatement(TrailingElseLoc);
2425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::kw_do:                  // C99 6.8.5.2: do-statement
243534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    Res = ParseDoStatement();
2446869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner    SemiError = "do/while";
2455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
2465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::kw_for:                 // C99 6.8.5.3: for-statement
247534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return ParseForStatement(TrailingElseLoc);
2485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::kw_goto:                // C99 6.8.6.1: goto-statement
250534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    Res = ParseGotoStatement();
2516869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner    SemiError = "goto";
2525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
2535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::kw_continue:            // C99 6.8.6.2: continue-statement
254534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    Res = ParseContinueStatement();
2556869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner    SemiError = "continue";
2565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
2575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::kw_break:               // C99 6.8.6.3: break-statement
258534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    Res = ParseBreakStatement();
2596869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner    SemiError = "break";
2605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
2615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::kw_return:              // C99 6.8.6.4: return-statement
262534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    Res = ParseReturnStatement();
2636869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner    SemiError = "return";
2645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
26561364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
266a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  case tok::kw_asm: {
267534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    ProhibitAttributes(Attrs);
268d62701bc5321049353017e9abf1963edd57646aaSteve Naroff    bool msAsm = false;
269d62701bc5321049353017e9abf1963edd57646aaSteve Naroff    Res = ParseAsmStatement(msAsm);
270bf8cafadb9d4e0d7a90fe78fc175efb80ae34d42Argyrios Kyrtzidis    Res = Actions.ActOnFinishFullStmt(Res.get());
2713fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer    if (msAsm) return Res;
2726869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner    SemiError = "asm";
2735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
2745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
27561364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
276ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  case tok::kw___if_exists:
277ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  case tok::kw___if_not_exists:
278ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    ProhibitAttributes(Attrs);
279ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    ParseMicrosoftIfExistsStatement(Stmts);
280ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    // An __if_exists block is like a compound statement, but it doesn't create
281ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    // a new scope.
282ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return StmtEmpty();
283ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
284a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  case tok::kw_try:                 // C++ 15: try-block
285534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return ParseCXXTryBlock();
28628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
28728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  case tok::kw___try:
288534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    ProhibitAttributes(Attrs); // TODO: is it correct?
289534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return ParseSEHTryBlock();
290aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman
291ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  case tok::kw___leave:
292ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    Res = ParseSEHLeaveStatement();
293ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    SemiError = "__leave";
294ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    break;
295ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
296aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman  case tok::annot_pragma_vis:
297534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    ProhibitAttributes(Attrs);
298aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman    HandlePragmaVisibility();
299aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman    return StmtEmpty();
300aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman
301aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman  case tok::annot_pragma_pack:
302534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    ProhibitAttributes(Attrs);
303aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman    HandlePragmaPack();
304aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman    return StmtEmpty();
3059595c7e2533c836537dc300e75d059c29feb7094Eli Friedman
3068b2bfdda35de8239df0ff4a588214d5876a38d28Eli Friedman  case tok::annot_pragma_msstruct:
3078b2bfdda35de8239df0ff4a588214d5876a38d28Eli Friedman    ProhibitAttributes(Attrs);
3088b2bfdda35de8239df0ff4a588214d5876a38d28Eli Friedman    HandlePragmaMSStruct();
3098b2bfdda35de8239df0ff4a588214d5876a38d28Eli Friedman    return StmtEmpty();
3108b2bfdda35de8239df0ff4a588214d5876a38d28Eli Friedman
3113ef38eea7ce400718e4ab523b4704ae1fd8f940fEli Friedman  case tok::annot_pragma_align:
3123ef38eea7ce400718e4ab523b4704ae1fd8f940fEli Friedman    ProhibitAttributes(Attrs);
3133ef38eea7ce400718e4ab523b4704ae1fd8f940fEli Friedman    HandlePragmaAlign();
3143ef38eea7ce400718e4ab523b4704ae1fd8f940fEli Friedman    return StmtEmpty();
3153ef38eea7ce400718e4ab523b4704ae1fd8f940fEli Friedman
3168b2bfdda35de8239df0ff4a588214d5876a38d28Eli Friedman  case tok::annot_pragma_weak:
3178b2bfdda35de8239df0ff4a588214d5876a38d28Eli Friedman    ProhibitAttributes(Attrs);
3188b2bfdda35de8239df0ff4a588214d5876a38d28Eli Friedman    HandlePragmaWeak();
3198b2bfdda35de8239df0ff4a588214d5876a38d28Eli Friedman    return StmtEmpty();
3208b2bfdda35de8239df0ff4a588214d5876a38d28Eli Friedman
3218b2bfdda35de8239df0ff4a588214d5876a38d28Eli Friedman  case tok::annot_pragma_weakalias:
3228b2bfdda35de8239df0ff4a588214d5876a38d28Eli Friedman    ProhibitAttributes(Attrs);
3238b2bfdda35de8239df0ff4a588214d5876a38d28Eli Friedman    HandlePragmaWeakAlias();
3248b2bfdda35de8239df0ff4a588214d5876a38d28Eli Friedman    return StmtEmpty();
3258b2bfdda35de8239df0ff4a588214d5876a38d28Eli Friedman
3268b2bfdda35de8239df0ff4a588214d5876a38d28Eli Friedman  case tok::annot_pragma_redefine_extname:
3278b2bfdda35de8239df0ff4a588214d5876a38d28Eli Friedman    ProhibitAttributes(Attrs);
3288b2bfdda35de8239df0ff4a588214d5876a38d28Eli Friedman    HandlePragmaRedefineExtname();
3298b2bfdda35de8239df0ff4a588214d5876a38d28Eli Friedman    return StmtEmpty();
3308b2bfdda35de8239df0ff4a588214d5876a38d28Eli Friedman
3319595c7e2533c836537dc300e75d059c29feb7094Eli Friedman  case tok::annot_pragma_fp_contract:
332aed01168e7593c42ce99aaf1c48deeb8a77dd120Richard Smith    ProhibitAttributes(Attrs);
333860022ccf71b3d63acd29912af970dad655630f7Lang Hames    Diag(Tok, diag::err_pragma_fp_contract_scope);
334860022ccf71b3d63acd29912af970dad655630f7Lang Hames    ConsumeToken();
335860022ccf71b3d63acd29912af970dad655630f7Lang Hames    return StmtError();
336860022ccf71b3d63acd29912af970dad655630f7Lang Hames
3379595c7e2533c836537dc300e75d059c29feb7094Eli Friedman  case tok::annot_pragma_opencl_extension:
3389595c7e2533c836537dc300e75d059c29feb7094Eli Friedman    ProhibitAttributes(Attrs);
3399595c7e2533c836537dc300e75d059c29feb7094Eli Friedman    HandlePragmaOpenCLExtension();
3409595c7e2533c836537dc300e75d059c29feb7094Eli Friedman    return StmtEmpty();
341c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev
34285192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj  case tok::annot_pragma_captured:
343175d417134124df3abba8d874e51f04d5b4b9ee6Richard Smith    ProhibitAttributes(Attrs);
34485192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    return HandlePragmaCaptured();
34585192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
346c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev  case tok::annot_pragma_openmp:
347175d417134124df3abba8d874e51f04d5b4b9ee6Richard Smith    ProhibitAttributes(Attrs);
3484fa7eab771ab8212e1058bd1a91061ff120c8fbbAlexey Bataev    return ParseOpenMPDeclarativeOrExecutableDirective();
3494fa7eab771ab8212e1058bd1a91061ff120c8fbbAlexey Bataev
350651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case tok::annot_pragma_ms_pointers_to_members:
351651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ProhibitAttributes(Attrs);
352651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    HandlePragmaMSPointersToMembers();
353651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return StmtEmpty();
354651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  case tok::annot_pragma_ms_pragma:
3566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    ProhibitAttributes(Attrs);
3576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    HandlePragmaMSPragma();
3586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return StmtEmpty();
359ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
360ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  case tok::annot_pragma_loop_hint:
361ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    ProhibitAttributes(Attrs);
362ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return ParsePragmaLoopHint(Stmts, OnlyStatement, TrailingElseLoc, Attrs);
363a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  }
364a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
3655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If we reached this code, the statement must end in a semicolon.
366651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!TryConsumeToken(tok::semi) && !Res.isInvalid()) {
3677b3684afffa2d5eda3dd6930f01faaa673686c16Chris Lattner    // If the result was valid, then we do want to diagnose this.  Use
3687b3684afffa2d5eda3dd6930f01faaa673686c16Chris Lattner    // ExpectAndConsume to emit the diagnostic, even though we know it won't
3697b3684afffa2d5eda3dd6930f01faaa673686c16Chris Lattner    // succeed.
3707b3684afffa2d5eda3dd6930f01faaa673686c16Chris Lattner    ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt, SemiError);
371195044028b76133e2a1f245b094468fe07db7330Chris Lattner    // Skip until we see a } or ;, but don't eat it.
3728fe2475a4b4c00475709c13d43eb9a57cce87cbcAlexey Bataev    SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
3735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3753fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer  return Res;
3765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
3775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
378312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor/// \brief Parse an expression statement.
379534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseExprStatement() {
380312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor  // If a case keyword is missing, this is where it should be inserted.
381312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor  Token OldToken = Tok;
382a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
383312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor  // expression[opt] ';'
3845ecdd78408a1c6f4be506d94f776642570d27336Douglas Gregor  ExprResult Expr(ParseExpression());
385312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor  if (Expr.isInvalid()) {
386312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    // If the expression is invalid, skip ahead to the next semicolon or '}'.
387312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    // Not doing this opens us up to the possibility of infinite loops if
388312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    // ParseExpression does not consume any tokens.
3898fe2475a4b4c00475709c13d43eb9a57cce87cbcAlexey Bataev    SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
390312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    if (Tok.is(tok::semi))
391312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor      ConsumeToken();
392b760f11fae94e3003b9241ac50c02617465f2fa2John McCall    return Actions.ActOnExprStmtError();
393312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor  }
394a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
395312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor  if (Tok.is(tok::colon) && getCurScope()->isSwitchScope() &&
396312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor      Actions.CheckCaseExpression(Expr.get())) {
397312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    // If a constant expression is followed by a colon inside a switch block,
398312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    // suggest a missing case keyword.
399312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    Diag(OldToken, diag::err_expected_case_before_expression)
400312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor      << FixItHint::CreateInsertion(OldToken.getLocation(), "case ");
401a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
402312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    // Recover parsing as a case statement.
403534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return ParseCaseStatement(/*MissingCase=*/true, Expr);
404312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor  }
405a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
406312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor  // Otherwise, eat the semicolon.
407312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor  ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
408419563768ef4929a622d7c2b066856e82901bb91Richard Smith  return Actions.ActOnExprStmt(Expr);
40928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley}
410312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor
411534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseSEHTryBlock() {
41228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  assert(Tok.is(tok::kw___try) && "Expected '__try'");
41328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  SourceLocation Loc = ConsumeToken();
41428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  return ParseSEHTryBlockCommon(Loc);
41528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley}
41628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
41728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// ParseSEHTryBlockCommon
41828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///
41928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// seh-try-block:
42028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///   '__try' compound-statement seh-handler
42128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///
42228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// seh-handler:
42328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///   seh-except-block
42428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///   seh-finally-block
42528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///
42628bbe4b8acc338476fe0825769b41fb32b423c72John WiegleyStmtResult Parser::ParseSEHTryBlockCommon(SourceLocation TryLoc) {
42728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  if(Tok.isNot(tok::l_brace))
428651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
42928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
430ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  StmtResult TryBlock(ParseCompoundStatement(/*isStmtExpr=*/false,
431ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                      Scope::DeclScope | Scope::SEHTryScope));
43228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  if(TryBlock.isInvalid())
4333fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer    return TryBlock;
43428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
43528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  StmtResult Handler;
436534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  if (Tok.is(tok::identifier) &&
437b57791e5b40afa6691063c83d0e95c416fb19fdeDouglas Gregor      Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
43828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    SourceLocation Loc = ConsumeToken();
43928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    Handler = ParseSEHExceptBlock(Loc);
44028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  } else if (Tok.is(tok::kw___finally)) {
44128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    SourceLocation Loc = ConsumeToken();
44228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    Handler = ParseSEHFinallyBlock(Loc);
44328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  } else {
44428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    return StmtError(Diag(Tok,diag::err_seh_expected_handler));
44528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  }
44628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
44728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  if(Handler.isInvalid())
4483fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer    return Handler;
44928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
45028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  return Actions.ActOnSEHTryBlock(false /* IsCXXTry */,
45128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley                                  TryLoc,
452ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                                  TryBlock.get(),
453ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                                  Handler.get());
45428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley}
45528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
45628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// ParseSEHExceptBlock - Handle __except
45728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///
45828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// seh-except-block:
45928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///   '__except' '(' seh-filter-expression ')' compound-statement
46028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///
46128bbe4b8acc338476fe0825769b41fb32b423c72John WiegleyStmtResult Parser::ParseSEHExceptBlock(SourceLocation ExceptLoc) {
46228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  PoisonIdentifierRAIIObject raii(Ident__exception_code, false),
46328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    raii2(Ident___exception_code, false),
46428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    raii3(Ident_GetExceptionCode, false);
46528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
466651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (ExpectAndConsume(tok::l_paren))
46728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    return StmtError();
46828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
46928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  ParseScope ExpectScope(this, Scope::DeclScope | Scope::ControlScope);
47028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
4714e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().Borland) {
472d7f02df6e949aaf26706bea3ac79ed65ca792a30Francois Pichet    Ident__exception_info->setIsPoisoned(false);
473d7f02df6e949aaf26706bea3ac79ed65ca792a30Francois Pichet    Ident___exception_info->setIsPoisoned(false);
474d7f02df6e949aaf26706bea3ac79ed65ca792a30Francois Pichet    Ident_GetExceptionInfo->setIsPoisoned(false);
475d7f02df6e949aaf26706bea3ac79ed65ca792a30Francois Pichet  }
47628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  ExprResult FilterExpr(ParseExpression());
477d7f02df6e949aaf26706bea3ac79ed65ca792a30Francois Pichet
4784e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().Borland) {
479d7f02df6e949aaf26706bea3ac79ed65ca792a30Francois Pichet    Ident__exception_info->setIsPoisoned(true);
480d7f02df6e949aaf26706bea3ac79ed65ca792a30Francois Pichet    Ident___exception_info->setIsPoisoned(true);
481d7f02df6e949aaf26706bea3ac79ed65ca792a30Francois Pichet    Ident_GetExceptionInfo->setIsPoisoned(true);
482d7f02df6e949aaf26706bea3ac79ed65ca792a30Francois Pichet  }
48328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
48428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  if(FilterExpr.isInvalid())
48528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    return StmtError();
48628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
487651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (ExpectAndConsume(tok::r_paren))
48828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    return StmtError();
48928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
490534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  StmtResult Block(ParseCompoundStatement());
49128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
49228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  if(Block.isInvalid())
4933fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer    return Block;
49428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
495ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return Actions.ActOnSEHExceptBlock(ExceptLoc, FilterExpr.get(), Block.get());
49628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley}
49728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
49828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// ParseSEHFinallyBlock - Handle __finally
49928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///
50028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// seh-finally-block:
50128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///   '__finally' compound-statement
50228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///
50328bbe4b8acc338476fe0825769b41fb32b423c72John WiegleyStmtResult Parser::ParseSEHFinallyBlock(SourceLocation FinallyBlock) {
50428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  PoisonIdentifierRAIIObject raii(Ident__abnormal_termination, false),
50528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    raii2(Ident___abnormal_termination, false),
50628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    raii3(Ident_AbnormalTermination, false);
50728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
508534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  StmtResult Block(ParseCompoundStatement());
50928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  if(Block.isInvalid())
5103fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer    return Block;
51128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
512ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return Actions.ActOnSEHFinallyBlock(FinallyBlock,Block.get());
513ef8225444452a1486bd721f3285301fe84643b00Stephen Hines}
514ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
515ef8225444452a1486bd721f3285301fe84643b00Stephen Hines/// Handle __leave
516ef8225444452a1486bd721f3285301fe84643b00Stephen Hines///
517ef8225444452a1486bd721f3285301fe84643b00Stephen Hines/// seh-leave-statement:
518ef8225444452a1486bd721f3285301fe84643b00Stephen Hines///   '__leave' ';'
519ef8225444452a1486bd721f3285301fe84643b00Stephen Hines///
520ef8225444452a1486bd721f3285301fe84643b00Stephen HinesStmtResult Parser::ParseSEHLeaveStatement() {
521ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  SourceLocation LeaveLoc = ConsumeToken();  // eat the '__leave'.
522ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return Actions.ActOnSEHLeaveStmt(LeaveLoc, getCurScope());
523312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor}
524312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor
525f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis/// ParseLabeledStatement - We have an identifier and a ':' after it.
5265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
5275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       labeled-statement:
5285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         identifier ':' statement
5295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU]   identifier ':' attributes[opt] statement
5305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
531534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseLabeledStatement(ParsedAttributesWithRange &attrs) {
5324e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
5335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         "Not an identifier!");
5345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
535d217773f106856a11879ec79dc468efefaf2ee75Chris Lattner  Token IdentTok = Tok;  // Save the whole token.
5365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ConsumeToken();  // eat the identifier.
537f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis
538f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis  assert(Tok.is(tok::colon) && "Not a label!");
53961364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
5405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // identifier ':' statement
541f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis  SourceLocation ColonLoc = ConsumeToken();
5425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
54393982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith  // Read label attributes, if present.
54493982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith  StmtResult SubStmt;
54593982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith  if (Tok.is(tok::kw___attribute)) {
54693982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith    ParsedAttributesWithRange TempAttrs(AttrFactory);
54793982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith    ParseGNUAttributes(TempAttrs);
54893982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith
54993982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith    // In C++, GNU attributes only apply to the label if they are followed by a
55093982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith    // semicolon, to disambiguate label attributes from attributes on a labeled
55193982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith    // declaration.
55293982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith    //
55393982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith    // This doesn't quite match what GCC does; if the attribute list is empty
55493982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith    // and followed by a semicolon, GCC will reject (it appears to parse the
55593982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith    // attributes as part of a statement in that case). That looks like a bug.
55693982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith    if (!getLangOpts().CPlusPlus || Tok.is(tok::semi))
55793982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith      attrs.takeAllFrom(TempAttrs);
55893982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith    else if (isDeclarationStatement()) {
55993982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith      StmtVector Stmts;
56093982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith      // FIXME: We should do this whether or not we have a declaration
56193982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith      // statement, but that doesn't work correctly (because ProhibitAttributes
56293982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith      // can't handle GNU attributes), so only call it in the one case where
56393982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith      // GNU attributes are allowed.
56493982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith      SubStmt = ParseStatementOrDeclarationAfterAttributes(
5656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          Stmts, /*OnlyStmts*/ true, nullptr, TempAttrs);
56693982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith      if (!TempAttrs.empty() && !SubStmt.isInvalid())
56793982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith        SubStmt = Actions.ProcessStmtAttributes(
56893982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith            SubStmt.get(), TempAttrs.getList(), TempAttrs.Range);
56993982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith    } else {
570651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Diag(Tok, diag::err_expected_after) << "__attribute__" << tok::semi;
57193982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith    }
57293982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith  }
5735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
57493982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith  // If we've not parsed a statement yet, parse one now.
57593982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith  if (!SubStmt.isInvalid() && !SubStmt.isUsable())
57693982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith    SubStmt = ParseStatement();
5770e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
578f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis  // Broken substmt shouldn't prevent the label from being added to the AST.
5790e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl  if (SubStmt.isInvalid())
580f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis    SubStmt = Actions.ActOnNullStmt(ColonLoc);
581a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
582337e550218128e7d922c09bb354fbc71de90c568Chris Lattner  LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
583337e550218128e7d922c09bb354fbc71de90c568Chris Lattner                                              IdentTok.getLocation());
584534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  if (AttributeList *Attrs = attrs.getList()) {
585337e550218128e7d922c09bb354fbc71de90c568Chris Lattner    Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
586534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    attrs.clear();
587534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  }
588a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
589337e550218128e7d922c09bb354fbc71de90c568Chris Lattner  return Actions.ActOnLabelStmt(IdentTok.getLocation(), LD, ColonLoc,
590337e550218128e7d922c09bb354fbc71de90c568Chris Lattner                                SubStmt.get());
591f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis}
5925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCaseStatement
5945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       labeled-statement:
5955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'case' constant-expression ':' statement
5965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU]   'case' constant-expression '...' constant-expression ':' statement
5975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
598534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseCaseStatement(bool MissingCase, ExprResult Expr) {
59946f1110b324583622521a01d2c8f949e1f215bd2Richard Smith  assert((MissingCase || Tok.is(tok::kw_case)) && "Not a case stmt!");
6001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
60124e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // It is very very common for code to contain many case statements recursively
60224e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // nested, as in (but usually without indentation):
60324e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  //  case 1:
60424e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  //    case 2:
60524e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  //      case 3:
60624e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  //         case 4:
60724e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  //           case 5: etc.
60824e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  //
60924e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // Parsing this naively works, but is both inefficient and can cause us to run
61024e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // out of stack space in our recursive descent parser.  As a special case,
61126140c6399d4b14a224d44cf0102a1919d8dab04Chris Lattner  // flatten this recursion into an iterative loop.  This is complex and gross,
61224e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // but all the grossness is constrained to ParseCaseStatement (and some
61393982a7557fae3c72d84a3fc4c8d2b9852ccc5dbRichard Smith  // weirdness in the actions), so this is just local grossness :).
6141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
61524e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // TopLevelCase - This is the highest level we have parsed.  'case 1' in the
61624e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // example above.
61760d7b3a319d84d688752be3870615ac0f111fb16John McCall  StmtResult TopLevelCase(true);
6181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
61924e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // DeepestParsedCaseStmt - This is the deepest statement we have parsed, which
62024e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // gets updated each time a new case is parsed, and whose body is unset so
62124e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // far.  When parsing 'case 4', this is the 'case 3' node.
6226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  Stmt *DeepestParsedCaseStmt = nullptr;
6231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
62424e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // While we have case statements, eat and stack them.
6250e1e69ca1b30df7692f302a5388377f507bc4567David Majnemer  SourceLocation ColonLoc;
62624e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  do {
627bb9b80c308d7d3f758886243c7145404a50c66cfRichard Trieu    SourceLocation CaseLoc = MissingCase ? Expr.get()->getExprLoc() :
628bb9b80c308d7d3f758886243c7145404a50c66cfRichard Trieu                                           ConsumeToken();  // eat the 'case'.
6296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    ColonLoc = SourceLocation();
6301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6313e1005f085006dfb3545f0c54ac5e22483137c7dDouglas Gregor    if (Tok.is(tok::code_completion)) {
63223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      Actions.CodeCompleteCase(getCurScope());
6337d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      cutOffParsing();
6347d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      return StmtError();
6353e1005f085006dfb3545f0c54ac5e22483137c7dDouglas Gregor    }
636a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
6376fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    /// We don't want to treat 'case x : y' as a potential typo for 'case x::y'.
6386fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    /// Disable this form of error recovery while we're parsing the case
6396fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    /// expression.
6406fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    ColonProtectionRAIIObject ColonProtection(*this);
641a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
6426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    ExprResult LHS;
6436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    if (!MissingCase) {
6446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      LHS = ParseConstantExpression();
6456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      if (LHS.isInvalid()) {
6466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        // If constant-expression is parsed unsuccessfully, recover by skipping
6476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        // current case statement (moving to the colon that ends it).
6486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        if (SkipUntil(tok::colon, tok::r_brace, StopAtSemi | StopBeforeMatch)) {
6496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          TryConsumeToken(tok::colon, ColonLoc);
6506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          continue;
6516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        }
6526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        return StmtError();
6536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      }
6546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    } else {
6556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      LHS = Expr;
6566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      MissingCase = false;
65724e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    }
6585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
65924e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    // GNU case range extension.
66024e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    SourceLocation DotDotDotLoc;
66160d7b3a319d84d688752be3870615ac0f111fb16John McCall    ExprResult RHS;
662651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (TryConsumeToken(tok::ellipsis, DotDotDotLoc)) {
663651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Diag(DotDotDotLoc, diag::ext_gnu_case_range);
66424e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      RHS = ParseConstantExpression();
66524e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      if (RHS.isInvalid()) {
6666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        if (SkipUntil(tok::colon, tok::r_brace, StopAtSemi | StopBeforeMatch)) {
6676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          TryConsumeToken(tok::colon, ColonLoc);
6686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          continue;
6696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        }
67024e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner        return StmtError();
67124e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      }
67224e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    }
673a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
6746fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    ColonProtection.restore();
6750e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
676651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (TryConsumeToken(tok::colon, ColonLoc)) {
6776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    } else if (TryConsumeToken(tok::semi, ColonLoc) ||
6786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines               TryConsumeToken(tok::coloncolon, ColonLoc)) {
6796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      // Treat "case blah;" or "case blah::" as a typo for "case blah:".
680651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Diag(ColonLoc, diag::err_expected_after)
681651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          << "'case'" << tok::colon
682651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          << FixItHint::CreateReplacement(ColonLoc, ":");
683f6a3ab0f167f23d0669eae77280c7ff660e7ad98John McCall    } else {
684662a4822ee7c8696434b054303c5076a606ab175Douglas Gregor      SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation);
685651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Diag(ExpectedLoc, diag::err_expected_after)
686651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          << "'case'" << tok::colon
687651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          << FixItHint::CreateInsertion(ExpectedLoc, ":");
688662a4822ee7c8696434b054303c5076a606ab175Douglas Gregor      ColonLoc = ExpectedLoc;
6895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
690a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
69160d7b3a319d84d688752be3870615ac0f111fb16John McCall    StmtResult Case =
6929ae2f076ca5ab1feb3ba95629099ec2319833701John McCall      Actions.ActOnCaseStmt(CaseLoc, LHS.get(), DotDotDotLoc,
6939ae2f076ca5ab1feb3ba95629099ec2319833701John McCall                            RHS.get(), ColonLoc);
6941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
69524e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    // If we had a sema error parsing this case, then just ignore it and
69624e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    // continue parsing the sub-stmt.
69724e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    if (Case.isInvalid()) {
69824e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      if (TopLevelCase.isInvalid())  // No parsed case stmts.
69924e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner        return ParseStatement();
70024e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      // Otherwise, just don't add it as a nested case.
70124e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    } else {
70224e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      // If this is the first case statement we parsed, it becomes TopLevelCase.
70324e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      // Otherwise we link it into the current chain.
704ca0408fb49c1370430672acf2d770b7151cf71deJohn McCall      Stmt *NextDeepest = Case.get();
70524e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      if (TopLevelCase.isInvalid())
7063fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer        TopLevelCase = Case;
70724e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      else
7089ae2f076ca5ab1feb3ba95629099ec2319833701John McCall        Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, Case.get());
70924e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      DeepestParsedCaseStmt = NextDeepest;
71024e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    }
7111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
71224e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    // Handle all case statements.
71324e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  } while (Tok.is(tok::kw_case));
7141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
71524e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // If we found a non-case statement, start by parsing it.
71660d7b3a319d84d688752be3870615ac0f111fb16John McCall  StmtResult SubStmt;
7171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
71824e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  if (Tok.isNot(tok::r_brace)) {
71924e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    SubStmt = ParseStatement();
72024e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  } else {
72124e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    // Nicely diagnose the common error "switch (X) { case 4: }", which is
7226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // not valid.  If ColonLoc doesn't point to a valid text location, there was
7236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // another parsing error, so avoid producing extra diagnostics.
7246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    if (ColonLoc.isValid()) {
7256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      SourceLocation AfterColonLoc = PP.getLocForEndOfToken(ColonLoc);
7266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      Diag(AfterColonLoc, diag::err_label_end_of_compound_statement)
7276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        << FixItHint::CreateInsertion(AfterColonLoc, " ;");
7286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    }
7296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    SubStmt = StmtError();
7305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
7311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
73224e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // Install the body into the most deeply-nested case.
7336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (DeepestParsedCaseStmt) {
7346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // Broken sub-stmt shouldn't prevent forming the case statement properly.
7356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    if (SubStmt.isInvalid())
7366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      SubStmt = Actions.ActOnNullStmt(SourceLocation());
7376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, SubStmt.get());
7386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
73961364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
74024e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // Return the top level parsed statement tree.
7413fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer  return TopLevelCase;
7425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
7435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseDefaultStatement
7455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       labeled-statement:
7465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'default' ':' statement
7475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Note that this does not parse the 'statement' at the end.
7485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
749534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseDefaultStatement() {
7504e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  assert(Tok.is(tok::kw_default) && "Not a default stmt!");
7515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation DefaultLoc = ConsumeToken();  // eat the 'default'.
7525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
753662a4822ee7c8696434b054303c5076a606ab175Douglas Gregor  SourceLocation ColonLoc;
754651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (TryConsumeToken(tok::colon, ColonLoc)) {
755651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  } else if (TryConsumeToken(tok::semi, ColonLoc)) {
756651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // Treat "default;" as a typo for "default:".
757651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Diag(ColonLoc, diag::err_expected_after)
758651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        << "'default'" << tok::colon
759651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        << FixItHint::CreateReplacement(ColonLoc, ":");
760f6a3ab0f167f23d0669eae77280c7ff660e7ad98John McCall  } else {
761662a4822ee7c8696434b054303c5076a606ab175Douglas Gregor    SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation);
762651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Diag(ExpectedLoc, diag::err_expected_after)
763651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        << "'default'" << tok::colon
764651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        << FixItHint::CreateInsertion(ExpectedLoc, ":");
765662a4822ee7c8696434b054303c5076a606ab175Douglas Gregor    ColonLoc = ExpectedLoc;
7665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
767a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
76885b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith  StmtResult SubStmt;
76985b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith
77085b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith  if (Tok.isNot(tok::r_brace)) {
77185b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith    SubStmt = ParseStatement();
77285b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith  } else {
77385b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith    // Diagnose the common error "switch (X) {... default: }", which is
77485b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith    // not valid.
77563f04ab297157c5905975e8f2c807b35251dace7David Majnemer    SourceLocation AfterColonLoc = PP.getLocForEndOfToken(ColonLoc);
77685b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith    Diag(AfterColonLoc, diag::err_label_end_of_compound_statement)
77785b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith      << FixItHint::CreateInsertion(AfterColonLoc, " ;");
77885b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith    SubStmt = true;
7795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
7805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
78185b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith  // Broken sub-stmt shouldn't prevent forming the case statement properly.
7820e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl  if (SubStmt.isInvalid())
78385b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith    SubStmt = Actions.ActOnNullStmt(ColonLoc);
78461364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
785117054a99f4994e4ec8a1fc904b554e1f2dc9b29Sebastian Redl  return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc,
7869ae2f076ca5ab1feb3ba95629099ec2319833701John McCall                                  SubStmt.get(), getCurScope());
7875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
7885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
789534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseCompoundStatement(bool isStmtExpr) {
790534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  return ParseCompoundStatement(isStmtExpr, Scope::DeclScope);
791bca01b46850f867b2f4137f25c882022b58f8471Douglas Gregor}
7925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCompoundStatement - Parse a "{}" block.
7945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
7955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       compound-statement: [C99 6.8.2]
7965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         { block-item-list[opt] }
7975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU]   { label-declarations block-item-list } [TODO]
7985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
7995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       block-item-list:
8005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         block-item
8015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         block-item-list block-item
8025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
8035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       block-item:
8045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         declaration
80545a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner/// [GNU]   '__extension__' declaration
8065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         statement
8075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [OMP]   openmp-directive            [TODO]
8085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
8095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU] label-declarations:
8105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU]   label-declaration
8115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU]   label-declarations label-declaration
8125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
8135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU] label-declaration:
8145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU]   '__label__' identifier-list ';'
8155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
8165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [OMP] openmp-directive:             [TODO]
8175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [OMP]   barrier-directive
8185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [OMP]   flush-directive
8195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
820534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseCompoundStatement(bool isStmtExpr,
821bca01b46850f867b2f4137f25c882022b58f8471Douglas Gregor                                          unsigned ScopeFlags) {
8224e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  assert(Tok.is(tok::l_brace) && "Not a compount stmt!");
82361364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
82431e057270232c1c37602579cb6461c2704175672Chris Lattner  // Enter a scope to hold everything within the compound stmt.  Compound
82531e057270232c1c37602579cb6461c2704175672Chris Lattner  // statements can always hold declarations.
826bca01b46850f867b2f4137f25c882022b58f8471Douglas Gregor  ParseScope CompoundScope(this, ScopeFlags);
8275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
8285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Parse the statements in the body.
82961364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl  return ParseCompoundStatementBody(isStmtExpr);
8305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
8315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
832a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames/// Parse any pragmas at the start of the compound expression. We handle these
833a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames/// separately since some pragmas (FP_CONTRACT) must appear before any C
834a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames/// statement in the compound, but may be intermingled with other pragmas.
835a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hamesvoid Parser::ParseCompoundStatementLeadingPragmas() {
836a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames  bool checkForPragmas = true;
837a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames  while (checkForPragmas) {
838a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames    switch (Tok.getKind()) {
839a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames    case tok::annot_pragma_vis:
840a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames      HandlePragmaVisibility();
841a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames      break;
842a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames    case tok::annot_pragma_pack:
843a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames      HandlePragmaPack();
844a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames      break;
845a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames    case tok::annot_pragma_msstruct:
846a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames      HandlePragmaMSStruct();
847a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames      break;
848a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames    case tok::annot_pragma_align:
849a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames      HandlePragmaAlign();
850a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames      break;
851a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames    case tok::annot_pragma_weak:
852a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames      HandlePragmaWeak();
853a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames      break;
854a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames    case tok::annot_pragma_weakalias:
855a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames      HandlePragmaWeakAlias();
856a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames      break;
857a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames    case tok::annot_pragma_redefine_extname:
858a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames      HandlePragmaRedefineExtname();
859a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames      break;
860a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames    case tok::annot_pragma_opencl_extension:
861a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames      HandlePragmaOpenCLExtension();
862a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames      break;
863a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames    case tok::annot_pragma_fp_contract:
864a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames      HandlePragmaFPContract();
865a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames      break;
866651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    case tok::annot_pragma_ms_pointers_to_members:
867651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      HandlePragmaMSPointersToMembers();
868651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      break;
8696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    case tok::annot_pragma_ms_pragma:
8706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      HandlePragmaMSPragma();
8716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      break;
872a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames    default:
873a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames      checkForPragmas = false;
874a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames      break;
875a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames    }
876a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames  }
877a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames
878a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames}
879a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames
8805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCompoundStatementBody - Parse a sequence of statements and invoke the
8811b273c403734d343d720acb28f04011807c8aa56Steve Naroff/// ActOnCompoundStmt action.  This expects the '{' to be the current token, and
8825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// consume the '}' at the end of the block.  It does not manipulate the scope
8835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// stack.
88460d7b3a319d84d688752be3870615ac0f111fb16John McCallStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
8851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),
886ae50fa0a9e7217b043ed4ffe175af4b26dc90f34Chris Lattner                                Tok.getLocation(),
887ae50fa0a9e7217b043ed4ffe175af4b26dc90f34Chris Lattner                                "in compound statement ('{}')");
888be9af1288881110e406b87914162eaa59f1e5918Lang Hames
889be9af1288881110e406b87914162eaa59f1e5918Lang Hames  // Record the state of the FP_CONTRACT pragma, restore on leaving the
890be9af1288881110e406b87914162eaa59f1e5918Lang Hames  // compound statement.
891be9af1288881110e406b87914162eaa59f1e5918Lang Hames  Sema::FPContractStateRAII SaveFPContractState(Actions);
892be9af1288881110e406b87914162eaa59f1e5918Lang Hames
8930fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor  InMessageExpressionRAIIObject InMessage(*this, false);
8944a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_brace);
8954a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  if (T.consumeOpen())
8964a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    return StmtError();
8975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
898625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  Sema::CompoundScopeRAII CompoundScope(Actions);
899625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
900a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames  // Parse any pragmas at the beginning of the compound statement.
901a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames  ParseCompoundStatementLeadingPragmas();
902b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis
903a60d21d9ffd2a995c58dc5c5a4e3d9a014e3bc60Lang Hames  StmtVector Stmts;
904860022ccf71b3d63acd29912af970dad655630f7Lang Hames
9054ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner  // "__label__ X, Y, Z;" is the GNU "Local Label" extension.  These are
9064ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner  // only allowed at the start of a compound stmt regardless of the language.
9074ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner  while (Tok.is(tok::kw___label__)) {
9084ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner    SourceLocation LabelLoc = ConsumeToken();
909a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
9105f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<Decl *, 8> DeclsInGroup;
9114ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner    while (1) {
9124ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner      if (Tok.isNot(tok::identifier)) {
913651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        Diag(Tok, diag::err_expected) << tok::identifier;
9144ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner        break;
9154ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner      }
916a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
9174ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner      IdentifierInfo *II = Tok.getIdentifierInfo();
9184ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner      SourceLocation IdLoc = ConsumeToken();
9196784304db526cde59046d613c4175ce2caf93e44Abramo Bagnara      DeclsInGroup.push_back(Actions.LookupOrCreateLabel(II, IdLoc, LabelLoc));
920a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
921651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (!TryConsumeToken(tok::comma))
9224ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner        break;
9234ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner    }
924a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
9250b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall    DeclSpec DS(AttrFactory);
9264549d7ffc15bdd7ab860aa68db089d9f559b79e7Rafael Espindola    DeclGroupPtrTy Res =
9274549d7ffc15bdd7ab860aa68db089d9f559b79e7Rafael Espindola        Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup);
9284ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner    StmtResult R = Actions.ActOnDeclStmt(Res, LabelLoc, Tok.getLocation());
929a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
9308bb21d32e9ccc9d9c221506dff26acafa8724ccaChris Lattner    ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
9314ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner    if (R.isUsable())
932ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      Stmts.push_back(R.get());
9334ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner  }
934a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
935651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
936b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis    if (Tok.is(tok::annot_pragma_unused)) {
937b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis      HandlePragmaUnused();
938b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis      continue;
939b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis    }
940b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis
94160d7b3a319d84d688752be3870615ac0f111fb16John McCall    StmtResult R;
9424e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner    if (Tok.isNot(tok::kw___extension__)) {
943c5be7b0fc804d8e6f87298ec03c94d8cccd74f29Fariborz Jahanian      R = ParseStatementOrDeclaration(Stmts, false);
94445a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner    } else {
94545a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner      // __extension__ can start declarations and it can also be a unary
94645a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner      // operator for expressions.  Consume multiple __extension__ markers here
94745a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner      // until we can determine which is which.
948adf077f46ba5cddcd801a647a5e9a3eb97060df4Eli Friedman      // FIXME: This loses extension expressions in the AST!
94945a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner      SourceLocation ExtLoc = ConsumeToken();
9504e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner      while (Tok.is(tok::kw___extension__))
95145a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner        ConsumeToken();
95239146d6497ad5e7ca8ef639221e7b3e15d07c888Chris Lattner
9530b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall      ParsedAttributesWithRange attrs(AttrFactory);
9546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      MaybeParseCXX11Attributes(attrs, nullptr,
9556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                /*MightBeObjCMessageSend*/ true);
956bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
95745a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner      // If this is the start of a declaration, parse it as such.
9585404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      if (isDeclarationStatement()) {
959bc6c848f3e0ec2dc44f6e3d59ef85e884cc9b7beEli Friedman        // __extension__ silences extension warnings in the subdeclaration.
96097144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner        // FIXME: Save the __extension__ on the decl as a node somehow?
961bc6c848f3e0ec2dc44f6e3d59ef85e884cc9b7beEli Friedman        ExtensionRAIIObject O(Diags);
962bc6c848f3e0ec2dc44f6e3d59ef85e884cc9b7beEli Friedman
96397144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner        SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
964c5be7b0fc804d8e6f87298ec03c94d8cccd74f29Fariborz Jahanian        DeclGroupPtrTy Res = ParseDeclaration(Stmts,
965c5be7b0fc804d8e6f87298ec03c94d8cccd74f29Fariborz Jahanian                                              Declarator::BlockContext, DeclEnd,
9667f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                              attrs);
96797144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner        R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);
96845a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner      } else {
969adf077f46ba5cddcd801a647a5e9a3eb97060df4Eli Friedman        // Otherwise this was a unary __extension__ marker.
97060d7b3a319d84d688752be3870615ac0f111fb16John McCall        ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
971043a0b50a2a7a29c78a1ffb774f6fca8baf464a0Chris Lattner
9720e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl        if (Res.isInvalid()) {
97345a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner          SkipUntil(tok::semi);
97445a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner          continue;
97545a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner        }
976f512e82f56671b695a32d019103e62a302838b7eSebastian Redl
977bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        // FIXME: Use attributes?
97839146d6497ad5e7ca8ef639221e7b3e15d07c888Chris Lattner        // Eat the semicolon at the end of stmt and convert the expr into a
97939146d6497ad5e7ca8ef639221e7b3e15d07c888Chris Lattner        // statement.
9809ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor        ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
981419563768ef4929a622d7c2b066856e82901bb91Richard Smith        R = Actions.ActOnExprStmt(Res);
98245a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner      }
98345a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner    }
98461364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
9850e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl    if (R.isUsable())
986ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      Stmts.push_back(R.get());
9875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
98861364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
9895d5ed59f1ee57ad2639f0ef1fb400f8854480bb0Argyrios Kyrtzidis  SourceLocation CloseLoc = Tok.getLocation();
9905d5ed59f1ee57ad2639f0ef1fb400f8854480bb0Argyrios Kyrtzidis
9915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // We broke out of the while loop because we found a '}' or EOF.
992d11f4355a77ab1f8897847d9a458b9f2447d44a4Nico Weber  if (!T.consumeClose())
9935d5ed59f1ee57ad2639f0ef1fb400f8854480bb0Argyrios Kyrtzidis    // Recover by creating a compound statement with what we parsed so far,
9945d5ed59f1ee57ad2639f0ef1fb400f8854480bb0Argyrios Kyrtzidis    // instead of dropping everything and returning StmtError();
995d11f4355a77ab1f8897847d9a458b9f2447d44a4Nico Weber    CloseLoc = T.getCloseLocation();
99661364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
9975d5ed59f1ee57ad2639f0ef1fb400f8854480bb0Argyrios Kyrtzidis  return Actions.ActOnCompoundStmt(T.getOpenLocation(), CloseLoc,
9983fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer                                   Stmts, isStmtExpr);
9995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
10005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
100115ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner/// ParseParenExprOrCondition:
100215ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner/// [C  ]     '(' expression ')'
1003ff871fb8f9c5906a4dee78afd81f60c3837e16cbChris Lattner/// [C++]     '(' condition ')'       [not allowed if OnlyAllowCondition=true]
100415ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner///
100515ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner/// This function parses and performs error recovery on the specified condition
100615ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner/// or expression (depending on whether we're in C++ or C mode).  This function
100715ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner/// goes out of its way to recover well.  It returns true if there was a parser
100815ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner/// error (the right paren couldn't be found), which indicates that the caller
100915ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner/// should try to recover harder.  It returns false if the condition is
101015ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner/// successfully parsed.  Note that a successful parse can still have semantic
101115ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner/// errors in the condition.
101260d7b3a319d84d688752be3870615ac0f111fb16John McCallbool Parser::ParseParenExprOrCondition(ExprResult &ExprResult,
1013d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall                                       Decl *&DeclResult,
1014586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor                                       SourceLocation Loc,
101544aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis                                       bool ConvertToBoolean) {
10164a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_paren);
10174a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeOpen();
10184a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor
10194e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().CPlusPlus)
1020dec0984fce504a39a7f085774fb67cfd9957be58Jeffrey Yasskin    ParseCXXCondition(ExprResult, DeclResult, Loc, ConvertToBoolean);
102199e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor  else {
102299e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor    ExprResult = ParseExpression();
10236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    DeclResult = nullptr;
1024a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
1025586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor    // If required, convert to a boolean value.
1026586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor    if (!ExprResult.isInvalid() && ConvertToBoolean)
1027586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor      ExprResult
10289ae2f076ca5ab1feb3ba95629099ec2319833701John McCall        = Actions.ActOnBooleanCondition(getCurScope(), Loc, ExprResult.get());
102999e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor  }
10301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
103115ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner  // If the parser was confused by the condition and we don't have a ')', try to
103215ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner  // recover by skipping ahead to a semi and bailing out.  If condexp is
103315ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner  // semantically invalid but we have well formed code, keep going.
1034d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  if (ExprResult.isInvalid() && !DeclResult && Tok.isNot(tok::r_paren)) {
103515ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner    SkipUntil(tok::semi);
103615ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner    // Skipping may have stopped if it found the containing ')'.  If so, we can
103715ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner    // continue parsing the if statement.
103815ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner    if (Tok.isNot(tok::r_paren))
103915ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner      return true;
104015ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner  }
10411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
104215ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner  // Otherwise the condition is valid or the rparen is present.
10434a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
1044b660446bcf47bfbcdebaf65a6616c4046579987aChad Rosier
1045bddc7e5ed3982b5845e4fbb5d9bc7b7431c35a4fChris Lattner  // Check for extraneous ')'s to catch things like "if (foo())) {".  We know
1046bddc7e5ed3982b5845e4fbb5d9bc7b7431c35a4fChris Lattner  // that all callers are looking for a statement after the condition, so ")"
1047bddc7e5ed3982b5845e4fbb5d9bc7b7431c35a4fChris Lattner  // isn't valid.
1048bddc7e5ed3982b5845e4fbb5d9bc7b7431c35a4fChris Lattner  while (Tok.is(tok::r_paren)) {
1049bddc7e5ed3982b5845e4fbb5d9bc7b7431c35a4fChris Lattner    Diag(Tok, diag::err_extraneous_rparen_in_condition)
1050bddc7e5ed3982b5845e4fbb5d9bc7b7431c35a4fChris Lattner      << FixItHint::CreateRemoval(Tok.getLocation());
1051bddc7e5ed3982b5845e4fbb5d9bc7b7431c35a4fChris Lattner    ConsumeParen();
1052bddc7e5ed3982b5845e4fbb5d9bc7b7431c35a4fChris Lattner  }
1053b660446bcf47bfbcdebaf65a6616c4046579987aChad Rosier
105415ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner  return false;
105515ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner}
105615ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner
105715ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner
10585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseIfStatement
10595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       if-statement: [C99 6.8.4.1]
10605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'if' '(' expression ')' statement
10615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'if' '(' expression ')' statement 'else' statement
106271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++]   'if' '(' condition ')' statement
106371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++]   'if' '(' condition ')' statement 'else' statement
10645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
1065534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
10664e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  assert(Tok.is(tok::kw_if) && "Not an if stmt!");
10675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation IfLoc = ConsumeToken();  // eat the 'if'.
10685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
10694e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (Tok.isNot(tok::l_paren)) {
10701ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_lparen_after) << "if";
10715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SkipUntil(tok::semi);
107261364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl    return StmtError();
10735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
107471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis
10754e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
1076488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis
10772215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  // C99 6.8.4p3 - In C99, the if statement is a block.  This is not
10782215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  // the case for C90.
1079488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1080488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // C++ 6.4p3:
1081488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // A name introduced by a declaration in a condition is in scope from its
1082488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // point of declaration until the end of the substatements controlled by the
1083488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // condition.
108414d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // C++ 3.3.2p4:
108514d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // Names declared in the for-init-statement, and in the condition of if,
108614d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // while, for, and switch statements are local to the if, while, for, or
108714d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // switch statement (including the controlled statement).
1088488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
10898935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  ParseScope IfScope(this, Scope::DeclScope | Scope::ControlScope, C99orCXX);
10902215325a5696fb3b23551239b900559bb3018ee9Chris Lattner
10915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Parse the condition.
109260d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult CondExp;
10936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  Decl *CondVar = nullptr;
109444aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis  if (ParseParenExprOrCondition(CondExp, CondVar, IfLoc, true))
109515ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner    return StmtError();
109618914bcb22774137ba720e5fcb377150bf2f6de3Chris Lattner
1097def07624ecc535431e0c814b4b5b842de8a06997David Blaikie  FullExprArg FullCondExp(Actions.MakeFullExpr(CondExp.get(), IfLoc));
10981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10990ecea03077117c7ea54c88091a44c73cef67923cChris Lattner  // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
110038484403c8356fb41540ace6c74f28867f28febaChris Lattner  // there is no compound stmt.  C90 does not have this clause.  We only do this
110138484403c8356fb41540ace6c74f28867f28febaChris Lattner  // if the body isn't a compound statement to avoid push/pop in common cases.
1102488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1103488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // C++ 6.4p1:
1104488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // The substatement in a selection-statement (each substatement, in the else
1105488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // form of the if statement) implicitly defines a local scope.
1106488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1107488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // For C++ we create a scope for the condition and a new scope for
1108488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // substatements because:
1109488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // -When the 'then' scope exits, we want the condition declaration to still be
1110488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //    active for the 'else' scope too.
1111488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // -Sema will detect name clashes by considering declarations of a
1112488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //    'ControlScope' as part of its direct subscope.
1113488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // -If we wanted the condition and substatement to be in the same scope, we
1114488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //    would have to notify ParseStatement not to create a new scope. It's
1115488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //    simpler to let it create a new scope.
1116488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1117651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
111871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis
1119b96728d90abc35a520798066d2a75ca36400a617Chris Lattner  // Read the 'then' stmt.
1120b96728d90abc35a520798066d2a75ca36400a617Chris Lattner  SourceLocation ThenStmtLoc = Tok.getLocation();
11215cb94a78202ccb1007df0be86884297761f4a53aNico Weber
11225cb94a78202ccb1007df0be86884297761f4a53aNico Weber  SourceLocation InnerStatementTrailingElseLoc;
11235cb94a78202ccb1007df0be86884297761f4a53aNico Weber  StmtResult ThenStmt(ParseStatement(&InnerStatementTrailingElseLoc));
11245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1125a36ce713cff561b88f1cba5aad3f384c0fb0a249Chris Lattner  // Pop the 'if' scope if needed.
11268935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  InnerScope.Exit();
112761364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
11285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If it has an else, parse it.
11295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation ElseLoc;
1130b96728d90abc35a520798066d2a75ca36400a617Chris Lattner  SourceLocation ElseStmtLoc;
113160d7b3a319d84d688752be3870615ac0f111fb16John McCall  StmtResult ElseStmt;
11320e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
11334e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (Tok.is(tok::kw_else)) {
11345cb94a78202ccb1007df0be86884297761f4a53aNico Weber    if (TrailingElseLoc)
11355cb94a78202ccb1007df0be86884297761f4a53aNico Weber      *TrailingElseLoc = Tok.getLocation();
11365cb94a78202ccb1007df0be86884297761f4a53aNico Weber
11375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ElseLoc = ConsumeToken();
1138966c78b79004061c1f64feff96818b9f1d68ea58Chris Lattner    ElseStmtLoc = Tok.getLocation();
113961364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
11400ecea03077117c7ea54c88091a44c73cef67923cChris Lattner    // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
114138484403c8356fb41540ace6c74f28867f28febaChris Lattner    // there is no compound stmt.  C90 does not have this clause.  We only do
114238484403c8356fb41540ace6c74f28867f28febaChris Lattner    // this if the body isn't a compound statement to avoid push/pop in common
114338484403c8356fb41540ace6c74f28867f28febaChris Lattner    // cases.
1144488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis    //
1145488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis    // C++ 6.4p1:
1146488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis    // The substatement in a selection-statement (each substatement, in the else
1147488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis    // form of the if statement) implicitly defines a local scope.
1148488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis    //
1149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
11500e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
11515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ElseStmt = ParseStatement();
1152a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
1153a36ce713cff561b88f1cba5aad3f384c0fb0a249Chris Lattner    // Pop the 'else' scope if needed.
11548935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor    InnerScope.Exit();
1155d2d8be6a27d0ef73d46039604682f7890e1cc3e0Douglas Gregor  } else if (Tok.is(tok::code_completion)) {
1156d2d8be6a27d0ef73d46039604682f7890e1cc3e0Douglas Gregor    Actions.CodeCompleteAfterIf(getCurScope());
11577d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
11587d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return StmtError();
11595cb94a78202ccb1007df0be86884297761f4a53aNico Weber  } else if (InnerStatementTrailingElseLoc.isValid()) {
11605cb94a78202ccb1007df0be86884297761f4a53aNico Weber    Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else);
11615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
116261364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
11638935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  IfScope.Exit();
11641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1165b96728d90abc35a520798066d2a75ca36400a617Chris Lattner  // If the then or else stmt is invalid and the other is valid (and present),
11661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // make turn the invalid one into a null stmt to avoid dropping the other
1167b96728d90abc35a520798066d2a75ca36400a617Chris Lattner  // part.  If both are invalid, return error.
11680e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl  if ((ThenStmt.isInvalid() && ElseStmt.isInvalid()) ||
11696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      (ThenStmt.isInvalid() && ElseStmt.get() == nullptr) ||
11706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      (ThenStmt.get() == nullptr && ElseStmt.isInvalid())) {
1171a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl    // Both invalid, or one is invalid and other is non-present: return error.
117261364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl    return StmtError();
1173b96728d90abc35a520798066d2a75ca36400a617Chris Lattner  }
11740e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
1175b96728d90abc35a520798066d2a75ca36400a617Chris Lattner  // Now if either are invalid, replace with a ';'.
11760e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl  if (ThenStmt.isInvalid())
1177b96728d90abc35a520798066d2a75ca36400a617Chris Lattner    ThenStmt = Actions.ActOnNullStmt(ThenStmtLoc);
11780e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl  if (ElseStmt.isInvalid())
1179b96728d90abc35a520798066d2a75ca36400a617Chris Lattner    ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);
11800e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
11819ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  return Actions.ActOnIfStmt(IfLoc, FullCondExp, CondVar, ThenStmt.get(),
118244aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis                             ElseLoc, ElseStmt.get());
11835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
11845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
11855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseSwitchStatement
11865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       switch-statement:
11875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'switch' '(' expression ')' statement
118871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++]   'switch' '(' condition ')' statement
1189534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseSwitchStatement(SourceLocation *TrailingElseLoc) {
11904e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  assert(Tok.is(tok::kw_switch) && "Not a switch stmt!");
11915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation SwitchLoc = ConsumeToken();  // eat the 'switch'.
11925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
11934e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (Tok.isNot(tok::l_paren)) {
11941ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_lparen_after) << "switch";
11955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SkipUntil(tok::semi);
11969a920342707e384473b464528d2fd286e8c70353Sebastian Redl    return StmtError();
11975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
11982215325a5696fb3b23551239b900559bb3018ee9Chris Lattner
11994e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
1200488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis
12012215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  // C99 6.8.4p3 - In C99, the switch statement is a block.  This is
12022215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  // not the case for C90.  Start the switch scope.
1203488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1204488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // C++ 6.4p3:
1205488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // A name introduced by a declaration in a condition is in scope from its
1206488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // point of declaration until the end of the substatements controlled by the
1207488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // condition.
120814d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // C++ 3.3.2p4:
120914d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // Names declared in the for-init-statement, and in the condition of if,
121014d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // while, for, and switch statements are local to the if, while, for, or
121114d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // switch statement (including the controlled statement).
1212488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned ScopeFlags = Scope::SwitchScope;
121415ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner  if (C99orCXX)
121515ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner    ScopeFlags |= Scope::DeclScope | Scope::ControlScope;
12168935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  ParseScope SwitchScope(this, ScopeFlags);
12175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
12185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Parse the condition.
121960d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult Cond;
12206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  Decl *CondVar = nullptr;
1221586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor  if (ParseParenExprOrCondition(Cond, CondVar, SwitchLoc, false))
12229a920342707e384473b464528d2fd286e8c70353Sebastian Redl    return StmtError();
12232342ef75797a2ad6c9d7a784cfff220fd1a66008Eli Friedman
122460d7b3a319d84d688752be3870615ac0f111fb16John McCall  StmtResult Switch
12259ae2f076ca5ab1feb3ba95629099ec2319833701John McCall    = Actions.ActOnStartOfSwitchStmt(SwitchLoc, Cond.get(), CondVar);
1226586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor
1227586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor  if (Switch.isInvalid()) {
1228a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi    // Skip the switch body.
1229586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor    // FIXME: This is not optimal recovery, but parsing the body is more
1230586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor    // dangerous due to the presence of case and default statements, which
1231586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor    // will have no place to connect back with the switch.
12324186ff4fc4102f63b7485c2bf89155d3b0899d32Douglas Gregor    if (Tok.is(tok::l_brace)) {
12334186ff4fc4102f63b7485c2bf89155d3b0899d32Douglas Gregor      ConsumeBrace();
12348fe2475a4b4c00475709c13d43eb9a57cce87cbcAlexey Bataev      SkipUntil(tok::r_brace);
12354186ff4fc4102f63b7485c2bf89155d3b0899d32Douglas Gregor    } else
1236586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor      SkipUntil(tok::semi);
12373fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer    return Switch;
1238586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor  }
1239a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
12400ecea03077117c7ea54c88091a44c73cef67923cChris Lattner  // C99 6.8.4p3 - In C99, the body of the switch statement is a scope, even if
124138484403c8356fb41540ace6c74f28867f28febaChris Lattner  // there is no compound stmt.  C90 does not have this clause.  We only do this
124238484403c8356fb41540ace6c74f28867f28febaChris Lattner  // if the body isn't a compound statement to avoid push/pop in common cases.
1243488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1244488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // C++ 6.4p1:
1245488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // The substatement in a selection-statement (each substatement, in the else
1246488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // form of the if statement) implicitly defines a local scope.
1247488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1248488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // See comments in ParseIfStatement for why we create a scope for the
1249488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // condition and a new scope for substatement in C++.
1250488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1251651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  getCurScope()->AddFlags(Scope::BreakScope);
1252651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
125361364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
1254ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  // We have incremented the mangling number for the SwitchScope and the
1255ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  // InnerScope, which is one too many.
1256ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (C99orCXX)
1257ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    getCurScope()->decrementMSLocalManglingNumber();
1258ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
12595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Read the body statement.
12605cb94a78202ccb1007df0be86884297761f4a53aNico Weber  StmtResult Body(ParseStatement(TrailingElseLoc));
12615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
12627e52de4b45286d057b367bb1f9283a1e32d79252Chris Lattner  // Pop the scopes.
12638935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  InnerScope.Exit();
12648935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  SwitchScope.Exit();
126561364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
12669ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.get(), Body.get());
12675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
12685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
12695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseWhileStatement
12705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       while-statement: [C99 6.8.5.1]
12715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'while' '(' expression ')' statement
127271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++]   'while' '(' condition ')' statement
1273534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseWhileStatement(SourceLocation *TrailingElseLoc) {
12744e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  assert(Tok.is(tok::kw_while) && "Not a while stmt!");
12755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation WhileLoc = Tok.getLocation();
12765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ConsumeToken();  // eat the 'while'.
12779a920342707e384473b464528d2fd286e8c70353Sebastian Redl
12784e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (Tok.isNot(tok::l_paren)) {
12791ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_lparen_after) << "while";
12805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SkipUntil(tok::semi);
12819a920342707e384473b464528d2fd286e8c70353Sebastian Redl    return StmtError();
12825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
12839a920342707e384473b464528d2fd286e8c70353Sebastian Redl
12844e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
1285488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis
12862215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  // C99 6.8.5p5 - In C99, the while statement is a block.  This is not
12872215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  // the case for C90.  Start the loop scope.
1288488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1289488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // C++ 6.4p3:
1290488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // A name introduced by a declaration in a condition is in scope from its
1291488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // point of declaration until the end of the substatements controlled by the
1292488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // condition.
129314d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // C++ 3.3.2p4:
129414d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // Names declared in the for-init-statement, and in the condition of if,
129514d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // while, for, and switch statements are local to the if, while, for, or
129614d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // switch statement (including the controlled statement).
1297488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
12988935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  unsigned ScopeFlags;
1299488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  if (C99orCXX)
13008935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor    ScopeFlags = Scope::BreakScope | Scope::ContinueScope |
13018935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor                 Scope::DeclScope  | Scope::ControlScope;
13022215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  else
13038935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor    ScopeFlags = Scope::BreakScope | Scope::ContinueScope;
13048935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  ParseScope WhileScope(this, ScopeFlags);
13055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
13065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Parse the condition.
130760d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult Cond;
13086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  Decl *CondVar = nullptr;
1309586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor  if (ParseParenExprOrCondition(Cond, CondVar, WhileLoc, true))
131015ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner    return StmtError();
13110e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
1312def07624ecc535431e0c814b4b5b842de8a06997David Blaikie  FullExprArg FullCond(Actions.MakeFullExpr(Cond.get(), WhileLoc));
13131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1314651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // C99 6.8.5p5 - In C99, the body of the while statement is a scope, even if
131538484403c8356fb41540ace6c74f28867f28febaChris Lattner  // there is no compound stmt.  C90 does not have this clause.  We only do this
131638484403c8356fb41540ace6c74f28867f28febaChris Lattner  // if the body isn't a compound statement to avoid push/pop in common cases.
1317488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1318488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // C++ 6.5p2:
1319488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // The substatement in an iteration-statement implicitly defines a local scope
1320488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // which is entered and exited each time through the loop.
1321488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1322488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // See comments in ParseIfStatement for why we create a scope for the
1323488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // condition and a new scope for substatement in C++.
1324488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1325651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
13269a920342707e384473b464528d2fd286e8c70353Sebastian Redl
13275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Read the body statement.
13285cb94a78202ccb1007df0be86884297761f4a53aNico Weber  StmtResult Body(ParseStatement(TrailingElseLoc));
13295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
13300ecea03077117c7ea54c88091a44c73cef67923cChris Lattner  // Pop the body scope if needed.
13318935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  InnerScope.Exit();
13328935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  WhileScope.Exit();
13339a920342707e384473b464528d2fd286e8c70353Sebastian Redl
1334d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  if ((Cond.isInvalid() && !CondVar) || Body.isInvalid())
13359a920342707e384473b464528d2fd286e8c70353Sebastian Redl    return StmtError();
13369a920342707e384473b464528d2fd286e8c70353Sebastian Redl
13379ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  return Actions.ActOnWhileStmt(WhileLoc, FullCond, CondVar, Body.get());
13385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
13395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
13405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseDoStatement
13415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       do-statement: [C99 6.8.5.2]
13425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'do' statement 'while' '(' expression ')' ';'
13435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Note: this lets the caller parse the end ';'.
1344534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseDoStatement() {
13454e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  assert(Tok.is(tok::kw_do) && "Not a do stmt!");
13465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation DoLoc = ConsumeToken();  // eat the 'do'.
13479a920342707e384473b464528d2fd286e8c70353Sebastian Redl
13482215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  // C99 6.8.5p5 - In C99, the do statement is a block.  This is not
13492215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  // the case for C90.  Start the loop scope.
13508935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  unsigned ScopeFlags;
13514e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().C99)
13528935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor    ScopeFlags = Scope::BreakScope | Scope::ContinueScope | Scope::DeclScope;
13532215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  else
13548935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor    ScopeFlags = Scope::BreakScope | Scope::ContinueScope;
13559a920342707e384473b464528d2fd286e8c70353Sebastian Redl
13568935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  ParseScope DoScope(this, ScopeFlags);
13575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1358651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // C99 6.8.5p5 - In C99, the body of the do statement is a scope, even if
135938484403c8356fb41540ace6c74f28867f28febaChris Lattner  // there is no compound stmt.  C90 does not have this clause. We only do this
136038484403c8356fb41540ace6c74f28867f28febaChris Lattner  // if the body isn't a compound statement to avoid push/pop in common cases.
1361143db71d8d87bc015fb496f71ef83b268813835aArgyrios Kyrtzidis  //
1362143db71d8d87bc015fb496f71ef83b268813835aArgyrios Kyrtzidis  // C++ 6.5p2:
1363143db71d8d87bc015fb496f71ef83b268813835aArgyrios Kyrtzidis  // The substatement in an iteration-statement implicitly defines a local scope
1364143db71d8d87bc015fb496f71ef83b268813835aArgyrios Kyrtzidis  // which is entered and exited each time through the loop.
1365143db71d8d87bc015fb496f71ef83b268813835aArgyrios Kyrtzidis  //
1366651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
1367651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
13689a920342707e384473b464528d2fd286e8c70353Sebastian Redl
13695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Read the body statement.
137060d7b3a319d84d688752be3870615ac0f111fb16John McCall  StmtResult Body(ParseStatement());
13715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
13720ecea03077117c7ea54c88091a44c73cef67923cChris Lattner  // Pop the body scope if needed.
13738935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  InnerScope.Exit();
13740ecea03077117c7ea54c88091a44c73cef67923cChris Lattner
13754e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (Tok.isNot(tok::kw_while)) {
13760e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl    if (!Body.isInvalid()) {
1377195044028b76133e2a1f245b094468fe07db7330Chris Lattner      Diag(Tok, diag::err_expected_while);
1378651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Diag(DoLoc, diag::note_matching) << "'do'";
13798fe2475a4b4c00475709c13d43eb9a57cce87cbcAlexey Bataev      SkipUntil(tok::semi, StopBeforeMatch);
1380195044028b76133e2a1f245b094468fe07db7330Chris Lattner    }
13819a920342707e384473b464528d2fd286e8c70353Sebastian Redl    return StmtError();
13825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
13835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation WhileLoc = ConsumeToken();
13849a920342707e384473b464528d2fd286e8c70353Sebastian Redl
13854e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (Tok.isNot(tok::l_paren)) {
13861ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_lparen_after) << "do/while";
13878fe2475a4b4c00475709c13d43eb9a57cce87cbcAlexey Bataev    SkipUntil(tok::semi, StopBeforeMatch);
13889a920342707e384473b464528d2fd286e8c70353Sebastian Redl    return StmtError();
13895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
13909a920342707e384473b464528d2fd286e8c70353Sebastian Redl
13915eed7e00b4ac8d589ca83e126dafa8767e8a0358Richard Smith  // Parse the parenthesized expression.
13924a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_paren);
13934a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeOpen();
1394b660446bcf47bfbcdebaf65a6616c4046579987aChad Rosier
13955eed7e00b4ac8d589ca83e126dafa8767e8a0358Richard Smith  // A do-while expression is not a condition, so can't have attributes.
13965eed7e00b4ac8d589ca83e126dafa8767e8a0358Richard Smith  DiagnoseAndSkipCXX11Attributes();
13972edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt
139860d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult Cond = ParseExpression();
13994a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
14008935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  DoScope.Exit();
14010e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
14029a920342707e384473b464528d2fd286e8c70353Sebastian Redl  if (Cond.isInvalid() || Body.isInvalid())
14039a920342707e384473b464528d2fd286e8c70353Sebastian Redl    return StmtError();
14040e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
14054a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  return Actions.ActOnDoStmt(DoLoc, Body.get(), WhileLoc, T.getOpenLocation(),
14064a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                             Cond.get(), T.getCloseLocation());
14075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
14085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1409ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesbool Parser::isForRangeIdentifier() {
1410ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  assert(Tok.is(tok::identifier));
1411ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
1412ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  const Token &Next = NextToken();
1413ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (Next.is(tok::colon))
1414ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return true;
1415ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
1416ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (Next.is(tok::l_square) || Next.is(tok::kw_alignas)) {
1417ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    TentativeParsingAction PA(*this);
1418ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    ConsumeToken();
1419ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    SkipCXX11Attributes();
1420ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    bool Result = Tok.is(tok::colon);
1421ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    PA.Revert();
1422ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return Result;
1423ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  }
1424ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
1425ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return false;
1426ef8225444452a1486bd721f3285301fe84643b00Stephen Hines}
1427ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
14285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseForStatement
14295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       for-statement: [C99 6.8.5.3]
14305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'for' '(' expr[opt] ';' expr[opt] ';' expr[opt] ')' statement
14315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'for' '(' declaration expr[opt] ';' expr[opt] ')' statement
143271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++]   'for' '(' for-init-statement condition[opt] ';' expression[opt] ')'
143371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++]       statement
1434ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith/// [C++0x] 'for' '(' for-range-declaration : for-range-initializer ) statement
14353ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian/// [OBJC2] 'for' '(' declaration 'in' expr ')' statement
14363ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian/// [OBJC2] 'for' '(' expr 'in' expr ')' statement
143771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis///
143871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++] for-init-statement:
143971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++]   expression-statement
144071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++]   simple-declaration
144171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis///
1442ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith/// [C++0x] for-range-declaration:
1443ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith/// [C++0x]   attribute-specifier-seq[opt] type-specifier-seq declarator
1444ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith/// [C++0x] for-range-initializer:
1445ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith/// [C++0x]   expression
1446ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith/// [C++0x]   braced-init-list            [TODO]
1447534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
14484e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  assert(Tok.is(tok::kw_for) && "Not a for stmt!");
14495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation ForLoc = ConsumeToken();  // eat the 'for'.
14509a920342707e384473b464528d2fd286e8c70353Sebastian Redl
14514e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (Tok.isNot(tok::l_paren)) {
14521ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_lparen_after) << "for";
14535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SkipUntil(tok::semi);
14549a920342707e384473b464528d2fd286e8c70353Sebastian Redl    return StmtError();
14555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
14569a920342707e384473b464528d2fd286e8c70353Sebastian Redl
1457b660446bcf47bfbcdebaf65a6616c4046579987aChad Rosier  bool C99orCXXorObjC = getLangOpts().C99 || getLangOpts().CPlusPlus ||
1458b660446bcf47bfbcdebaf65a6616c4046579987aChad Rosier    getLangOpts().ObjC1;
1459488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis
14602215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  // C99 6.8.5p5 - In C99, the for statement is a block.  This is not
14612215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  // the case for C90.  Start the loop scope.
1462488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1463488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // C++ 6.4p3:
1464488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // A name introduced by a declaration in a condition is in scope from its
1465488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // point of declaration until the end of the substatements controlled by the
1466488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // condition.
146714d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // C++ 3.3.2p4:
146814d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // Names declared in the for-init-statement, and in the condition of if,
146914d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // while, for, and switch statements are local to the if, while, for, or
147014d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // switch statement (including the controlled statement).
1471488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // C++ 6.5.3p1:
1472488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // Names declared in the for-init-statement are in the same declarative-region
1473488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // as those declared in the condition.
1474488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1475651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned ScopeFlags = 0;
14764d00f2a5a9b670cd0d67d640a42dbf7b9f342c59Chris Lattner  if (C99orCXXorObjC)
1477651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ScopeFlags = Scope::DeclScope | Scope::ControlScope;
14788935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor
14798935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  ParseScope ForScope(this, ScopeFlags);
14805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
14814a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_paren);
14824a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeOpen();
14834a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor
148460d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult Value;
14850e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
1486ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  bool ForEach = false, ForRange = false;
148760d7b3a319d84d688752be3870615ac0f111fb16John McCall  StmtResult FirstPart;
1488eecf38f821fe8e113722096b77da7d68b26d28d1Douglas Gregor  bool SecondPartIsInvalid = false;
1489586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor  FullExprArg SecondPart(Actions);
149060d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult Collection;
1491ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  ForRangeInit ForRangeInit;
1492586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor  FullExprArg ThirdPart(Actions);
14936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  Decl *SecondVar = nullptr;
1494a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
1495791215b7a24666912c0b71175d2ca5ba082f666eDouglas Gregor  if (Tok.is(tok::code_completion)) {
1496a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi    Actions.CodeCompleteOrdinaryName(getCurScope(),
1497f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                     C99orCXXorObjC? Sema::PCC_ForInit
1498f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                                   : Sema::PCC_Expression);
14997d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
15007d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return StmtError();
1501791215b7a24666912c0b71175d2ca5ba082f666eDouglas Gregor  }
1502a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
15032edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt  ParsedAttributesWithRange attrs(AttrFactory);
15044e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith  MaybeParseCXX11Attributes(attrs);
15052edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt
15065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Parse the first part of the for specifier.
15074e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (Tok.is(tok::semi)) {  // for (;
15082edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt    ProhibitAttributes(attrs);
15095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // no first part, eat the ';'.
15105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ConsumeToken();
1511ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  } else if (getLangOpts().CPlusPlus && Tok.is(tok::identifier) &&
1512ef8225444452a1486bd721f3285301fe84643b00Stephen Hines             isForRangeIdentifier()) {
1513ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    ProhibitAttributes(attrs);
1514ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    IdentifierInfo *Name = Tok.getIdentifierInfo();
1515ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    SourceLocation Loc = ConsumeToken();
1516ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    MaybeParseCXX11Attributes(attrs);
1517ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
1518ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    ForRangeInit.ColonLoc = ConsumeToken();
1519ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    if (Tok.is(tok::l_brace))
1520ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      ForRangeInit.RangeExpr = ParseBraceInitializer();
1521ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    else
1522ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      ForRangeInit.RangeExpr = ParseExpression();
1523ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
1524ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    Diag(Loc, getLangOpts().CPlusPlus1z
1525ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                  ? diag::warn_cxx1y_compat_for_range_identifier
1526ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                  : diag::ext_for_range_identifier)
1527ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      << ((getLangOpts().CPlusPlus11 && !getLangOpts().CPlusPlus1z)
1528ef8225444452a1486bd721f3285301fe84643b00Stephen Hines              ? FixItHint::CreateInsertion(Loc, "auto &&")
1529ef8225444452a1486bd721f3285301fe84643b00Stephen Hines              : FixItHint());
1530ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
1531ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    FirstPart = Actions.ActOnCXXForRangeIdentifier(getCurScope(), Loc, Name,
1532ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                                                   attrs, attrs.Range.getEnd());
1533ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    ForRange = true;
15349490ab433deef70105d817616928d700f87642d9Eli Friedman  } else if (isForInitDeclaration()) {  // for (int X = 4;
15355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Parse declaration, which eats the ';'.
15364d00f2a5a9b670cd0d67d640a42dbf7b9f342c59Chris Lattner    if (!C99orCXXorObjC)   // Use of C99-style for loops in C90 mode?
15375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
15389a920342707e384473b464528d2fd286e8c70353Sebastian Redl
1539ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    // In C++0x, "for (T NS:a" might not be a typo for ::
15404e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    bool MightBeForRangeStmt = getLangOpts().CPlusPlus;
1541ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    ColonProtectionRAIIObject ColonProtection(*this, MightBeForRangeStmt);
1542ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
154397144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
15444e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer    StmtVector Stmts;
15456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    DeclGroupPtrTy DG = ParseSimpleDeclaration(
15466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        Stmts, Declarator::ForContext, DeclEnd, attrs, false,
15476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        MightBeForRangeStmt ? &ForRangeInit : nullptr);
1548cd1477562e7cf03279850885583d615e1f631dd4Chris Lattner    FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
1549ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    if (ForRangeInit.ParsedForRangeDecl()) {
155080ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith      Diag(ForRangeInit.ColonLoc, getLangOpts().CPlusPlus11 ?
15517fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith           diag::warn_cxx98_compat_for_range : diag::ext_for_range);
15528f4fb190852d3f86787c7e2c3dfc1b96143197aeRichard Smith
1553ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith      ForRange = true;
1554ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    } else if (Tok.is(tok::semi)) {  // for (int x = 4;
1555cd1477562e7cf03279850885583d615e1f631dd4Chris Lattner      ConsumeToken();
1556cd1477562e7cf03279850885583d615e1f631dd4Chris Lattner    } else if ((ForEach = isTokIdentifier_in())) {
1557a7cf23a72b0846fc5aacf3f38bb8c8f9e76784cfFariborz Jahanian      Actions.ActOnForEachDeclStmt(DG);
15581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      // ObjC: for (id x in expr)
15593ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian      ConsumeToken(); // consume 'in'
1560a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
1561fb6294123b9de1605adae69d85cb4fddf81a9bc5Douglas Gregor      if (Tok.is(tok::code_completion)) {
1562fb6294123b9de1605adae69d85cb4fddf81a9bc5Douglas Gregor        Actions.CodeCompleteObjCForCollection(getCurScope(), DG);
15637d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis        cutOffParsing();
15647d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis        return StmtError();
1565fb6294123b9de1605adae69d85cb4fddf81a9bc5Douglas Gregor      }
1566586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor      Collection = ParseExpression();
1567cd1477562e7cf03279850885583d615e1f631dd4Chris Lattner    } else {
1568cd1477562e7cf03279850885583d615e1f631dd4Chris Lattner      Diag(Tok, diag::err_expected_semi_for);
15693ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian    }
15705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  } else {
15712edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt    ProhibitAttributes(attrs);
15725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Value = ParseExpression();
15735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1574f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    ForEach = isTokIdentifier_in();
1575f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall
15765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Turn the expression into a stmt.
1577f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    if (!Value.isInvalid()) {
1578f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall      if (ForEach)
1579f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall        FirstPart = Actions.ActOnForEachLValueExpr(Value.get());
1580f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall      else
1581419563768ef4929a622d7c2b066856e82901bb91Richard Smith        FirstPart = Actions.ActOnExprStmt(Value);
1582f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    }
1583effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl
15844e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner    if (Tok.is(tok::semi)) {
15855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      ConsumeToken();
1586f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    } else if (ForEach) {
15873ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian      ConsumeToken(); // consume 'in'
1588a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
1589fb6294123b9de1605adae69d85cb4fddf81a9bc5Douglas Gregor      if (Tok.is(tok::code_completion)) {
1590fb6294123b9de1605adae69d85cb4fddf81a9bc5Douglas Gregor        Actions.CodeCompleteObjCForCollection(getCurScope(), DeclGroupPtrTy());
15917d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis        cutOffParsing();
15927d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis        return StmtError();
1593fb6294123b9de1605adae69d85cb4fddf81a9bc5Douglas Gregor      }
1594586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor      Collection = ParseExpression();
159580ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith    } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::colon) && FirstPart.get()) {
1596a44854a23b3f090729d82f447aa88df4f6563263Richard Smith      // User tried to write the reasonable, but ill-formed, for-range-statement
1597a44854a23b3f090729d82f447aa88df4f6563263Richard Smith      //   for (expr : expr) { ... }
1598a44854a23b3f090729d82f447aa88df4f6563263Richard Smith      Diag(Tok, diag::err_for_range_expected_decl)
1599a44854a23b3f090729d82f447aa88df4f6563263Richard Smith        << FirstPart.get()->getSourceRange();
16008fe2475a4b4c00475709c13d43eb9a57cce87cbcAlexey Bataev      SkipUntil(tok::r_paren, StopBeforeMatch);
1601a44854a23b3f090729d82f447aa88df4f6563263Richard Smith      SecondPartIsInvalid = true;
1602682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    } else {
1603b72c77855473379c4c47e701005f7818946f659bDouglas Gregor      if (!Value.isInvalid()) {
1604b72c77855473379c4c47e701005f7818946f659bDouglas Gregor        Diag(Tok, diag::err_expected_semi_for);
1605b72c77855473379c4c47e701005f7818946f659bDouglas Gregor      } else {
1606b72c77855473379c4c47e701005f7818946f659bDouglas Gregor        // Skip until semicolon or rparen, don't consume it.
16078fe2475a4b4c00475709c13d43eb9a57cce87cbcAlexey Bataev        SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch);
1608b72c77855473379c4c47e701005f7818946f659bDouglas Gregor        if (Tok.is(tok::semi))
1609b72c77855473379c4c47e701005f7818946f659bDouglas Gregor          ConsumeToken();
1610b72c77855473379c4c47e701005f7818946f659bDouglas Gregor      }
16115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
16125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1613651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1614651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Parse the second part of the for specifier.
1615651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  getCurScope()->AddFlags(Scope::BreakScope | Scope::ContinueScope);
1616ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  if (!ForEach && !ForRange) {
16179ae2f076ca5ab1feb3ba95629099ec2319833701John McCall    assert(!SecondPart.get() && "Shouldn't have a second expression yet.");
16183ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian    // Parse the second part of the for specifier.
16193ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian    if (Tok.is(tok::semi)) {  // for (...;;
16203ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian      // no second part.
1621b72c77855473379c4c47e701005f7818946f659bDouglas Gregor    } else if (Tok.is(tok::r_paren)) {
1622b72c77855473379c4c47e701005f7818946f659bDouglas Gregor      // missing both semicolons.
16233ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian    } else {
162460d7b3a319d84d688752be3870615ac0f111fb16John McCall      ExprResult Second;
16254e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie      if (getLangOpts().CPlusPlus)
1626586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor        ParseCXXCondition(Second, SecondVar, ForLoc, true);
1627586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor      else {
1628586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor        Second = ParseExpression();
1629586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor        if (!Second.isInvalid())
1630a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi          Second = Actions.ActOnBooleanCondition(getCurScope(), ForLoc,
16319ae2f076ca5ab1feb3ba95629099ec2319833701John McCall                                                 Second.get());
1632586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor      }
1633eecf38f821fe8e113722096b77da7d68b26d28d1Douglas Gregor      SecondPartIsInvalid = Second.isInvalid();
1634def07624ecc535431e0c814b4b5b842de8a06997David Blaikie      SecondPart = Actions.MakeFullExpr(Second.get(), ForLoc);
16353ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian    }
16360e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
1637b72c77855473379c4c47e701005f7818946f659bDouglas Gregor    if (Tok.isNot(tok::semi)) {
1638b72c77855473379c4c47e701005f7818946f659bDouglas Gregor      if (!SecondPartIsInvalid || SecondVar)
1639b72c77855473379c4c47e701005f7818946f659bDouglas Gregor        Diag(Tok, diag::err_expected_semi_for);
1640b72c77855473379c4c47e701005f7818946f659bDouglas Gregor      else
1641b72c77855473379c4c47e701005f7818946f659bDouglas Gregor        // Skip until semicolon or rparen, don't consume it.
16428fe2475a4b4c00475709c13d43eb9a57cce87cbcAlexey Bataev        SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch);
1643b72c77855473379c4c47e701005f7818946f659bDouglas Gregor    }
1644b72c77855473379c4c47e701005f7818946f659bDouglas Gregor
16453ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian    if (Tok.is(tok::semi)) {
16463ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian      ConsumeToken();
16473ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian    }
16489a920342707e384473b464528d2fd286e8c70353Sebastian Redl
16493ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian    // Parse the third part of the for specifier.
1650586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor    if (Tok.isNot(tok::r_paren)) {   // for (...;...;)
165160d7b3a319d84d688752be3870615ac0f111fb16John McCall      ExprResult Third = ParseExpression();
1652419563768ef4929a622d7c2b066856e82901bb91Richard Smith      // FIXME: The C++11 standard doesn't actually say that this is a
1653419563768ef4929a622d7c2b066856e82901bb91Richard Smith      // discarded-value expression, but it clearly should be.
1654ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      ThirdPart = Actions.MakeFullDiscardedValueExpr(Third.get());
1655586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor    }
16565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
16575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Match the ')'.
16584a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
16590e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
1660ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // We need to perform most of the semantic analysis for a C++0x for-range
1661ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // statememt before parsing the body, in order to be able to deduce the type
1662ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // of an auto-typed loop variable.
1663ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  StmtResult ForRangeStmt;
1664a1eec4bd198b96ef40a7c15cd0e131ca94511ad8Fariborz Jahanian  StmtResult ForEachStmt;
1665b660446bcf47bfbcdebaf65a6616c4046579987aChad Rosier
1666990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  if (ForRange) {
1667ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    ForRangeStmt = Actions.ActOnCXXForRangeStmt(ForLoc, FirstPart.get(),
1668ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith                                                ForRangeInit.ColonLoc,
1669ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith                                                ForRangeInit.RangeExpr.get(),
16708b533d97e0683a0c87096b95927a2e9ce02243d4Richard Smith                                                T.getCloseLocation(),
16718b533d97e0683a0c87096b95927a2e9ce02243d4Richard Smith                                                Sema::BFRK_Build);
1672ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
1673990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall
1674990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  // Similarly, we need to do the semantic analysis for a for-range
1675990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  // statement immediately in order to close over temporaries correctly.
1676990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  } else if (ForEach) {
1677bc20bbb0bf90446a469848c658ca376832f43dc8Sam Panzer    ForEachStmt = Actions.ActOnObjCForCollectionStmt(ForLoc,
1678ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                                                     FirstPart.get(),
1679ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                                                     Collection.get(),
1680a1eec4bd198b96ef40a7c15cd0e131ca94511ad8Fariborz Jahanian                                                     T.getCloseLocation());
1681990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  }
1682990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall
1683651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // C99 6.8.5p5 - In C99, the body of the for statement is a scope, even if
168438484403c8356fb41540ace6c74f28867f28febaChris Lattner  // there is no compound stmt.  C90 does not have this clause.  We only do this
168538484403c8356fb41540ace6c74f28867f28febaChris Lattner  // if the body isn't a compound statement to avoid push/pop in common cases.
1686488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1687488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // C++ 6.5p2:
1688488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // The substatement in an iteration-statement implicitly defines a local scope
1689488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // which is entered and exited each time through the loop.
1690488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1691488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // See comments in ParseIfStatement for why we create a scope for
1692488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // for-init-statement/condition and a new scope for substatement in C++.
1693488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1694651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ParseScope InnerScope(this, Scope::DeclScope, C99orCXXorObjC,
1695651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                        Tok.is(tok::l_brace));
1696651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1697651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // The body of the for loop has the same local mangling number as the
1698651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // for-init-statement.
1699651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // It will only be incremented if the body contains other things that would
1700651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // normally increment the mangling number (like a compound statement).
1701651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (C99orCXXorObjC)
1702651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    getCurScope()->decrementMSLocalManglingNumber();
17030e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
17045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Read the body statement.
17055cb94a78202ccb1007df0be86884297761f4a53aNico Weber  StmtResult Body(ParseStatement(TrailingElseLoc));
17060e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
17070ecea03077117c7ea54c88091a44c73cef67923cChris Lattner  // Pop the body scope if needed.
17088935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  InnerScope.Exit();
17090ecea03077117c7ea54c88091a44c73cef67923cChris Lattner
17105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Leave the for-scope.
17118935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  ForScope.Exit();
17120e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
17130e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl  if (Body.isInvalid())
17149a920342707e384473b464528d2fd286e8c70353Sebastian Redl    return StmtError();
1715effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl
1716ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  if (ForEach)
1717ef8225444452a1486bd721f3285301fe84643b00Stephen Hines   return Actions.FinishObjCForCollectionStmt(ForEachStmt.get(),
1718ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                                              Body.get());
1719ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
1720ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  if (ForRange)
1721ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return Actions.FinishCXXForRangeStmt(ForRangeStmt.get(), Body.get());
1722586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor
1723ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return Actions.ActOnForStmt(ForLoc, T.getOpenLocation(), FirstPart.get(),
17244a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                              SecondPart, SecondVar, ThirdPart,
1725ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                              T.getCloseLocation(), Body.get());
17265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
17275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
17285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseGotoStatement
17295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       jump-statement:
17305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'goto' identifier ';'
17315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU]   'goto' '*' expression ';'
17325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
17335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Note: this lets the caller parse the end ';'.
17345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
1735534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseGotoStatement() {
17364e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");
17375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation GotoLoc = ConsumeToken();  // eat the 'goto'.
17389a920342707e384473b464528d2fd286e8c70353Sebastian Redl
173960d7b3a319d84d688752be3870615ac0f111fb16John McCall  StmtResult Res;
17404e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (Tok.is(tok::identifier)) {
1741337e550218128e7d922c09bb354fbc71de90c568Chris Lattner    LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(),
1742337e550218128e7d922c09bb354fbc71de90c568Chris Lattner                                                Tok.getLocation());
1743337e550218128e7d922c09bb354fbc71de90c568Chris Lattner    Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(), LD);
17445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ConsumeToken();
1745f01fdff97b245caac98100d232c760b4d0531411Eli Friedman  } else if (Tok.is(tok::star)) {
17465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // GNU indirect goto extension.
17475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Diag(Tok, diag::ext_gnu_indirect_goto);
17485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SourceLocation StarLoc = ConsumeToken();
174960d7b3a319d84d688752be3870615ac0f111fb16John McCall    ExprResult R(ParseExpression());
17500e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl    if (R.isInvalid()) {  // Skip to the semicolon, but don't consume it.
17518fe2475a4b4c00475709c13d43eb9a57cce87cbcAlexey Bataev      SkipUntil(tok::semi, StopBeforeMatch);
17529a920342707e384473b464528d2fd286e8c70353Sebastian Redl      return StmtError();
17535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
1754ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.get());
175595cfb85ad1820117e0864712555f3aa4fdf4721aChris Lattner  } else {
1756651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Diag(Tok, diag::err_expected) << tok::identifier;
17579a920342707e384473b464528d2fd286e8c70353Sebastian Redl    return StmtError();
17585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
17590e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
17603fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer  return Res;
17615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
17625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
17635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseContinueStatement
17645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       jump-statement:
17655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'continue' ';'
17665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
17675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Note: this lets the caller parse the end ';'.
17685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
1769534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseContinueStatement() {
17705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation ContinueLoc = ConsumeToken();  // eat the 'continue'.
177123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  return Actions.ActOnContinueStmt(ContinueLoc, getCurScope());
17725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
17735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
17745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseBreakStatement
17755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       jump-statement:
17765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'break' ';'
17775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
17785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Note: this lets the caller parse the end ';'.
17795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
1780534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseBreakStatement() {
17815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation BreakLoc = ConsumeToken();  // eat the 'break'.
178223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  return Actions.ActOnBreakStmt(BreakLoc, getCurScope());
17835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
17845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
17855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseReturnStatement
17865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       jump-statement:
17875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'return' expression[opt] ';'
1788534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseReturnStatement() {
17894e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  assert(Tok.is(tok::kw_return) && "Not a return stmt!");
17905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation ReturnLoc = ConsumeToken();  // eat the 'return'.
17919a920342707e384473b464528d2fd286e8c70353Sebastian Redl
179260d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult R;
17934e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (Tok.isNot(tok::semi)) {
17945ac3bdb2cb0113b640c54f01468d21985c08b252Douglas Gregor    if (Tok.is(tok::code_completion)) {
179523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      Actions.CodeCompleteReturn(getCurScope());
17967d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      cutOffParsing();
17975ac3bdb2cb0113b640c54f01468d21985c08b252Douglas Gregor      return StmtError();
17985ac3bdb2cb0113b640c54f01468d21985c08b252Douglas Gregor    }
1799a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
18004e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (Tok.is(tok::l_brace) && getLangOpts().CPlusPlus) {
18016f4596cfb70ec706dd2da38db1be3663c214ff7aDouglas Gregor      R = ParseInitializer();
18027fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith      if (R.isUsable())
180380ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith        Diag(R.get()->getLocStart(), getLangOpts().CPlusPlus11 ?
18047fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith             diag::warn_cxx98_compat_generalized_initializer_lists :
18057fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith             diag::ext_generalized_initializer_lists)
18066f4596cfb70ec706dd2da38db1be3663c214ff7aDouglas Gregor          << R.get()->getSourceRange();
18076f4596cfb70ec706dd2da38db1be3663c214ff7aDouglas Gregor    } else
18086f4596cfb70ec706dd2da38db1be3663c214ff7aDouglas Gregor        R = ParseExpression();
1809651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (R.isInvalid()) {
1810651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
18119a920342707e384473b464528d2fd286e8c70353Sebastian Redl      return StmtError();
18125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
18135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1814ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return Actions.ActOnReturnStmt(ReturnLoc, R.get(), getCurScope());
1815d62701bc5321049353017e9abf1963edd57646aaSteve Naroff}
1816d62701bc5321049353017e9abf1963edd57646aaSteve Naroff
1817ef8225444452a1486bd721f3285301fe84643b00Stephen HinesStmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts, bool OnlyStatement,
1818ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                                       SourceLocation *TrailingElseLoc,
1819ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                                       ParsedAttributesWithRange &Attrs) {
1820ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  // Create temporary attribute list.
1821ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  ParsedAttributesWithRange TempAttrs(AttrFactory);
18229a920342707e384473b464528d2fd286e8c70353Sebastian Redl
1823ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  // Get vectorize hints and consume annotated token.
1824ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  while (Tok.is(tok::annot_pragma_loop_hint)) {
1825ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    LoopHint Hint = HandlePragmaLoopHint();
182664cb4757acbf10f0c702f17c4fe90f4b7aba3490Chris Lattner    ConsumeToken();
1827a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
1828ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    if (!Hint.LoopLoc || !Hint.OptionLoc || !Hint.ValueLoc)
1829ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      continue;
1830effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl
1831ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    ArgsUnion ArgHints[] = {Hint.OptionLoc, Hint.ValueLoc,
1832ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                            ArgsUnion(Hint.ValueExpr)};
1833ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    TempAttrs.addNew(Hint.LoopLoc->Ident, Hint.Range, nullptr,
1834ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                     Hint.LoopLoc->Loc, ArgHints, 3, AttributeList::AS_Pragma);
1835dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson  }
1836effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl
1837ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  // Get the next statement.
1838ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  MaybeParseCXX11Attributes(Attrs);
18390e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
1840ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  StmtResult S = ParseStatementOrDeclarationAfterAttributes(
1841ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      Stmts, OnlyStatement, TrailingElseLoc, Attrs);
18425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1843ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  Attrs.takeAllFrom(TempAttrs);
1844ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return S;
18455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1846f9ed3157c93495474003a5ec360039030fd42e9cFariborz Jahanian
1847c9977d09a2de7f7d2245973413d4caf86c736640Douglas GregorDecl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) {
184840e9bc84a2ab49fc33c2b1a95c6674ab2b820e9eChris Lattner  assert(Tok.is(tok::l_brace));
184940e9bc84a2ab49fc33c2b1a95c6674ab2b820e9eChris Lattner  SourceLocation LBraceLoc = Tok.getLocation();
1850d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl
18511f12c47ae90c03633496d96e79a61762097a4681Argyrios Kyrtzidis  if (SkipFunctionBodies && (!Decl || Actions.canSkipFunctionBody(Decl)) &&
18521a5bd5d680726f3d133da27791b228b2c8fe96c6Richard Smith      trySkippingFunctionBody()) {
18536a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen    BodyScope.Exit();
185435f3f36cb9451f347b83a6e7f01e3c702df4732dArgyrios Kyrtzidis    return Actions.ActOnSkippedFunctionBody(Decl);
1855c9977d09a2de7f7d2245973413d4caf86c736640Douglas Gregor  }
1856a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
1857f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  PrettyDeclStackTraceEntry CrashInfo(Actions, Decl, LBraceLoc,
1858f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                      "parsing function body");
18591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1860f9ed3157c93495474003a5ec360039030fd42e9cFariborz Jahanian  // Do not enter a scope for the brace, as the arguments are in the same scope
1861f9ed3157c93495474003a5ec360039030fd42e9cFariborz Jahanian  // (the function body) as the body itself.  Instead, just read the statement
1862f9ed3157c93495474003a5ec360039030fd42e9cFariborz Jahanian  // list and put it into a CompoundStmt for safe keeping.
186360d7b3a319d84d688752be3870615ac0f111fb16John McCall  StmtResult FnBody(ParseCompoundStatementBody());
186461364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
1865f9ed3157c93495474003a5ec360039030fd42e9cFariborz Jahanian  // If the function body could not be parsed, make a bogus compoundstmt.
1866625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  if (FnBody.isInvalid()) {
1867625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko    Sema::CompoundScopeRAII CompoundScope(Actions);
1868c895f4d411152b08365cac48f330a8a7898fb382Robert Wilhelm    FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, None, false);
1869625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  }
187061364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
1871c9977d09a2de7f7d2245973413d4caf86c736640Douglas Gregor  BodyScope.Exit();
1872ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
1873cd5af4b5863c63b62cde96ad6d52fb1eec0e26bbSeo Sanghyeon}
1874a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
1875d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl/// ParseFunctionTryBlock - Parse a C++ function-try-block.
1876d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///
1877d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///       function-try-block:
1878d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///         'try' ctor-initializer[opt] compound-statement handler-seq
1879d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///
1880c9977d09a2de7f7d2245973413d4caf86c736640Douglas GregorDecl *Parser::ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope) {
1881d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  assert(Tok.is(tok::kw_try) && "Expected 'try'");
1882d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  SourceLocation TryLoc = ConsumeToken();
1883d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl
1884f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  PrettyDeclStackTraceEntry CrashInfo(Actions, Decl, TryLoc,
1885f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                      "parsing function try block");
1886d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl
1887d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  // Constructor initializer list?
1888d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  if (Tok.is(tok::colon))
1889d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl    ParseConstructorInitializer(Decl);
18902eef427c8666cbe9a3cad40d4947c67c3ba0c400Douglas Gregor  else
18912eef427c8666cbe9a3cad40d4947c67c3ba0c400Douglas Gregor    Actions.ActOnDefaultCtorInitializers(Decl);
1892a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
18931a5bd5d680726f3d133da27791b228b2c8fe96c6Richard Smith  if (SkipFunctionBodies && Actions.canSkipFunctionBody(Decl) &&
18941a5bd5d680726f3d133da27791b228b2c8fe96c6Richard Smith      trySkippingFunctionBody()) {
18956a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen    BodyScope.Exit();
189635f3f36cb9451f347b83a6e7f01e3c702df4732dArgyrios Kyrtzidis    return Actions.ActOnSkippedFunctionBody(Decl);
1897c9977d09a2de7f7d2245973413d4caf86c736640Douglas Gregor  }
18980fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis
1899de1b60a9868f80f0872ed05d78df3b40a10ba5caSebastian Redl  SourceLocation LBraceLoc = Tok.getLocation();
1900c4027c82ad4a61f2da1b893ac8fe47bf11e5d50dDavid Blaikie  StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc, /*FnTry*/true));
1901d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  // If we failed to parse the try-catch, we just give the function an empty
1902d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  // compound statement as the body.
1903625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  if (FnBody.isInvalid()) {
1904625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko    Sema::CompoundScopeRAII CompoundScope(Actions);
1905c895f4d411152b08365cac48f330a8a7898fb382Robert Wilhelm    FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, None, false);
1906625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  }
1907d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl
1908c9977d09a2de7f7d2245973413d4caf86c736640Douglas Gregor  BodyScope.Exit();
1909ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
1910d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl}
1911d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl
19126a91d385618ea4d28236c496f540a26877c95525Erik Verbruggenbool Parser::trySkippingFunctionBody() {
19130fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis  assert(Tok.is(tok::l_brace));
19146a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen  assert(SkipFunctionBodies &&
19156a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen         "Should only be called when SkipFunctionBodies is enabled");
19160fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis
191781939a752bfb4adbe302e2872271be195e2eacb2Argyrios Kyrtzidis  if (!PP.isCodeCompletionEnabled()) {
191881939a752bfb4adbe302e2872271be195e2eacb2Argyrios Kyrtzidis    ConsumeBrace();
19198fe2475a4b4c00475709c13d43eb9a57cce87cbcAlexey Bataev    SkipUntil(tok::r_brace);
192081939a752bfb4adbe302e2872271be195e2eacb2Argyrios Kyrtzidis    return true;
192181939a752bfb4adbe302e2872271be195e2eacb2Argyrios Kyrtzidis  }
192281939a752bfb4adbe302e2872271be195e2eacb2Argyrios Kyrtzidis
19230fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis  // We're in code-completion mode. Skip parsing for all function bodies unless
19240fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis  // the body contains the code-completion point.
19250fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis  TentativeParsingAction PA(*this);
19260fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis  ConsumeBrace();
19278fe2475a4b4c00475709c13d43eb9a57cce87cbcAlexey Bataev  if (SkipUntil(tok::r_brace, StopAtCodeCompletion)) {
19280fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis    PA.Commit();
19290fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis    return true;
19300fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis  }
19310fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis
19320fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis  PA.Revert();
19330fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis  return false;
19340fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis}
19350fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis
1936a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl/// ParseCXXTryBlock - Parse a C++ try-block.
1937a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl///
1938a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl///       try-block:
1939a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl///         'try' compound-statement handler-seq
1940a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl///
1941534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseCXXTryBlock() {
1942a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  assert(Tok.is(tok::kw_try) && "Expected 'try'");
1943a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
1944a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  SourceLocation TryLoc = ConsumeToken();
1945d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  return ParseCXXTryBlockCommon(TryLoc);
1946d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl}
1947d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl
1948d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl/// ParseCXXTryBlockCommon - Parse the common part of try-block and
1949d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl/// function-try-block.
1950d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///
1951d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///       try-block:
1952d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///         'try' compound-statement handler-seq
1953d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///
1954d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///       function-try-block:
1955d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///         'try' ctor-initializer[opt] compound-statement handler-seq
1956d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///
1957d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///       handler-seq:
1958d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///         handler handler-seq[opt]
1959d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///
196028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///       [Borland] try-block:
196128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///         'try' compound-statement seh-except-block
1962651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines///         'try' compound-statement seh-finally-block
196328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///
1964c4027c82ad4a61f2da1b893ac8fe47bf11e5d50dDavid BlaikieStmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry) {
1965a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  if (Tok.isNot(tok::l_brace))
1966651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
1967bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Possible draft standard bug: attribute-specifier should be allowed?
1968534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith
1969534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  StmtResult TryBlock(ParseCompoundStatement(/*isStmtExpr=*/false,
1970e5afdcfd6a80efc20b0a2e5bde806c08c3bda887David Blaikie                      Scope::DeclScope | Scope::TryScope |
1971e5afdcfd6a80efc20b0a2e5bde806c08c3bda887David Blaikie                        (FnTry ? Scope::FnTryCatchScope : 0)));
1972a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  if (TryBlock.isInvalid())
19733fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer    return TryBlock;
1974a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
197528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  // Borland allows SEH-handlers with 'try'
1976b660446bcf47bfbcdebaf65a6616c4046579987aChad Rosier
1977534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  if ((Tok.is(tok::identifier) &&
1978534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith       Tok.getIdentifierInfo() == getSEHExceptKeyword()) ||
1979534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith      Tok.is(tok::kw___finally)) {
198028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    // TODO: Factor into common return ParseSEHHandlerCommon(...)
198128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    StmtResult Handler;
1982b57791e5b40afa6691063c83d0e95c416fb19fdeDouglas Gregor    if(Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
198328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley      SourceLocation Loc = ConsumeToken();
198428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley      Handler = ParseSEHExceptBlock(Loc);
198528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    }
198628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    else {
198728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley      SourceLocation Loc = ConsumeToken();
198828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley      Handler = ParseSEHFinallyBlock(Loc);
198928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    }
199028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    if(Handler.isInvalid())
19913fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer      return Handler;
199228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
199328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    return Actions.ActOnSEHTryBlock(true /* IsCXXTry */,
199428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley                                    TryLoc,
1995ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                                    TryBlock.get(),
1996ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                                    Handler.get());
1997a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  }
199828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  else {
19994e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer    StmtVector Handlers;
20005eed7e00b4ac8d589ca83e126dafa8767e8a0358Richard Smith
20015eed7e00b4ac8d589ca83e126dafa8767e8a0358Richard Smith    // C++11 attributes can't appear here, despite this context seeming
20025eed7e00b4ac8d589ca83e126dafa8767e8a0358Richard Smith    // statement-like.
20035eed7e00b4ac8d589ca83e126dafa8767e8a0358Richard Smith    DiagnoseAndSkipCXX11Attributes();
200428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
200528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    if (Tok.isNot(tok::kw_catch))
200628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley      return StmtError(Diag(Tok, diag::err_expected_catch));
200728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    while (Tok.is(tok::kw_catch)) {
2008c4027c82ad4a61f2da1b893ac8fe47bf11e5d50dDavid Blaikie      StmtResult Handler(ParseCXXCatchBlock(FnTry));
200928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley      if (!Handler.isInvalid())
2010ef8225444452a1486bd721f3285301fe84643b00Stephen Hines        Handlers.push_back(Handler.get());
201128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    }
201228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    // Don't bother creating the full statement if we don't have any usable
201328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    // handlers.
201428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    if (Handlers.empty())
201528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley      return StmtError();
2016a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
2017ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.get(), Handlers);
201828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  }
2019a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl}
2020a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
2021a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl/// ParseCXXCatchBlock - Parse a C++ catch block, called handler in the standard
2022a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl///
20234cd81c5bf5957b2b10ddf253035f6e1596082108Richard Smith///   handler:
20244cd81c5bf5957b2b10ddf253035f6e1596082108Richard Smith///     'catch' '(' exception-declaration ')' compound-statement
2025a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl///
20264cd81c5bf5957b2b10ddf253035f6e1596082108Richard Smith///   exception-declaration:
20274cd81c5bf5957b2b10ddf253035f6e1596082108Richard Smith///     attribute-specifier-seq[opt] type-specifier-seq declarator
20284cd81c5bf5957b2b10ddf253035f6e1596082108Richard Smith///     attribute-specifier-seq[opt] type-specifier-seq abstract-declarator[opt]
20294cd81c5bf5957b2b10ddf253035f6e1596082108Richard Smith///     '...'
2030a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl///
2031c4027c82ad4a61f2da1b893ac8fe47bf11e5d50dDavid BlaikieStmtResult Parser::ParseCXXCatchBlock(bool FnCatch) {
2032a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  assert(Tok.is(tok::kw_catch) && "Expected 'catch'");
2033a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
2034a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  SourceLocation CatchLoc = ConsumeToken();
2035a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
20364a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_paren);
2037651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (T.expectAndConsume())
2038a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl    return StmtError();
2039a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
2040a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  // C++ 3.3.2p3:
2041a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  // The name in a catch exception-declaration is local to the handler and
2042a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  // shall not be redeclared in the outermost block of the handler.
2043c4027c82ad4a61f2da1b893ac8fe47bf11e5d50dDavid Blaikie  ParseScope CatchScope(this, Scope::DeclScope | Scope::ControlScope |
2044e5afdcfd6a80efc20b0a2e5bde806c08c3bda887David Blaikie                          (FnCatch ? Scope::FnTryCatchScope : 0));
2045a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
2046a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  // exception-declaration is equivalent to '...' or a parameter-declaration
2047a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  // without default arguments.
20486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  Decl *ExceptionDecl = nullptr;
2049a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  if (Tok.isNot(tok::ellipsis)) {
20504cd81c5bf5957b2b10ddf253035f6e1596082108Richard Smith    ParsedAttributesWithRange Attributes(AttrFactory);
20514cd81c5bf5957b2b10ddf253035f6e1596082108Richard Smith    MaybeParseCXX11Attributes(Attributes);
20524cd81c5bf5957b2b10ddf253035f6e1596082108Richard Smith
20530b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall    DeclSpec DS(AttrFactory);
20544cd81c5bf5957b2b10ddf253035f6e1596082108Richard Smith    DS.takeAttributesFrom(Attributes);
20554cd81c5bf5957b2b10ddf253035f6e1596082108Richard Smith
20564b07b2968f87f3cd5a3d8c76145f1cbfd718d42dSebastian Redl    if (ParseCXXTypeSpecifierSeq(DS))
20574b07b2968f87f3cd5a3d8c76145f1cbfd718d42dSebastian Redl      return StmtError();
20584cd81c5bf5957b2b10ddf253035f6e1596082108Richard Smith
2059a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl    Declarator ExDecl(DS, Declarator::CXXCatchContext);
2060a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl    ParseDeclarator(ExDecl);
206123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    ExceptionDecl = Actions.ActOnExceptionDeclarator(getCurScope(), ExDecl);
2062a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  } else
2063a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl    ConsumeToken();
2064a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
20654a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
20664a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  if (T.getCloseLocation().isInvalid())
2067a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl    return StmtError();
2068a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
2069a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  if (Tok.isNot(tok::l_brace))
2070651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
2071a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
2072bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Possible draft standard bug: attribute-specifier should be allowed?
2073534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  StmtResult Block(ParseCompoundStatement());
2074a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  if (Block.isInvalid())
20753fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer    return Block;
2076a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
2077ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl, Block.get());
2078a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl}
20791e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet
20801e862693c63067ae467b0b3884c44f753cd6e821Francois Pichetvoid Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
20813896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  IfExistsCondition Result;
2082f986038beed360c031de8654cfba43a5d3184605Francois Pichet  if (ParseMicrosoftIfExistsCondition(Result))
20831e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet    return;
2084a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
20853896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  // Handle dependent statements by parsing the braces as a compound statement.
20863896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  // This is not the same behavior as Visual C++, which don't treat this as a
20873896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  // compound statement, but for Clang's type checking we can't have anything
20883896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  // inside these braces escaping to the surrounding code.
20893896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  if (Result.Behavior == IEB_Dependent) {
20903896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    if (!Tok.is(tok::l_brace)) {
2091651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Diag(Tok, diag::err_expected) << tok::l_brace;
2092534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith      return;
20933896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    }
2094534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith
2095534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    StmtResult Compound = ParseCompoundStatement();
2096ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor    if (Compound.isInvalid())
2097ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor      return;
2098534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith
2099ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor    StmtResult DepResult = Actions.ActOnMSDependentExistsStmt(Result.KeywordLoc,
2100ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor                                                              Result.IsIfExists,
2101534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith                                                              Result.SS,
2102ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor                                                              Result.Name,
2103ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor                                                              Compound.get());
2104ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor    if (DepResult.isUsable())
2105ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor      Stmts.push_back(DepResult.get());
21063896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    return;
21073896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  }
2108534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith
21093896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  BalancedDelimiterTracker Braces(*this, tok::l_brace);
21103896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  if (Braces.consumeOpen()) {
2111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Diag(Tok, diag::err_expected) << tok::l_brace;
21121e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet    return;
21131e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet  }
21141e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet
21153896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  switch (Result.Behavior) {
21163896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  case IEB_Parse:
21173896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    // Parse the statements below.
21183896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    break;
2119b660446bcf47bfbcdebaf65a6616c4046579987aChad Rosier
21203896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  case IEB_Dependent:
21213896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    llvm_unreachable("Dependent case handled above");
2122b660446bcf47bfbcdebaf65a6616c4046579987aChad Rosier
21233896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  case IEB_Skip:
21243896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    Braces.skipToEnd();
21251e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet    return;
21261e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet  }
21271e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet
21281e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet  // Condition is true, parse the statements.
21291e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet  while (Tok.isNot(tok::r_brace)) {
21301e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet    StmtResult R = ParseStatementOrDeclaration(Stmts, false);
21311e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet    if (R.isUsable())
2132ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      Stmts.push_back(R.get());
21331e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet  }
21343896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  Braces.consumeClose();
21351e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet}
2136