1193326Sed//===--- ParseStmt.cpp - Statement and Block Parser -----------------------===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file implements the Statement and Block portions of the Parser 11193326Sed// interface. 12193326Sed// 13193326Sed//===----------------------------------------------------------------------===// 14193326Sed 15193326Sed#include "clang/Parse/Parser.h" 16200583Srdivacky#include "RAIIObjectsForParser.h" 17251662Sdim#include "clang/AST/ASTContext.h" 18249423Sdim#include "clang/Basic/Diagnostic.h" 19249423Sdim#include "clang/Basic/PrettyStackTrace.h" 20249423Sdim#include "clang/Basic/SourceManager.h" 21251662Sdim#include "clang/Basic/TargetInfo.h" 22212904Sdim#include "clang/Sema/DeclSpec.h" 23212904Sdim#include "clang/Sema/PrettyDeclStackTrace.h" 24212904Sdim#include "clang/Sema/Scope.h" 25243830Sdim#include "clang/Sema/TypoCorrection.h" 26251662Sdim#include "llvm/MC/MCAsmInfo.h" 27251662Sdim#include "llvm/MC/MCContext.h" 28251662Sdim#include "llvm/MC/MCObjectFileInfo.h" 29251662Sdim#include "llvm/MC/MCParser/MCAsmParser.h" 30251662Sdim#include "llvm/MC/MCRegisterInfo.h" 31251662Sdim#include "llvm/MC/MCStreamer.h" 32251662Sdim#include "llvm/MC/MCSubtargetInfo.h" 33251662Sdim#include "llvm/MC/MCTargetAsmParser.h" 34251662Sdim#include "llvm/Support/SourceMgr.h" 35251662Sdim#include "llvm/Support/TargetRegistry.h" 36251662Sdim#include "llvm/Support/TargetSelect.h" 37239462Sdim#include "llvm/ADT/SmallString.h" 38193326Sedusing namespace clang; 39193326Sed 40193326Sed//===----------------------------------------------------------------------===// 41193326Sed// C99 6.8: Statements and Blocks. 42193326Sed//===----------------------------------------------------------------------===// 43193326Sed 44263508Sdim/// \brief Parse a standalone statement (for instance, as the body of an 'if', 45263508Sdim/// 'while', or 'for'). 46263508SdimStmtResult Parser::ParseStatement(SourceLocation *TrailingElseLoc) { 47263508Sdim StmtResult Res; 48263508Sdim 49263508Sdim // We may get back a null statement if we found a #pragma. Keep going until 50263508Sdim // we get an actual statement. 51263508Sdim do { 52263508Sdim StmtVector Stmts; 53263508Sdim Res = ParseStatementOrDeclaration(Stmts, true, TrailingElseLoc); 54263508Sdim } while (!Res.isInvalid() && !Res.get()); 55263508Sdim 56263508Sdim return Res; 57263508Sdim} 58263508Sdim 59193326Sed/// ParseStatementOrDeclaration - Read 'statement' or 'declaration'. 60193326Sed/// StatementOrDeclaration: 61193326Sed/// statement 62193326Sed/// declaration 63193326Sed/// 64193326Sed/// statement: 65193326Sed/// labeled-statement 66193326Sed/// compound-statement 67193326Sed/// expression-statement 68193326Sed/// selection-statement 69193326Sed/// iteration-statement 70193326Sed/// jump-statement 71193326Sed/// [C++] declaration-statement 72193326Sed/// [C++] try-block 73221345Sdim/// [MS] seh-try-block 74193326Sed/// [OBC] objc-throw-statement 75193326Sed/// [OBC] objc-try-catch-statement 76193326Sed/// [OBC] objc-synchronized-statement 77193326Sed/// [GNU] asm-statement 78193326Sed/// [OMP] openmp-construct [TODO] 79193326Sed/// 80193326Sed/// labeled-statement: 81193326Sed/// identifier ':' statement 82193326Sed/// 'case' constant-expression ':' statement 83193326Sed/// 'default' ':' statement 84193326Sed/// 85193326Sed/// selection-statement: 86193326Sed/// if-statement 87193326Sed/// switch-statement 88193326Sed/// 89193326Sed/// iteration-statement: 90193326Sed/// while-statement 91193326Sed/// do-statement 92193326Sed/// for-statement 93193326Sed/// 94193326Sed/// expression-statement: 95193326Sed/// expression[opt] ';' 96193326Sed/// 97193326Sed/// jump-statement: 98193326Sed/// 'goto' identifier ';' 99193326Sed/// 'continue' ';' 100193326Sed/// 'break' ';' 101193326Sed/// 'return' expression[opt] ';' 102193326Sed/// [GNU] 'goto' '*' expression ';' 103193326Sed/// 104193326Sed/// [OBC] objc-throw-statement: 105193326Sed/// [OBC] '@' 'throw' expression ';' 106198092Srdivacky/// [OBC] '@' 'throw' ';' 107198092Srdivacky/// 108212904SdimStmtResult 109234353SdimParser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement, 110234353Sdim SourceLocation *TrailingElseLoc) { 111226633Sdim 112210299Sed ParenBraceBracketBalancer BalancerRAIIObj(*this); 113193326Sed 114234982Sdim ParsedAttributesWithRange Attrs(AttrFactory); 115249423Sdim MaybeParseCXX11Attributes(Attrs, 0, /*MightBeObjCMessageSend*/ true); 116199990Srdivacky 117234982Sdim StmtResult Res = ParseStatementOrDeclarationAfterAttributes(Stmts, 118234982Sdim OnlyStatement, TrailingElseLoc, Attrs); 119234982Sdim 120234982Sdim assert((Attrs.empty() || Res.isInvalid() || Res.isUsable()) && 121234982Sdim "attributes on empty statement"); 122234982Sdim 123234982Sdim if (Attrs.empty() || Res.isInvalid()) 124234982Sdim return Res; 125234982Sdim 126234982Sdim return Actions.ProcessStmtAttributes(Res.get(), Attrs.getList(), Attrs.Range); 127234982Sdim} 128234982Sdim 129263508Sdimnamespace { 130263508Sdimclass StatementFilterCCC : public CorrectionCandidateCallback { 131263508Sdimpublic: 132263508Sdim StatementFilterCCC(Token nextTok) : NextToken(nextTok) { 133263508Sdim WantTypeSpecifiers = nextTok.is(tok::l_paren) || nextTok.is(tok::less) || 134263508Sdim nextTok.is(tok::identifier) || nextTok.is(tok::star) || 135263508Sdim nextTok.is(tok::amp) || nextTok.is(tok::l_square); 136263508Sdim WantExpressionKeywords = nextTok.is(tok::l_paren) || 137263508Sdim nextTok.is(tok::identifier) || 138263508Sdim nextTok.is(tok::arrow) || nextTok.is(tok::period); 139263508Sdim WantRemainingKeywords = nextTok.is(tok::l_paren) || nextTok.is(tok::semi) || 140263508Sdim nextTok.is(tok::identifier) || 141263508Sdim nextTok.is(tok::l_brace); 142263508Sdim WantCXXNamedCasts = false; 143263508Sdim } 144263508Sdim 145263508Sdim virtual bool ValidateCandidate(const TypoCorrection &candidate) { 146263508Sdim if (FieldDecl *FD = candidate.getCorrectionDeclAs<FieldDecl>()) 147263508Sdim return !candidate.getCorrectionSpecifier() || isa<ObjCIvarDecl>(FD); 148263508Sdim if (NextToken.is(tok::equal)) 149263508Sdim return candidate.getCorrectionDeclAs<VarDecl>(); 150263508Sdim if (NextToken.is(tok::period) && 151263508Sdim candidate.getCorrectionDeclAs<NamespaceDecl>()) 152263508Sdim return false; 153263508Sdim return CorrectionCandidateCallback::ValidateCandidate(candidate); 154263508Sdim } 155263508Sdim 156263508Sdimprivate: 157263508Sdim Token NextToken; 158263508Sdim}; 159263508Sdim} 160263508Sdim 161234982SdimStmtResult 162234982SdimParser::ParseStatementOrDeclarationAfterAttributes(StmtVector &Stmts, 163234982Sdim bool OnlyStatement, SourceLocation *TrailingElseLoc, 164234982Sdim ParsedAttributesWithRange &Attrs) { 165234982Sdim const char *SemiError = 0; 166234982Sdim StmtResult Res; 167234982Sdim 168193326Sed // Cases in this switch statement should fall through if the parser expects 169193326Sed // the token to end in a semicolon (in which case SemiError should be set), 170193326Sed // or they directly 'return;' if not. 171221345SdimRetry: 172193326Sed tok::TokenKind Kind = Tok.getKind(); 173193326Sed SourceLocation AtLoc; 174193326Sed switch (Kind) { 175193326Sed case tok::at: // May be a @try or @throw statement 176193326Sed { 177234982Sdim ProhibitAttributes(Attrs); // TODO: is it correct? 178193326Sed AtLoc = ConsumeToken(); // consume @ 179193326Sed return ParseObjCAtStatement(AtLoc); 180193326Sed } 181193326Sed 182198092Srdivacky case tok::code_completion: 183212904Sdim Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Statement); 184226633Sdim cutOffParsing(); 185226633Sdim return StmtError(); 186226633Sdim 187221345Sdim case tok::identifier: { 188221345Sdim Token Next = NextToken(); 189221345Sdim if (Next.is(tok::colon)) { // C99 6.8.1: labeled-statement 190193326Sed // identifier ':' statement 191234982Sdim return ParseLabeledStatement(Attrs); 192193326Sed } 193226633Sdim 194243830Sdim // Look up the identifier, and typo-correct it to a keyword if it's not 195243830Sdim // found. 196221345Sdim if (Next.isNot(tok::coloncolon)) { 197243830Sdim // Try to limit which sets of keywords should be included in typo 198243830Sdim // correction based on what the next token is. 199263508Sdim StatementFilterCCC Validator(Next); 200263508Sdim if (TryAnnotateName(/*IsAddressOfOperand*/false, &Validator) 201243830Sdim == ANK_Error) { 202221345Sdim // Handle errors here by skipping up to the next semicolon or '}', and 203221345Sdim // eat the semicolon if that's what stopped us. 204263508Sdim SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); 205221345Sdim if (Tok.is(tok::semi)) 206221345Sdim ConsumeToken(); 207221345Sdim return StmtError(); 208243830Sdim } 209226633Sdim 210243830Sdim // If the identifier was typo-corrected, try again. 211243830Sdim if (Tok.isNot(tok::identifier)) 212221345Sdim goto Retry; 213221345Sdim } 214226633Sdim 215221345Sdim // Fall through 216221345Sdim } 217226633Sdim 218193326Sed default: { 219234353Sdim if ((getLangOpts().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) { 220193326Sed SourceLocation DeclStart = Tok.getLocation(), DeclEnd; 221218893Sdim DeclGroupPtrTy Decl = ParseDeclaration(Stmts, Declarator::BlockContext, 222234982Sdim DeclEnd, Attrs); 223193326Sed return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd); 224193326Sed } 225193326Sed 226193326Sed if (Tok.is(tok::r_brace)) { 227193326Sed Diag(Tok, diag::err_expected_statement); 228193326Sed return StmtError(); 229193326Sed } 230198092Srdivacky 231234982Sdim return ParseExprStatement(); 232193326Sed } 233193326Sed 234193326Sed case tok::kw_case: // C99 6.8.1: labeled-statement 235234982Sdim return ParseCaseStatement(); 236193326Sed case tok::kw_default: // C99 6.8.1: labeled-statement 237234982Sdim return ParseDefaultStatement(); 238193326Sed 239193326Sed case tok::l_brace: // C99 6.8.2: compound-statement 240234982Sdim return ParseCompoundStatement(); 241218893Sdim case tok::semi: { // C99 6.8.3p3: expression[opt] ';' 242226633Sdim bool HasLeadingEmptyMacro = Tok.hasLeadingEmptyMacro(); 243226633Sdim return Actions.ActOnNullStmt(ConsumeToken(), HasLeadingEmptyMacro); 244218893Sdim } 245193326Sed 246193326Sed case tok::kw_if: // C99 6.8.4.1: if-statement 247234982Sdim return ParseIfStatement(TrailingElseLoc); 248193326Sed case tok::kw_switch: // C99 6.8.4.2: switch-statement 249234982Sdim return ParseSwitchStatement(TrailingElseLoc); 250193326Sed 251193326Sed case tok::kw_while: // C99 6.8.5.1: while-statement 252234982Sdim return ParseWhileStatement(TrailingElseLoc); 253193326Sed case tok::kw_do: // C99 6.8.5.2: do-statement 254234982Sdim Res = ParseDoStatement(); 255194179Sed SemiError = "do/while"; 256193326Sed break; 257193326Sed case tok::kw_for: // C99 6.8.5.3: for-statement 258234982Sdim return ParseForStatement(TrailingElseLoc); 259193326Sed 260193326Sed case tok::kw_goto: // C99 6.8.6.1: goto-statement 261234982Sdim Res = ParseGotoStatement(); 262194179Sed SemiError = "goto"; 263193326Sed break; 264193326Sed case tok::kw_continue: // C99 6.8.6.2: continue-statement 265234982Sdim Res = ParseContinueStatement(); 266194179Sed SemiError = "continue"; 267193326Sed break; 268193326Sed case tok::kw_break: // C99 6.8.6.3: break-statement 269234982Sdim Res = ParseBreakStatement(); 270194179Sed SemiError = "break"; 271193326Sed break; 272193326Sed case tok::kw_return: // C99 6.8.6.4: return-statement 273234982Sdim Res = ParseReturnStatement(); 274194179Sed SemiError = "return"; 275193326Sed break; 276193326Sed 277193326Sed case tok::kw_asm: { 278234982Sdim ProhibitAttributes(Attrs); 279193326Sed bool msAsm = false; 280193326Sed Res = ParseAsmStatement(msAsm); 281218893Sdim Res = Actions.ActOnFinishFullStmt(Res.get()); 282243830Sdim if (msAsm) return Res; 283194179Sed SemiError = "asm"; 284193326Sed break; 285193326Sed } 286193326Sed 287193326Sed case tok::kw_try: // C++ 15: try-block 288234982Sdim return ParseCXXTryBlock(); 289221345Sdim 290221345Sdim case tok::kw___try: 291234982Sdim ProhibitAttributes(Attrs); // TODO: is it correct? 292234982Sdim return ParseSEHTryBlock(); 293234353Sdim 294234353Sdim case tok::annot_pragma_vis: 295234982Sdim ProhibitAttributes(Attrs); 296234353Sdim HandlePragmaVisibility(); 297234353Sdim return StmtEmpty(); 298234353Sdim 299234353Sdim case tok::annot_pragma_pack: 300234982Sdim ProhibitAttributes(Attrs); 301234353Sdim HandlePragmaPack(); 302234353Sdim return StmtEmpty(); 303243830Sdim 304243830Sdim case tok::annot_pragma_msstruct: 305243830Sdim ProhibitAttributes(Attrs); 306243830Sdim HandlePragmaMSStruct(); 307243830Sdim return StmtEmpty(); 308243830Sdim 309243830Sdim case tok::annot_pragma_align: 310243830Sdim ProhibitAttributes(Attrs); 311243830Sdim HandlePragmaAlign(); 312243830Sdim return StmtEmpty(); 313243830Sdim 314243830Sdim case tok::annot_pragma_weak: 315243830Sdim ProhibitAttributes(Attrs); 316243830Sdim HandlePragmaWeak(); 317243830Sdim return StmtEmpty(); 318243830Sdim 319243830Sdim case tok::annot_pragma_weakalias: 320243830Sdim ProhibitAttributes(Attrs); 321243830Sdim HandlePragmaWeakAlias(); 322243830Sdim return StmtEmpty(); 323243830Sdim 324243830Sdim case tok::annot_pragma_redefine_extname: 325243830Sdim ProhibitAttributes(Attrs); 326243830Sdim HandlePragmaRedefineExtname(); 327243830Sdim return StmtEmpty(); 328243830Sdim 329243830Sdim case tok::annot_pragma_fp_contract: 330263508Sdim ProhibitAttributes(Attrs); 331243830Sdim Diag(Tok, diag::err_pragma_fp_contract_scope); 332243830Sdim ConsumeToken(); 333243830Sdim return StmtError(); 334243830Sdim 335243830Sdim case tok::annot_pragma_opencl_extension: 336243830Sdim ProhibitAttributes(Attrs); 337243830Sdim HandlePragmaOpenCLExtension(); 338243830Sdim return StmtEmpty(); 339249423Sdim 340251662Sdim case tok::annot_pragma_captured: 341263508Sdim ProhibitAttributes(Attrs); 342251662Sdim return HandlePragmaCaptured(); 343251662Sdim 344249423Sdim case tok::annot_pragma_openmp: 345263508Sdim ProhibitAttributes(Attrs); 346263508Sdim return ParseOpenMPDeclarativeOrExecutableDirective(); 347263508Sdim 348193326Sed } 349193326Sed 350193326Sed // If we reached this code, the statement must end in a semicolon. 351193326Sed if (Tok.is(tok::semi)) { 352193326Sed ConsumeToken(); 353193326Sed } else if (!Res.isInvalid()) { 354194179Sed // If the result was valid, then we do want to diagnose this. Use 355194179Sed // ExpectAndConsume to emit the diagnostic, even though we know it won't 356194179Sed // succeed. 357194179Sed ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt, SemiError); 358193326Sed // Skip until we see a } or ;, but don't eat it. 359263508Sdim SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); 360193326Sed } 361198092Srdivacky 362243830Sdim return Res; 363193326Sed} 364193326Sed 365221345Sdim/// \brief Parse an expression statement. 366234982SdimStmtResult Parser::ParseExprStatement() { 367221345Sdim // If a case keyword is missing, this is where it should be inserted. 368221345Sdim Token OldToken = Tok; 369226633Sdim 370221345Sdim // expression[opt] ';' 371221345Sdim ExprResult Expr(ParseExpression()); 372221345Sdim if (Expr.isInvalid()) { 373221345Sdim // If the expression is invalid, skip ahead to the next semicolon or '}'. 374221345Sdim // Not doing this opens us up to the possibility of infinite loops if 375221345Sdim // ParseExpression does not consume any tokens. 376263508Sdim SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); 377221345Sdim if (Tok.is(tok::semi)) 378221345Sdim ConsumeToken(); 379249423Sdim return Actions.ActOnExprStmtError(); 380221345Sdim } 381226633Sdim 382221345Sdim if (Tok.is(tok::colon) && getCurScope()->isSwitchScope() && 383221345Sdim Actions.CheckCaseExpression(Expr.get())) { 384221345Sdim // If a constant expression is followed by a colon inside a switch block, 385221345Sdim // suggest a missing case keyword. 386221345Sdim Diag(OldToken, diag::err_expected_case_before_expression) 387221345Sdim << FixItHint::CreateInsertion(OldToken.getLocation(), "case "); 388226633Sdim 389221345Sdim // Recover parsing as a case statement. 390234982Sdim return ParseCaseStatement(/*MissingCase=*/true, Expr); 391221345Sdim } 392226633Sdim 393221345Sdim // Otherwise, eat the semicolon. 394221345Sdim ExpectAndConsumeSemi(diag::err_expected_semi_after_expr); 395249423Sdim return Actions.ActOnExprStmt(Expr); 396221345Sdim} 397221345Sdim 398234982SdimStmtResult Parser::ParseSEHTryBlock() { 399221345Sdim assert(Tok.is(tok::kw___try) && "Expected '__try'"); 400221345Sdim SourceLocation Loc = ConsumeToken(); 401221345Sdim return ParseSEHTryBlockCommon(Loc); 402221345Sdim} 403221345Sdim 404221345Sdim/// ParseSEHTryBlockCommon 405221345Sdim/// 406221345Sdim/// seh-try-block: 407221345Sdim/// '__try' compound-statement seh-handler 408221345Sdim/// 409221345Sdim/// seh-handler: 410221345Sdim/// seh-except-block 411221345Sdim/// seh-finally-block 412221345Sdim/// 413221345SdimStmtResult Parser::ParseSEHTryBlockCommon(SourceLocation TryLoc) { 414221345Sdim if(Tok.isNot(tok::l_brace)) 415221345Sdim return StmtError(Diag(Tok,diag::err_expected_lbrace)); 416221345Sdim 417234982Sdim StmtResult TryBlock(ParseCompoundStatement()); 418221345Sdim if(TryBlock.isInvalid()) 419243830Sdim return TryBlock; 420221345Sdim 421221345Sdim StmtResult Handler; 422234982Sdim if (Tok.is(tok::identifier) && 423234353Sdim Tok.getIdentifierInfo() == getSEHExceptKeyword()) { 424221345Sdim SourceLocation Loc = ConsumeToken(); 425221345Sdim Handler = ParseSEHExceptBlock(Loc); 426221345Sdim } else if (Tok.is(tok::kw___finally)) { 427221345Sdim SourceLocation Loc = ConsumeToken(); 428221345Sdim Handler = ParseSEHFinallyBlock(Loc); 429221345Sdim } else { 430221345Sdim return StmtError(Diag(Tok,diag::err_seh_expected_handler)); 431221345Sdim } 432221345Sdim 433221345Sdim if(Handler.isInvalid()) 434243830Sdim return Handler; 435221345Sdim 436221345Sdim return Actions.ActOnSEHTryBlock(false /* IsCXXTry */, 437221345Sdim TryLoc, 438221345Sdim TryBlock.take(), 439221345Sdim Handler.take()); 440221345Sdim} 441221345Sdim 442221345Sdim/// ParseSEHExceptBlock - Handle __except 443221345Sdim/// 444221345Sdim/// seh-except-block: 445221345Sdim/// '__except' '(' seh-filter-expression ')' compound-statement 446221345Sdim/// 447221345SdimStmtResult Parser::ParseSEHExceptBlock(SourceLocation ExceptLoc) { 448221345Sdim PoisonIdentifierRAIIObject raii(Ident__exception_code, false), 449221345Sdim raii2(Ident___exception_code, false), 450221345Sdim raii3(Ident_GetExceptionCode, false); 451221345Sdim 452221345Sdim if(ExpectAndConsume(tok::l_paren,diag::err_expected_lparen)) 453221345Sdim return StmtError(); 454221345Sdim 455221345Sdim ParseScope ExpectScope(this, Scope::DeclScope | Scope::ControlScope); 456221345Sdim 457234353Sdim if (getLangOpts().Borland) { 458221345Sdim Ident__exception_info->setIsPoisoned(false); 459221345Sdim Ident___exception_info->setIsPoisoned(false); 460221345Sdim Ident_GetExceptionInfo->setIsPoisoned(false); 461221345Sdim } 462221345Sdim ExprResult FilterExpr(ParseExpression()); 463221345Sdim 464234353Sdim if (getLangOpts().Borland) { 465221345Sdim Ident__exception_info->setIsPoisoned(true); 466221345Sdim Ident___exception_info->setIsPoisoned(true); 467221345Sdim Ident_GetExceptionInfo->setIsPoisoned(true); 468221345Sdim } 469221345Sdim 470221345Sdim if(FilterExpr.isInvalid()) 471221345Sdim return StmtError(); 472221345Sdim 473221345Sdim if(ExpectAndConsume(tok::r_paren,diag::err_expected_rparen)) 474221345Sdim return StmtError(); 475221345Sdim 476234982Sdim StmtResult Block(ParseCompoundStatement()); 477221345Sdim 478221345Sdim if(Block.isInvalid()) 479243830Sdim return Block; 480221345Sdim 481221345Sdim return Actions.ActOnSEHExceptBlock(ExceptLoc, FilterExpr.take(), Block.take()); 482221345Sdim} 483221345Sdim 484221345Sdim/// ParseSEHFinallyBlock - Handle __finally 485221345Sdim/// 486221345Sdim/// seh-finally-block: 487221345Sdim/// '__finally' compound-statement 488221345Sdim/// 489221345SdimStmtResult Parser::ParseSEHFinallyBlock(SourceLocation FinallyBlock) { 490221345Sdim PoisonIdentifierRAIIObject raii(Ident__abnormal_termination, false), 491221345Sdim raii2(Ident___abnormal_termination, false), 492221345Sdim raii3(Ident_AbnormalTermination, false); 493221345Sdim 494234982Sdim StmtResult Block(ParseCompoundStatement()); 495221345Sdim if(Block.isInvalid()) 496243830Sdim return Block; 497221345Sdim 498221345Sdim return Actions.ActOnSEHFinallyBlock(FinallyBlock,Block.take()); 499221345Sdim} 500221345Sdim 501193326Sed/// ParseLabeledStatement - We have an identifier and a ':' after it. 502193326Sed/// 503193326Sed/// labeled-statement: 504193326Sed/// identifier ':' statement 505193326Sed/// [GNU] identifier ':' attributes[opt] statement 506193326Sed/// 507234982SdimStmtResult Parser::ParseLabeledStatement(ParsedAttributesWithRange &attrs) { 508193326Sed assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() && 509193326Sed "Not an identifier!"); 510193326Sed 511193326Sed Token IdentTok = Tok; // Save the whole token. 512193326Sed ConsumeToken(); // eat the identifier. 513193326Sed 514193326Sed assert(Tok.is(tok::colon) && "Not a label!"); 515193326Sed 516193326Sed // identifier ':' statement 517193326Sed SourceLocation ColonLoc = ConsumeToken(); 518193326Sed 519263508Sdim // Read label attributes, if present. 520263508Sdim StmtResult SubStmt; 521263508Sdim if (Tok.is(tok::kw___attribute)) { 522263508Sdim ParsedAttributesWithRange TempAttrs(AttrFactory); 523263508Sdim ParseGNUAttributes(TempAttrs); 524193326Sed 525263508Sdim // In C++, GNU attributes only apply to the label if they are followed by a 526263508Sdim // semicolon, to disambiguate label attributes from attributes on a labeled 527263508Sdim // declaration. 528263508Sdim // 529263508Sdim // This doesn't quite match what GCC does; if the attribute list is empty 530263508Sdim // and followed by a semicolon, GCC will reject (it appears to parse the 531263508Sdim // attributes as part of a statement in that case). That looks like a bug. 532263508Sdim if (!getLangOpts().CPlusPlus || Tok.is(tok::semi)) 533263508Sdim attrs.takeAllFrom(TempAttrs); 534263508Sdim else if (isDeclarationStatement()) { 535263508Sdim StmtVector Stmts; 536263508Sdim // FIXME: We should do this whether or not we have a declaration 537263508Sdim // statement, but that doesn't work correctly (because ProhibitAttributes 538263508Sdim // can't handle GNU attributes), so only call it in the one case where 539263508Sdim // GNU attributes are allowed. 540263508Sdim SubStmt = ParseStatementOrDeclarationAfterAttributes( 541263508Sdim Stmts, /*OnlyStmts*/ true, 0, TempAttrs); 542263508Sdim if (!TempAttrs.empty() && !SubStmt.isInvalid()) 543263508Sdim SubStmt = Actions.ProcessStmtAttributes( 544263508Sdim SubStmt.get(), TempAttrs.getList(), TempAttrs.Range); 545263508Sdim } else { 546263508Sdim Diag(Tok, diag::err_expected_semi_after) << "__attribute__"; 547263508Sdim } 548263508Sdim } 549193326Sed 550263508Sdim // If we've not parsed a statement yet, parse one now. 551263508Sdim if (!SubStmt.isInvalid() && !SubStmt.isUsable()) 552263508Sdim SubStmt = ParseStatement(); 553263508Sdim 554193326Sed // Broken substmt shouldn't prevent the label from being added to the AST. 555193326Sed if (SubStmt.isInvalid()) 556193326Sed SubStmt = Actions.ActOnNullStmt(ColonLoc); 557226633Sdim 558218893Sdim LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(), 559218893Sdim IdentTok.getLocation()); 560234982Sdim if (AttributeList *Attrs = attrs.getList()) { 561218893Sdim Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs); 562234982Sdim attrs.clear(); 563234982Sdim } 564226633Sdim 565218893Sdim return Actions.ActOnLabelStmt(IdentTok.getLocation(), LD, ColonLoc, 566218893Sdim SubStmt.get()); 567193326Sed} 568193326Sed 569193326Sed/// ParseCaseStatement 570193326Sed/// labeled-statement: 571193326Sed/// 'case' constant-expression ':' statement 572193326Sed/// [GNU] 'case' constant-expression '...' constant-expression ':' statement 573193326Sed/// 574234982SdimStmtResult Parser::ParseCaseStatement(bool MissingCase, ExprResult Expr) { 575221345Sdim assert((MissingCase || Tok.is(tok::kw_case)) && "Not a case stmt!"); 576198092Srdivacky 577193326Sed // It is very very common for code to contain many case statements recursively 578193326Sed // nested, as in (but usually without indentation): 579193326Sed // case 1: 580193326Sed // case 2: 581193326Sed // case 3: 582193326Sed // case 4: 583193326Sed // case 5: etc. 584193326Sed // 585193326Sed // Parsing this naively works, but is both inefficient and can cause us to run 586193326Sed // out of stack space in our recursive descent parser. As a special case, 587193326Sed // flatten this recursion into an iterative loop. This is complex and gross, 588193326Sed // but all the grossness is constrained to ParseCaseStatement (and some 589263508Sdim // weirdness in the actions), so this is just local grossness :). 590198092Srdivacky 591193326Sed // TopLevelCase - This is the highest level we have parsed. 'case 1' in the 592193326Sed // example above. 593212904Sdim StmtResult TopLevelCase(true); 594198092Srdivacky 595193326Sed // DeepestParsedCaseStmt - This is the deepest statement we have parsed, which 596193326Sed // gets updated each time a new case is parsed, and whose body is unset so 597193326Sed // far. When parsing 'case 4', this is the 'case 3' node. 598226633Sdim Stmt *DeepestParsedCaseStmt = 0; 599198092Srdivacky 600193326Sed // While we have case statements, eat and stack them. 601224145Sdim SourceLocation ColonLoc; 602193326Sed do { 603221345Sdim SourceLocation CaseLoc = MissingCase ? Expr.get()->getExprLoc() : 604221345Sdim ConsumeToken(); // eat the 'case'. 605198092Srdivacky 606198092Srdivacky if (Tok.is(tok::code_completion)) { 607210299Sed Actions.CodeCompleteCase(getCurScope()); 608226633Sdim cutOffParsing(); 609226633Sdim return StmtError(); 610198092Srdivacky } 611226633Sdim 612200583Srdivacky /// We don't want to treat 'case x : y' as a potential typo for 'case x::y'. 613200583Srdivacky /// Disable this form of error recovery while we're parsing the case 614200583Srdivacky /// expression. 615200583Srdivacky ColonProtectionRAIIObject ColonProtection(*this); 616226633Sdim 617221345Sdim ExprResult LHS(MissingCase ? Expr : ParseConstantExpression()); 618221345Sdim MissingCase = false; 619193326Sed if (LHS.isInvalid()) { 620263508Sdim SkipUntil(tok::colon, StopAtSemi); 621193326Sed return StmtError(); 622193326Sed } 623193326Sed 624193326Sed // GNU case range extension. 625193326Sed SourceLocation DotDotDotLoc; 626212904Sdim ExprResult RHS; 627193326Sed if (Tok.is(tok::ellipsis)) { 628193326Sed Diag(Tok, diag::ext_gnu_case_range); 629193326Sed DotDotDotLoc = ConsumeToken(); 630193326Sed 631193326Sed RHS = ParseConstantExpression(); 632193326Sed if (RHS.isInvalid()) { 633263508Sdim SkipUntil(tok::colon, StopAtSemi); 634193326Sed return StmtError(); 635193326Sed } 636193326Sed } 637226633Sdim 638200583Srdivacky ColonProtection.restore(); 639193326Sed 640218893Sdim if (Tok.is(tok::colon)) { 641218893Sdim ColonLoc = ConsumeToken(); 642218893Sdim 643218893Sdim // Treat "case blah;" as a typo for "case blah:". 644218893Sdim } else if (Tok.is(tok::semi)) { 645218893Sdim ColonLoc = ConsumeToken(); 646218893Sdim Diag(ColonLoc, diag::err_expected_colon_after) << "'case'" 647218893Sdim << FixItHint::CreateReplacement(ColonLoc, ":"); 648218893Sdim } else { 649218893Sdim SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation); 650218893Sdim Diag(ExpectedLoc, diag::err_expected_colon_after) << "'case'" 651218893Sdim << FixItHint::CreateInsertion(ExpectedLoc, ":"); 652218893Sdim ColonLoc = ExpectedLoc; 653193326Sed } 654226633Sdim 655212904Sdim StmtResult Case = 656212904Sdim Actions.ActOnCaseStmt(CaseLoc, LHS.get(), DotDotDotLoc, 657212904Sdim RHS.get(), ColonLoc); 658198092Srdivacky 659193326Sed // If we had a sema error parsing this case, then just ignore it and 660193326Sed // continue parsing the sub-stmt. 661193326Sed if (Case.isInvalid()) { 662193326Sed if (TopLevelCase.isInvalid()) // No parsed case stmts. 663193326Sed return ParseStatement(); 664193326Sed // Otherwise, just don't add it as a nested case. 665193326Sed } else { 666193326Sed // If this is the first case statement we parsed, it becomes TopLevelCase. 667193326Sed // Otherwise we link it into the current chain. 668212904Sdim Stmt *NextDeepest = Case.get(); 669193326Sed if (TopLevelCase.isInvalid()) 670243830Sdim TopLevelCase = Case; 671193326Sed else 672212904Sdim Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, Case.get()); 673193326Sed DeepestParsedCaseStmt = NextDeepest; 674193326Sed } 675198092Srdivacky 676193326Sed // Handle all case statements. 677193326Sed } while (Tok.is(tok::kw_case)); 678198092Srdivacky 679193326Sed assert(!TopLevelCase.isInvalid() && "Should have parsed at least one case!"); 680198092Srdivacky 681193326Sed // If we found a non-case statement, start by parsing it. 682212904Sdim StmtResult SubStmt; 683198092Srdivacky 684193326Sed if (Tok.isNot(tok::r_brace)) { 685193326Sed SubStmt = ParseStatement(); 686193326Sed } else { 687193326Sed // Nicely diagnose the common error "switch (X) { case 4: }", which is 688193326Sed // not valid. 689224145Sdim SourceLocation AfterColonLoc = PP.getLocForEndOfToken(ColonLoc); 690234353Sdim Diag(AfterColonLoc, diag::err_label_end_of_compound_statement) 691234353Sdim << FixItHint::CreateInsertion(AfterColonLoc, " ;"); 692193326Sed SubStmt = true; 693193326Sed } 694198092Srdivacky 695193326Sed // Broken sub-stmt shouldn't prevent forming the case statement properly. 696193326Sed if (SubStmt.isInvalid()) 697193326Sed SubStmt = Actions.ActOnNullStmt(SourceLocation()); 698198092Srdivacky 699193326Sed // Install the body into the most deeply-nested case. 700212904Sdim Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, SubStmt.get()); 701193326Sed 702193326Sed // Return the top level parsed statement tree. 703243830Sdim return TopLevelCase; 704193326Sed} 705193326Sed 706193326Sed/// ParseDefaultStatement 707193326Sed/// labeled-statement: 708193326Sed/// 'default' ':' statement 709193326Sed/// Note that this does not parse the 'statement' at the end. 710193326Sed/// 711234982SdimStmtResult Parser::ParseDefaultStatement() { 712193326Sed assert(Tok.is(tok::kw_default) && "Not a default stmt!"); 713193326Sed SourceLocation DefaultLoc = ConsumeToken(); // eat the 'default'. 714193326Sed 715218893Sdim SourceLocation ColonLoc; 716218893Sdim if (Tok.is(tok::colon)) { 717218893Sdim ColonLoc = ConsumeToken(); 718218893Sdim 719218893Sdim // Treat "default;" as a typo for "default:". 720218893Sdim } else if (Tok.is(tok::semi)) { 721218893Sdim ColonLoc = ConsumeToken(); 722218893Sdim Diag(ColonLoc, diag::err_expected_colon_after) << "'default'" 723218893Sdim << FixItHint::CreateReplacement(ColonLoc, ":"); 724218893Sdim } else { 725218893Sdim SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation); 726218893Sdim Diag(ExpectedLoc, diag::err_expected_colon_after) << "'default'" 727218893Sdim << FixItHint::CreateInsertion(ExpectedLoc, ":"); 728218893Sdim ColonLoc = ExpectedLoc; 729193326Sed } 730226633Sdim 731234353Sdim StmtResult SubStmt; 732234353Sdim 733234353Sdim if (Tok.isNot(tok::r_brace)) { 734234353Sdim SubStmt = ParseStatement(); 735234353Sdim } else { 736234353Sdim // Diagnose the common error "switch (X) {... default: }", which is 737234353Sdim // not valid. 738224145Sdim SourceLocation AfterColonLoc = PP.getLocForEndOfToken(ColonLoc); 739234353Sdim Diag(AfterColonLoc, diag::err_label_end_of_compound_statement) 740234353Sdim << FixItHint::CreateInsertion(AfterColonLoc, " ;"); 741234353Sdim SubStmt = true; 742193326Sed } 743193326Sed 744234353Sdim // Broken sub-stmt shouldn't prevent forming the case statement properly. 745193326Sed if (SubStmt.isInvalid()) 746234353Sdim SubStmt = Actions.ActOnNullStmt(ColonLoc); 747193326Sed 748193326Sed return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc, 749212904Sdim SubStmt.get(), getCurScope()); 750193326Sed} 751193326Sed 752234982SdimStmtResult Parser::ParseCompoundStatement(bool isStmtExpr) { 753234982Sdim return ParseCompoundStatement(isStmtExpr, Scope::DeclScope); 754224145Sdim} 755193326Sed 756193326Sed/// ParseCompoundStatement - Parse a "{}" block. 757193326Sed/// 758193326Sed/// compound-statement: [C99 6.8.2] 759193326Sed/// { block-item-list[opt] } 760193326Sed/// [GNU] { label-declarations block-item-list } [TODO] 761193326Sed/// 762193326Sed/// block-item-list: 763193326Sed/// block-item 764193326Sed/// block-item-list block-item 765193326Sed/// 766193326Sed/// block-item: 767193326Sed/// declaration 768193326Sed/// [GNU] '__extension__' declaration 769193326Sed/// statement 770193326Sed/// [OMP] openmp-directive [TODO] 771193326Sed/// 772193326Sed/// [GNU] label-declarations: 773193326Sed/// [GNU] label-declaration 774193326Sed/// [GNU] label-declarations label-declaration 775193326Sed/// 776193326Sed/// [GNU] label-declaration: 777193326Sed/// [GNU] '__label__' identifier-list ';' 778193326Sed/// 779193326Sed/// [OMP] openmp-directive: [TODO] 780193326Sed/// [OMP] barrier-directive 781193326Sed/// [OMP] flush-directive 782193326Sed/// 783234982SdimStmtResult Parser::ParseCompoundStatement(bool isStmtExpr, 784224145Sdim unsigned ScopeFlags) { 785193326Sed assert(Tok.is(tok::l_brace) && "Not a compount stmt!"); 786193326Sed 787193326Sed // Enter a scope to hold everything within the compound stmt. Compound 788193326Sed // statements can always hold declarations. 789224145Sdim ParseScope CompoundScope(this, ScopeFlags); 790193326Sed 791193326Sed // Parse the statements in the body. 792193326Sed return ParseCompoundStatementBody(isStmtExpr); 793193326Sed} 794193326Sed 795243830Sdim/// Parse any pragmas at the start of the compound expression. We handle these 796243830Sdim/// separately since some pragmas (FP_CONTRACT) must appear before any C 797243830Sdim/// statement in the compound, but may be intermingled with other pragmas. 798243830Sdimvoid Parser::ParseCompoundStatementLeadingPragmas() { 799243830Sdim bool checkForPragmas = true; 800243830Sdim while (checkForPragmas) { 801243830Sdim switch (Tok.getKind()) { 802243830Sdim case tok::annot_pragma_vis: 803243830Sdim HandlePragmaVisibility(); 804243830Sdim break; 805243830Sdim case tok::annot_pragma_pack: 806243830Sdim HandlePragmaPack(); 807243830Sdim break; 808243830Sdim case tok::annot_pragma_msstruct: 809243830Sdim HandlePragmaMSStruct(); 810243830Sdim break; 811243830Sdim case tok::annot_pragma_align: 812243830Sdim HandlePragmaAlign(); 813243830Sdim break; 814243830Sdim case tok::annot_pragma_weak: 815243830Sdim HandlePragmaWeak(); 816243830Sdim break; 817243830Sdim case tok::annot_pragma_weakalias: 818243830Sdim HandlePragmaWeakAlias(); 819243830Sdim break; 820243830Sdim case tok::annot_pragma_redefine_extname: 821243830Sdim HandlePragmaRedefineExtname(); 822243830Sdim break; 823243830Sdim case tok::annot_pragma_opencl_extension: 824243830Sdim HandlePragmaOpenCLExtension(); 825243830Sdim break; 826243830Sdim case tok::annot_pragma_fp_contract: 827243830Sdim HandlePragmaFPContract(); 828243830Sdim break; 829243830Sdim default: 830243830Sdim checkForPragmas = false; 831243830Sdim break; 832243830Sdim } 833243830Sdim } 834243830Sdim 835243830Sdim} 836243830Sdim 837193326Sed/// ParseCompoundStatementBody - Parse a sequence of statements and invoke the 838193326Sed/// ActOnCompoundStmt action. This expects the '{' to be the current token, and 839193326Sed/// consume the '}' at the end of the block. It does not manipulate the scope 840193326Sed/// stack. 841212904SdimStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { 842198092Srdivacky PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), 843193326Sed Tok.getLocation(), 844193326Sed "in compound statement ('{}')"); 845243830Sdim 846243830Sdim // Record the state of the FP_CONTRACT pragma, restore on leaving the 847243830Sdim // compound statement. 848243830Sdim Sema::FPContractStateRAII SaveFPContractState(Actions); 849243830Sdim 850218893Sdim InMessageExpressionRAIIObject InMessage(*this, false); 851226633Sdim BalancedDelimiterTracker T(*this, tok::l_brace); 852226633Sdim if (T.consumeOpen()) 853226633Sdim return StmtError(); 854193326Sed 855234353Sdim Sema::CompoundScopeRAII CompoundScope(Actions); 856234353Sdim 857243830Sdim // Parse any pragmas at the beginning of the compound statement. 858243830Sdim ParseCompoundStatementLeadingPragmas(); 859218893Sdim 860243830Sdim StmtVector Stmts; 861243830Sdim 862218893Sdim // "__label__ X, Y, Z;" is the GNU "Local Label" extension. These are 863193326Sed // only allowed at the start of a compound stmt regardless of the language. 864218893Sdim while (Tok.is(tok::kw___label__)) { 865218893Sdim SourceLocation LabelLoc = ConsumeToken(); 866226633Sdim 867226633Sdim SmallVector<Decl *, 8> DeclsInGroup; 868218893Sdim while (1) { 869218893Sdim if (Tok.isNot(tok::identifier)) { 870218893Sdim Diag(Tok, diag::err_expected_ident); 871218893Sdim break; 872218893Sdim } 873226633Sdim 874218893Sdim IdentifierInfo *II = Tok.getIdentifierInfo(); 875218893Sdim SourceLocation IdLoc = ConsumeToken(); 876221345Sdim DeclsInGroup.push_back(Actions.LookupOrCreateLabel(II, IdLoc, LabelLoc)); 877226633Sdim 878218893Sdim if (!Tok.is(tok::comma)) 879218893Sdim break; 880218893Sdim ConsumeToken(); 881218893Sdim } 882226633Sdim 883221345Sdim DeclSpec DS(AttrFactory); 884263508Sdim DeclGroupPtrTy Res = 885263508Sdim Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup); 886218893Sdim StmtResult R = Actions.ActOnDeclStmt(Res, LabelLoc, Tok.getLocation()); 887226633Sdim 888239462Sdim ExpectAndConsumeSemi(diag::err_expected_semi_declaration); 889218893Sdim if (R.isUsable()) 890218893Sdim Stmts.push_back(R.release()); 891218893Sdim } 892226633Sdim 893218893Sdim while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 894218893Sdim if (Tok.is(tok::annot_pragma_unused)) { 895218893Sdim HandlePragmaUnused(); 896218893Sdim continue; 897218893Sdim } 898193326Sed 899234353Sdim if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) || 900223017Sdim Tok.is(tok::kw___if_not_exists))) { 901223017Sdim ParseMicrosoftIfExistsStatement(Stmts); 902223017Sdim continue; 903223017Sdim } 904223017Sdim 905212904Sdim StmtResult R; 906193326Sed if (Tok.isNot(tok::kw___extension__)) { 907218893Sdim R = ParseStatementOrDeclaration(Stmts, false); 908193326Sed } else { 909193326Sed // __extension__ can start declarations and it can also be a unary 910193326Sed // operator for expressions. Consume multiple __extension__ markers here 911193326Sed // until we can determine which is which. 912193326Sed // FIXME: This loses extension expressions in the AST! 913193326Sed SourceLocation ExtLoc = ConsumeToken(); 914193326Sed while (Tok.is(tok::kw___extension__)) 915193326Sed ConsumeToken(); 916193326Sed 917221345Sdim ParsedAttributesWithRange attrs(AttrFactory); 918249423Sdim MaybeParseCXX11Attributes(attrs, 0, /*MightBeObjCMessageSend*/ true); 919199990Srdivacky 920193326Sed // If this is the start of a declaration, parse it as such. 921193326Sed if (isDeclarationStatement()) { 922193326Sed // __extension__ silences extension warnings in the subdeclaration. 923193326Sed // FIXME: Save the __extension__ on the decl as a node somehow? 924193326Sed ExtensionRAIIObject O(Diags); 925193326Sed 926193326Sed SourceLocation DeclStart = Tok.getLocation(), DeclEnd; 927218893Sdim DeclGroupPtrTy Res = ParseDeclaration(Stmts, 928218893Sdim Declarator::BlockContext, DeclEnd, 929218893Sdim attrs); 930193326Sed R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd); 931193326Sed } else { 932193326Sed // Otherwise this was a unary __extension__ marker. 933212904Sdim ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc)); 934193326Sed 935193326Sed if (Res.isInvalid()) { 936193326Sed SkipUntil(tok::semi); 937193326Sed continue; 938193326Sed } 939193326Sed 940199990Srdivacky // FIXME: Use attributes? 941193326Sed // Eat the semicolon at the end of stmt and convert the expr into a 942193326Sed // statement. 943218893Sdim ExpectAndConsumeSemi(diag::err_expected_semi_after_expr); 944249423Sdim R = Actions.ActOnExprStmt(Res); 945193326Sed } 946193326Sed } 947193326Sed 948193326Sed if (R.isUsable()) 949193326Sed Stmts.push_back(R.release()); 950193326Sed } 951193326Sed 952234353Sdim SourceLocation CloseLoc = Tok.getLocation(); 953234353Sdim 954193326Sed // We broke out of the while loop because we found a '}' or EOF. 955249423Sdim if (!T.consumeClose()) 956234353Sdim // Recover by creating a compound statement with what we parsed so far, 957234353Sdim // instead of dropping everything and returning StmtError(); 958249423Sdim CloseLoc = T.getCloseLocation(); 959193326Sed 960234353Sdim return Actions.ActOnCompoundStmt(T.getOpenLocation(), CloseLoc, 961243830Sdim Stmts, isStmtExpr); 962193326Sed} 963193326Sed 964193326Sed/// ParseParenExprOrCondition: 965193326Sed/// [C ] '(' expression ')' 966193326Sed/// [C++] '(' condition ')' [not allowed if OnlyAllowCondition=true] 967193326Sed/// 968193326Sed/// This function parses and performs error recovery on the specified condition 969193326Sed/// or expression (depending on whether we're in C++ or C mode). This function 970193326Sed/// goes out of its way to recover well. It returns true if there was a parser 971193326Sed/// error (the right paren couldn't be found), which indicates that the caller 972193326Sed/// should try to recover harder. It returns false if the condition is 973193326Sed/// successfully parsed. Note that a successful parse can still have semantic 974193326Sed/// errors in the condition. 975212904Sdimbool Parser::ParseParenExprOrCondition(ExprResult &ExprResult, 976212904Sdim Decl *&DeclResult, 977208600Srdivacky SourceLocation Loc, 978208600Srdivacky bool ConvertToBoolean) { 979226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 980226633Sdim T.consumeOpen(); 981226633Sdim 982234353Sdim if (getLangOpts().CPlusPlus) 983218893Sdim ParseCXXCondition(ExprResult, DeclResult, Loc, ConvertToBoolean); 984199990Srdivacky else { 985199990Srdivacky ExprResult = ParseExpression(); 986212904Sdim DeclResult = 0; 987226633Sdim 988208600Srdivacky // If required, convert to a boolean value. 989208600Srdivacky if (!ExprResult.isInvalid() && ConvertToBoolean) 990208600Srdivacky ExprResult 991212904Sdim = Actions.ActOnBooleanCondition(getCurScope(), Loc, ExprResult.get()); 992199990Srdivacky } 993198092Srdivacky 994193326Sed // If the parser was confused by the condition and we don't have a ')', try to 995193326Sed // recover by skipping ahead to a semi and bailing out. If condexp is 996193326Sed // semantically invalid but we have well formed code, keep going. 997212904Sdim if (ExprResult.isInvalid() && !DeclResult && Tok.isNot(tok::r_paren)) { 998193326Sed SkipUntil(tok::semi); 999193326Sed // Skipping may have stopped if it found the containing ')'. If so, we can 1000193326Sed // continue parsing the if statement. 1001193326Sed if (Tok.isNot(tok::r_paren)) 1002193326Sed return true; 1003193326Sed } 1004198092Srdivacky 1005193326Sed // Otherwise the condition is valid or the rparen is present. 1006226633Sdim T.consumeClose(); 1007239462Sdim 1008239462Sdim // Check for extraneous ')'s to catch things like "if (foo())) {". We know 1009239462Sdim // that all callers are looking for a statement after the condition, so ")" 1010239462Sdim // isn't valid. 1011239462Sdim while (Tok.is(tok::r_paren)) { 1012239462Sdim Diag(Tok, diag::err_extraneous_rparen_in_condition) 1013239462Sdim << FixItHint::CreateRemoval(Tok.getLocation()); 1014239462Sdim ConsumeParen(); 1015239462Sdim } 1016239462Sdim 1017193326Sed return false; 1018193326Sed} 1019193326Sed 1020193326Sed 1021193326Sed/// ParseIfStatement 1022193326Sed/// if-statement: [C99 6.8.4.1] 1023193326Sed/// 'if' '(' expression ')' statement 1024193326Sed/// 'if' '(' expression ')' statement 'else' statement 1025193326Sed/// [C++] 'if' '(' condition ')' statement 1026193326Sed/// [C++] 'if' '(' condition ')' statement 'else' statement 1027193326Sed/// 1028234982SdimStmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) { 1029193326Sed assert(Tok.is(tok::kw_if) && "Not an if stmt!"); 1030193326Sed SourceLocation IfLoc = ConsumeToken(); // eat the 'if'. 1031193326Sed 1032193326Sed if (Tok.isNot(tok::l_paren)) { 1033193326Sed Diag(Tok, diag::err_expected_lparen_after) << "if"; 1034193326Sed SkipUntil(tok::semi); 1035193326Sed return StmtError(); 1036193326Sed } 1037193326Sed 1038234353Sdim bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus; 1039193326Sed 1040193326Sed // C99 6.8.4p3 - In C99, the if statement is a block. This is not 1041193326Sed // the case for C90. 1042193326Sed // 1043193326Sed // C++ 6.4p3: 1044193326Sed // A name introduced by a declaration in a condition is in scope from its 1045193326Sed // point of declaration until the end of the substatements controlled by the 1046193326Sed // condition. 1047193326Sed // C++ 3.3.2p4: 1048193326Sed // Names declared in the for-init-statement, and in the condition of if, 1049193326Sed // while, for, and switch statements are local to the if, while, for, or 1050193326Sed // switch statement (including the controlled statement). 1051193326Sed // 1052193326Sed ParseScope IfScope(this, Scope::DeclScope | Scope::ControlScope, C99orCXX); 1053193326Sed 1054193326Sed // Parse the condition. 1055212904Sdim ExprResult CondExp; 1056212904Sdim Decl *CondVar = 0; 1057208600Srdivacky if (ParseParenExprOrCondition(CondExp, CondVar, IfLoc, true)) 1058193326Sed return StmtError(); 1059193326Sed 1060239462Sdim FullExprArg FullCondExp(Actions.MakeFullExpr(CondExp.get(), IfLoc)); 1061198092Srdivacky 1062193326Sed // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if 1063193326Sed // there is no compound stmt. C90 does not have this clause. We only do this 1064193326Sed // if the body isn't a compound statement to avoid push/pop in common cases. 1065193326Sed // 1066193326Sed // C++ 6.4p1: 1067193326Sed // The substatement in a selection-statement (each substatement, in the else 1068193326Sed // form of the if statement) implicitly defines a local scope. 1069193326Sed // 1070193326Sed // For C++ we create a scope for the condition and a new scope for 1071193326Sed // substatements because: 1072193326Sed // -When the 'then' scope exits, we want the condition declaration to still be 1073193326Sed // active for the 'else' scope too. 1074193326Sed // -Sema will detect name clashes by considering declarations of a 1075193326Sed // 'ControlScope' as part of its direct subscope. 1076193326Sed // -If we wanted the condition and substatement to be in the same scope, we 1077193326Sed // would have to notify ParseStatement not to create a new scope. It's 1078193326Sed // simpler to let it create a new scope. 1079193326Sed // 1080198092Srdivacky ParseScope InnerScope(this, Scope::DeclScope, 1081193326Sed C99orCXX && Tok.isNot(tok::l_brace)); 1082193326Sed 1083193326Sed // Read the 'then' stmt. 1084193326Sed SourceLocation ThenStmtLoc = Tok.getLocation(); 1085193326Sed 1086234353Sdim SourceLocation InnerStatementTrailingElseLoc; 1087234353Sdim StmtResult ThenStmt(ParseStatement(&InnerStatementTrailingElseLoc)); 1088234353Sdim 1089193326Sed // Pop the 'if' scope if needed. 1090193326Sed InnerScope.Exit(); 1091193326Sed 1092193326Sed // If it has an else, parse it. 1093193326Sed SourceLocation ElseLoc; 1094193326Sed SourceLocation ElseStmtLoc; 1095212904Sdim StmtResult ElseStmt; 1096193326Sed 1097193326Sed if (Tok.is(tok::kw_else)) { 1098234353Sdim if (TrailingElseLoc) 1099234353Sdim *TrailingElseLoc = Tok.getLocation(); 1100234353Sdim 1101193326Sed ElseLoc = ConsumeToken(); 1102207619Srdivacky ElseStmtLoc = Tok.getLocation(); 1103193326Sed 1104193326Sed // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if 1105193326Sed // there is no compound stmt. C90 does not have this clause. We only do 1106193326Sed // this if the body isn't a compound statement to avoid push/pop in common 1107193326Sed // cases. 1108193326Sed // 1109193326Sed // C++ 6.4p1: 1110193326Sed // The substatement in a selection-statement (each substatement, in the else 1111193326Sed // form of the if statement) implicitly defines a local scope. 1112193326Sed // 1113193326Sed ParseScope InnerScope(this, Scope::DeclScope, 1114193326Sed C99orCXX && Tok.isNot(tok::l_brace)); 1115193326Sed 1116193326Sed ElseStmt = ParseStatement(); 1117226633Sdim 1118193326Sed // Pop the 'else' scope if needed. 1119193326Sed InnerScope.Exit(); 1120226633Sdim } else if (Tok.is(tok::code_completion)) { 1121226633Sdim Actions.CodeCompleteAfterIf(getCurScope()); 1122226633Sdim cutOffParsing(); 1123226633Sdim return StmtError(); 1124234353Sdim } else if (InnerStatementTrailingElseLoc.isValid()) { 1125234353Sdim Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else); 1126193326Sed } 1127193326Sed 1128193326Sed IfScope.Exit(); 1129198092Srdivacky 1130193326Sed // If the then or else stmt is invalid and the other is valid (and present), 1131198092Srdivacky // make turn the invalid one into a null stmt to avoid dropping the other 1132193326Sed // part. If both are invalid, return error. 1133193326Sed if ((ThenStmt.isInvalid() && ElseStmt.isInvalid()) || 1134193326Sed (ThenStmt.isInvalid() && ElseStmt.get() == 0) || 1135193326Sed (ThenStmt.get() == 0 && ElseStmt.isInvalid())) { 1136193326Sed // Both invalid, or one is invalid and other is non-present: return error. 1137193326Sed return StmtError(); 1138193326Sed } 1139193326Sed 1140193326Sed // Now if either are invalid, replace with a ';'. 1141193326Sed if (ThenStmt.isInvalid()) 1142193326Sed ThenStmt = Actions.ActOnNullStmt(ThenStmtLoc); 1143193326Sed if (ElseStmt.isInvalid()) 1144193326Sed ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc); 1145193326Sed 1146212904Sdim return Actions.ActOnIfStmt(IfLoc, FullCondExp, CondVar, ThenStmt.get(), 1147212904Sdim ElseLoc, ElseStmt.get()); 1148193326Sed} 1149193326Sed 1150193326Sed/// ParseSwitchStatement 1151193326Sed/// switch-statement: 1152193326Sed/// 'switch' '(' expression ')' statement 1153193326Sed/// [C++] 'switch' '(' condition ')' statement 1154234982SdimStmtResult Parser::ParseSwitchStatement(SourceLocation *TrailingElseLoc) { 1155193326Sed assert(Tok.is(tok::kw_switch) && "Not a switch stmt!"); 1156193326Sed SourceLocation SwitchLoc = ConsumeToken(); // eat the 'switch'. 1157193326Sed 1158193326Sed if (Tok.isNot(tok::l_paren)) { 1159193326Sed Diag(Tok, diag::err_expected_lparen_after) << "switch"; 1160193326Sed SkipUntil(tok::semi); 1161193326Sed return StmtError(); 1162193326Sed } 1163193326Sed 1164234353Sdim bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus; 1165193326Sed 1166193326Sed // C99 6.8.4p3 - In C99, the switch statement is a block. This is 1167193326Sed // not the case for C90. Start the switch scope. 1168193326Sed // 1169193326Sed // C++ 6.4p3: 1170193326Sed // A name introduced by a declaration in a condition is in scope from its 1171193326Sed // point of declaration until the end of the substatements controlled by the 1172193326Sed // condition. 1173193326Sed // C++ 3.3.2p4: 1174193326Sed // Names declared in the for-init-statement, and in the condition of if, 1175193326Sed // while, for, and switch statements are local to the if, while, for, or 1176193326Sed // switch statement (including the controlled statement). 1177193326Sed // 1178221345Sdim unsigned ScopeFlags = Scope::BreakScope | Scope::SwitchScope; 1179193326Sed if (C99orCXX) 1180193326Sed ScopeFlags |= Scope::DeclScope | Scope::ControlScope; 1181193326Sed ParseScope SwitchScope(this, ScopeFlags); 1182193326Sed 1183193326Sed // Parse the condition. 1184212904Sdim ExprResult Cond; 1185212904Sdim Decl *CondVar = 0; 1186208600Srdivacky if (ParseParenExprOrCondition(Cond, CondVar, SwitchLoc, false)) 1187193326Sed return StmtError(); 1188193326Sed 1189212904Sdim StmtResult Switch 1190212904Sdim = Actions.ActOnStartOfSwitchStmt(SwitchLoc, Cond.get(), CondVar); 1191208600Srdivacky 1192208600Srdivacky if (Switch.isInvalid()) { 1193226633Sdim // Skip the switch body. 1194208600Srdivacky // FIXME: This is not optimal recovery, but parsing the body is more 1195208600Srdivacky // dangerous due to the presence of case and default statements, which 1196208600Srdivacky // will have no place to connect back with the switch. 1197208600Srdivacky if (Tok.is(tok::l_brace)) { 1198208600Srdivacky ConsumeBrace(); 1199263508Sdim SkipUntil(tok::r_brace); 1200208600Srdivacky } else 1201208600Srdivacky SkipUntil(tok::semi); 1202243830Sdim return Switch; 1203208600Srdivacky } 1204226633Sdim 1205193326Sed // C99 6.8.4p3 - In C99, the body of the switch statement is a scope, even if 1206193326Sed // there is no compound stmt. C90 does not have this clause. We only do this 1207193326Sed // if the body isn't a compound statement to avoid push/pop in common cases. 1208193326Sed // 1209193326Sed // C++ 6.4p1: 1210193326Sed // The substatement in a selection-statement (each substatement, in the else 1211193326Sed // form of the if statement) implicitly defines a local scope. 1212193326Sed // 1213193326Sed // See comments in ParseIfStatement for why we create a scope for the 1214193326Sed // condition and a new scope for substatement in C++. 1215193326Sed // 1216198092Srdivacky ParseScope InnerScope(this, Scope::DeclScope, 1217193326Sed C99orCXX && Tok.isNot(tok::l_brace)); 1218193326Sed 1219193326Sed // Read the body statement. 1220234353Sdim StmtResult Body(ParseStatement(TrailingElseLoc)); 1221193326Sed 1222203955Srdivacky // Pop the scopes. 1223193326Sed InnerScope.Exit(); 1224193326Sed SwitchScope.Exit(); 1225193326Sed 1226234353Sdim if (Body.isInvalid()) { 1227203955Srdivacky // FIXME: Remove the case statement list from the Switch statement. 1228226633Sdim 1229234353Sdim // Put the synthesized null statement on the same line as the end of switch 1230234353Sdim // condition. 1231234353Sdim SourceLocation SynthesizedNullStmtLocation = Cond.get()->getLocEnd(); 1232234353Sdim Body = Actions.ActOnNullStmt(SynthesizedNullStmtLocation); 1233234353Sdim } 1234234353Sdim 1235212904Sdim return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.get(), Body.get()); 1236193326Sed} 1237193326Sed 1238193326Sed/// ParseWhileStatement 1239193326Sed/// while-statement: [C99 6.8.5.1] 1240193326Sed/// 'while' '(' expression ')' statement 1241193326Sed/// [C++] 'while' '(' condition ')' statement 1242234982SdimStmtResult Parser::ParseWhileStatement(SourceLocation *TrailingElseLoc) { 1243193326Sed assert(Tok.is(tok::kw_while) && "Not a while stmt!"); 1244193326Sed SourceLocation WhileLoc = Tok.getLocation(); 1245193326Sed ConsumeToken(); // eat the 'while'. 1246193326Sed 1247193326Sed if (Tok.isNot(tok::l_paren)) { 1248193326Sed Diag(Tok, diag::err_expected_lparen_after) << "while"; 1249193326Sed SkipUntil(tok::semi); 1250193326Sed return StmtError(); 1251193326Sed } 1252193326Sed 1253234353Sdim bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus; 1254193326Sed 1255193326Sed // C99 6.8.5p5 - In C99, the while statement is a block. This is not 1256193326Sed // the case for C90. Start the loop scope. 1257193326Sed // 1258193326Sed // C++ 6.4p3: 1259193326Sed // A name introduced by a declaration in a condition is in scope from its 1260193326Sed // point of declaration until the end of the substatements controlled by the 1261193326Sed // condition. 1262193326Sed // C++ 3.3.2p4: 1263193326Sed // Names declared in the for-init-statement, and in the condition of if, 1264193326Sed // while, for, and switch statements are local to the if, while, for, or 1265193326Sed // switch statement (including the controlled statement). 1266193326Sed // 1267193326Sed unsigned ScopeFlags; 1268193326Sed if (C99orCXX) 1269193326Sed ScopeFlags = Scope::BreakScope | Scope::ContinueScope | 1270193326Sed Scope::DeclScope | Scope::ControlScope; 1271193326Sed else 1272193326Sed ScopeFlags = Scope::BreakScope | Scope::ContinueScope; 1273193326Sed ParseScope WhileScope(this, ScopeFlags); 1274193326Sed 1275193326Sed // Parse the condition. 1276212904Sdim ExprResult Cond; 1277212904Sdim Decl *CondVar = 0; 1278208600Srdivacky if (ParseParenExprOrCondition(Cond, CondVar, WhileLoc, true)) 1279193326Sed return StmtError(); 1280193326Sed 1281239462Sdim FullExprArg FullCond(Actions.MakeFullExpr(Cond.get(), WhileLoc)); 1282198092Srdivacky 1283193326Sed // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if 1284193326Sed // there is no compound stmt. C90 does not have this clause. We only do this 1285193326Sed // if the body isn't a compound statement to avoid push/pop in common cases. 1286193326Sed // 1287193326Sed // C++ 6.5p2: 1288193326Sed // The substatement in an iteration-statement implicitly defines a local scope 1289193326Sed // which is entered and exited each time through the loop. 1290193326Sed // 1291193326Sed // See comments in ParseIfStatement for why we create a scope for the 1292193326Sed // condition and a new scope for substatement in C++. 1293193326Sed // 1294198092Srdivacky ParseScope InnerScope(this, Scope::DeclScope, 1295193326Sed C99orCXX && Tok.isNot(tok::l_brace)); 1296193326Sed 1297193326Sed // Read the body statement. 1298234353Sdim StmtResult Body(ParseStatement(TrailingElseLoc)); 1299193326Sed 1300193326Sed // Pop the body scope if needed. 1301193326Sed InnerScope.Exit(); 1302193326Sed WhileScope.Exit(); 1303193326Sed 1304212904Sdim if ((Cond.isInvalid() && !CondVar) || Body.isInvalid()) 1305193326Sed return StmtError(); 1306193326Sed 1307212904Sdim return Actions.ActOnWhileStmt(WhileLoc, FullCond, CondVar, Body.get()); 1308193326Sed} 1309193326Sed 1310193326Sed/// ParseDoStatement 1311193326Sed/// do-statement: [C99 6.8.5.2] 1312193326Sed/// 'do' statement 'while' '(' expression ')' ';' 1313193326Sed/// Note: this lets the caller parse the end ';'. 1314234982SdimStmtResult Parser::ParseDoStatement() { 1315193326Sed assert(Tok.is(tok::kw_do) && "Not a do stmt!"); 1316193326Sed SourceLocation DoLoc = ConsumeToken(); // eat the 'do'. 1317193326Sed 1318193326Sed // C99 6.8.5p5 - In C99, the do statement is a block. This is not 1319193326Sed // the case for C90. Start the loop scope. 1320193326Sed unsigned ScopeFlags; 1321234353Sdim if (getLangOpts().C99) 1322193326Sed ScopeFlags = Scope::BreakScope | Scope::ContinueScope | Scope::DeclScope; 1323193326Sed else 1324193326Sed ScopeFlags = Scope::BreakScope | Scope::ContinueScope; 1325193326Sed 1326193326Sed ParseScope DoScope(this, ScopeFlags); 1327193326Sed 1328193326Sed // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if 1329193326Sed // there is no compound stmt. C90 does not have this clause. We only do this 1330193326Sed // if the body isn't a compound statement to avoid push/pop in common cases. 1331193326Sed // 1332193326Sed // C++ 6.5p2: 1333193326Sed // The substatement in an iteration-statement implicitly defines a local scope 1334193326Sed // which is entered and exited each time through the loop. 1335193326Sed // 1336193326Sed ParseScope InnerScope(this, Scope::DeclScope, 1337234353Sdim (getLangOpts().C99 || getLangOpts().CPlusPlus) && 1338193326Sed Tok.isNot(tok::l_brace)); 1339193326Sed 1340193326Sed // Read the body statement. 1341212904Sdim StmtResult Body(ParseStatement()); 1342193326Sed 1343193326Sed // Pop the body scope if needed. 1344193326Sed InnerScope.Exit(); 1345193326Sed 1346193326Sed if (Tok.isNot(tok::kw_while)) { 1347193326Sed if (!Body.isInvalid()) { 1348193326Sed Diag(Tok, diag::err_expected_while); 1349193326Sed Diag(DoLoc, diag::note_matching) << "do"; 1350263508Sdim SkipUntil(tok::semi, StopBeforeMatch); 1351193326Sed } 1352193326Sed return StmtError(); 1353193326Sed } 1354193326Sed SourceLocation WhileLoc = ConsumeToken(); 1355193326Sed 1356193326Sed if (Tok.isNot(tok::l_paren)) { 1357193326Sed Diag(Tok, diag::err_expected_lparen_after) << "do/while"; 1358263508Sdim SkipUntil(tok::semi, StopBeforeMatch); 1359193326Sed return StmtError(); 1360193326Sed } 1361193326Sed 1362263508Sdim // Parse the parenthesized expression. 1363226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 1364226633Sdim T.consumeOpen(); 1365239462Sdim 1366263508Sdim // A do-while expression is not a condition, so can't have attributes. 1367263508Sdim DiagnoseAndSkipCXX11Attributes(); 1368239462Sdim 1369212904Sdim ExprResult Cond = ParseExpression(); 1370226633Sdim T.consumeClose(); 1371193326Sed DoScope.Exit(); 1372193326Sed 1373193326Sed if (Cond.isInvalid() || Body.isInvalid()) 1374193326Sed return StmtError(); 1375193326Sed 1376226633Sdim return Actions.ActOnDoStmt(DoLoc, Body.get(), WhileLoc, T.getOpenLocation(), 1377226633Sdim Cond.get(), T.getCloseLocation()); 1378193326Sed} 1379193326Sed 1380193326Sed/// ParseForStatement 1381193326Sed/// for-statement: [C99 6.8.5.3] 1382193326Sed/// 'for' '(' expr[opt] ';' expr[opt] ';' expr[opt] ')' statement 1383193326Sed/// 'for' '(' declaration expr[opt] ';' expr[opt] ')' statement 1384193326Sed/// [C++] 'for' '(' for-init-statement condition[opt] ';' expression[opt] ')' 1385193326Sed/// [C++] statement 1386221345Sdim/// [C++0x] 'for' '(' for-range-declaration : for-range-initializer ) statement 1387193326Sed/// [OBJC2] 'for' '(' declaration 'in' expr ')' statement 1388193326Sed/// [OBJC2] 'for' '(' expr 'in' expr ')' statement 1389193326Sed/// 1390193326Sed/// [C++] for-init-statement: 1391193326Sed/// [C++] expression-statement 1392193326Sed/// [C++] simple-declaration 1393193326Sed/// 1394221345Sdim/// [C++0x] for-range-declaration: 1395221345Sdim/// [C++0x] attribute-specifier-seq[opt] type-specifier-seq declarator 1396221345Sdim/// [C++0x] for-range-initializer: 1397221345Sdim/// [C++0x] expression 1398221345Sdim/// [C++0x] braced-init-list [TODO] 1399234982SdimStmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { 1400193326Sed assert(Tok.is(tok::kw_for) && "Not a for stmt!"); 1401193326Sed SourceLocation ForLoc = ConsumeToken(); // eat the 'for'. 1402193326Sed 1403193326Sed if (Tok.isNot(tok::l_paren)) { 1404193326Sed Diag(Tok, diag::err_expected_lparen_after) << "for"; 1405193326Sed SkipUntil(tok::semi); 1406193326Sed return StmtError(); 1407193326Sed } 1408193326Sed 1409239462Sdim bool C99orCXXorObjC = getLangOpts().C99 || getLangOpts().CPlusPlus || 1410239462Sdim getLangOpts().ObjC1; 1411193326Sed 1412193326Sed // C99 6.8.5p5 - In C99, the for statement is a block. This is not 1413193326Sed // the case for C90. Start the loop scope. 1414193326Sed // 1415193326Sed // C++ 6.4p3: 1416193326Sed // A name introduced by a declaration in a condition is in scope from its 1417193326Sed // point of declaration until the end of the substatements controlled by the 1418193326Sed // condition. 1419193326Sed // C++ 3.3.2p4: 1420193326Sed // Names declared in the for-init-statement, and in the condition of if, 1421193326Sed // while, for, and switch statements are local to the if, while, for, or 1422193326Sed // switch statement (including the controlled statement). 1423193326Sed // C++ 6.5.3p1: 1424193326Sed // Names declared in the for-init-statement are in the same declarative-region 1425193326Sed // as those declared in the condition. 1426193326Sed // 1427193326Sed unsigned ScopeFlags; 1428193326Sed if (C99orCXXorObjC) 1429193326Sed ScopeFlags = Scope::BreakScope | Scope::ContinueScope | 1430193326Sed Scope::DeclScope | Scope::ControlScope; 1431193326Sed else 1432193326Sed ScopeFlags = Scope::BreakScope | Scope::ContinueScope; 1433193326Sed 1434193326Sed ParseScope ForScope(this, ScopeFlags); 1435193326Sed 1436226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 1437226633Sdim T.consumeOpen(); 1438226633Sdim 1439212904Sdim ExprResult Value; 1440193326Sed 1441221345Sdim bool ForEach = false, ForRange = false; 1442212904Sdim StmtResult FirstPart; 1443208600Srdivacky bool SecondPartIsInvalid = false; 1444208600Srdivacky FullExprArg SecondPart(Actions); 1445212904Sdim ExprResult Collection; 1446221345Sdim ForRangeInit ForRangeInit; 1447208600Srdivacky FullExprArg ThirdPart(Actions); 1448212904Sdim Decl *SecondVar = 0; 1449226633Sdim 1450198092Srdivacky if (Tok.is(tok::code_completion)) { 1451226633Sdim Actions.CodeCompleteOrdinaryName(getCurScope(), 1452212904Sdim C99orCXXorObjC? Sema::PCC_ForInit 1453212904Sdim : Sema::PCC_Expression); 1454226633Sdim cutOffParsing(); 1455226633Sdim return StmtError(); 1456198092Srdivacky } 1457226633Sdim 1458239462Sdim ParsedAttributesWithRange attrs(AttrFactory); 1459249423Sdim MaybeParseCXX11Attributes(attrs); 1460239462Sdim 1461193326Sed // Parse the first part of the for specifier. 1462193326Sed if (Tok.is(tok::semi)) { // for (; 1463239462Sdim ProhibitAttributes(attrs); 1464193326Sed // no first part, eat the ';'. 1465193326Sed ConsumeToken(); 1466234353Sdim } else if (isForInitDeclaration()) { // for (int X = 4; 1467193326Sed // Parse declaration, which eats the ';'. 1468193326Sed if (!C99orCXXorObjC) // Use of C99-style for loops in C90 mode? 1469193326Sed Diag(Tok, diag::ext_c99_variable_decl_in_for_loop); 1470193326Sed 1471221345Sdim // In C++0x, "for (T NS:a" might not be a typo for :: 1472234353Sdim bool MightBeForRangeStmt = getLangOpts().CPlusPlus; 1473221345Sdim ColonProtectionRAIIObject ColonProtection(*this, MightBeForRangeStmt); 1474221345Sdim 1475193326Sed SourceLocation DeclStart = Tok.getLocation(), DeclEnd; 1476243830Sdim StmtVector Stmts; 1477226633Sdim DeclGroupPtrTy DG = ParseSimpleDeclaration(Stmts, Declarator::ForContext, 1478221345Sdim DeclEnd, attrs, false, 1479221345Sdim MightBeForRangeStmt ? 1480221345Sdim &ForRangeInit : 0); 1481193326Sed FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation()); 1482198092Srdivacky 1483221345Sdim if (ForRangeInit.ParsedForRangeDecl()) { 1484249423Sdim Diag(ForRangeInit.ColonLoc, getLangOpts().CPlusPlus11 ? 1485234353Sdim diag::warn_cxx98_compat_for_range : diag::ext_for_range); 1486226633Sdim 1487221345Sdim ForRange = true; 1488221345Sdim } else if (Tok.is(tok::semi)) { // for (int x = 4; 1489193326Sed ConsumeToken(); 1490193326Sed } else if ((ForEach = isTokIdentifier_in())) { 1491199990Srdivacky Actions.ActOnForEachDeclStmt(DG); 1492198092Srdivacky // ObjC: for (id x in expr) 1493193326Sed ConsumeToken(); // consume 'in' 1494226633Sdim 1495212904Sdim if (Tok.is(tok::code_completion)) { 1496212904Sdim Actions.CodeCompleteObjCForCollection(getCurScope(), DG); 1497226633Sdim cutOffParsing(); 1498226633Sdim return StmtError(); 1499212904Sdim } 1500208600Srdivacky Collection = ParseExpression(); 1501193326Sed } else { 1502193326Sed Diag(Tok, diag::err_expected_semi_for); 1503193326Sed } 1504193326Sed } else { 1505239462Sdim ProhibitAttributes(attrs); 1506193326Sed Value = ParseExpression(); 1507193326Sed 1508218893Sdim ForEach = isTokIdentifier_in(); 1509218893Sdim 1510193326Sed // Turn the expression into a stmt. 1511218893Sdim if (!Value.isInvalid()) { 1512218893Sdim if (ForEach) 1513218893Sdim FirstPart = Actions.ActOnForEachLValueExpr(Value.get()); 1514218893Sdim else 1515249423Sdim FirstPart = Actions.ActOnExprStmt(Value); 1516218893Sdim } 1517193326Sed 1518193326Sed if (Tok.is(tok::semi)) { 1519193326Sed ConsumeToken(); 1520218893Sdim } else if (ForEach) { 1521193326Sed ConsumeToken(); // consume 'in' 1522226633Sdim 1523212904Sdim if (Tok.is(tok::code_completion)) { 1524212904Sdim Actions.CodeCompleteObjCForCollection(getCurScope(), DeclGroupPtrTy()); 1525226633Sdim cutOffParsing(); 1526226633Sdim return StmtError(); 1527212904Sdim } 1528208600Srdivacky Collection = ParseExpression(); 1529249423Sdim } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::colon) && FirstPart.get()) { 1530234353Sdim // User tried to write the reasonable, but ill-formed, for-range-statement 1531234353Sdim // for (expr : expr) { ... } 1532234353Sdim Diag(Tok, diag::err_for_range_expected_decl) 1533234353Sdim << FirstPart.get()->getSourceRange(); 1534263508Sdim SkipUntil(tok::r_paren, StopBeforeMatch); 1535234353Sdim SecondPartIsInvalid = true; 1536193326Sed } else { 1537218893Sdim if (!Value.isInvalid()) { 1538218893Sdim Diag(Tok, diag::err_expected_semi_for); 1539218893Sdim } else { 1540218893Sdim // Skip until semicolon or rparen, don't consume it. 1541263508Sdim SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch); 1542218893Sdim if (Tok.is(tok::semi)) 1543218893Sdim ConsumeToken(); 1544218893Sdim } 1545193326Sed } 1546193326Sed } 1547221345Sdim if (!ForEach && !ForRange) { 1548212904Sdim assert(!SecondPart.get() && "Shouldn't have a second expression yet."); 1549193326Sed // Parse the second part of the for specifier. 1550193326Sed if (Tok.is(tok::semi)) { // for (...;; 1551193326Sed // no second part. 1552218893Sdim } else if (Tok.is(tok::r_paren)) { 1553218893Sdim // missing both semicolons. 1554193326Sed } else { 1555212904Sdim ExprResult Second; 1556234353Sdim if (getLangOpts().CPlusPlus) 1557208600Srdivacky ParseCXXCondition(Second, SecondVar, ForLoc, true); 1558208600Srdivacky else { 1559208600Srdivacky Second = ParseExpression(); 1560208600Srdivacky if (!Second.isInvalid()) 1561226633Sdim Second = Actions.ActOnBooleanCondition(getCurScope(), ForLoc, 1562212904Sdim Second.get()); 1563208600Srdivacky } 1564208600Srdivacky SecondPartIsInvalid = Second.isInvalid(); 1565239462Sdim SecondPart = Actions.MakeFullExpr(Second.get(), ForLoc); 1566193326Sed } 1567193326Sed 1568218893Sdim if (Tok.isNot(tok::semi)) { 1569218893Sdim if (!SecondPartIsInvalid || SecondVar) 1570218893Sdim Diag(Tok, diag::err_expected_semi_for); 1571218893Sdim else 1572218893Sdim // Skip until semicolon or rparen, don't consume it. 1573263508Sdim SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch); 1574218893Sdim } 1575218893Sdim 1576193326Sed if (Tok.is(tok::semi)) { 1577193326Sed ConsumeToken(); 1578193326Sed } 1579193326Sed 1580193326Sed // Parse the third part of the for specifier. 1581208600Srdivacky if (Tok.isNot(tok::r_paren)) { // for (...;...;) 1582212904Sdim ExprResult Third = ParseExpression(); 1583249423Sdim // FIXME: The C++11 standard doesn't actually say that this is a 1584249423Sdim // discarded-value expression, but it clearly should be. 1585249423Sdim ThirdPart = Actions.MakeFullDiscardedValueExpr(Third.take()); 1586208600Srdivacky } 1587193326Sed } 1588193326Sed // Match the ')'. 1589226633Sdim T.consumeClose(); 1590193326Sed 1591221345Sdim // We need to perform most of the semantic analysis for a C++0x for-range 1592221345Sdim // statememt before parsing the body, in order to be able to deduce the type 1593221345Sdim // of an auto-typed loop variable. 1594221345Sdim StmtResult ForRangeStmt; 1595239462Sdim StmtResult ForEachStmt; 1596239462Sdim 1597226633Sdim if (ForRange) { 1598239462Sdim ForRangeStmt = Actions.ActOnCXXForRangeStmt(ForLoc, FirstPart.take(), 1599221345Sdim ForRangeInit.ColonLoc, 1600221345Sdim ForRangeInit.RangeExpr.get(), 1601243830Sdim T.getCloseLocation(), 1602243830Sdim Sema::BFRK_Build); 1603221345Sdim 1604226633Sdim 1605226633Sdim // Similarly, we need to do the semantic analysis for a for-range 1606226633Sdim // statement immediately in order to close over temporaries correctly. 1607226633Sdim } else if (ForEach) { 1608239462Sdim ForEachStmt = Actions.ActOnObjCForCollectionStmt(ForLoc, 1609239462Sdim FirstPart.take(), 1610239462Sdim Collection.take(), 1611239462Sdim T.getCloseLocation()); 1612226633Sdim } 1613226633Sdim 1614193326Sed // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if 1615193326Sed // there is no compound stmt. C90 does not have this clause. We only do this 1616193326Sed // if the body isn't a compound statement to avoid push/pop in common cases. 1617193326Sed // 1618193326Sed // C++ 6.5p2: 1619193326Sed // The substatement in an iteration-statement implicitly defines a local scope 1620193326Sed // which is entered and exited each time through the loop. 1621193326Sed // 1622193326Sed // See comments in ParseIfStatement for why we create a scope for 1623193326Sed // for-init-statement/condition and a new scope for substatement in C++. 1624193326Sed // 1625198092Srdivacky ParseScope InnerScope(this, Scope::DeclScope, 1626193326Sed C99orCXXorObjC && Tok.isNot(tok::l_brace)); 1627193326Sed 1628193326Sed // Read the body statement. 1629234353Sdim StmtResult Body(ParseStatement(TrailingElseLoc)); 1630193326Sed 1631193326Sed // Pop the body scope if needed. 1632193326Sed InnerScope.Exit(); 1633193326Sed 1634193326Sed // Leave the for-scope. 1635193326Sed ForScope.Exit(); 1636193326Sed 1637193326Sed if (Body.isInvalid()) 1638193326Sed return StmtError(); 1639193326Sed 1640221345Sdim if (ForEach) 1641239462Sdim return Actions.FinishObjCForCollectionStmt(ForEachStmt.take(), 1642239462Sdim Body.take()); 1643198092Srdivacky 1644221345Sdim if (ForRange) 1645221345Sdim return Actions.FinishCXXForRangeStmt(ForRangeStmt.take(), Body.take()); 1646221345Sdim 1647226633Sdim return Actions.ActOnForStmt(ForLoc, T.getOpenLocation(), FirstPart.take(), 1648226633Sdim SecondPart, SecondVar, ThirdPart, 1649226633Sdim T.getCloseLocation(), Body.take()); 1650193326Sed} 1651193326Sed 1652193326Sed/// ParseGotoStatement 1653193326Sed/// jump-statement: 1654193326Sed/// 'goto' identifier ';' 1655193326Sed/// [GNU] 'goto' '*' expression ';' 1656193326Sed/// 1657193326Sed/// Note: this lets the caller parse the end ';'. 1658193326Sed/// 1659234982SdimStmtResult Parser::ParseGotoStatement() { 1660193326Sed assert(Tok.is(tok::kw_goto) && "Not a goto stmt!"); 1661193326Sed SourceLocation GotoLoc = ConsumeToken(); // eat the 'goto'. 1662193326Sed 1663212904Sdim StmtResult Res; 1664193326Sed if (Tok.is(tok::identifier)) { 1665218893Sdim LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(), 1666218893Sdim Tok.getLocation()); 1667218893Sdim Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(), LD); 1668193326Sed ConsumeToken(); 1669193326Sed } else if (Tok.is(tok::star)) { 1670193326Sed // GNU indirect goto extension. 1671193326Sed Diag(Tok, diag::ext_gnu_indirect_goto); 1672193326Sed SourceLocation StarLoc = ConsumeToken(); 1673212904Sdim ExprResult R(ParseExpression()); 1674193326Sed if (R.isInvalid()) { // Skip to the semicolon, but don't consume it. 1675263508Sdim SkipUntil(tok::semi, StopBeforeMatch); 1676193326Sed return StmtError(); 1677193326Sed } 1678212904Sdim Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.take()); 1679193326Sed } else { 1680193326Sed Diag(Tok, diag::err_expected_ident); 1681193326Sed return StmtError(); 1682193326Sed } 1683193326Sed 1684243830Sdim return Res; 1685193326Sed} 1686193326Sed 1687193326Sed/// ParseContinueStatement 1688193326Sed/// jump-statement: 1689193326Sed/// 'continue' ';' 1690193326Sed/// 1691193326Sed/// Note: this lets the caller parse the end ';'. 1692193326Sed/// 1693234982SdimStmtResult Parser::ParseContinueStatement() { 1694193326Sed SourceLocation ContinueLoc = ConsumeToken(); // eat the 'continue'. 1695210299Sed return Actions.ActOnContinueStmt(ContinueLoc, getCurScope()); 1696193326Sed} 1697193326Sed 1698193326Sed/// ParseBreakStatement 1699193326Sed/// jump-statement: 1700193326Sed/// 'break' ';' 1701193326Sed/// 1702193326Sed/// Note: this lets the caller parse the end ';'. 1703193326Sed/// 1704234982SdimStmtResult Parser::ParseBreakStatement() { 1705193326Sed SourceLocation BreakLoc = ConsumeToken(); // eat the 'break'. 1706210299Sed return Actions.ActOnBreakStmt(BreakLoc, getCurScope()); 1707193326Sed} 1708193326Sed 1709193326Sed/// ParseReturnStatement 1710193326Sed/// jump-statement: 1711193326Sed/// 'return' expression[opt] ';' 1712234982SdimStmtResult Parser::ParseReturnStatement() { 1713193326Sed assert(Tok.is(tok::kw_return) && "Not a return stmt!"); 1714193326Sed SourceLocation ReturnLoc = ConsumeToken(); // eat the 'return'. 1715193326Sed 1716212904Sdim ExprResult R; 1717193326Sed if (Tok.isNot(tok::semi)) { 1718210299Sed if (Tok.is(tok::code_completion)) { 1719210299Sed Actions.CodeCompleteReturn(getCurScope()); 1720226633Sdim cutOffParsing(); 1721210299Sed return StmtError(); 1722210299Sed } 1723226633Sdim 1724234353Sdim if (Tok.is(tok::l_brace) && getLangOpts().CPlusPlus) { 1725221345Sdim R = ParseInitializer(); 1726234353Sdim if (R.isUsable()) 1727249423Sdim Diag(R.get()->getLocStart(), getLangOpts().CPlusPlus11 ? 1728234353Sdim diag::warn_cxx98_compat_generalized_initializer_lists : 1729234353Sdim diag::ext_generalized_initializer_lists) 1730221345Sdim << R.get()->getSourceRange(); 1731221345Sdim } else 1732221345Sdim R = ParseExpression(); 1733193326Sed if (R.isInvalid()) { // Skip to the semicolon, but don't consume it. 1734263508Sdim SkipUntil(tok::semi, StopBeforeMatch); 1735193326Sed return StmtError(); 1736193326Sed } 1737193326Sed } 1738212904Sdim return Actions.ActOnReturnStmt(ReturnLoc, R.take()); 1739193326Sed} 1740193326Sed 1741251662Sdimnamespace { 1742251662Sdim class ClangAsmParserCallback : public llvm::MCAsmParserSemaCallback { 1743251662Sdim Parser &TheParser; 1744251662Sdim SourceLocation AsmLoc; 1745251662Sdim StringRef AsmString; 1746251662Sdim 1747251662Sdim /// The tokens we streamed into AsmString and handed off to MC. 1748251662Sdim ArrayRef<Token> AsmToks; 1749251662Sdim 1750251662Sdim /// The offset of each token in AsmToks within AsmString. 1751251662Sdim ArrayRef<unsigned> AsmTokOffsets; 1752251662Sdim 1753251662Sdim public: 1754251662Sdim ClangAsmParserCallback(Parser &P, SourceLocation Loc, 1755251662Sdim StringRef AsmString, 1756251662Sdim ArrayRef<Token> Toks, 1757251662Sdim ArrayRef<unsigned> Offsets) 1758251662Sdim : TheParser(P), AsmLoc(Loc), AsmString(AsmString), 1759251662Sdim AsmToks(Toks), AsmTokOffsets(Offsets) { 1760251662Sdim assert(AsmToks.size() == AsmTokOffsets.size()); 1761251662Sdim } 1762251662Sdim 1763251662Sdim void *LookupInlineAsmIdentifier(StringRef &LineBuf, 1764251662Sdim InlineAsmIdentifierInfo &Info, 1765251662Sdim bool IsUnevaluatedContext) { 1766251662Sdim // Collect the desired tokens. 1767251662Sdim SmallVector<Token, 16> LineToks; 1768251662Sdim const Token *FirstOrigToken = 0; 1769251662Sdim findTokensForString(LineBuf, LineToks, FirstOrigToken); 1770251662Sdim 1771251662Sdim unsigned NumConsumedToks; 1772251662Sdim ExprResult Result = 1773251662Sdim TheParser.ParseMSAsmIdentifier(LineToks, NumConsumedToks, &Info, 1774251662Sdim IsUnevaluatedContext); 1775251662Sdim 1776251662Sdim // If we consumed the entire line, tell MC that. 1777251662Sdim // Also do this if we consumed nothing as a way of reporting failure. 1778251662Sdim if (NumConsumedToks == 0 || NumConsumedToks == LineToks.size()) { 1779251662Sdim // By not modifying LineBuf, we're implicitly consuming it all. 1780251662Sdim 1781251662Sdim // Otherwise, consume up to the original tokens. 1782251662Sdim } else { 1783251662Sdim assert(FirstOrigToken && "not using original tokens?"); 1784251662Sdim 1785251662Sdim // Since we're using original tokens, apply that offset. 1786251662Sdim assert(FirstOrigToken[NumConsumedToks].getLocation() 1787251662Sdim == LineToks[NumConsumedToks].getLocation()); 1788251662Sdim unsigned FirstIndex = FirstOrigToken - AsmToks.begin(); 1789251662Sdim unsigned LastIndex = FirstIndex + NumConsumedToks - 1; 1790251662Sdim 1791251662Sdim // The total length we've consumed is the relative offset 1792251662Sdim // of the last token we consumed plus its length. 1793251662Sdim unsigned TotalOffset = (AsmTokOffsets[LastIndex] 1794251662Sdim + AsmToks[LastIndex].getLength() 1795251662Sdim - AsmTokOffsets[FirstIndex]); 1796251662Sdim LineBuf = LineBuf.substr(0, TotalOffset); 1797251662Sdim } 1798251662Sdim 1799251662Sdim // Initialize the "decl" with the lookup result. 1800251662Sdim Info.OpDecl = static_cast<void*>(Result.take()); 1801251662Sdim return Info.OpDecl; 1802251662Sdim } 1803251662Sdim 1804251662Sdim bool LookupInlineAsmField(StringRef Base, StringRef Member, 1805251662Sdim unsigned &Offset) { 1806251662Sdim return TheParser.getActions().LookupInlineAsmField(Base, Member, 1807251662Sdim Offset, AsmLoc); 1808251662Sdim } 1809251662Sdim 1810251662Sdim static void DiagHandlerCallback(const llvm::SMDiagnostic &D, 1811251662Sdim void *Context) { 1812251662Sdim ((ClangAsmParserCallback*) Context)->handleDiagnostic(D); 1813251662Sdim } 1814251662Sdim 1815251662Sdim private: 1816251662Sdim /// Collect the appropriate tokens for the given string. 1817251662Sdim void findTokensForString(StringRef Str, SmallVectorImpl<Token> &TempToks, 1818251662Sdim const Token *&FirstOrigToken) const { 1819251662Sdim // For now, assert that the string we're working with is a substring 1820251662Sdim // of what we gave to MC. This lets us use the original tokens. 1821251662Sdim assert(!std::less<const char*>()(Str.begin(), AsmString.begin()) && 1822251662Sdim !std::less<const char*>()(AsmString.end(), Str.end())); 1823251662Sdim 1824251662Sdim // Try to find a token whose offset matches the first token. 1825251662Sdim unsigned FirstCharOffset = Str.begin() - AsmString.begin(); 1826251662Sdim const unsigned *FirstTokOffset 1827251662Sdim = std::lower_bound(AsmTokOffsets.begin(), AsmTokOffsets.end(), 1828251662Sdim FirstCharOffset); 1829251662Sdim 1830251662Sdim // For now, assert that the start of the string exactly 1831251662Sdim // corresponds to the start of a token. 1832251662Sdim assert(*FirstTokOffset == FirstCharOffset); 1833251662Sdim 1834251662Sdim // Use all the original tokens for this line. (We assume the 1835251662Sdim // end of the line corresponds cleanly to a token break.) 1836251662Sdim unsigned FirstTokIndex = FirstTokOffset - AsmTokOffsets.begin(); 1837251662Sdim FirstOrigToken = &AsmToks[FirstTokIndex]; 1838251662Sdim unsigned LastCharOffset = Str.end() - AsmString.begin(); 1839251662Sdim for (unsigned i = FirstTokIndex, e = AsmTokOffsets.size(); i != e; ++i) { 1840251662Sdim if (AsmTokOffsets[i] >= LastCharOffset) break; 1841251662Sdim TempToks.push_back(AsmToks[i]); 1842251662Sdim } 1843251662Sdim } 1844251662Sdim 1845251662Sdim void handleDiagnostic(const llvm::SMDiagnostic &D) { 1846251662Sdim // Compute an offset into the inline asm buffer. 1847251662Sdim // FIXME: This isn't right if .macro is involved (but hopefully, no 1848251662Sdim // real-world code does that). 1849251662Sdim const llvm::SourceMgr &LSM = *D.getSourceMgr(); 1850251662Sdim const llvm::MemoryBuffer *LBuf = 1851251662Sdim LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc())); 1852251662Sdim unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart(); 1853251662Sdim 1854251662Sdim // Figure out which token that offset points into. 1855251662Sdim const unsigned *TokOffsetPtr = 1856251662Sdim std::lower_bound(AsmTokOffsets.begin(), AsmTokOffsets.end(), Offset); 1857251662Sdim unsigned TokIndex = TokOffsetPtr - AsmTokOffsets.begin(); 1858251662Sdim unsigned TokOffset = *TokOffsetPtr; 1859251662Sdim 1860251662Sdim // If we come up with an answer which seems sane, use it; otherwise, 1861251662Sdim // just point at the __asm keyword. 1862251662Sdim // FIXME: Assert the answer is sane once we handle .macro correctly. 1863251662Sdim SourceLocation Loc = AsmLoc; 1864251662Sdim if (TokIndex < AsmToks.size()) { 1865251662Sdim const Token &Tok = AsmToks[TokIndex]; 1866251662Sdim Loc = Tok.getLocation(); 1867251662Sdim Loc = Loc.getLocWithOffset(Offset - TokOffset); 1868251662Sdim } 1869251662Sdim TheParser.Diag(Loc, diag::err_inline_ms_asm_parsing) 1870251662Sdim << D.getMessage(); 1871251662Sdim } 1872251662Sdim }; 1873251662Sdim} 1874251662Sdim 1875251662Sdim/// Parse an identifier in an MS-style inline assembly block. 1876251662Sdim/// 1877251662Sdim/// \param CastInfo - a void* so that we don't have to teach Parser.h 1878251662Sdim/// about the actual type. 1879251662SdimExprResult Parser::ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks, 1880251662Sdim unsigned &NumLineToksConsumed, 1881251662Sdim void *CastInfo, 1882251662Sdim bool IsUnevaluatedContext) { 1883251662Sdim llvm::InlineAsmIdentifierInfo &Info = 1884251662Sdim *(llvm::InlineAsmIdentifierInfo *) CastInfo; 1885251662Sdim 1886251662Sdim // Push a fake token on the end so that we don't overrun the token 1887251662Sdim // stream. We use ';' because it expression-parsing should never 1888251662Sdim // overrun it. 1889251662Sdim const tok::TokenKind EndOfStream = tok::semi; 1890251662Sdim Token EndOfStreamTok; 1891251662Sdim EndOfStreamTok.startToken(); 1892251662Sdim EndOfStreamTok.setKind(EndOfStream); 1893251662Sdim LineToks.push_back(EndOfStreamTok); 1894251662Sdim 1895251662Sdim // Also copy the current token over. 1896251662Sdim LineToks.push_back(Tok); 1897251662Sdim 1898251662Sdim PP.EnterTokenStream(LineToks.begin(), 1899251662Sdim LineToks.size(), 1900251662Sdim /*disable macros*/ true, 1901251662Sdim /*owns tokens*/ false); 1902251662Sdim 1903251662Sdim // Clear the current token and advance to the first token in LineToks. 1904251662Sdim ConsumeAnyToken(); 1905251662Sdim 1906251662Sdim // Parse an optional scope-specifier if we're in C++. 1907251662Sdim CXXScopeSpec SS; 1908251662Sdim if (getLangOpts().CPlusPlus) { 1909251662Sdim ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); 1910251662Sdim } 1911251662Sdim 1912251662Sdim // Require an identifier here. 1913251662Sdim SourceLocation TemplateKWLoc; 1914251662Sdim UnqualifiedId Id; 1915251662Sdim bool Invalid = ParseUnqualifiedId(SS, 1916251662Sdim /*EnteringContext=*/false, 1917251662Sdim /*AllowDestructorName=*/false, 1918251662Sdim /*AllowConstructorName=*/false, 1919251662Sdim /*ObjectType=*/ ParsedType(), 1920251662Sdim TemplateKWLoc, 1921251662Sdim Id); 1922251662Sdim 1923251662Sdim // If we've run into the poison token we inserted before, or there 1924251662Sdim // was a parsing error, then claim the entire line. 1925251662Sdim if (Invalid || Tok.is(EndOfStream)) { 1926251662Sdim NumLineToksConsumed = LineToks.size() - 2; 1927251662Sdim 1928251662Sdim // Otherwise, claim up to the start of the next token. 1929251662Sdim } else { 1930251662Sdim // Figure out how many tokens we are into LineToks. 1931251662Sdim unsigned LineIndex = 0; 1932251662Sdim while (LineToks[LineIndex].getLocation() != Tok.getLocation()) { 1933251662Sdim LineIndex++; 1934251662Sdim assert(LineIndex < LineToks.size() - 2); // we added two extra tokens 1935251662Sdim } 1936251662Sdim 1937251662Sdim NumLineToksConsumed = LineIndex; 1938251662Sdim } 1939251662Sdim 1940251662Sdim // Finally, restore the old parsing state by consuming all the 1941251662Sdim // tokens we staged before, implicitly killing off the 1942251662Sdim // token-lexer we pushed. 1943251662Sdim for (unsigned n = LineToks.size() - 2 - NumLineToksConsumed; n != 0; --n) { 1944251662Sdim ConsumeAnyToken(); 1945251662Sdim } 1946251662Sdim ConsumeToken(EndOfStream); 1947251662Sdim 1948251662Sdim // Leave LineToks in its original state. 1949251662Sdim LineToks.pop_back(); 1950251662Sdim LineToks.pop_back(); 1951251662Sdim 1952251662Sdim // Perform the lookup. 1953251662Sdim return Actions.LookupInlineAsmIdentifier(SS, TemplateKWLoc, Id, Info, 1954251662Sdim IsUnevaluatedContext); 1955251662Sdim} 1956251662Sdim 1957251662Sdim/// Turn a sequence of our tokens back into a string that we can hand 1958251662Sdim/// to the MC asm parser. 1959251662Sdimstatic bool buildMSAsmString(Preprocessor &PP, 1960251662Sdim SourceLocation AsmLoc, 1961251662Sdim ArrayRef<Token> AsmToks, 1962251662Sdim SmallVectorImpl<unsigned> &TokOffsets, 1963251662Sdim SmallString<512> &Asm) { 1964251662Sdim assert (!AsmToks.empty() && "Didn't expect an empty AsmToks!"); 1965251662Sdim 1966251662Sdim // Is this the start of a new assembly statement? 1967251662Sdim bool isNewStatement = true; 1968251662Sdim 1969251662Sdim for (unsigned i = 0, e = AsmToks.size(); i < e; ++i) { 1970251662Sdim const Token &Tok = AsmToks[i]; 1971251662Sdim 1972251662Sdim // Start each new statement with a newline and a tab. 1973251662Sdim if (!isNewStatement && 1974251662Sdim (Tok.is(tok::kw_asm) || Tok.isAtStartOfLine())) { 1975251662Sdim Asm += "\n\t"; 1976251662Sdim isNewStatement = true; 1977251662Sdim } 1978251662Sdim 1979251662Sdim // Preserve the existence of leading whitespace except at the 1980251662Sdim // start of a statement. 1981251662Sdim if (!isNewStatement && Tok.hasLeadingSpace()) 1982251662Sdim Asm += ' '; 1983251662Sdim 1984251662Sdim // Remember the offset of this token. 1985251662Sdim TokOffsets.push_back(Asm.size()); 1986251662Sdim 1987251662Sdim // Don't actually write '__asm' into the assembly stream. 1988251662Sdim if (Tok.is(tok::kw_asm)) { 1989251662Sdim // Complain about __asm at the end of the stream. 1990251662Sdim if (i + 1 == e) { 1991251662Sdim PP.Diag(AsmLoc, diag::err_asm_empty); 1992251662Sdim return true; 1993251662Sdim } 1994251662Sdim 1995251662Sdim continue; 1996251662Sdim } 1997251662Sdim 1998251662Sdim // Append the spelling of the token. 1999251662Sdim SmallString<32> SpellingBuffer; 2000251662Sdim bool SpellingInvalid = false; 2001251662Sdim Asm += PP.getSpelling(Tok, SpellingBuffer, &SpellingInvalid); 2002251662Sdim assert(!SpellingInvalid && "spelling was invalid after correct parse?"); 2003251662Sdim 2004251662Sdim // We are no longer at the start of a statement. 2005251662Sdim isNewStatement = false; 2006251662Sdim } 2007251662Sdim 2008251662Sdim // Ensure that the buffer is null-terminated. 2009251662Sdim Asm.push_back('\0'); 2010251662Sdim Asm.pop_back(); 2011251662Sdim 2012251662Sdim assert(TokOffsets.size() == AsmToks.size()); 2013251662Sdim return false; 2014251662Sdim} 2015251662Sdim 2016226633Sdim/// ParseMicrosoftAsmStatement. When -fms-extensions/-fasm-blocks is enabled, 2017226633Sdim/// this routine is called to collect the tokens for an MS asm statement. 2018239462Sdim/// 2019239462Sdim/// [MS] ms-asm-statement: 2020239462Sdim/// ms-asm-block 2021239462Sdim/// ms-asm-block ms-asm-statement 2022239462Sdim/// 2023239462Sdim/// [MS] ms-asm-block: 2024239462Sdim/// '__asm' ms-asm-line '\n' 2025239462Sdim/// '__asm' '{' ms-asm-instruction-block[opt] '}' ';'[opt] 2026239462Sdim/// 2027239462Sdim/// [MS] ms-asm-instruction-block 2028239462Sdim/// ms-asm-line 2029239462Sdim/// ms-asm-line '\n' ms-asm-instruction-block 2030239462Sdim/// 2031226633SdimStmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) { 2032226633Sdim SourceManager &SrcMgr = PP.getSourceManager(); 2033226633Sdim SourceLocation EndLoc = AsmLoc; 2034239462Sdim SmallVector<Token, 4> AsmToks; 2035226633Sdim 2036239462Sdim bool InBraces = false; 2037239462Sdim unsigned short savedBraceCount = 0; 2038239462Sdim bool InAsmComment = false; 2039239462Sdim FileID FID; 2040239462Sdim unsigned LineNo = 0; 2041239462Sdim unsigned NumTokensRead = 0; 2042239462Sdim SourceLocation LBraceLoc; 2043226633Sdim 2044239462Sdim if (Tok.is(tok::l_brace)) { 2045239462Sdim // Braced inline asm: consume the opening brace. 2046239462Sdim InBraces = true; 2047239462Sdim savedBraceCount = BraceCount; 2048239462Sdim EndLoc = LBraceLoc = ConsumeBrace(); 2049239462Sdim ++NumTokensRead; 2050239462Sdim } else { 2051239462Sdim // Single-line inline asm; compute which line it is on. 2052239462Sdim std::pair<FileID, unsigned> ExpAsmLoc = 2053239462Sdim SrcMgr.getDecomposedExpansionLoc(EndLoc); 2054239462Sdim FID = ExpAsmLoc.first; 2055239462Sdim LineNo = SrcMgr.getLineNumber(FID, ExpAsmLoc.second); 2056239462Sdim } 2057226633Sdim 2058239462Sdim SourceLocation TokLoc = Tok.getLocation(); 2059239462Sdim do { 2060239462Sdim // If we hit EOF, we're done, period. 2061239462Sdim if (Tok.is(tok::eof)) 2062239462Sdim break; 2063239462Sdim 2064239462Sdim if (!InAsmComment && Tok.is(tok::semi)) { 2065239462Sdim // A semicolon in an asm is the start of a comment. 2066239462Sdim InAsmComment = true; 2067239462Sdim if (InBraces) { 2068239462Sdim // Compute which line the comment is on. 2069239462Sdim std::pair<FileID, unsigned> ExpSemiLoc = 2070239462Sdim SrcMgr.getDecomposedExpansionLoc(TokLoc); 2071239462Sdim FID = ExpSemiLoc.first; 2072239462Sdim LineNo = SrcMgr.getLineNumber(FID, ExpSemiLoc.second); 2073239462Sdim } 2074239462Sdim } else if (!InBraces || InAsmComment) { 2075239462Sdim // If end-of-line is significant, check whether this token is on a 2076239462Sdim // new line. 2077239462Sdim std::pair<FileID, unsigned> ExpLoc = 2078239462Sdim SrcMgr.getDecomposedExpansionLoc(TokLoc); 2079239462Sdim if (ExpLoc.first != FID || 2080239462Sdim SrcMgr.getLineNumber(ExpLoc.first, ExpLoc.second) != LineNo) { 2081239462Sdim // If this is a single-line __asm, we're done. 2082239462Sdim if (!InBraces) 2083226633Sdim break; 2084239462Sdim // We're no longer in a comment. 2085239462Sdim InAsmComment = false; 2086239462Sdim } else if (!InAsmComment && Tok.is(tok::r_brace)) { 2087239462Sdim // Single-line asm always ends when a closing brace is seen. 2088239462Sdim // FIXME: This is compatible with Apple gcc's -fasm-blocks; what 2089239462Sdim // does MSVC do here? 2090239462Sdim break; 2091226633Sdim } 2092239462Sdim } 2093239462Sdim if (!InAsmComment && InBraces && Tok.is(tok::r_brace) && 2094239462Sdim BraceCount == (savedBraceCount + 1)) { 2095239462Sdim // Consume the closing brace, and finish 2096239462Sdim EndLoc = ConsumeBrace(); 2097239462Sdim break; 2098239462Sdim } 2099226633Sdim 2100239462Sdim // Consume the next token; make sure we don't modify the brace count etc. 2101239462Sdim // if we are in a comment. 2102239462Sdim EndLoc = TokLoc; 2103239462Sdim if (InAsmComment) 2104239462Sdim PP.Lex(Tok); 2105239462Sdim else { 2106239462Sdim AsmToks.push_back(Tok); 2107239462Sdim ConsumeAnyToken(); 2108226633Sdim } 2109239462Sdim TokLoc = Tok.getLocation(); 2110239462Sdim ++NumTokensRead; 2111226633Sdim } while (1); 2112239462Sdim 2113239462Sdim if (InBraces && BraceCount != savedBraceCount) { 2114239462Sdim // __asm without closing brace (this can happen at EOF). 2115239462Sdim Diag(Tok, diag::err_expected_rbrace); 2116239462Sdim Diag(LBraceLoc, diag::note_matching) << "{"; 2117239462Sdim return StmtError(); 2118239462Sdim } else if (NumTokensRead == 0) { 2119239462Sdim // Empty __asm. 2120239462Sdim Diag(Tok, diag::err_expected_lbrace); 2121239462Sdim return StmtError(); 2122239462Sdim } 2123239462Sdim 2124251662Sdim // Okay, prepare to use MC to parse the assembly. 2125251662Sdim SmallVector<StringRef, 4> ConstraintRefs; 2126251662Sdim SmallVector<Expr*, 4> Exprs; 2127251662Sdim SmallVector<StringRef, 4> ClobberRefs; 2128251662Sdim 2129251662Sdim // We need an actual supported target. 2130251662Sdim llvm::Triple TheTriple = Actions.Context.getTargetInfo().getTriple(); 2131251662Sdim llvm::Triple::ArchType ArchTy = TheTriple.getArch(); 2132263508Sdim const std::string &TT = TheTriple.getTriple(); 2133263508Sdim const llvm::Target *TheTarget = 0; 2134251662Sdim bool UnsupportedArch = (ArchTy != llvm::Triple::x86 && 2135251662Sdim ArchTy != llvm::Triple::x86_64); 2136263508Sdim if (UnsupportedArch) { 2137251662Sdim Diag(AsmLoc, diag::err_msasm_unsupported_arch) << TheTriple.getArchName(); 2138263508Sdim } else { 2139263508Sdim std::string Error; 2140263508Sdim TheTarget = llvm::TargetRegistry::lookupTarget(TT, Error); 2141263508Sdim if (!TheTarget) 2142263508Sdim Diag(AsmLoc, diag::err_msasm_unable_to_create_target) << Error; 2143263508Sdim } 2144263508Sdim 2145251662Sdim // If we don't support assembly, or the assembly is empty, we don't 2146251662Sdim // need to instantiate the AsmParser, etc. 2147263508Sdim if (!TheTarget || AsmToks.empty()) { 2148251662Sdim return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, StringRef(), 2149251662Sdim /*NumOutputs*/ 0, /*NumInputs*/ 0, 2150251662Sdim ConstraintRefs, ClobberRefs, Exprs, EndLoc); 2151251662Sdim } 2152251662Sdim 2153251662Sdim // Expand the tokens into a string buffer. 2154251662Sdim SmallString<512> AsmString; 2155251662Sdim SmallVector<unsigned, 8> TokOffsets; 2156251662Sdim if (buildMSAsmString(PP, AsmLoc, AsmToks, TokOffsets, AsmString)) 2157251662Sdim return StmtError(); 2158251662Sdim 2159251662Sdim OwningPtr<llvm::MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TT)); 2160263508Sdim OwningPtr<llvm::MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TT)); 2161263508Sdim // Get the instruction descriptor. 2162263508Sdim const llvm::MCInstrInfo *MII = TheTarget->createMCInstrInfo(); 2163251662Sdim OwningPtr<llvm::MCObjectFileInfo> MOFI(new llvm::MCObjectFileInfo()); 2164251662Sdim OwningPtr<llvm::MCSubtargetInfo> 2165251662Sdim STI(TheTarget->createMCSubtargetInfo(TT, "", "")); 2166251662Sdim 2167251662Sdim llvm::SourceMgr TempSrcMgr; 2168263508Sdim llvm::MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &TempSrcMgr); 2169251662Sdim llvm::MemoryBuffer *Buffer = 2170251662Sdim llvm::MemoryBuffer::getMemBuffer(AsmString, "<MS inline asm>"); 2171251662Sdim 2172251662Sdim // Tell SrcMgr about this buffer, which is what the parser will pick up. 2173251662Sdim TempSrcMgr.AddNewSourceBuffer(Buffer, llvm::SMLoc()); 2174251662Sdim 2175251662Sdim OwningPtr<llvm::MCStreamer> Str(createNullStreamer(Ctx)); 2176251662Sdim OwningPtr<llvm::MCAsmParser> 2177251662Sdim Parser(createMCAsmParser(TempSrcMgr, Ctx, *Str.get(), *MAI)); 2178251662Sdim OwningPtr<llvm::MCTargetAsmParser> 2179263508Sdim TargetParser(TheTarget->createMCAsmParser(*STI, *Parser, *MII)); 2180251662Sdim 2181251662Sdim llvm::MCInstPrinter *IP = 2182251662Sdim TheTarget->createMCInstPrinter(1, *MAI, *MII, *MRI, *STI); 2183251662Sdim 2184251662Sdim // Change to the Intel dialect. 2185251662Sdim Parser->setAssemblerDialect(1); 2186251662Sdim Parser->setTargetParser(*TargetParser.get()); 2187251662Sdim Parser->setParsingInlineAsm(true); 2188251662Sdim TargetParser->setParsingInlineAsm(true); 2189251662Sdim 2190251662Sdim ClangAsmParserCallback Callback(*this, AsmLoc, AsmString, 2191251662Sdim AsmToks, TokOffsets); 2192251662Sdim TargetParser->setSemaCallback(&Callback); 2193251662Sdim TempSrcMgr.setDiagHandler(ClangAsmParserCallback::DiagHandlerCallback, 2194251662Sdim &Callback); 2195251662Sdim 2196251662Sdim unsigned NumOutputs; 2197251662Sdim unsigned NumInputs; 2198251662Sdim std::string AsmStringIR; 2199251662Sdim SmallVector<std::pair<void *, bool>, 4> OpExprs; 2200251662Sdim SmallVector<std::string, 4> Constraints; 2201251662Sdim SmallVector<std::string, 4> Clobbers; 2202251662Sdim if (Parser->parseMSInlineAsm(AsmLoc.getPtrEncoding(), AsmStringIR, 2203251662Sdim NumOutputs, NumInputs, OpExprs, Constraints, 2204251662Sdim Clobbers, MII, IP, Callback)) 2205251662Sdim return StmtError(); 2206251662Sdim 2207251662Sdim // Build the vector of clobber StringRefs. 2208251662Sdim unsigned NumClobbers = Clobbers.size(); 2209251662Sdim ClobberRefs.resize(NumClobbers); 2210251662Sdim for (unsigned i = 0; i != NumClobbers; ++i) 2211251662Sdim ClobberRefs[i] = StringRef(Clobbers[i]); 2212251662Sdim 2213251662Sdim // Recast the void pointers and build the vector of constraint StringRefs. 2214251662Sdim unsigned NumExprs = NumOutputs + NumInputs; 2215251662Sdim ConstraintRefs.resize(NumExprs); 2216251662Sdim Exprs.resize(NumExprs); 2217251662Sdim for (unsigned i = 0, e = NumExprs; i != e; ++i) { 2218251662Sdim Expr *OpExpr = static_cast<Expr *>(OpExprs[i].first); 2219251662Sdim if (!OpExpr) 2220251662Sdim return StmtError(); 2221251662Sdim 2222251662Sdim // Need address of variable. 2223251662Sdim if (OpExprs[i].second) 2224251662Sdim OpExpr = Actions.BuildUnaryOp(getCurScope(), AsmLoc, UO_AddrOf, OpExpr) 2225251662Sdim .take(); 2226251662Sdim 2227251662Sdim ConstraintRefs[i] = StringRef(Constraints[i]); 2228251662Sdim Exprs[i] = OpExpr; 2229251662Sdim } 2230251662Sdim 2231239462Sdim // FIXME: We should be passing source locations for better diagnostics. 2232251662Sdim return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmStringIR, 2233251662Sdim NumOutputs, NumInputs, 2234251662Sdim ConstraintRefs, ClobberRefs, Exprs, EndLoc); 2235193326Sed} 2236193326Sed 2237193326Sed/// ParseAsmStatement - Parse a GNU extended asm statement. 2238193326Sed/// asm-statement: 2239193326Sed/// gnu-asm-statement 2240193326Sed/// ms-asm-statement 2241193326Sed/// 2242193326Sed/// [GNU] gnu-asm-statement: 2243193326Sed/// 'asm' type-qualifier[opt] '(' asm-argument ')' ';' 2244193326Sed/// 2245193326Sed/// [GNU] asm-argument: 2246193326Sed/// asm-string-literal 2247193326Sed/// asm-string-literal ':' asm-operands[opt] 2248193326Sed/// asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt] 2249193326Sed/// asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt] 2250193326Sed/// ':' asm-clobbers 2251193326Sed/// 2252193326Sed/// [GNU] asm-clobbers: 2253193326Sed/// asm-string-literal 2254193326Sed/// asm-clobbers ',' asm-string-literal 2255193326Sed/// 2256212904SdimStmtResult Parser::ParseAsmStatement(bool &msAsm) { 2257193326Sed assert(Tok.is(tok::kw_asm) && "Not an asm stmt"); 2258193326Sed SourceLocation AsmLoc = ConsumeToken(); 2259193326Sed 2260249423Sdim if (getLangOpts().AsmBlocks && Tok.isNot(tok::l_paren) && 2261239462Sdim !isTypeQualifier()) { 2262193326Sed msAsm = true; 2263226633Sdim return ParseMicrosoftAsmStatement(AsmLoc); 2264193326Sed } 2265221345Sdim DeclSpec DS(AttrFactory); 2266193326Sed SourceLocation Loc = Tok.getLocation(); 2267199990Srdivacky ParseTypeQualifierListOpt(DS, true, false); 2268193326Sed 2269193326Sed // GNU asms accept, but warn, about type-qualifiers other than volatile. 2270193326Sed if (DS.getTypeQualifiers() & DeclSpec::TQ_const) 2271193326Sed Diag(Loc, diag::w_asm_qualifier_ignored) << "const"; 2272193326Sed if (DS.getTypeQualifiers() & DeclSpec::TQ_restrict) 2273193326Sed Diag(Loc, diag::w_asm_qualifier_ignored) << "restrict"; 2274249423Sdim // FIXME: Once GCC supports _Atomic, check whether it permits it here. 2275249423Sdim if (DS.getTypeQualifiers() & DeclSpec::TQ_atomic) 2276249423Sdim Diag(Loc, diag::w_asm_qualifier_ignored) << "_Atomic"; 2277193326Sed 2278193326Sed // Remember if this was a volatile asm. 2279193326Sed bool isVolatile = DS.getTypeQualifiers() & DeclSpec::TQ_volatile; 2280193326Sed if (Tok.isNot(tok::l_paren)) { 2281193326Sed Diag(Tok, diag::err_expected_lparen_after) << "asm"; 2282263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 2283193326Sed return StmtError(); 2284193326Sed } 2285226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 2286226633Sdim T.consumeOpen(); 2287193326Sed 2288212904Sdim ExprResult AsmString(ParseAsmStringLiteral()); 2289234353Sdim if (AsmString.isInvalid()) { 2290234353Sdim // Consume up to and including the closing paren. 2291234353Sdim T.skipToEnd(); 2292193326Sed return StmtError(); 2293234353Sdim } 2294193326Sed 2295226633Sdim SmallVector<IdentifierInfo *, 4> Names; 2296243830Sdim ExprVector Constraints; 2297243830Sdim ExprVector Exprs; 2298243830Sdim ExprVector Clobbers; 2299193326Sed 2300193326Sed if (Tok.is(tok::r_paren)) { 2301201361Srdivacky // We have a simple asm expression like 'asm("foo")'. 2302226633Sdim T.consumeClose(); 2303243830Sdim return Actions.ActOnGCCAsmStmt(AsmLoc, /*isSimple*/ true, isVolatile, 2304243830Sdim /*NumOutputs*/ 0, /*NumInputs*/ 0, 0, 2305243830Sdim Constraints, Exprs, AsmString.take(), 2306243830Sdim Clobbers, T.getCloseLocation()); 2307201361Srdivacky } 2308193326Sed 2309201361Srdivacky // Parse Outputs, if present. 2310201361Srdivacky bool AteExtraColon = false; 2311201361Srdivacky if (Tok.is(tok::colon) || Tok.is(tok::coloncolon)) { 2312201361Srdivacky // In C++ mode, parse "::" like ": :". 2313201361Srdivacky AteExtraColon = Tok.is(tok::coloncolon); 2314201361Srdivacky ConsumeToken(); 2315226633Sdim 2316201361Srdivacky if (!AteExtraColon && 2317201361Srdivacky ParseAsmOperandsOpt(Names, Constraints, Exprs)) 2318201361Srdivacky return StmtError(); 2319201361Srdivacky } 2320226633Sdim 2321201361Srdivacky unsigned NumOutputs = Names.size(); 2322193326Sed 2323201361Srdivacky // Parse Inputs, if present. 2324201361Srdivacky if (AteExtraColon || 2325201361Srdivacky Tok.is(tok::colon) || Tok.is(tok::coloncolon)) { 2326201361Srdivacky // In C++ mode, parse "::" like ": :". 2327201361Srdivacky if (AteExtraColon) 2328201361Srdivacky AteExtraColon = false; 2329201361Srdivacky else { 2330201361Srdivacky AteExtraColon = Tok.is(tok::coloncolon); 2331201361Srdivacky ConsumeToken(); 2332201361Srdivacky } 2333226633Sdim 2334201361Srdivacky if (!AteExtraColon && 2335201361Srdivacky ParseAsmOperandsOpt(Names, Constraints, Exprs)) 2336201361Srdivacky return StmtError(); 2337201361Srdivacky } 2338193326Sed 2339201361Srdivacky assert(Names.size() == Constraints.size() && 2340201361Srdivacky Constraints.size() == Exprs.size() && 2341201361Srdivacky "Input operand size mismatch!"); 2342193326Sed 2343201361Srdivacky unsigned NumInputs = Names.size() - NumOutputs; 2344193326Sed 2345201361Srdivacky // Parse the clobbers, if present. 2346201361Srdivacky if (AteExtraColon || Tok.is(tok::colon)) { 2347201361Srdivacky if (!AteExtraColon) 2348193326Sed ConsumeToken(); 2349193326Sed 2350212904Sdim // Parse the asm-string list for clobbers if present. 2351212904Sdim if (Tok.isNot(tok::r_paren)) { 2352212904Sdim while (1) { 2353212904Sdim ExprResult Clobber(ParseAsmStringLiteral()); 2354193326Sed 2355212904Sdim if (Clobber.isInvalid()) 2356212904Sdim break; 2357193326Sed 2358212904Sdim Clobbers.push_back(Clobber.release()); 2359193326Sed 2360212904Sdim if (Tok.isNot(tok::comma)) break; 2361212904Sdim ConsumeToken(); 2362212904Sdim } 2363193326Sed } 2364193326Sed } 2365193326Sed 2366226633Sdim T.consumeClose(); 2367243830Sdim return Actions.ActOnGCCAsmStmt(AsmLoc, false, isVolatile, NumOutputs, 2368243830Sdim NumInputs, Names.data(), Constraints, Exprs, 2369243830Sdim AsmString.take(), Clobbers, 2370243830Sdim T.getCloseLocation()); 2371193326Sed} 2372193326Sed 2373193326Sed/// ParseAsmOperands - Parse the asm-operands production as used by 2374201361Srdivacky/// asm-statement, assuming the leading ':' token was eaten. 2375193326Sed/// 2376193326Sed/// [GNU] asm-operands: 2377193326Sed/// asm-operand 2378193326Sed/// asm-operands ',' asm-operand 2379193326Sed/// 2380193326Sed/// [GNU] asm-operand: 2381193326Sed/// asm-string-literal '(' expression ')' 2382193326Sed/// '[' identifier ']' asm-string-literal '(' expression ')' 2383193326Sed/// 2384198398Srdivacky// 2385198398Srdivacky// FIXME: Avoid unnecessary std::string trashing. 2386226633Sdimbool Parser::ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names, 2387226633Sdim SmallVectorImpl<Expr *> &Constraints, 2388226633Sdim SmallVectorImpl<Expr *> &Exprs) { 2389193326Sed // 'asm-operands' isn't present? 2390193326Sed if (!isTokenStringLiteral() && Tok.isNot(tok::l_square)) 2391193326Sed return false; 2392198092Srdivacky 2393198092Srdivacky while (1) { 2394193326Sed // Read the [id] if present. 2395193326Sed if (Tok.is(tok::l_square)) { 2396226633Sdim BalancedDelimiterTracker T(*this, tok::l_square); 2397226633Sdim T.consumeOpen(); 2398198092Srdivacky 2399193326Sed if (Tok.isNot(tok::identifier)) { 2400193326Sed Diag(Tok, diag::err_expected_ident); 2401263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 2402193326Sed return true; 2403193326Sed } 2404198092Srdivacky 2405193326Sed IdentifierInfo *II = Tok.getIdentifierInfo(); 2406193326Sed ConsumeToken(); 2407193326Sed 2408203955Srdivacky Names.push_back(II); 2409226633Sdim T.consumeClose(); 2410193326Sed } else 2411203955Srdivacky Names.push_back(0); 2412193326Sed 2413212904Sdim ExprResult Constraint(ParseAsmStringLiteral()); 2414193326Sed if (Constraint.isInvalid()) { 2415263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 2416193326Sed return true; 2417193326Sed } 2418193326Sed Constraints.push_back(Constraint.release()); 2419193326Sed 2420193326Sed if (Tok.isNot(tok::l_paren)) { 2421193326Sed Diag(Tok, diag::err_expected_lparen_after) << "asm operand"; 2422263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 2423193326Sed return true; 2424193326Sed } 2425193326Sed 2426193326Sed // Read the parenthesized expression. 2427226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 2428226633Sdim T.consumeOpen(); 2429212904Sdim ExprResult Res(ParseExpression()); 2430226633Sdim T.consumeClose(); 2431193326Sed if (Res.isInvalid()) { 2432263508Sdim SkipUntil(tok::r_paren, StopAtSemi); 2433193326Sed return true; 2434193326Sed } 2435193326Sed Exprs.push_back(Res.release()); 2436193326Sed // Eat the comma and continue parsing if it exists. 2437193326Sed if (Tok.isNot(tok::comma)) return false; 2438193326Sed ConsumeToken(); 2439193326Sed } 2440193326Sed} 2441193326Sed 2442221345SdimDecl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) { 2443193326Sed assert(Tok.is(tok::l_brace)); 2444193326Sed SourceLocation LBraceLoc = Tok.getLocation(); 2445193326Sed 2446249423Sdim if (SkipFunctionBodies && (!Decl || Actions.canSkipFunctionBody(Decl)) && 2447249423Sdim trySkippingFunctionBody()) { 2448234353Sdim BodyScope.Exit(); 2449249423Sdim return Actions.ActOnSkippedFunctionBody(Decl); 2450221345Sdim } 2451226633Sdim 2452212904Sdim PrettyDeclStackTraceEntry CrashInfo(Actions, Decl, LBraceLoc, 2453212904Sdim "parsing function body"); 2454198092Srdivacky 2455193326Sed // Do not enter a scope for the brace, as the arguments are in the same scope 2456193326Sed // (the function body) as the body itself. Instead, just read the statement 2457193326Sed // list and put it into a CompoundStmt for safe keeping. 2458212904Sdim StmtResult FnBody(ParseCompoundStatementBody()); 2459193326Sed 2460193326Sed // If the function body could not be parsed, make a bogus compoundstmt. 2461234353Sdim if (FnBody.isInvalid()) { 2462234353Sdim Sema::CompoundScopeRAII CompoundScope(Actions); 2463263508Sdim FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, None, false); 2464234353Sdim } 2465193326Sed 2466221345Sdim BodyScope.Exit(); 2467212904Sdim return Actions.ActOnFinishFunctionBody(Decl, FnBody.take()); 2468193326Sed} 2469193326Sed 2470193326Sed/// ParseFunctionTryBlock - Parse a C++ function-try-block. 2471193326Sed/// 2472193326Sed/// function-try-block: 2473193326Sed/// 'try' ctor-initializer[opt] compound-statement handler-seq 2474193326Sed/// 2475221345SdimDecl *Parser::ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope) { 2476193326Sed assert(Tok.is(tok::kw_try) && "Expected 'try'"); 2477193326Sed SourceLocation TryLoc = ConsumeToken(); 2478193326Sed 2479212904Sdim PrettyDeclStackTraceEntry CrashInfo(Actions, Decl, TryLoc, 2480212904Sdim "parsing function try block"); 2481193326Sed 2482193326Sed // Constructor initializer list? 2483193326Sed if (Tok.is(tok::colon)) 2484193326Sed ParseConstructorInitializer(Decl); 2485226633Sdim else 2486226633Sdim Actions.ActOnDefaultCtorInitializers(Decl); 2487193326Sed 2488249423Sdim if (SkipFunctionBodies && Actions.canSkipFunctionBody(Decl) && 2489249423Sdim trySkippingFunctionBody()) { 2490234353Sdim BodyScope.Exit(); 2491249423Sdim return Actions.ActOnSkippedFunctionBody(Decl); 2492221345Sdim } 2493218893Sdim 2494193326Sed SourceLocation LBraceLoc = Tok.getLocation(); 2495243830Sdim StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc, /*FnTry*/true)); 2496193326Sed // If we failed to parse the try-catch, we just give the function an empty 2497193326Sed // compound statement as the body. 2498234353Sdim if (FnBody.isInvalid()) { 2499234353Sdim Sema::CompoundScopeRAII CompoundScope(Actions); 2500263508Sdim FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, None, false); 2501234353Sdim } 2502193326Sed 2503221345Sdim BodyScope.Exit(); 2504212904Sdim return Actions.ActOnFinishFunctionBody(Decl, FnBody.take()); 2505193326Sed} 2506193326Sed 2507234353Sdimbool Parser::trySkippingFunctionBody() { 2508218893Sdim assert(Tok.is(tok::l_brace)); 2509234353Sdim assert(SkipFunctionBodies && 2510234353Sdim "Should only be called when SkipFunctionBodies is enabled"); 2511218893Sdim 2512243830Sdim if (!PP.isCodeCompletionEnabled()) { 2513243830Sdim ConsumeBrace(); 2514263508Sdim SkipUntil(tok::r_brace); 2515243830Sdim return true; 2516243830Sdim } 2517243830Sdim 2518218893Sdim // We're in code-completion mode. Skip parsing for all function bodies unless 2519218893Sdim // the body contains the code-completion point. 2520218893Sdim TentativeParsingAction PA(*this); 2521218893Sdim ConsumeBrace(); 2522263508Sdim if (SkipUntil(tok::r_brace, StopAtCodeCompletion)) { 2523218893Sdim PA.Commit(); 2524218893Sdim return true; 2525218893Sdim } 2526218893Sdim 2527218893Sdim PA.Revert(); 2528218893Sdim return false; 2529218893Sdim} 2530218893Sdim 2531193326Sed/// ParseCXXTryBlock - Parse a C++ try-block. 2532193326Sed/// 2533193326Sed/// try-block: 2534193326Sed/// 'try' compound-statement handler-seq 2535193326Sed/// 2536234982SdimStmtResult Parser::ParseCXXTryBlock() { 2537193326Sed assert(Tok.is(tok::kw_try) && "Expected 'try'"); 2538193326Sed 2539193326Sed SourceLocation TryLoc = ConsumeToken(); 2540193326Sed return ParseCXXTryBlockCommon(TryLoc); 2541193326Sed} 2542193326Sed 2543193326Sed/// ParseCXXTryBlockCommon - Parse the common part of try-block and 2544193326Sed/// function-try-block. 2545193326Sed/// 2546193326Sed/// try-block: 2547193326Sed/// 'try' compound-statement handler-seq 2548193326Sed/// 2549193326Sed/// function-try-block: 2550193326Sed/// 'try' ctor-initializer[opt] compound-statement handler-seq 2551193326Sed/// 2552193326Sed/// handler-seq: 2553193326Sed/// handler handler-seq[opt] 2554193326Sed/// 2555221345Sdim/// [Borland] try-block: 2556221345Sdim/// 'try' compound-statement seh-except-block 2557221345Sdim/// 'try' compound-statment seh-finally-block 2558221345Sdim/// 2559243830SdimStmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry) { 2560193326Sed if (Tok.isNot(tok::l_brace)) 2561193326Sed return StmtError(Diag(Tok, diag::err_expected_lbrace)); 2562199990Srdivacky // FIXME: Possible draft standard bug: attribute-specifier should be allowed? 2563234982Sdim 2564234982Sdim StmtResult TryBlock(ParseCompoundStatement(/*isStmtExpr=*/false, 2565249423Sdim Scope::DeclScope | Scope::TryScope | 2566249423Sdim (FnTry ? Scope::FnTryCatchScope : 0))); 2567193326Sed if (TryBlock.isInvalid()) 2568243830Sdim return TryBlock; 2569193326Sed 2570221345Sdim // Borland allows SEH-handlers with 'try' 2571239462Sdim 2572234982Sdim if ((Tok.is(tok::identifier) && 2573234982Sdim Tok.getIdentifierInfo() == getSEHExceptKeyword()) || 2574234982Sdim Tok.is(tok::kw___finally)) { 2575221345Sdim // TODO: Factor into common return ParseSEHHandlerCommon(...) 2576221345Sdim StmtResult Handler; 2577234353Sdim if(Tok.getIdentifierInfo() == getSEHExceptKeyword()) { 2578221345Sdim SourceLocation Loc = ConsumeToken(); 2579221345Sdim Handler = ParseSEHExceptBlock(Loc); 2580221345Sdim } 2581221345Sdim else { 2582221345Sdim SourceLocation Loc = ConsumeToken(); 2583221345Sdim Handler = ParseSEHFinallyBlock(Loc); 2584221345Sdim } 2585221345Sdim if(Handler.isInvalid()) 2586243830Sdim return Handler; 2587218893Sdim 2588221345Sdim return Actions.ActOnSEHTryBlock(true /* IsCXXTry */, 2589221345Sdim TryLoc, 2590221345Sdim TryBlock.take(), 2591221345Sdim Handler.take()); 2592193326Sed } 2593221345Sdim else { 2594243830Sdim StmtVector Handlers; 2595193326Sed 2596263508Sdim // C++11 attributes can't appear here, despite this context seeming 2597263508Sdim // statement-like. 2598263508Sdim DiagnoseAndSkipCXX11Attributes(); 2599263508Sdim 2600221345Sdim if (Tok.isNot(tok::kw_catch)) 2601221345Sdim return StmtError(Diag(Tok, diag::err_expected_catch)); 2602221345Sdim while (Tok.is(tok::kw_catch)) { 2603243830Sdim StmtResult Handler(ParseCXXCatchBlock(FnTry)); 2604221345Sdim if (!Handler.isInvalid()) 2605221345Sdim Handlers.push_back(Handler.release()); 2606221345Sdim } 2607221345Sdim // Don't bother creating the full statement if we don't have any usable 2608221345Sdim // handlers. 2609221345Sdim if (Handlers.empty()) 2610221345Sdim return StmtError(); 2611221345Sdim 2612263508Sdim return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.take(), Handlers); 2613221345Sdim } 2614193326Sed} 2615193326Sed 2616193326Sed/// ParseCXXCatchBlock - Parse a C++ catch block, called handler in the standard 2617193326Sed/// 2618249423Sdim/// handler: 2619249423Sdim/// 'catch' '(' exception-declaration ')' compound-statement 2620193326Sed/// 2621249423Sdim/// exception-declaration: 2622249423Sdim/// attribute-specifier-seq[opt] type-specifier-seq declarator 2623249423Sdim/// attribute-specifier-seq[opt] type-specifier-seq abstract-declarator[opt] 2624249423Sdim/// '...' 2625193326Sed/// 2626243830SdimStmtResult Parser::ParseCXXCatchBlock(bool FnCatch) { 2627193326Sed assert(Tok.is(tok::kw_catch) && "Expected 'catch'"); 2628193326Sed 2629193326Sed SourceLocation CatchLoc = ConsumeToken(); 2630193326Sed 2631226633Sdim BalancedDelimiterTracker T(*this, tok::l_paren); 2632226633Sdim if (T.expectAndConsume(diag::err_expected_lparen)) 2633193326Sed return StmtError(); 2634193326Sed 2635193326Sed // C++ 3.3.2p3: 2636193326Sed // The name in a catch exception-declaration is local to the handler and 2637193326Sed // shall not be redeclared in the outermost block of the handler. 2638243830Sdim ParseScope CatchScope(this, Scope::DeclScope | Scope::ControlScope | 2639249423Sdim (FnCatch ? Scope::FnTryCatchScope : 0)); 2640193326Sed 2641193326Sed // exception-declaration is equivalent to '...' or a parameter-declaration 2642193326Sed // without default arguments. 2643212904Sdim Decl *ExceptionDecl = 0; 2644193326Sed if (Tok.isNot(tok::ellipsis)) { 2645249423Sdim ParsedAttributesWithRange Attributes(AttrFactory); 2646249423Sdim MaybeParseCXX11Attributes(Attributes); 2647249423Sdim 2648221345Sdim DeclSpec DS(AttrFactory); 2649249423Sdim DS.takeAttributesFrom(Attributes); 2650249423Sdim 2651193326Sed if (ParseCXXTypeSpecifierSeq(DS)) 2652193326Sed return StmtError(); 2653249423Sdim 2654193326Sed Declarator ExDecl(DS, Declarator::CXXCatchContext); 2655193326Sed ParseDeclarator(ExDecl); 2656210299Sed ExceptionDecl = Actions.ActOnExceptionDeclarator(getCurScope(), ExDecl); 2657193326Sed } else 2658193326Sed ConsumeToken(); 2659193326Sed 2660226633Sdim T.consumeClose(); 2661226633Sdim if (T.getCloseLocation().isInvalid()) 2662193326Sed return StmtError(); 2663193326Sed 2664193326Sed if (Tok.isNot(tok::l_brace)) 2665193326Sed return StmtError(Diag(Tok, diag::err_expected_lbrace)); 2666193326Sed 2667199990Srdivacky // FIXME: Possible draft standard bug: attribute-specifier should be allowed? 2668234982Sdim StmtResult Block(ParseCompoundStatement()); 2669193326Sed if (Block.isInvalid()) 2670243830Sdim return Block; 2671193326Sed 2672212904Sdim return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl, Block.take()); 2673193326Sed} 2674223017Sdim 2675223017Sdimvoid Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) { 2676234353Sdim IfExistsCondition Result; 2677223017Sdim if (ParseMicrosoftIfExistsCondition(Result)) 2678223017Sdim return; 2679226633Sdim 2680234353Sdim // Handle dependent statements by parsing the braces as a compound statement. 2681234353Sdim // This is not the same behavior as Visual C++, which don't treat this as a 2682234353Sdim // compound statement, but for Clang's type checking we can't have anything 2683234353Sdim // inside these braces escaping to the surrounding code. 2684234353Sdim if (Result.Behavior == IEB_Dependent) { 2685234353Sdim if (!Tok.is(tok::l_brace)) { 2686234353Sdim Diag(Tok, diag::err_expected_lbrace); 2687234982Sdim return; 2688234353Sdim } 2689234982Sdim 2690234982Sdim StmtResult Compound = ParseCompoundStatement(); 2691234353Sdim if (Compound.isInvalid()) 2692234353Sdim return; 2693234982Sdim 2694234353Sdim StmtResult DepResult = Actions.ActOnMSDependentExistsStmt(Result.KeywordLoc, 2695234353Sdim Result.IsIfExists, 2696234982Sdim Result.SS, 2697234353Sdim Result.Name, 2698234353Sdim Compound.get()); 2699234353Sdim if (DepResult.isUsable()) 2700234353Sdim Stmts.push_back(DepResult.get()); 2701234353Sdim return; 2702234353Sdim } 2703234982Sdim 2704234353Sdim BalancedDelimiterTracker Braces(*this, tok::l_brace); 2705234353Sdim if (Braces.consumeOpen()) { 2706223017Sdim Diag(Tok, diag::err_expected_lbrace); 2707223017Sdim return; 2708223017Sdim } 2709223017Sdim 2710234353Sdim switch (Result.Behavior) { 2711234353Sdim case IEB_Parse: 2712234353Sdim // Parse the statements below. 2713234353Sdim break; 2714239462Sdim 2715234353Sdim case IEB_Dependent: 2716234353Sdim llvm_unreachable("Dependent case handled above"); 2717239462Sdim 2718234353Sdim case IEB_Skip: 2719234353Sdim Braces.skipToEnd(); 2720223017Sdim return; 2721223017Sdim } 2722223017Sdim 2723223017Sdim // Condition is true, parse the statements. 2724223017Sdim while (Tok.isNot(tok::r_brace)) { 2725223017Sdim StmtResult R = ParseStatementOrDeclaration(Stmts, false); 2726223017Sdim if (R.isUsable()) 2727223017Sdim Stmts.push_back(R.release()); 2728223017Sdim } 2729234353Sdim Braces.consumeClose(); 2730223017Sdim} 2731