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