1*f4a2713aSLionel Sambuc //===--- ParseStmt.cpp - Statement and Block Parser -----------------------===// 2*f4a2713aSLionel Sambuc // 3*f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure 4*f4a2713aSLionel Sambuc // 5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source 6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details. 7*f4a2713aSLionel Sambuc // 8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 9*f4a2713aSLionel Sambuc // 10*f4a2713aSLionel Sambuc // This file implements the Statement and Block portions of the Parser 11*f4a2713aSLionel Sambuc // interface. 12*f4a2713aSLionel Sambuc // 13*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 14*f4a2713aSLionel Sambuc 15*f4a2713aSLionel Sambuc #include "clang/Parse/Parser.h" 16*f4a2713aSLionel Sambuc #include "RAIIObjectsForParser.h" 17*f4a2713aSLionel Sambuc #include "clang/AST/ASTContext.h" 18*f4a2713aSLionel Sambuc #include "clang/Basic/Diagnostic.h" 19*f4a2713aSLionel Sambuc #include "clang/Basic/PrettyStackTrace.h" 20*f4a2713aSLionel Sambuc #include "clang/Basic/SourceManager.h" 21*f4a2713aSLionel Sambuc #include "clang/Basic/TargetInfo.h" 22*f4a2713aSLionel Sambuc #include "clang/Sema/DeclSpec.h" 23*f4a2713aSLionel Sambuc #include "clang/Sema/PrettyDeclStackTrace.h" 24*f4a2713aSLionel Sambuc #include "clang/Sema/Scope.h" 25*f4a2713aSLionel Sambuc #include "clang/Sema/TypoCorrection.h" 26*f4a2713aSLionel Sambuc #include "llvm/MC/MCAsmInfo.h" 27*f4a2713aSLionel Sambuc #include "llvm/MC/MCContext.h" 28*f4a2713aSLionel Sambuc #include "llvm/MC/MCObjectFileInfo.h" 29*f4a2713aSLionel Sambuc #include "llvm/MC/MCParser/MCAsmParser.h" 30*f4a2713aSLionel Sambuc #include "llvm/MC/MCRegisterInfo.h" 31*f4a2713aSLionel Sambuc #include "llvm/MC/MCStreamer.h" 32*f4a2713aSLionel Sambuc #include "llvm/MC/MCSubtargetInfo.h" 33*f4a2713aSLionel Sambuc #include "llvm/MC/MCTargetAsmParser.h" 34*f4a2713aSLionel Sambuc #include "llvm/Support/SourceMgr.h" 35*f4a2713aSLionel Sambuc #include "llvm/Support/TargetRegistry.h" 36*f4a2713aSLionel Sambuc #include "llvm/Support/TargetSelect.h" 37*f4a2713aSLionel Sambuc #include "llvm/ADT/SmallString.h" 38*f4a2713aSLionel Sambuc using namespace clang; 39*f4a2713aSLionel Sambuc 40*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 41*f4a2713aSLionel Sambuc // C99 6.8: Statements and Blocks. 42*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 43*f4a2713aSLionel Sambuc 44*f4a2713aSLionel Sambuc /// \brief Parse a standalone statement (for instance, as the body of an 'if', 45*f4a2713aSLionel Sambuc /// 'while', or 'for'). 46*f4a2713aSLionel Sambuc StmtResult Parser::ParseStatement(SourceLocation *TrailingElseLoc) { 47*f4a2713aSLionel Sambuc StmtResult Res; 48*f4a2713aSLionel Sambuc 49*f4a2713aSLionel Sambuc // We may get back a null statement if we found a #pragma. Keep going until 50*f4a2713aSLionel Sambuc // we get an actual statement. 51*f4a2713aSLionel Sambuc do { 52*f4a2713aSLionel Sambuc StmtVector Stmts; 53*f4a2713aSLionel Sambuc Res = ParseStatementOrDeclaration(Stmts, true, TrailingElseLoc); 54*f4a2713aSLionel Sambuc } while (!Res.isInvalid() && !Res.get()); 55*f4a2713aSLionel Sambuc 56*f4a2713aSLionel Sambuc return Res; 57*f4a2713aSLionel Sambuc } 58*f4a2713aSLionel Sambuc 59*f4a2713aSLionel Sambuc /// ParseStatementOrDeclaration - Read 'statement' or 'declaration'. 60*f4a2713aSLionel Sambuc /// StatementOrDeclaration: 61*f4a2713aSLionel Sambuc /// statement 62*f4a2713aSLionel Sambuc /// declaration 63*f4a2713aSLionel Sambuc /// 64*f4a2713aSLionel Sambuc /// statement: 65*f4a2713aSLionel Sambuc /// labeled-statement 66*f4a2713aSLionel Sambuc /// compound-statement 67*f4a2713aSLionel Sambuc /// expression-statement 68*f4a2713aSLionel Sambuc /// selection-statement 69*f4a2713aSLionel Sambuc /// iteration-statement 70*f4a2713aSLionel Sambuc /// jump-statement 71*f4a2713aSLionel Sambuc /// [C++] declaration-statement 72*f4a2713aSLionel Sambuc /// [C++] try-block 73*f4a2713aSLionel Sambuc /// [MS] seh-try-block 74*f4a2713aSLionel Sambuc /// [OBC] objc-throw-statement 75*f4a2713aSLionel Sambuc /// [OBC] objc-try-catch-statement 76*f4a2713aSLionel Sambuc /// [OBC] objc-synchronized-statement 77*f4a2713aSLionel Sambuc /// [GNU] asm-statement 78*f4a2713aSLionel Sambuc /// [OMP] openmp-construct [TODO] 79*f4a2713aSLionel Sambuc /// 80*f4a2713aSLionel Sambuc /// labeled-statement: 81*f4a2713aSLionel Sambuc /// identifier ':' statement 82*f4a2713aSLionel Sambuc /// 'case' constant-expression ':' statement 83*f4a2713aSLionel Sambuc /// 'default' ':' statement 84*f4a2713aSLionel Sambuc /// 85*f4a2713aSLionel Sambuc /// selection-statement: 86*f4a2713aSLionel Sambuc /// if-statement 87*f4a2713aSLionel Sambuc /// switch-statement 88*f4a2713aSLionel Sambuc /// 89*f4a2713aSLionel Sambuc /// iteration-statement: 90*f4a2713aSLionel Sambuc /// while-statement 91*f4a2713aSLionel Sambuc /// do-statement 92*f4a2713aSLionel Sambuc /// for-statement 93*f4a2713aSLionel Sambuc /// 94*f4a2713aSLionel Sambuc /// expression-statement: 95*f4a2713aSLionel Sambuc /// expression[opt] ';' 96*f4a2713aSLionel Sambuc /// 97*f4a2713aSLionel Sambuc /// jump-statement: 98*f4a2713aSLionel Sambuc /// 'goto' identifier ';' 99*f4a2713aSLionel Sambuc /// 'continue' ';' 100*f4a2713aSLionel Sambuc /// 'break' ';' 101*f4a2713aSLionel Sambuc /// 'return' expression[opt] ';' 102*f4a2713aSLionel Sambuc /// [GNU] 'goto' '*' expression ';' 103*f4a2713aSLionel Sambuc /// 104*f4a2713aSLionel Sambuc /// [OBC] objc-throw-statement: 105*f4a2713aSLionel Sambuc /// [OBC] '@' 'throw' expression ';' 106*f4a2713aSLionel Sambuc /// [OBC] '@' 'throw' ';' 107*f4a2713aSLionel Sambuc /// 108*f4a2713aSLionel Sambuc StmtResult 109*f4a2713aSLionel Sambuc Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement, 110*f4a2713aSLionel Sambuc SourceLocation *TrailingElseLoc) { 111*f4a2713aSLionel Sambuc 112*f4a2713aSLionel Sambuc ParenBraceBracketBalancer BalancerRAIIObj(*this); 113*f4a2713aSLionel Sambuc 114*f4a2713aSLionel Sambuc ParsedAttributesWithRange Attrs(AttrFactory); 115*f4a2713aSLionel Sambuc MaybeParseCXX11Attributes(Attrs, 0, /*MightBeObjCMessageSend*/ true); 116*f4a2713aSLionel Sambuc 117*f4a2713aSLionel Sambuc StmtResult Res = ParseStatementOrDeclarationAfterAttributes(Stmts, 118*f4a2713aSLionel Sambuc OnlyStatement, TrailingElseLoc, Attrs); 119*f4a2713aSLionel Sambuc 120*f4a2713aSLionel Sambuc assert((Attrs.empty() || Res.isInvalid() || Res.isUsable()) && 121*f4a2713aSLionel Sambuc "attributes on empty statement"); 122*f4a2713aSLionel Sambuc 123*f4a2713aSLionel Sambuc if (Attrs.empty() || Res.isInvalid()) 124*f4a2713aSLionel Sambuc return Res; 125*f4a2713aSLionel Sambuc 126*f4a2713aSLionel Sambuc return Actions.ProcessStmtAttributes(Res.get(), Attrs.getList(), Attrs.Range); 127*f4a2713aSLionel Sambuc } 128*f4a2713aSLionel Sambuc 129*f4a2713aSLionel Sambuc namespace { 130*f4a2713aSLionel Sambuc class StatementFilterCCC : public CorrectionCandidateCallback { 131*f4a2713aSLionel Sambuc public: 132*f4a2713aSLionel Sambuc StatementFilterCCC(Token nextTok) : NextToken(nextTok) { 133*f4a2713aSLionel Sambuc WantTypeSpecifiers = nextTok.is(tok::l_paren) || nextTok.is(tok::less) || 134*f4a2713aSLionel Sambuc nextTok.is(tok::identifier) || nextTok.is(tok::star) || 135*f4a2713aSLionel Sambuc nextTok.is(tok::amp) || nextTok.is(tok::l_square); 136*f4a2713aSLionel Sambuc WantExpressionKeywords = nextTok.is(tok::l_paren) || 137*f4a2713aSLionel Sambuc nextTok.is(tok::identifier) || 138*f4a2713aSLionel Sambuc nextTok.is(tok::arrow) || nextTok.is(tok::period); 139*f4a2713aSLionel Sambuc WantRemainingKeywords = nextTok.is(tok::l_paren) || nextTok.is(tok::semi) || 140*f4a2713aSLionel Sambuc nextTok.is(tok::identifier) || 141*f4a2713aSLionel Sambuc nextTok.is(tok::l_brace); 142*f4a2713aSLionel Sambuc WantCXXNamedCasts = false; 143*f4a2713aSLionel Sambuc } 144*f4a2713aSLionel Sambuc 145*f4a2713aSLionel Sambuc virtual bool ValidateCandidate(const TypoCorrection &candidate) { 146*f4a2713aSLionel Sambuc if (FieldDecl *FD = candidate.getCorrectionDeclAs<FieldDecl>()) 147*f4a2713aSLionel Sambuc return !candidate.getCorrectionSpecifier() || isa<ObjCIvarDecl>(FD); 148*f4a2713aSLionel Sambuc if (NextToken.is(tok::equal)) 149*f4a2713aSLionel Sambuc return candidate.getCorrectionDeclAs<VarDecl>(); 150*f4a2713aSLionel Sambuc if (NextToken.is(tok::period) && 151*f4a2713aSLionel Sambuc candidate.getCorrectionDeclAs<NamespaceDecl>()) 152*f4a2713aSLionel Sambuc return false; 153*f4a2713aSLionel Sambuc return CorrectionCandidateCallback::ValidateCandidate(candidate); 154*f4a2713aSLionel Sambuc } 155*f4a2713aSLionel Sambuc 156*f4a2713aSLionel Sambuc private: 157*f4a2713aSLionel Sambuc Token NextToken; 158*f4a2713aSLionel Sambuc }; 159*f4a2713aSLionel Sambuc } 160*f4a2713aSLionel Sambuc 161*f4a2713aSLionel Sambuc StmtResult 162*f4a2713aSLionel Sambuc Parser::ParseStatementOrDeclarationAfterAttributes(StmtVector &Stmts, 163*f4a2713aSLionel Sambuc bool OnlyStatement, SourceLocation *TrailingElseLoc, 164*f4a2713aSLionel Sambuc ParsedAttributesWithRange &Attrs) { 165*f4a2713aSLionel Sambuc const char *SemiError = 0; 166*f4a2713aSLionel Sambuc StmtResult Res; 167*f4a2713aSLionel Sambuc 168*f4a2713aSLionel Sambuc // Cases in this switch statement should fall through if the parser expects 169*f4a2713aSLionel Sambuc // the token to end in a semicolon (in which case SemiError should be set), 170*f4a2713aSLionel Sambuc // or they directly 'return;' if not. 171*f4a2713aSLionel Sambuc Retry: 172*f4a2713aSLionel Sambuc tok::TokenKind Kind = Tok.getKind(); 173*f4a2713aSLionel Sambuc SourceLocation AtLoc; 174*f4a2713aSLionel Sambuc switch (Kind) { 175*f4a2713aSLionel Sambuc case tok::at: // May be a @try or @throw statement 176*f4a2713aSLionel Sambuc { 177*f4a2713aSLionel Sambuc ProhibitAttributes(Attrs); // TODO: is it correct? 178*f4a2713aSLionel Sambuc AtLoc = ConsumeToken(); // consume @ 179*f4a2713aSLionel Sambuc return ParseObjCAtStatement(AtLoc); 180*f4a2713aSLionel Sambuc } 181*f4a2713aSLionel Sambuc 182*f4a2713aSLionel Sambuc case tok::code_completion: 183*f4a2713aSLionel Sambuc Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Statement); 184*f4a2713aSLionel Sambuc cutOffParsing(); 185*f4a2713aSLionel Sambuc return StmtError(); 186*f4a2713aSLionel Sambuc 187*f4a2713aSLionel Sambuc case tok::identifier: { 188*f4a2713aSLionel Sambuc Token Next = NextToken(); 189*f4a2713aSLionel Sambuc if (Next.is(tok::colon)) { // C99 6.8.1: labeled-statement 190*f4a2713aSLionel Sambuc // identifier ':' statement 191*f4a2713aSLionel Sambuc return ParseLabeledStatement(Attrs); 192*f4a2713aSLionel Sambuc } 193*f4a2713aSLionel Sambuc 194*f4a2713aSLionel Sambuc // Look up the identifier, and typo-correct it to a keyword if it's not 195*f4a2713aSLionel Sambuc // found. 196*f4a2713aSLionel Sambuc if (Next.isNot(tok::coloncolon)) { 197*f4a2713aSLionel Sambuc // Try to limit which sets of keywords should be included in typo 198*f4a2713aSLionel Sambuc // correction based on what the next token is. 199*f4a2713aSLionel Sambuc StatementFilterCCC Validator(Next); 200*f4a2713aSLionel Sambuc if (TryAnnotateName(/*IsAddressOfOperand*/false, &Validator) 201*f4a2713aSLionel Sambuc == ANK_Error) { 202*f4a2713aSLionel Sambuc // Handle errors here by skipping up to the next semicolon or '}', and 203*f4a2713aSLionel Sambuc // eat the semicolon if that's what stopped us. 204*f4a2713aSLionel Sambuc SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); 205*f4a2713aSLionel Sambuc if (Tok.is(tok::semi)) 206*f4a2713aSLionel Sambuc ConsumeToken(); 207*f4a2713aSLionel Sambuc return StmtError(); 208*f4a2713aSLionel Sambuc } 209*f4a2713aSLionel Sambuc 210*f4a2713aSLionel Sambuc // If the identifier was typo-corrected, try again. 211*f4a2713aSLionel Sambuc if (Tok.isNot(tok::identifier)) 212*f4a2713aSLionel Sambuc goto Retry; 213*f4a2713aSLionel Sambuc } 214*f4a2713aSLionel Sambuc 215*f4a2713aSLionel Sambuc // Fall through 216*f4a2713aSLionel Sambuc } 217*f4a2713aSLionel Sambuc 218*f4a2713aSLionel Sambuc default: { 219*f4a2713aSLionel Sambuc if ((getLangOpts().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) { 220*f4a2713aSLionel Sambuc SourceLocation DeclStart = Tok.getLocation(), DeclEnd; 221*f4a2713aSLionel Sambuc DeclGroupPtrTy Decl = ParseDeclaration(Stmts, Declarator::BlockContext, 222*f4a2713aSLionel Sambuc DeclEnd, Attrs); 223*f4a2713aSLionel Sambuc return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd); 224*f4a2713aSLionel Sambuc } 225*f4a2713aSLionel Sambuc 226*f4a2713aSLionel Sambuc if (Tok.is(tok::r_brace)) { 227*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_statement); 228*f4a2713aSLionel Sambuc return StmtError(); 229*f4a2713aSLionel Sambuc } 230*f4a2713aSLionel Sambuc 231*f4a2713aSLionel Sambuc return ParseExprStatement(); 232*f4a2713aSLionel Sambuc } 233*f4a2713aSLionel Sambuc 234*f4a2713aSLionel Sambuc case tok::kw_case: // C99 6.8.1: labeled-statement 235*f4a2713aSLionel Sambuc return ParseCaseStatement(); 236*f4a2713aSLionel Sambuc case tok::kw_default: // C99 6.8.1: labeled-statement 237*f4a2713aSLionel Sambuc return ParseDefaultStatement(); 238*f4a2713aSLionel Sambuc 239*f4a2713aSLionel Sambuc case tok::l_brace: // C99 6.8.2: compound-statement 240*f4a2713aSLionel Sambuc return ParseCompoundStatement(); 241*f4a2713aSLionel Sambuc case tok::semi: { // C99 6.8.3p3: expression[opt] ';' 242*f4a2713aSLionel Sambuc bool HasLeadingEmptyMacro = Tok.hasLeadingEmptyMacro(); 243*f4a2713aSLionel Sambuc return Actions.ActOnNullStmt(ConsumeToken(), HasLeadingEmptyMacro); 244*f4a2713aSLionel Sambuc } 245*f4a2713aSLionel Sambuc 246*f4a2713aSLionel Sambuc case tok::kw_if: // C99 6.8.4.1: if-statement 247*f4a2713aSLionel Sambuc return ParseIfStatement(TrailingElseLoc); 248*f4a2713aSLionel Sambuc case tok::kw_switch: // C99 6.8.4.2: switch-statement 249*f4a2713aSLionel Sambuc return ParseSwitchStatement(TrailingElseLoc); 250*f4a2713aSLionel Sambuc 251*f4a2713aSLionel Sambuc case tok::kw_while: // C99 6.8.5.1: while-statement 252*f4a2713aSLionel Sambuc return ParseWhileStatement(TrailingElseLoc); 253*f4a2713aSLionel Sambuc case tok::kw_do: // C99 6.8.5.2: do-statement 254*f4a2713aSLionel Sambuc Res = ParseDoStatement(); 255*f4a2713aSLionel Sambuc SemiError = "do/while"; 256*f4a2713aSLionel Sambuc break; 257*f4a2713aSLionel Sambuc case tok::kw_for: // C99 6.8.5.3: for-statement 258*f4a2713aSLionel Sambuc return ParseForStatement(TrailingElseLoc); 259*f4a2713aSLionel Sambuc 260*f4a2713aSLionel Sambuc case tok::kw_goto: // C99 6.8.6.1: goto-statement 261*f4a2713aSLionel Sambuc Res = ParseGotoStatement(); 262*f4a2713aSLionel Sambuc SemiError = "goto"; 263*f4a2713aSLionel Sambuc break; 264*f4a2713aSLionel Sambuc case tok::kw_continue: // C99 6.8.6.2: continue-statement 265*f4a2713aSLionel Sambuc Res = ParseContinueStatement(); 266*f4a2713aSLionel Sambuc SemiError = "continue"; 267*f4a2713aSLionel Sambuc break; 268*f4a2713aSLionel Sambuc case tok::kw_break: // C99 6.8.6.3: break-statement 269*f4a2713aSLionel Sambuc Res = ParseBreakStatement(); 270*f4a2713aSLionel Sambuc SemiError = "break"; 271*f4a2713aSLionel Sambuc break; 272*f4a2713aSLionel Sambuc case tok::kw_return: // C99 6.8.6.4: return-statement 273*f4a2713aSLionel Sambuc Res = ParseReturnStatement(); 274*f4a2713aSLionel Sambuc SemiError = "return"; 275*f4a2713aSLionel Sambuc break; 276*f4a2713aSLionel Sambuc 277*f4a2713aSLionel Sambuc case tok::kw_asm: { 278*f4a2713aSLionel Sambuc ProhibitAttributes(Attrs); 279*f4a2713aSLionel Sambuc bool msAsm = false; 280*f4a2713aSLionel Sambuc Res = ParseAsmStatement(msAsm); 281*f4a2713aSLionel Sambuc Res = Actions.ActOnFinishFullStmt(Res.get()); 282*f4a2713aSLionel Sambuc if (msAsm) return Res; 283*f4a2713aSLionel Sambuc SemiError = "asm"; 284*f4a2713aSLionel Sambuc break; 285*f4a2713aSLionel Sambuc } 286*f4a2713aSLionel Sambuc 287*f4a2713aSLionel Sambuc case tok::kw_try: // C++ 15: try-block 288*f4a2713aSLionel Sambuc return ParseCXXTryBlock(); 289*f4a2713aSLionel Sambuc 290*f4a2713aSLionel Sambuc case tok::kw___try: 291*f4a2713aSLionel Sambuc ProhibitAttributes(Attrs); // TODO: is it correct? 292*f4a2713aSLionel Sambuc return ParseSEHTryBlock(); 293*f4a2713aSLionel Sambuc 294*f4a2713aSLionel Sambuc case tok::annot_pragma_vis: 295*f4a2713aSLionel Sambuc ProhibitAttributes(Attrs); 296*f4a2713aSLionel Sambuc HandlePragmaVisibility(); 297*f4a2713aSLionel Sambuc return StmtEmpty(); 298*f4a2713aSLionel Sambuc 299*f4a2713aSLionel Sambuc case tok::annot_pragma_pack: 300*f4a2713aSLionel Sambuc ProhibitAttributes(Attrs); 301*f4a2713aSLionel Sambuc HandlePragmaPack(); 302*f4a2713aSLionel Sambuc return StmtEmpty(); 303*f4a2713aSLionel Sambuc 304*f4a2713aSLionel Sambuc case tok::annot_pragma_msstruct: 305*f4a2713aSLionel Sambuc ProhibitAttributes(Attrs); 306*f4a2713aSLionel Sambuc HandlePragmaMSStruct(); 307*f4a2713aSLionel Sambuc return StmtEmpty(); 308*f4a2713aSLionel Sambuc 309*f4a2713aSLionel Sambuc case tok::annot_pragma_align: 310*f4a2713aSLionel Sambuc ProhibitAttributes(Attrs); 311*f4a2713aSLionel Sambuc HandlePragmaAlign(); 312*f4a2713aSLionel Sambuc return StmtEmpty(); 313*f4a2713aSLionel Sambuc 314*f4a2713aSLionel Sambuc case tok::annot_pragma_weak: 315*f4a2713aSLionel Sambuc ProhibitAttributes(Attrs); 316*f4a2713aSLionel Sambuc HandlePragmaWeak(); 317*f4a2713aSLionel Sambuc return StmtEmpty(); 318*f4a2713aSLionel Sambuc 319*f4a2713aSLionel Sambuc case tok::annot_pragma_weakalias: 320*f4a2713aSLionel Sambuc ProhibitAttributes(Attrs); 321*f4a2713aSLionel Sambuc HandlePragmaWeakAlias(); 322*f4a2713aSLionel Sambuc return StmtEmpty(); 323*f4a2713aSLionel Sambuc 324*f4a2713aSLionel Sambuc case tok::annot_pragma_redefine_extname: 325*f4a2713aSLionel Sambuc ProhibitAttributes(Attrs); 326*f4a2713aSLionel Sambuc HandlePragmaRedefineExtname(); 327*f4a2713aSLionel Sambuc return StmtEmpty(); 328*f4a2713aSLionel Sambuc 329*f4a2713aSLionel Sambuc case tok::annot_pragma_fp_contract: 330*f4a2713aSLionel Sambuc ProhibitAttributes(Attrs); 331*f4a2713aSLionel Sambuc Diag(Tok, diag::err_pragma_fp_contract_scope); 332*f4a2713aSLionel Sambuc ConsumeToken(); 333*f4a2713aSLionel Sambuc return StmtError(); 334*f4a2713aSLionel Sambuc 335*f4a2713aSLionel Sambuc case tok::annot_pragma_opencl_extension: 336*f4a2713aSLionel Sambuc ProhibitAttributes(Attrs); 337*f4a2713aSLionel Sambuc HandlePragmaOpenCLExtension(); 338*f4a2713aSLionel Sambuc return StmtEmpty(); 339*f4a2713aSLionel Sambuc 340*f4a2713aSLionel Sambuc case tok::annot_pragma_captured: 341*f4a2713aSLionel Sambuc ProhibitAttributes(Attrs); 342*f4a2713aSLionel Sambuc return HandlePragmaCaptured(); 343*f4a2713aSLionel Sambuc 344*f4a2713aSLionel Sambuc case tok::annot_pragma_openmp: 345*f4a2713aSLionel Sambuc ProhibitAttributes(Attrs); 346*f4a2713aSLionel Sambuc return ParseOpenMPDeclarativeOrExecutableDirective(); 347*f4a2713aSLionel Sambuc 348*f4a2713aSLionel Sambuc } 349*f4a2713aSLionel Sambuc 350*f4a2713aSLionel Sambuc // If we reached this code, the statement must end in a semicolon. 351*f4a2713aSLionel Sambuc if (Tok.is(tok::semi)) { 352*f4a2713aSLionel Sambuc ConsumeToken(); 353*f4a2713aSLionel Sambuc } else if (!Res.isInvalid()) { 354*f4a2713aSLionel Sambuc // If the result was valid, then we do want to diagnose this. Use 355*f4a2713aSLionel Sambuc // ExpectAndConsume to emit the diagnostic, even though we know it won't 356*f4a2713aSLionel Sambuc // succeed. 357*f4a2713aSLionel Sambuc ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt, SemiError); 358*f4a2713aSLionel Sambuc // Skip until we see a } or ;, but don't eat it. 359*f4a2713aSLionel Sambuc SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); 360*f4a2713aSLionel Sambuc } 361*f4a2713aSLionel Sambuc 362*f4a2713aSLionel Sambuc return Res; 363*f4a2713aSLionel Sambuc } 364*f4a2713aSLionel Sambuc 365*f4a2713aSLionel Sambuc /// \brief Parse an expression statement. 366*f4a2713aSLionel Sambuc StmtResult Parser::ParseExprStatement() { 367*f4a2713aSLionel Sambuc // If a case keyword is missing, this is where it should be inserted. 368*f4a2713aSLionel Sambuc Token OldToken = Tok; 369*f4a2713aSLionel Sambuc 370*f4a2713aSLionel Sambuc // expression[opt] ';' 371*f4a2713aSLionel Sambuc ExprResult Expr(ParseExpression()); 372*f4a2713aSLionel Sambuc if (Expr.isInvalid()) { 373*f4a2713aSLionel Sambuc // If the expression is invalid, skip ahead to the next semicolon or '}'. 374*f4a2713aSLionel Sambuc // Not doing this opens us up to the possibility of infinite loops if 375*f4a2713aSLionel Sambuc // ParseExpression does not consume any tokens. 376*f4a2713aSLionel Sambuc SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); 377*f4a2713aSLionel Sambuc if (Tok.is(tok::semi)) 378*f4a2713aSLionel Sambuc ConsumeToken(); 379*f4a2713aSLionel Sambuc return Actions.ActOnExprStmtError(); 380*f4a2713aSLionel Sambuc } 381*f4a2713aSLionel Sambuc 382*f4a2713aSLionel Sambuc if (Tok.is(tok::colon) && getCurScope()->isSwitchScope() && 383*f4a2713aSLionel Sambuc Actions.CheckCaseExpression(Expr.get())) { 384*f4a2713aSLionel Sambuc // If a constant expression is followed by a colon inside a switch block, 385*f4a2713aSLionel Sambuc // suggest a missing case keyword. 386*f4a2713aSLionel Sambuc Diag(OldToken, diag::err_expected_case_before_expression) 387*f4a2713aSLionel Sambuc << FixItHint::CreateInsertion(OldToken.getLocation(), "case "); 388*f4a2713aSLionel Sambuc 389*f4a2713aSLionel Sambuc // Recover parsing as a case statement. 390*f4a2713aSLionel Sambuc return ParseCaseStatement(/*MissingCase=*/true, Expr); 391*f4a2713aSLionel Sambuc } 392*f4a2713aSLionel Sambuc 393*f4a2713aSLionel Sambuc // Otherwise, eat the semicolon. 394*f4a2713aSLionel Sambuc ExpectAndConsumeSemi(diag::err_expected_semi_after_expr); 395*f4a2713aSLionel Sambuc return Actions.ActOnExprStmt(Expr); 396*f4a2713aSLionel Sambuc } 397*f4a2713aSLionel Sambuc 398*f4a2713aSLionel Sambuc StmtResult Parser::ParseSEHTryBlock() { 399*f4a2713aSLionel Sambuc assert(Tok.is(tok::kw___try) && "Expected '__try'"); 400*f4a2713aSLionel Sambuc SourceLocation Loc = ConsumeToken(); 401*f4a2713aSLionel Sambuc return ParseSEHTryBlockCommon(Loc); 402*f4a2713aSLionel Sambuc } 403*f4a2713aSLionel Sambuc 404*f4a2713aSLionel Sambuc /// ParseSEHTryBlockCommon 405*f4a2713aSLionel Sambuc /// 406*f4a2713aSLionel Sambuc /// seh-try-block: 407*f4a2713aSLionel Sambuc /// '__try' compound-statement seh-handler 408*f4a2713aSLionel Sambuc /// 409*f4a2713aSLionel Sambuc /// seh-handler: 410*f4a2713aSLionel Sambuc /// seh-except-block 411*f4a2713aSLionel Sambuc /// seh-finally-block 412*f4a2713aSLionel Sambuc /// 413*f4a2713aSLionel Sambuc StmtResult Parser::ParseSEHTryBlockCommon(SourceLocation TryLoc) { 414*f4a2713aSLionel Sambuc if(Tok.isNot(tok::l_brace)) 415*f4a2713aSLionel Sambuc return StmtError(Diag(Tok,diag::err_expected_lbrace)); 416*f4a2713aSLionel Sambuc 417*f4a2713aSLionel Sambuc StmtResult TryBlock(ParseCompoundStatement()); 418*f4a2713aSLionel Sambuc if(TryBlock.isInvalid()) 419*f4a2713aSLionel Sambuc return TryBlock; 420*f4a2713aSLionel Sambuc 421*f4a2713aSLionel Sambuc StmtResult Handler; 422*f4a2713aSLionel Sambuc if (Tok.is(tok::identifier) && 423*f4a2713aSLionel Sambuc Tok.getIdentifierInfo() == getSEHExceptKeyword()) { 424*f4a2713aSLionel Sambuc SourceLocation Loc = ConsumeToken(); 425*f4a2713aSLionel Sambuc Handler = ParseSEHExceptBlock(Loc); 426*f4a2713aSLionel Sambuc } else if (Tok.is(tok::kw___finally)) { 427*f4a2713aSLionel Sambuc SourceLocation Loc = ConsumeToken(); 428*f4a2713aSLionel Sambuc Handler = ParseSEHFinallyBlock(Loc); 429*f4a2713aSLionel Sambuc } else { 430*f4a2713aSLionel Sambuc return StmtError(Diag(Tok,diag::err_seh_expected_handler)); 431*f4a2713aSLionel Sambuc } 432*f4a2713aSLionel Sambuc 433*f4a2713aSLionel Sambuc if(Handler.isInvalid()) 434*f4a2713aSLionel Sambuc return Handler; 435*f4a2713aSLionel Sambuc 436*f4a2713aSLionel Sambuc return Actions.ActOnSEHTryBlock(false /* IsCXXTry */, 437*f4a2713aSLionel Sambuc TryLoc, 438*f4a2713aSLionel Sambuc TryBlock.take(), 439*f4a2713aSLionel Sambuc Handler.take()); 440*f4a2713aSLionel Sambuc } 441*f4a2713aSLionel Sambuc 442*f4a2713aSLionel Sambuc /// ParseSEHExceptBlock - Handle __except 443*f4a2713aSLionel Sambuc /// 444*f4a2713aSLionel Sambuc /// seh-except-block: 445*f4a2713aSLionel Sambuc /// '__except' '(' seh-filter-expression ')' compound-statement 446*f4a2713aSLionel Sambuc /// 447*f4a2713aSLionel Sambuc StmtResult Parser::ParseSEHExceptBlock(SourceLocation ExceptLoc) { 448*f4a2713aSLionel Sambuc PoisonIdentifierRAIIObject raii(Ident__exception_code, false), 449*f4a2713aSLionel Sambuc raii2(Ident___exception_code, false), 450*f4a2713aSLionel Sambuc raii3(Ident_GetExceptionCode, false); 451*f4a2713aSLionel Sambuc 452*f4a2713aSLionel Sambuc if(ExpectAndConsume(tok::l_paren,diag::err_expected_lparen)) 453*f4a2713aSLionel Sambuc return StmtError(); 454*f4a2713aSLionel Sambuc 455*f4a2713aSLionel Sambuc ParseScope ExpectScope(this, Scope::DeclScope | Scope::ControlScope); 456*f4a2713aSLionel Sambuc 457*f4a2713aSLionel Sambuc if (getLangOpts().Borland) { 458*f4a2713aSLionel Sambuc Ident__exception_info->setIsPoisoned(false); 459*f4a2713aSLionel Sambuc Ident___exception_info->setIsPoisoned(false); 460*f4a2713aSLionel Sambuc Ident_GetExceptionInfo->setIsPoisoned(false); 461*f4a2713aSLionel Sambuc } 462*f4a2713aSLionel Sambuc ExprResult FilterExpr(ParseExpression()); 463*f4a2713aSLionel Sambuc 464*f4a2713aSLionel Sambuc if (getLangOpts().Borland) { 465*f4a2713aSLionel Sambuc Ident__exception_info->setIsPoisoned(true); 466*f4a2713aSLionel Sambuc Ident___exception_info->setIsPoisoned(true); 467*f4a2713aSLionel Sambuc Ident_GetExceptionInfo->setIsPoisoned(true); 468*f4a2713aSLionel Sambuc } 469*f4a2713aSLionel Sambuc 470*f4a2713aSLionel Sambuc if(FilterExpr.isInvalid()) 471*f4a2713aSLionel Sambuc return StmtError(); 472*f4a2713aSLionel Sambuc 473*f4a2713aSLionel Sambuc if(ExpectAndConsume(tok::r_paren,diag::err_expected_rparen)) 474*f4a2713aSLionel Sambuc return StmtError(); 475*f4a2713aSLionel Sambuc 476*f4a2713aSLionel Sambuc StmtResult Block(ParseCompoundStatement()); 477*f4a2713aSLionel Sambuc 478*f4a2713aSLionel Sambuc if(Block.isInvalid()) 479*f4a2713aSLionel Sambuc return Block; 480*f4a2713aSLionel Sambuc 481*f4a2713aSLionel Sambuc return Actions.ActOnSEHExceptBlock(ExceptLoc, FilterExpr.take(), Block.take()); 482*f4a2713aSLionel Sambuc } 483*f4a2713aSLionel Sambuc 484*f4a2713aSLionel Sambuc /// ParseSEHFinallyBlock - Handle __finally 485*f4a2713aSLionel Sambuc /// 486*f4a2713aSLionel Sambuc /// seh-finally-block: 487*f4a2713aSLionel Sambuc /// '__finally' compound-statement 488*f4a2713aSLionel Sambuc /// 489*f4a2713aSLionel Sambuc StmtResult Parser::ParseSEHFinallyBlock(SourceLocation FinallyBlock) { 490*f4a2713aSLionel Sambuc PoisonIdentifierRAIIObject raii(Ident__abnormal_termination, false), 491*f4a2713aSLionel Sambuc raii2(Ident___abnormal_termination, false), 492*f4a2713aSLionel Sambuc raii3(Ident_AbnormalTermination, false); 493*f4a2713aSLionel Sambuc 494*f4a2713aSLionel Sambuc StmtResult Block(ParseCompoundStatement()); 495*f4a2713aSLionel Sambuc if(Block.isInvalid()) 496*f4a2713aSLionel Sambuc return Block; 497*f4a2713aSLionel Sambuc 498*f4a2713aSLionel Sambuc return Actions.ActOnSEHFinallyBlock(FinallyBlock,Block.take()); 499*f4a2713aSLionel Sambuc } 500*f4a2713aSLionel Sambuc 501*f4a2713aSLionel Sambuc /// ParseLabeledStatement - We have an identifier and a ':' after it. 502*f4a2713aSLionel Sambuc /// 503*f4a2713aSLionel Sambuc /// labeled-statement: 504*f4a2713aSLionel Sambuc /// identifier ':' statement 505*f4a2713aSLionel Sambuc /// [GNU] identifier ':' attributes[opt] statement 506*f4a2713aSLionel Sambuc /// 507*f4a2713aSLionel Sambuc StmtResult Parser::ParseLabeledStatement(ParsedAttributesWithRange &attrs) { 508*f4a2713aSLionel Sambuc assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() && 509*f4a2713aSLionel Sambuc "Not an identifier!"); 510*f4a2713aSLionel Sambuc 511*f4a2713aSLionel Sambuc Token IdentTok = Tok; // Save the whole token. 512*f4a2713aSLionel Sambuc ConsumeToken(); // eat the identifier. 513*f4a2713aSLionel Sambuc 514*f4a2713aSLionel Sambuc assert(Tok.is(tok::colon) && "Not a label!"); 515*f4a2713aSLionel Sambuc 516*f4a2713aSLionel Sambuc // identifier ':' statement 517*f4a2713aSLionel Sambuc SourceLocation ColonLoc = ConsumeToken(); 518*f4a2713aSLionel Sambuc 519*f4a2713aSLionel Sambuc // Read label attributes, if present. 520*f4a2713aSLionel Sambuc StmtResult SubStmt; 521*f4a2713aSLionel Sambuc if (Tok.is(tok::kw___attribute)) { 522*f4a2713aSLionel Sambuc ParsedAttributesWithRange TempAttrs(AttrFactory); 523*f4a2713aSLionel Sambuc ParseGNUAttributes(TempAttrs); 524*f4a2713aSLionel Sambuc 525*f4a2713aSLionel Sambuc // In C++, GNU attributes only apply to the label if they are followed by a 526*f4a2713aSLionel Sambuc // semicolon, to disambiguate label attributes from attributes on a labeled 527*f4a2713aSLionel Sambuc // declaration. 528*f4a2713aSLionel Sambuc // 529*f4a2713aSLionel Sambuc // This doesn't quite match what GCC does; if the attribute list is empty 530*f4a2713aSLionel Sambuc // and followed by a semicolon, GCC will reject (it appears to parse the 531*f4a2713aSLionel Sambuc // attributes as part of a statement in that case). That looks like a bug. 532*f4a2713aSLionel Sambuc if (!getLangOpts().CPlusPlus || Tok.is(tok::semi)) 533*f4a2713aSLionel Sambuc attrs.takeAllFrom(TempAttrs); 534*f4a2713aSLionel Sambuc else if (isDeclarationStatement()) { 535*f4a2713aSLionel Sambuc StmtVector Stmts; 536*f4a2713aSLionel Sambuc // FIXME: We should do this whether or not we have a declaration 537*f4a2713aSLionel Sambuc // statement, but that doesn't work correctly (because ProhibitAttributes 538*f4a2713aSLionel Sambuc // can't handle GNU attributes), so only call it in the one case where 539*f4a2713aSLionel Sambuc // GNU attributes are allowed. 540*f4a2713aSLionel Sambuc SubStmt = ParseStatementOrDeclarationAfterAttributes( 541*f4a2713aSLionel Sambuc Stmts, /*OnlyStmts*/ true, 0, TempAttrs); 542*f4a2713aSLionel Sambuc if (!TempAttrs.empty() && !SubStmt.isInvalid()) 543*f4a2713aSLionel Sambuc SubStmt = Actions.ProcessStmtAttributes( 544*f4a2713aSLionel Sambuc SubStmt.get(), TempAttrs.getList(), TempAttrs.Range); 545*f4a2713aSLionel Sambuc } else { 546*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_semi_after) << "__attribute__"; 547*f4a2713aSLionel Sambuc } 548*f4a2713aSLionel Sambuc } 549*f4a2713aSLionel Sambuc 550*f4a2713aSLionel Sambuc // If we've not parsed a statement yet, parse one now. 551*f4a2713aSLionel Sambuc if (!SubStmt.isInvalid() && !SubStmt.isUsable()) 552*f4a2713aSLionel Sambuc SubStmt = ParseStatement(); 553*f4a2713aSLionel Sambuc 554*f4a2713aSLionel Sambuc // Broken substmt shouldn't prevent the label from being added to the AST. 555*f4a2713aSLionel Sambuc if (SubStmt.isInvalid()) 556*f4a2713aSLionel Sambuc SubStmt = Actions.ActOnNullStmt(ColonLoc); 557*f4a2713aSLionel Sambuc 558*f4a2713aSLionel Sambuc LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(), 559*f4a2713aSLionel Sambuc IdentTok.getLocation()); 560*f4a2713aSLionel Sambuc if (AttributeList *Attrs = attrs.getList()) { 561*f4a2713aSLionel Sambuc Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs); 562*f4a2713aSLionel Sambuc attrs.clear(); 563*f4a2713aSLionel Sambuc } 564*f4a2713aSLionel Sambuc 565*f4a2713aSLionel Sambuc return Actions.ActOnLabelStmt(IdentTok.getLocation(), LD, ColonLoc, 566*f4a2713aSLionel Sambuc SubStmt.get()); 567*f4a2713aSLionel Sambuc } 568*f4a2713aSLionel Sambuc 569*f4a2713aSLionel Sambuc /// ParseCaseStatement 570*f4a2713aSLionel Sambuc /// labeled-statement: 571*f4a2713aSLionel Sambuc /// 'case' constant-expression ':' statement 572*f4a2713aSLionel Sambuc /// [GNU] 'case' constant-expression '...' constant-expression ':' statement 573*f4a2713aSLionel Sambuc /// 574*f4a2713aSLionel Sambuc StmtResult Parser::ParseCaseStatement(bool MissingCase, ExprResult Expr) { 575*f4a2713aSLionel Sambuc assert((MissingCase || Tok.is(tok::kw_case)) && "Not a case stmt!"); 576*f4a2713aSLionel Sambuc 577*f4a2713aSLionel Sambuc // It is very very common for code to contain many case statements recursively 578*f4a2713aSLionel Sambuc // nested, as in (but usually without indentation): 579*f4a2713aSLionel Sambuc // case 1: 580*f4a2713aSLionel Sambuc // case 2: 581*f4a2713aSLionel Sambuc // case 3: 582*f4a2713aSLionel Sambuc // case 4: 583*f4a2713aSLionel Sambuc // case 5: etc. 584*f4a2713aSLionel Sambuc // 585*f4a2713aSLionel Sambuc // Parsing this naively works, but is both inefficient and can cause us to run 586*f4a2713aSLionel Sambuc // out of stack space in our recursive descent parser. As a special case, 587*f4a2713aSLionel Sambuc // flatten this recursion into an iterative loop. This is complex and gross, 588*f4a2713aSLionel Sambuc // but all the grossness is constrained to ParseCaseStatement (and some 589*f4a2713aSLionel Sambuc // weirdness in the actions), so this is just local grossness :). 590*f4a2713aSLionel Sambuc 591*f4a2713aSLionel Sambuc // TopLevelCase - This is the highest level we have parsed. 'case 1' in the 592*f4a2713aSLionel Sambuc // example above. 593*f4a2713aSLionel Sambuc StmtResult TopLevelCase(true); 594*f4a2713aSLionel Sambuc 595*f4a2713aSLionel Sambuc // DeepestParsedCaseStmt - This is the deepest statement we have parsed, which 596*f4a2713aSLionel Sambuc // gets updated each time a new case is parsed, and whose body is unset so 597*f4a2713aSLionel Sambuc // far. When parsing 'case 4', this is the 'case 3' node. 598*f4a2713aSLionel Sambuc Stmt *DeepestParsedCaseStmt = 0; 599*f4a2713aSLionel Sambuc 600*f4a2713aSLionel Sambuc // While we have case statements, eat and stack them. 601*f4a2713aSLionel Sambuc SourceLocation ColonLoc; 602*f4a2713aSLionel Sambuc do { 603*f4a2713aSLionel Sambuc SourceLocation CaseLoc = MissingCase ? Expr.get()->getExprLoc() : 604*f4a2713aSLionel Sambuc ConsumeToken(); // eat the 'case'. 605*f4a2713aSLionel Sambuc 606*f4a2713aSLionel Sambuc if (Tok.is(tok::code_completion)) { 607*f4a2713aSLionel Sambuc Actions.CodeCompleteCase(getCurScope()); 608*f4a2713aSLionel Sambuc cutOffParsing(); 609*f4a2713aSLionel Sambuc return StmtError(); 610*f4a2713aSLionel Sambuc } 611*f4a2713aSLionel Sambuc 612*f4a2713aSLionel Sambuc /// We don't want to treat 'case x : y' as a potential typo for 'case x::y'. 613*f4a2713aSLionel Sambuc /// Disable this form of error recovery while we're parsing the case 614*f4a2713aSLionel Sambuc /// expression. 615*f4a2713aSLionel Sambuc ColonProtectionRAIIObject ColonProtection(*this); 616*f4a2713aSLionel Sambuc 617*f4a2713aSLionel Sambuc ExprResult LHS(MissingCase ? Expr : ParseConstantExpression()); 618*f4a2713aSLionel Sambuc MissingCase = false; 619*f4a2713aSLionel Sambuc if (LHS.isInvalid()) { 620*f4a2713aSLionel Sambuc SkipUntil(tok::colon, StopAtSemi); 621*f4a2713aSLionel Sambuc return StmtError(); 622*f4a2713aSLionel Sambuc } 623*f4a2713aSLionel Sambuc 624*f4a2713aSLionel Sambuc // GNU case range extension. 625*f4a2713aSLionel Sambuc SourceLocation DotDotDotLoc; 626*f4a2713aSLionel Sambuc ExprResult RHS; 627*f4a2713aSLionel Sambuc if (Tok.is(tok::ellipsis)) { 628*f4a2713aSLionel Sambuc Diag(Tok, diag::ext_gnu_case_range); 629*f4a2713aSLionel Sambuc DotDotDotLoc = ConsumeToken(); 630*f4a2713aSLionel Sambuc 631*f4a2713aSLionel Sambuc RHS = ParseConstantExpression(); 632*f4a2713aSLionel Sambuc if (RHS.isInvalid()) { 633*f4a2713aSLionel Sambuc SkipUntil(tok::colon, StopAtSemi); 634*f4a2713aSLionel Sambuc return StmtError(); 635*f4a2713aSLionel Sambuc } 636*f4a2713aSLionel Sambuc } 637*f4a2713aSLionel Sambuc 638*f4a2713aSLionel Sambuc ColonProtection.restore(); 639*f4a2713aSLionel Sambuc 640*f4a2713aSLionel Sambuc if (Tok.is(tok::colon)) { 641*f4a2713aSLionel Sambuc ColonLoc = ConsumeToken(); 642*f4a2713aSLionel Sambuc 643*f4a2713aSLionel Sambuc // Treat "case blah;" as a typo for "case blah:". 644*f4a2713aSLionel Sambuc } else if (Tok.is(tok::semi)) { 645*f4a2713aSLionel Sambuc ColonLoc = ConsumeToken(); 646*f4a2713aSLionel Sambuc Diag(ColonLoc, diag::err_expected_colon_after) << "'case'" 647*f4a2713aSLionel Sambuc << FixItHint::CreateReplacement(ColonLoc, ":"); 648*f4a2713aSLionel Sambuc } else { 649*f4a2713aSLionel Sambuc SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation); 650*f4a2713aSLionel Sambuc Diag(ExpectedLoc, diag::err_expected_colon_after) << "'case'" 651*f4a2713aSLionel Sambuc << FixItHint::CreateInsertion(ExpectedLoc, ":"); 652*f4a2713aSLionel Sambuc ColonLoc = ExpectedLoc; 653*f4a2713aSLionel Sambuc } 654*f4a2713aSLionel Sambuc 655*f4a2713aSLionel Sambuc StmtResult Case = 656*f4a2713aSLionel Sambuc Actions.ActOnCaseStmt(CaseLoc, LHS.get(), DotDotDotLoc, 657*f4a2713aSLionel Sambuc RHS.get(), ColonLoc); 658*f4a2713aSLionel Sambuc 659*f4a2713aSLionel Sambuc // If we had a sema error parsing this case, then just ignore it and 660*f4a2713aSLionel Sambuc // continue parsing the sub-stmt. 661*f4a2713aSLionel Sambuc if (Case.isInvalid()) { 662*f4a2713aSLionel Sambuc if (TopLevelCase.isInvalid()) // No parsed case stmts. 663*f4a2713aSLionel Sambuc return ParseStatement(); 664*f4a2713aSLionel Sambuc // Otherwise, just don't add it as a nested case. 665*f4a2713aSLionel Sambuc } else { 666*f4a2713aSLionel Sambuc // If this is the first case statement we parsed, it becomes TopLevelCase. 667*f4a2713aSLionel Sambuc // Otherwise we link it into the current chain. 668*f4a2713aSLionel Sambuc Stmt *NextDeepest = Case.get(); 669*f4a2713aSLionel Sambuc if (TopLevelCase.isInvalid()) 670*f4a2713aSLionel Sambuc TopLevelCase = Case; 671*f4a2713aSLionel Sambuc else 672*f4a2713aSLionel Sambuc Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, Case.get()); 673*f4a2713aSLionel Sambuc DeepestParsedCaseStmt = NextDeepest; 674*f4a2713aSLionel Sambuc } 675*f4a2713aSLionel Sambuc 676*f4a2713aSLionel Sambuc // Handle all case statements. 677*f4a2713aSLionel Sambuc } while (Tok.is(tok::kw_case)); 678*f4a2713aSLionel Sambuc 679*f4a2713aSLionel Sambuc assert(!TopLevelCase.isInvalid() && "Should have parsed at least one case!"); 680*f4a2713aSLionel Sambuc 681*f4a2713aSLionel Sambuc // If we found a non-case statement, start by parsing it. 682*f4a2713aSLionel Sambuc StmtResult SubStmt; 683*f4a2713aSLionel Sambuc 684*f4a2713aSLionel Sambuc if (Tok.isNot(tok::r_brace)) { 685*f4a2713aSLionel Sambuc SubStmt = ParseStatement(); 686*f4a2713aSLionel Sambuc } else { 687*f4a2713aSLionel Sambuc // Nicely diagnose the common error "switch (X) { case 4: }", which is 688*f4a2713aSLionel Sambuc // not valid. 689*f4a2713aSLionel Sambuc SourceLocation AfterColonLoc = PP.getLocForEndOfToken(ColonLoc); 690*f4a2713aSLionel Sambuc Diag(AfterColonLoc, diag::err_label_end_of_compound_statement) 691*f4a2713aSLionel Sambuc << FixItHint::CreateInsertion(AfterColonLoc, " ;"); 692*f4a2713aSLionel Sambuc SubStmt = true; 693*f4a2713aSLionel Sambuc } 694*f4a2713aSLionel Sambuc 695*f4a2713aSLionel Sambuc // Broken sub-stmt shouldn't prevent forming the case statement properly. 696*f4a2713aSLionel Sambuc if (SubStmt.isInvalid()) 697*f4a2713aSLionel Sambuc SubStmt = Actions.ActOnNullStmt(SourceLocation()); 698*f4a2713aSLionel Sambuc 699*f4a2713aSLionel Sambuc // Install the body into the most deeply-nested case. 700*f4a2713aSLionel Sambuc Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, SubStmt.get()); 701*f4a2713aSLionel Sambuc 702*f4a2713aSLionel Sambuc // Return the top level parsed statement tree. 703*f4a2713aSLionel Sambuc return TopLevelCase; 704*f4a2713aSLionel Sambuc } 705*f4a2713aSLionel Sambuc 706*f4a2713aSLionel Sambuc /// ParseDefaultStatement 707*f4a2713aSLionel Sambuc /// labeled-statement: 708*f4a2713aSLionel Sambuc /// 'default' ':' statement 709*f4a2713aSLionel Sambuc /// Note that this does not parse the 'statement' at the end. 710*f4a2713aSLionel Sambuc /// 711*f4a2713aSLionel Sambuc StmtResult Parser::ParseDefaultStatement() { 712*f4a2713aSLionel Sambuc assert(Tok.is(tok::kw_default) && "Not a default stmt!"); 713*f4a2713aSLionel Sambuc SourceLocation DefaultLoc = ConsumeToken(); // eat the 'default'. 714*f4a2713aSLionel Sambuc 715*f4a2713aSLionel Sambuc SourceLocation ColonLoc; 716*f4a2713aSLionel Sambuc if (Tok.is(tok::colon)) { 717*f4a2713aSLionel Sambuc ColonLoc = ConsumeToken(); 718*f4a2713aSLionel Sambuc 719*f4a2713aSLionel Sambuc // Treat "default;" as a typo for "default:". 720*f4a2713aSLionel Sambuc } else if (Tok.is(tok::semi)) { 721*f4a2713aSLionel Sambuc ColonLoc = ConsumeToken(); 722*f4a2713aSLionel Sambuc Diag(ColonLoc, diag::err_expected_colon_after) << "'default'" 723*f4a2713aSLionel Sambuc << FixItHint::CreateReplacement(ColonLoc, ":"); 724*f4a2713aSLionel Sambuc } else { 725*f4a2713aSLionel Sambuc SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation); 726*f4a2713aSLionel Sambuc Diag(ExpectedLoc, diag::err_expected_colon_after) << "'default'" 727*f4a2713aSLionel Sambuc << FixItHint::CreateInsertion(ExpectedLoc, ":"); 728*f4a2713aSLionel Sambuc ColonLoc = ExpectedLoc; 729*f4a2713aSLionel Sambuc } 730*f4a2713aSLionel Sambuc 731*f4a2713aSLionel Sambuc StmtResult SubStmt; 732*f4a2713aSLionel Sambuc 733*f4a2713aSLionel Sambuc if (Tok.isNot(tok::r_brace)) { 734*f4a2713aSLionel Sambuc SubStmt = ParseStatement(); 735*f4a2713aSLionel Sambuc } else { 736*f4a2713aSLionel Sambuc // Diagnose the common error "switch (X) {... default: }", which is 737*f4a2713aSLionel Sambuc // not valid. 738*f4a2713aSLionel Sambuc SourceLocation AfterColonLoc = PP.getLocForEndOfToken(ColonLoc); 739*f4a2713aSLionel Sambuc Diag(AfterColonLoc, diag::err_label_end_of_compound_statement) 740*f4a2713aSLionel Sambuc << FixItHint::CreateInsertion(AfterColonLoc, " ;"); 741*f4a2713aSLionel Sambuc SubStmt = true; 742*f4a2713aSLionel Sambuc } 743*f4a2713aSLionel Sambuc 744*f4a2713aSLionel Sambuc // Broken sub-stmt shouldn't prevent forming the case statement properly. 745*f4a2713aSLionel Sambuc if (SubStmt.isInvalid()) 746*f4a2713aSLionel Sambuc SubStmt = Actions.ActOnNullStmt(ColonLoc); 747*f4a2713aSLionel Sambuc 748*f4a2713aSLionel Sambuc return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc, 749*f4a2713aSLionel Sambuc SubStmt.get(), getCurScope()); 750*f4a2713aSLionel Sambuc } 751*f4a2713aSLionel Sambuc 752*f4a2713aSLionel Sambuc StmtResult Parser::ParseCompoundStatement(bool isStmtExpr) { 753*f4a2713aSLionel Sambuc return ParseCompoundStatement(isStmtExpr, Scope::DeclScope); 754*f4a2713aSLionel Sambuc } 755*f4a2713aSLionel Sambuc 756*f4a2713aSLionel Sambuc /// ParseCompoundStatement - Parse a "{}" block. 757*f4a2713aSLionel Sambuc /// 758*f4a2713aSLionel Sambuc /// compound-statement: [C99 6.8.2] 759*f4a2713aSLionel Sambuc /// { block-item-list[opt] } 760*f4a2713aSLionel Sambuc /// [GNU] { label-declarations block-item-list } [TODO] 761*f4a2713aSLionel Sambuc /// 762*f4a2713aSLionel Sambuc /// block-item-list: 763*f4a2713aSLionel Sambuc /// block-item 764*f4a2713aSLionel Sambuc /// block-item-list block-item 765*f4a2713aSLionel Sambuc /// 766*f4a2713aSLionel Sambuc /// block-item: 767*f4a2713aSLionel Sambuc /// declaration 768*f4a2713aSLionel Sambuc /// [GNU] '__extension__' declaration 769*f4a2713aSLionel Sambuc /// statement 770*f4a2713aSLionel Sambuc /// [OMP] openmp-directive [TODO] 771*f4a2713aSLionel Sambuc /// 772*f4a2713aSLionel Sambuc /// [GNU] label-declarations: 773*f4a2713aSLionel Sambuc /// [GNU] label-declaration 774*f4a2713aSLionel Sambuc /// [GNU] label-declarations label-declaration 775*f4a2713aSLionel Sambuc /// 776*f4a2713aSLionel Sambuc /// [GNU] label-declaration: 777*f4a2713aSLionel Sambuc /// [GNU] '__label__' identifier-list ';' 778*f4a2713aSLionel Sambuc /// 779*f4a2713aSLionel Sambuc /// [OMP] openmp-directive: [TODO] 780*f4a2713aSLionel Sambuc /// [OMP] barrier-directive 781*f4a2713aSLionel Sambuc /// [OMP] flush-directive 782*f4a2713aSLionel Sambuc /// 783*f4a2713aSLionel Sambuc StmtResult Parser::ParseCompoundStatement(bool isStmtExpr, 784*f4a2713aSLionel Sambuc unsigned ScopeFlags) { 785*f4a2713aSLionel Sambuc assert(Tok.is(tok::l_brace) && "Not a compount stmt!"); 786*f4a2713aSLionel Sambuc 787*f4a2713aSLionel Sambuc // Enter a scope to hold everything within the compound stmt. Compound 788*f4a2713aSLionel Sambuc // statements can always hold declarations. 789*f4a2713aSLionel Sambuc ParseScope CompoundScope(this, ScopeFlags); 790*f4a2713aSLionel Sambuc 791*f4a2713aSLionel Sambuc // Parse the statements in the body. 792*f4a2713aSLionel Sambuc return ParseCompoundStatementBody(isStmtExpr); 793*f4a2713aSLionel Sambuc } 794*f4a2713aSLionel Sambuc 795*f4a2713aSLionel Sambuc /// Parse any pragmas at the start of the compound expression. We handle these 796*f4a2713aSLionel Sambuc /// separately since some pragmas (FP_CONTRACT) must appear before any C 797*f4a2713aSLionel Sambuc /// statement in the compound, but may be intermingled with other pragmas. 798*f4a2713aSLionel Sambuc void Parser::ParseCompoundStatementLeadingPragmas() { 799*f4a2713aSLionel Sambuc bool checkForPragmas = true; 800*f4a2713aSLionel Sambuc while (checkForPragmas) { 801*f4a2713aSLionel Sambuc switch (Tok.getKind()) { 802*f4a2713aSLionel Sambuc case tok::annot_pragma_vis: 803*f4a2713aSLionel Sambuc HandlePragmaVisibility(); 804*f4a2713aSLionel Sambuc break; 805*f4a2713aSLionel Sambuc case tok::annot_pragma_pack: 806*f4a2713aSLionel Sambuc HandlePragmaPack(); 807*f4a2713aSLionel Sambuc break; 808*f4a2713aSLionel Sambuc case tok::annot_pragma_msstruct: 809*f4a2713aSLionel Sambuc HandlePragmaMSStruct(); 810*f4a2713aSLionel Sambuc break; 811*f4a2713aSLionel Sambuc case tok::annot_pragma_align: 812*f4a2713aSLionel Sambuc HandlePragmaAlign(); 813*f4a2713aSLionel Sambuc break; 814*f4a2713aSLionel Sambuc case tok::annot_pragma_weak: 815*f4a2713aSLionel Sambuc HandlePragmaWeak(); 816*f4a2713aSLionel Sambuc break; 817*f4a2713aSLionel Sambuc case tok::annot_pragma_weakalias: 818*f4a2713aSLionel Sambuc HandlePragmaWeakAlias(); 819*f4a2713aSLionel Sambuc break; 820*f4a2713aSLionel Sambuc case tok::annot_pragma_redefine_extname: 821*f4a2713aSLionel Sambuc HandlePragmaRedefineExtname(); 822*f4a2713aSLionel Sambuc break; 823*f4a2713aSLionel Sambuc case tok::annot_pragma_opencl_extension: 824*f4a2713aSLionel Sambuc HandlePragmaOpenCLExtension(); 825*f4a2713aSLionel Sambuc break; 826*f4a2713aSLionel Sambuc case tok::annot_pragma_fp_contract: 827*f4a2713aSLionel Sambuc HandlePragmaFPContract(); 828*f4a2713aSLionel Sambuc break; 829*f4a2713aSLionel Sambuc default: 830*f4a2713aSLionel Sambuc checkForPragmas = false; 831*f4a2713aSLionel Sambuc break; 832*f4a2713aSLionel Sambuc } 833*f4a2713aSLionel Sambuc } 834*f4a2713aSLionel Sambuc 835*f4a2713aSLionel Sambuc } 836*f4a2713aSLionel Sambuc 837*f4a2713aSLionel Sambuc /// ParseCompoundStatementBody - Parse a sequence of statements and invoke the 838*f4a2713aSLionel Sambuc /// ActOnCompoundStmt action. This expects the '{' to be the current token, and 839*f4a2713aSLionel Sambuc /// consume the '}' at the end of the block. It does not manipulate the scope 840*f4a2713aSLionel Sambuc /// stack. 841*f4a2713aSLionel Sambuc StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { 842*f4a2713aSLionel Sambuc PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), 843*f4a2713aSLionel Sambuc Tok.getLocation(), 844*f4a2713aSLionel Sambuc "in compound statement ('{}')"); 845*f4a2713aSLionel Sambuc 846*f4a2713aSLionel Sambuc // Record the state of the FP_CONTRACT pragma, restore on leaving the 847*f4a2713aSLionel Sambuc // compound statement. 848*f4a2713aSLionel Sambuc Sema::FPContractStateRAII SaveFPContractState(Actions); 849*f4a2713aSLionel Sambuc 850*f4a2713aSLionel Sambuc InMessageExpressionRAIIObject InMessage(*this, false); 851*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_brace); 852*f4a2713aSLionel Sambuc if (T.consumeOpen()) 853*f4a2713aSLionel Sambuc return StmtError(); 854*f4a2713aSLionel Sambuc 855*f4a2713aSLionel Sambuc Sema::CompoundScopeRAII CompoundScope(Actions); 856*f4a2713aSLionel Sambuc 857*f4a2713aSLionel Sambuc // Parse any pragmas at the beginning of the compound statement. 858*f4a2713aSLionel Sambuc ParseCompoundStatementLeadingPragmas(); 859*f4a2713aSLionel Sambuc 860*f4a2713aSLionel Sambuc StmtVector Stmts; 861*f4a2713aSLionel Sambuc 862*f4a2713aSLionel Sambuc // "__label__ X, Y, Z;" is the GNU "Local Label" extension. These are 863*f4a2713aSLionel Sambuc // only allowed at the start of a compound stmt regardless of the language. 864*f4a2713aSLionel Sambuc while (Tok.is(tok::kw___label__)) { 865*f4a2713aSLionel Sambuc SourceLocation LabelLoc = ConsumeToken(); 866*f4a2713aSLionel Sambuc 867*f4a2713aSLionel Sambuc SmallVector<Decl *, 8> DeclsInGroup; 868*f4a2713aSLionel Sambuc while (1) { 869*f4a2713aSLionel Sambuc if (Tok.isNot(tok::identifier)) { 870*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_ident); 871*f4a2713aSLionel Sambuc break; 872*f4a2713aSLionel Sambuc } 873*f4a2713aSLionel Sambuc 874*f4a2713aSLionel Sambuc IdentifierInfo *II = Tok.getIdentifierInfo(); 875*f4a2713aSLionel Sambuc SourceLocation IdLoc = ConsumeToken(); 876*f4a2713aSLionel Sambuc DeclsInGroup.push_back(Actions.LookupOrCreateLabel(II, IdLoc, LabelLoc)); 877*f4a2713aSLionel Sambuc 878*f4a2713aSLionel Sambuc if (!Tok.is(tok::comma)) 879*f4a2713aSLionel Sambuc break; 880*f4a2713aSLionel Sambuc ConsumeToken(); 881*f4a2713aSLionel Sambuc } 882*f4a2713aSLionel Sambuc 883*f4a2713aSLionel Sambuc DeclSpec DS(AttrFactory); 884*f4a2713aSLionel Sambuc DeclGroupPtrTy Res = 885*f4a2713aSLionel Sambuc Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup); 886*f4a2713aSLionel Sambuc StmtResult R = Actions.ActOnDeclStmt(Res, LabelLoc, Tok.getLocation()); 887*f4a2713aSLionel Sambuc 888*f4a2713aSLionel Sambuc ExpectAndConsumeSemi(diag::err_expected_semi_declaration); 889*f4a2713aSLionel Sambuc if (R.isUsable()) 890*f4a2713aSLionel Sambuc Stmts.push_back(R.release()); 891*f4a2713aSLionel Sambuc } 892*f4a2713aSLionel Sambuc 893*f4a2713aSLionel Sambuc while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 894*f4a2713aSLionel Sambuc if (Tok.is(tok::annot_pragma_unused)) { 895*f4a2713aSLionel Sambuc HandlePragmaUnused(); 896*f4a2713aSLionel Sambuc continue; 897*f4a2713aSLionel Sambuc } 898*f4a2713aSLionel Sambuc 899*f4a2713aSLionel Sambuc if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) || 900*f4a2713aSLionel Sambuc Tok.is(tok::kw___if_not_exists))) { 901*f4a2713aSLionel Sambuc ParseMicrosoftIfExistsStatement(Stmts); 902*f4a2713aSLionel Sambuc continue; 903*f4a2713aSLionel Sambuc } 904*f4a2713aSLionel Sambuc 905*f4a2713aSLionel Sambuc StmtResult R; 906*f4a2713aSLionel Sambuc if (Tok.isNot(tok::kw___extension__)) { 907*f4a2713aSLionel Sambuc R = ParseStatementOrDeclaration(Stmts, false); 908*f4a2713aSLionel Sambuc } else { 909*f4a2713aSLionel Sambuc // __extension__ can start declarations and it can also be a unary 910*f4a2713aSLionel Sambuc // operator for expressions. Consume multiple __extension__ markers here 911*f4a2713aSLionel Sambuc // until we can determine which is which. 912*f4a2713aSLionel Sambuc // FIXME: This loses extension expressions in the AST! 913*f4a2713aSLionel Sambuc SourceLocation ExtLoc = ConsumeToken(); 914*f4a2713aSLionel Sambuc while (Tok.is(tok::kw___extension__)) 915*f4a2713aSLionel Sambuc ConsumeToken(); 916*f4a2713aSLionel Sambuc 917*f4a2713aSLionel Sambuc ParsedAttributesWithRange attrs(AttrFactory); 918*f4a2713aSLionel Sambuc MaybeParseCXX11Attributes(attrs, 0, /*MightBeObjCMessageSend*/ true); 919*f4a2713aSLionel Sambuc 920*f4a2713aSLionel Sambuc // If this is the start of a declaration, parse it as such. 921*f4a2713aSLionel Sambuc if (isDeclarationStatement()) { 922*f4a2713aSLionel Sambuc // __extension__ silences extension warnings in the subdeclaration. 923*f4a2713aSLionel Sambuc // FIXME: Save the __extension__ on the decl as a node somehow? 924*f4a2713aSLionel Sambuc ExtensionRAIIObject O(Diags); 925*f4a2713aSLionel Sambuc 926*f4a2713aSLionel Sambuc SourceLocation DeclStart = Tok.getLocation(), DeclEnd; 927*f4a2713aSLionel Sambuc DeclGroupPtrTy Res = ParseDeclaration(Stmts, 928*f4a2713aSLionel Sambuc Declarator::BlockContext, DeclEnd, 929*f4a2713aSLionel Sambuc attrs); 930*f4a2713aSLionel Sambuc R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd); 931*f4a2713aSLionel Sambuc } else { 932*f4a2713aSLionel Sambuc // Otherwise this was a unary __extension__ marker. 933*f4a2713aSLionel Sambuc ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc)); 934*f4a2713aSLionel Sambuc 935*f4a2713aSLionel Sambuc if (Res.isInvalid()) { 936*f4a2713aSLionel Sambuc SkipUntil(tok::semi); 937*f4a2713aSLionel Sambuc continue; 938*f4a2713aSLionel Sambuc } 939*f4a2713aSLionel Sambuc 940*f4a2713aSLionel Sambuc // FIXME: Use attributes? 941*f4a2713aSLionel Sambuc // Eat the semicolon at the end of stmt and convert the expr into a 942*f4a2713aSLionel Sambuc // statement. 943*f4a2713aSLionel Sambuc ExpectAndConsumeSemi(diag::err_expected_semi_after_expr); 944*f4a2713aSLionel Sambuc R = Actions.ActOnExprStmt(Res); 945*f4a2713aSLionel Sambuc } 946*f4a2713aSLionel Sambuc } 947*f4a2713aSLionel Sambuc 948*f4a2713aSLionel Sambuc if (R.isUsable()) 949*f4a2713aSLionel Sambuc Stmts.push_back(R.release()); 950*f4a2713aSLionel Sambuc } 951*f4a2713aSLionel Sambuc 952*f4a2713aSLionel Sambuc SourceLocation CloseLoc = Tok.getLocation(); 953*f4a2713aSLionel Sambuc 954*f4a2713aSLionel Sambuc // We broke out of the while loop because we found a '}' or EOF. 955*f4a2713aSLionel Sambuc if (!T.consumeClose()) 956*f4a2713aSLionel Sambuc // Recover by creating a compound statement with what we parsed so far, 957*f4a2713aSLionel Sambuc // instead of dropping everything and returning StmtError(); 958*f4a2713aSLionel Sambuc CloseLoc = T.getCloseLocation(); 959*f4a2713aSLionel Sambuc 960*f4a2713aSLionel Sambuc return Actions.ActOnCompoundStmt(T.getOpenLocation(), CloseLoc, 961*f4a2713aSLionel Sambuc Stmts, isStmtExpr); 962*f4a2713aSLionel Sambuc } 963*f4a2713aSLionel Sambuc 964*f4a2713aSLionel Sambuc /// ParseParenExprOrCondition: 965*f4a2713aSLionel Sambuc /// [C ] '(' expression ')' 966*f4a2713aSLionel Sambuc /// [C++] '(' condition ')' [not allowed if OnlyAllowCondition=true] 967*f4a2713aSLionel Sambuc /// 968*f4a2713aSLionel Sambuc /// This function parses and performs error recovery on the specified condition 969*f4a2713aSLionel Sambuc /// or expression (depending on whether we're in C++ or C mode). This function 970*f4a2713aSLionel Sambuc /// goes out of its way to recover well. It returns true if there was a parser 971*f4a2713aSLionel Sambuc /// error (the right paren couldn't be found), which indicates that the caller 972*f4a2713aSLionel Sambuc /// should try to recover harder. It returns false if the condition is 973*f4a2713aSLionel Sambuc /// successfully parsed. Note that a successful parse can still have semantic 974*f4a2713aSLionel Sambuc /// errors in the condition. 975*f4a2713aSLionel Sambuc bool Parser::ParseParenExprOrCondition(ExprResult &ExprResult, 976*f4a2713aSLionel Sambuc Decl *&DeclResult, 977*f4a2713aSLionel Sambuc SourceLocation Loc, 978*f4a2713aSLionel Sambuc bool ConvertToBoolean) { 979*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren); 980*f4a2713aSLionel Sambuc T.consumeOpen(); 981*f4a2713aSLionel Sambuc 982*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus) 983*f4a2713aSLionel Sambuc ParseCXXCondition(ExprResult, DeclResult, Loc, ConvertToBoolean); 984*f4a2713aSLionel Sambuc else { 985*f4a2713aSLionel Sambuc ExprResult = ParseExpression(); 986*f4a2713aSLionel Sambuc DeclResult = 0; 987*f4a2713aSLionel Sambuc 988*f4a2713aSLionel Sambuc // If required, convert to a boolean value. 989*f4a2713aSLionel Sambuc if (!ExprResult.isInvalid() && ConvertToBoolean) 990*f4a2713aSLionel Sambuc ExprResult 991*f4a2713aSLionel Sambuc = Actions.ActOnBooleanCondition(getCurScope(), Loc, ExprResult.get()); 992*f4a2713aSLionel Sambuc } 993*f4a2713aSLionel Sambuc 994*f4a2713aSLionel Sambuc // If the parser was confused by the condition and we don't have a ')', try to 995*f4a2713aSLionel Sambuc // recover by skipping ahead to a semi and bailing out. If condexp is 996*f4a2713aSLionel Sambuc // semantically invalid but we have well formed code, keep going. 997*f4a2713aSLionel Sambuc if (ExprResult.isInvalid() && !DeclResult && Tok.isNot(tok::r_paren)) { 998*f4a2713aSLionel Sambuc SkipUntil(tok::semi); 999*f4a2713aSLionel Sambuc // Skipping may have stopped if it found the containing ')'. If so, we can 1000*f4a2713aSLionel Sambuc // continue parsing the if statement. 1001*f4a2713aSLionel Sambuc if (Tok.isNot(tok::r_paren)) 1002*f4a2713aSLionel Sambuc return true; 1003*f4a2713aSLionel Sambuc } 1004*f4a2713aSLionel Sambuc 1005*f4a2713aSLionel Sambuc // Otherwise the condition is valid or the rparen is present. 1006*f4a2713aSLionel Sambuc T.consumeClose(); 1007*f4a2713aSLionel Sambuc 1008*f4a2713aSLionel Sambuc // Check for extraneous ')'s to catch things like "if (foo())) {". We know 1009*f4a2713aSLionel Sambuc // that all callers are looking for a statement after the condition, so ")" 1010*f4a2713aSLionel Sambuc // isn't valid. 1011*f4a2713aSLionel Sambuc while (Tok.is(tok::r_paren)) { 1012*f4a2713aSLionel Sambuc Diag(Tok, diag::err_extraneous_rparen_in_condition) 1013*f4a2713aSLionel Sambuc << FixItHint::CreateRemoval(Tok.getLocation()); 1014*f4a2713aSLionel Sambuc ConsumeParen(); 1015*f4a2713aSLionel Sambuc } 1016*f4a2713aSLionel Sambuc 1017*f4a2713aSLionel Sambuc return false; 1018*f4a2713aSLionel Sambuc } 1019*f4a2713aSLionel Sambuc 1020*f4a2713aSLionel Sambuc 1021*f4a2713aSLionel Sambuc /// ParseIfStatement 1022*f4a2713aSLionel Sambuc /// if-statement: [C99 6.8.4.1] 1023*f4a2713aSLionel Sambuc /// 'if' '(' expression ')' statement 1024*f4a2713aSLionel Sambuc /// 'if' '(' expression ')' statement 'else' statement 1025*f4a2713aSLionel Sambuc /// [C++] 'if' '(' condition ')' statement 1026*f4a2713aSLionel Sambuc /// [C++] 'if' '(' condition ')' statement 'else' statement 1027*f4a2713aSLionel Sambuc /// 1028*f4a2713aSLionel Sambuc StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) { 1029*f4a2713aSLionel Sambuc assert(Tok.is(tok::kw_if) && "Not an if stmt!"); 1030*f4a2713aSLionel Sambuc SourceLocation IfLoc = ConsumeToken(); // eat the 'if'. 1031*f4a2713aSLionel Sambuc 1032*f4a2713aSLionel Sambuc if (Tok.isNot(tok::l_paren)) { 1033*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_lparen_after) << "if"; 1034*f4a2713aSLionel Sambuc SkipUntil(tok::semi); 1035*f4a2713aSLionel Sambuc return StmtError(); 1036*f4a2713aSLionel Sambuc } 1037*f4a2713aSLionel Sambuc 1038*f4a2713aSLionel Sambuc bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus; 1039*f4a2713aSLionel Sambuc 1040*f4a2713aSLionel Sambuc // C99 6.8.4p3 - In C99, the if statement is a block. This is not 1041*f4a2713aSLionel Sambuc // the case for C90. 1042*f4a2713aSLionel Sambuc // 1043*f4a2713aSLionel Sambuc // C++ 6.4p3: 1044*f4a2713aSLionel Sambuc // A name introduced by a declaration in a condition is in scope from its 1045*f4a2713aSLionel Sambuc // point of declaration until the end of the substatements controlled by the 1046*f4a2713aSLionel Sambuc // condition. 1047*f4a2713aSLionel Sambuc // C++ 3.3.2p4: 1048*f4a2713aSLionel Sambuc // Names declared in the for-init-statement, and in the condition of if, 1049*f4a2713aSLionel Sambuc // while, for, and switch statements are local to the if, while, for, or 1050*f4a2713aSLionel Sambuc // switch statement (including the controlled statement). 1051*f4a2713aSLionel Sambuc // 1052*f4a2713aSLionel Sambuc ParseScope IfScope(this, Scope::DeclScope | Scope::ControlScope, C99orCXX); 1053*f4a2713aSLionel Sambuc 1054*f4a2713aSLionel Sambuc // Parse the condition. 1055*f4a2713aSLionel Sambuc ExprResult CondExp; 1056*f4a2713aSLionel Sambuc Decl *CondVar = 0; 1057*f4a2713aSLionel Sambuc if (ParseParenExprOrCondition(CondExp, CondVar, IfLoc, true)) 1058*f4a2713aSLionel Sambuc return StmtError(); 1059*f4a2713aSLionel Sambuc 1060*f4a2713aSLionel Sambuc FullExprArg FullCondExp(Actions.MakeFullExpr(CondExp.get(), IfLoc)); 1061*f4a2713aSLionel Sambuc 1062*f4a2713aSLionel Sambuc // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if 1063*f4a2713aSLionel Sambuc // there is no compound stmt. C90 does not have this clause. We only do this 1064*f4a2713aSLionel Sambuc // if the body isn't a compound statement to avoid push/pop in common cases. 1065*f4a2713aSLionel Sambuc // 1066*f4a2713aSLionel Sambuc // C++ 6.4p1: 1067*f4a2713aSLionel Sambuc // The substatement in a selection-statement (each substatement, in the else 1068*f4a2713aSLionel Sambuc // form of the if statement) implicitly defines a local scope. 1069*f4a2713aSLionel Sambuc // 1070*f4a2713aSLionel Sambuc // For C++ we create a scope for the condition and a new scope for 1071*f4a2713aSLionel Sambuc // substatements because: 1072*f4a2713aSLionel Sambuc // -When the 'then' scope exits, we want the condition declaration to still be 1073*f4a2713aSLionel Sambuc // active for the 'else' scope too. 1074*f4a2713aSLionel Sambuc // -Sema will detect name clashes by considering declarations of a 1075*f4a2713aSLionel Sambuc // 'ControlScope' as part of its direct subscope. 1076*f4a2713aSLionel Sambuc // -If we wanted the condition and substatement to be in the same scope, we 1077*f4a2713aSLionel Sambuc // would have to notify ParseStatement not to create a new scope. It's 1078*f4a2713aSLionel Sambuc // simpler to let it create a new scope. 1079*f4a2713aSLionel Sambuc // 1080*f4a2713aSLionel Sambuc ParseScope InnerScope(this, Scope::DeclScope, 1081*f4a2713aSLionel Sambuc C99orCXX && Tok.isNot(tok::l_brace)); 1082*f4a2713aSLionel Sambuc 1083*f4a2713aSLionel Sambuc // Read the 'then' stmt. 1084*f4a2713aSLionel Sambuc SourceLocation ThenStmtLoc = Tok.getLocation(); 1085*f4a2713aSLionel Sambuc 1086*f4a2713aSLionel Sambuc SourceLocation InnerStatementTrailingElseLoc; 1087*f4a2713aSLionel Sambuc StmtResult ThenStmt(ParseStatement(&InnerStatementTrailingElseLoc)); 1088*f4a2713aSLionel Sambuc 1089*f4a2713aSLionel Sambuc // Pop the 'if' scope if needed. 1090*f4a2713aSLionel Sambuc InnerScope.Exit(); 1091*f4a2713aSLionel Sambuc 1092*f4a2713aSLionel Sambuc // If it has an else, parse it. 1093*f4a2713aSLionel Sambuc SourceLocation ElseLoc; 1094*f4a2713aSLionel Sambuc SourceLocation ElseStmtLoc; 1095*f4a2713aSLionel Sambuc StmtResult ElseStmt; 1096*f4a2713aSLionel Sambuc 1097*f4a2713aSLionel Sambuc if (Tok.is(tok::kw_else)) { 1098*f4a2713aSLionel Sambuc if (TrailingElseLoc) 1099*f4a2713aSLionel Sambuc *TrailingElseLoc = Tok.getLocation(); 1100*f4a2713aSLionel Sambuc 1101*f4a2713aSLionel Sambuc ElseLoc = ConsumeToken(); 1102*f4a2713aSLionel Sambuc ElseStmtLoc = Tok.getLocation(); 1103*f4a2713aSLionel Sambuc 1104*f4a2713aSLionel Sambuc // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if 1105*f4a2713aSLionel Sambuc // there is no compound stmt. C90 does not have this clause. We only do 1106*f4a2713aSLionel Sambuc // this if the body isn't a compound statement to avoid push/pop in common 1107*f4a2713aSLionel Sambuc // cases. 1108*f4a2713aSLionel Sambuc // 1109*f4a2713aSLionel Sambuc // C++ 6.4p1: 1110*f4a2713aSLionel Sambuc // The substatement in a selection-statement (each substatement, in the else 1111*f4a2713aSLionel Sambuc // form of the if statement) implicitly defines a local scope. 1112*f4a2713aSLionel Sambuc // 1113*f4a2713aSLionel Sambuc ParseScope InnerScope(this, Scope::DeclScope, 1114*f4a2713aSLionel Sambuc C99orCXX && Tok.isNot(tok::l_brace)); 1115*f4a2713aSLionel Sambuc 1116*f4a2713aSLionel Sambuc ElseStmt = ParseStatement(); 1117*f4a2713aSLionel Sambuc 1118*f4a2713aSLionel Sambuc // Pop the 'else' scope if needed. 1119*f4a2713aSLionel Sambuc InnerScope.Exit(); 1120*f4a2713aSLionel Sambuc } else if (Tok.is(tok::code_completion)) { 1121*f4a2713aSLionel Sambuc Actions.CodeCompleteAfterIf(getCurScope()); 1122*f4a2713aSLionel Sambuc cutOffParsing(); 1123*f4a2713aSLionel Sambuc return StmtError(); 1124*f4a2713aSLionel Sambuc } else if (InnerStatementTrailingElseLoc.isValid()) { 1125*f4a2713aSLionel Sambuc Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else); 1126*f4a2713aSLionel Sambuc } 1127*f4a2713aSLionel Sambuc 1128*f4a2713aSLionel Sambuc IfScope.Exit(); 1129*f4a2713aSLionel Sambuc 1130*f4a2713aSLionel Sambuc // If the then or else stmt is invalid and the other is valid (and present), 1131*f4a2713aSLionel Sambuc // make turn the invalid one into a null stmt to avoid dropping the other 1132*f4a2713aSLionel Sambuc // part. If both are invalid, return error. 1133*f4a2713aSLionel Sambuc if ((ThenStmt.isInvalid() && ElseStmt.isInvalid()) || 1134*f4a2713aSLionel Sambuc (ThenStmt.isInvalid() && ElseStmt.get() == 0) || 1135*f4a2713aSLionel Sambuc (ThenStmt.get() == 0 && ElseStmt.isInvalid())) { 1136*f4a2713aSLionel Sambuc // Both invalid, or one is invalid and other is non-present: return error. 1137*f4a2713aSLionel Sambuc return StmtError(); 1138*f4a2713aSLionel Sambuc } 1139*f4a2713aSLionel Sambuc 1140*f4a2713aSLionel Sambuc // Now if either are invalid, replace with a ';'. 1141*f4a2713aSLionel Sambuc if (ThenStmt.isInvalid()) 1142*f4a2713aSLionel Sambuc ThenStmt = Actions.ActOnNullStmt(ThenStmtLoc); 1143*f4a2713aSLionel Sambuc if (ElseStmt.isInvalid()) 1144*f4a2713aSLionel Sambuc ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc); 1145*f4a2713aSLionel Sambuc 1146*f4a2713aSLionel Sambuc return Actions.ActOnIfStmt(IfLoc, FullCondExp, CondVar, ThenStmt.get(), 1147*f4a2713aSLionel Sambuc ElseLoc, ElseStmt.get()); 1148*f4a2713aSLionel Sambuc } 1149*f4a2713aSLionel Sambuc 1150*f4a2713aSLionel Sambuc /// ParseSwitchStatement 1151*f4a2713aSLionel Sambuc /// switch-statement: 1152*f4a2713aSLionel Sambuc /// 'switch' '(' expression ')' statement 1153*f4a2713aSLionel Sambuc /// [C++] 'switch' '(' condition ')' statement 1154*f4a2713aSLionel Sambuc StmtResult Parser::ParseSwitchStatement(SourceLocation *TrailingElseLoc) { 1155*f4a2713aSLionel Sambuc assert(Tok.is(tok::kw_switch) && "Not a switch stmt!"); 1156*f4a2713aSLionel Sambuc SourceLocation SwitchLoc = ConsumeToken(); // eat the 'switch'. 1157*f4a2713aSLionel Sambuc 1158*f4a2713aSLionel Sambuc if (Tok.isNot(tok::l_paren)) { 1159*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_lparen_after) << "switch"; 1160*f4a2713aSLionel Sambuc SkipUntil(tok::semi); 1161*f4a2713aSLionel Sambuc return StmtError(); 1162*f4a2713aSLionel Sambuc } 1163*f4a2713aSLionel Sambuc 1164*f4a2713aSLionel Sambuc bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus; 1165*f4a2713aSLionel Sambuc 1166*f4a2713aSLionel Sambuc // C99 6.8.4p3 - In C99, the switch statement is a block. This is 1167*f4a2713aSLionel Sambuc // not the case for C90. Start the switch scope. 1168*f4a2713aSLionel Sambuc // 1169*f4a2713aSLionel Sambuc // C++ 6.4p3: 1170*f4a2713aSLionel Sambuc // A name introduced by a declaration in a condition is in scope from its 1171*f4a2713aSLionel Sambuc // point of declaration until the end of the substatements controlled by the 1172*f4a2713aSLionel Sambuc // condition. 1173*f4a2713aSLionel Sambuc // C++ 3.3.2p4: 1174*f4a2713aSLionel Sambuc // Names declared in the for-init-statement, and in the condition of if, 1175*f4a2713aSLionel Sambuc // while, for, and switch statements are local to the if, while, for, or 1176*f4a2713aSLionel Sambuc // switch statement (including the controlled statement). 1177*f4a2713aSLionel Sambuc // 1178*f4a2713aSLionel Sambuc unsigned ScopeFlags = Scope::BreakScope | Scope::SwitchScope; 1179*f4a2713aSLionel Sambuc if (C99orCXX) 1180*f4a2713aSLionel Sambuc ScopeFlags |= Scope::DeclScope | Scope::ControlScope; 1181*f4a2713aSLionel Sambuc ParseScope SwitchScope(this, ScopeFlags); 1182*f4a2713aSLionel Sambuc 1183*f4a2713aSLionel Sambuc // Parse the condition. 1184*f4a2713aSLionel Sambuc ExprResult Cond; 1185*f4a2713aSLionel Sambuc Decl *CondVar = 0; 1186*f4a2713aSLionel Sambuc if (ParseParenExprOrCondition(Cond, CondVar, SwitchLoc, false)) 1187*f4a2713aSLionel Sambuc return StmtError(); 1188*f4a2713aSLionel Sambuc 1189*f4a2713aSLionel Sambuc StmtResult Switch 1190*f4a2713aSLionel Sambuc = Actions.ActOnStartOfSwitchStmt(SwitchLoc, Cond.get(), CondVar); 1191*f4a2713aSLionel Sambuc 1192*f4a2713aSLionel Sambuc if (Switch.isInvalid()) { 1193*f4a2713aSLionel Sambuc // Skip the switch body. 1194*f4a2713aSLionel Sambuc // FIXME: This is not optimal recovery, but parsing the body is more 1195*f4a2713aSLionel Sambuc // dangerous due to the presence of case and default statements, which 1196*f4a2713aSLionel Sambuc // will have no place to connect back with the switch. 1197*f4a2713aSLionel Sambuc if (Tok.is(tok::l_brace)) { 1198*f4a2713aSLionel Sambuc ConsumeBrace(); 1199*f4a2713aSLionel Sambuc SkipUntil(tok::r_brace); 1200*f4a2713aSLionel Sambuc } else 1201*f4a2713aSLionel Sambuc SkipUntil(tok::semi); 1202*f4a2713aSLionel Sambuc return Switch; 1203*f4a2713aSLionel Sambuc } 1204*f4a2713aSLionel Sambuc 1205*f4a2713aSLionel Sambuc // C99 6.8.4p3 - In C99, the body of the switch statement is a scope, even if 1206*f4a2713aSLionel Sambuc // there is no compound stmt. C90 does not have this clause. We only do this 1207*f4a2713aSLionel Sambuc // if the body isn't a compound statement to avoid push/pop in common cases. 1208*f4a2713aSLionel Sambuc // 1209*f4a2713aSLionel Sambuc // C++ 6.4p1: 1210*f4a2713aSLionel Sambuc // The substatement in a selection-statement (each substatement, in the else 1211*f4a2713aSLionel Sambuc // form of the if statement) implicitly defines a local scope. 1212*f4a2713aSLionel Sambuc // 1213*f4a2713aSLionel Sambuc // See comments in ParseIfStatement for why we create a scope for the 1214*f4a2713aSLionel Sambuc // condition and a new scope for substatement in C++. 1215*f4a2713aSLionel Sambuc // 1216*f4a2713aSLionel Sambuc ParseScope InnerScope(this, Scope::DeclScope, 1217*f4a2713aSLionel Sambuc C99orCXX && Tok.isNot(tok::l_brace)); 1218*f4a2713aSLionel Sambuc 1219*f4a2713aSLionel Sambuc // Read the body statement. 1220*f4a2713aSLionel Sambuc StmtResult Body(ParseStatement(TrailingElseLoc)); 1221*f4a2713aSLionel Sambuc 1222*f4a2713aSLionel Sambuc // Pop the scopes. 1223*f4a2713aSLionel Sambuc InnerScope.Exit(); 1224*f4a2713aSLionel Sambuc SwitchScope.Exit(); 1225*f4a2713aSLionel Sambuc 1226*f4a2713aSLionel Sambuc if (Body.isInvalid()) { 1227*f4a2713aSLionel Sambuc // FIXME: Remove the case statement list from the Switch statement. 1228*f4a2713aSLionel Sambuc 1229*f4a2713aSLionel Sambuc // Put the synthesized null statement on the same line as the end of switch 1230*f4a2713aSLionel Sambuc // condition. 1231*f4a2713aSLionel Sambuc SourceLocation SynthesizedNullStmtLocation = Cond.get()->getLocEnd(); 1232*f4a2713aSLionel Sambuc Body = Actions.ActOnNullStmt(SynthesizedNullStmtLocation); 1233*f4a2713aSLionel Sambuc } 1234*f4a2713aSLionel Sambuc 1235*f4a2713aSLionel Sambuc return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.get(), Body.get()); 1236*f4a2713aSLionel Sambuc } 1237*f4a2713aSLionel Sambuc 1238*f4a2713aSLionel Sambuc /// ParseWhileStatement 1239*f4a2713aSLionel Sambuc /// while-statement: [C99 6.8.5.1] 1240*f4a2713aSLionel Sambuc /// 'while' '(' expression ')' statement 1241*f4a2713aSLionel Sambuc /// [C++] 'while' '(' condition ')' statement 1242*f4a2713aSLionel Sambuc StmtResult Parser::ParseWhileStatement(SourceLocation *TrailingElseLoc) { 1243*f4a2713aSLionel Sambuc assert(Tok.is(tok::kw_while) && "Not a while stmt!"); 1244*f4a2713aSLionel Sambuc SourceLocation WhileLoc = Tok.getLocation(); 1245*f4a2713aSLionel Sambuc ConsumeToken(); // eat the 'while'. 1246*f4a2713aSLionel Sambuc 1247*f4a2713aSLionel Sambuc if (Tok.isNot(tok::l_paren)) { 1248*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_lparen_after) << "while"; 1249*f4a2713aSLionel Sambuc SkipUntil(tok::semi); 1250*f4a2713aSLionel Sambuc return StmtError(); 1251*f4a2713aSLionel Sambuc } 1252*f4a2713aSLionel Sambuc 1253*f4a2713aSLionel Sambuc bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus; 1254*f4a2713aSLionel Sambuc 1255*f4a2713aSLionel Sambuc // C99 6.8.5p5 - In C99, the while statement is a block. This is not 1256*f4a2713aSLionel Sambuc // the case for C90. Start the loop scope. 1257*f4a2713aSLionel Sambuc // 1258*f4a2713aSLionel Sambuc // C++ 6.4p3: 1259*f4a2713aSLionel Sambuc // A name introduced by a declaration in a condition is in scope from its 1260*f4a2713aSLionel Sambuc // point of declaration until the end of the substatements controlled by the 1261*f4a2713aSLionel Sambuc // condition. 1262*f4a2713aSLionel Sambuc // C++ 3.3.2p4: 1263*f4a2713aSLionel Sambuc // Names declared in the for-init-statement, and in the condition of if, 1264*f4a2713aSLionel Sambuc // while, for, and switch statements are local to the if, while, for, or 1265*f4a2713aSLionel Sambuc // switch statement (including the controlled statement). 1266*f4a2713aSLionel Sambuc // 1267*f4a2713aSLionel Sambuc unsigned ScopeFlags; 1268*f4a2713aSLionel Sambuc if (C99orCXX) 1269*f4a2713aSLionel Sambuc ScopeFlags = Scope::BreakScope | Scope::ContinueScope | 1270*f4a2713aSLionel Sambuc Scope::DeclScope | Scope::ControlScope; 1271*f4a2713aSLionel Sambuc else 1272*f4a2713aSLionel Sambuc ScopeFlags = Scope::BreakScope | Scope::ContinueScope; 1273*f4a2713aSLionel Sambuc ParseScope WhileScope(this, ScopeFlags); 1274*f4a2713aSLionel Sambuc 1275*f4a2713aSLionel Sambuc // Parse the condition. 1276*f4a2713aSLionel Sambuc ExprResult Cond; 1277*f4a2713aSLionel Sambuc Decl *CondVar = 0; 1278*f4a2713aSLionel Sambuc if (ParseParenExprOrCondition(Cond, CondVar, WhileLoc, true)) 1279*f4a2713aSLionel Sambuc return StmtError(); 1280*f4a2713aSLionel Sambuc 1281*f4a2713aSLionel Sambuc FullExprArg FullCond(Actions.MakeFullExpr(Cond.get(), WhileLoc)); 1282*f4a2713aSLionel Sambuc 1283*f4a2713aSLionel Sambuc // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if 1284*f4a2713aSLionel Sambuc // there is no compound stmt. C90 does not have this clause. We only do this 1285*f4a2713aSLionel Sambuc // if the body isn't a compound statement to avoid push/pop in common cases. 1286*f4a2713aSLionel Sambuc // 1287*f4a2713aSLionel Sambuc // C++ 6.5p2: 1288*f4a2713aSLionel Sambuc // The substatement in an iteration-statement implicitly defines a local scope 1289*f4a2713aSLionel Sambuc // which is entered and exited each time through the loop. 1290*f4a2713aSLionel Sambuc // 1291*f4a2713aSLionel Sambuc // See comments in ParseIfStatement for why we create a scope for the 1292*f4a2713aSLionel Sambuc // condition and a new scope for substatement in C++. 1293*f4a2713aSLionel Sambuc // 1294*f4a2713aSLionel Sambuc ParseScope InnerScope(this, Scope::DeclScope, 1295*f4a2713aSLionel Sambuc C99orCXX && Tok.isNot(tok::l_brace)); 1296*f4a2713aSLionel Sambuc 1297*f4a2713aSLionel Sambuc // Read the body statement. 1298*f4a2713aSLionel Sambuc StmtResult Body(ParseStatement(TrailingElseLoc)); 1299*f4a2713aSLionel Sambuc 1300*f4a2713aSLionel Sambuc // Pop the body scope if needed. 1301*f4a2713aSLionel Sambuc InnerScope.Exit(); 1302*f4a2713aSLionel Sambuc WhileScope.Exit(); 1303*f4a2713aSLionel Sambuc 1304*f4a2713aSLionel Sambuc if ((Cond.isInvalid() && !CondVar) || Body.isInvalid()) 1305*f4a2713aSLionel Sambuc return StmtError(); 1306*f4a2713aSLionel Sambuc 1307*f4a2713aSLionel Sambuc return Actions.ActOnWhileStmt(WhileLoc, FullCond, CondVar, Body.get()); 1308*f4a2713aSLionel Sambuc } 1309*f4a2713aSLionel Sambuc 1310*f4a2713aSLionel Sambuc /// ParseDoStatement 1311*f4a2713aSLionel Sambuc /// do-statement: [C99 6.8.5.2] 1312*f4a2713aSLionel Sambuc /// 'do' statement 'while' '(' expression ')' ';' 1313*f4a2713aSLionel Sambuc /// Note: this lets the caller parse the end ';'. 1314*f4a2713aSLionel Sambuc StmtResult Parser::ParseDoStatement() { 1315*f4a2713aSLionel Sambuc assert(Tok.is(tok::kw_do) && "Not a do stmt!"); 1316*f4a2713aSLionel Sambuc SourceLocation DoLoc = ConsumeToken(); // eat the 'do'. 1317*f4a2713aSLionel Sambuc 1318*f4a2713aSLionel Sambuc // C99 6.8.5p5 - In C99, the do statement is a block. This is not 1319*f4a2713aSLionel Sambuc // the case for C90. Start the loop scope. 1320*f4a2713aSLionel Sambuc unsigned ScopeFlags; 1321*f4a2713aSLionel Sambuc if (getLangOpts().C99) 1322*f4a2713aSLionel Sambuc ScopeFlags = Scope::BreakScope | Scope::ContinueScope | Scope::DeclScope; 1323*f4a2713aSLionel Sambuc else 1324*f4a2713aSLionel Sambuc ScopeFlags = Scope::BreakScope | Scope::ContinueScope; 1325*f4a2713aSLionel Sambuc 1326*f4a2713aSLionel Sambuc ParseScope DoScope(this, ScopeFlags); 1327*f4a2713aSLionel Sambuc 1328*f4a2713aSLionel Sambuc // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if 1329*f4a2713aSLionel Sambuc // there is no compound stmt. C90 does not have this clause. We only do this 1330*f4a2713aSLionel Sambuc // if the body isn't a compound statement to avoid push/pop in common cases. 1331*f4a2713aSLionel Sambuc // 1332*f4a2713aSLionel Sambuc // C++ 6.5p2: 1333*f4a2713aSLionel Sambuc // The substatement in an iteration-statement implicitly defines a local scope 1334*f4a2713aSLionel Sambuc // which is entered and exited each time through the loop. 1335*f4a2713aSLionel Sambuc // 1336*f4a2713aSLionel Sambuc ParseScope InnerScope(this, Scope::DeclScope, 1337*f4a2713aSLionel Sambuc (getLangOpts().C99 || getLangOpts().CPlusPlus) && 1338*f4a2713aSLionel Sambuc Tok.isNot(tok::l_brace)); 1339*f4a2713aSLionel Sambuc 1340*f4a2713aSLionel Sambuc // Read the body statement. 1341*f4a2713aSLionel Sambuc StmtResult Body(ParseStatement()); 1342*f4a2713aSLionel Sambuc 1343*f4a2713aSLionel Sambuc // Pop the body scope if needed. 1344*f4a2713aSLionel Sambuc InnerScope.Exit(); 1345*f4a2713aSLionel Sambuc 1346*f4a2713aSLionel Sambuc if (Tok.isNot(tok::kw_while)) { 1347*f4a2713aSLionel Sambuc if (!Body.isInvalid()) { 1348*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_while); 1349*f4a2713aSLionel Sambuc Diag(DoLoc, diag::note_matching) << "do"; 1350*f4a2713aSLionel Sambuc SkipUntil(tok::semi, StopBeforeMatch); 1351*f4a2713aSLionel Sambuc } 1352*f4a2713aSLionel Sambuc return StmtError(); 1353*f4a2713aSLionel Sambuc } 1354*f4a2713aSLionel Sambuc SourceLocation WhileLoc = ConsumeToken(); 1355*f4a2713aSLionel Sambuc 1356*f4a2713aSLionel Sambuc if (Tok.isNot(tok::l_paren)) { 1357*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_lparen_after) << "do/while"; 1358*f4a2713aSLionel Sambuc SkipUntil(tok::semi, StopBeforeMatch); 1359*f4a2713aSLionel Sambuc return StmtError(); 1360*f4a2713aSLionel Sambuc } 1361*f4a2713aSLionel Sambuc 1362*f4a2713aSLionel Sambuc // Parse the parenthesized expression. 1363*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren); 1364*f4a2713aSLionel Sambuc T.consumeOpen(); 1365*f4a2713aSLionel Sambuc 1366*f4a2713aSLionel Sambuc // A do-while expression is not a condition, so can't have attributes. 1367*f4a2713aSLionel Sambuc DiagnoseAndSkipCXX11Attributes(); 1368*f4a2713aSLionel Sambuc 1369*f4a2713aSLionel Sambuc ExprResult Cond = ParseExpression(); 1370*f4a2713aSLionel Sambuc T.consumeClose(); 1371*f4a2713aSLionel Sambuc DoScope.Exit(); 1372*f4a2713aSLionel Sambuc 1373*f4a2713aSLionel Sambuc if (Cond.isInvalid() || Body.isInvalid()) 1374*f4a2713aSLionel Sambuc return StmtError(); 1375*f4a2713aSLionel Sambuc 1376*f4a2713aSLionel Sambuc return Actions.ActOnDoStmt(DoLoc, Body.get(), WhileLoc, T.getOpenLocation(), 1377*f4a2713aSLionel Sambuc Cond.get(), T.getCloseLocation()); 1378*f4a2713aSLionel Sambuc } 1379*f4a2713aSLionel Sambuc 1380*f4a2713aSLionel Sambuc /// ParseForStatement 1381*f4a2713aSLionel Sambuc /// for-statement: [C99 6.8.5.3] 1382*f4a2713aSLionel Sambuc /// 'for' '(' expr[opt] ';' expr[opt] ';' expr[opt] ')' statement 1383*f4a2713aSLionel Sambuc /// 'for' '(' declaration expr[opt] ';' expr[opt] ')' statement 1384*f4a2713aSLionel Sambuc /// [C++] 'for' '(' for-init-statement condition[opt] ';' expression[opt] ')' 1385*f4a2713aSLionel Sambuc /// [C++] statement 1386*f4a2713aSLionel Sambuc /// [C++0x] 'for' '(' for-range-declaration : for-range-initializer ) statement 1387*f4a2713aSLionel Sambuc /// [OBJC2] 'for' '(' declaration 'in' expr ')' statement 1388*f4a2713aSLionel Sambuc /// [OBJC2] 'for' '(' expr 'in' expr ')' statement 1389*f4a2713aSLionel Sambuc /// 1390*f4a2713aSLionel Sambuc /// [C++] for-init-statement: 1391*f4a2713aSLionel Sambuc /// [C++] expression-statement 1392*f4a2713aSLionel Sambuc /// [C++] simple-declaration 1393*f4a2713aSLionel Sambuc /// 1394*f4a2713aSLionel Sambuc /// [C++0x] for-range-declaration: 1395*f4a2713aSLionel Sambuc /// [C++0x] attribute-specifier-seq[opt] type-specifier-seq declarator 1396*f4a2713aSLionel Sambuc /// [C++0x] for-range-initializer: 1397*f4a2713aSLionel Sambuc /// [C++0x] expression 1398*f4a2713aSLionel Sambuc /// [C++0x] braced-init-list [TODO] 1399*f4a2713aSLionel Sambuc StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { 1400*f4a2713aSLionel Sambuc assert(Tok.is(tok::kw_for) && "Not a for stmt!"); 1401*f4a2713aSLionel Sambuc SourceLocation ForLoc = ConsumeToken(); // eat the 'for'. 1402*f4a2713aSLionel Sambuc 1403*f4a2713aSLionel Sambuc if (Tok.isNot(tok::l_paren)) { 1404*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_lparen_after) << "for"; 1405*f4a2713aSLionel Sambuc SkipUntil(tok::semi); 1406*f4a2713aSLionel Sambuc return StmtError(); 1407*f4a2713aSLionel Sambuc } 1408*f4a2713aSLionel Sambuc 1409*f4a2713aSLionel Sambuc bool C99orCXXorObjC = getLangOpts().C99 || getLangOpts().CPlusPlus || 1410*f4a2713aSLionel Sambuc getLangOpts().ObjC1; 1411*f4a2713aSLionel Sambuc 1412*f4a2713aSLionel Sambuc // C99 6.8.5p5 - In C99, the for statement is a block. This is not 1413*f4a2713aSLionel Sambuc // the case for C90. Start the loop scope. 1414*f4a2713aSLionel Sambuc // 1415*f4a2713aSLionel Sambuc // C++ 6.4p3: 1416*f4a2713aSLionel Sambuc // A name introduced by a declaration in a condition is in scope from its 1417*f4a2713aSLionel Sambuc // point of declaration until the end of the substatements controlled by the 1418*f4a2713aSLionel Sambuc // condition. 1419*f4a2713aSLionel Sambuc // C++ 3.3.2p4: 1420*f4a2713aSLionel Sambuc // Names declared in the for-init-statement, and in the condition of if, 1421*f4a2713aSLionel Sambuc // while, for, and switch statements are local to the if, while, for, or 1422*f4a2713aSLionel Sambuc // switch statement (including the controlled statement). 1423*f4a2713aSLionel Sambuc // C++ 6.5.3p1: 1424*f4a2713aSLionel Sambuc // Names declared in the for-init-statement are in the same declarative-region 1425*f4a2713aSLionel Sambuc // as those declared in the condition. 1426*f4a2713aSLionel Sambuc // 1427*f4a2713aSLionel Sambuc unsigned ScopeFlags; 1428*f4a2713aSLionel Sambuc if (C99orCXXorObjC) 1429*f4a2713aSLionel Sambuc ScopeFlags = Scope::BreakScope | Scope::ContinueScope | 1430*f4a2713aSLionel Sambuc Scope::DeclScope | Scope::ControlScope; 1431*f4a2713aSLionel Sambuc else 1432*f4a2713aSLionel Sambuc ScopeFlags = Scope::BreakScope | Scope::ContinueScope; 1433*f4a2713aSLionel Sambuc 1434*f4a2713aSLionel Sambuc ParseScope ForScope(this, ScopeFlags); 1435*f4a2713aSLionel Sambuc 1436*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren); 1437*f4a2713aSLionel Sambuc T.consumeOpen(); 1438*f4a2713aSLionel Sambuc 1439*f4a2713aSLionel Sambuc ExprResult Value; 1440*f4a2713aSLionel Sambuc 1441*f4a2713aSLionel Sambuc bool ForEach = false, ForRange = false; 1442*f4a2713aSLionel Sambuc StmtResult FirstPart; 1443*f4a2713aSLionel Sambuc bool SecondPartIsInvalid = false; 1444*f4a2713aSLionel Sambuc FullExprArg SecondPart(Actions); 1445*f4a2713aSLionel Sambuc ExprResult Collection; 1446*f4a2713aSLionel Sambuc ForRangeInit ForRangeInit; 1447*f4a2713aSLionel Sambuc FullExprArg ThirdPart(Actions); 1448*f4a2713aSLionel Sambuc Decl *SecondVar = 0; 1449*f4a2713aSLionel Sambuc 1450*f4a2713aSLionel Sambuc if (Tok.is(tok::code_completion)) { 1451*f4a2713aSLionel Sambuc Actions.CodeCompleteOrdinaryName(getCurScope(), 1452*f4a2713aSLionel Sambuc C99orCXXorObjC? Sema::PCC_ForInit 1453*f4a2713aSLionel Sambuc : Sema::PCC_Expression); 1454*f4a2713aSLionel Sambuc cutOffParsing(); 1455*f4a2713aSLionel Sambuc return StmtError(); 1456*f4a2713aSLionel Sambuc } 1457*f4a2713aSLionel Sambuc 1458*f4a2713aSLionel Sambuc ParsedAttributesWithRange attrs(AttrFactory); 1459*f4a2713aSLionel Sambuc MaybeParseCXX11Attributes(attrs); 1460*f4a2713aSLionel Sambuc 1461*f4a2713aSLionel Sambuc // Parse the first part of the for specifier. 1462*f4a2713aSLionel Sambuc if (Tok.is(tok::semi)) { // for (; 1463*f4a2713aSLionel Sambuc ProhibitAttributes(attrs); 1464*f4a2713aSLionel Sambuc // no first part, eat the ';'. 1465*f4a2713aSLionel Sambuc ConsumeToken(); 1466*f4a2713aSLionel Sambuc } else if (isForInitDeclaration()) { // for (int X = 4; 1467*f4a2713aSLionel Sambuc // Parse declaration, which eats the ';'. 1468*f4a2713aSLionel Sambuc if (!C99orCXXorObjC) // Use of C99-style for loops in C90 mode? 1469*f4a2713aSLionel Sambuc Diag(Tok, diag::ext_c99_variable_decl_in_for_loop); 1470*f4a2713aSLionel Sambuc 1471*f4a2713aSLionel Sambuc // In C++0x, "for (T NS:a" might not be a typo for :: 1472*f4a2713aSLionel Sambuc bool MightBeForRangeStmt = getLangOpts().CPlusPlus; 1473*f4a2713aSLionel Sambuc ColonProtectionRAIIObject ColonProtection(*this, MightBeForRangeStmt); 1474*f4a2713aSLionel Sambuc 1475*f4a2713aSLionel Sambuc SourceLocation DeclStart = Tok.getLocation(), DeclEnd; 1476*f4a2713aSLionel Sambuc StmtVector Stmts; 1477*f4a2713aSLionel Sambuc DeclGroupPtrTy DG = ParseSimpleDeclaration(Stmts, Declarator::ForContext, 1478*f4a2713aSLionel Sambuc DeclEnd, attrs, false, 1479*f4a2713aSLionel Sambuc MightBeForRangeStmt ? 1480*f4a2713aSLionel Sambuc &ForRangeInit : 0); 1481*f4a2713aSLionel Sambuc FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation()); 1482*f4a2713aSLionel Sambuc 1483*f4a2713aSLionel Sambuc if (ForRangeInit.ParsedForRangeDecl()) { 1484*f4a2713aSLionel Sambuc Diag(ForRangeInit.ColonLoc, getLangOpts().CPlusPlus11 ? 1485*f4a2713aSLionel Sambuc diag::warn_cxx98_compat_for_range : diag::ext_for_range); 1486*f4a2713aSLionel Sambuc 1487*f4a2713aSLionel Sambuc ForRange = true; 1488*f4a2713aSLionel Sambuc } else if (Tok.is(tok::semi)) { // for (int x = 4; 1489*f4a2713aSLionel Sambuc ConsumeToken(); 1490*f4a2713aSLionel Sambuc } else if ((ForEach = isTokIdentifier_in())) { 1491*f4a2713aSLionel Sambuc Actions.ActOnForEachDeclStmt(DG); 1492*f4a2713aSLionel Sambuc // ObjC: for (id x in expr) 1493*f4a2713aSLionel Sambuc ConsumeToken(); // consume 'in' 1494*f4a2713aSLionel Sambuc 1495*f4a2713aSLionel Sambuc if (Tok.is(tok::code_completion)) { 1496*f4a2713aSLionel Sambuc Actions.CodeCompleteObjCForCollection(getCurScope(), DG); 1497*f4a2713aSLionel Sambuc cutOffParsing(); 1498*f4a2713aSLionel Sambuc return StmtError(); 1499*f4a2713aSLionel Sambuc } 1500*f4a2713aSLionel Sambuc Collection = ParseExpression(); 1501*f4a2713aSLionel Sambuc } else { 1502*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_semi_for); 1503*f4a2713aSLionel Sambuc } 1504*f4a2713aSLionel Sambuc } else { 1505*f4a2713aSLionel Sambuc ProhibitAttributes(attrs); 1506*f4a2713aSLionel Sambuc Value = ParseExpression(); 1507*f4a2713aSLionel Sambuc 1508*f4a2713aSLionel Sambuc ForEach = isTokIdentifier_in(); 1509*f4a2713aSLionel Sambuc 1510*f4a2713aSLionel Sambuc // Turn the expression into a stmt. 1511*f4a2713aSLionel Sambuc if (!Value.isInvalid()) { 1512*f4a2713aSLionel Sambuc if (ForEach) 1513*f4a2713aSLionel Sambuc FirstPart = Actions.ActOnForEachLValueExpr(Value.get()); 1514*f4a2713aSLionel Sambuc else 1515*f4a2713aSLionel Sambuc FirstPart = Actions.ActOnExprStmt(Value); 1516*f4a2713aSLionel Sambuc } 1517*f4a2713aSLionel Sambuc 1518*f4a2713aSLionel Sambuc if (Tok.is(tok::semi)) { 1519*f4a2713aSLionel Sambuc ConsumeToken(); 1520*f4a2713aSLionel Sambuc } else if (ForEach) { 1521*f4a2713aSLionel Sambuc ConsumeToken(); // consume 'in' 1522*f4a2713aSLionel Sambuc 1523*f4a2713aSLionel Sambuc if (Tok.is(tok::code_completion)) { 1524*f4a2713aSLionel Sambuc Actions.CodeCompleteObjCForCollection(getCurScope(), DeclGroupPtrTy()); 1525*f4a2713aSLionel Sambuc cutOffParsing(); 1526*f4a2713aSLionel Sambuc return StmtError(); 1527*f4a2713aSLionel Sambuc } 1528*f4a2713aSLionel Sambuc Collection = ParseExpression(); 1529*f4a2713aSLionel Sambuc } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::colon) && FirstPart.get()) { 1530*f4a2713aSLionel Sambuc // User tried to write the reasonable, but ill-formed, for-range-statement 1531*f4a2713aSLionel Sambuc // for (expr : expr) { ... } 1532*f4a2713aSLionel Sambuc Diag(Tok, diag::err_for_range_expected_decl) 1533*f4a2713aSLionel Sambuc << FirstPart.get()->getSourceRange(); 1534*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopBeforeMatch); 1535*f4a2713aSLionel Sambuc SecondPartIsInvalid = true; 1536*f4a2713aSLionel Sambuc } else { 1537*f4a2713aSLionel Sambuc if (!Value.isInvalid()) { 1538*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_semi_for); 1539*f4a2713aSLionel Sambuc } else { 1540*f4a2713aSLionel Sambuc // Skip until semicolon or rparen, don't consume it. 1541*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch); 1542*f4a2713aSLionel Sambuc if (Tok.is(tok::semi)) 1543*f4a2713aSLionel Sambuc ConsumeToken(); 1544*f4a2713aSLionel Sambuc } 1545*f4a2713aSLionel Sambuc } 1546*f4a2713aSLionel Sambuc } 1547*f4a2713aSLionel Sambuc if (!ForEach && !ForRange) { 1548*f4a2713aSLionel Sambuc assert(!SecondPart.get() && "Shouldn't have a second expression yet."); 1549*f4a2713aSLionel Sambuc // Parse the second part of the for specifier. 1550*f4a2713aSLionel Sambuc if (Tok.is(tok::semi)) { // for (...;; 1551*f4a2713aSLionel Sambuc // no second part. 1552*f4a2713aSLionel Sambuc } else if (Tok.is(tok::r_paren)) { 1553*f4a2713aSLionel Sambuc // missing both semicolons. 1554*f4a2713aSLionel Sambuc } else { 1555*f4a2713aSLionel Sambuc ExprResult Second; 1556*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus) 1557*f4a2713aSLionel Sambuc ParseCXXCondition(Second, SecondVar, ForLoc, true); 1558*f4a2713aSLionel Sambuc else { 1559*f4a2713aSLionel Sambuc Second = ParseExpression(); 1560*f4a2713aSLionel Sambuc if (!Second.isInvalid()) 1561*f4a2713aSLionel Sambuc Second = Actions.ActOnBooleanCondition(getCurScope(), ForLoc, 1562*f4a2713aSLionel Sambuc Second.get()); 1563*f4a2713aSLionel Sambuc } 1564*f4a2713aSLionel Sambuc SecondPartIsInvalid = Second.isInvalid(); 1565*f4a2713aSLionel Sambuc SecondPart = Actions.MakeFullExpr(Second.get(), ForLoc); 1566*f4a2713aSLionel Sambuc } 1567*f4a2713aSLionel Sambuc 1568*f4a2713aSLionel Sambuc if (Tok.isNot(tok::semi)) { 1569*f4a2713aSLionel Sambuc if (!SecondPartIsInvalid || SecondVar) 1570*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_semi_for); 1571*f4a2713aSLionel Sambuc else 1572*f4a2713aSLionel Sambuc // Skip until semicolon or rparen, don't consume it. 1573*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch); 1574*f4a2713aSLionel Sambuc } 1575*f4a2713aSLionel Sambuc 1576*f4a2713aSLionel Sambuc if (Tok.is(tok::semi)) { 1577*f4a2713aSLionel Sambuc ConsumeToken(); 1578*f4a2713aSLionel Sambuc } 1579*f4a2713aSLionel Sambuc 1580*f4a2713aSLionel Sambuc // Parse the third part of the for specifier. 1581*f4a2713aSLionel Sambuc if (Tok.isNot(tok::r_paren)) { // for (...;...;) 1582*f4a2713aSLionel Sambuc ExprResult Third = ParseExpression(); 1583*f4a2713aSLionel Sambuc // FIXME: The C++11 standard doesn't actually say that this is a 1584*f4a2713aSLionel Sambuc // discarded-value expression, but it clearly should be. 1585*f4a2713aSLionel Sambuc ThirdPart = Actions.MakeFullDiscardedValueExpr(Third.take()); 1586*f4a2713aSLionel Sambuc } 1587*f4a2713aSLionel Sambuc } 1588*f4a2713aSLionel Sambuc // Match the ')'. 1589*f4a2713aSLionel Sambuc T.consumeClose(); 1590*f4a2713aSLionel Sambuc 1591*f4a2713aSLionel Sambuc // We need to perform most of the semantic analysis for a C++0x for-range 1592*f4a2713aSLionel Sambuc // statememt before parsing the body, in order to be able to deduce the type 1593*f4a2713aSLionel Sambuc // of an auto-typed loop variable. 1594*f4a2713aSLionel Sambuc StmtResult ForRangeStmt; 1595*f4a2713aSLionel Sambuc StmtResult ForEachStmt; 1596*f4a2713aSLionel Sambuc 1597*f4a2713aSLionel Sambuc if (ForRange) { 1598*f4a2713aSLionel Sambuc ForRangeStmt = Actions.ActOnCXXForRangeStmt(ForLoc, FirstPart.take(), 1599*f4a2713aSLionel Sambuc ForRangeInit.ColonLoc, 1600*f4a2713aSLionel Sambuc ForRangeInit.RangeExpr.get(), 1601*f4a2713aSLionel Sambuc T.getCloseLocation(), 1602*f4a2713aSLionel Sambuc Sema::BFRK_Build); 1603*f4a2713aSLionel Sambuc 1604*f4a2713aSLionel Sambuc 1605*f4a2713aSLionel Sambuc // Similarly, we need to do the semantic analysis for a for-range 1606*f4a2713aSLionel Sambuc // statement immediately in order to close over temporaries correctly. 1607*f4a2713aSLionel Sambuc } else if (ForEach) { 1608*f4a2713aSLionel Sambuc ForEachStmt = Actions.ActOnObjCForCollectionStmt(ForLoc, 1609*f4a2713aSLionel Sambuc FirstPart.take(), 1610*f4a2713aSLionel Sambuc Collection.take(), 1611*f4a2713aSLionel Sambuc T.getCloseLocation()); 1612*f4a2713aSLionel Sambuc } 1613*f4a2713aSLionel Sambuc 1614*f4a2713aSLionel Sambuc // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if 1615*f4a2713aSLionel Sambuc // there is no compound stmt. C90 does not have this clause. We only do this 1616*f4a2713aSLionel Sambuc // if the body isn't a compound statement to avoid push/pop in common cases. 1617*f4a2713aSLionel Sambuc // 1618*f4a2713aSLionel Sambuc // C++ 6.5p2: 1619*f4a2713aSLionel Sambuc // The substatement in an iteration-statement implicitly defines a local scope 1620*f4a2713aSLionel Sambuc // which is entered and exited each time through the loop. 1621*f4a2713aSLionel Sambuc // 1622*f4a2713aSLionel Sambuc // See comments in ParseIfStatement for why we create a scope for 1623*f4a2713aSLionel Sambuc // for-init-statement/condition and a new scope for substatement in C++. 1624*f4a2713aSLionel Sambuc // 1625*f4a2713aSLionel Sambuc ParseScope InnerScope(this, Scope::DeclScope, 1626*f4a2713aSLionel Sambuc C99orCXXorObjC && Tok.isNot(tok::l_brace)); 1627*f4a2713aSLionel Sambuc 1628*f4a2713aSLionel Sambuc // Read the body statement. 1629*f4a2713aSLionel Sambuc StmtResult Body(ParseStatement(TrailingElseLoc)); 1630*f4a2713aSLionel Sambuc 1631*f4a2713aSLionel Sambuc // Pop the body scope if needed. 1632*f4a2713aSLionel Sambuc InnerScope.Exit(); 1633*f4a2713aSLionel Sambuc 1634*f4a2713aSLionel Sambuc // Leave the for-scope. 1635*f4a2713aSLionel Sambuc ForScope.Exit(); 1636*f4a2713aSLionel Sambuc 1637*f4a2713aSLionel Sambuc if (Body.isInvalid()) 1638*f4a2713aSLionel Sambuc return StmtError(); 1639*f4a2713aSLionel Sambuc 1640*f4a2713aSLionel Sambuc if (ForEach) 1641*f4a2713aSLionel Sambuc return Actions.FinishObjCForCollectionStmt(ForEachStmt.take(), 1642*f4a2713aSLionel Sambuc Body.take()); 1643*f4a2713aSLionel Sambuc 1644*f4a2713aSLionel Sambuc if (ForRange) 1645*f4a2713aSLionel Sambuc return Actions.FinishCXXForRangeStmt(ForRangeStmt.take(), Body.take()); 1646*f4a2713aSLionel Sambuc 1647*f4a2713aSLionel Sambuc return Actions.ActOnForStmt(ForLoc, T.getOpenLocation(), FirstPart.take(), 1648*f4a2713aSLionel Sambuc SecondPart, SecondVar, ThirdPart, 1649*f4a2713aSLionel Sambuc T.getCloseLocation(), Body.take()); 1650*f4a2713aSLionel Sambuc } 1651*f4a2713aSLionel Sambuc 1652*f4a2713aSLionel Sambuc /// ParseGotoStatement 1653*f4a2713aSLionel Sambuc /// jump-statement: 1654*f4a2713aSLionel Sambuc /// 'goto' identifier ';' 1655*f4a2713aSLionel Sambuc /// [GNU] 'goto' '*' expression ';' 1656*f4a2713aSLionel Sambuc /// 1657*f4a2713aSLionel Sambuc /// Note: this lets the caller parse the end ';'. 1658*f4a2713aSLionel Sambuc /// 1659*f4a2713aSLionel Sambuc StmtResult Parser::ParseGotoStatement() { 1660*f4a2713aSLionel Sambuc assert(Tok.is(tok::kw_goto) && "Not a goto stmt!"); 1661*f4a2713aSLionel Sambuc SourceLocation GotoLoc = ConsumeToken(); // eat the 'goto'. 1662*f4a2713aSLionel Sambuc 1663*f4a2713aSLionel Sambuc StmtResult Res; 1664*f4a2713aSLionel Sambuc if (Tok.is(tok::identifier)) { 1665*f4a2713aSLionel Sambuc LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(), 1666*f4a2713aSLionel Sambuc Tok.getLocation()); 1667*f4a2713aSLionel Sambuc Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(), LD); 1668*f4a2713aSLionel Sambuc ConsumeToken(); 1669*f4a2713aSLionel Sambuc } else if (Tok.is(tok::star)) { 1670*f4a2713aSLionel Sambuc // GNU indirect goto extension. 1671*f4a2713aSLionel Sambuc Diag(Tok, diag::ext_gnu_indirect_goto); 1672*f4a2713aSLionel Sambuc SourceLocation StarLoc = ConsumeToken(); 1673*f4a2713aSLionel Sambuc ExprResult R(ParseExpression()); 1674*f4a2713aSLionel Sambuc if (R.isInvalid()) { // Skip to the semicolon, but don't consume it. 1675*f4a2713aSLionel Sambuc SkipUntil(tok::semi, StopBeforeMatch); 1676*f4a2713aSLionel Sambuc return StmtError(); 1677*f4a2713aSLionel Sambuc } 1678*f4a2713aSLionel Sambuc Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.take()); 1679*f4a2713aSLionel Sambuc } else { 1680*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_ident); 1681*f4a2713aSLionel Sambuc return StmtError(); 1682*f4a2713aSLionel Sambuc } 1683*f4a2713aSLionel Sambuc 1684*f4a2713aSLionel Sambuc return Res; 1685*f4a2713aSLionel Sambuc } 1686*f4a2713aSLionel Sambuc 1687*f4a2713aSLionel Sambuc /// ParseContinueStatement 1688*f4a2713aSLionel Sambuc /// jump-statement: 1689*f4a2713aSLionel Sambuc /// 'continue' ';' 1690*f4a2713aSLionel Sambuc /// 1691*f4a2713aSLionel Sambuc /// Note: this lets the caller parse the end ';'. 1692*f4a2713aSLionel Sambuc /// 1693*f4a2713aSLionel Sambuc StmtResult Parser::ParseContinueStatement() { 1694*f4a2713aSLionel Sambuc SourceLocation ContinueLoc = ConsumeToken(); // eat the 'continue'. 1695*f4a2713aSLionel Sambuc return Actions.ActOnContinueStmt(ContinueLoc, getCurScope()); 1696*f4a2713aSLionel Sambuc } 1697*f4a2713aSLionel Sambuc 1698*f4a2713aSLionel Sambuc /// ParseBreakStatement 1699*f4a2713aSLionel Sambuc /// jump-statement: 1700*f4a2713aSLionel Sambuc /// 'break' ';' 1701*f4a2713aSLionel Sambuc /// 1702*f4a2713aSLionel Sambuc /// Note: this lets the caller parse the end ';'. 1703*f4a2713aSLionel Sambuc /// 1704*f4a2713aSLionel Sambuc StmtResult Parser::ParseBreakStatement() { 1705*f4a2713aSLionel Sambuc SourceLocation BreakLoc = ConsumeToken(); // eat the 'break'. 1706*f4a2713aSLionel Sambuc return Actions.ActOnBreakStmt(BreakLoc, getCurScope()); 1707*f4a2713aSLionel Sambuc } 1708*f4a2713aSLionel Sambuc 1709*f4a2713aSLionel Sambuc /// ParseReturnStatement 1710*f4a2713aSLionel Sambuc /// jump-statement: 1711*f4a2713aSLionel Sambuc /// 'return' expression[opt] ';' 1712*f4a2713aSLionel Sambuc StmtResult Parser::ParseReturnStatement() { 1713*f4a2713aSLionel Sambuc assert(Tok.is(tok::kw_return) && "Not a return stmt!"); 1714*f4a2713aSLionel Sambuc SourceLocation ReturnLoc = ConsumeToken(); // eat the 'return'. 1715*f4a2713aSLionel Sambuc 1716*f4a2713aSLionel Sambuc ExprResult R; 1717*f4a2713aSLionel Sambuc if (Tok.isNot(tok::semi)) { 1718*f4a2713aSLionel Sambuc if (Tok.is(tok::code_completion)) { 1719*f4a2713aSLionel Sambuc Actions.CodeCompleteReturn(getCurScope()); 1720*f4a2713aSLionel Sambuc cutOffParsing(); 1721*f4a2713aSLionel Sambuc return StmtError(); 1722*f4a2713aSLionel Sambuc } 1723*f4a2713aSLionel Sambuc 1724*f4a2713aSLionel Sambuc if (Tok.is(tok::l_brace) && getLangOpts().CPlusPlus) { 1725*f4a2713aSLionel Sambuc R = ParseInitializer(); 1726*f4a2713aSLionel Sambuc if (R.isUsable()) 1727*f4a2713aSLionel Sambuc Diag(R.get()->getLocStart(), getLangOpts().CPlusPlus11 ? 1728*f4a2713aSLionel Sambuc diag::warn_cxx98_compat_generalized_initializer_lists : 1729*f4a2713aSLionel Sambuc diag::ext_generalized_initializer_lists) 1730*f4a2713aSLionel Sambuc << R.get()->getSourceRange(); 1731*f4a2713aSLionel Sambuc } else 1732*f4a2713aSLionel Sambuc R = ParseExpression(); 1733*f4a2713aSLionel Sambuc if (R.isInvalid()) { // Skip to the semicolon, but don't consume it. 1734*f4a2713aSLionel Sambuc SkipUntil(tok::semi, StopBeforeMatch); 1735*f4a2713aSLionel Sambuc return StmtError(); 1736*f4a2713aSLionel Sambuc } 1737*f4a2713aSLionel Sambuc } 1738*f4a2713aSLionel Sambuc return Actions.ActOnReturnStmt(ReturnLoc, R.take()); 1739*f4a2713aSLionel Sambuc } 1740*f4a2713aSLionel Sambuc 1741*f4a2713aSLionel Sambuc namespace { 1742*f4a2713aSLionel Sambuc class ClangAsmParserCallback : public llvm::MCAsmParserSemaCallback { 1743*f4a2713aSLionel Sambuc Parser &TheParser; 1744*f4a2713aSLionel Sambuc SourceLocation AsmLoc; 1745*f4a2713aSLionel Sambuc StringRef AsmString; 1746*f4a2713aSLionel Sambuc 1747*f4a2713aSLionel Sambuc /// The tokens we streamed into AsmString and handed off to MC. 1748*f4a2713aSLionel Sambuc ArrayRef<Token> AsmToks; 1749*f4a2713aSLionel Sambuc 1750*f4a2713aSLionel Sambuc /// The offset of each token in AsmToks within AsmString. 1751*f4a2713aSLionel Sambuc ArrayRef<unsigned> AsmTokOffsets; 1752*f4a2713aSLionel Sambuc 1753*f4a2713aSLionel Sambuc public: 1754*f4a2713aSLionel Sambuc ClangAsmParserCallback(Parser &P, SourceLocation Loc, 1755*f4a2713aSLionel Sambuc StringRef AsmString, 1756*f4a2713aSLionel Sambuc ArrayRef<Token> Toks, 1757*f4a2713aSLionel Sambuc ArrayRef<unsigned> Offsets) 1758*f4a2713aSLionel Sambuc : TheParser(P), AsmLoc(Loc), AsmString(AsmString), 1759*f4a2713aSLionel Sambuc AsmToks(Toks), AsmTokOffsets(Offsets) { 1760*f4a2713aSLionel Sambuc assert(AsmToks.size() == AsmTokOffsets.size()); 1761*f4a2713aSLionel Sambuc } 1762*f4a2713aSLionel Sambuc 1763*f4a2713aSLionel Sambuc void *LookupInlineAsmIdentifier(StringRef &LineBuf, 1764*f4a2713aSLionel Sambuc InlineAsmIdentifierInfo &Info, 1765*f4a2713aSLionel Sambuc bool IsUnevaluatedContext) { 1766*f4a2713aSLionel Sambuc // Collect the desired tokens. 1767*f4a2713aSLionel Sambuc SmallVector<Token, 16> LineToks; 1768*f4a2713aSLionel Sambuc const Token *FirstOrigToken = 0; 1769*f4a2713aSLionel Sambuc findTokensForString(LineBuf, LineToks, FirstOrigToken); 1770*f4a2713aSLionel Sambuc 1771*f4a2713aSLionel Sambuc unsigned NumConsumedToks; 1772*f4a2713aSLionel Sambuc ExprResult Result = 1773*f4a2713aSLionel Sambuc TheParser.ParseMSAsmIdentifier(LineToks, NumConsumedToks, &Info, 1774*f4a2713aSLionel Sambuc IsUnevaluatedContext); 1775*f4a2713aSLionel Sambuc 1776*f4a2713aSLionel Sambuc // If we consumed the entire line, tell MC that. 1777*f4a2713aSLionel Sambuc // Also do this if we consumed nothing as a way of reporting failure. 1778*f4a2713aSLionel Sambuc if (NumConsumedToks == 0 || NumConsumedToks == LineToks.size()) { 1779*f4a2713aSLionel Sambuc // By not modifying LineBuf, we're implicitly consuming it all. 1780*f4a2713aSLionel Sambuc 1781*f4a2713aSLionel Sambuc // Otherwise, consume up to the original tokens. 1782*f4a2713aSLionel Sambuc } else { 1783*f4a2713aSLionel Sambuc assert(FirstOrigToken && "not using original tokens?"); 1784*f4a2713aSLionel Sambuc 1785*f4a2713aSLionel Sambuc // Since we're using original tokens, apply that offset. 1786*f4a2713aSLionel Sambuc assert(FirstOrigToken[NumConsumedToks].getLocation() 1787*f4a2713aSLionel Sambuc == LineToks[NumConsumedToks].getLocation()); 1788*f4a2713aSLionel Sambuc unsigned FirstIndex = FirstOrigToken - AsmToks.begin(); 1789*f4a2713aSLionel Sambuc unsigned LastIndex = FirstIndex + NumConsumedToks - 1; 1790*f4a2713aSLionel Sambuc 1791*f4a2713aSLionel Sambuc // The total length we've consumed is the relative offset 1792*f4a2713aSLionel Sambuc // of the last token we consumed plus its length. 1793*f4a2713aSLionel Sambuc unsigned TotalOffset = (AsmTokOffsets[LastIndex] 1794*f4a2713aSLionel Sambuc + AsmToks[LastIndex].getLength() 1795*f4a2713aSLionel Sambuc - AsmTokOffsets[FirstIndex]); 1796*f4a2713aSLionel Sambuc LineBuf = LineBuf.substr(0, TotalOffset); 1797*f4a2713aSLionel Sambuc } 1798*f4a2713aSLionel Sambuc 1799*f4a2713aSLionel Sambuc // Initialize the "decl" with the lookup result. 1800*f4a2713aSLionel Sambuc Info.OpDecl = static_cast<void*>(Result.take()); 1801*f4a2713aSLionel Sambuc return Info.OpDecl; 1802*f4a2713aSLionel Sambuc } 1803*f4a2713aSLionel Sambuc 1804*f4a2713aSLionel Sambuc bool LookupInlineAsmField(StringRef Base, StringRef Member, 1805*f4a2713aSLionel Sambuc unsigned &Offset) { 1806*f4a2713aSLionel Sambuc return TheParser.getActions().LookupInlineAsmField(Base, Member, 1807*f4a2713aSLionel Sambuc Offset, AsmLoc); 1808*f4a2713aSLionel Sambuc } 1809*f4a2713aSLionel Sambuc 1810*f4a2713aSLionel Sambuc static void DiagHandlerCallback(const llvm::SMDiagnostic &D, 1811*f4a2713aSLionel Sambuc void *Context) { 1812*f4a2713aSLionel Sambuc ((ClangAsmParserCallback*) Context)->handleDiagnostic(D); 1813*f4a2713aSLionel Sambuc } 1814*f4a2713aSLionel Sambuc 1815*f4a2713aSLionel Sambuc private: 1816*f4a2713aSLionel Sambuc /// Collect the appropriate tokens for the given string. 1817*f4a2713aSLionel Sambuc void findTokensForString(StringRef Str, SmallVectorImpl<Token> &TempToks, 1818*f4a2713aSLionel Sambuc const Token *&FirstOrigToken) const { 1819*f4a2713aSLionel Sambuc // For now, assert that the string we're working with is a substring 1820*f4a2713aSLionel Sambuc // of what we gave to MC. This lets us use the original tokens. 1821*f4a2713aSLionel Sambuc assert(!std::less<const char*>()(Str.begin(), AsmString.begin()) && 1822*f4a2713aSLionel Sambuc !std::less<const char*>()(AsmString.end(), Str.end())); 1823*f4a2713aSLionel Sambuc 1824*f4a2713aSLionel Sambuc // Try to find a token whose offset matches the first token. 1825*f4a2713aSLionel Sambuc unsigned FirstCharOffset = Str.begin() - AsmString.begin(); 1826*f4a2713aSLionel Sambuc const unsigned *FirstTokOffset 1827*f4a2713aSLionel Sambuc = std::lower_bound(AsmTokOffsets.begin(), AsmTokOffsets.end(), 1828*f4a2713aSLionel Sambuc FirstCharOffset); 1829*f4a2713aSLionel Sambuc 1830*f4a2713aSLionel Sambuc // For now, assert that the start of the string exactly 1831*f4a2713aSLionel Sambuc // corresponds to the start of a token. 1832*f4a2713aSLionel Sambuc assert(*FirstTokOffset == FirstCharOffset); 1833*f4a2713aSLionel Sambuc 1834*f4a2713aSLionel Sambuc // Use all the original tokens for this line. (We assume the 1835*f4a2713aSLionel Sambuc // end of the line corresponds cleanly to a token break.) 1836*f4a2713aSLionel Sambuc unsigned FirstTokIndex = FirstTokOffset - AsmTokOffsets.begin(); 1837*f4a2713aSLionel Sambuc FirstOrigToken = &AsmToks[FirstTokIndex]; 1838*f4a2713aSLionel Sambuc unsigned LastCharOffset = Str.end() - AsmString.begin(); 1839*f4a2713aSLionel Sambuc for (unsigned i = FirstTokIndex, e = AsmTokOffsets.size(); i != e; ++i) { 1840*f4a2713aSLionel Sambuc if (AsmTokOffsets[i] >= LastCharOffset) break; 1841*f4a2713aSLionel Sambuc TempToks.push_back(AsmToks[i]); 1842*f4a2713aSLionel Sambuc } 1843*f4a2713aSLionel Sambuc } 1844*f4a2713aSLionel Sambuc 1845*f4a2713aSLionel Sambuc void handleDiagnostic(const llvm::SMDiagnostic &D) { 1846*f4a2713aSLionel Sambuc // Compute an offset into the inline asm buffer. 1847*f4a2713aSLionel Sambuc // FIXME: This isn't right if .macro is involved (but hopefully, no 1848*f4a2713aSLionel Sambuc // real-world code does that). 1849*f4a2713aSLionel Sambuc const llvm::SourceMgr &LSM = *D.getSourceMgr(); 1850*f4a2713aSLionel Sambuc const llvm::MemoryBuffer *LBuf = 1851*f4a2713aSLionel Sambuc LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc())); 1852*f4a2713aSLionel Sambuc unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart(); 1853*f4a2713aSLionel Sambuc 1854*f4a2713aSLionel Sambuc // Figure out which token that offset points into. 1855*f4a2713aSLionel Sambuc const unsigned *TokOffsetPtr = 1856*f4a2713aSLionel Sambuc std::lower_bound(AsmTokOffsets.begin(), AsmTokOffsets.end(), Offset); 1857*f4a2713aSLionel Sambuc unsigned TokIndex = TokOffsetPtr - AsmTokOffsets.begin(); 1858*f4a2713aSLionel Sambuc unsigned TokOffset = *TokOffsetPtr; 1859*f4a2713aSLionel Sambuc 1860*f4a2713aSLionel Sambuc // If we come up with an answer which seems sane, use it; otherwise, 1861*f4a2713aSLionel Sambuc // just point at the __asm keyword. 1862*f4a2713aSLionel Sambuc // FIXME: Assert the answer is sane once we handle .macro correctly. 1863*f4a2713aSLionel Sambuc SourceLocation Loc = AsmLoc; 1864*f4a2713aSLionel Sambuc if (TokIndex < AsmToks.size()) { 1865*f4a2713aSLionel Sambuc const Token &Tok = AsmToks[TokIndex]; 1866*f4a2713aSLionel Sambuc Loc = Tok.getLocation(); 1867*f4a2713aSLionel Sambuc Loc = Loc.getLocWithOffset(Offset - TokOffset); 1868*f4a2713aSLionel Sambuc } 1869*f4a2713aSLionel Sambuc TheParser.Diag(Loc, diag::err_inline_ms_asm_parsing) 1870*f4a2713aSLionel Sambuc << D.getMessage(); 1871*f4a2713aSLionel Sambuc } 1872*f4a2713aSLionel Sambuc }; 1873*f4a2713aSLionel Sambuc } 1874*f4a2713aSLionel Sambuc 1875*f4a2713aSLionel Sambuc /// Parse an identifier in an MS-style inline assembly block. 1876*f4a2713aSLionel Sambuc /// 1877*f4a2713aSLionel Sambuc /// \param CastInfo - a void* so that we don't have to teach Parser.h 1878*f4a2713aSLionel Sambuc /// about the actual type. 1879*f4a2713aSLionel Sambuc ExprResult Parser::ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks, 1880*f4a2713aSLionel Sambuc unsigned &NumLineToksConsumed, 1881*f4a2713aSLionel Sambuc void *CastInfo, 1882*f4a2713aSLionel Sambuc bool IsUnevaluatedContext) { 1883*f4a2713aSLionel Sambuc llvm::InlineAsmIdentifierInfo &Info = 1884*f4a2713aSLionel Sambuc *(llvm::InlineAsmIdentifierInfo *) CastInfo; 1885*f4a2713aSLionel Sambuc 1886*f4a2713aSLionel Sambuc // Push a fake token on the end so that we don't overrun the token 1887*f4a2713aSLionel Sambuc // stream. We use ';' because it expression-parsing should never 1888*f4a2713aSLionel Sambuc // overrun it. 1889*f4a2713aSLionel Sambuc const tok::TokenKind EndOfStream = tok::semi; 1890*f4a2713aSLionel Sambuc Token EndOfStreamTok; 1891*f4a2713aSLionel Sambuc EndOfStreamTok.startToken(); 1892*f4a2713aSLionel Sambuc EndOfStreamTok.setKind(EndOfStream); 1893*f4a2713aSLionel Sambuc LineToks.push_back(EndOfStreamTok); 1894*f4a2713aSLionel Sambuc 1895*f4a2713aSLionel Sambuc // Also copy the current token over. 1896*f4a2713aSLionel Sambuc LineToks.push_back(Tok); 1897*f4a2713aSLionel Sambuc 1898*f4a2713aSLionel Sambuc PP.EnterTokenStream(LineToks.begin(), 1899*f4a2713aSLionel Sambuc LineToks.size(), 1900*f4a2713aSLionel Sambuc /*disable macros*/ true, 1901*f4a2713aSLionel Sambuc /*owns tokens*/ false); 1902*f4a2713aSLionel Sambuc 1903*f4a2713aSLionel Sambuc // Clear the current token and advance to the first token in LineToks. 1904*f4a2713aSLionel Sambuc ConsumeAnyToken(); 1905*f4a2713aSLionel Sambuc 1906*f4a2713aSLionel Sambuc // Parse an optional scope-specifier if we're in C++. 1907*f4a2713aSLionel Sambuc CXXScopeSpec SS; 1908*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus) { 1909*f4a2713aSLionel Sambuc ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); 1910*f4a2713aSLionel Sambuc } 1911*f4a2713aSLionel Sambuc 1912*f4a2713aSLionel Sambuc // Require an identifier here. 1913*f4a2713aSLionel Sambuc SourceLocation TemplateKWLoc; 1914*f4a2713aSLionel Sambuc UnqualifiedId Id; 1915*f4a2713aSLionel Sambuc bool Invalid = ParseUnqualifiedId(SS, 1916*f4a2713aSLionel Sambuc /*EnteringContext=*/false, 1917*f4a2713aSLionel Sambuc /*AllowDestructorName=*/false, 1918*f4a2713aSLionel Sambuc /*AllowConstructorName=*/false, 1919*f4a2713aSLionel Sambuc /*ObjectType=*/ ParsedType(), 1920*f4a2713aSLionel Sambuc TemplateKWLoc, 1921*f4a2713aSLionel Sambuc Id); 1922*f4a2713aSLionel Sambuc 1923*f4a2713aSLionel Sambuc // If we've run into the poison token we inserted before, or there 1924*f4a2713aSLionel Sambuc // was a parsing error, then claim the entire line. 1925*f4a2713aSLionel Sambuc if (Invalid || Tok.is(EndOfStream)) { 1926*f4a2713aSLionel Sambuc NumLineToksConsumed = LineToks.size() - 2; 1927*f4a2713aSLionel Sambuc 1928*f4a2713aSLionel Sambuc // Otherwise, claim up to the start of the next token. 1929*f4a2713aSLionel Sambuc } else { 1930*f4a2713aSLionel Sambuc // Figure out how many tokens we are into LineToks. 1931*f4a2713aSLionel Sambuc unsigned LineIndex = 0; 1932*f4a2713aSLionel Sambuc while (LineToks[LineIndex].getLocation() != Tok.getLocation()) { 1933*f4a2713aSLionel Sambuc LineIndex++; 1934*f4a2713aSLionel Sambuc assert(LineIndex < LineToks.size() - 2); // we added two extra tokens 1935*f4a2713aSLionel Sambuc } 1936*f4a2713aSLionel Sambuc 1937*f4a2713aSLionel Sambuc NumLineToksConsumed = LineIndex; 1938*f4a2713aSLionel Sambuc } 1939*f4a2713aSLionel Sambuc 1940*f4a2713aSLionel Sambuc // Finally, restore the old parsing state by consuming all the 1941*f4a2713aSLionel Sambuc // tokens we staged before, implicitly killing off the 1942*f4a2713aSLionel Sambuc // token-lexer we pushed. 1943*f4a2713aSLionel Sambuc for (unsigned n = LineToks.size() - 2 - NumLineToksConsumed; n != 0; --n) { 1944*f4a2713aSLionel Sambuc ConsumeAnyToken(); 1945*f4a2713aSLionel Sambuc } 1946*f4a2713aSLionel Sambuc ConsumeToken(EndOfStream); 1947*f4a2713aSLionel Sambuc 1948*f4a2713aSLionel Sambuc // Leave LineToks in its original state. 1949*f4a2713aSLionel Sambuc LineToks.pop_back(); 1950*f4a2713aSLionel Sambuc LineToks.pop_back(); 1951*f4a2713aSLionel Sambuc 1952*f4a2713aSLionel Sambuc // Perform the lookup. 1953*f4a2713aSLionel Sambuc return Actions.LookupInlineAsmIdentifier(SS, TemplateKWLoc, Id, Info, 1954*f4a2713aSLionel Sambuc IsUnevaluatedContext); 1955*f4a2713aSLionel Sambuc } 1956*f4a2713aSLionel Sambuc 1957*f4a2713aSLionel Sambuc /// Turn a sequence of our tokens back into a string that we can hand 1958*f4a2713aSLionel Sambuc /// to the MC asm parser. 1959*f4a2713aSLionel Sambuc static bool buildMSAsmString(Preprocessor &PP, 1960*f4a2713aSLionel Sambuc SourceLocation AsmLoc, 1961*f4a2713aSLionel Sambuc ArrayRef<Token> AsmToks, 1962*f4a2713aSLionel Sambuc SmallVectorImpl<unsigned> &TokOffsets, 1963*f4a2713aSLionel Sambuc SmallString<512> &Asm) { 1964*f4a2713aSLionel Sambuc assert (!AsmToks.empty() && "Didn't expect an empty AsmToks!"); 1965*f4a2713aSLionel Sambuc 1966*f4a2713aSLionel Sambuc // Is this the start of a new assembly statement? 1967*f4a2713aSLionel Sambuc bool isNewStatement = true; 1968*f4a2713aSLionel Sambuc 1969*f4a2713aSLionel Sambuc for (unsigned i = 0, e = AsmToks.size(); i < e; ++i) { 1970*f4a2713aSLionel Sambuc const Token &Tok = AsmToks[i]; 1971*f4a2713aSLionel Sambuc 1972*f4a2713aSLionel Sambuc // Start each new statement with a newline and a tab. 1973*f4a2713aSLionel Sambuc if (!isNewStatement && 1974*f4a2713aSLionel Sambuc (Tok.is(tok::kw_asm) || Tok.isAtStartOfLine())) { 1975*f4a2713aSLionel Sambuc Asm += "\n\t"; 1976*f4a2713aSLionel Sambuc isNewStatement = true; 1977*f4a2713aSLionel Sambuc } 1978*f4a2713aSLionel Sambuc 1979*f4a2713aSLionel Sambuc // Preserve the existence of leading whitespace except at the 1980*f4a2713aSLionel Sambuc // start of a statement. 1981*f4a2713aSLionel Sambuc if (!isNewStatement && Tok.hasLeadingSpace()) 1982*f4a2713aSLionel Sambuc Asm += ' '; 1983*f4a2713aSLionel Sambuc 1984*f4a2713aSLionel Sambuc // Remember the offset of this token. 1985*f4a2713aSLionel Sambuc TokOffsets.push_back(Asm.size()); 1986*f4a2713aSLionel Sambuc 1987*f4a2713aSLionel Sambuc // Don't actually write '__asm' into the assembly stream. 1988*f4a2713aSLionel Sambuc if (Tok.is(tok::kw_asm)) { 1989*f4a2713aSLionel Sambuc // Complain about __asm at the end of the stream. 1990*f4a2713aSLionel Sambuc if (i + 1 == e) { 1991*f4a2713aSLionel Sambuc PP.Diag(AsmLoc, diag::err_asm_empty); 1992*f4a2713aSLionel Sambuc return true; 1993*f4a2713aSLionel Sambuc } 1994*f4a2713aSLionel Sambuc 1995*f4a2713aSLionel Sambuc continue; 1996*f4a2713aSLionel Sambuc } 1997*f4a2713aSLionel Sambuc 1998*f4a2713aSLionel Sambuc // Append the spelling of the token. 1999*f4a2713aSLionel Sambuc SmallString<32> SpellingBuffer; 2000*f4a2713aSLionel Sambuc bool SpellingInvalid = false; 2001*f4a2713aSLionel Sambuc Asm += PP.getSpelling(Tok, SpellingBuffer, &SpellingInvalid); 2002*f4a2713aSLionel Sambuc assert(!SpellingInvalid && "spelling was invalid after correct parse?"); 2003*f4a2713aSLionel Sambuc 2004*f4a2713aSLionel Sambuc // We are no longer at the start of a statement. 2005*f4a2713aSLionel Sambuc isNewStatement = false; 2006*f4a2713aSLionel Sambuc } 2007*f4a2713aSLionel Sambuc 2008*f4a2713aSLionel Sambuc // Ensure that the buffer is null-terminated. 2009*f4a2713aSLionel Sambuc Asm.push_back('\0'); 2010*f4a2713aSLionel Sambuc Asm.pop_back(); 2011*f4a2713aSLionel Sambuc 2012*f4a2713aSLionel Sambuc assert(TokOffsets.size() == AsmToks.size()); 2013*f4a2713aSLionel Sambuc return false; 2014*f4a2713aSLionel Sambuc } 2015*f4a2713aSLionel Sambuc 2016*f4a2713aSLionel Sambuc /// ParseMicrosoftAsmStatement. When -fms-extensions/-fasm-blocks is enabled, 2017*f4a2713aSLionel Sambuc /// this routine is called to collect the tokens for an MS asm statement. 2018*f4a2713aSLionel Sambuc /// 2019*f4a2713aSLionel Sambuc /// [MS] ms-asm-statement: 2020*f4a2713aSLionel Sambuc /// ms-asm-block 2021*f4a2713aSLionel Sambuc /// ms-asm-block ms-asm-statement 2022*f4a2713aSLionel Sambuc /// 2023*f4a2713aSLionel Sambuc /// [MS] ms-asm-block: 2024*f4a2713aSLionel Sambuc /// '__asm' ms-asm-line '\n' 2025*f4a2713aSLionel Sambuc /// '__asm' '{' ms-asm-instruction-block[opt] '}' ';'[opt] 2026*f4a2713aSLionel Sambuc /// 2027*f4a2713aSLionel Sambuc /// [MS] ms-asm-instruction-block 2028*f4a2713aSLionel Sambuc /// ms-asm-line 2029*f4a2713aSLionel Sambuc /// ms-asm-line '\n' ms-asm-instruction-block 2030*f4a2713aSLionel Sambuc /// 2031*f4a2713aSLionel Sambuc StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) { 2032*f4a2713aSLionel Sambuc SourceManager &SrcMgr = PP.getSourceManager(); 2033*f4a2713aSLionel Sambuc SourceLocation EndLoc = AsmLoc; 2034*f4a2713aSLionel Sambuc SmallVector<Token, 4> AsmToks; 2035*f4a2713aSLionel Sambuc 2036*f4a2713aSLionel Sambuc bool InBraces = false; 2037*f4a2713aSLionel Sambuc unsigned short savedBraceCount = 0; 2038*f4a2713aSLionel Sambuc bool InAsmComment = false; 2039*f4a2713aSLionel Sambuc FileID FID; 2040*f4a2713aSLionel Sambuc unsigned LineNo = 0; 2041*f4a2713aSLionel Sambuc unsigned NumTokensRead = 0; 2042*f4a2713aSLionel Sambuc SourceLocation LBraceLoc; 2043*f4a2713aSLionel Sambuc 2044*f4a2713aSLionel Sambuc if (Tok.is(tok::l_brace)) { 2045*f4a2713aSLionel Sambuc // Braced inline asm: consume the opening brace. 2046*f4a2713aSLionel Sambuc InBraces = true; 2047*f4a2713aSLionel Sambuc savedBraceCount = BraceCount; 2048*f4a2713aSLionel Sambuc EndLoc = LBraceLoc = ConsumeBrace(); 2049*f4a2713aSLionel Sambuc ++NumTokensRead; 2050*f4a2713aSLionel Sambuc } else { 2051*f4a2713aSLionel Sambuc // Single-line inline asm; compute which line it is on. 2052*f4a2713aSLionel Sambuc std::pair<FileID, unsigned> ExpAsmLoc = 2053*f4a2713aSLionel Sambuc SrcMgr.getDecomposedExpansionLoc(EndLoc); 2054*f4a2713aSLionel Sambuc FID = ExpAsmLoc.first; 2055*f4a2713aSLionel Sambuc LineNo = SrcMgr.getLineNumber(FID, ExpAsmLoc.second); 2056*f4a2713aSLionel Sambuc } 2057*f4a2713aSLionel Sambuc 2058*f4a2713aSLionel Sambuc SourceLocation TokLoc = Tok.getLocation(); 2059*f4a2713aSLionel Sambuc do { 2060*f4a2713aSLionel Sambuc // If we hit EOF, we're done, period. 2061*f4a2713aSLionel Sambuc if (Tok.is(tok::eof)) 2062*f4a2713aSLionel Sambuc break; 2063*f4a2713aSLionel Sambuc 2064*f4a2713aSLionel Sambuc if (!InAsmComment && Tok.is(tok::semi)) { 2065*f4a2713aSLionel Sambuc // A semicolon in an asm is the start of a comment. 2066*f4a2713aSLionel Sambuc InAsmComment = true; 2067*f4a2713aSLionel Sambuc if (InBraces) { 2068*f4a2713aSLionel Sambuc // Compute which line the comment is on. 2069*f4a2713aSLionel Sambuc std::pair<FileID, unsigned> ExpSemiLoc = 2070*f4a2713aSLionel Sambuc SrcMgr.getDecomposedExpansionLoc(TokLoc); 2071*f4a2713aSLionel Sambuc FID = ExpSemiLoc.first; 2072*f4a2713aSLionel Sambuc LineNo = SrcMgr.getLineNumber(FID, ExpSemiLoc.second); 2073*f4a2713aSLionel Sambuc } 2074*f4a2713aSLionel Sambuc } else if (!InBraces || InAsmComment) { 2075*f4a2713aSLionel Sambuc // If end-of-line is significant, check whether this token is on a 2076*f4a2713aSLionel Sambuc // new line. 2077*f4a2713aSLionel Sambuc std::pair<FileID, unsigned> ExpLoc = 2078*f4a2713aSLionel Sambuc SrcMgr.getDecomposedExpansionLoc(TokLoc); 2079*f4a2713aSLionel Sambuc if (ExpLoc.first != FID || 2080*f4a2713aSLionel Sambuc SrcMgr.getLineNumber(ExpLoc.first, ExpLoc.second) != LineNo) { 2081*f4a2713aSLionel Sambuc // If this is a single-line __asm, we're done. 2082*f4a2713aSLionel Sambuc if (!InBraces) 2083*f4a2713aSLionel Sambuc break; 2084*f4a2713aSLionel Sambuc // We're no longer in a comment. 2085*f4a2713aSLionel Sambuc InAsmComment = false; 2086*f4a2713aSLionel Sambuc } else if (!InAsmComment && Tok.is(tok::r_brace)) { 2087*f4a2713aSLionel Sambuc // Single-line asm always ends when a closing brace is seen. 2088*f4a2713aSLionel Sambuc // FIXME: This is compatible with Apple gcc's -fasm-blocks; what 2089*f4a2713aSLionel Sambuc // does MSVC do here? 2090*f4a2713aSLionel Sambuc break; 2091*f4a2713aSLionel Sambuc } 2092*f4a2713aSLionel Sambuc } 2093*f4a2713aSLionel Sambuc if (!InAsmComment && InBraces && Tok.is(tok::r_brace) && 2094*f4a2713aSLionel Sambuc BraceCount == (savedBraceCount + 1)) { 2095*f4a2713aSLionel Sambuc // Consume the closing brace, and finish 2096*f4a2713aSLionel Sambuc EndLoc = ConsumeBrace(); 2097*f4a2713aSLionel Sambuc break; 2098*f4a2713aSLionel Sambuc } 2099*f4a2713aSLionel Sambuc 2100*f4a2713aSLionel Sambuc // Consume the next token; make sure we don't modify the brace count etc. 2101*f4a2713aSLionel Sambuc // if we are in a comment. 2102*f4a2713aSLionel Sambuc EndLoc = TokLoc; 2103*f4a2713aSLionel Sambuc if (InAsmComment) 2104*f4a2713aSLionel Sambuc PP.Lex(Tok); 2105*f4a2713aSLionel Sambuc else { 2106*f4a2713aSLionel Sambuc AsmToks.push_back(Tok); 2107*f4a2713aSLionel Sambuc ConsumeAnyToken(); 2108*f4a2713aSLionel Sambuc } 2109*f4a2713aSLionel Sambuc TokLoc = Tok.getLocation(); 2110*f4a2713aSLionel Sambuc ++NumTokensRead; 2111*f4a2713aSLionel Sambuc } while (1); 2112*f4a2713aSLionel Sambuc 2113*f4a2713aSLionel Sambuc if (InBraces && BraceCount != savedBraceCount) { 2114*f4a2713aSLionel Sambuc // __asm without closing brace (this can happen at EOF). 2115*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_rbrace); 2116*f4a2713aSLionel Sambuc Diag(LBraceLoc, diag::note_matching) << "{"; 2117*f4a2713aSLionel Sambuc return StmtError(); 2118*f4a2713aSLionel Sambuc } else if (NumTokensRead == 0) { 2119*f4a2713aSLionel Sambuc // Empty __asm. 2120*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_lbrace); 2121*f4a2713aSLionel Sambuc return StmtError(); 2122*f4a2713aSLionel Sambuc } 2123*f4a2713aSLionel Sambuc 2124*f4a2713aSLionel Sambuc // Okay, prepare to use MC to parse the assembly. 2125*f4a2713aSLionel Sambuc SmallVector<StringRef, 4> ConstraintRefs; 2126*f4a2713aSLionel Sambuc SmallVector<Expr*, 4> Exprs; 2127*f4a2713aSLionel Sambuc SmallVector<StringRef, 4> ClobberRefs; 2128*f4a2713aSLionel Sambuc 2129*f4a2713aSLionel Sambuc // We need an actual supported target. 2130*f4a2713aSLionel Sambuc llvm::Triple TheTriple = Actions.Context.getTargetInfo().getTriple(); 2131*f4a2713aSLionel Sambuc llvm::Triple::ArchType ArchTy = TheTriple.getArch(); 2132*f4a2713aSLionel Sambuc const std::string &TT = TheTriple.getTriple(); 2133*f4a2713aSLionel Sambuc const llvm::Target *TheTarget = 0; 2134*f4a2713aSLionel Sambuc bool UnsupportedArch = (ArchTy != llvm::Triple::x86 && 2135*f4a2713aSLionel Sambuc ArchTy != llvm::Triple::x86_64); 2136*f4a2713aSLionel Sambuc if (UnsupportedArch) { 2137*f4a2713aSLionel Sambuc Diag(AsmLoc, diag::err_msasm_unsupported_arch) << TheTriple.getArchName(); 2138*f4a2713aSLionel Sambuc } else { 2139*f4a2713aSLionel Sambuc std::string Error; 2140*f4a2713aSLionel Sambuc TheTarget = llvm::TargetRegistry::lookupTarget(TT, Error); 2141*f4a2713aSLionel Sambuc if (!TheTarget) 2142*f4a2713aSLionel Sambuc Diag(AsmLoc, diag::err_msasm_unable_to_create_target) << Error; 2143*f4a2713aSLionel Sambuc } 2144*f4a2713aSLionel Sambuc 2145*f4a2713aSLionel Sambuc // If we don't support assembly, or the assembly is empty, we don't 2146*f4a2713aSLionel Sambuc // need to instantiate the AsmParser, etc. 2147*f4a2713aSLionel Sambuc if (!TheTarget || AsmToks.empty()) { 2148*f4a2713aSLionel Sambuc return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, StringRef(), 2149*f4a2713aSLionel Sambuc /*NumOutputs*/ 0, /*NumInputs*/ 0, 2150*f4a2713aSLionel Sambuc ConstraintRefs, ClobberRefs, Exprs, EndLoc); 2151*f4a2713aSLionel Sambuc } 2152*f4a2713aSLionel Sambuc 2153*f4a2713aSLionel Sambuc // Expand the tokens into a string buffer. 2154*f4a2713aSLionel Sambuc SmallString<512> AsmString; 2155*f4a2713aSLionel Sambuc SmallVector<unsigned, 8> TokOffsets; 2156*f4a2713aSLionel Sambuc if (buildMSAsmString(PP, AsmLoc, AsmToks, TokOffsets, AsmString)) 2157*f4a2713aSLionel Sambuc return StmtError(); 2158*f4a2713aSLionel Sambuc 2159*f4a2713aSLionel Sambuc OwningPtr<llvm::MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TT)); 2160*f4a2713aSLionel Sambuc OwningPtr<llvm::MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TT)); 2161*f4a2713aSLionel Sambuc // Get the instruction descriptor. 2162*f4a2713aSLionel Sambuc const llvm::MCInstrInfo *MII = TheTarget->createMCInstrInfo(); 2163*f4a2713aSLionel Sambuc OwningPtr<llvm::MCObjectFileInfo> MOFI(new llvm::MCObjectFileInfo()); 2164*f4a2713aSLionel Sambuc OwningPtr<llvm::MCSubtargetInfo> 2165*f4a2713aSLionel Sambuc STI(TheTarget->createMCSubtargetInfo(TT, "", "")); 2166*f4a2713aSLionel Sambuc 2167*f4a2713aSLionel Sambuc llvm::SourceMgr TempSrcMgr; 2168*f4a2713aSLionel Sambuc llvm::MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &TempSrcMgr); 2169*f4a2713aSLionel Sambuc llvm::MemoryBuffer *Buffer = 2170*f4a2713aSLionel Sambuc llvm::MemoryBuffer::getMemBuffer(AsmString, "<MS inline asm>"); 2171*f4a2713aSLionel Sambuc 2172*f4a2713aSLionel Sambuc // Tell SrcMgr about this buffer, which is what the parser will pick up. 2173*f4a2713aSLionel Sambuc TempSrcMgr.AddNewSourceBuffer(Buffer, llvm::SMLoc()); 2174*f4a2713aSLionel Sambuc 2175*f4a2713aSLionel Sambuc OwningPtr<llvm::MCStreamer> Str(createNullStreamer(Ctx)); 2176*f4a2713aSLionel Sambuc OwningPtr<llvm::MCAsmParser> 2177*f4a2713aSLionel Sambuc Parser(createMCAsmParser(TempSrcMgr, Ctx, *Str.get(), *MAI)); 2178*f4a2713aSLionel Sambuc OwningPtr<llvm::MCTargetAsmParser> 2179*f4a2713aSLionel Sambuc TargetParser(TheTarget->createMCAsmParser(*STI, *Parser, *MII)); 2180*f4a2713aSLionel Sambuc 2181*f4a2713aSLionel Sambuc llvm::MCInstPrinter *IP = 2182*f4a2713aSLionel Sambuc TheTarget->createMCInstPrinter(1, *MAI, *MII, *MRI, *STI); 2183*f4a2713aSLionel Sambuc 2184*f4a2713aSLionel Sambuc // Change to the Intel dialect. 2185*f4a2713aSLionel Sambuc Parser->setAssemblerDialect(1); 2186*f4a2713aSLionel Sambuc Parser->setTargetParser(*TargetParser.get()); 2187*f4a2713aSLionel Sambuc Parser->setParsingInlineAsm(true); 2188*f4a2713aSLionel Sambuc TargetParser->setParsingInlineAsm(true); 2189*f4a2713aSLionel Sambuc 2190*f4a2713aSLionel Sambuc ClangAsmParserCallback Callback(*this, AsmLoc, AsmString, 2191*f4a2713aSLionel Sambuc AsmToks, TokOffsets); 2192*f4a2713aSLionel Sambuc TargetParser->setSemaCallback(&Callback); 2193*f4a2713aSLionel Sambuc TempSrcMgr.setDiagHandler(ClangAsmParserCallback::DiagHandlerCallback, 2194*f4a2713aSLionel Sambuc &Callback); 2195*f4a2713aSLionel Sambuc 2196*f4a2713aSLionel Sambuc unsigned NumOutputs; 2197*f4a2713aSLionel Sambuc unsigned NumInputs; 2198*f4a2713aSLionel Sambuc std::string AsmStringIR; 2199*f4a2713aSLionel Sambuc SmallVector<std::pair<void *, bool>, 4> OpExprs; 2200*f4a2713aSLionel Sambuc SmallVector<std::string, 4> Constraints; 2201*f4a2713aSLionel Sambuc SmallVector<std::string, 4> Clobbers; 2202*f4a2713aSLionel Sambuc if (Parser->parseMSInlineAsm(AsmLoc.getPtrEncoding(), AsmStringIR, 2203*f4a2713aSLionel Sambuc NumOutputs, NumInputs, OpExprs, Constraints, 2204*f4a2713aSLionel Sambuc Clobbers, MII, IP, Callback)) 2205*f4a2713aSLionel Sambuc return StmtError(); 2206*f4a2713aSLionel Sambuc 2207*f4a2713aSLionel Sambuc // Build the vector of clobber StringRefs. 2208*f4a2713aSLionel Sambuc unsigned NumClobbers = Clobbers.size(); 2209*f4a2713aSLionel Sambuc ClobberRefs.resize(NumClobbers); 2210*f4a2713aSLionel Sambuc for (unsigned i = 0; i != NumClobbers; ++i) 2211*f4a2713aSLionel Sambuc ClobberRefs[i] = StringRef(Clobbers[i]); 2212*f4a2713aSLionel Sambuc 2213*f4a2713aSLionel Sambuc // Recast the void pointers and build the vector of constraint StringRefs. 2214*f4a2713aSLionel Sambuc unsigned NumExprs = NumOutputs + NumInputs; 2215*f4a2713aSLionel Sambuc ConstraintRefs.resize(NumExprs); 2216*f4a2713aSLionel Sambuc Exprs.resize(NumExprs); 2217*f4a2713aSLionel Sambuc for (unsigned i = 0, e = NumExprs; i != e; ++i) { 2218*f4a2713aSLionel Sambuc Expr *OpExpr = static_cast<Expr *>(OpExprs[i].first); 2219*f4a2713aSLionel Sambuc if (!OpExpr) 2220*f4a2713aSLionel Sambuc return StmtError(); 2221*f4a2713aSLionel Sambuc 2222*f4a2713aSLionel Sambuc // Need address of variable. 2223*f4a2713aSLionel Sambuc if (OpExprs[i].second) 2224*f4a2713aSLionel Sambuc OpExpr = Actions.BuildUnaryOp(getCurScope(), AsmLoc, UO_AddrOf, OpExpr) 2225*f4a2713aSLionel Sambuc .take(); 2226*f4a2713aSLionel Sambuc 2227*f4a2713aSLionel Sambuc ConstraintRefs[i] = StringRef(Constraints[i]); 2228*f4a2713aSLionel Sambuc Exprs[i] = OpExpr; 2229*f4a2713aSLionel Sambuc } 2230*f4a2713aSLionel Sambuc 2231*f4a2713aSLionel Sambuc // FIXME: We should be passing source locations for better diagnostics. 2232*f4a2713aSLionel Sambuc return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmStringIR, 2233*f4a2713aSLionel Sambuc NumOutputs, NumInputs, 2234*f4a2713aSLionel Sambuc ConstraintRefs, ClobberRefs, Exprs, EndLoc); 2235*f4a2713aSLionel Sambuc } 2236*f4a2713aSLionel Sambuc 2237*f4a2713aSLionel Sambuc /// ParseAsmStatement - Parse a GNU extended asm statement. 2238*f4a2713aSLionel Sambuc /// asm-statement: 2239*f4a2713aSLionel Sambuc /// gnu-asm-statement 2240*f4a2713aSLionel Sambuc /// ms-asm-statement 2241*f4a2713aSLionel Sambuc /// 2242*f4a2713aSLionel Sambuc /// [GNU] gnu-asm-statement: 2243*f4a2713aSLionel Sambuc /// 'asm' type-qualifier[opt] '(' asm-argument ')' ';' 2244*f4a2713aSLionel Sambuc /// 2245*f4a2713aSLionel Sambuc /// [GNU] asm-argument: 2246*f4a2713aSLionel Sambuc /// asm-string-literal 2247*f4a2713aSLionel Sambuc /// asm-string-literal ':' asm-operands[opt] 2248*f4a2713aSLionel Sambuc /// asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt] 2249*f4a2713aSLionel Sambuc /// asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt] 2250*f4a2713aSLionel Sambuc /// ':' asm-clobbers 2251*f4a2713aSLionel Sambuc /// 2252*f4a2713aSLionel Sambuc /// [GNU] asm-clobbers: 2253*f4a2713aSLionel Sambuc /// asm-string-literal 2254*f4a2713aSLionel Sambuc /// asm-clobbers ',' asm-string-literal 2255*f4a2713aSLionel Sambuc /// 2256*f4a2713aSLionel Sambuc StmtResult Parser::ParseAsmStatement(bool &msAsm) { 2257*f4a2713aSLionel Sambuc assert(Tok.is(tok::kw_asm) && "Not an asm stmt"); 2258*f4a2713aSLionel Sambuc SourceLocation AsmLoc = ConsumeToken(); 2259*f4a2713aSLionel Sambuc 2260*f4a2713aSLionel Sambuc if (getLangOpts().AsmBlocks && Tok.isNot(tok::l_paren) && 2261*f4a2713aSLionel Sambuc !isTypeQualifier()) { 2262*f4a2713aSLionel Sambuc msAsm = true; 2263*f4a2713aSLionel Sambuc return ParseMicrosoftAsmStatement(AsmLoc); 2264*f4a2713aSLionel Sambuc } 2265*f4a2713aSLionel Sambuc DeclSpec DS(AttrFactory); 2266*f4a2713aSLionel Sambuc SourceLocation Loc = Tok.getLocation(); 2267*f4a2713aSLionel Sambuc ParseTypeQualifierListOpt(DS, true, false); 2268*f4a2713aSLionel Sambuc 2269*f4a2713aSLionel Sambuc // GNU asms accept, but warn, about type-qualifiers other than volatile. 2270*f4a2713aSLionel Sambuc if (DS.getTypeQualifiers() & DeclSpec::TQ_const) 2271*f4a2713aSLionel Sambuc Diag(Loc, diag::w_asm_qualifier_ignored) << "const"; 2272*f4a2713aSLionel Sambuc if (DS.getTypeQualifiers() & DeclSpec::TQ_restrict) 2273*f4a2713aSLionel Sambuc Diag(Loc, diag::w_asm_qualifier_ignored) << "restrict"; 2274*f4a2713aSLionel Sambuc // FIXME: Once GCC supports _Atomic, check whether it permits it here. 2275*f4a2713aSLionel Sambuc if (DS.getTypeQualifiers() & DeclSpec::TQ_atomic) 2276*f4a2713aSLionel Sambuc Diag(Loc, diag::w_asm_qualifier_ignored) << "_Atomic"; 2277*f4a2713aSLionel Sambuc 2278*f4a2713aSLionel Sambuc // Remember if this was a volatile asm. 2279*f4a2713aSLionel Sambuc bool isVolatile = DS.getTypeQualifiers() & DeclSpec::TQ_volatile; 2280*f4a2713aSLionel Sambuc if (Tok.isNot(tok::l_paren)) { 2281*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_lparen_after) << "asm"; 2282*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 2283*f4a2713aSLionel Sambuc return StmtError(); 2284*f4a2713aSLionel Sambuc } 2285*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren); 2286*f4a2713aSLionel Sambuc T.consumeOpen(); 2287*f4a2713aSLionel Sambuc 2288*f4a2713aSLionel Sambuc ExprResult AsmString(ParseAsmStringLiteral()); 2289*f4a2713aSLionel Sambuc if (AsmString.isInvalid()) { 2290*f4a2713aSLionel Sambuc // Consume up to and including the closing paren. 2291*f4a2713aSLionel Sambuc T.skipToEnd(); 2292*f4a2713aSLionel Sambuc return StmtError(); 2293*f4a2713aSLionel Sambuc } 2294*f4a2713aSLionel Sambuc 2295*f4a2713aSLionel Sambuc SmallVector<IdentifierInfo *, 4> Names; 2296*f4a2713aSLionel Sambuc ExprVector Constraints; 2297*f4a2713aSLionel Sambuc ExprVector Exprs; 2298*f4a2713aSLionel Sambuc ExprVector Clobbers; 2299*f4a2713aSLionel Sambuc 2300*f4a2713aSLionel Sambuc if (Tok.is(tok::r_paren)) { 2301*f4a2713aSLionel Sambuc // We have a simple asm expression like 'asm("foo")'. 2302*f4a2713aSLionel Sambuc T.consumeClose(); 2303*f4a2713aSLionel Sambuc return Actions.ActOnGCCAsmStmt(AsmLoc, /*isSimple*/ true, isVolatile, 2304*f4a2713aSLionel Sambuc /*NumOutputs*/ 0, /*NumInputs*/ 0, 0, 2305*f4a2713aSLionel Sambuc Constraints, Exprs, AsmString.take(), 2306*f4a2713aSLionel Sambuc Clobbers, T.getCloseLocation()); 2307*f4a2713aSLionel Sambuc } 2308*f4a2713aSLionel Sambuc 2309*f4a2713aSLionel Sambuc // Parse Outputs, if present. 2310*f4a2713aSLionel Sambuc bool AteExtraColon = false; 2311*f4a2713aSLionel Sambuc if (Tok.is(tok::colon) || Tok.is(tok::coloncolon)) { 2312*f4a2713aSLionel Sambuc // In C++ mode, parse "::" like ": :". 2313*f4a2713aSLionel Sambuc AteExtraColon = Tok.is(tok::coloncolon); 2314*f4a2713aSLionel Sambuc ConsumeToken(); 2315*f4a2713aSLionel Sambuc 2316*f4a2713aSLionel Sambuc if (!AteExtraColon && 2317*f4a2713aSLionel Sambuc ParseAsmOperandsOpt(Names, Constraints, Exprs)) 2318*f4a2713aSLionel Sambuc return StmtError(); 2319*f4a2713aSLionel Sambuc } 2320*f4a2713aSLionel Sambuc 2321*f4a2713aSLionel Sambuc unsigned NumOutputs = Names.size(); 2322*f4a2713aSLionel Sambuc 2323*f4a2713aSLionel Sambuc // Parse Inputs, if present. 2324*f4a2713aSLionel Sambuc if (AteExtraColon || 2325*f4a2713aSLionel Sambuc Tok.is(tok::colon) || Tok.is(tok::coloncolon)) { 2326*f4a2713aSLionel Sambuc // In C++ mode, parse "::" like ": :". 2327*f4a2713aSLionel Sambuc if (AteExtraColon) 2328*f4a2713aSLionel Sambuc AteExtraColon = false; 2329*f4a2713aSLionel Sambuc else { 2330*f4a2713aSLionel Sambuc AteExtraColon = Tok.is(tok::coloncolon); 2331*f4a2713aSLionel Sambuc ConsumeToken(); 2332*f4a2713aSLionel Sambuc } 2333*f4a2713aSLionel Sambuc 2334*f4a2713aSLionel Sambuc if (!AteExtraColon && 2335*f4a2713aSLionel Sambuc ParseAsmOperandsOpt(Names, Constraints, Exprs)) 2336*f4a2713aSLionel Sambuc return StmtError(); 2337*f4a2713aSLionel Sambuc } 2338*f4a2713aSLionel Sambuc 2339*f4a2713aSLionel Sambuc assert(Names.size() == Constraints.size() && 2340*f4a2713aSLionel Sambuc Constraints.size() == Exprs.size() && 2341*f4a2713aSLionel Sambuc "Input operand size mismatch!"); 2342*f4a2713aSLionel Sambuc 2343*f4a2713aSLionel Sambuc unsigned NumInputs = Names.size() - NumOutputs; 2344*f4a2713aSLionel Sambuc 2345*f4a2713aSLionel Sambuc // Parse the clobbers, if present. 2346*f4a2713aSLionel Sambuc if (AteExtraColon || Tok.is(tok::colon)) { 2347*f4a2713aSLionel Sambuc if (!AteExtraColon) 2348*f4a2713aSLionel Sambuc ConsumeToken(); 2349*f4a2713aSLionel Sambuc 2350*f4a2713aSLionel Sambuc // Parse the asm-string list for clobbers if present. 2351*f4a2713aSLionel Sambuc if (Tok.isNot(tok::r_paren)) { 2352*f4a2713aSLionel Sambuc while (1) { 2353*f4a2713aSLionel Sambuc ExprResult Clobber(ParseAsmStringLiteral()); 2354*f4a2713aSLionel Sambuc 2355*f4a2713aSLionel Sambuc if (Clobber.isInvalid()) 2356*f4a2713aSLionel Sambuc break; 2357*f4a2713aSLionel Sambuc 2358*f4a2713aSLionel Sambuc Clobbers.push_back(Clobber.release()); 2359*f4a2713aSLionel Sambuc 2360*f4a2713aSLionel Sambuc if (Tok.isNot(tok::comma)) break; 2361*f4a2713aSLionel Sambuc ConsumeToken(); 2362*f4a2713aSLionel Sambuc } 2363*f4a2713aSLionel Sambuc } 2364*f4a2713aSLionel Sambuc } 2365*f4a2713aSLionel Sambuc 2366*f4a2713aSLionel Sambuc T.consumeClose(); 2367*f4a2713aSLionel Sambuc return Actions.ActOnGCCAsmStmt(AsmLoc, false, isVolatile, NumOutputs, 2368*f4a2713aSLionel Sambuc NumInputs, Names.data(), Constraints, Exprs, 2369*f4a2713aSLionel Sambuc AsmString.take(), Clobbers, 2370*f4a2713aSLionel Sambuc T.getCloseLocation()); 2371*f4a2713aSLionel Sambuc } 2372*f4a2713aSLionel Sambuc 2373*f4a2713aSLionel Sambuc /// ParseAsmOperands - Parse the asm-operands production as used by 2374*f4a2713aSLionel Sambuc /// asm-statement, assuming the leading ':' token was eaten. 2375*f4a2713aSLionel Sambuc /// 2376*f4a2713aSLionel Sambuc /// [GNU] asm-operands: 2377*f4a2713aSLionel Sambuc /// asm-operand 2378*f4a2713aSLionel Sambuc /// asm-operands ',' asm-operand 2379*f4a2713aSLionel Sambuc /// 2380*f4a2713aSLionel Sambuc /// [GNU] asm-operand: 2381*f4a2713aSLionel Sambuc /// asm-string-literal '(' expression ')' 2382*f4a2713aSLionel Sambuc /// '[' identifier ']' asm-string-literal '(' expression ')' 2383*f4a2713aSLionel Sambuc /// 2384*f4a2713aSLionel Sambuc // 2385*f4a2713aSLionel Sambuc // FIXME: Avoid unnecessary std::string trashing. 2386*f4a2713aSLionel Sambuc bool Parser::ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names, 2387*f4a2713aSLionel Sambuc SmallVectorImpl<Expr *> &Constraints, 2388*f4a2713aSLionel Sambuc SmallVectorImpl<Expr *> &Exprs) { 2389*f4a2713aSLionel Sambuc // 'asm-operands' isn't present? 2390*f4a2713aSLionel Sambuc if (!isTokenStringLiteral() && Tok.isNot(tok::l_square)) 2391*f4a2713aSLionel Sambuc return false; 2392*f4a2713aSLionel Sambuc 2393*f4a2713aSLionel Sambuc while (1) { 2394*f4a2713aSLionel Sambuc // Read the [id] if present. 2395*f4a2713aSLionel Sambuc if (Tok.is(tok::l_square)) { 2396*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_square); 2397*f4a2713aSLionel Sambuc T.consumeOpen(); 2398*f4a2713aSLionel Sambuc 2399*f4a2713aSLionel Sambuc if (Tok.isNot(tok::identifier)) { 2400*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_ident); 2401*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 2402*f4a2713aSLionel Sambuc return true; 2403*f4a2713aSLionel Sambuc } 2404*f4a2713aSLionel Sambuc 2405*f4a2713aSLionel Sambuc IdentifierInfo *II = Tok.getIdentifierInfo(); 2406*f4a2713aSLionel Sambuc ConsumeToken(); 2407*f4a2713aSLionel Sambuc 2408*f4a2713aSLionel Sambuc Names.push_back(II); 2409*f4a2713aSLionel Sambuc T.consumeClose(); 2410*f4a2713aSLionel Sambuc } else 2411*f4a2713aSLionel Sambuc Names.push_back(0); 2412*f4a2713aSLionel Sambuc 2413*f4a2713aSLionel Sambuc ExprResult Constraint(ParseAsmStringLiteral()); 2414*f4a2713aSLionel Sambuc if (Constraint.isInvalid()) { 2415*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 2416*f4a2713aSLionel Sambuc return true; 2417*f4a2713aSLionel Sambuc } 2418*f4a2713aSLionel Sambuc Constraints.push_back(Constraint.release()); 2419*f4a2713aSLionel Sambuc 2420*f4a2713aSLionel Sambuc if (Tok.isNot(tok::l_paren)) { 2421*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_lparen_after) << "asm operand"; 2422*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 2423*f4a2713aSLionel Sambuc return true; 2424*f4a2713aSLionel Sambuc } 2425*f4a2713aSLionel Sambuc 2426*f4a2713aSLionel Sambuc // Read the parenthesized expression. 2427*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren); 2428*f4a2713aSLionel Sambuc T.consumeOpen(); 2429*f4a2713aSLionel Sambuc ExprResult Res(ParseExpression()); 2430*f4a2713aSLionel Sambuc T.consumeClose(); 2431*f4a2713aSLionel Sambuc if (Res.isInvalid()) { 2432*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 2433*f4a2713aSLionel Sambuc return true; 2434*f4a2713aSLionel Sambuc } 2435*f4a2713aSLionel Sambuc Exprs.push_back(Res.release()); 2436*f4a2713aSLionel Sambuc // Eat the comma and continue parsing if it exists. 2437*f4a2713aSLionel Sambuc if (Tok.isNot(tok::comma)) return false; 2438*f4a2713aSLionel Sambuc ConsumeToken(); 2439*f4a2713aSLionel Sambuc } 2440*f4a2713aSLionel Sambuc } 2441*f4a2713aSLionel Sambuc 2442*f4a2713aSLionel Sambuc Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) { 2443*f4a2713aSLionel Sambuc assert(Tok.is(tok::l_brace)); 2444*f4a2713aSLionel Sambuc SourceLocation LBraceLoc = Tok.getLocation(); 2445*f4a2713aSLionel Sambuc 2446*f4a2713aSLionel Sambuc if (SkipFunctionBodies && (!Decl || Actions.canSkipFunctionBody(Decl)) && 2447*f4a2713aSLionel Sambuc trySkippingFunctionBody()) { 2448*f4a2713aSLionel Sambuc BodyScope.Exit(); 2449*f4a2713aSLionel Sambuc return Actions.ActOnSkippedFunctionBody(Decl); 2450*f4a2713aSLionel Sambuc } 2451*f4a2713aSLionel Sambuc 2452*f4a2713aSLionel Sambuc PrettyDeclStackTraceEntry CrashInfo(Actions, Decl, LBraceLoc, 2453*f4a2713aSLionel Sambuc "parsing function body"); 2454*f4a2713aSLionel Sambuc 2455*f4a2713aSLionel Sambuc // Do not enter a scope for the brace, as the arguments are in the same scope 2456*f4a2713aSLionel Sambuc // (the function body) as the body itself. Instead, just read the statement 2457*f4a2713aSLionel Sambuc // list and put it into a CompoundStmt for safe keeping. 2458*f4a2713aSLionel Sambuc StmtResult FnBody(ParseCompoundStatementBody()); 2459*f4a2713aSLionel Sambuc 2460*f4a2713aSLionel Sambuc // If the function body could not be parsed, make a bogus compoundstmt. 2461*f4a2713aSLionel Sambuc if (FnBody.isInvalid()) { 2462*f4a2713aSLionel Sambuc Sema::CompoundScopeRAII CompoundScope(Actions); 2463*f4a2713aSLionel Sambuc FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, None, false); 2464*f4a2713aSLionel Sambuc } 2465*f4a2713aSLionel Sambuc 2466*f4a2713aSLionel Sambuc BodyScope.Exit(); 2467*f4a2713aSLionel Sambuc return Actions.ActOnFinishFunctionBody(Decl, FnBody.take()); 2468*f4a2713aSLionel Sambuc } 2469*f4a2713aSLionel Sambuc 2470*f4a2713aSLionel Sambuc /// ParseFunctionTryBlock - Parse a C++ function-try-block. 2471*f4a2713aSLionel Sambuc /// 2472*f4a2713aSLionel Sambuc /// function-try-block: 2473*f4a2713aSLionel Sambuc /// 'try' ctor-initializer[opt] compound-statement handler-seq 2474*f4a2713aSLionel Sambuc /// 2475*f4a2713aSLionel Sambuc Decl *Parser::ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope) { 2476*f4a2713aSLionel Sambuc assert(Tok.is(tok::kw_try) && "Expected 'try'"); 2477*f4a2713aSLionel Sambuc SourceLocation TryLoc = ConsumeToken(); 2478*f4a2713aSLionel Sambuc 2479*f4a2713aSLionel Sambuc PrettyDeclStackTraceEntry CrashInfo(Actions, Decl, TryLoc, 2480*f4a2713aSLionel Sambuc "parsing function try block"); 2481*f4a2713aSLionel Sambuc 2482*f4a2713aSLionel Sambuc // Constructor initializer list? 2483*f4a2713aSLionel Sambuc if (Tok.is(tok::colon)) 2484*f4a2713aSLionel Sambuc ParseConstructorInitializer(Decl); 2485*f4a2713aSLionel Sambuc else 2486*f4a2713aSLionel Sambuc Actions.ActOnDefaultCtorInitializers(Decl); 2487*f4a2713aSLionel Sambuc 2488*f4a2713aSLionel Sambuc if (SkipFunctionBodies && Actions.canSkipFunctionBody(Decl) && 2489*f4a2713aSLionel Sambuc trySkippingFunctionBody()) { 2490*f4a2713aSLionel Sambuc BodyScope.Exit(); 2491*f4a2713aSLionel Sambuc return Actions.ActOnSkippedFunctionBody(Decl); 2492*f4a2713aSLionel Sambuc } 2493*f4a2713aSLionel Sambuc 2494*f4a2713aSLionel Sambuc SourceLocation LBraceLoc = Tok.getLocation(); 2495*f4a2713aSLionel Sambuc StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc, /*FnTry*/true)); 2496*f4a2713aSLionel Sambuc // If we failed to parse the try-catch, we just give the function an empty 2497*f4a2713aSLionel Sambuc // compound statement as the body. 2498*f4a2713aSLionel Sambuc if (FnBody.isInvalid()) { 2499*f4a2713aSLionel Sambuc Sema::CompoundScopeRAII CompoundScope(Actions); 2500*f4a2713aSLionel Sambuc FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, None, false); 2501*f4a2713aSLionel Sambuc } 2502*f4a2713aSLionel Sambuc 2503*f4a2713aSLionel Sambuc BodyScope.Exit(); 2504*f4a2713aSLionel Sambuc return Actions.ActOnFinishFunctionBody(Decl, FnBody.take()); 2505*f4a2713aSLionel Sambuc } 2506*f4a2713aSLionel Sambuc 2507*f4a2713aSLionel Sambuc bool Parser::trySkippingFunctionBody() { 2508*f4a2713aSLionel Sambuc assert(Tok.is(tok::l_brace)); 2509*f4a2713aSLionel Sambuc assert(SkipFunctionBodies && 2510*f4a2713aSLionel Sambuc "Should only be called when SkipFunctionBodies is enabled"); 2511*f4a2713aSLionel Sambuc 2512*f4a2713aSLionel Sambuc if (!PP.isCodeCompletionEnabled()) { 2513*f4a2713aSLionel Sambuc ConsumeBrace(); 2514*f4a2713aSLionel Sambuc SkipUntil(tok::r_brace); 2515*f4a2713aSLionel Sambuc return true; 2516*f4a2713aSLionel Sambuc } 2517*f4a2713aSLionel Sambuc 2518*f4a2713aSLionel Sambuc // We're in code-completion mode. Skip parsing for all function bodies unless 2519*f4a2713aSLionel Sambuc // the body contains the code-completion point. 2520*f4a2713aSLionel Sambuc TentativeParsingAction PA(*this); 2521*f4a2713aSLionel Sambuc ConsumeBrace(); 2522*f4a2713aSLionel Sambuc if (SkipUntil(tok::r_brace, StopAtCodeCompletion)) { 2523*f4a2713aSLionel Sambuc PA.Commit(); 2524*f4a2713aSLionel Sambuc return true; 2525*f4a2713aSLionel Sambuc } 2526*f4a2713aSLionel Sambuc 2527*f4a2713aSLionel Sambuc PA.Revert(); 2528*f4a2713aSLionel Sambuc return false; 2529*f4a2713aSLionel Sambuc } 2530*f4a2713aSLionel Sambuc 2531*f4a2713aSLionel Sambuc /// ParseCXXTryBlock - Parse a C++ try-block. 2532*f4a2713aSLionel Sambuc /// 2533*f4a2713aSLionel Sambuc /// try-block: 2534*f4a2713aSLionel Sambuc /// 'try' compound-statement handler-seq 2535*f4a2713aSLionel Sambuc /// 2536*f4a2713aSLionel Sambuc StmtResult Parser::ParseCXXTryBlock() { 2537*f4a2713aSLionel Sambuc assert(Tok.is(tok::kw_try) && "Expected 'try'"); 2538*f4a2713aSLionel Sambuc 2539*f4a2713aSLionel Sambuc SourceLocation TryLoc = ConsumeToken(); 2540*f4a2713aSLionel Sambuc return ParseCXXTryBlockCommon(TryLoc); 2541*f4a2713aSLionel Sambuc } 2542*f4a2713aSLionel Sambuc 2543*f4a2713aSLionel Sambuc /// ParseCXXTryBlockCommon - Parse the common part of try-block and 2544*f4a2713aSLionel Sambuc /// function-try-block. 2545*f4a2713aSLionel Sambuc /// 2546*f4a2713aSLionel Sambuc /// try-block: 2547*f4a2713aSLionel Sambuc /// 'try' compound-statement handler-seq 2548*f4a2713aSLionel Sambuc /// 2549*f4a2713aSLionel Sambuc /// function-try-block: 2550*f4a2713aSLionel Sambuc /// 'try' ctor-initializer[opt] compound-statement handler-seq 2551*f4a2713aSLionel Sambuc /// 2552*f4a2713aSLionel Sambuc /// handler-seq: 2553*f4a2713aSLionel Sambuc /// handler handler-seq[opt] 2554*f4a2713aSLionel Sambuc /// 2555*f4a2713aSLionel Sambuc /// [Borland] try-block: 2556*f4a2713aSLionel Sambuc /// 'try' compound-statement seh-except-block 2557*f4a2713aSLionel Sambuc /// 'try' compound-statment seh-finally-block 2558*f4a2713aSLionel Sambuc /// 2559*f4a2713aSLionel Sambuc StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry) { 2560*f4a2713aSLionel Sambuc if (Tok.isNot(tok::l_brace)) 2561*f4a2713aSLionel Sambuc return StmtError(Diag(Tok, diag::err_expected_lbrace)); 2562*f4a2713aSLionel Sambuc // FIXME: Possible draft standard bug: attribute-specifier should be allowed? 2563*f4a2713aSLionel Sambuc 2564*f4a2713aSLionel Sambuc StmtResult TryBlock(ParseCompoundStatement(/*isStmtExpr=*/false, 2565*f4a2713aSLionel Sambuc Scope::DeclScope | Scope::TryScope | 2566*f4a2713aSLionel Sambuc (FnTry ? Scope::FnTryCatchScope : 0))); 2567*f4a2713aSLionel Sambuc if (TryBlock.isInvalid()) 2568*f4a2713aSLionel Sambuc return TryBlock; 2569*f4a2713aSLionel Sambuc 2570*f4a2713aSLionel Sambuc // Borland allows SEH-handlers with 'try' 2571*f4a2713aSLionel Sambuc 2572*f4a2713aSLionel Sambuc if ((Tok.is(tok::identifier) && 2573*f4a2713aSLionel Sambuc Tok.getIdentifierInfo() == getSEHExceptKeyword()) || 2574*f4a2713aSLionel Sambuc Tok.is(tok::kw___finally)) { 2575*f4a2713aSLionel Sambuc // TODO: Factor into common return ParseSEHHandlerCommon(...) 2576*f4a2713aSLionel Sambuc StmtResult Handler; 2577*f4a2713aSLionel Sambuc if(Tok.getIdentifierInfo() == getSEHExceptKeyword()) { 2578*f4a2713aSLionel Sambuc SourceLocation Loc = ConsumeToken(); 2579*f4a2713aSLionel Sambuc Handler = ParseSEHExceptBlock(Loc); 2580*f4a2713aSLionel Sambuc } 2581*f4a2713aSLionel Sambuc else { 2582*f4a2713aSLionel Sambuc SourceLocation Loc = ConsumeToken(); 2583*f4a2713aSLionel Sambuc Handler = ParseSEHFinallyBlock(Loc); 2584*f4a2713aSLionel Sambuc } 2585*f4a2713aSLionel Sambuc if(Handler.isInvalid()) 2586*f4a2713aSLionel Sambuc return Handler; 2587*f4a2713aSLionel Sambuc 2588*f4a2713aSLionel Sambuc return Actions.ActOnSEHTryBlock(true /* IsCXXTry */, 2589*f4a2713aSLionel Sambuc TryLoc, 2590*f4a2713aSLionel Sambuc TryBlock.take(), 2591*f4a2713aSLionel Sambuc Handler.take()); 2592*f4a2713aSLionel Sambuc } 2593*f4a2713aSLionel Sambuc else { 2594*f4a2713aSLionel Sambuc StmtVector Handlers; 2595*f4a2713aSLionel Sambuc 2596*f4a2713aSLionel Sambuc // C++11 attributes can't appear here, despite this context seeming 2597*f4a2713aSLionel Sambuc // statement-like. 2598*f4a2713aSLionel Sambuc DiagnoseAndSkipCXX11Attributes(); 2599*f4a2713aSLionel Sambuc 2600*f4a2713aSLionel Sambuc if (Tok.isNot(tok::kw_catch)) 2601*f4a2713aSLionel Sambuc return StmtError(Diag(Tok, diag::err_expected_catch)); 2602*f4a2713aSLionel Sambuc while (Tok.is(tok::kw_catch)) { 2603*f4a2713aSLionel Sambuc StmtResult Handler(ParseCXXCatchBlock(FnTry)); 2604*f4a2713aSLionel Sambuc if (!Handler.isInvalid()) 2605*f4a2713aSLionel Sambuc Handlers.push_back(Handler.release()); 2606*f4a2713aSLionel Sambuc } 2607*f4a2713aSLionel Sambuc // Don't bother creating the full statement if we don't have any usable 2608*f4a2713aSLionel Sambuc // handlers. 2609*f4a2713aSLionel Sambuc if (Handlers.empty()) 2610*f4a2713aSLionel Sambuc return StmtError(); 2611*f4a2713aSLionel Sambuc 2612*f4a2713aSLionel Sambuc return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.take(), Handlers); 2613*f4a2713aSLionel Sambuc } 2614*f4a2713aSLionel Sambuc } 2615*f4a2713aSLionel Sambuc 2616*f4a2713aSLionel Sambuc /// ParseCXXCatchBlock - Parse a C++ catch block, called handler in the standard 2617*f4a2713aSLionel Sambuc /// 2618*f4a2713aSLionel Sambuc /// handler: 2619*f4a2713aSLionel Sambuc /// 'catch' '(' exception-declaration ')' compound-statement 2620*f4a2713aSLionel Sambuc /// 2621*f4a2713aSLionel Sambuc /// exception-declaration: 2622*f4a2713aSLionel Sambuc /// attribute-specifier-seq[opt] type-specifier-seq declarator 2623*f4a2713aSLionel Sambuc /// attribute-specifier-seq[opt] type-specifier-seq abstract-declarator[opt] 2624*f4a2713aSLionel Sambuc /// '...' 2625*f4a2713aSLionel Sambuc /// 2626*f4a2713aSLionel Sambuc StmtResult Parser::ParseCXXCatchBlock(bool FnCatch) { 2627*f4a2713aSLionel Sambuc assert(Tok.is(tok::kw_catch) && "Expected 'catch'"); 2628*f4a2713aSLionel Sambuc 2629*f4a2713aSLionel Sambuc SourceLocation CatchLoc = ConsumeToken(); 2630*f4a2713aSLionel Sambuc 2631*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren); 2632*f4a2713aSLionel Sambuc if (T.expectAndConsume(diag::err_expected_lparen)) 2633*f4a2713aSLionel Sambuc return StmtError(); 2634*f4a2713aSLionel Sambuc 2635*f4a2713aSLionel Sambuc // C++ 3.3.2p3: 2636*f4a2713aSLionel Sambuc // The name in a catch exception-declaration is local to the handler and 2637*f4a2713aSLionel Sambuc // shall not be redeclared in the outermost block of the handler. 2638*f4a2713aSLionel Sambuc ParseScope CatchScope(this, Scope::DeclScope | Scope::ControlScope | 2639*f4a2713aSLionel Sambuc (FnCatch ? Scope::FnTryCatchScope : 0)); 2640*f4a2713aSLionel Sambuc 2641*f4a2713aSLionel Sambuc // exception-declaration is equivalent to '...' or a parameter-declaration 2642*f4a2713aSLionel Sambuc // without default arguments. 2643*f4a2713aSLionel Sambuc Decl *ExceptionDecl = 0; 2644*f4a2713aSLionel Sambuc if (Tok.isNot(tok::ellipsis)) { 2645*f4a2713aSLionel Sambuc ParsedAttributesWithRange Attributes(AttrFactory); 2646*f4a2713aSLionel Sambuc MaybeParseCXX11Attributes(Attributes); 2647*f4a2713aSLionel Sambuc 2648*f4a2713aSLionel Sambuc DeclSpec DS(AttrFactory); 2649*f4a2713aSLionel Sambuc DS.takeAttributesFrom(Attributes); 2650*f4a2713aSLionel Sambuc 2651*f4a2713aSLionel Sambuc if (ParseCXXTypeSpecifierSeq(DS)) 2652*f4a2713aSLionel Sambuc return StmtError(); 2653*f4a2713aSLionel Sambuc 2654*f4a2713aSLionel Sambuc Declarator ExDecl(DS, Declarator::CXXCatchContext); 2655*f4a2713aSLionel Sambuc ParseDeclarator(ExDecl); 2656*f4a2713aSLionel Sambuc ExceptionDecl = Actions.ActOnExceptionDeclarator(getCurScope(), ExDecl); 2657*f4a2713aSLionel Sambuc } else 2658*f4a2713aSLionel Sambuc ConsumeToken(); 2659*f4a2713aSLionel Sambuc 2660*f4a2713aSLionel Sambuc T.consumeClose(); 2661*f4a2713aSLionel Sambuc if (T.getCloseLocation().isInvalid()) 2662*f4a2713aSLionel Sambuc return StmtError(); 2663*f4a2713aSLionel Sambuc 2664*f4a2713aSLionel Sambuc if (Tok.isNot(tok::l_brace)) 2665*f4a2713aSLionel Sambuc return StmtError(Diag(Tok, diag::err_expected_lbrace)); 2666*f4a2713aSLionel Sambuc 2667*f4a2713aSLionel Sambuc // FIXME: Possible draft standard bug: attribute-specifier should be allowed? 2668*f4a2713aSLionel Sambuc StmtResult Block(ParseCompoundStatement()); 2669*f4a2713aSLionel Sambuc if (Block.isInvalid()) 2670*f4a2713aSLionel Sambuc return Block; 2671*f4a2713aSLionel Sambuc 2672*f4a2713aSLionel Sambuc return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl, Block.take()); 2673*f4a2713aSLionel Sambuc } 2674*f4a2713aSLionel Sambuc 2675*f4a2713aSLionel Sambuc void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) { 2676*f4a2713aSLionel Sambuc IfExistsCondition Result; 2677*f4a2713aSLionel Sambuc if (ParseMicrosoftIfExistsCondition(Result)) 2678*f4a2713aSLionel Sambuc return; 2679*f4a2713aSLionel Sambuc 2680*f4a2713aSLionel Sambuc // Handle dependent statements by parsing the braces as a compound statement. 2681*f4a2713aSLionel Sambuc // This is not the same behavior as Visual C++, which don't treat this as a 2682*f4a2713aSLionel Sambuc // compound statement, but for Clang's type checking we can't have anything 2683*f4a2713aSLionel Sambuc // inside these braces escaping to the surrounding code. 2684*f4a2713aSLionel Sambuc if (Result.Behavior == IEB_Dependent) { 2685*f4a2713aSLionel Sambuc if (!Tok.is(tok::l_brace)) { 2686*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_lbrace); 2687*f4a2713aSLionel Sambuc return; 2688*f4a2713aSLionel Sambuc } 2689*f4a2713aSLionel Sambuc 2690*f4a2713aSLionel Sambuc StmtResult Compound = ParseCompoundStatement(); 2691*f4a2713aSLionel Sambuc if (Compound.isInvalid()) 2692*f4a2713aSLionel Sambuc return; 2693*f4a2713aSLionel Sambuc 2694*f4a2713aSLionel Sambuc StmtResult DepResult = Actions.ActOnMSDependentExistsStmt(Result.KeywordLoc, 2695*f4a2713aSLionel Sambuc Result.IsIfExists, 2696*f4a2713aSLionel Sambuc Result.SS, 2697*f4a2713aSLionel Sambuc Result.Name, 2698*f4a2713aSLionel Sambuc Compound.get()); 2699*f4a2713aSLionel Sambuc if (DepResult.isUsable()) 2700*f4a2713aSLionel Sambuc Stmts.push_back(DepResult.get()); 2701*f4a2713aSLionel Sambuc return; 2702*f4a2713aSLionel Sambuc } 2703*f4a2713aSLionel Sambuc 2704*f4a2713aSLionel Sambuc BalancedDelimiterTracker Braces(*this, tok::l_brace); 2705*f4a2713aSLionel Sambuc if (Braces.consumeOpen()) { 2706*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_lbrace); 2707*f4a2713aSLionel Sambuc return; 2708*f4a2713aSLionel Sambuc } 2709*f4a2713aSLionel Sambuc 2710*f4a2713aSLionel Sambuc switch (Result.Behavior) { 2711*f4a2713aSLionel Sambuc case IEB_Parse: 2712*f4a2713aSLionel Sambuc // Parse the statements below. 2713*f4a2713aSLionel Sambuc break; 2714*f4a2713aSLionel Sambuc 2715*f4a2713aSLionel Sambuc case IEB_Dependent: 2716*f4a2713aSLionel Sambuc llvm_unreachable("Dependent case handled above"); 2717*f4a2713aSLionel Sambuc 2718*f4a2713aSLionel Sambuc case IEB_Skip: 2719*f4a2713aSLionel Sambuc Braces.skipToEnd(); 2720*f4a2713aSLionel Sambuc return; 2721*f4a2713aSLionel Sambuc } 2722*f4a2713aSLionel Sambuc 2723*f4a2713aSLionel Sambuc // Condition is true, parse the statements. 2724*f4a2713aSLionel Sambuc while (Tok.isNot(tok::r_brace)) { 2725*f4a2713aSLionel Sambuc StmtResult R = ParseStatementOrDeclaration(Stmts, false); 2726*f4a2713aSLionel Sambuc if (R.isUsable()) 2727*f4a2713aSLionel Sambuc Stmts.push_back(R.release()); 2728*f4a2713aSLionel Sambuc } 2729*f4a2713aSLionel Sambuc Braces.consumeClose(); 2730*f4a2713aSLionel Sambuc } 2731