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"
1719510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h"
18f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall#include "clang/Sema/PrettyDeclStackTrace.h"
1919510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/Scope.h"
200576681bac125be07f77f66b02a3dba2c3a24557Richard Smith#include "clang/Sema/TypoCorrection.h"
21ae50fa0a9e7217b043ed4ffe175af4b26dc90f34Chris Lattner#include "clang/Basic/Diagnostic.h"
22ae50fa0a9e7217b043ed4ffe175af4b26dc90f34Chris Lattner#include "clang/Basic/PrettyStackTrace.h"
23ae50fa0a9e7217b043ed4ffe175af4b26dc90f34Chris Lattner#include "clang/Basic/SourceManager.h"
248cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier#include "llvm/ADT/SmallString.h"
255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang;
265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// C99 6.8: Statements and Blocks.
295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseStatementOrDeclaration - Read 'statement' or 'declaration'.
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       StatementOrDeclaration:
335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         statement
345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         declaration
355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       statement:
375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         labeled-statement
385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         compound-statement
395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         expression-statement
405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         selection-statement
415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         iteration-statement
425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         jump-statement
43dcdd55fb4d28de8c314d6c6c1a38aa6aba76d431Argyrios Kyrtzidis/// [C++]   declaration-statement
44a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl/// [C++]   try-block
4528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// [MS]    seh-try-block
46b384d329e0b727d4f2effa28fbb9aba2ac420e7bFariborz Jahanian/// [OBC]   objc-throw-statement
47b384d329e0b727d4f2effa28fbb9aba2ac420e7bFariborz Jahanian/// [OBC]   objc-try-catch-statement
48c385c90c68dfa376650e2facfbb444b2ec9bd110Fariborz Jahanian/// [OBC]   objc-synchronized-statement
495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU]   asm-statement
505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [OMP]   openmp-construct             [TODO]
515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       labeled-statement:
535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         identifier ':' statement
545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'case' constant-expression ':' statement
555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'default' ':' statement
565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       selection-statement:
585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         if-statement
595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         switch-statement
605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       iteration-statement:
625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         while-statement
635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         do-statement
645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         for-statement
655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       expression-statement:
675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         expression[opt] ';'
685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       jump-statement:
705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'goto' identifier ';'
715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'continue' ';'
725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'break' ';'
735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'return' expression[opt] ';'
745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU]   'goto' '*' expression ';'
755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
76b384d329e0b727d4f2effa28fbb9aba2ac420e7bFariborz Jahanian/// [OBC] objc-throw-statement:
77b384d329e0b727d4f2effa28fbb9aba2ac420e7bFariborz Jahanian/// [OBC]   '@' 'throw' expression ';'
781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [OBC]   '@' 'throw' ';'
791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
8060d7b3a319d84d688752be3870615ac0f111fb16John McCallStmtResult
815cb94a78202ccb1007df0be86884297761f4a53aNico WeberParser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement,
825cb94a78202ccb1007df0be86884297761f4a53aNico Weber                                    SourceLocation *TrailingElseLoc) {
83a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
8436d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis  ParenBraceBracketBalancer BalancerRAIIObj(*this);
850e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
86534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  ParsedAttributesWithRange Attrs(AttrFactory);
87534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  MaybeParseCXX0XAttributes(Attrs, 0, /*MightBeObjCMessageSend*/ true);
88534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith
89534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  StmtResult Res = ParseStatementOrDeclarationAfterAttributes(Stmts,
90534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith                                 OnlyStatement, TrailingElseLoc, Attrs);
91534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith
92534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  assert((Attrs.empty() || Res.isInvalid() || Res.isUsable()) &&
93534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith         "attributes on empty statement");
94534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith
95534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  if (Attrs.empty() || Res.isInvalid())
96534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return Res;
97534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith
98534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  return Actions.ProcessStmtAttributes(Res.get(), Attrs.getList(), Attrs.Range);
99534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith}
100534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith
101534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult
102534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithParser::ParseStatementOrDeclarationAfterAttributes(StmtVector &Stmts,
103534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith          bool OnlyStatement, SourceLocation *TrailingElseLoc,
104534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith          ParsedAttributesWithRange &Attrs) {
105534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  const char *SemiError = 0;
106534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  StmtResult Res;
107bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Cases in this switch statement should fall through if the parser expects
1095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // the token to end in a semicolon (in which case SemiError should be set),
1105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // or they directly 'return;' if not.
111312eadb832cab4497a069409954500d8192b8f0dDouglas GregorRetry:
112397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian  tok::TokenKind Kind  = Tok.getKind();
113397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian  SourceLocation AtLoc;
114397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian  switch (Kind) {
115397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian  case tok::at: // May be a @try or @throw statement
116397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian    {
117534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith      ProhibitAttributes(Attrs); // TODO: is it correct?
118397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian      AtLoc = ConsumeToken();  // consume @
11943bc2a0973ffe404fabba6f8280cd6bad2c69fcbSebastian Redl      return ParseObjCAtStatement(AtLoc);
120397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian    }
121397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian
122791215b7a24666912c0b71175d2ca5ba082f666eDouglas Gregor  case tok::code_completion:
123f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Statement);
1247d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
1257d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return StmtError();
126a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
127312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor  case tok::identifier: {
128312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    Token Next = NextToken();
129312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    if (Next.is(tok::colon)) { // C99 6.8.1: labeled-statement
130b9f930d7bdb911be8420e044876221bf8a39f45fArgyrios Kyrtzidis      // identifier ':' statement
131534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith      return ParseLabeledStatement(Attrs);
132b9f930d7bdb911be8420e044876221bf8a39f45fArgyrios Kyrtzidis    }
133a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
1340576681bac125be07f77f66b02a3dba2c3a24557Richard Smith    // Look up the identifier, and typo-correct it to a keyword if it's not
1350576681bac125be07f77f66b02a3dba2c3a24557Richard Smith    // found.
1363b887354b1b667c97d070ddc67b5354353c4c07bDouglas Gregor    if (Next.isNot(tok::coloncolon)) {
1370576681bac125be07f77f66b02a3dba2c3a24557Richard Smith      // Try to limit which sets of keywords should be included in typo
1380576681bac125be07f77f66b02a3dba2c3a24557Richard Smith      // correction based on what the next token is.
1390576681bac125be07f77f66b02a3dba2c3a24557Richard Smith      // FIXME: Pass the next token into the CorrectionCandidateCallback and
1400576681bac125be07f77f66b02a3dba2c3a24557Richard Smith      //        do this filtering in a more fine-grained manner.
1410576681bac125be07f77f66b02a3dba2c3a24557Richard Smith      CorrectionCandidateCallback DefaultValidator;
1420576681bac125be07f77f66b02a3dba2c3a24557Richard Smith      DefaultValidator.WantTypeSpecifiers =
1430576681bac125be07f77f66b02a3dba2c3a24557Richard Smith          Next.is(tok::l_paren) || Next.is(tok::less) ||
1440576681bac125be07f77f66b02a3dba2c3a24557Richard Smith          Next.is(tok::identifier) || Next.is(tok::star) ||
1450576681bac125be07f77f66b02a3dba2c3a24557Richard Smith          Next.is(tok::amp) || Next.is(tok::l_square);
1460576681bac125be07f77f66b02a3dba2c3a24557Richard Smith      DefaultValidator.WantExpressionKeywords =
1470576681bac125be07f77f66b02a3dba2c3a24557Richard Smith          Next.is(tok::l_paren) || Next.is(tok::identifier) ||
1480576681bac125be07f77f66b02a3dba2c3a24557Richard Smith          Next.is(tok::arrow) || Next.is(tok::period);
1490576681bac125be07f77f66b02a3dba2c3a24557Richard Smith      DefaultValidator.WantRemainingKeywords =
1500576681bac125be07f77f66b02a3dba2c3a24557Richard Smith          Next.is(tok::l_paren) || Next.is(tok::semi) ||
1510576681bac125be07f77f66b02a3dba2c3a24557Richard Smith          Next.is(tok::identifier) || Next.is(tok::l_brace);
1520576681bac125be07f77f66b02a3dba2c3a24557Richard Smith      DefaultValidator.WantCXXNamedCasts = false;
1530576681bac125be07f77f66b02a3dba2c3a24557Richard Smith      if (TryAnnotateName(/*IsAddressOfOperand*/false, &DefaultValidator)
1540576681bac125be07f77f66b02a3dba2c3a24557Richard Smith            == ANK_Error) {
155312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor        // Handle errors here by skipping up to the next semicolon or '}', and
156312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor        // eat the semicolon if that's what stopped us.
157312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor        SkipUntil(tok::r_brace, /*StopAtSemi=*/true, /*DontConsume=*/true);
158312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor        if (Tok.is(tok::semi))
159312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor          ConsumeToken();
160312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor        return StmtError();
161312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor      }
162a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
1630576681bac125be07f77f66b02a3dba2c3a24557Richard Smith      // If the identifier was typo-corrected, try again.
1640576681bac125be07f77f66b02a3dba2c3a24557Richard Smith      if (Tok.isNot(tok::identifier))
1650576681bac125be07f77f66b02a3dba2c3a24557Richard Smith        goto Retry;
166312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    }
167a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
168312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    // Fall through
169312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor  }
170a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
171f919bfe282b8a94d956290dc9812b456fa2b447eChris Lattner  default: {
1724e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if ((getLangOpts().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) {
17397144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner      SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
1748113ecfa4e41e2c888b1794389dfe3bce6386493Ted Kremenek      DeclGroupPtrTy Decl = ParseDeclaration(Stmts, Declarator::BlockContext,
175534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith                                             DeclEnd, Attrs);
17697144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner      return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
177f919bfe282b8a94d956290dc9812b456fa2b447eChris Lattner    }
178f919bfe282b8a94d956290dc9812b456fa2b447eChris Lattner
179f919bfe282b8a94d956290dc9812b456fa2b447eChris Lattner    if (Tok.is(tok::r_brace)) {
1805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Diag(Tok, diag::err_expected_statement);
18161364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl      return StmtError();
1825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
1831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
184534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return ParseExprStatement();
185f919bfe282b8a94d956290dc9812b456fa2b447eChris Lattner  }
18661364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
1875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::kw_case:                // C99 6.8.1: labeled-statement
188534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return ParseCaseStatement();
1895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::kw_default:             // C99 6.8.1: labeled-statement
190534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return ParseDefaultStatement();
19161364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
1925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::l_brace:                // C99 6.8.2: compound-statement
193534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return ParseCompoundStatement();
19444aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis  case tok::semi: {                 // C99 6.8.3p3: expression[opt] ';'
195e2ca828119b8bff4a5c25c6db8ee4fec558451e7Argyrios Kyrtzidis    bool HasLeadingEmptyMacro = Tok.hasLeadingEmptyMacro();
196e2ca828119b8bff4a5c25c6db8ee4fec558451e7Argyrios Kyrtzidis    return Actions.ActOnNullStmt(ConsumeToken(), HasLeadingEmptyMacro);
19744aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis  }
19861364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
1995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::kw_if:                  // C99 6.8.4.1: if-statement
200534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return ParseIfStatement(TrailingElseLoc);
2015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::kw_switch:              // C99 6.8.4.2: switch-statement
202534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return ParseSwitchStatement(TrailingElseLoc);
20361364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
2045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::kw_while:               // C99 6.8.5.1: while-statement
205534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return ParseWhileStatement(TrailingElseLoc);
2065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::kw_do:                  // C99 6.8.5.2: do-statement
207534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    Res = ParseDoStatement();
2086869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner    SemiError = "do/while";
2095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
2105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::kw_for:                 // C99 6.8.5.3: for-statement
211534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return ParseForStatement(TrailingElseLoc);
2125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::kw_goto:                // C99 6.8.6.1: goto-statement
214534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    Res = ParseGotoStatement();
2156869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner    SemiError = "goto";
2165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
2175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::kw_continue:            // C99 6.8.6.2: continue-statement
218534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    Res = ParseContinueStatement();
2196869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner    SemiError = "continue";
2205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
2215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::kw_break:               // C99 6.8.6.3: break-statement
222534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    Res = ParseBreakStatement();
2236869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner    SemiError = "break";
2245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
2255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case tok::kw_return:              // C99 6.8.6.4: return-statement
226534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    Res = ParseReturnStatement();
2276869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner    SemiError = "return";
2285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
22961364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
230a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  case tok::kw_asm: {
231534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    ProhibitAttributes(Attrs);
232d62701bc5321049353017e9abf1963edd57646aaSteve Naroff    bool msAsm = false;
233d62701bc5321049353017e9abf1963edd57646aaSteve Naroff    Res = ParseAsmStatement(msAsm);
234bf8cafadb9d4e0d7a90fe78fc175efb80ae34d42Argyrios Kyrtzidis    Res = Actions.ActOnFinishFullStmt(Res.get());
2353fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer    if (msAsm) return Res;
2366869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner    SemiError = "asm";
2375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
2385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
23961364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
240a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  case tok::kw_try:                 // C++ 15: try-block
241534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return ParseCXXTryBlock();
24228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
24328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  case tok::kw___try:
244534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    ProhibitAttributes(Attrs); // TODO: is it correct?
245534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return ParseSEHTryBlock();
246aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman
247aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman  case tok::annot_pragma_vis:
248534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    ProhibitAttributes(Attrs);
249aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman    HandlePragmaVisibility();
250aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman    return StmtEmpty();
251aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman
252aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman  case tok::annot_pragma_pack:
253534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    ProhibitAttributes(Attrs);
254aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman    HandlePragmaPack();
255aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman    return StmtEmpty();
256a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  }
257a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
2585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If we reached this code, the statement must end in a semicolon.
2594e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (Tok.is(tok::semi)) {
2605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ConsumeToken();
2610e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl  } else if (!Res.isInvalid()) {
2627b3684afffa2d5eda3dd6930f01faaa673686c16Chris Lattner    // If the result was valid, then we do want to diagnose this.  Use
2637b3684afffa2d5eda3dd6930f01faaa673686c16Chris Lattner    // ExpectAndConsume to emit the diagnostic, even though we know it won't
2647b3684afffa2d5eda3dd6930f01faaa673686c16Chris Lattner    // succeed.
2657b3684afffa2d5eda3dd6930f01faaa673686c16Chris Lattner    ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt, SemiError);
266195044028b76133e2a1f245b094468fe07db7330Chris Lattner    // Skip until we see a } or ;, but don't eat it.
267195044028b76133e2a1f245b094468fe07db7330Chris Lattner    SkipUntil(tok::r_brace, true, true);
2685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2703fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer  return Res;
2715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
2725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
273312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor/// \brief Parse an expression statement.
274534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseExprStatement() {
275312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor  // If a case keyword is missing, this is where it should be inserted.
276312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor  Token OldToken = Tok;
277a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
278312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor  // expression[opt] ';'
2795ecdd78408a1c6f4be506d94f776642570d27336Douglas Gregor  ExprResult Expr(ParseExpression());
280312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor  if (Expr.isInvalid()) {
281312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    // If the expression is invalid, skip ahead to the next semicolon or '}'.
282312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    // Not doing this opens us up to the possibility of infinite loops if
283312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    // ParseExpression does not consume any tokens.
284312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    SkipUntil(tok::r_brace, /*StopAtSemi=*/true, /*DontConsume=*/true);
285312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    if (Tok.is(tok::semi))
286312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor      ConsumeToken();
287312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    return StmtError();
288312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor  }
289a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
290312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor  if (Tok.is(tok::colon) && getCurScope()->isSwitchScope() &&
291312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor      Actions.CheckCaseExpression(Expr.get())) {
292312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    // If a constant expression is followed by a colon inside a switch block,
293312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    // suggest a missing case keyword.
294312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    Diag(OldToken, diag::err_expected_case_before_expression)
295312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor      << FixItHint::CreateInsertion(OldToken.getLocation(), "case ");
296a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
297312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor    // Recover parsing as a case statement.
298534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    return ParseCaseStatement(/*MissingCase=*/true, Expr);
299312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor  }
300a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
301312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor  // Otherwise, eat the semicolon.
302312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor  ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
303312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor  return Actions.ActOnExprStmt(Actions.MakeFullExpr(Expr.get()));
30428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley}
305312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor
306534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseSEHTryBlock() {
30728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  assert(Tok.is(tok::kw___try) && "Expected '__try'");
30828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  SourceLocation Loc = ConsumeToken();
30928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  return ParseSEHTryBlockCommon(Loc);
31028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley}
31128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
31228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// ParseSEHTryBlockCommon
31328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///
31428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// seh-try-block:
31528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///   '__try' compound-statement seh-handler
31628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///
31728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// seh-handler:
31828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///   seh-except-block
31928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///   seh-finally-block
32028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///
32128bbe4b8acc338476fe0825769b41fb32b423c72John WiegleyStmtResult Parser::ParseSEHTryBlockCommon(SourceLocation TryLoc) {
32228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  if(Tok.isNot(tok::l_brace))
32328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    return StmtError(Diag(Tok,diag::err_expected_lbrace));
32428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
325568ba871bbac959029671b81f8e531edb7e0d7d6Joao Matos  StmtResult TryBlock(ParseCompoundStatement());
32628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  if(TryBlock.isInvalid())
3273fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer    return TryBlock;
32828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
32928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  StmtResult Handler;
330534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  if (Tok.is(tok::identifier) &&
331b57791e5b40afa6691063c83d0e95c416fb19fdeDouglas Gregor      Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
33228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    SourceLocation Loc = ConsumeToken();
33328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    Handler = ParseSEHExceptBlock(Loc);
33428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  } else if (Tok.is(tok::kw___finally)) {
33528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    SourceLocation Loc = ConsumeToken();
33628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    Handler = ParseSEHFinallyBlock(Loc);
33728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  } else {
33828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    return StmtError(Diag(Tok,diag::err_seh_expected_handler));
33928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  }
34028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
34128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  if(Handler.isInvalid())
3423fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer    return Handler;
34328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
34428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  return Actions.ActOnSEHTryBlock(false /* IsCXXTry */,
34528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley                                  TryLoc,
34628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley                                  TryBlock.take(),
34728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley                                  Handler.take());
34828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley}
34928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
35028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// ParseSEHExceptBlock - Handle __except
35128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///
35228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// seh-except-block:
35328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///   '__except' '(' seh-filter-expression ')' compound-statement
35428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///
35528bbe4b8acc338476fe0825769b41fb32b423c72John WiegleyStmtResult Parser::ParseSEHExceptBlock(SourceLocation ExceptLoc) {
35628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  PoisonIdentifierRAIIObject raii(Ident__exception_code, false),
35728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    raii2(Ident___exception_code, false),
35828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    raii3(Ident_GetExceptionCode, false);
35928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
36028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  if(ExpectAndConsume(tok::l_paren,diag::err_expected_lparen))
36128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    return StmtError();
36228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
36328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  ParseScope ExpectScope(this, Scope::DeclScope | Scope::ControlScope);
36428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
3654e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().Borland) {
366d7f02df6e949aaf26706bea3ac79ed65ca792a30Francois Pichet    Ident__exception_info->setIsPoisoned(false);
367d7f02df6e949aaf26706bea3ac79ed65ca792a30Francois Pichet    Ident___exception_info->setIsPoisoned(false);
368d7f02df6e949aaf26706bea3ac79ed65ca792a30Francois Pichet    Ident_GetExceptionInfo->setIsPoisoned(false);
369d7f02df6e949aaf26706bea3ac79ed65ca792a30Francois Pichet  }
37028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  ExprResult FilterExpr(ParseExpression());
371d7f02df6e949aaf26706bea3ac79ed65ca792a30Francois Pichet
3724e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().Borland) {
373d7f02df6e949aaf26706bea3ac79ed65ca792a30Francois Pichet    Ident__exception_info->setIsPoisoned(true);
374d7f02df6e949aaf26706bea3ac79ed65ca792a30Francois Pichet    Ident___exception_info->setIsPoisoned(true);
375d7f02df6e949aaf26706bea3ac79ed65ca792a30Francois Pichet    Ident_GetExceptionInfo->setIsPoisoned(true);
376d7f02df6e949aaf26706bea3ac79ed65ca792a30Francois Pichet  }
37728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
37828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  if(FilterExpr.isInvalid())
37928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    return StmtError();
38028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
38128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  if(ExpectAndConsume(tok::r_paren,diag::err_expected_rparen))
38228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    return StmtError();
38328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
384534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  StmtResult Block(ParseCompoundStatement());
38528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
38628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  if(Block.isInvalid())
3873fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer    return Block;
38828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
38928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  return Actions.ActOnSEHExceptBlock(ExceptLoc, FilterExpr.take(), Block.take());
39028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley}
39128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
39228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// ParseSEHFinallyBlock - Handle __finally
39328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///
39428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley/// seh-finally-block:
39528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///   '__finally' compound-statement
39628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///
39728bbe4b8acc338476fe0825769b41fb32b423c72John WiegleyStmtResult Parser::ParseSEHFinallyBlock(SourceLocation FinallyBlock) {
39828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  PoisonIdentifierRAIIObject raii(Ident__abnormal_termination, false),
39928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    raii2(Ident___abnormal_termination, false),
40028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    raii3(Ident_AbnormalTermination, false);
40128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
402534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  StmtResult Block(ParseCompoundStatement());
40328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  if(Block.isInvalid())
4043fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer    return Block;
40528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
40628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  return Actions.ActOnSEHFinallyBlock(FinallyBlock,Block.take());
407312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor}
408312eadb832cab4497a069409954500d8192b8f0dDouglas Gregor
409f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis/// ParseLabeledStatement - We have an identifier and a ':' after it.
4105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
4115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       labeled-statement:
4125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         identifier ':' statement
4135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU]   identifier ':' attributes[opt] statement
4145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
415534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseLabeledStatement(ParsedAttributesWithRange &attrs) {
4164e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
4175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         "Not an identifier!");
4185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
419d217773f106856a11879ec79dc468efefaf2ee75Chris Lattner  Token IdentTok = Tok;  // Save the whole token.
4205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ConsumeToken();  // eat the identifier.
421f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis
422f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis  assert(Tok.is(tok::colon) && "Not a label!");
42361364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
4245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // identifier ':' statement
425f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis  SourceLocation ColonLoc = ConsumeToken();
4265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
427534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  // Read label attributes, if present. attrs will contain both C++11 and GNU
428534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  // attributes (if present) after this point.
4297f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseGNUAttributes(attrs);
4305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
43160d7b3a319d84d688752be3870615ac0f111fb16John McCall  StmtResult SubStmt(ParseStatement());
4320e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
433f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis  // Broken substmt shouldn't prevent the label from being added to the AST.
4340e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl  if (SubStmt.isInvalid())
435f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis    SubStmt = Actions.ActOnNullStmt(ColonLoc);
436a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
437337e550218128e7d922c09bb354fbc71de90c568Chris Lattner  LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
438337e550218128e7d922c09bb354fbc71de90c568Chris Lattner                                              IdentTok.getLocation());
439534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  if (AttributeList *Attrs = attrs.getList()) {
440337e550218128e7d922c09bb354fbc71de90c568Chris Lattner    Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
441534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    attrs.clear();
442534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  }
443a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
444337e550218128e7d922c09bb354fbc71de90c568Chris Lattner  return Actions.ActOnLabelStmt(IdentTok.getLocation(), LD, ColonLoc,
445337e550218128e7d922c09bb354fbc71de90c568Chris Lattner                                SubStmt.get());
446f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis}
4475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCaseStatement
4495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       labeled-statement:
4505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'case' constant-expression ':' statement
4515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU]   'case' constant-expression '...' constant-expression ':' statement
4525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
453534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseCaseStatement(bool MissingCase, ExprResult Expr) {
45446f1110b324583622521a01d2c8f949e1f215bd2Richard Smith  assert((MissingCase || Tok.is(tok::kw_case)) && "Not a case stmt!");
4551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
45624e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // It is very very common for code to contain many case statements recursively
45724e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // nested, as in (but usually without indentation):
45824e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  //  case 1:
45924e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  //    case 2:
46024e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  //      case 3:
46124e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  //         case 4:
46224e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  //           case 5: etc.
46324e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  //
46424e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // Parsing this naively works, but is both inefficient and can cause us to run
46524e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // out of stack space in our recursive descent parser.  As a special case,
46626140c6399d4b14a224d44cf0102a1919d8dab04Chris Lattner  // flatten this recursion into an iterative loop.  This is complex and gross,
46724e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // but all the grossness is constrained to ParseCaseStatement (and some
46824e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // wierdness in the actions), so this is just local grossness :).
4691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
47024e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // TopLevelCase - This is the highest level we have parsed.  'case 1' in the
47124e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // example above.
47260d7b3a319d84d688752be3870615ac0f111fb16John McCall  StmtResult TopLevelCase(true);
4731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
47424e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // DeepestParsedCaseStmt - This is the deepest statement we have parsed, which
47524e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // gets updated each time a new case is parsed, and whose body is unset so
47624e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // far.  When parsing 'case 4', this is the 'case 3' node.
477b2fc69097d15f6374b9e5e6101f33960c34acbedRichard Trieu  Stmt *DeepestParsedCaseStmt = 0;
4781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
47924e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // While we have case statements, eat and stack them.
4800e1e69ca1b30df7692f302a5388377f507bc4567David Majnemer  SourceLocation ColonLoc;
48124e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  do {
482bb9b80c308d7d3f758886243c7145404a50c66cfRichard Trieu    SourceLocation CaseLoc = MissingCase ? Expr.get()->getExprLoc() :
483bb9b80c308d7d3f758886243c7145404a50c66cfRichard Trieu                                           ConsumeToken();  // eat the 'case'.
4841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4853e1005f085006dfb3545f0c54ac5e22483137c7dDouglas Gregor    if (Tok.is(tok::code_completion)) {
48623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      Actions.CodeCompleteCase(getCurScope());
4877d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      cutOffParsing();
4887d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      return StmtError();
4893e1005f085006dfb3545f0c54ac5e22483137c7dDouglas Gregor    }
490a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
4916fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    /// We don't want to treat 'case x : y' as a potential typo for 'case x::y'.
4926fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    /// Disable this form of error recovery while we're parsing the case
4936fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    /// expression.
4946fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    ColonProtectionRAIIObject ColonProtection(*this);
495a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
496bb9b80c308d7d3f758886243c7145404a50c66cfRichard Trieu    ExprResult LHS(MissingCase ? Expr : ParseConstantExpression());
497bb9b80c308d7d3f758886243c7145404a50c66cfRichard Trieu    MissingCase = false;
49824e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    if (LHS.isInvalid()) {
49924e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      SkipUntil(tok::colon);
50024e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      return StmtError();
50124e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    }
5025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
50324e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    // GNU case range extension.
50424e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    SourceLocation DotDotDotLoc;
50560d7b3a319d84d688752be3870615ac0f111fb16John McCall    ExprResult RHS;
50624e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    if (Tok.is(tok::ellipsis)) {
50724e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      Diag(Tok, diag::ext_gnu_case_range);
50824e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      DotDotDotLoc = ConsumeToken();
5090e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
51024e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      RHS = ParseConstantExpression();
51124e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      if (RHS.isInvalid()) {
51224e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner        SkipUntil(tok::colon);
51324e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner        return StmtError();
51424e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      }
51524e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    }
516a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
5176fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    ColonProtection.restore();
5180e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
519f6a3ab0f167f23d0669eae77280c7ff660e7ad98John McCall    if (Tok.is(tok::colon)) {
520f6a3ab0f167f23d0669eae77280c7ff660e7ad98John McCall      ColonLoc = ConsumeToken();
521f6a3ab0f167f23d0669eae77280c7ff660e7ad98John McCall
522f6a3ab0f167f23d0669eae77280c7ff660e7ad98John McCall    // Treat "case blah;" as a typo for "case blah:".
523f6a3ab0f167f23d0669eae77280c7ff660e7ad98John McCall    } else if (Tok.is(tok::semi)) {
524f6a3ab0f167f23d0669eae77280c7ff660e7ad98John McCall      ColonLoc = ConsumeToken();
525f6a3ab0f167f23d0669eae77280c7ff660e7ad98John McCall      Diag(ColonLoc, diag::err_expected_colon_after) << "'case'"
526f6a3ab0f167f23d0669eae77280c7ff660e7ad98John McCall        << FixItHint::CreateReplacement(ColonLoc, ":");
527f6a3ab0f167f23d0669eae77280c7ff660e7ad98John McCall    } else {
528662a4822ee7c8696434b054303c5076a606ab175Douglas Gregor      SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation);
529662a4822ee7c8696434b054303c5076a606ab175Douglas Gregor      Diag(ExpectedLoc, diag::err_expected_colon_after) << "'case'"
530662a4822ee7c8696434b054303c5076a606ab175Douglas Gregor        << FixItHint::CreateInsertion(ExpectedLoc, ":");
531662a4822ee7c8696434b054303c5076a606ab175Douglas Gregor      ColonLoc = ExpectedLoc;
5325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
533a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
53460d7b3a319d84d688752be3870615ac0f111fb16John McCall    StmtResult Case =
5359ae2f076ca5ab1feb3ba95629099ec2319833701John McCall      Actions.ActOnCaseStmt(CaseLoc, LHS.get(), DotDotDotLoc,
5369ae2f076ca5ab1feb3ba95629099ec2319833701John McCall                            RHS.get(), ColonLoc);
5371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
53824e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    // If we had a sema error parsing this case, then just ignore it and
53924e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    // continue parsing the sub-stmt.
54024e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    if (Case.isInvalid()) {
54124e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      if (TopLevelCase.isInvalid())  // No parsed case stmts.
54224e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner        return ParseStatement();
54324e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      // Otherwise, just don't add it as a nested case.
54424e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    } else {
54524e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      // If this is the first case statement we parsed, it becomes TopLevelCase.
54624e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      // Otherwise we link it into the current chain.
547ca0408fb49c1370430672acf2d770b7151cf71deJohn McCall      Stmt *NextDeepest = Case.get();
54824e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      if (TopLevelCase.isInvalid())
5493fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer        TopLevelCase = Case;
55024e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      else
5519ae2f076ca5ab1feb3ba95629099ec2319833701John McCall        Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, Case.get());
55224e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner      DeepestParsedCaseStmt = NextDeepest;
55324e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    }
5541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
55524e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    // Handle all case statements.
55624e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  } while (Tok.is(tok::kw_case));
5571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
55824e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  assert(!TopLevelCase.isInvalid() && "Should have parsed at least one case!");
5591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
56024e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // If we found a non-case statement, start by parsing it.
56160d7b3a319d84d688752be3870615ac0f111fb16John McCall  StmtResult SubStmt;
5621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
56324e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  if (Tok.isNot(tok::r_brace)) {
56424e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    SubStmt = ParseStatement();
56524e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  } else {
56624e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    // Nicely diagnose the common error "switch (X) { case 4: }", which is
56724e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    // not valid.
56863f04ab297157c5905975e8f2c807b35251dace7David Majnemer    SourceLocation AfterColonLoc = PP.getLocForEndOfToken(ColonLoc);
56985b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith    Diag(AfterColonLoc, diag::err_label_end_of_compound_statement)
57085b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith      << FixItHint::CreateInsertion(AfterColonLoc, " ;");
57124e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    SubStmt = true;
5725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
5731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
57424e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // Broken sub-stmt shouldn't prevent forming the case statement properly.
5750e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl  if (SubStmt.isInvalid())
57624e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner    SubStmt = Actions.ActOnNullStmt(SourceLocation());
5771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
57824e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // Install the body into the most deeply-nested case.
5799ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, SubStmt.get());
58061364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
58124e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner  // Return the top level parsed statement tree.
5823fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer  return TopLevelCase;
5835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
5845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseDefaultStatement
5865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       labeled-statement:
5875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'default' ':' statement
5885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Note that this does not parse the 'statement' at the end.
5895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
590534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseDefaultStatement() {
5914e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  assert(Tok.is(tok::kw_default) && "Not a default stmt!");
5925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation DefaultLoc = ConsumeToken();  // eat the 'default'.
5935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
594662a4822ee7c8696434b054303c5076a606ab175Douglas Gregor  SourceLocation ColonLoc;
595f6a3ab0f167f23d0669eae77280c7ff660e7ad98John McCall  if (Tok.is(tok::colon)) {
596f6a3ab0f167f23d0669eae77280c7ff660e7ad98John McCall    ColonLoc = ConsumeToken();
597f6a3ab0f167f23d0669eae77280c7ff660e7ad98John McCall
598f6a3ab0f167f23d0669eae77280c7ff660e7ad98John McCall  // Treat "default;" as a typo for "default:".
599f6a3ab0f167f23d0669eae77280c7ff660e7ad98John McCall  } else if (Tok.is(tok::semi)) {
600f6a3ab0f167f23d0669eae77280c7ff660e7ad98John McCall    ColonLoc = ConsumeToken();
601f6a3ab0f167f23d0669eae77280c7ff660e7ad98John McCall    Diag(ColonLoc, diag::err_expected_colon_after) << "'default'"
602f6a3ab0f167f23d0669eae77280c7ff660e7ad98John McCall      << FixItHint::CreateReplacement(ColonLoc, ":");
603f6a3ab0f167f23d0669eae77280c7ff660e7ad98John McCall  } else {
604662a4822ee7c8696434b054303c5076a606ab175Douglas Gregor    SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation);
605662a4822ee7c8696434b054303c5076a606ab175Douglas Gregor    Diag(ExpectedLoc, diag::err_expected_colon_after) << "'default'"
606662a4822ee7c8696434b054303c5076a606ab175Douglas Gregor      << FixItHint::CreateInsertion(ExpectedLoc, ":");
607662a4822ee7c8696434b054303c5076a606ab175Douglas Gregor    ColonLoc = ExpectedLoc;
6085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
609a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
61085b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith  StmtResult SubStmt;
61185b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith
61285b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith  if (Tok.isNot(tok::r_brace)) {
61385b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith    SubStmt = ParseStatement();
61485b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith  } else {
61585b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith    // Diagnose the common error "switch (X) {... default: }", which is
61685b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith    // not valid.
61763f04ab297157c5905975e8f2c807b35251dace7David Majnemer    SourceLocation AfterColonLoc = PP.getLocForEndOfToken(ColonLoc);
61885b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith    Diag(AfterColonLoc, diag::err_label_end_of_compound_statement)
61985b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith      << FixItHint::CreateInsertion(AfterColonLoc, " ;");
62085b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith    SubStmt = true;
6215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
6225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
62385b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith  // Broken sub-stmt shouldn't prevent forming the case statement properly.
6240e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl  if (SubStmt.isInvalid())
62585b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith    SubStmt = Actions.ActOnNullStmt(ColonLoc);
62661364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
627117054a99f4994e4ec8a1fc904b554e1f2dc9b29Sebastian Redl  return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc,
6289ae2f076ca5ab1feb3ba95629099ec2319833701John McCall                                  SubStmt.get(), getCurScope());
6295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
6305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
631534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseCompoundStatement(bool isStmtExpr) {
632534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  return ParseCompoundStatement(isStmtExpr, Scope::DeclScope);
633bca01b46850f867b2f4137f25c882022b58f8471Douglas Gregor}
6345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCompoundStatement - Parse a "{}" block.
6365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
6375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       compound-statement: [C99 6.8.2]
6385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         { block-item-list[opt] }
6395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU]   { label-declarations block-item-list } [TODO]
6405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
6415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       block-item-list:
6425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         block-item
6435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         block-item-list block-item
6445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
6455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       block-item:
6465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         declaration
64745a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner/// [GNU]   '__extension__' declaration
6485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         statement
6495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [OMP]   openmp-directive            [TODO]
6505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
6515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU] label-declarations:
6525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU]   label-declaration
6535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU]   label-declarations label-declaration
6545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
6555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU] label-declaration:
6565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU]   '__label__' identifier-list ';'
6575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
6585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [OMP] openmp-directive:             [TODO]
6595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [OMP]   barrier-directive
6605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [OMP]   flush-directive
6615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
662534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseCompoundStatement(bool isStmtExpr,
663bca01b46850f867b2f4137f25c882022b58f8471Douglas Gregor                                          unsigned ScopeFlags) {
6644e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  assert(Tok.is(tok::l_brace) && "Not a compount stmt!");
66561364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
66631e057270232c1c37602579cb6461c2704175672Chris Lattner  // Enter a scope to hold everything within the compound stmt.  Compound
66731e057270232c1c37602579cb6461c2704175672Chris Lattner  // statements can always hold declarations.
668bca01b46850f867b2f4137f25c882022b58f8471Douglas Gregor  ParseScope CompoundScope(this, ScopeFlags);
6695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Parse the statements in the body.
67161364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl  return ParseCompoundStatementBody(isStmtExpr);
6725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
6735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCompoundStatementBody - Parse a sequence of statements and invoke the
6751b273c403734d343d720acb28f04011807c8aa56Steve Naroff/// ActOnCompoundStmt action.  This expects the '{' to be the current token, and
6765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// consume the '}' at the end of the block.  It does not manipulate the scope
6775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// stack.
67860d7b3a319d84d688752be3870615ac0f111fb16John McCallStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
6791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),
680ae50fa0a9e7217b043ed4ffe175af4b26dc90f34Chris Lattner                                Tok.getLocation(),
681ae50fa0a9e7217b043ed4ffe175af4b26dc90f34Chris Lattner                                "in compound statement ('{}')");
6820fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor  InMessageExpressionRAIIObject InMessage(*this, false);
6834a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_brace);
6844a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  if (T.consumeOpen())
6854a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    return StmtError();
6865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
687625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  Sema::CompoundScopeRAII CompoundScope(Actions);
688625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
6894e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer  StmtVector Stmts;
690b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis
6914ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner  // "__label__ X, Y, Z;" is the GNU "Local Label" extension.  These are
6924ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner  // only allowed at the start of a compound stmt regardless of the language.
6934ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner  while (Tok.is(tok::kw___label__)) {
6944ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner    SourceLocation LabelLoc = ConsumeToken();
6954ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner    Diag(LabelLoc, diag::ext_gnu_local_label);
696a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
6975f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<Decl *, 8> DeclsInGroup;
6984ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner    while (1) {
6994ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner      if (Tok.isNot(tok::identifier)) {
7004ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner        Diag(Tok, diag::err_expected_ident);
7014ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner        break;
7024ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner      }
703a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
7044ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner      IdentifierInfo *II = Tok.getIdentifierInfo();
7054ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner      SourceLocation IdLoc = ConsumeToken();
7066784304db526cde59046d613c4175ce2caf93e44Abramo Bagnara      DeclsInGroup.push_back(Actions.LookupOrCreateLabel(II, IdLoc, LabelLoc));
707a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
7084ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner      if (!Tok.is(tok::comma))
7094ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner        break;
7104ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner      ConsumeToken();
7114ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner    }
712a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
7130b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall    DeclSpec DS(AttrFactory);
7144ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner    DeclGroupPtrTy Res = Actions.FinalizeDeclaratorGroup(getCurScope(), DS,
7154ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner                                      DeclsInGroup.data(), DeclsInGroup.size());
7164ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner    StmtResult R = Actions.ActOnDeclStmt(Res, LabelLoc, Tok.getLocation());
717a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
7188bb21d32e9ccc9d9c221506dff26acafa8724ccaChris Lattner    ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
7194ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner    if (R.isUsable())
7204ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner      Stmts.push_back(R.release());
7214ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner  }
722a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
7234ae493cccbfbf122ec6ebac0e330232c22fa8489Chris Lattner  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
724b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis    if (Tok.is(tok::annot_pragma_unused)) {
725b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis      HandlePragmaUnused();
726b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis      continue;
727b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis    }
728b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis
7294e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) ||
7301e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet        Tok.is(tok::kw___if_not_exists))) {
7311e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet      ParseMicrosoftIfExistsStatement(Stmts);
7321e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet      continue;
7331e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet    }
7341e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet
73560d7b3a319d84d688752be3870615ac0f111fb16John McCall    StmtResult R;
7364e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner    if (Tok.isNot(tok::kw___extension__)) {
737c5be7b0fc804d8e6f87298ec03c94d8cccd74f29Fariborz Jahanian      R = ParseStatementOrDeclaration(Stmts, false);
73845a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner    } else {
73945a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner      // __extension__ can start declarations and it can also be a unary
74045a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner      // operator for expressions.  Consume multiple __extension__ markers here
74145a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner      // until we can determine which is which.
742adf077f46ba5cddcd801a647a5e9a3eb97060df4Eli Friedman      // FIXME: This loses extension expressions in the AST!
74345a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner      SourceLocation ExtLoc = ConsumeToken();
7444e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner      while (Tok.is(tok::kw___extension__))
74545a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner        ConsumeToken();
74639146d6497ad5e7ca8ef639221e7b3e15d07c888Chris Lattner
7470b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall      ParsedAttributesWithRange attrs(AttrFactory);
7486ee326af4e77e6f05973486097884d7431f2108dRichard Smith      MaybeParseCXX0XAttributes(attrs, 0, /*MightBeObjCMessageSend*/ true);
749bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
75045a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner      // If this is the start of a declaration, parse it as such.
7515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      if (isDeclarationStatement()) {
752bc6c848f3e0ec2dc44f6e3d59ef85e884cc9b7beEli Friedman        // __extension__ silences extension warnings in the subdeclaration.
75397144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner        // FIXME: Save the __extension__ on the decl as a node somehow?
754bc6c848f3e0ec2dc44f6e3d59ef85e884cc9b7beEli Friedman        ExtensionRAIIObject O(Diags);
755bc6c848f3e0ec2dc44f6e3d59ef85e884cc9b7beEli Friedman
75697144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner        SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
757c5be7b0fc804d8e6f87298ec03c94d8cccd74f29Fariborz Jahanian        DeclGroupPtrTy Res = ParseDeclaration(Stmts,
758c5be7b0fc804d8e6f87298ec03c94d8cccd74f29Fariborz Jahanian                                              Declarator::BlockContext, DeclEnd,
7597f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                              attrs);
76097144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner        R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);
76145a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner      } else {
762adf077f46ba5cddcd801a647a5e9a3eb97060df4Eli Friedman        // Otherwise this was a unary __extension__ marker.
76360d7b3a319d84d688752be3870615ac0f111fb16John McCall        ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
764043a0b50a2a7a29c78a1ffb774f6fca8baf464a0Chris Lattner
7650e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl        if (Res.isInvalid()) {
76645a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner          SkipUntil(tok::semi);
76745a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner          continue;
76845a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner        }
769f512e82f56671b695a32d019103e62a302838b7eSebastian Redl
770bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        // FIXME: Use attributes?
77139146d6497ad5e7ca8ef639221e7b3e15d07c888Chris Lattner        // Eat the semicolon at the end of stmt and convert the expr into a
77239146d6497ad5e7ca8ef639221e7b3e15d07c888Chris Lattner        // statement.
7739ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor        ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
7749ae2f076ca5ab1feb3ba95629099ec2319833701John McCall        R = Actions.ActOnExprStmt(Actions.MakeFullExpr(Res.get()));
77545a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner      }
77645a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner    }
77761364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
7780e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl    if (R.isUsable())
779effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl      Stmts.push_back(R.release());
7805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
78161364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
7825d5ed59f1ee57ad2639f0ef1fb400f8854480bb0Argyrios Kyrtzidis  SourceLocation CloseLoc = Tok.getLocation();
7835d5ed59f1ee57ad2639f0ef1fb400f8854480bb0Argyrios Kyrtzidis
7845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // We broke out of the while loop because we found a '}' or EOF.
7854e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (Tok.isNot(tok::r_brace)) {
7865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Diag(Tok, diag::err_expected_rbrace);
7874a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    Diag(T.getOpenLocation(), diag::note_matching) << "{";
7885d5ed59f1ee57ad2639f0ef1fb400f8854480bb0Argyrios Kyrtzidis    // Recover by creating a compound statement with what we parsed so far,
7895d5ed59f1ee57ad2639f0ef1fb400f8854480bb0Argyrios Kyrtzidis    // instead of dropping everything and returning StmtError();
7905d5ed59f1ee57ad2639f0ef1fb400f8854480bb0Argyrios Kyrtzidis  } else {
7915d5ed59f1ee57ad2639f0ef1fb400f8854480bb0Argyrios Kyrtzidis    if (!T.consumeClose())
7925d5ed59f1ee57ad2639f0ef1fb400f8854480bb0Argyrios Kyrtzidis      CloseLoc = T.getCloseLocation();
7935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
79461364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
7955d5ed59f1ee57ad2639f0ef1fb400f8854480bb0Argyrios Kyrtzidis  return Actions.ActOnCompoundStmt(T.getOpenLocation(), CloseLoc,
7963fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer                                   Stmts, isStmtExpr);
7975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
7985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
79915ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner/// ParseParenExprOrCondition:
80015ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner/// [C  ]     '(' expression ')'
801ff871fb8f9c5906a4dee78afd81f60c3837e16cbChris Lattner/// [C++]     '(' condition ')'       [not allowed if OnlyAllowCondition=true]
80215ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner///
80315ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner/// This function parses and performs error recovery on the specified condition
80415ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner/// or expression (depending on whether we're in C++ or C mode).  This function
80515ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner/// goes out of its way to recover well.  It returns true if there was a parser
80615ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner/// error (the right paren couldn't be found), which indicates that the caller
80715ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner/// should try to recover harder.  It returns false if the condition is
80815ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner/// successfully parsed.  Note that a successful parse can still have semantic
80915ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner/// errors in the condition.
81060d7b3a319d84d688752be3870615ac0f111fb16John McCallbool Parser::ParseParenExprOrCondition(ExprResult &ExprResult,
811d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall                                       Decl *&DeclResult,
812586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor                                       SourceLocation Loc,
81344aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis                                       bool ConvertToBoolean) {
8144a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_paren);
8154a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeOpen();
8164a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor
8174e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().CPlusPlus)
818dec0984fce504a39a7f085774fb67cfd9957be58Jeffrey Yasskin    ParseCXXCondition(ExprResult, DeclResult, Loc, ConvertToBoolean);
81999e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor  else {
82099e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor    ExprResult = ParseExpression();
821d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    DeclResult = 0;
822a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
823586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor    // If required, convert to a boolean value.
824586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor    if (!ExprResult.isInvalid() && ConvertToBoolean)
825586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor      ExprResult
8269ae2f076ca5ab1feb3ba95629099ec2319833701John McCall        = Actions.ActOnBooleanCondition(getCurScope(), Loc, ExprResult.get());
82799e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor  }
8281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
82915ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner  // If the parser was confused by the condition and we don't have a ')', try to
83015ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner  // recover by skipping ahead to a semi and bailing out.  If condexp is
83115ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner  // semantically invalid but we have well formed code, keep going.
832d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  if (ExprResult.isInvalid() && !DeclResult && Tok.isNot(tok::r_paren)) {
83315ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner    SkipUntil(tok::semi);
83415ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner    // Skipping may have stopped if it found the containing ')'.  If so, we can
83515ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner    // continue parsing the if statement.
83615ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner    if (Tok.isNot(tok::r_paren))
83715ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner      return true;
83815ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner  }
8391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
84015ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner  // Otherwise the condition is valid or the rparen is present.
8414a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
842b660446bcf47bfbcdebaf65a6616c4046579987aChad Rosier
843bddc7e5ed3982b5845e4fbb5d9bc7b7431c35a4fChris Lattner  // Check for extraneous ')'s to catch things like "if (foo())) {".  We know
844bddc7e5ed3982b5845e4fbb5d9bc7b7431c35a4fChris Lattner  // that all callers are looking for a statement after the condition, so ")"
845bddc7e5ed3982b5845e4fbb5d9bc7b7431c35a4fChris Lattner  // isn't valid.
846bddc7e5ed3982b5845e4fbb5d9bc7b7431c35a4fChris Lattner  while (Tok.is(tok::r_paren)) {
847bddc7e5ed3982b5845e4fbb5d9bc7b7431c35a4fChris Lattner    Diag(Tok, diag::err_extraneous_rparen_in_condition)
848bddc7e5ed3982b5845e4fbb5d9bc7b7431c35a4fChris Lattner      << FixItHint::CreateRemoval(Tok.getLocation());
849bddc7e5ed3982b5845e4fbb5d9bc7b7431c35a4fChris Lattner    ConsumeParen();
850bddc7e5ed3982b5845e4fbb5d9bc7b7431c35a4fChris Lattner  }
851b660446bcf47bfbcdebaf65a6616c4046579987aChad Rosier
85215ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner  return false;
85315ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner}
85415ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner
85515ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner
8565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseIfStatement
8575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       if-statement: [C99 6.8.4.1]
8585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'if' '(' expression ')' statement
8595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'if' '(' expression ')' statement 'else' statement
86071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++]   'if' '(' condition ')' statement
86171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++]   'if' '(' condition ')' statement 'else' statement
8625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
863534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
8644e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  assert(Tok.is(tok::kw_if) && "Not an if stmt!");
8655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation IfLoc = ConsumeToken();  // eat the 'if'.
8665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
8674e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (Tok.isNot(tok::l_paren)) {
8681ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_lparen_after) << "if";
8695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SkipUntil(tok::semi);
87061364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl    return StmtError();
8715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
87271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis
8734e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
874488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis
8752215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  // C99 6.8.4p3 - In C99, the if statement is a block.  This is not
8762215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  // the case for C90.
877488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
878488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // C++ 6.4p3:
879488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // A name introduced by a declaration in a condition is in scope from its
880488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // point of declaration until the end of the substatements controlled by the
881488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // condition.
88214d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // C++ 3.3.2p4:
88314d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // Names declared in the for-init-statement, and in the condition of if,
88414d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // while, for, and switch statements are local to the if, while, for, or
88514d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // switch statement (including the controlled statement).
886488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
8878935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  ParseScope IfScope(this, Scope::DeclScope | Scope::ControlScope, C99orCXX);
8882215325a5696fb3b23551239b900559bb3018ee9Chris Lattner
8895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Parse the condition.
89060d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult CondExp;
891d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  Decl *CondVar = 0;
89244aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis  if (ParseParenExprOrCondition(CondExp, CondVar, IfLoc, true))
89315ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner    return StmtError();
89418914bcb22774137ba720e5fcb377150bf2f6de3Chris Lattner
895def07624ecc535431e0c814b4b5b842de8a06997David Blaikie  FullExprArg FullCondExp(Actions.MakeFullExpr(CondExp.get(), IfLoc));
8961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8970ecea03077117c7ea54c88091a44c73cef67923cChris Lattner  // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
89838484403c8356fb41540ace6c74f28867f28febaChris Lattner  // there is no compound stmt.  C90 does not have this clause.  We only do this
89938484403c8356fb41540ace6c74f28867f28febaChris Lattner  // if the body isn't a compound statement to avoid push/pop in common cases.
900488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
901488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // C++ 6.4p1:
902488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // The substatement in a selection-statement (each substatement, in the else
903488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // form of the if statement) implicitly defines a local scope.
904488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
905488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // For C++ we create a scope for the condition and a new scope for
906488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // substatements because:
907488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // -When the 'then' scope exits, we want the condition declaration to still be
908488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //    active for the 'else' scope too.
909488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // -Sema will detect name clashes by considering declarations of a
910488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //    'ControlScope' as part of its direct subscope.
911488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // -If we wanted the condition and substatement to be in the same scope, we
912488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //    would have to notify ParseStatement not to create a new scope. It's
913488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //    simpler to let it create a new scope.
914488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
9151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ParseScope InnerScope(this, Scope::DeclScope,
9168935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor                        C99orCXX && Tok.isNot(tok::l_brace));
91771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis
918b96728d90abc35a520798066d2a75ca36400a617Chris Lattner  // Read the 'then' stmt.
919b96728d90abc35a520798066d2a75ca36400a617Chris Lattner  SourceLocation ThenStmtLoc = Tok.getLocation();
9205cb94a78202ccb1007df0be86884297761f4a53aNico Weber
9215cb94a78202ccb1007df0be86884297761f4a53aNico Weber  SourceLocation InnerStatementTrailingElseLoc;
9225cb94a78202ccb1007df0be86884297761f4a53aNico Weber  StmtResult ThenStmt(ParseStatement(&InnerStatementTrailingElseLoc));
9235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
924a36ce713cff561b88f1cba5aad3f384c0fb0a249Chris Lattner  // Pop the 'if' scope if needed.
9258935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  InnerScope.Exit();
92661364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
9275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If it has an else, parse it.
9285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation ElseLoc;
929b96728d90abc35a520798066d2a75ca36400a617Chris Lattner  SourceLocation ElseStmtLoc;
93060d7b3a319d84d688752be3870615ac0f111fb16John McCall  StmtResult ElseStmt;
9310e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
9324e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (Tok.is(tok::kw_else)) {
9335cb94a78202ccb1007df0be86884297761f4a53aNico Weber    if (TrailingElseLoc)
9345cb94a78202ccb1007df0be86884297761f4a53aNico Weber      *TrailingElseLoc = Tok.getLocation();
9355cb94a78202ccb1007df0be86884297761f4a53aNico Weber
9365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ElseLoc = ConsumeToken();
937966c78b79004061c1f64feff96818b9f1d68ea58Chris Lattner    ElseStmtLoc = Tok.getLocation();
93861364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
9390ecea03077117c7ea54c88091a44c73cef67923cChris Lattner    // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
94038484403c8356fb41540ace6c74f28867f28febaChris Lattner    // there is no compound stmt.  C90 does not have this clause.  We only do
94138484403c8356fb41540ace6c74f28867f28febaChris Lattner    // this if the body isn't a compound statement to avoid push/pop in common
94238484403c8356fb41540ace6c74f28867f28febaChris Lattner    // cases.
943488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis    //
944488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis    // C++ 6.4p1:
945488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis    // The substatement in a selection-statement (each substatement, in the else
946488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis    // form of the if statement) implicitly defines a local scope.
947488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis    //
94861364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl    ParseScope InnerScope(this, Scope::DeclScope,
9498935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor                          C99orCXX && Tok.isNot(tok::l_brace));
9500e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
9515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ElseStmt = ParseStatement();
952a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
953a36ce713cff561b88f1cba5aad3f384c0fb0a249Chris Lattner    // Pop the 'else' scope if needed.
9548935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor    InnerScope.Exit();
955d2d8be6a27d0ef73d46039604682f7890e1cc3e0Douglas Gregor  } else if (Tok.is(tok::code_completion)) {
956d2d8be6a27d0ef73d46039604682f7890e1cc3e0Douglas Gregor    Actions.CodeCompleteAfterIf(getCurScope());
9577d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
9587d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return StmtError();
9595cb94a78202ccb1007df0be86884297761f4a53aNico Weber  } else if (InnerStatementTrailingElseLoc.isValid()) {
9605cb94a78202ccb1007df0be86884297761f4a53aNico Weber    Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else);
9615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
96261364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
9638935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  IfScope.Exit();
9641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
96518914bcb22774137ba720e5fcb377150bf2f6de3Chris Lattner  // If the condition was invalid, discard the if statement.  We could recover
96618914bcb22774137ba720e5fcb377150bf2f6de3Chris Lattner  // better by replacing it with a valid expr, but don't do that yet.
967d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  if (CondExp.isInvalid() && !CondVar)
96818914bcb22774137ba720e5fcb377150bf2f6de3Chris Lattner    return StmtError();
9692215325a5696fb3b23551239b900559bb3018ee9Chris Lattner
970b96728d90abc35a520798066d2a75ca36400a617Chris Lattner  // If the then or else stmt is invalid and the other is valid (and present),
9711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // make turn the invalid one into a null stmt to avoid dropping the other
972b96728d90abc35a520798066d2a75ca36400a617Chris Lattner  // part.  If both are invalid, return error.
9730e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl  if ((ThenStmt.isInvalid() && ElseStmt.isInvalid()) ||
9740e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      (ThenStmt.isInvalid() && ElseStmt.get() == 0) ||
9750e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      (ThenStmt.get() == 0  && ElseStmt.isInvalid())) {
976a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl    // Both invalid, or one is invalid and other is non-present: return error.
97761364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl    return StmtError();
978b96728d90abc35a520798066d2a75ca36400a617Chris Lattner  }
9790e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
980b96728d90abc35a520798066d2a75ca36400a617Chris Lattner  // Now if either are invalid, replace with a ';'.
9810e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl  if (ThenStmt.isInvalid())
982b96728d90abc35a520798066d2a75ca36400a617Chris Lattner    ThenStmt = Actions.ActOnNullStmt(ThenStmtLoc);
9830e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl  if (ElseStmt.isInvalid())
984b96728d90abc35a520798066d2a75ca36400a617Chris Lattner    ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);
9850e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
9869ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  return Actions.ActOnIfStmt(IfLoc, FullCondExp, CondVar, ThenStmt.get(),
98744aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis                             ElseLoc, ElseStmt.get());
9885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
9895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
9905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseSwitchStatement
9915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       switch-statement:
9925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'switch' '(' expression ')' statement
99371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++]   'switch' '(' condition ')' statement
994534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseSwitchStatement(SourceLocation *TrailingElseLoc) {
9954e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  assert(Tok.is(tok::kw_switch) && "Not a switch stmt!");
9965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation SwitchLoc = ConsumeToken();  // eat the 'switch'.
9975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
9984e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (Tok.isNot(tok::l_paren)) {
9991ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_lparen_after) << "switch";
10005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SkipUntil(tok::semi);
10019a920342707e384473b464528d2fd286e8c70353Sebastian Redl    return StmtError();
10025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
10032215325a5696fb3b23551239b900559bb3018ee9Chris Lattner
10044e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
1005488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis
10062215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  // C99 6.8.4p3 - In C99, the switch statement is a block.  This is
10072215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  // not the case for C90.  Start the switch scope.
1008488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1009488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // C++ 6.4p3:
1010488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // A name introduced by a declaration in a condition is in scope from its
1011488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // point of declaration until the end of the substatements controlled by the
1012488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // condition.
101314d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // C++ 3.3.2p4:
101414d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // Names declared in the for-init-statement, and in the condition of if,
101514d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // while, for, and switch statements are local to the if, while, for, or
101614d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // switch statement (including the controlled statement).
1017488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1018bb9b80c308d7d3f758886243c7145404a50c66cfRichard Trieu  unsigned ScopeFlags = Scope::BreakScope | Scope::SwitchScope;
101915ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner  if (C99orCXX)
102015ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner    ScopeFlags |= Scope::DeclScope | Scope::ControlScope;
10218935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  ParseScope SwitchScope(this, ScopeFlags);
10225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
10235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Parse the condition.
102460d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult Cond;
1025d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  Decl *CondVar = 0;
1026586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor  if (ParseParenExprOrCondition(Cond, CondVar, SwitchLoc, false))
10279a920342707e384473b464528d2fd286e8c70353Sebastian Redl    return StmtError();
10282342ef75797a2ad6c9d7a784cfff220fd1a66008Eli Friedman
102960d7b3a319d84d688752be3870615ac0f111fb16John McCall  StmtResult Switch
10309ae2f076ca5ab1feb3ba95629099ec2319833701John McCall    = Actions.ActOnStartOfSwitchStmt(SwitchLoc, Cond.get(), CondVar);
1031586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor
1032586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor  if (Switch.isInvalid()) {
1033a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi    // Skip the switch body.
1034586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor    // FIXME: This is not optimal recovery, but parsing the body is more
1035586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor    // dangerous due to the presence of case and default statements, which
1036586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor    // will have no place to connect back with the switch.
10374186ff4fc4102f63b7485c2bf89155d3b0899d32Douglas Gregor    if (Tok.is(tok::l_brace)) {
10384186ff4fc4102f63b7485c2bf89155d3b0899d32Douglas Gregor      ConsumeBrace();
10394186ff4fc4102f63b7485c2bf89155d3b0899d32Douglas Gregor      SkipUntil(tok::r_brace, false, false);
10404186ff4fc4102f63b7485c2bf89155d3b0899d32Douglas Gregor    } else
1041586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor      SkipUntil(tok::semi);
10423fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer    return Switch;
1043586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor  }
1044a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
10450ecea03077117c7ea54c88091a44c73cef67923cChris Lattner  // C99 6.8.4p3 - In C99, the body of the switch statement is a scope, even if
104638484403c8356fb41540ace6c74f28867f28febaChris Lattner  // there is no compound stmt.  C90 does not have this clause.  We only do this
104738484403c8356fb41540ace6c74f28867f28febaChris Lattner  // if the body isn't a compound statement to avoid push/pop in common cases.
1048488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1049488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // C++ 6.4p1:
1050488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // The substatement in a selection-statement (each substatement, in the else
1051488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // form of the if statement) implicitly defines a local scope.
1052488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1053488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // See comments in ParseIfStatement for why we create a scope for the
1054488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // condition and a new scope for substatement in C++.
1055488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
10561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ParseScope InnerScope(this, Scope::DeclScope,
10578935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor                        C99orCXX && Tok.isNot(tok::l_brace));
105861364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
10595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Read the body statement.
10605cb94a78202ccb1007df0be86884297761f4a53aNico Weber  StmtResult Body(ParseStatement(TrailingElseLoc));
10615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
10627e52de4b45286d057b367bb1f9283a1e32d79252Chris Lattner  // Pop the scopes.
10638935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  InnerScope.Exit();
10648935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  SwitchScope.Exit();
106561364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
1066625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  if (Body.isInvalid()) {
10677e52de4b45286d057b367bb1f9283a1e32d79252Chris Lattner    // FIXME: Remove the case statement list from the Switch statement.
1068625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
1069625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko    // Put the synthesized null statement on the same line as the end of switch
1070625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko    // condition.
1071625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko    SourceLocation SynthesizedNullStmtLocation = Cond.get()->getLocEnd();
1072625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko    Body = Actions.ActOnNullStmt(SynthesizedNullStmtLocation);
1073625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  }
1074a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
10759ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.get(), Body.get());
10765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
10775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
10785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseWhileStatement
10795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       while-statement: [C99 6.8.5.1]
10805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'while' '(' expression ')' statement
108171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++]   'while' '(' condition ')' statement
1082534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseWhileStatement(SourceLocation *TrailingElseLoc) {
10834e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  assert(Tok.is(tok::kw_while) && "Not a while stmt!");
10845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation WhileLoc = Tok.getLocation();
10855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ConsumeToken();  // eat the 'while'.
10869a920342707e384473b464528d2fd286e8c70353Sebastian Redl
10874e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (Tok.isNot(tok::l_paren)) {
10881ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_lparen_after) << "while";
10895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SkipUntil(tok::semi);
10909a920342707e384473b464528d2fd286e8c70353Sebastian Redl    return StmtError();
10915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
10929a920342707e384473b464528d2fd286e8c70353Sebastian Redl
10934e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
1094488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis
10952215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  // C99 6.8.5p5 - In C99, the while statement is a block.  This is not
10962215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  // the case for C90.  Start the loop scope.
1097488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1098488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // C++ 6.4p3:
1099488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // A name introduced by a declaration in a condition is in scope from its
1100488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // point of declaration until the end of the substatements controlled by the
1101488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // condition.
110214d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // C++ 3.3.2p4:
110314d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // Names declared in the for-init-statement, and in the condition of if,
110414d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // while, for, and switch statements are local to the if, while, for, or
110514d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // switch statement (including the controlled statement).
1106488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
11078935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  unsigned ScopeFlags;
1108488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  if (C99orCXX)
11098935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor    ScopeFlags = Scope::BreakScope | Scope::ContinueScope |
11108935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor                 Scope::DeclScope  | Scope::ControlScope;
11112215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  else
11128935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor    ScopeFlags = Scope::BreakScope | Scope::ContinueScope;
11138935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  ParseScope WhileScope(this, ScopeFlags);
11145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
11155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Parse the condition.
111660d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult Cond;
1117d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  Decl *CondVar = 0;
1118586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor  if (ParseParenExprOrCondition(Cond, CondVar, WhileLoc, true))
111915ff1110c96a26c9315142d407c1f29d86a5ad1fChris Lattner    return StmtError();
11200e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
1121def07624ecc535431e0c814b4b5b842de8a06997David Blaikie  FullExprArg FullCond(Actions.MakeFullExpr(Cond.get(), WhileLoc));
11221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11230ecea03077117c7ea54c88091a44c73cef67923cChris Lattner  // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
112438484403c8356fb41540ace6c74f28867f28febaChris Lattner  // there is no compound stmt.  C90 does not have this clause.  We only do this
112538484403c8356fb41540ace6c74f28867f28febaChris Lattner  // if the body isn't a compound statement to avoid push/pop in common cases.
1126488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1127488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // C++ 6.5p2:
1128488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // The substatement in an iteration-statement implicitly defines a local scope
1129488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // which is entered and exited each time through the loop.
1130488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1131488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // See comments in ParseIfStatement for why we create a scope for the
1132488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // condition and a new scope for substatement in C++.
1133488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
11341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ParseScope InnerScope(this, Scope::DeclScope,
11358935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor                        C99orCXX && Tok.isNot(tok::l_brace));
11369a920342707e384473b464528d2fd286e8c70353Sebastian Redl
11375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Read the body statement.
11385cb94a78202ccb1007df0be86884297761f4a53aNico Weber  StmtResult Body(ParseStatement(TrailingElseLoc));
11395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
11400ecea03077117c7ea54c88091a44c73cef67923cChris Lattner  // Pop the body scope if needed.
11418935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  InnerScope.Exit();
11428935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  WhileScope.Exit();
11439a920342707e384473b464528d2fd286e8c70353Sebastian Redl
1144d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  if ((Cond.isInvalid() && !CondVar) || Body.isInvalid())
11459a920342707e384473b464528d2fd286e8c70353Sebastian Redl    return StmtError();
11469a920342707e384473b464528d2fd286e8c70353Sebastian Redl
11479ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  return Actions.ActOnWhileStmt(WhileLoc, FullCond, CondVar, Body.get());
11485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
11495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
11505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseDoStatement
11515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       do-statement: [C99 6.8.5.2]
11525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'do' statement 'while' '(' expression ')' ';'
11535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Note: this lets the caller parse the end ';'.
1154534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseDoStatement() {
11554e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  assert(Tok.is(tok::kw_do) && "Not a do stmt!");
11565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation DoLoc = ConsumeToken();  // eat the 'do'.
11579a920342707e384473b464528d2fd286e8c70353Sebastian Redl
11582215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  // C99 6.8.5p5 - In C99, the do statement is a block.  This is not
11592215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  // the case for C90.  Start the loop scope.
11608935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  unsigned ScopeFlags;
11614e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().C99)
11628935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor    ScopeFlags = Scope::BreakScope | Scope::ContinueScope | Scope::DeclScope;
11632215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  else
11648935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor    ScopeFlags = Scope::BreakScope | Scope::ContinueScope;
11659a920342707e384473b464528d2fd286e8c70353Sebastian Redl
11668935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  ParseScope DoScope(this, ScopeFlags);
11675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
11680ecea03077117c7ea54c88091a44c73cef67923cChris Lattner  // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
116938484403c8356fb41540ace6c74f28867f28febaChris Lattner  // there is no compound stmt.  C90 does not have this clause. We only do this
117038484403c8356fb41540ace6c74f28867f28febaChris Lattner  // if the body isn't a compound statement to avoid push/pop in common cases.
1171143db71d8d87bc015fb496f71ef83b268813835aArgyrios Kyrtzidis  //
1172143db71d8d87bc015fb496f71ef83b268813835aArgyrios Kyrtzidis  // C++ 6.5p2:
1173143db71d8d87bc015fb496f71ef83b268813835aArgyrios Kyrtzidis  // The substatement in an iteration-statement implicitly defines a local scope
1174143db71d8d87bc015fb496f71ef83b268813835aArgyrios Kyrtzidis  // which is entered and exited each time through the loop.
1175143db71d8d87bc015fb496f71ef83b268813835aArgyrios Kyrtzidis  //
11768935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  ParseScope InnerScope(this, Scope::DeclScope,
11774e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie                        (getLangOpts().C99 || getLangOpts().CPlusPlus) &&
11788935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor                        Tok.isNot(tok::l_brace));
11799a920342707e384473b464528d2fd286e8c70353Sebastian Redl
11805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Read the body statement.
118160d7b3a319d84d688752be3870615ac0f111fb16John McCall  StmtResult Body(ParseStatement());
11825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
11830ecea03077117c7ea54c88091a44c73cef67923cChris Lattner  // Pop the body scope if needed.
11848935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  InnerScope.Exit();
11850ecea03077117c7ea54c88091a44c73cef67923cChris Lattner
11864e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (Tok.isNot(tok::kw_while)) {
11870e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl    if (!Body.isInvalid()) {
1188195044028b76133e2a1f245b094468fe07db7330Chris Lattner      Diag(Tok, diag::err_expected_while);
118928eb7e992b9a266abb300da25b6d3c1557cec361Chris Lattner      Diag(DoLoc, diag::note_matching) << "do";
1190195044028b76133e2a1f245b094468fe07db7330Chris Lattner      SkipUntil(tok::semi, false, true);
1191195044028b76133e2a1f245b094468fe07db7330Chris Lattner    }
11929a920342707e384473b464528d2fd286e8c70353Sebastian Redl    return StmtError();
11935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
11945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation WhileLoc = ConsumeToken();
11959a920342707e384473b464528d2fd286e8c70353Sebastian Redl
11964e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (Tok.isNot(tok::l_paren)) {
11971ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_lparen_after) << "do/while";
1198195044028b76133e2a1f245b094468fe07db7330Chris Lattner    SkipUntil(tok::semi, false, true);
11999a920342707e384473b464528d2fd286e8c70353Sebastian Redl    return StmtError();
12005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
12019a920342707e384473b464528d2fd286e8c70353Sebastian Redl
1202ff871fb8f9c5906a4dee78afd81f60c3837e16cbChris Lattner  // Parse the parenthesized condition.
12034a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_paren);
12044a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeOpen();
1205b660446bcf47bfbcdebaf65a6616c4046579987aChad Rosier
12062edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt  // FIXME: Do not just parse the attribute contents and throw them away
12072edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt  ParsedAttributesWithRange attrs(AttrFactory);
12082edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt  MaybeParseCXX0XAttributes(attrs);
12092edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt  ProhibitAttributes(attrs);
12102edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt
121160d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult Cond = ParseExpression();
12124a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
12138935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  DoScope.Exit();
12140e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
12159a920342707e384473b464528d2fd286e8c70353Sebastian Redl  if (Cond.isInvalid() || Body.isInvalid())
12169a920342707e384473b464528d2fd286e8c70353Sebastian Redl    return StmtError();
12170e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
12184a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  return Actions.ActOnDoStmt(DoLoc, Body.get(), WhileLoc, T.getOpenLocation(),
12194a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                             Cond.get(), T.getCloseLocation());
12205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
12215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
12225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseForStatement
12235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       for-statement: [C99 6.8.5.3]
12245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'for' '(' expr[opt] ';' expr[opt] ';' expr[opt] ')' statement
12255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'for' '(' declaration expr[opt] ';' expr[opt] ')' statement
122671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++]   'for' '(' for-init-statement condition[opt] ';' expression[opt] ')'
122771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++]       statement
1228ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith/// [C++0x] 'for' '(' for-range-declaration : for-range-initializer ) statement
12293ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian/// [OBJC2] 'for' '(' declaration 'in' expr ')' statement
12303ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian/// [OBJC2] 'for' '(' expr 'in' expr ')' statement
123171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis///
123271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++] for-init-statement:
123371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++]   expression-statement
123471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++]   simple-declaration
123571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis///
1236ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith/// [C++0x] for-range-declaration:
1237ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith/// [C++0x]   attribute-specifier-seq[opt] type-specifier-seq declarator
1238ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith/// [C++0x] for-range-initializer:
1239ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith/// [C++0x]   expression
1240ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith/// [C++0x]   braced-init-list            [TODO]
1241534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
12424e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  assert(Tok.is(tok::kw_for) && "Not a for stmt!");
12435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation ForLoc = ConsumeToken();  // eat the 'for'.
12449a920342707e384473b464528d2fd286e8c70353Sebastian Redl
12454e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (Tok.isNot(tok::l_paren)) {
12461ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_lparen_after) << "for";
12475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SkipUntil(tok::semi);
12489a920342707e384473b464528d2fd286e8c70353Sebastian Redl    return StmtError();
12495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
12509a920342707e384473b464528d2fd286e8c70353Sebastian Redl
1251b660446bcf47bfbcdebaf65a6616c4046579987aChad Rosier  bool C99orCXXorObjC = getLangOpts().C99 || getLangOpts().CPlusPlus ||
1252b660446bcf47bfbcdebaf65a6616c4046579987aChad Rosier    getLangOpts().ObjC1;
1253488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis
12542215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  // C99 6.8.5p5 - In C99, the for statement is a block.  This is not
12552215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  // the case for C90.  Start the loop scope.
1256488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1257488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // C++ 6.4p3:
1258488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // A name introduced by a declaration in a condition is in scope from its
1259488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // point of declaration until the end of the substatements controlled by the
1260488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // condition.
126114d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // C++ 3.3.2p4:
126214d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // Names declared in the for-init-statement, and in the condition of if,
126314d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // while, for, and switch statements are local to the if, while, for, or
126414d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis  // switch statement (including the controlled statement).
1265488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // C++ 6.5.3p1:
1266488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // Names declared in the for-init-statement are in the same declarative-region
1267488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // as those declared in the condition.
1268488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
12698935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  unsigned ScopeFlags;
12704d00f2a5a9b670cd0d67d640a42dbf7b9f342c59Chris Lattner  if (C99orCXXorObjC)
12718935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor    ScopeFlags = Scope::BreakScope | Scope::ContinueScope |
12728935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor                 Scope::DeclScope  | Scope::ControlScope;
12732215325a5696fb3b23551239b900559bb3018ee9Chris Lattner  else
12748935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor    ScopeFlags = Scope::BreakScope | Scope::ContinueScope;
12758935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor
12768935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  ParseScope ForScope(this, ScopeFlags);
12775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
12784a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_paren);
12794a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeOpen();
12804a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor
128160d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult Value;
12820e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
1283ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  bool ForEach = false, ForRange = false;
128460d7b3a319d84d688752be3870615ac0f111fb16John McCall  StmtResult FirstPart;
1285eecf38f821fe8e113722096b77da7d68b26d28d1Douglas Gregor  bool SecondPartIsInvalid = false;
1286586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor  FullExprArg SecondPart(Actions);
128760d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult Collection;
1288ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  ForRangeInit ForRangeInit;
1289586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor  FullExprArg ThirdPart(Actions);
1290d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  Decl *SecondVar = 0;
1291a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
1292791215b7a24666912c0b71175d2ca5ba082f666eDouglas Gregor  if (Tok.is(tok::code_completion)) {
1293a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi    Actions.CodeCompleteOrdinaryName(getCurScope(),
1294f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                     C99orCXXorObjC? Sema::PCC_ForInit
1295f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                                   : Sema::PCC_Expression);
12967d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
12977d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return StmtError();
1298791215b7a24666912c0b71175d2ca5ba082f666eDouglas Gregor  }
1299a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
13002edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt  ParsedAttributesWithRange attrs(AttrFactory);
13012edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt  MaybeParseCXX0XAttributes(attrs);
13022edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt
13035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Parse the first part of the for specifier.
13044e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (Tok.is(tok::semi)) {  // for (;
13052edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt    ProhibitAttributes(attrs);
13065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // no first part, eat the ';'.
13075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ConsumeToken();
13089490ab433deef70105d817616928d700f87642d9Eli Friedman  } else if (isForInitDeclaration()) {  // for (int X = 4;
13095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Parse declaration, which eats the ';'.
13104d00f2a5a9b670cd0d67d640a42dbf7b9f342c59Chris Lattner    if (!C99orCXXorObjC)   // Use of C99-style for loops in C90 mode?
13115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
13129a920342707e384473b464528d2fd286e8c70353Sebastian Redl
13130b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall    ParsedAttributesWithRange attrs(AttrFactory);
13147f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    MaybeParseCXX0XAttributes(attrs);
1315bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1316ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    // In C++0x, "for (T NS:a" might not be a typo for ::
13174e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    bool MightBeForRangeStmt = getLangOpts().CPlusPlus;
1318ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    ColonProtectionRAIIObject ColonProtection(*this, MightBeForRangeStmt);
1319ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
132097144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
13214e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer    StmtVector Stmts;
1322a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi    DeclGroupPtrTy DG = ParseSimpleDeclaration(Stmts, Declarator::ForContext,
1323ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith                                               DeclEnd, attrs, false,
1324ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith                                               MightBeForRangeStmt ?
1325ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith                                                 &ForRangeInit : 0);
1326cd1477562e7cf03279850885583d615e1f631dd4Chris Lattner    FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
13271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1328ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    if (ForRangeInit.ParsedForRangeDecl()) {
13294e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie      Diag(ForRangeInit.ColonLoc, getLangOpts().CPlusPlus0x ?
13307fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith           diag::warn_cxx98_compat_for_range : diag::ext_for_range);
13318f4fb190852d3f86787c7e2c3dfc1b96143197aeRichard Smith
1332ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith      ForRange = true;
1333ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    } else if (Tok.is(tok::semi)) {  // for (int x = 4;
1334cd1477562e7cf03279850885583d615e1f631dd4Chris Lattner      ConsumeToken();
1335cd1477562e7cf03279850885583d615e1f631dd4Chris Lattner    } else if ((ForEach = isTokIdentifier_in())) {
1336a7cf23a72b0846fc5aacf3f38bb8c8f9e76784cfFariborz Jahanian      Actions.ActOnForEachDeclStmt(DG);
13371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      // ObjC: for (id x in expr)
13383ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian      ConsumeToken(); // consume 'in'
1339a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
1340fb6294123b9de1605adae69d85cb4fddf81a9bc5Douglas Gregor      if (Tok.is(tok::code_completion)) {
1341fb6294123b9de1605adae69d85cb4fddf81a9bc5Douglas Gregor        Actions.CodeCompleteObjCForCollection(getCurScope(), DG);
13427d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis        cutOffParsing();
13437d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis        return StmtError();
1344fb6294123b9de1605adae69d85cb4fddf81a9bc5Douglas Gregor      }
1345586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor      Collection = ParseExpression();
1346cd1477562e7cf03279850885583d615e1f631dd4Chris Lattner    } else {
1347cd1477562e7cf03279850885583d615e1f631dd4Chris Lattner      Diag(Tok, diag::err_expected_semi_for);
13483ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian    }
13495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  } else {
13502edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt    ProhibitAttributes(attrs);
13515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Value = ParseExpression();
13525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1353f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    ForEach = isTokIdentifier_in();
1354f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall
13555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Turn the expression into a stmt.
1356f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    if (!Value.isInvalid()) {
1357f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall      if (ForEach)
1358f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall        FirstPart = Actions.ActOnForEachLValueExpr(Value.get());
1359f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall      else
1360f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall        FirstPart = Actions.ActOnExprStmt(Actions.MakeFullExpr(Value.get()));
1361f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    }
1362effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl
13634e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner    if (Tok.is(tok::semi)) {
13645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      ConsumeToken();
1365f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    } else if (ForEach) {
13663ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian      ConsumeToken(); // consume 'in'
1367a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
1368fb6294123b9de1605adae69d85cb4fddf81a9bc5Douglas Gregor      if (Tok.is(tok::code_completion)) {
1369fb6294123b9de1605adae69d85cb4fddf81a9bc5Douglas Gregor        Actions.CodeCompleteObjCForCollection(getCurScope(), DeclGroupPtrTy());
13707d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis        cutOffParsing();
13717d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis        return StmtError();
1372fb6294123b9de1605adae69d85cb4fddf81a9bc5Douglas Gregor      }
1373586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor      Collection = ParseExpression();
13744e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    } else if (getLangOpts().CPlusPlus0x && Tok.is(tok::colon) && FirstPart.get()) {
1375a44854a23b3f090729d82f447aa88df4f6563263Richard Smith      // User tried to write the reasonable, but ill-formed, for-range-statement
1376a44854a23b3f090729d82f447aa88df4f6563263Richard Smith      //   for (expr : expr) { ... }
1377a44854a23b3f090729d82f447aa88df4f6563263Richard Smith      Diag(Tok, diag::err_for_range_expected_decl)
1378a44854a23b3f090729d82f447aa88df4f6563263Richard Smith        << FirstPart.get()->getSourceRange();
1379a44854a23b3f090729d82f447aa88df4f6563263Richard Smith      SkipUntil(tok::r_paren, false, true);
1380a44854a23b3f090729d82f447aa88df4f6563263Richard Smith      SecondPartIsInvalid = true;
1381682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    } else {
1382b72c77855473379c4c47e701005f7818946f659bDouglas Gregor      if (!Value.isInvalid()) {
1383b72c77855473379c4c47e701005f7818946f659bDouglas Gregor        Diag(Tok, diag::err_expected_semi_for);
1384b72c77855473379c4c47e701005f7818946f659bDouglas Gregor      } else {
1385b72c77855473379c4c47e701005f7818946f659bDouglas Gregor        // Skip until semicolon or rparen, don't consume it.
1386b72c77855473379c4c47e701005f7818946f659bDouglas Gregor        SkipUntil(tok::r_paren, true, true);
1387b72c77855473379c4c47e701005f7818946f659bDouglas Gregor        if (Tok.is(tok::semi))
1388b72c77855473379c4c47e701005f7818946f659bDouglas Gregor          ConsumeToken();
1389b72c77855473379c4c47e701005f7818946f659bDouglas Gregor      }
13905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
13915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1392ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  if (!ForEach && !ForRange) {
13939ae2f076ca5ab1feb3ba95629099ec2319833701John McCall    assert(!SecondPart.get() && "Shouldn't have a second expression yet.");
13943ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian    // Parse the second part of the for specifier.
13953ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian    if (Tok.is(tok::semi)) {  // for (...;;
13963ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian      // no second part.
1397b72c77855473379c4c47e701005f7818946f659bDouglas Gregor    } else if (Tok.is(tok::r_paren)) {
1398b72c77855473379c4c47e701005f7818946f659bDouglas Gregor      // missing both semicolons.
13993ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian    } else {
140060d7b3a319d84d688752be3870615ac0f111fb16John McCall      ExprResult Second;
14014e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie      if (getLangOpts().CPlusPlus)
1402586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor        ParseCXXCondition(Second, SecondVar, ForLoc, true);
1403586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor      else {
1404586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor        Second = ParseExpression();
1405586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor        if (!Second.isInvalid())
1406a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi          Second = Actions.ActOnBooleanCondition(getCurScope(), ForLoc,
14079ae2f076ca5ab1feb3ba95629099ec2319833701John McCall                                                 Second.get());
1408586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor      }
1409eecf38f821fe8e113722096b77da7d68b26d28d1Douglas Gregor      SecondPartIsInvalid = Second.isInvalid();
1410def07624ecc535431e0c814b4b5b842de8a06997David Blaikie      SecondPart = Actions.MakeFullExpr(Second.get(), ForLoc);
14113ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian    }
14120e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
1413b72c77855473379c4c47e701005f7818946f659bDouglas Gregor    if (Tok.isNot(tok::semi)) {
1414b72c77855473379c4c47e701005f7818946f659bDouglas Gregor      if (!SecondPartIsInvalid || SecondVar)
1415b72c77855473379c4c47e701005f7818946f659bDouglas Gregor        Diag(Tok, diag::err_expected_semi_for);
1416b72c77855473379c4c47e701005f7818946f659bDouglas Gregor      else
1417b72c77855473379c4c47e701005f7818946f659bDouglas Gregor        // Skip until semicolon or rparen, don't consume it.
1418b72c77855473379c4c47e701005f7818946f659bDouglas Gregor        SkipUntil(tok::r_paren, true, true);
1419b72c77855473379c4c47e701005f7818946f659bDouglas Gregor    }
1420b72c77855473379c4c47e701005f7818946f659bDouglas Gregor
14213ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian    if (Tok.is(tok::semi)) {
14223ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian      ConsumeToken();
14233ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian    }
14249a920342707e384473b464528d2fd286e8c70353Sebastian Redl
14253ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian    // Parse the third part of the for specifier.
1426586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor    if (Tok.isNot(tok::r_paren)) {   // for (...;...;)
142760d7b3a319d84d688752be3870615ac0f111fb16John McCall      ExprResult Third = ParseExpression();
14289ae2f076ca5ab1feb3ba95629099ec2319833701John McCall      ThirdPart = Actions.MakeFullExpr(Third.take());
1429586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor    }
14305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
14315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Match the ')'.
14324a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
14330e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
1434ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // We need to perform most of the semantic analysis for a C++0x for-range
1435ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // statememt before parsing the body, in order to be able to deduce the type
1436ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // of an auto-typed loop variable.
1437ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  StmtResult ForRangeStmt;
1438a1eec4bd198b96ef40a7c15cd0e131ca94511ad8Fariborz Jahanian  StmtResult ForEachStmt;
1439b660446bcf47bfbcdebaf65a6616c4046579987aChad Rosier
1440990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  if (ForRange) {
1441bc20bbb0bf90446a469848c658ca376832f43dc8Sam Panzer    ForRangeStmt = Actions.ActOnCXXForRangeStmt(ForLoc, FirstPart.take(),
1442ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith                                                ForRangeInit.ColonLoc,
1443ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith                                                ForRangeInit.RangeExpr.get(),
1444e1715b66a878bcab315513351e5df68bfc010d2eSam Panzer                                                T.getCloseLocation(), true);
1445ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
1446990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall
1447990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  // Similarly, we need to do the semantic analysis for a for-range
1448990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  // statement immediately in order to close over temporaries correctly.
1449990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  } else if (ForEach) {
1450bc20bbb0bf90446a469848c658ca376832f43dc8Sam Panzer    ForEachStmt = Actions.ActOnObjCForCollectionStmt(ForLoc,
1451a1eec4bd198b96ef40a7c15cd0e131ca94511ad8Fariborz Jahanian                                                     FirstPart.take(),
1452b660446bcf47bfbcdebaf65a6616c4046579987aChad Rosier                                                     Collection.take(),
1453a1eec4bd198b96ef40a7c15cd0e131ca94511ad8Fariborz Jahanian                                                     T.getCloseLocation());
1454990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  }
1455990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall
14560ecea03077117c7ea54c88091a44c73cef67923cChris Lattner  // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
145738484403c8356fb41540ace6c74f28867f28febaChris Lattner  // there is no compound stmt.  C90 does not have this clause.  We only do this
145838484403c8356fb41540ace6c74f28867f28febaChris Lattner  // if the body isn't a compound statement to avoid push/pop in common cases.
1459488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1460488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // C++ 6.5p2:
1461488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // The substatement in an iteration-statement implicitly defines a local scope
1462488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // which is entered and exited each time through the loop.
1463488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
1464488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // See comments in ParseIfStatement for why we create a scope for
1465488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  // for-init-statement/condition and a new scope for substatement in C++.
1466488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis  //
14671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ParseScope InnerScope(this, Scope::DeclScope,
14684d00f2a5a9b670cd0d67d640a42dbf7b9f342c59Chris Lattner                        C99orCXXorObjC && Tok.isNot(tok::l_brace));
14690e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
14705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Read the body statement.
14715cb94a78202ccb1007df0be86884297761f4a53aNico Weber  StmtResult Body(ParseStatement(TrailingElseLoc));
14720e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
14730ecea03077117c7ea54c88091a44c73cef67923cChris Lattner  // Pop the body scope if needed.
14748935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  InnerScope.Exit();
14750ecea03077117c7ea54c88091a44c73cef67923cChris Lattner
14765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Leave the for-scope.
14778935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  ForScope.Exit();
14780e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
14790e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl  if (Body.isInvalid())
14809a920342707e384473b464528d2fd286e8c70353Sebastian Redl    return StmtError();
1481effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl
1482ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  if (ForEach)
1483a1eec4bd198b96ef40a7c15cd0e131ca94511ad8Fariborz Jahanian   return Actions.FinishObjCForCollectionStmt(ForEachStmt.take(),
1484a1eec4bd198b96ef40a7c15cd0e131ca94511ad8Fariborz Jahanian                                              Body.take());
1485ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
1486ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  if (ForRange)
1487ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    return Actions.FinishCXXForRangeStmt(ForRangeStmt.take(), Body.take());
1488586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor
14894a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  return Actions.ActOnForStmt(ForLoc, T.getOpenLocation(), FirstPart.take(),
14904a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                              SecondPart, SecondVar, ThirdPart,
14914a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                              T.getCloseLocation(), Body.take());
14925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
14935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
14945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseGotoStatement
14955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       jump-statement:
14965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'goto' identifier ';'
14975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU]   'goto' '*' expression ';'
14985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
14995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Note: this lets the caller parse the end ';'.
15005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
1501534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseGotoStatement() {
15024e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");
15035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation GotoLoc = ConsumeToken();  // eat the 'goto'.
15049a920342707e384473b464528d2fd286e8c70353Sebastian Redl
150560d7b3a319d84d688752be3870615ac0f111fb16John McCall  StmtResult Res;
15064e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (Tok.is(tok::identifier)) {
1507337e550218128e7d922c09bb354fbc71de90c568Chris Lattner    LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(),
1508337e550218128e7d922c09bb354fbc71de90c568Chris Lattner                                                Tok.getLocation());
1509337e550218128e7d922c09bb354fbc71de90c568Chris Lattner    Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(), LD);
15105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ConsumeToken();
1511f01fdff97b245caac98100d232c760b4d0531411Eli Friedman  } else if (Tok.is(tok::star)) {
15125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // GNU indirect goto extension.
15135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Diag(Tok, diag::ext_gnu_indirect_goto);
15145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SourceLocation StarLoc = ConsumeToken();
151560d7b3a319d84d688752be3870615ac0f111fb16John McCall    ExprResult R(ParseExpression());
15160e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl    if (R.isInvalid()) {  // Skip to the semicolon, but don't consume it.
15175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      SkipUntil(tok::semi, false, true);
15189a920342707e384473b464528d2fd286e8c70353Sebastian Redl      return StmtError();
15195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
15209ae2f076ca5ab1feb3ba95629099ec2319833701John McCall    Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.take());
152195cfb85ad1820117e0864712555f3aa4fdf4721aChris Lattner  } else {
152295cfb85ad1820117e0864712555f3aa4fdf4721aChris Lattner    Diag(Tok, diag::err_expected_ident);
15239a920342707e384473b464528d2fd286e8c70353Sebastian Redl    return StmtError();
15245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
15250e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
15263fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer  return Res;
15275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
15285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
15295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseContinueStatement
15305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       jump-statement:
15315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'continue' ';'
15325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
15335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Note: this lets the caller parse the end ';'.
15345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
1535534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseContinueStatement() {
15365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation ContinueLoc = ConsumeToken();  // eat the 'continue'.
153723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  return Actions.ActOnContinueStmt(ContinueLoc, getCurScope());
15385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
15395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
15405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseBreakStatement
15415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       jump-statement:
15425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'break' ';'
15435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
15445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Note: this lets the caller parse the end ';'.
15455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
1546534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseBreakStatement() {
15475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation BreakLoc = ConsumeToken();  // eat the 'break'.
154823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  return Actions.ActOnBreakStmt(BreakLoc, getCurScope());
15495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
15505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
15515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseReturnStatement
15525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       jump-statement:
15535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'return' expression[opt] ';'
1554534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseReturnStatement() {
15554e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  assert(Tok.is(tok::kw_return) && "Not a return stmt!");
15565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation ReturnLoc = ConsumeToken();  // eat the 'return'.
15579a920342707e384473b464528d2fd286e8c70353Sebastian Redl
155860d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult R;
15594e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (Tok.isNot(tok::semi)) {
15605ac3bdb2cb0113b640c54f01468d21985c08b252Douglas Gregor    if (Tok.is(tok::code_completion)) {
156123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      Actions.CodeCompleteReturn(getCurScope());
15627d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      cutOffParsing();
15635ac3bdb2cb0113b640c54f01468d21985c08b252Douglas Gregor      return StmtError();
15645ac3bdb2cb0113b640c54f01468d21985c08b252Douglas Gregor    }
1565a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
15664e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (Tok.is(tok::l_brace) && getLangOpts().CPlusPlus) {
15676f4596cfb70ec706dd2da38db1be3663c214ff7aDouglas Gregor      R = ParseInitializer();
15687fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith      if (R.isUsable())
15694e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie        Diag(R.get()->getLocStart(), getLangOpts().CPlusPlus0x ?
15707fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith             diag::warn_cxx98_compat_generalized_initializer_lists :
15717fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith             diag::ext_generalized_initializer_lists)
15726f4596cfb70ec706dd2da38db1be3663c214ff7aDouglas Gregor          << R.get()->getSourceRange();
15736f4596cfb70ec706dd2da38db1be3663c214ff7aDouglas Gregor    } else
15746f4596cfb70ec706dd2da38db1be3663c214ff7aDouglas Gregor        R = ParseExpression();
15750e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl    if (R.isInvalid()) {  // Skip to the semicolon, but don't consume it.
15765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      SkipUntil(tok::semi, false, true);
15779a920342707e384473b464528d2fd286e8c70353Sebastian Redl      return StmtError();
15785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
15795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
15809ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  return Actions.ActOnReturnStmt(ReturnLoc, R.take());
15815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
15825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
15833fedbe1f71c18fba01d39109d606f421a0103a2aEli Friedman/// ParseMicrosoftAsmStatement. When -fms-extensions/-fasm-blocks is enabled,
15843fedbe1f71c18fba01d39109d606f421a0103a2aEli Friedman/// this routine is called to collect the tokens for an MS asm statement.
15858cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier///
15868cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier/// [MS]  ms-asm-statement:
15878cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier///         ms-asm-block
15888cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier///         ms-asm-block ms-asm-statement
15898cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier///
15908cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier/// [MS]  ms-asm-block:
15918cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier///         '__asm' ms-asm-line '\n'
15928cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier///         '__asm' '{' ms-asm-instruction-block[opt] '}' ';'[opt]
15938cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier///
15948cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier/// [MS]  ms-asm-instruction-block
15958cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier///         ms-asm-line
15968cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier///         ms-asm-line '\n' ms-asm-instruction-block
15978cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier///
15983fedbe1f71c18fba01d39109d606f421a0103a2aEli FriedmanStmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
159956d7f2348a182002563700db2158da0c6fc115a5Chad Rosier  // MS-style inline assembly is not fully supported, so emit a warning.
160056d7f2348a182002563700db2158da0c6fc115a5Chad Rosier  Diag(AsmLoc, diag::warn_unsupported_msasm);
160156d7f2348a182002563700db2158da0c6fc115a5Chad Rosier
16023fedbe1f71c18fba01d39109d606f421a0103a2aEli Friedman  SourceManager &SrcMgr = PP.getSourceManager();
16033fedbe1f71c18fba01d39109d606f421a0103a2aEli Friedman  SourceLocation EndLoc = AsmLoc;
16048cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier  SmallVector<Token, 4> AsmToks;
16053fedbe1f71c18fba01d39109d606f421a0103a2aEli Friedman
160621ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier  bool InBraces = false;
160721ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier  unsigned short savedBraceCount = 0;
160821ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier  bool InAsmComment = false;
160921ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier  FileID FID;
161021ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier  unsigned LineNo = 0;
161121ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier  unsigned NumTokensRead = 0;
161221ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier  SourceLocation LBraceLoc;
161321ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier
161421ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier  if (Tok.is(tok::l_brace)) {
161521ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    // Braced inline asm: consume the opening brace.
161621ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    InBraces = true;
161721ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    savedBraceCount = BraceCount;
161821ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    EndLoc = LBraceLoc = ConsumeBrace();
161921ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    ++NumTokensRead;
162021ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier  } else {
162121ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    // Single-line inline asm; compute which line it is on.
162221ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    std::pair<FileID, unsigned> ExpAsmLoc =
162321ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier      SrcMgr.getDecomposedExpansionLoc(EndLoc);
162421ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    FID = ExpAsmLoc.first;
162521ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    LineNo = SrcMgr.getLineNumber(FID, ExpAsmLoc.second);
162621ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier  }
16273fedbe1f71c18fba01d39109d606f421a0103a2aEli Friedman
162821ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier  SourceLocation TokLoc = Tok.getLocation();
162921ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier  do {
163021ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    // If we hit EOF, we're done, period.
163121ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    if (Tok.is(tok::eof))
163221ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier      break;
16333fedbe1f71c18fba01d39109d606f421a0103a2aEli Friedman
163421ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    if (!InAsmComment && Tok.is(tok::semi)) {
163521ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier      // A semicolon in an asm is the start of a comment.
163621ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier      InAsmComment = true;
163721ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier      if (InBraces) {
163821ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier        // Compute which line the comment is on.
163921ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier        std::pair<FileID, unsigned> ExpSemiLoc =
164021ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier          SrcMgr.getDecomposedExpansionLoc(TokLoc);
164121ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier        FID = ExpSemiLoc.first;
164221ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier        LineNo = SrcMgr.getLineNumber(FID, ExpSemiLoc.second);
1643a01eddbd07aa7e864da14cae20ce772dfdd082faChad Rosier      }
164421ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    } else if (!InBraces || InAsmComment) {
164521ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier      // If end-of-line is significant, check whether this token is on a
164621ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier      // new line.
164721ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier      std::pair<FileID, unsigned> ExpLoc =
164821ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier        SrcMgr.getDecomposedExpansionLoc(TokLoc);
164921ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier      if (ExpLoc.first != FID ||
165021ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier          SrcMgr.getLineNumber(ExpLoc.first, ExpLoc.second) != LineNo) {
165121ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier        // If this is a single-line __asm, we're done.
165221ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier        if (!InBraces)
165321ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier          break;
165421ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier        // We're no longer in a comment.
165521ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier        InAsmComment = false;
165621ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier      } else if (!InAsmComment && Tok.is(tok::r_brace)) {
165721ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier        // Single-line asm always ends when a closing brace is seen.
165821ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier        // FIXME: This is compatible with Apple gcc's -fasm-blocks; what
165921ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier        // does MSVC do here?
16608cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier        break;
16613fedbe1f71c18fba01d39109d606f421a0103a2aEli Friedman      }
16623fedbe1f71c18fba01d39109d606f421a0103a2aEli Friedman    }
166321ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    if (!InAsmComment && InBraces && Tok.is(tok::r_brace) &&
166421ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier        BraceCount == (savedBraceCount + 1)) {
166521ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier      // Consume the closing brace, and finish
166621ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier      EndLoc = ConsumeBrace();
16673fedbe1f71c18fba01d39109d606f421a0103a2aEli Friedman      break;
166821ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    }
166921ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier
167021ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    // Consume the next token; make sure we don't modify the brace count etc.
167121ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    // if we are in a comment.
167221ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    EndLoc = TokLoc;
167321ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    if (InAsmComment)
167421ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier      PP.Lex(Tok);
167521ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    else {
167621ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier      AsmToks.push_back(Tok);
167721ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier      ConsumeAnyToken();
167821ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    }
167921ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    TokLoc = Tok.getLocation();
168021ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    ++NumTokensRead;
16813fedbe1f71c18fba01d39109d606f421a0103a2aEli Friedman  } while (1);
16828cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier
168321ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier  if (InBraces && BraceCount != savedBraceCount) {
168421ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    // __asm without closing brace (this can happen at EOF).
168521ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    Diag(Tok, diag::err_expected_rbrace);
168621ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    Diag(LBraceLoc, diag::note_matching) << "{";
168721ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    return StmtError();
168821ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier  } else if (NumTokensRead == 0) {
168921ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    // Empty __asm.
169021ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    Diag(Tok, diag::err_expected_lbrace);
169121ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier    return StmtError();
169221ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier  }
169321ef7116ef308ba565b094ab32559f1eb1c277b7Chad Rosier
169456d7f2348a182002563700db2158da0c6fc115a5Chad Rosier  // If MS-style inline assembly is disabled, then build an empty asm.
169556d7f2348a182002563700db2158da0c6fc115a5Chad Rosier  if (!getLangOpts().EmitMicrosoftInlineAsm) {
169656d7f2348a182002563700db2158da0c6fc115a5Chad Rosier    Token t;
169756d7f2348a182002563700db2158da0c6fc115a5Chad Rosier    t.setKind(tok::string_literal);
169856d7f2348a182002563700db2158da0c6fc115a5Chad Rosier    t.setLiteralData("\"/*FIXME: not done*/\"");
169956d7f2348a182002563700db2158da0c6fc115a5Chad Rosier    t.clearFlag(Token::NeedsCleaning);
170056d7f2348a182002563700db2158da0c6fc115a5Chad Rosier    t.setLength(21);
170156d7f2348a182002563700db2158da0c6fc115a5Chad Rosier    ExprResult AsmString(Actions.ActOnStringLiteral(&t, 1));
170256d7f2348a182002563700db2158da0c6fc115a5Chad Rosier    ExprVector Constraints;
170356d7f2348a182002563700db2158da0c6fc115a5Chad Rosier    ExprVector Exprs;
170456d7f2348a182002563700db2158da0c6fc115a5Chad Rosier    ExprVector Clobbers;
1705df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier    return Actions.ActOnGCCAsmStmt(AsmLoc, true, true, 0, 0, 0, Constraints,
1706df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier                                   Exprs, AsmString.take(), Clobbers, EndLoc);
170756d7f2348a182002563700db2158da0c6fc115a5Chad Rosier  }
170856d7f2348a182002563700db2158da0c6fc115a5Chad Rosier
17098f726de55412870ef70e788b852c6cc50873e15bChad Rosier  // FIXME: We should be passing source locations for better diagnostics.
17107bd092b054444e9800e8de1d8d71c408dbdc8eadChad Rosier  return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLoc,
17117bd092b054444e9800e8de1d8d71c408dbdc8eadChad Rosier                                llvm::makeArrayRef(AsmToks), EndLoc);
1712d62701bc5321049353017e9abf1963edd57646aaSteve Naroff}
1713d62701bc5321049353017e9abf1963edd57646aaSteve Naroff
17145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseAsmStatement - Parse a GNU extended asm statement.
17155f8aa696619e32bf307232841fedb704ba733b4dSteve Naroff///       asm-statement:
17165f8aa696619e32bf307232841fedb704ba733b4dSteve Naroff///         gnu-asm-statement
17175f8aa696619e32bf307232841fedb704ba733b4dSteve Naroff///         ms-asm-statement
17185f8aa696619e32bf307232841fedb704ba733b4dSteve Naroff///
17195f8aa696619e32bf307232841fedb704ba733b4dSteve Naroff/// [GNU] gnu-asm-statement:
17205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         'asm' type-qualifier[opt] '(' asm-argument ')' ';'
17215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
17225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU] asm-argument:
17235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         asm-string-literal
17245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         asm-string-literal ':' asm-operands[opt]
17255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt]
17265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt]
17275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///                 ':' asm-clobbers
17285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
17295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU] asm-clobbers:
17305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         asm-string-literal
17315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         asm-clobbers ',' asm-string-literal
17325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
173360d7b3a319d84d688752be3870615ac0f111fb16John McCallStmtResult Parser::ParseAsmStatement(bool &msAsm) {
17344e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  assert(Tok.is(tok::kw_asm) && "Not an asm stmt");
1735fe795956194141c91ae555985c9b930595bff43fChris Lattner  SourceLocation AsmLoc = ConsumeToken();
17369a920342707e384473b464528d2fd286e8c70353Sebastian Redl
1737b660446bcf47bfbcdebaf65a6616c4046579987aChad Rosier  if (getLangOpts().MicrosoftExt && Tok.isNot(tok::l_paren) &&
1738b660446bcf47bfbcdebaf65a6616c4046579987aChad Rosier      !isTypeQualifier()) {
1739d62701bc5321049353017e9abf1963edd57646aaSteve Naroff    msAsm = true;
17403fedbe1f71c18fba01d39109d606f421a0103a2aEli Friedman    return ParseMicrosoftAsmStatement(AsmLoc);
1741d62701bc5321049353017e9abf1963edd57646aaSteve Naroff  }
17420b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  DeclSpec DS(AttrFactory);
17435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation Loc = Tok.getLocation();
1744bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  ParseTypeQualifierListOpt(DS, true, false);
17459a920342707e384473b464528d2fd286e8c70353Sebastian Redl
17465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // GNU asms accept, but warn, about type-qualifiers other than volatile.
17475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
17481ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Loc, diag::w_asm_qualifier_ignored) << "const";
17495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (DS.getTypeQualifiers() & DeclSpec::TQ_restrict)
17501ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Loc, diag::w_asm_qualifier_ignored) << "restrict";
17519a920342707e384473b464528d2fd286e8c70353Sebastian Redl
17525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Remember if this was a volatile asm.
175339c47b56f45437bbc49c9568b7308a400234a730Anders Carlsson  bool isVolatile = DS.getTypeQualifiers() & DeclSpec::TQ_volatile;
17544e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (Tok.isNot(tok::l_paren)) {
17551ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_lparen_after) << "asm";
17565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SkipUntil(tok::r_paren);
17579a920342707e384473b464528d2fd286e8c70353Sebastian Redl    return StmtError();
17585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
17594a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_paren);
17604a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeOpen();
17619a920342707e384473b464528d2fd286e8c70353Sebastian Redl
176260d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult AsmString(ParseAsmStringLiteral());
1763320fa4b6051ff032aaa50d924ca39e3d529dcf5fTed Kremenek  if (AsmString.isInvalid()) {
176499831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    // Consume up to and including the closing paren.
176599831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    T.skipToEnd();
17669a920342707e384473b464528d2fd286e8c70353Sebastian Redl    return StmtError();
1767320fa4b6051ff032aaa50d924ca39e3d529dcf5fTed Kremenek  }
17680e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
17695f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<IdentifierInfo *, 4> Names;
17704e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer  ExprVector Constraints;
17714e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer  ExprVector Exprs;
17724e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer  ExprVector Clobbers;
1773dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson
1774dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson  if (Tok.is(tok::r_paren)) {
177564cb4757acbf10f0c702f17c4fe90f4b7aba3490Chris Lattner    // We have a simple asm expression like 'asm("foo")'.
17764a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeClose();
1777df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier    return Actions.ActOnGCCAsmStmt(AsmLoc, /*isSimple*/ true, isVolatile,
1778df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier                                   /*NumOutputs*/ 0, /*NumInputs*/ 0, 0,
1779df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier                                   Constraints, Exprs, AsmString.take(),
1780df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier                                   Clobbers, T.getCloseLocation());
178164cb4757acbf10f0c702f17c4fe90f4b7aba3490Chris Lattner  }
17829a920342707e384473b464528d2fd286e8c70353Sebastian Redl
178364cb4757acbf10f0c702f17c4fe90f4b7aba3490Chris Lattner  // Parse Outputs, if present.
17846405646cb649e4b4c6768b92d1fc83c175722f62Chris Lattner  bool AteExtraColon = false;
17856405646cb649e4b4c6768b92d1fc83c175722f62Chris Lattner  if (Tok.is(tok::colon) || Tok.is(tok::coloncolon)) {
17866405646cb649e4b4c6768b92d1fc83c175722f62Chris Lattner    // In C++ mode, parse "::" like ": :".
17876405646cb649e4b4c6768b92d1fc83c175722f62Chris Lattner    AteExtraColon = Tok.is(tok::coloncolon);
178864cb4757acbf10f0c702f17c4fe90f4b7aba3490Chris Lattner    ConsumeToken();
1789a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
17906405646cb649e4b4c6768b92d1fc83c175722f62Chris Lattner    if (!AteExtraColon &&
17916405646cb649e4b4c6768b92d1fc83c175722f62Chris Lattner        ParseAsmOperandsOpt(Names, Constraints, Exprs))
179264cb4757acbf10f0c702f17c4fe90f4b7aba3490Chris Lattner      return StmtError();
179364cb4757acbf10f0c702f17c4fe90f4b7aba3490Chris Lattner  }
1794a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
179564cb4757acbf10f0c702f17c4fe90f4b7aba3490Chris Lattner  unsigned NumOutputs = Names.size();
17969a920342707e384473b464528d2fd286e8c70353Sebastian Redl
179764cb4757acbf10f0c702f17c4fe90f4b7aba3490Chris Lattner  // Parse Inputs, if present.
17986405646cb649e4b4c6768b92d1fc83c175722f62Chris Lattner  if (AteExtraColon ||
17996405646cb649e4b4c6768b92d1fc83c175722f62Chris Lattner      Tok.is(tok::colon) || Tok.is(tok::coloncolon)) {
18006405646cb649e4b4c6768b92d1fc83c175722f62Chris Lattner    // In C++ mode, parse "::" like ": :".
18016405646cb649e4b4c6768b92d1fc83c175722f62Chris Lattner    if (AteExtraColon)
18026405646cb649e4b4c6768b92d1fc83c175722f62Chris Lattner      AteExtraColon = false;
18036405646cb649e4b4c6768b92d1fc83c175722f62Chris Lattner    else {
18046405646cb649e4b4c6768b92d1fc83c175722f62Chris Lattner      AteExtraColon = Tok.is(tok::coloncolon);
18056405646cb649e4b4c6768b92d1fc83c175722f62Chris Lattner      ConsumeToken();
18066405646cb649e4b4c6768b92d1fc83c175722f62Chris Lattner    }
1807a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
18086405646cb649e4b4c6768b92d1fc83c175722f62Chris Lattner    if (!AteExtraColon &&
18096405646cb649e4b4c6768b92d1fc83c175722f62Chris Lattner        ParseAsmOperandsOpt(Names, Constraints, Exprs))
181064cb4757acbf10f0c702f17c4fe90f4b7aba3490Chris Lattner      return StmtError();
181164cb4757acbf10f0c702f17c4fe90f4b7aba3490Chris Lattner  }
1812effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl
181364cb4757acbf10f0c702f17c4fe90f4b7aba3490Chris Lattner  assert(Names.size() == Constraints.size() &&
181464cb4757acbf10f0c702f17c4fe90f4b7aba3490Chris Lattner         Constraints.size() == Exprs.size() &&
181564cb4757acbf10f0c702f17c4fe90f4b7aba3490Chris Lattner         "Input operand size mismatch!");
1816b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson
181764cb4757acbf10f0c702f17c4fe90f4b7aba3490Chris Lattner  unsigned NumInputs = Names.size() - NumOutputs;
1818effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl
181964cb4757acbf10f0c702f17c4fe90f4b7aba3490Chris Lattner  // Parse the clobbers, if present.
18206405646cb649e4b4c6768b92d1fc83c175722f62Chris Lattner  if (AteExtraColon || Tok.is(tok::colon)) {
18216405646cb649e4b4c6768b92d1fc83c175722f62Chris Lattner    if (!AteExtraColon)
18226405646cb649e4b4c6768b92d1fc83c175722f62Chris Lattner      ConsumeToken();
1823effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl
1824102e1b6a4753b0bd3662ad1bd119f6efa04b8763Chandler Carruth    // Parse the asm-string list for clobbers if present.
1825102e1b6a4753b0bd3662ad1bd119f6efa04b8763Chandler Carruth    if (Tok.isNot(tok::r_paren)) {
1826102e1b6a4753b0bd3662ad1bd119f6efa04b8763Chandler Carruth      while (1) {
182760d7b3a319d84d688752be3870615ac0f111fb16John McCall        ExprResult Clobber(ParseAsmStringLiteral());
18285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1829102e1b6a4753b0bd3662ad1bd119f6efa04b8763Chandler Carruth        if (Clobber.isInvalid())
1830102e1b6a4753b0bd3662ad1bd119f6efa04b8763Chandler Carruth          break;
1831effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl
1832102e1b6a4753b0bd3662ad1bd119f6efa04b8763Chandler Carruth        Clobbers.push_back(Clobber.release());
1833effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl
1834102e1b6a4753b0bd3662ad1bd119f6efa04b8763Chandler Carruth        if (Tok.isNot(tok::comma)) break;
1835102e1b6a4753b0bd3662ad1bd119f6efa04b8763Chandler Carruth        ConsumeToken();
1836102e1b6a4753b0bd3662ad1bd119f6efa04b8763Chandler Carruth      }
18375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
1838dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson  }
1839effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl
18404a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
1841df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier  return Actions.ActOnGCCAsmStmt(AsmLoc, false, isVolatile, NumOutputs,
1842df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier                                 NumInputs, Names.data(), Constraints, Exprs,
1843df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier                                 AsmString.take(), Clobbers,
1844df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier                                 T.getCloseLocation());
18455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
18465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
18475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseAsmOperands - Parse the asm-operands production as used by
184864cb4757acbf10f0c702f17c4fe90f4b7aba3490Chris Lattner/// asm-statement, assuming the leading ':' token was eaten.
18495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
18505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU] asm-operands:
18515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         asm-operand
18525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         asm-operands ',' asm-operand
18535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
18545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU] asm-operand:
18555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         asm-string-literal '(' expression ')'
18565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///         '[' identifier ']' asm-string-literal '(' expression ')'
18575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
18585ffe14ca96bd662de7820f6875d3f04789a640c1Daniel Dunbar//
18595ffe14ca96bd662de7820f6875d3f04789a640c1Daniel Dunbar// FIXME: Avoid unnecessary std::string trashing.
18605f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerbool Parser::ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names,
1861f81e5a9e3f3ff80c56e4afb4fe6311a8735f36e8Richard Trieu                                 SmallVectorImpl<Expr *> &Constraints,
1862f81e5a9e3f3ff80c56e4afb4fe6311a8735f36e8Richard Trieu                                 SmallVectorImpl<Expr *> &Exprs) {
18635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // 'asm-operands' isn't present?
18644e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner  if (!isTokenStringLiteral() && Tok.isNot(tok::l_square))
18658bd36fcb4427519f41197d88b9121e2bbe9e3fc3Anders Carlsson    return false;
18661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  while (1) {
18685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Read the [id] if present.
18694e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner    if (Tok.is(tok::l_square)) {
18704a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor      BalancedDelimiterTracker T(*this, tok::l_square);
18714a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor      T.consumeOpen();
18721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18734e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner      if (Tok.isNot(tok::identifier)) {
18745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        Diag(Tok, diag::err_expected_ident);
18755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        SkipUntil(tok::r_paren);
18768bd36fcb4427519f41197d88b9121e2bbe9e3fc3Anders Carlsson        return true;
18775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      }
18781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1879b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson      IdentifierInfo *II = Tok.getIdentifierInfo();
188069efba74cf5488060accf34c011b33ce6c15ece0Chris Lattner      ConsumeToken();
1881b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson
1882ff93dbd887e40588ed55d135037bb9287488b285Anders Carlsson      Names.push_back(II);
18834a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor      T.consumeClose();
1884b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson    } else
1885ff93dbd887e40588ed55d135037bb9287488b285Anders Carlsson      Names.push_back(0);
18860e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
188760d7b3a319d84d688752be3870615ac0f111fb16John McCall    ExprResult Constraint(ParseAsmStringLiteral());
18880e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl    if (Constraint.isInvalid()) {
1889b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson        SkipUntil(tok::r_paren);
18908bd36fcb4427519f41197d88b9121e2bbe9e3fc3Anders Carlsson        return true;
1891b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson    }
1892effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl    Constraints.push_back(Constraint.release());
18935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
18944e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner    if (Tok.isNot(tok::l_paren)) {
18951ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner      Diag(Tok, diag::err_expected_lparen_after) << "asm operand";
18965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      SkipUntil(tok::r_paren);
18978bd36fcb4427519f41197d88b9121e2bbe9e3fc3Anders Carlsson      return true;
18985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
1899effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl
19005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Read the parenthesized expression.
19014a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    BalancedDelimiterTracker T(*this, tok::l_paren);
19024a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeOpen();
190360d7b3a319d84d688752be3870615ac0f111fb16John McCall    ExprResult Res(ParseExpression());
19044a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeClose();
19050e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl    if (Res.isInvalid()) {
19065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      SkipUntil(tok::r_paren);
19078bd36fcb4427519f41197d88b9121e2bbe9e3fc3Anders Carlsson      return true;
19085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
1909effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl    Exprs.push_back(Res.release());
19105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Eat the comma and continue parsing if it exists.
19118bd36fcb4427519f41197d88b9121e2bbe9e3fc3Anders Carlsson    if (Tok.isNot(tok::comma)) return false;
19125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ConsumeToken();
19135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
19145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1915f9ed3157c93495474003a5ec360039030fd42e9cFariborz Jahanian
1916c9977d09a2de7f7d2245973413d4caf86c736640Douglas GregorDecl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) {
191740e9bc84a2ab49fc33c2b1a95c6674ab2b820e9eChris Lattner  assert(Tok.is(tok::l_brace));
191840e9bc84a2ab49fc33c2b1a95c6674ab2b820e9eChris Lattner  SourceLocation LBraceLoc = Tok.getLocation();
1919d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl
19206a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen  if (SkipFunctionBodies && trySkippingFunctionBody()) {
19216a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen    BodyScope.Exit();
19226a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen    return Actions.ActOnFinishFunctionBody(Decl, 0);
1923c9977d09a2de7f7d2245973413d4caf86c736640Douglas Gregor  }
1924a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
1925f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  PrettyDeclStackTraceEntry CrashInfo(Actions, Decl, LBraceLoc,
1926f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                      "parsing function body");
19271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1928f9ed3157c93495474003a5ec360039030fd42e9cFariborz Jahanian  // Do not enter a scope for the brace, as the arguments are in the same scope
1929f9ed3157c93495474003a5ec360039030fd42e9cFariborz Jahanian  // (the function body) as the body itself.  Instead, just read the statement
1930f9ed3157c93495474003a5ec360039030fd42e9cFariborz Jahanian  // list and put it into a CompoundStmt for safe keeping.
193160d7b3a319d84d688752be3870615ac0f111fb16John McCall  StmtResult FnBody(ParseCompoundStatementBody());
193261364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
1933f9ed3157c93495474003a5ec360039030fd42e9cFariborz Jahanian  // If the function body could not be parsed, make a bogus compoundstmt.
1934625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  if (FnBody.isInvalid()) {
1935625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko    Sema::CompoundScopeRAII CompoundScope(Actions);
19361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc,
19375354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer                                       MultiStmtArg(), false);
1938625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  }
193961364dddc33383e62cfe3b841dbc0f471280d95bSebastian Redl
1940c9977d09a2de7f7d2245973413d4caf86c736640Douglas Gregor  BodyScope.Exit();
19419ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  return Actions.ActOnFinishFunctionBody(Decl, FnBody.take());
1942cd5af4b5863c63b62cde96ad6d52fb1eec0e26bbSeo Sanghyeon}
1943a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
1944d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl/// ParseFunctionTryBlock - Parse a C++ function-try-block.
1945d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///
1946d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///       function-try-block:
1947d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///         'try' ctor-initializer[opt] compound-statement handler-seq
1948d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///
1949c9977d09a2de7f7d2245973413d4caf86c736640Douglas GregorDecl *Parser::ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope) {
1950d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  assert(Tok.is(tok::kw_try) && "Expected 'try'");
1951d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  SourceLocation TryLoc = ConsumeToken();
1952d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl
1953f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  PrettyDeclStackTraceEntry CrashInfo(Actions, Decl, TryLoc,
1954f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                      "parsing function try block");
1955d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl
1956d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  // Constructor initializer list?
1957d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  if (Tok.is(tok::colon))
1958d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl    ParseConstructorInitializer(Decl);
19592eef427c8666cbe9a3cad40d4947c67c3ba0c400Douglas Gregor  else
19602eef427c8666cbe9a3cad40d4947c67c3ba0c400Douglas Gregor    Actions.ActOnDefaultCtorInitializers(Decl);
1961a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
19626a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen  if (SkipFunctionBodies && trySkippingFunctionBody()) {
19636a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen    BodyScope.Exit();
19646a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen    return Actions.ActOnFinishFunctionBody(Decl, 0);
1965c9977d09a2de7f7d2245973413d4caf86c736640Douglas Gregor  }
19660fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis
1967de1b60a9868f80f0872ed05d78df3b40a10ba5caSebastian Redl  SourceLocation LBraceLoc = Tok.getLocation();
196860d7b3a319d84d688752be3870615ac0f111fb16John McCall  StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc));
1969d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  // If we failed to parse the try-catch, we just give the function an empty
1970d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  // compound statement as the body.
1971625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  if (FnBody.isInvalid()) {
1972625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko    Sema::CompoundScopeRAII CompoundScope(Actions);
1973de1b60a9868f80f0872ed05d78df3b40a10ba5caSebastian Redl    FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc,
19745354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer                                       MultiStmtArg(), false);
1975625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  }
1976d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl
1977c9977d09a2de7f7d2245973413d4caf86c736640Douglas Gregor  BodyScope.Exit();
19789ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  return Actions.ActOnFinishFunctionBody(Decl, FnBody.take());
1979d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl}
1980d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl
19816a91d385618ea4d28236c496f540a26877c95525Erik Verbruggenbool Parser::trySkippingFunctionBody() {
19820fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis  assert(Tok.is(tok::l_brace));
19836a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen  assert(SkipFunctionBodies &&
19846a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen         "Should only be called when SkipFunctionBodies is enabled");
19850fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis
19860fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis  // We're in code-completion mode. Skip parsing for all function bodies unless
19870fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis  // the body contains the code-completion point.
19880fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis  TentativeParsingAction PA(*this);
19890fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis  ConsumeBrace();
19900fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis  if (SkipUntil(tok::r_brace, /*StopAtSemi=*/false, /*DontConsume=*/false,
19916a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen                /*StopAtCodeCompletion=*/PP.isCodeCompletionEnabled())) {
19920fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis    PA.Commit();
19930fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis    return true;
19940fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis  }
19950fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis
19960fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis  PA.Revert();
19970fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis  return false;
19980fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis}
19990fe5397b26695926a835fa99eceb7fc879b307afArgyrios Kyrtzidis
2000a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl/// ParseCXXTryBlock - Parse a C++ try-block.
2001a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl///
2002a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl///       try-block:
2003a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl///         'try' compound-statement handler-seq
2004a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl///
2005534986f2b21e6050bf00163cd6423fd92155a6edRichard SmithStmtResult Parser::ParseCXXTryBlock() {
2006a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  assert(Tok.is(tok::kw_try) && "Expected 'try'");
2007a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
2008a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  SourceLocation TryLoc = ConsumeToken();
2009d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  return ParseCXXTryBlockCommon(TryLoc);
2010d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl}
2011d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl
2012d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl/// ParseCXXTryBlockCommon - Parse the common part of try-block and
2013d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl/// function-try-block.
2014d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///
2015d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///       try-block:
2016d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///         'try' compound-statement handler-seq
2017d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///
2018d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///       function-try-block:
2019d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///         'try' ctor-initializer[opt] compound-statement handler-seq
2020d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///
2021d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///       handler-seq:
2022d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///         handler handler-seq[opt]
2023d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl///
202428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///       [Borland] try-block:
202528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///         'try' compound-statement seh-except-block
202628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///         'try' compound-statment  seh-finally-block
202728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley///
202860d7b3a319d84d688752be3870615ac0f111fb16John McCallStmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc) {
2029a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  if (Tok.isNot(tok::l_brace))
2030a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl    return StmtError(Diag(Tok, diag::err_expected_lbrace));
2031bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Possible draft standard bug: attribute-specifier should be allowed?
2032534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith
2033534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  StmtResult TryBlock(ParseCompoundStatement(/*isStmtExpr=*/false,
2034bca01b46850f867b2f4137f25c882022b58f8471Douglas Gregor                                             Scope::DeclScope|Scope::TryScope));
2035a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  if (TryBlock.isInvalid())
20363fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer    return TryBlock;
2037a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
203828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  // Borland allows SEH-handlers with 'try'
2039b660446bcf47bfbcdebaf65a6616c4046579987aChad Rosier
2040534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  if ((Tok.is(tok::identifier) &&
2041534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith       Tok.getIdentifierInfo() == getSEHExceptKeyword()) ||
2042534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith      Tok.is(tok::kw___finally)) {
204328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    // TODO: Factor into common return ParseSEHHandlerCommon(...)
204428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    StmtResult Handler;
2045b57791e5b40afa6691063c83d0e95c416fb19fdeDouglas Gregor    if(Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
204628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley      SourceLocation Loc = ConsumeToken();
204728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley      Handler = ParseSEHExceptBlock(Loc);
204828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    }
204928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    else {
205028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley      SourceLocation Loc = ConsumeToken();
205128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley      Handler = ParseSEHFinallyBlock(Loc);
205228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    }
205328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    if(Handler.isInvalid())
20543fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer      return Handler;
205528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
205628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    return Actions.ActOnSEHTryBlock(true /* IsCXXTry */,
205728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley                                    TryLoc,
205828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley                                    TryBlock.take(),
205928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley                                    Handler.take());
2060a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  }
206128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  else {
20624e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer    StmtVector Handlers;
2063534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    ParsedAttributesWithRange attrs(AttrFactory);
206428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    MaybeParseCXX0XAttributes(attrs);
206528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    ProhibitAttributes(attrs);
206628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
206728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    if (Tok.isNot(tok::kw_catch))
206828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley      return StmtError(Diag(Tok, diag::err_expected_catch));
206928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    while (Tok.is(tok::kw_catch)) {
207028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley      StmtResult Handler(ParseCXXCatchBlock());
207128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley      if (!Handler.isInvalid())
207228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Handlers.push_back(Handler.release());
207328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    }
207428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    // Don't bother creating the full statement if we don't have any usable
207528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    // handlers.
207628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    if (Handlers.empty())
207728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley      return StmtError();
2078a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
20793fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer    return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.take(),Handlers);
208028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  }
2081a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl}
2082a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
2083a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl/// ParseCXXCatchBlock - Parse a C++ catch block, called handler in the standard
2084a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl///
2085a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl///       handler:
2086a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl///         'catch' '(' exception-declaration ')' compound-statement
2087a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl///
2088a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl///       exception-declaration:
2089a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl///         type-specifier-seq declarator
2090a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl///         type-specifier-seq abstract-declarator
2091a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl///         type-specifier-seq
2092a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl///         '...'
2093a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl///
209460d7b3a319d84d688752be3870615ac0f111fb16John McCallStmtResult Parser::ParseCXXCatchBlock() {
2095a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  assert(Tok.is(tok::kw_catch) && "Expected 'catch'");
2096a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
2097a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  SourceLocation CatchLoc = ConsumeToken();
2098a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
20994a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_paren);
21004a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  if (T.expectAndConsume(diag::err_expected_lparen))
2101a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl    return StmtError();
2102a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
2103a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  // C++ 3.3.2p3:
2104a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  // The name in a catch exception-declaration is local to the handler and
2105a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  // shall not be redeclared in the outermost block of the handler.
2106a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  ParseScope CatchScope(this, Scope::DeclScope | Scope::ControlScope);
2107a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
2108a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  // exception-declaration is equivalent to '...' or a parameter-declaration
2109a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  // without default arguments.
2110d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  Decl *ExceptionDecl = 0;
2111a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  if (Tok.isNot(tok::ellipsis)) {
21120b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall    DeclSpec DS(AttrFactory);
21134b07b2968f87f3cd5a3d8c76145f1cbfd718d42dSebastian Redl    if (ParseCXXTypeSpecifierSeq(DS))
21144b07b2968f87f3cd5a3d8c76145f1cbfd718d42dSebastian Redl      return StmtError();
2115a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl    Declarator ExDecl(DS, Declarator::CXXCatchContext);
2116a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl    ParseDeclarator(ExDecl);
211723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    ExceptionDecl = Actions.ActOnExceptionDeclarator(getCurScope(), ExDecl);
2118a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  } else
2119a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl    ConsumeToken();
2120a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
21214a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
21224a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  if (T.getCloseLocation().isInvalid())
2123a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl    return StmtError();
2124a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
2125a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  if (Tok.isNot(tok::l_brace))
2126a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl    return StmtError(Diag(Tok, diag::err_expected_lbrace));
2127a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
2128bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Possible draft standard bug: attribute-specifier should be allowed?
2129534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  StmtResult Block(ParseCompoundStatement());
2130a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl  if (Block.isInvalid())
21313fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer    return Block;
2132a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl
21339ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl, Block.take());
2134a0fd8652f3302d0f39ed9849b521ee5b76597b0aSebastian Redl}
21351e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet
21361e862693c63067ae467b0b3884c44f753cd6e821Francois Pichetvoid Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
21373896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  IfExistsCondition Result;
2138f986038beed360c031de8654cfba43a5d3184605Francois Pichet  if (ParseMicrosoftIfExistsCondition(Result))
21391e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet    return;
2140a789ca9b967abe47b84df83bcf4afb150856a8d9NAKAMURA Takumi
21413896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  // Handle dependent statements by parsing the braces as a compound statement.
21423896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  // This is not the same behavior as Visual C++, which don't treat this as a
21433896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  // compound statement, but for Clang's type checking we can't have anything
21443896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  // inside these braces escaping to the surrounding code.
21453896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  if (Result.Behavior == IEB_Dependent) {
21463896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    if (!Tok.is(tok::l_brace)) {
21473896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor      Diag(Tok, diag::err_expected_lbrace);
2148534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith      return;
21493896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    }
2150534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith
2151534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    StmtResult Compound = ParseCompoundStatement();
2152ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor    if (Compound.isInvalid())
2153ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor      return;
2154534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith
2155ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor    StmtResult DepResult = Actions.ActOnMSDependentExistsStmt(Result.KeywordLoc,
2156ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor                                                              Result.IsIfExists,
2157534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith                                                              Result.SS,
2158ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor                                                              Result.Name,
2159ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor                                                              Compound.get());
2160ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor    if (DepResult.isUsable())
2161ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor      Stmts.push_back(DepResult.get());
21623896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    return;
21633896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  }
2164534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith
21653896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  BalancedDelimiterTracker Braces(*this, tok::l_brace);
21663896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  if (Braces.consumeOpen()) {
21671e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet    Diag(Tok, diag::err_expected_lbrace);
21681e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet    return;
21691e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet  }
21701e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet
21713896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  switch (Result.Behavior) {
21723896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  case IEB_Parse:
21733896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    // Parse the statements below.
21743896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    break;
2175b660446bcf47bfbcdebaf65a6616c4046579987aChad Rosier
21763896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  case IEB_Dependent:
21773896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    llvm_unreachable("Dependent case handled above");
2178b660446bcf47bfbcdebaf65a6616c4046579987aChad Rosier
21793896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  case IEB_Skip:
21803896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    Braces.skipToEnd();
21811e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet    return;
21821e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet  }
21831e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet
21841e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet  // Condition is true, parse the statements.
21851e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet  while (Tok.isNot(tok::r_brace)) {
21861e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet    StmtResult R = ParseStatementOrDeclaration(Stmts, false);
21871e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet    if (R.isUsable())
21881e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet      Stmts.push_back(R.release());
21891e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet  }
21903896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  Braces.consumeClose();
21911e862693c63067ae467b0b3884c44f753cd6e821Francois Pichet}
2192