ParseStmt.cpp revision caaf29a08761b14fbe42a29080c22dd6961056d1
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" 1639146d6497ad5e7ca8ef639221e7b3e15d07c888Chris Lattner#include "ExtensionRAIIObject.h" 17a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl#include "AstGuard.h" 185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/Diagnostic.h" 19b746ce84fb5c3fd2c5659f84dc6f2a883b499dc2Steve Naroff#include "clang/Basic/SourceManager.h" 205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Parse/DeclSpec.h" 215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Parse/Scope.h" 225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang; 235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// C99 6.8: Statements and Blocks. 265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseStatementOrDeclaration - Read 'statement' or 'declaration'. 295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// StatementOrDeclaration: 305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// statement 315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// declaration 325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// statement: 345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// labeled-statement 355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// compound-statement 365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// expression-statement 375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// selection-statement 385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// iteration-statement 395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// jump-statement 40dcdd55fb4d28de8c314d6c6c1a38aa6aba76d431Argyrios Kyrtzidis/// [C++] declaration-statement 41b384d329e0b727d4f2effa28fbb9aba2ac420e7bFariborz Jahanian/// [OBC] objc-throw-statement 42b384d329e0b727d4f2effa28fbb9aba2ac420e7bFariborz Jahanian/// [OBC] objc-try-catch-statement 43c385c90c68dfa376650e2facfbb444b2ec9bd110Fariborz Jahanian/// [OBC] objc-synchronized-statement 445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU] asm-statement 455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [OMP] openmp-construct [TODO] 465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// labeled-statement: 485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// identifier ':' statement 495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'case' constant-expression ':' statement 505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'default' ':' statement 515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// selection-statement: 535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// if-statement 545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// switch-statement 555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// iteration-statement: 575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// while-statement 585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// do-statement 595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// for-statement 605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// expression-statement: 625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// expression[opt] ';' 635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// jump-statement: 655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'goto' identifier ';' 665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'continue' ';' 675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'break' ';' 685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'return' expression[opt] ';' 695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU] 'goto' '*' expression ';' 705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 71b384d329e0b727d4f2effa28fbb9aba2ac420e7bFariborz Jahanian/// [OBC] objc-throw-statement: 72b384d329e0b727d4f2effa28fbb9aba2ac420e7bFariborz Jahanian/// [OBC] '@' 'throw' expression ';' 73b384d329e0b727d4f2effa28fbb9aba2ac420e7bFariborz Jahanian/// [OBC] '@' 'throw' ';' 745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerParser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) { 765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *SemiError = 0; 7715faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningStmtResult Res(Actions); 780e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Cases in this switch statement should fall through if the parser expects 805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // the token to end in a semicolon (in which case SemiError should be set), 815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // or they directly 'return;' if not. 82397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian tok::TokenKind Kind = Tok.getKind(); 83397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian SourceLocation AtLoc; 84397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian switch (Kind) { 85397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian case tok::at: // May be a @try or @throw statement 86397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian { 87397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian AtLoc = ConsumeToken(); // consume @ 8864515f31850024a263e8f55f81e9ea4b39925cfaSteve Naroff return ParseObjCAtStatement(AtLoc); 89397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian } 90397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian 91b9f930d7bdb911be8420e044876221bf8a39f45fArgyrios Kyrtzidis case tok::identifier: 92b9f930d7bdb911be8420e044876221bf8a39f45fArgyrios Kyrtzidis if (NextToken().is(tok::colon)) { // C99 6.8.1: labeled-statement 93b9f930d7bdb911be8420e044876221bf8a39f45fArgyrios Kyrtzidis // identifier ':' statement 94b9f930d7bdb911be8420e044876221bf8a39f45fArgyrios Kyrtzidis return ParseLabeledStatement(); 95b9f930d7bdb911be8420e044876221bf8a39f45fArgyrios Kyrtzidis } 96b9f930d7bdb911be8420e044876221bf8a39f45fArgyrios Kyrtzidis // PASS THROUGH. 97b9f930d7bdb911be8420e044876221bf8a39f45fArgyrios Kyrtzidis 985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer default: 995404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if ((getLang().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) { 10081c018d9482e7cc2addadc6202dcf162a01faefdChris Lattner SourceLocation DeclStart = Tok.getLocation(); 1010e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl DeclTy *Decl = ParseDeclaration(Declarator::BlockContext); 10281c018d9482e7cc2addadc6202dcf162a01faefdChris Lattner // FIXME: Pass in the right location for the end of the declstmt. 1030e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl return Actions.ActOnDeclStmt(Decl, DeclStart, DeclStart); 1044e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner } else if (Tok.is(tok::r_brace)) { 1055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Diag(Tok, diag::err_expected_statement); 1065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 1075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 1085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // expression[opt] ';' 10915faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult Expr(Actions, ParseExpression()); 1100e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Expr.isInvalid()) { 1115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If the expression is invalid, skip ahead to the next semicolon. Not 1125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // doing this opens us up to the possibility of infinite loops if 1135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // ParseExpression does not consume any tokens. 1145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SkipUntil(tok::semi); 1155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 1165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Otherwise, eat the semicolon. 1185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr); 119effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl return Actions.ActOnExprStmt(Expr.release()); 1205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_case: // C99 6.8.1: labeled-statement 1235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return ParseCaseStatement(); 1245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_default: // C99 6.8.1: labeled-statement 1255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return ParseDefaultStatement(); 1265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::l_brace: // C99 6.8.2: compound-statement 1285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return ParseCompoundStatement(); 1295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::semi: // C99 6.8.3p3: expression[opt] ';' 1301b273c403734d343d720acb28f04011807c8aa56Steve Naroff return Actions.ActOnNullStmt(ConsumeToken()); 1315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_if: // C99 6.8.4.1: if-statement 1335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return ParseIfStatement(); 1345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_switch: // C99 6.8.4.2: switch-statement 1355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return ParseSwitchStatement(); 1365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_while: // C99 6.8.5.1: while-statement 1385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return ParseWhileStatement(); 1395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_do: // C99 6.8.5.2: do-statement 1405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Res = ParseDoStatement(); 1415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SemiError = "do/while loop"; 1425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer break; 1435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_for: // C99 6.8.5.3: for-statement 1445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return ParseForStatement(); 1455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_goto: // C99 6.8.6.1: goto-statement 1475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Res = ParseGotoStatement(); 1485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SemiError = "goto statement"; 1495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer break; 1505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_continue: // C99 6.8.6.2: continue-statement 1515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Res = ParseContinueStatement(); 1525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SemiError = "continue statement"; 1535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer break; 1545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_break: // C99 6.8.6.3: break-statement 1555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Res = ParseBreakStatement(); 1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SemiError = "break statement"; 1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer break; 1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_return: // C99 6.8.6.4: return-statement 1595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Res = ParseReturnStatement(); 1605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SemiError = "return statement"; 1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer break; 1625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_asm: 164d62701bc5321049353017e9abf1963edd57646aaSteve Naroff bool msAsm = false; 165d62701bc5321049353017e9abf1963edd57646aaSteve Naroff Res = ParseAsmStatement(msAsm); 166effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl if (msAsm) return Res.result(); 1675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SemiError = "asm statement"; 1685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer break; 1695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If we reached this code, the statement must end in a semicolon. 1724e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.is(tok::semi)) { 1735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ConsumeToken(); 1740e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl } else if (!Res.isInvalid()) { 1751ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_semi_after) << SemiError; 176195044028b76133e2a1f245b094468fe07db7330Chris Lattner // Skip until we see a } or ;, but don't eat it. 177195044028b76133e2a1f245b094468fe07db7330Chris Lattner SkipUntil(tok::r_brace, true, true); 1785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 179effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl return Res.result(); 1805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 1815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 182f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis/// ParseLabeledStatement - We have an identifier and a ':' after it. 1835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 1845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// labeled-statement: 1855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// identifier ':' statement 1865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU] identifier ':' attributes[opt] statement 1875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 188f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios KyrtzidisParser::StmtResult Parser::ParseLabeledStatement() { 1894e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() && 1905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer "Not an identifier!"); 1915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 192d217773f106856a11879ec79dc468efefaf2ee75Chris Lattner Token IdentTok = Tok; // Save the whole token. 1935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ConsumeToken(); // eat the identifier. 194f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis 195f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis assert(Tok.is(tok::colon) && "Not a label!"); 1965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // identifier ':' statement 198f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis SourceLocation ColonLoc = ConsumeToken(); 1995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 200f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis // Read label attributes, if present. 201f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis DeclTy *AttrList = 0; 202f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis if (Tok.is(tok::kw___attribute)) 203f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis // TODO: save these somewhere. 204f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis AttrList = ParseAttributes(); 2055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 20615faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningStmtResult SubStmt(Actions, ParseStatement()); 2070e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 208f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis // Broken substmt shouldn't prevent the label from being added to the AST. 2090e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (SubStmt.isInvalid()) 210f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis SubStmt = Actions.ActOnNullStmt(ColonLoc); 2110e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 212f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis return Actions.ActOnLabelStmt(IdentTok.getLocation(), 213f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis IdentTok.getIdentifierInfo(), 214effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl ColonLoc, SubStmt.release()); 215f7da726f09a6b7c5b9f5308e9690cb015398e671Argyrios Kyrtzidis} 2165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCaseStatement 2185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// labeled-statement: 2195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'case' constant-expression ':' statement 2205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU] 'case' constant-expression '...' constant-expression ':' statement 2215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 2225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Note that this does not parse the 'statement' at the end. 2235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 2245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerParser::StmtResult Parser::ParseCaseStatement() { 2254e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner assert(Tok.is(tok::kw_case) && "Not a case stmt!"); 2265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation CaseLoc = ConsumeToken(); // eat the 'case'. 2275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 22815faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult LHS(Actions, ParseConstantExpression()); 2290e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (LHS.isInvalid()) { 2305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SkipUntil(tok::colon); 2315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 2325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2330e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 2345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // GNU case range extension. 2355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation DotDotDotLoc; 23615faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult RHS(Actions); 2374e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.is(tok::ellipsis)) { 2385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Diag(Tok, diag::ext_gnu_case_range); 2395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer DotDotDotLoc = ConsumeToken(); 2400e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 2410e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl RHS = ParseConstantExpression(); 2420e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (RHS.isInvalid()) { 2435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SkipUntil(tok::colon); 2445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 2455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2470e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 2484e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.isNot(tok::colon)) { 2491ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_colon_after) << "'case'"; 2505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SkipUntil(tok::colon); 2515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 2525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation ColonLoc = ConsumeToken(); 2555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Diagnose the common error "switch (X) { case 4: }", which is not valid. 2574e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.is(tok::r_brace)) { 2585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Diag(Tok, diag::err_label_end_of_compound_statement); 2595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 2605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 26215faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningStmtResult SubStmt(Actions, ParseStatement()); 2635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Broken substmt shouldn't prevent the case from being added to the AST. 2650e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (SubStmt.isInvalid()) 2661b273c403734d343d720acb28f04011807c8aa56Steve Naroff SubStmt = Actions.ActOnNullStmt(ColonLoc); 2675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 268effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl return Actions.ActOnCaseStmt(CaseLoc, LHS.release(), DotDotDotLoc, 269effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl RHS.release(), ColonLoc, SubStmt.release()); 2705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseDefaultStatement 2735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// labeled-statement: 2745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'default' ':' statement 2755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Note that this does not parse the 'statement' at the end. 2765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 2775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerParser::StmtResult Parser::ParseDefaultStatement() { 2784e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner assert(Tok.is(tok::kw_default) && "Not a default stmt!"); 2795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation DefaultLoc = ConsumeToken(); // eat the 'default'. 2805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2814e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.isNot(tok::colon)) { 2821ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_colon_after) << "'default'"; 2835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SkipUntil(tok::colon); 2845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 2855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation ColonLoc = ConsumeToken(); 2885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Diagnose the common error "switch (X) {... default: }", which is not valid. 2904e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.is(tok::r_brace)) { 2915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Diag(Tok, diag::err_label_end_of_compound_statement); 2925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 2935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 29515faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningStmtResult SubStmt(Actions, ParseStatement()); 2960e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (SubStmt.isInvalid()) 2975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 2985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2990e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc, 300effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl SubStmt.release(), CurScope); 3015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 3025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCompoundStatement - Parse a "{}" block. 3055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 3065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// compound-statement: [C99 6.8.2] 3075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// { block-item-list[opt] } 3085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU] { label-declarations block-item-list } [TODO] 3095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 3105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// block-item-list: 3115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// block-item 3125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// block-item-list block-item 3135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 3145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// block-item: 3155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// declaration 31645a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner/// [GNU] '__extension__' declaration 3175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// statement 3185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [OMP] openmp-directive [TODO] 3195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 3205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU] label-declarations: 3215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU] label-declaration 3225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU] label-declarations label-declaration 3235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 3245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU] label-declaration: 3255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU] '__label__' identifier-list ';' 3265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 3275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [OMP] openmp-directive: [TODO] 3285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [OMP] barrier-directive 3295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [OMP] flush-directive 3305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 33198414c1b7d1944a57156d52e29bd41c005de09acChris LattnerParser::StmtResult Parser::ParseCompoundStatement(bool isStmtExpr) { 3324e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner assert(Tok.is(tok::l_brace) && "Not a compount stmt!"); 3335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 33431e057270232c1c37602579cb6461c2704175672Chris Lattner // Enter a scope to hold everything within the compound stmt. Compound 33531e057270232c1c37602579cb6461c2704175672Chris Lattner // statements can always hold declarations. 3368935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ParseScope CompoundScope(this, Scope::DeclScope); 3375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Parse the statements in the body. 33915faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningStmtResult Body(Actions, ParseCompoundStatementBody(isStmtExpr)); 340effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl return Body.result(); 3415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 3425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCompoundStatementBody - Parse a sequence of statements and invoke the 3451b273c403734d343d720acb28f04011807c8aa56Steve Naroff/// ActOnCompoundStmt action. This expects the '{' to be the current token, and 3465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// consume the '}' at the end of the block. It does not manipulate the scope 3475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// stack. 34898414c1b7d1944a57156d52e29bd41c005de09acChris LattnerParser::StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { 3495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation LBraceLoc = ConsumeBrace(); // eat the '{'. 3505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // TODO: "__label__ X, Y, Z;" is the GNU "Local Label" extension. These are 35245a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner // only allowed at the start of a compound stmt regardless of the language. 353a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl 354a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl typedef StmtVector StmtsTy; 355a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl StmtsTy Stmts(Actions); 3564e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 35715faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningStmtResult R(Actions); 3584e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.isNot(tok::kw___extension__)) { 35945a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner R = ParseStatementOrDeclaration(false); 36045a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner } else { 36145a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner // __extension__ can start declarations and it can also be a unary 36245a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner // operator for expressions. Consume multiple __extension__ markers here 36345a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner // until we can determine which is which. 36445a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner SourceLocation ExtLoc = ConsumeToken(); 3654e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner while (Tok.is(tok::kw___extension__)) 36645a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner ConsumeToken(); 36745a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner 368043a0b50a2a7a29c78a1ffb774f6fca8baf464a0Chris Lattner // __extension__ silences extension warnings in the subexpression. 36939146d6497ad5e7ca8ef639221e7b3e15d07c888Chris Lattner ExtensionRAIIObject O(Diags); // Use RAII to do this. 37039146d6497ad5e7ca8ef639221e7b3e15d07c888Chris Lattner 37145a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner // If this is the start of a declaration, parse it as such. 3725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (isDeclarationStatement()) { 37345a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner // FIXME: Save the __extension__ on the decl as a node somehow. 37481c018d9482e7cc2addadc6202dcf162a01faefdChris Lattner SourceLocation DeclStart = Tok.getLocation(); 37581c018d9482e7cc2addadc6202dcf162a01faefdChris Lattner DeclTy *Res = ParseDeclaration(Declarator::BlockContext); 37681c018d9482e7cc2addadc6202dcf162a01faefdChris Lattner // FIXME: Pass in the right location for the end of the declstmt. 377691a38b740562119ea8b2e25c3e04599971e708fChris Lattner R = Actions.ActOnDeclStmt(Res, DeclStart, DeclStart); 37845a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner } else { 37945a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner // Otherwise this was a unary __extension__ marker. Parse the 38045a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner // subexpression and add the __extension__ unary op. 38115faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult Res(Actions, ParseCastExpression(false)); 382043a0b50a2a7a29c78a1ffb774f6fca8baf464a0Chris Lattner 3830e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Res.isInvalid()) { 38445a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner SkipUntil(tok::semi); 38545a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner continue; 38645a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner } 38745a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner 38845a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner // Add the __extension__ node to the AST. 38974253736184c0717a0649922551bf9d8b6815651Douglas Gregor Res = Actions.ActOnUnaryOp(CurScope, ExtLoc, tok::kw___extension__, 390effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Res.release()); 3910e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Res.isInvalid()) 39245a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner continue; 39345a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner 39439146d6497ad5e7ca8ef639221e7b3e15d07c888Chris Lattner // Eat the semicolon at the end of stmt and convert the expr into a 39539146d6497ad5e7ca8ef639221e7b3e15d07c888Chris Lattner // statement. 39645a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr); 397effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl R = Actions.ActOnExprStmt(Res.release()); 39845a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner } 39945a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner } 40045a566cfcbec0efd50bc737991bdfcc70e986811Chris Lattner 4010e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (R.isUsable()) 402effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Stmts.push_back(R.release()); 4035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 4045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // We broke out of the while loop because we found a '}' or EOF. 4064e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.isNot(tok::r_brace)) { 4075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Diag(Tok, diag::err_expected_rbrace); 408d1a7cf8c922ae97cd70d784553c5b7566b5c5e7bSteve Naroff return true; 4095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 4105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation RBraceLoc = ConsumeBrace(); 4121b273c403734d343d720acb28f04011807c8aa56Steve Naroff return Actions.ActOnCompoundStmt(LBraceLoc, RBraceLoc, 413a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl Stmts.take(), Stmts.size(), isStmtExpr); 4145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 4155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseIfStatement 4175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// if-statement: [C99 6.8.4.1] 4185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'if' '(' expression ')' statement 4195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'if' '(' expression ')' statement 'else' statement 42071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++] 'if' '(' condition ')' statement 42171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++] 'if' '(' condition ')' statement 'else' statement 4225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 4235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerParser::StmtResult Parser::ParseIfStatement() { 4244e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner assert(Tok.is(tok::kw_if) && "Not an if stmt!"); 4255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation IfLoc = ConsumeToken(); // eat the 'if'. 4265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4274e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.isNot(tok::l_paren)) { 4281ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_lparen_after) << "if"; 4295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SkipUntil(tok::semi); 4305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 4315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 43271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 433488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis bool C99orCXX = getLang().C99 || getLang().CPlusPlus; 434488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis 4352215325a5696fb3b23551239b900559bb3018ee9Chris Lattner // C99 6.8.4p3 - In C99, the if statement is a block. This is not 4362215325a5696fb3b23551239b900559bb3018ee9Chris Lattner // the case for C90. 437488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // 438488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // C++ 6.4p3: 439488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // A name introduced by a declaration in a condition is in scope from its 440488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // point of declaration until the end of the substatements controlled by the 441488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // condition. 44214d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis // C++ 3.3.2p4: 44314d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis // Names declared in the for-init-statement, and in the condition of if, 44414d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis // while, for, and switch statements are local to the if, while, for, or 44514d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis // switch statement (including the controlled statement). 446488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // 4478935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ParseScope IfScope(this, Scope::DeclScope | Scope::ControlScope, C99orCXX); 4482215325a5696fb3b23551239b900559bb3018ee9Chris Lattner 4495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Parse the condition. 45015faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult CondExp(Actions); 45171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (getLang().CPlusPlus) { 45271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SourceLocation LParenLoc = ConsumeParen(); 45371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis CondExp = ParseCXXCondition(); 45471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis MatchRHSPunctuation(tok::r_paren, LParenLoc); 45571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } else { 45671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis CondExp = ParseSimpleParenExpression(); 45771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } 45871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 4590e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (CondExp.isInvalid()) { 4605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SkipUntil(tok::semi); 4615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 4625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 4635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4640ecea03077117c7ea54c88091a44c73cef67923cChris Lattner // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if 46538484403c8356fb41540ace6c74f28867f28febaChris Lattner // there is no compound stmt. C90 does not have this clause. We only do this 46638484403c8356fb41540ace6c74f28867f28febaChris Lattner // if the body isn't a compound statement to avoid push/pop in common cases. 467488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // 468488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // C++ 6.4p1: 469488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // The substatement in a selection-statement (each substatement, in the else 470488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // form of the if statement) implicitly defines a local scope. 471488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // 472488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // For C++ we create a scope for the condition and a new scope for 473488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // substatements because: 474488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // -When the 'then' scope exits, we want the condition declaration to still be 475488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // active for the 'else' scope too. 476488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // -Sema will detect name clashes by considering declarations of a 477488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // 'ControlScope' as part of its direct subscope. 478488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // -If we wanted the condition and substatement to be in the same scope, we 479488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // would have to notify ParseStatement not to create a new scope. It's 480488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // simpler to let it create a new scope. 481488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // 4828935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ParseScope InnerScope(this, Scope::DeclScope, 4838935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor C99orCXX && Tok.isNot(tok::l_brace)); 48471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 485b96728d90abc35a520798066d2a75ca36400a617Chris Lattner // Read the 'then' stmt. 486b96728d90abc35a520798066d2a75ca36400a617Chris Lattner SourceLocation ThenStmtLoc = Tok.getLocation(); 48715faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningStmtResult ThenStmt(Actions, ParseStatement()); 4885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 489a36ce713cff561b88f1cba5aad3f384c0fb0a249Chris Lattner // Pop the 'if' scope if needed. 4908935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor InnerScope.Exit(); 4915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If it has an else, parse it. 4935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation ElseLoc; 494b96728d90abc35a520798066d2a75ca36400a617Chris Lattner SourceLocation ElseStmtLoc; 49515faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningStmtResult ElseStmt(Actions); 4960e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 4974e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.is(tok::kw_else)) { 4985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ElseLoc = ConsumeToken(); 499a36ce713cff561b88f1cba5aad3f384c0fb0a249Chris Lattner 5000ecea03077117c7ea54c88091a44c73cef67923cChris Lattner // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if 50138484403c8356fb41540ace6c74f28867f28febaChris Lattner // there is no compound stmt. C90 does not have this clause. We only do 50238484403c8356fb41540ace6c74f28867f28febaChris Lattner // this if the body isn't a compound statement to avoid push/pop in common 50338484403c8356fb41540ace6c74f28867f28febaChris Lattner // cases. 504488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // 505488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // C++ 6.4p1: 506488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // The substatement in a selection-statement (each substatement, in the else 507488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // form of the if statement) implicitly defines a local scope. 508488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // 5098935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ParseScope InnerScope(this, Scope::DeclScope, 5108935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor C99orCXX && Tok.isNot(tok::l_brace)); 5110e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 512caaf29a08761b14fbe42a29080c22dd6961056d1Douglas Gregor bool WithinElse = CurScope->isWithinElse(); 513caaf29a08761b14fbe42a29080c22dd6961056d1Douglas Gregor CurScope->setWithinElse(true); 514b96728d90abc35a520798066d2a75ca36400a617Chris Lattner ElseStmtLoc = Tok.getLocation(); 5155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ElseStmt = ParseStatement(); 516caaf29a08761b14fbe42a29080c22dd6961056d1Douglas Gregor CurScope->setWithinElse(WithinElse); 517a36ce713cff561b88f1cba5aad3f384c0fb0a249Chris Lattner 518a36ce713cff561b88f1cba5aad3f384c0fb0a249Chris Lattner // Pop the 'else' scope if needed. 5198935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor InnerScope.Exit(); 5205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 5215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5228935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor IfScope.Exit(); 5232215325a5696fb3b23551239b900559bb3018ee9Chris Lattner 524b96728d90abc35a520798066d2a75ca36400a617Chris Lattner // If the then or else stmt is invalid and the other is valid (and present), 525b96728d90abc35a520798066d2a75ca36400a617Chris Lattner // make turn the invalid one into a null stmt to avoid dropping the other 526b96728d90abc35a520798066d2a75ca36400a617Chris Lattner // part. If both are invalid, return error. 5270e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if ((ThenStmt.isInvalid() && ElseStmt.isInvalid()) || 5280e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl (ThenStmt.isInvalid() && ElseStmt.get() == 0) || 5290e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl (ThenStmt.get() == 0 && ElseStmt.isInvalid())) { 530a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl // Both invalid, or one is invalid and other is non-present: return error. 531b96728d90abc35a520798066d2a75ca36400a617Chris Lattner return true; 532b96728d90abc35a520798066d2a75ca36400a617Chris Lattner } 5330e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 534b96728d90abc35a520798066d2a75ca36400a617Chris Lattner // Now if either are invalid, replace with a ';'. 5350e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (ThenStmt.isInvalid()) 536b96728d90abc35a520798066d2a75ca36400a617Chris Lattner ThenStmt = Actions.ActOnNullStmt(ThenStmtLoc); 5370e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (ElseStmt.isInvalid()) 538b96728d90abc35a520798066d2a75ca36400a617Chris Lattner ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc); 5390e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 540effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl return Actions.ActOnIfStmt(IfLoc, CondExp.release(), ThenStmt.release(), 541effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl ElseLoc, ElseStmt.release()); 5425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 5435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseSwitchStatement 5455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// switch-statement: 5465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'switch' '(' expression ')' statement 54771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++] 'switch' '(' condition ')' statement 5485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerParser::StmtResult Parser::ParseSwitchStatement() { 5494e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner assert(Tok.is(tok::kw_switch) && "Not a switch stmt!"); 5505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation SwitchLoc = ConsumeToken(); // eat the 'switch'. 5515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5524e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.isNot(tok::l_paren)) { 5531ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_lparen_after) << "switch"; 5545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SkipUntil(tok::semi); 5555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 5565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 5572215325a5696fb3b23551239b900559bb3018ee9Chris Lattner 558488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis bool C99orCXX = getLang().C99 || getLang().CPlusPlus; 559488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis 5602215325a5696fb3b23551239b900559bb3018ee9Chris Lattner // C99 6.8.4p3 - In C99, the switch statement is a block. This is 5612215325a5696fb3b23551239b900559bb3018ee9Chris Lattner // not the case for C90. Start the switch scope. 562488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // 563488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // C++ 6.4p3: 564488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // A name introduced by a declaration in a condition is in scope from its 565488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // point of declaration until the end of the substatements controlled by the 566488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // condition. 56714d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis // C++ 3.3.2p4: 56814d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis // Names declared in the for-init-statement, and in the condition of if, 56914d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis // while, for, and switch statements are local to the if, while, for, or 57014d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis // switch statement (including the controlled statement). 571488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // 5728935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor unsigned ScopeFlags 5738935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor = C99orCXX? Scope::BreakScope | Scope::DeclScope | Scope::ControlScope 5748935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor : Scope::BreakScope; 5758935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ParseScope SwitchScope(this, ScopeFlags); 5765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Parse the condition. 57815faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult Cond(Actions); 57971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (getLang().CPlusPlus) { 58071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SourceLocation LParenLoc = ConsumeParen(); 58171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis Cond = ParseCXXCondition(); 58271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis MatchRHSPunctuation(tok::r_paren, LParenLoc); 58371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } else { 58471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis Cond = ParseSimpleParenExpression(); 58571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } 5865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5878935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor if (Cond.isInvalid()) 588c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson return true; 5890e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 590effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl OwningStmtResult Switch(Actions, 591effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Actions.ActOnStartOfSwitchStmt(Cond.release())); 5920e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 5930ecea03077117c7ea54c88091a44c73cef67923cChris Lattner // C99 6.8.4p3 - In C99, the body of the switch statement is a scope, even if 59438484403c8356fb41540ace6c74f28867f28febaChris Lattner // there is no compound stmt. C90 does not have this clause. We only do this 59538484403c8356fb41540ace6c74f28867f28febaChris Lattner // if the body isn't a compound statement to avoid push/pop in common cases. 596488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // 597488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // C++ 6.4p1: 598488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // The substatement in a selection-statement (each substatement, in the else 599488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // form of the if statement) implicitly defines a local scope. 600488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // 601488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // See comments in ParseIfStatement for why we create a scope for the 602488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // condition and a new scope for substatement in C++. 603488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // 6048935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ParseScope InnerScope(this, Scope::DeclScope, 6058935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor C99orCXX && Tok.isNot(tok::l_brace)); 6060ecea03077117c7ea54c88091a44c73cef67923cChris Lattner 6075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Read the body statement. 60815faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningStmtResult Body(Actions, ParseStatement()); 6095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 6100ecea03077117c7ea54c88091a44c73cef67923cChris Lattner // Pop the body scope if needed. 6118935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor InnerScope.Exit(); 6120ecea03077117c7ea54c88091a44c73cef67923cChris Lattner 6130e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Body.isInvalid()) { 6141b273c403734d343d720acb28f04011807c8aa56Steve Naroff Body = Actions.ActOnNullStmt(Tok.getLocation()); 615c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson // FIXME: Remove the case statement list from the Switch statement. 616c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson } 6178935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor 6188935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor SwitchScope.Exit(); 6195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 620effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.release(), 621effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Body.release()); 6225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 6235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 6245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseWhileStatement 6255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// while-statement: [C99 6.8.5.1] 6265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'while' '(' expression ')' statement 62771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++] 'while' '(' condition ')' statement 6285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerParser::StmtResult Parser::ParseWhileStatement() { 6294e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner assert(Tok.is(tok::kw_while) && "Not a while stmt!"); 6305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation WhileLoc = Tok.getLocation(); 6315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ConsumeToken(); // eat the 'while'. 6325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 6334e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.isNot(tok::l_paren)) { 6341ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_lparen_after) << "while"; 6355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SkipUntil(tok::semi); 6365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 6375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 6385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 639488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis bool C99orCXX = getLang().C99 || getLang().CPlusPlus; 640488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis 6412215325a5696fb3b23551239b900559bb3018ee9Chris Lattner // C99 6.8.5p5 - In C99, the while statement is a block. This is not 6422215325a5696fb3b23551239b900559bb3018ee9Chris Lattner // the case for C90. Start the loop scope. 643488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // 644488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // C++ 6.4p3: 645488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // A name introduced by a declaration in a condition is in scope from its 646488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // point of declaration until the end of the substatements controlled by the 647488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // condition. 64814d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis // C++ 3.3.2p4: 64914d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis // Names declared in the for-init-statement, and in the condition of if, 65014d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis // while, for, and switch statements are local to the if, while, for, or 65114d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis // switch statement (including the controlled statement). 652488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // 6538935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor unsigned ScopeFlags; 654488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis if (C99orCXX) 6558935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ScopeFlags = Scope::BreakScope | Scope::ContinueScope | 6568935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor Scope::DeclScope | Scope::ControlScope; 6572215325a5696fb3b23551239b900559bb3018ee9Chris Lattner else 6588935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ScopeFlags = Scope::BreakScope | Scope::ContinueScope; 6598935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ParseScope WhileScope(this, ScopeFlags); 6605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 6615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Parse the condition. 66215faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult Cond(Actions); 66371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (getLang().CPlusPlus) { 66471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SourceLocation LParenLoc = ConsumeParen(); 66571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis Cond = ParseCXXCondition(); 66671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis MatchRHSPunctuation(tok::r_paren, LParenLoc); 66771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } else { 66871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis Cond = ParseSimpleParenExpression(); 66971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } 6700e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 6710ecea03077117c7ea54c88091a44c73cef67923cChris Lattner // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if 67238484403c8356fb41540ace6c74f28867f28febaChris Lattner // there is no compound stmt. C90 does not have this clause. We only do this 67338484403c8356fb41540ace6c74f28867f28febaChris Lattner // if the body isn't a compound statement to avoid push/pop in common cases. 674488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // 675488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // C++ 6.5p2: 676488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // The substatement in an iteration-statement implicitly defines a local scope 677488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // which is entered and exited each time through the loop. 678488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // 679488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // See comments in ParseIfStatement for why we create a scope for the 680488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // condition and a new scope for substatement in C++. 681488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // 6828935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ParseScope InnerScope(this, Scope::DeclScope, 6838935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor C99orCXX && Tok.isNot(tok::l_brace)); 6840ecea03077117c7ea54c88091a44c73cef67923cChris Lattner 6855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Read the body statement. 68615faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningStmtResult Body(Actions, ParseStatement()); 6875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 6880ecea03077117c7ea54c88091a44c73cef67923cChris Lattner // Pop the body scope if needed. 6898935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor InnerScope.Exit(); 6908935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor WhileScope.Exit(); 6915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 6920e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Cond.isInvalid() || Body.isInvalid()) return true; 6935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 694effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl return Actions.ActOnWhileStmt(WhileLoc, Cond.release(), Body.release()); 6955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 6965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 6975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseDoStatement 6985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// do-statement: [C99 6.8.5.2] 6995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'do' statement 'while' '(' expression ')' ';' 7005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Note: this lets the caller parse the end ';'. 7015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerParser::StmtResult Parser::ParseDoStatement() { 7024e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner assert(Tok.is(tok::kw_do) && "Not a do stmt!"); 7035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation DoLoc = ConsumeToken(); // eat the 'do'. 7045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 7052215325a5696fb3b23551239b900559bb3018ee9Chris Lattner // C99 6.8.5p5 - In C99, the do statement is a block. This is not 7062215325a5696fb3b23551239b900559bb3018ee9Chris Lattner // the case for C90. Start the loop scope. 7078935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor unsigned ScopeFlags; 7082215325a5696fb3b23551239b900559bb3018ee9Chris Lattner if (getLang().C99) 7098935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ScopeFlags = Scope::BreakScope | Scope::ContinueScope | Scope::DeclScope; 7102215325a5696fb3b23551239b900559bb3018ee9Chris Lattner else 7118935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ScopeFlags = Scope::BreakScope | Scope::ContinueScope; 7128935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor 7138935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ParseScope DoScope(this, ScopeFlags); 7145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 7150ecea03077117c7ea54c88091a44c73cef67923cChris Lattner // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if 71638484403c8356fb41540ace6c74f28867f28febaChris Lattner // there is no compound stmt. C90 does not have this clause. We only do this 71738484403c8356fb41540ace6c74f28867f28febaChris Lattner // if the body isn't a compound statement to avoid push/pop in common cases. 718143db71d8d87bc015fb496f71ef83b268813835aArgyrios Kyrtzidis // 719143db71d8d87bc015fb496f71ef83b268813835aArgyrios Kyrtzidis // C++ 6.5p2: 720143db71d8d87bc015fb496f71ef83b268813835aArgyrios Kyrtzidis // The substatement in an iteration-statement implicitly defines a local scope 721143db71d8d87bc015fb496f71ef83b268813835aArgyrios Kyrtzidis // which is entered and exited each time through the loop. 722143db71d8d87bc015fb496f71ef83b268813835aArgyrios Kyrtzidis // 7238935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ParseScope InnerScope(this, Scope::DeclScope, 7248935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor (getLang().C99 || getLang().CPlusPlus) && 7258935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor Tok.isNot(tok::l_brace)); 7260ecea03077117c7ea54c88091a44c73cef67923cChris Lattner 7275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Read the body statement. 72815faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningStmtResult Body(Actions, ParseStatement()); 7295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 7300ecea03077117c7ea54c88091a44c73cef67923cChris Lattner // Pop the body scope if needed. 7318935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor InnerScope.Exit(); 7320ecea03077117c7ea54c88091a44c73cef67923cChris Lattner 7334e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.isNot(tok::kw_while)) { 7340e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (!Body.isInvalid()) { 735195044028b76133e2a1f245b094468fe07db7330Chris Lattner Diag(Tok, diag::err_expected_while); 73628eb7e992b9a266abb300da25b6d3c1557cec361Chris Lattner Diag(DoLoc, diag::note_matching) << "do"; 737195044028b76133e2a1f245b094468fe07db7330Chris Lattner SkipUntil(tok::semi, false, true); 738195044028b76133e2a1f245b094468fe07db7330Chris Lattner } 7395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 7405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 7415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation WhileLoc = ConsumeToken(); 7425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 7434e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.isNot(tok::l_paren)) { 7441ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_lparen_after) << "do/while"; 745195044028b76133e2a1f245b094468fe07db7330Chris Lattner SkipUntil(tok::semi, false, true); 7465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 7475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 7485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 7495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Parse the condition. 75015faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult Cond(Actions, ParseSimpleParenExpression()); 7518935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor DoScope.Exit(); 7520e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 7530e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Cond.isInvalid() || Body.isInvalid()) return true; 7540e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 755effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl return Actions.ActOnDoStmt(DoLoc, Body.release(), WhileLoc, Cond.release()); 7565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 7575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 7585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseForStatement 7595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// for-statement: [C99 6.8.5.3] 7605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'for' '(' expr[opt] ';' expr[opt] ';' expr[opt] ')' statement 7615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'for' '(' declaration expr[opt] ';' expr[opt] ')' statement 76271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++] 'for' '(' for-init-statement condition[opt] ';' expression[opt] ')' 76371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++] statement 7643ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian/// [OBJC2] 'for' '(' declaration 'in' expr ')' statement 7653ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian/// [OBJC2] 'for' '(' expr 'in' expr ')' statement 76671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// 76771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++] for-init-statement: 76871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++] expression-statement 76971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [C++] simple-declaration 77071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// 7715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerParser::StmtResult Parser::ParseForStatement() { 7724e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner assert(Tok.is(tok::kw_for) && "Not a for stmt!"); 7735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation ForLoc = ConsumeToken(); // eat the 'for'. 7745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 7754e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.isNot(tok::l_paren)) { 7761ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_lparen_after) << "for"; 7775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SkipUntil(tok::semi); 7785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 7795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 7805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 781488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis bool C99orCXX = getLang().C99 || getLang().CPlusPlus; 782488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis 7832215325a5696fb3b23551239b900559bb3018ee9Chris Lattner // C99 6.8.5p5 - In C99, the for statement is a block. This is not 7842215325a5696fb3b23551239b900559bb3018ee9Chris Lattner // the case for C90. Start the loop scope. 785488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // 786488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // C++ 6.4p3: 787488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // A name introduced by a declaration in a condition is in scope from its 788488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // point of declaration until the end of the substatements controlled by the 789488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // condition. 79014d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis // C++ 3.3.2p4: 79114d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis // Names declared in the for-init-statement, and in the condition of if, 79214d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis // while, for, and switch statements are local to the if, while, for, or 79314d08c0c776302e2df12239d276072f43c894f0eArgyrios Kyrtzidis // switch statement (including the controlled statement). 794488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // C++ 6.5.3p1: 795488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // Names declared in the for-init-statement are in the same declarative-region 796488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // as those declared in the condition. 797488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // 7988935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor unsigned ScopeFlags; 799488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis if (C99orCXX) 8008935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ScopeFlags = Scope::BreakScope | Scope::ContinueScope | 8018935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor Scope::DeclScope | Scope::ControlScope; 8022215325a5696fb3b23551239b900559bb3018ee9Chris Lattner else 8038935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ScopeFlags = Scope::BreakScope | Scope::ContinueScope; 8048935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor 8058935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ParseScope ForScope(this, ScopeFlags); 8065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 8075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation LParenLoc = ConsumeParen(); 80815faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult Value(Actions); 8090e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 810bdd15f701fe98f77b1b8ddb3f4a5c0d83bb8fa9cFariborz Jahanian bool ForEach = false; 81115faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningStmtResult FirstPart(Actions), ThirdPart(Actions); 81215faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult SecondPart(Actions); 8130e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 8145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Parse the first part of the for specifier. 8154e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.is(tok::semi)) { // for (; 8165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // no first part, eat the ';'. 8175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ConsumeToken(); 818bbc70c019f7b7f9a256ee29dab5287ecc82c6553Argyrios Kyrtzidis } else if (isSimpleDeclaration()) { // for (int X = 4; 8195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Parse declaration, which eats the ';'. 820488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis if (!C99orCXX) // Use of C99-style for loops in C90 mode? 8215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Diag(Tok, diag::ext_c99_variable_decl_in_for_loop); 82281c018d9482e7cc2addadc6202dcf162a01faefdChris Lattner 82381c018d9482e7cc2addadc6202dcf162a01faefdChris Lattner SourceLocation DeclStart = Tok.getLocation(); 82471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis DeclTy *aBlockVarDecl = ParseSimpleDeclaration(Declarator::ForContext); 82581c018d9482e7cc2addadc6202dcf162a01faefdChris Lattner // FIXME: Pass in the right location for the end of the declstmt. 8260e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl FirstPart = Actions.ActOnDeclStmt(aBlockVarDecl, DeclStart, 8270e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl DeclStart); 828bdd15f701fe98f77b1b8ddb3f4a5c0d83bb8fa9cFariborz Jahanian if ((ForEach = isTokIdentifier_in())) { 8293ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian ConsumeToken(); // consume 'in' 8300e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl SecondPart = ParseExpression(); 8313ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian } 8325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 8335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Value = ParseExpression(); 8345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 8355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Turn the expression into a stmt. 8360e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (!Value.isInvalid()) 837effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl FirstPart = Actions.ActOnExprStmt(Value.release()); 838effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl 8394e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.is(tok::semi)) { 8405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ConsumeToken(); 8413ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian } 842bdd15f701fe98f77b1b8ddb3f4a5c0d83bb8fa9cFariborz Jahanian else if ((ForEach = isTokIdentifier_in())) { 8433ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian ConsumeToken(); // consume 'in' 8440e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl SecondPart = ParseExpression(); 8453ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian } 8463ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian else { 8470e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (!Value.isInvalid()) Diag(Tok, diag::err_expected_semi_for); 8485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SkipUntil(tok::semi); 8495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 8505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 851bdd15f701fe98f77b1b8ddb3f4a5c0d83bb8fa9cFariborz Jahanian if (!ForEach) { 8520e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl assert(!SecondPart.get() && "Shouldn't have a second expression yet."); 8533ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian // Parse the second part of the for specifier. 8543ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian if (Tok.is(tok::semi)) { // for (...;; 8553ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian // no second part. 8563ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian } else { 8570e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl SecondPart = getLang().CPlusPlus ? ParseCXXCondition() 8580e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl : ParseExpression(); 8593ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian } 8600e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 8613ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian if (Tok.is(tok::semi)) { 8623ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian ConsumeToken(); 8633ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian } else { 8640e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (!SecondPart.isInvalid()) Diag(Tok, diag::err_expected_semi_for); 8653ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian SkipUntil(tok::semi); 8663ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian } 8675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 8683ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian // Parse the third part of the for specifier. 8693ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian if (Tok.is(tok::r_paren)) { // for (...;...;) 8703ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian // no third part. 8713ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian } else { 8723ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian Value = ParseExpression(); 8730e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (!Value.isInvalid()) { 8743ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian // Turn the expression into a stmt. 875effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl ThirdPart = Actions.ActOnExprStmt(Value.release()); 8763ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian } 8775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 8785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 8795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Match the ')'. 8805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 8810e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 8820ecea03077117c7ea54c88091a44c73cef67923cChris Lattner // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if 88338484403c8356fb41540ace6c74f28867f28febaChris Lattner // there is no compound stmt. C90 does not have this clause. We only do this 88438484403c8356fb41540ace6c74f28867f28febaChris Lattner // if the body isn't a compound statement to avoid push/pop in common cases. 885488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // 886488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // C++ 6.5p2: 887488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // The substatement in an iteration-statement implicitly defines a local scope 888488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // which is entered and exited each time through the loop. 889488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // 890488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // See comments in ParseIfStatement for why we create a scope for 891488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // for-init-statement/condition and a new scope for substatement in C++. 892488d37e8c0bffe5c11e8fe508e43e445e83bfbddArgyrios Kyrtzidis // 8938935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ParseScope InnerScope(this, Scope::DeclScope, 8948935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor C99orCXX && Tok.isNot(tok::l_brace)); 8950e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 8965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Read the body statement. 89715faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningStmtResult Body(Actions, ParseStatement()); 8980e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 8990ecea03077117c7ea54c88091a44c73cef67923cChris Lattner // Pop the body scope if needed. 9008935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor InnerScope.Exit(); 9010ecea03077117c7ea54c88091a44c73cef67923cChris Lattner 9025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Leave the for-scope. 9038935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ForScope.Exit(); 9040e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 9050e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Body.isInvalid()) 9060e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl return true; 907effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl 908effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl if (!ForEach) 909effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl return Actions.ActOnForStmt(ForLoc, LParenLoc, FirstPart.release(), 910effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl SecondPart.release(), ThirdPart.release(), 911effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl RParenLoc, Body.release()); 912bdd15f701fe98f77b1b8ddb3f4a5c0d83bb8fa9cFariborz Jahanian else 9130e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl return Actions.ActOnObjCForCollectionStmt(ForLoc, LParenLoc, 914effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl FirstPart.release(), 915effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl SecondPart.release(), 916effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl RParenLoc, Body.release()); 9175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 9185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 9195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseGotoStatement 9205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// jump-statement: 9215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'goto' identifier ';' 9225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU] 'goto' '*' expression ';' 9235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 9245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Note: this lets the caller parse the end ';'. 9255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 9265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerParser::StmtResult Parser::ParseGotoStatement() { 9274e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner assert(Tok.is(tok::kw_goto) && "Not a goto stmt!"); 9285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation GotoLoc = ConsumeToken(); // eat the 'goto'. 9295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 93015faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningStmtResult Res(Actions); 9314e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.is(tok::identifier)) { 9321b273c403734d343d720acb28f04011807c8aa56Steve Naroff Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(), 9335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Tok.getIdentifierInfo()); 9345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ConsumeToken(); 9354e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner } else if (Tok.is(tok::star) && !getLang().NoExtensions) { 9365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // GNU indirect goto extension. 9375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Diag(Tok, diag::ext_gnu_indirect_goto); 9385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation StarLoc = ConsumeToken(); 93915faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult R(Actions, ParseExpression()); 9400e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (R.isInvalid()) { // Skip to the semicolon, but don't consume it. 9415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SkipUntil(tok::semi, false, true); 9425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 9435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 944effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.release()); 94595cfb85ad1820117e0864712555f3aa4fdf4721aChris Lattner } else { 94695cfb85ad1820117e0864712555f3aa4fdf4721aChris Lattner Diag(Tok, diag::err_expected_ident); 94795cfb85ad1820117e0864712555f3aa4fdf4721aChris Lattner return true; 9485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 9490e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 950effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl return Res.result(); 9515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 9525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 9535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseContinueStatement 9545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// jump-statement: 9555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'continue' ';' 9565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 9575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Note: this lets the caller parse the end ';'. 9585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 9595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerParser::StmtResult Parser::ParseContinueStatement() { 9605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation ContinueLoc = ConsumeToken(); // eat the 'continue'. 9611b273c403734d343d720acb28f04011807c8aa56Steve Naroff return Actions.ActOnContinueStmt(ContinueLoc, CurScope); 9625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 9635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 9645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseBreakStatement 9655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// jump-statement: 9665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'break' ';' 9675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 9685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Note: this lets the caller parse the end ';'. 9695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 9705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerParser::StmtResult Parser::ParseBreakStatement() { 9715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation BreakLoc = ConsumeToken(); // eat the 'break'. 9721b273c403734d343d720acb28f04011807c8aa56Steve Naroff return Actions.ActOnBreakStmt(BreakLoc, CurScope); 9735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 9745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 9755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseReturnStatement 9765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// jump-statement: 9775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'return' expression[opt] ';' 9785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerParser::StmtResult Parser::ParseReturnStatement() { 9794e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner assert(Tok.is(tok::kw_return) && "Not a return stmt!"); 9805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation ReturnLoc = ConsumeToken(); // eat the 'return'. 9815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 98215faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult R(Actions); 9834e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.isNot(tok::semi)) { 9845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer R = ParseExpression(); 9850e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (R.isInvalid()) { // Skip to the semicolon, but don't consume it. 9865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SkipUntil(tok::semi, false, true); 9875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 9885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 9895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 990effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl return Actions.ActOnReturnStmt(ReturnLoc, R.release()); 9915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 9925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 9935f8aa696619e32bf307232841fedb704ba733b4dSteve Naroff/// FuzzyParseMicrosoftAsmStatement. When -fms-extensions is enabled, this 9945f8aa696619e32bf307232841fedb704ba733b4dSteve Naroff/// routine is called to skip/ignore tokens that comprise the MS asm statement. 995d62701bc5321049353017e9abf1963edd57646aaSteve NaroffParser::StmtResult Parser::FuzzyParseMicrosoftAsmStatement() { 996b746ce84fb5c3fd2c5659f84dc6f2a883b499dc2Steve Naroff if (Tok.is(tok::l_brace)) { 997b746ce84fb5c3fd2c5659f84dc6f2a883b499dc2Steve Naroff unsigned short savedBraceCount = BraceCount; 998b746ce84fb5c3fd2c5659f84dc6f2a883b499dc2Steve Naroff do { 999b746ce84fb5c3fd2c5659f84dc6f2a883b499dc2Steve Naroff ConsumeAnyToken(); 1000b746ce84fb5c3fd2c5659f84dc6f2a883b499dc2Steve Naroff } while (BraceCount > savedBraceCount && Tok.isNot(tok::eof)); 1001b746ce84fb5c3fd2c5659f84dc6f2a883b499dc2Steve Naroff } else { 1002b746ce84fb5c3fd2c5659f84dc6f2a883b499dc2Steve Naroff // From the MS website: If used without braces, the __asm keyword means 1003b746ce84fb5c3fd2c5659f84dc6f2a883b499dc2Steve Naroff // that the rest of the line is an assembly-language statement. 1004b746ce84fb5c3fd2c5659f84dc6f2a883b499dc2Steve Naroff SourceManager &SrcMgr = PP.getSourceManager(); 100503d6bc6734eb79dc27628d9ea1126c299c80b4b6Steve Naroff SourceLocation TokLoc = Tok.getLocation(); 1006362809751711f7dc4ab01653ec7964a2e95f999bSteve Naroff unsigned lineNo = SrcMgr.getLogicalLineNumber(TokLoc); 1007362809751711f7dc4ab01653ec7964a2e95f999bSteve Naroff do { 1008362809751711f7dc4ab01653ec7964a2e95f999bSteve Naroff ConsumeAnyToken(); 1009362809751711f7dc4ab01653ec7964a2e95f999bSteve Naroff TokLoc = Tok.getLocation(); 1010362809751711f7dc4ab01653ec7964a2e95f999bSteve Naroff } while ((SrcMgr.getLogicalLineNumber(TokLoc) == lineNo) && 1011362809751711f7dc4ab01653ec7964a2e95f999bSteve Naroff Tok.isNot(tok::r_brace) && Tok.isNot(tok::semi) && 1012362809751711f7dc4ab01653ec7964a2e95f999bSteve Naroff Tok.isNot(tok::eof)); 1013b746ce84fb5c3fd2c5659f84dc6f2a883b499dc2Steve Naroff } 1014d77bc2834269593282e06806a74d14e244bc26a4Steve Naroff return Actions.ActOnNullStmt(Tok.getLocation()); 1015d62701bc5321049353017e9abf1963edd57646aaSteve Naroff} 1016d62701bc5321049353017e9abf1963edd57646aaSteve Naroff 10175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseAsmStatement - Parse a GNU extended asm statement. 10185f8aa696619e32bf307232841fedb704ba733b4dSteve Naroff/// asm-statement: 10195f8aa696619e32bf307232841fedb704ba733b4dSteve Naroff/// gnu-asm-statement 10205f8aa696619e32bf307232841fedb704ba733b4dSteve Naroff/// ms-asm-statement 10215f8aa696619e32bf307232841fedb704ba733b4dSteve Naroff/// 10225f8aa696619e32bf307232841fedb704ba733b4dSteve Naroff/// [GNU] gnu-asm-statement: 10235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'asm' type-qualifier[opt] '(' asm-argument ')' ';' 10245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 10255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU] asm-argument: 10265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// asm-string-literal 10275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// asm-string-literal ':' asm-operands[opt] 10285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt] 10295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt] 10305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ':' asm-clobbers 10315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 10325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU] asm-clobbers: 10335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// asm-string-literal 10345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// asm-clobbers ',' asm-string-literal 10355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 10365f8aa696619e32bf307232841fedb704ba733b4dSteve Naroff/// [MS] ms-asm-statement: 10375f8aa696619e32bf307232841fedb704ba733b4dSteve Naroff/// '__asm' assembly-instruction ';'[opt] 10385f8aa696619e32bf307232841fedb704ba733b4dSteve Naroff/// '__asm' '{' assembly-instruction-list '}' ';'[opt] 10395f8aa696619e32bf307232841fedb704ba733b4dSteve Naroff/// 10405f8aa696619e32bf307232841fedb704ba733b4dSteve Naroff/// [MS] assembly-instruction-list: 10415f8aa696619e32bf307232841fedb704ba733b4dSteve Naroff/// assembly-instruction ';'[opt] 10425f8aa696619e32bf307232841fedb704ba733b4dSteve Naroff/// assembly-instruction-list ';' assembly-instruction ';'[opt] 10435f8aa696619e32bf307232841fedb704ba733b4dSteve Naroff/// 1044d62701bc5321049353017e9abf1963edd57646aaSteve NaroffParser::StmtResult Parser::ParseAsmStatement(bool &msAsm) { 10454e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner assert(Tok.is(tok::kw_asm) && "Not an asm stmt"); 1046fe795956194141c91ae555985c9b930595bff43fChris Lattner SourceLocation AsmLoc = ConsumeToken(); 10475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 10485f8aa696619e32bf307232841fedb704ba733b4dSteve Naroff if (getLang().Microsoft && Tok.isNot(tok::l_paren) && !isTypeQualifier()) { 1049d62701bc5321049353017e9abf1963edd57646aaSteve Naroff msAsm = true; 1050d62701bc5321049353017e9abf1963edd57646aaSteve Naroff return FuzzyParseMicrosoftAsmStatement(); 1051d62701bc5321049353017e9abf1963edd57646aaSteve Naroff } 10525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer DeclSpec DS; 10535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation Loc = Tok.getLocation(); 10545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ParseTypeQualifierListOpt(DS); 10555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 10565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // GNU asms accept, but warn, about type-qualifiers other than volatile. 10575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (DS.getTypeQualifiers() & DeclSpec::TQ_const) 10581ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Loc, diag::w_asm_qualifier_ignored) << "const"; 10595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (DS.getTypeQualifiers() & DeclSpec::TQ_restrict) 10601ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Loc, diag::w_asm_qualifier_ignored) << "restrict"; 10615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 10625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Remember if this was a volatile asm. 106339c47b56f45437bbc49c9568b7308a400234a730Anders Carlsson bool isVolatile = DS.getTypeQualifiers() & DeclSpec::TQ_volatile; 1064dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson bool isSimple = false; 10654e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.isNot(tok::l_paren)) { 10661ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_lparen_after) << "asm"; 10675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SkipUntil(tok::r_paren); 10685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 10695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 10705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Loc = ConsumeParen(); 10715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1072effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl OwningExprResult AsmString(ParseAsmStringLiteral()); 10730e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (AsmString.isInvalid()) 10746a0ef4b83c91a6d6d5acb4ed5577c4659fe022a3Anders Carlsson return true; 10750e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 1076b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson llvm::SmallVector<std::string, 4> Names; 1077a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector Constraints(Actions); 1078a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector Exprs(Actions); 1079a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector Clobbers(Actions); 1080dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson 1081dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson unsigned NumInputs = 0, NumOutputs = 0; 1082b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson 1083dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson SourceLocation RParenLoc; 1084dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson if (Tok.is(tok::r_paren)) { 1085dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson // We have a simple asm expression 1086dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson isSimple = true; 1087dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson 1088dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson RParenLoc = ConsumeParen(); 1089dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson } else { 1090a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl // Parse Outputs, if present. 10918bd36fcb4427519f41197d88b9121e2bbe9e3fc3Anders Carlsson if (ParseAsmOperandsOpt(Names, Constraints, Exprs)) 10928bd36fcb4427519f41197d88b9121e2bbe9e3fc3Anders Carlsson return true; 1093b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson 1094dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson NumOutputs = Names.size(); 10955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1096dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson // Parse Inputs, if present. 10978bd36fcb4427519f41197d88b9121e2bbe9e3fc3Anders Carlsson if (ParseAsmOperandsOpt(Names, Constraints, Exprs)) 10988bd36fcb4427519f41197d88b9121e2bbe9e3fc3Anders Carlsson return true; 1099effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl 1100dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson assert(Names.size() == Constraints.size() && 1101dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson Constraints.size() == Exprs.size() 1102dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson && "Input operand size mismatch!"); 1103b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson 1104dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson NumInputs = Names.size() - NumOutputs; 1105effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl 1106dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson // Parse the clobbers, if present. 1107dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson if (Tok.is(tok::colon)) { 1108dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson ConsumeToken(); 1109effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl 1110dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson // Parse the asm-string list for clobbers. 1111dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson while (1) { 1112effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl OwningExprResult Clobber(ParseAsmStringLiteral()); 11135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 11140e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Clobber.isInvalid()) 1115dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson break; 1116effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl 1117effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Clobbers.push_back(Clobber.release()); 1118effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl 1119dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson if (Tok.isNot(tok::comma)) break; 1120dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson ConsumeToken(); 1121dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson } 11225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1123effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl 1124dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson RParenLoc = MatchRHSPunctuation(tok::r_paren, Loc); 1125dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson } 1126effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl 1127dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson return Actions.ActOnAsmStmt(AsmLoc, isSimple, isVolatile, 1128dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson NumOutputs, NumInputs, 1129a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl &Names[0], Constraints.take(), 1130effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Exprs.take(), AsmString.release(), 1131a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl Clobbers.size(), Clobbers.take(), 1132b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson RParenLoc); 11335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 11345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 11355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseAsmOperands - Parse the asm-operands production as used by 11365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// asm-statement. We also parse a leading ':' token. If the leading colon is 11375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// not present, we do not parse anything. 11385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 11395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU] asm-operands: 11405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// asm-operand 11415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// asm-operands ',' asm-operand 11425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 11435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [GNU] asm-operand: 11445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// asm-string-literal '(' expression ')' 11455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// '[' identifier ']' asm-string-literal '(' expression ')' 11465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 11478bd36fcb4427519f41197d88b9121e2bbe9e3fc3Anders Carlssonbool Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names, 1148b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson llvm::SmallVectorImpl<ExprTy*> &Constraints, 1149b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson llvm::SmallVectorImpl<ExprTy*> &Exprs) { 11505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Only do anything if this operand is present. 11518bd36fcb4427519f41197d88b9121e2bbe9e3fc3Anders Carlsson if (Tok.isNot(tok::colon)) return false; 11525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ConsumeToken(); 11535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 11545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // 'asm-operands' isn't present? 11554e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (!isTokenStringLiteral() && Tok.isNot(tok::l_square)) 11568bd36fcb4427519f41197d88b9121e2bbe9e3fc3Anders Carlsson return false; 11575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1158b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson while (1) { 11595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Read the [id] if present. 11604e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.is(tok::l_square)) { 11615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation Loc = ConsumeBracket(); 11625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 11634e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.isNot(tok::identifier)) { 11645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Diag(Tok, diag::err_expected_ident); 11655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SkipUntil(tok::r_paren); 11668bd36fcb4427519f41197d88b9121e2bbe9e3fc3Anders Carlsson return true; 11675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 116869efba74cf5488060accf34c011b33ce6c15ece0Chris Lattner 1169b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson IdentifierInfo *II = Tok.getIdentifierInfo(); 117069efba74cf5488060accf34c011b33ce6c15ece0Chris Lattner ConsumeToken(); 1171b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson 1172b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson Names.push_back(std::string(II->getName(), II->getLength())); 11735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer MatchRHSPunctuation(tok::r_square, Loc); 1174b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson } else 1175b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson Names.push_back(std::string()); 11760e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl 1177effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl OwningExprResult Constraint(ParseAsmStringLiteral()); 11780e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Constraint.isInvalid()) { 1179b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson SkipUntil(tok::r_paren); 11808bd36fcb4427519f41197d88b9121e2bbe9e3fc3Anders Carlsson return true; 1181b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson } 1182effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Constraints.push_back(Constraint.release()); 11835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 11844e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.isNot(tok::l_paren)) { 11851ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_lparen_after) << "asm operand"; 11865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SkipUntil(tok::r_paren); 11878bd36fcb4427519f41197d88b9121e2bbe9e3fc3Anders Carlsson return true; 11885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1189effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl 11905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Read the parenthesized expression. 119115faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult Res(Actions, ParseSimpleParenExpression()); 11920e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Res.isInvalid()) { 11935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SkipUntil(tok::r_paren); 11948bd36fcb4427519f41197d88b9121e2bbe9e3fc3Anders Carlsson return true; 11955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1196effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Exprs.push_back(Res.release()); 11975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Eat the comma and continue parsing if it exists. 11988bd36fcb4427519f41197d88b9121e2bbe9e3fc3Anders Carlsson if (Tok.isNot(tok::comma)) return false; 11995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ConsumeToken(); 12005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 12018bd36fcb4427519f41197d88b9121e2bbe9e3fc3Anders Carlsson 12028bd36fcb4427519f41197d88b9121e2bbe9e3fc3Anders Carlsson return true; 12035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 1204f9ed3157c93495474003a5ec360039030fd42e9cFariborz Jahanian 1205f9ed3157c93495474003a5ec360039030fd42e9cFariborz JahanianParser::DeclTy *Parser::ParseFunctionStatementBody(DeclTy *Decl, 1206f9ed3157c93495474003a5ec360039030fd42e9cFariborz Jahanian SourceLocation L, SourceLocation R) { 1207f9ed3157c93495474003a5ec360039030fd42e9cFariborz Jahanian // Do not enter a scope for the brace, as the arguments are in the same scope 1208f9ed3157c93495474003a5ec360039030fd42e9cFariborz Jahanian // (the function body) as the body itself. Instead, just read the statement 1209f9ed3157c93495474003a5ec360039030fd42e9cFariborz Jahanian // list and put it into a CompoundStmt for safe keeping. 121015faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningStmtResult FnBody(Actions, ParseCompoundStatementBody()); 1211f9ed3157c93495474003a5ec360039030fd42e9cFariborz Jahanian 1212f9ed3157c93495474003a5ec360039030fd42e9cFariborz Jahanian // If the function body could not be parsed, make a bogus compoundstmt. 12130e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (FnBody.isInvalid()) 1214f9ed3157c93495474003a5ec360039030fd42e9cFariborz Jahanian FnBody = Actions.ActOnCompoundStmt(L, R, 0, 0, false); 1215f9ed3157c93495474003a5ec360039030fd42e9cFariborz Jahanian 1216effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl return Actions.ActOnFinishFunctionBody(Decl, FnBody.release()); 1217cd5af4b5863c63b62cde96ad6d52fb1eec0e26bbSeo Sanghyeon} 1218