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