Convert some more statement parsers to smart pointers.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60892 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Sebastian Redl 2008-12-11 19:48:14 +00:00
Родитель 9fa72ef7e8
Коммит 9a92034270
2 изменённых файлов: 89 добавлений и 86 удалений

Просмотреть файл

@ -635,16 +635,16 @@ private:
OwningStmtResult ParseCompoundStatement(bool isStmtExpr = false); OwningStmtResult ParseCompoundStatement(bool isStmtExpr = false);
OwningStmtResult ParseCompoundStatementBody(bool isStmtExpr = false); OwningStmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
OwningStmtResult ParseIfStatement(); OwningStmtResult ParseIfStatement();
StmtResult ParseSwitchStatement(); OwningStmtResult ParseSwitchStatement();
StmtResult ParseWhileStatement(); OwningStmtResult ParseWhileStatement();
StmtResult ParseDoStatement(); OwningStmtResult ParseDoStatement();
StmtResult ParseForStatement(); OwningStmtResult ParseForStatement();
StmtResult ParseGotoStatement(); OwningStmtResult ParseGotoStatement();
StmtResult ParseContinueStatement(); OwningStmtResult ParseContinueStatement();
StmtResult ParseBreakStatement(); OwningStmtResult ParseBreakStatement();
StmtResult ParseReturnStatement(); OwningStmtResult ParseReturnStatement();
StmtResult ParseAsmStatement(bool &msAsm); OwningStmtResult ParseAsmStatement(bool &msAsm);
StmtResult FuzzyParseMicrosoftAsmStatement(); OwningStmtResult FuzzyParseMicrosoftAsmStatement();
StmtResult ParseObjCAtStatement(SourceLocation atLoc); StmtResult ParseObjCAtStatement(SourceLocation atLoc);
StmtResult ParseObjCTryStmt(SourceLocation atLoc); StmtResult ParseObjCTryStmt(SourceLocation atLoc);
StmtResult ParseObjCThrowStmt(SourceLocation atLoc); StmtResult ParseObjCThrowStmt(SourceLocation atLoc);

Просмотреть файл

@ -133,16 +133,16 @@ Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
case tok::kw_if: // C99 6.8.4.1: if-statement case tok::kw_if: // C99 6.8.4.1: if-statement
return ParseIfStatement(); return ParseIfStatement();
case tok::kw_switch: // C99 6.8.4.2: switch-statement case tok::kw_switch: // C99 6.8.4.2: switch-statement
return Owned(ParseSwitchStatement()); return ParseSwitchStatement();
case tok::kw_while: // C99 6.8.5.1: while-statement case tok::kw_while: // C99 6.8.5.1: while-statement
return Owned(ParseWhileStatement()); return ParseWhileStatement();
case tok::kw_do: // C99 6.8.5.2: do-statement case tok::kw_do: // C99 6.8.5.2: do-statement
Res = ParseDoStatement(); Res = ParseDoStatement();
SemiError = "do/while loop"; SemiError = "do/while loop";
break; break;
case tok::kw_for: // C99 6.8.5.3: for-statement case tok::kw_for: // C99 6.8.5.3: for-statement
return Owned(ParseForStatement()); return ParseForStatement();
case tok::kw_goto: // C99 6.8.6.1: goto-statement case tok::kw_goto: // C99 6.8.6.1: goto-statement
Res = ParseGotoStatement(); Res = ParseGotoStatement();
@ -546,14 +546,14 @@ Parser::OwningStmtResult Parser::ParseIfStatement() {
/// switch-statement: /// switch-statement:
/// 'switch' '(' expression ')' statement /// 'switch' '(' expression ')' statement
/// [C++] 'switch' '(' condition ')' statement /// [C++] 'switch' '(' condition ')' statement
Parser::StmtResult Parser::ParseSwitchStatement() { Parser::OwningStmtResult Parser::ParseSwitchStatement() {
assert(Tok.is(tok::kw_switch) && "Not a switch stmt!"); assert(Tok.is(tok::kw_switch) && "Not a switch stmt!");
SourceLocation SwitchLoc = ConsumeToken(); // eat the 'switch'. SourceLocation SwitchLoc = ConsumeToken(); // eat the 'switch'.
if (Tok.isNot(tok::l_paren)) { if (Tok.isNot(tok::l_paren)) {
Diag(Tok, diag::err_expected_lparen_after) << "switch"; Diag(Tok, diag::err_expected_lparen_after) << "switch";
SkipUntil(tok::semi); SkipUntil(tok::semi);
return true; return StmtError();
} }
bool C99orCXX = getLang().C99 || getLang().CPlusPlus; bool C99orCXX = getLang().C99 || getLang().CPlusPlus;
@ -586,7 +586,7 @@ Parser::StmtResult Parser::ParseSwitchStatement() {
} }
if (Cond.isInvalid()) if (Cond.isInvalid())
return true; return StmtError();
OwningStmtResult Switch(Actions, OwningStmtResult Switch(Actions,
Actions.ActOnStartOfSwitchStmt(Cond.release())); Actions.ActOnStartOfSwitchStmt(Cond.release()));
@ -610,7 +610,7 @@ Parser::StmtResult Parser::ParseSwitchStatement() {
// Pop the body scope if needed. // Pop the body scope if needed.
InnerScope.Exit(); InnerScope.Exit();
if (Body.isInvalid()) { if (Body.isInvalid()) {
Body = Actions.ActOnNullStmt(Tok.getLocation()); Body = Actions.ActOnNullStmt(Tok.getLocation());
// FIXME: Remove the case statement list from the Switch statement. // FIXME: Remove the case statement list from the Switch statement.
@ -618,25 +618,25 @@ Parser::StmtResult Parser::ParseSwitchStatement() {
SwitchScope.Exit(); SwitchScope.Exit();
return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.release(), return Owned(Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.release(),
Body.release()); Body.release()));
} }
/// ParseWhileStatement /// ParseWhileStatement
/// while-statement: [C99 6.8.5.1] /// while-statement: [C99 6.8.5.1]
/// 'while' '(' expression ')' statement /// 'while' '(' expression ')' statement
/// [C++] 'while' '(' condition ')' statement /// [C++] 'while' '(' condition ')' statement
Parser::StmtResult Parser::ParseWhileStatement() { Parser::OwningStmtResult Parser::ParseWhileStatement() {
assert(Tok.is(tok::kw_while) && "Not a while stmt!"); assert(Tok.is(tok::kw_while) && "Not a while stmt!");
SourceLocation WhileLoc = Tok.getLocation(); SourceLocation WhileLoc = Tok.getLocation();
ConsumeToken(); // eat the 'while'. ConsumeToken(); // eat the 'while'.
if (Tok.isNot(tok::l_paren)) { if (Tok.isNot(tok::l_paren)) {
Diag(Tok, diag::err_expected_lparen_after) << "while"; Diag(Tok, diag::err_expected_lparen_after) << "while";
SkipUntil(tok::semi); SkipUntil(tok::semi);
return true; return StmtError();
} }
bool C99orCXX = getLang().C99 || getLang().CPlusPlus; bool C99orCXX = getLang().C99 || getLang().CPlusPlus;
// C99 6.8.5p5 - In C99, the while statement is a block. This is not // C99 6.8.5p5 - In C99, the while statement is a block. This is not
@ -682,27 +682,28 @@ Parser::StmtResult Parser::ParseWhileStatement() {
// //
ParseScope InnerScope(this, Scope::DeclScope, ParseScope InnerScope(this, Scope::DeclScope,
C99orCXX && Tok.isNot(tok::l_brace)); C99orCXX && Tok.isNot(tok::l_brace));
// Read the body statement. // Read the body statement.
OwningStmtResult Body(ParseStatement()); OwningStmtResult Body(ParseStatement());
// Pop the body scope if needed. // Pop the body scope if needed.
InnerScope.Exit(); InnerScope.Exit();
WhileScope.Exit(); WhileScope.Exit();
if (Cond.isInvalid() || Body.isInvalid()) return true; if (Cond.isInvalid() || Body.isInvalid())
return StmtError();
return Actions.ActOnWhileStmt(WhileLoc, Cond.release(), Body.release());
return Owned(Actions.ActOnWhileStmt(WhileLoc, Cond.release(),Body.release()));
} }
/// ParseDoStatement /// ParseDoStatement
/// do-statement: [C99 6.8.5.2] /// do-statement: [C99 6.8.5.2]
/// 'do' statement 'while' '(' expression ')' ';' /// 'do' statement 'while' '(' expression ')' ';'
/// Note: this lets the caller parse the end ';'. /// Note: this lets the caller parse the end ';'.
Parser::StmtResult Parser::ParseDoStatement() { Parser::OwningStmtResult Parser::ParseDoStatement() {
assert(Tok.is(tok::kw_do) && "Not a do stmt!"); assert(Tok.is(tok::kw_do) && "Not a do stmt!");
SourceLocation DoLoc = ConsumeToken(); // eat the 'do'. SourceLocation DoLoc = ConsumeToken(); // eat the 'do'.
// C99 6.8.5p5 - In C99, the do statement is a block. This is not // C99 6.8.5p5 - In C99, the do statement is a block. This is not
// the case for C90. Start the loop scope. // the case for C90. Start the loop scope.
unsigned ScopeFlags; unsigned ScopeFlags;
@ -710,7 +711,7 @@ Parser::StmtResult Parser::ParseDoStatement() {
ScopeFlags = Scope::BreakScope | Scope::ContinueScope | Scope::DeclScope; ScopeFlags = Scope::BreakScope | Scope::ContinueScope | Scope::DeclScope;
else else
ScopeFlags = Scope::BreakScope | Scope::ContinueScope; ScopeFlags = Scope::BreakScope | Scope::ContinueScope;
ParseScope DoScope(this, ScopeFlags); ParseScope DoScope(this, ScopeFlags);
// C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
@ -724,7 +725,7 @@ Parser::StmtResult Parser::ParseDoStatement() {
ParseScope InnerScope(this, Scope::DeclScope, ParseScope InnerScope(this, Scope::DeclScope,
(getLang().C99 || getLang().CPlusPlus) && (getLang().C99 || getLang().CPlusPlus) &&
Tok.isNot(tok::l_brace)); Tok.isNot(tok::l_brace));
// Read the body statement. // Read the body statement.
OwningStmtResult Body(ParseStatement()); OwningStmtResult Body(ParseStatement());
@ -737,23 +738,25 @@ Parser::StmtResult Parser::ParseDoStatement() {
Diag(DoLoc, diag::note_matching) << "do"; Diag(DoLoc, diag::note_matching) << "do";
SkipUntil(tok::semi, false, true); SkipUntil(tok::semi, false, true);
} }
return true; return StmtError();
} }
SourceLocation WhileLoc = ConsumeToken(); SourceLocation WhileLoc = ConsumeToken();
if (Tok.isNot(tok::l_paren)) { if (Tok.isNot(tok::l_paren)) {
Diag(Tok, diag::err_expected_lparen_after) << "do/while"; Diag(Tok, diag::err_expected_lparen_after) << "do/while";
SkipUntil(tok::semi, false, true); SkipUntil(tok::semi, false, true);
return true; return StmtError();
} }
// Parse the condition. // Parse the condition.
OwningExprResult Cond(Actions, ParseSimpleParenExpression()); OwningExprResult Cond(Actions, ParseSimpleParenExpression());
DoScope.Exit(); DoScope.Exit();
if (Cond.isInvalid() || Body.isInvalid()) return true; if (Cond.isInvalid() || Body.isInvalid())
return StmtError();
return Actions.ActOnDoStmt(DoLoc, Body.release(), WhileLoc, Cond.release()); return Owned(Actions.ActOnDoStmt(DoLoc, Body.release(), WhileLoc,
Cond.release()));
} }
/// ParseForStatement /// ParseForStatement
@ -769,16 +772,16 @@ Parser::StmtResult Parser::ParseDoStatement() {
/// [C++] expression-statement /// [C++] expression-statement
/// [C++] simple-declaration /// [C++] simple-declaration
/// ///
Parser::StmtResult Parser::ParseForStatement() { Parser::OwningStmtResult Parser::ParseForStatement() {
assert(Tok.is(tok::kw_for) && "Not a for stmt!"); assert(Tok.is(tok::kw_for) && "Not a for stmt!");
SourceLocation ForLoc = ConsumeToken(); // eat the 'for'. SourceLocation ForLoc = ConsumeToken(); // eat the 'for'.
if (Tok.isNot(tok::l_paren)) { if (Tok.isNot(tok::l_paren)) {
Diag(Tok, diag::err_expected_lparen_after) << "for"; Diag(Tok, diag::err_expected_lparen_after) << "for";
SkipUntil(tok::semi); SkipUntil(tok::semi);
return true; return StmtError();
} }
bool C99orCXX = getLang().C99 || getLang().CPlusPlus; bool C99orCXX = getLang().C99 || getLang().CPlusPlus;
// C99 6.8.5p5 - In C99, the for statement is a block. This is not // C99 6.8.5p5 - In C99, the for statement is a block. This is not
@ -820,7 +823,7 @@ Parser::StmtResult Parser::ParseForStatement() {
// Parse declaration, which eats the ';'. // Parse declaration, which eats the ';'.
if (!C99orCXX) // Use of C99-style for loops in C90 mode? if (!C99orCXX) // Use of C99-style for loops in C90 mode?
Diag(Tok, diag::ext_c99_variable_decl_in_for_loop); Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
SourceLocation DeclStart = Tok.getLocation(); SourceLocation DeclStart = Tok.getLocation();
DeclTy *aBlockVarDecl = ParseSimpleDeclaration(Declarator::ForContext); DeclTy *aBlockVarDecl = ParseSimpleDeclaration(Declarator::ForContext);
// FIXME: Pass in the right location for the end of the declstmt. // FIXME: Pass in the right location for the end of the declstmt.
@ -865,7 +868,7 @@ Parser::StmtResult Parser::ParseForStatement() {
if (!SecondPart.isInvalid()) Diag(Tok, diag::err_expected_semi_for); if (!SecondPart.isInvalid()) Diag(Tok, diag::err_expected_semi_for);
SkipUntil(tok::semi); SkipUntil(tok::semi);
} }
// Parse the third part of the for specifier. // Parse the third part of the for specifier.
if (Tok.is(tok::r_paren)) { // for (...;...;) if (Tok.is(tok::r_paren)) { // for (...;...;)
// no third part. // no third part.
@ -904,17 +907,17 @@ Parser::StmtResult Parser::ParseForStatement() {
ForScope.Exit(); ForScope.Exit();
if (Body.isInvalid()) if (Body.isInvalid())
return true; return StmtError();
if (!ForEach) if (!ForEach)
return Actions.ActOnForStmt(ForLoc, LParenLoc, FirstPart.release(), return Owned(Actions.ActOnForStmt(ForLoc, LParenLoc, FirstPart.release(),
SecondPart.release(), ThirdPart.release(), SecondPart.release(), ThirdPart.release(),
RParenLoc, Body.release()); RParenLoc, Body.release()));
else else
return Actions.ActOnObjCForCollectionStmt(ForLoc, LParenLoc, return Owned(Actions.ActOnObjCForCollectionStmt(ForLoc, LParenLoc,
FirstPart.release(), FirstPart.release(),
SecondPart.release(), SecondPart.release(),
RParenLoc, Body.release()); RParenLoc, Body.release()));
} }
/// ParseGotoStatement /// ParseGotoStatement
@ -924,10 +927,10 @@ Parser::StmtResult Parser::ParseForStatement() {
/// ///
/// Note: this lets the caller parse the end ';'. /// Note: this lets the caller parse the end ';'.
/// ///
Parser::StmtResult Parser::ParseGotoStatement() { Parser::OwningStmtResult Parser::ParseGotoStatement() {
assert(Tok.is(tok::kw_goto) && "Not a goto stmt!"); assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");
SourceLocation GotoLoc = ConsumeToken(); // eat the 'goto'. SourceLocation GotoLoc = ConsumeToken(); // eat the 'goto'.
OwningStmtResult Res(Actions); OwningStmtResult Res(Actions);
if (Tok.is(tok::identifier)) { if (Tok.is(tok::identifier)) {
Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(), Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(),
@ -940,15 +943,15 @@ Parser::StmtResult Parser::ParseGotoStatement() {
OwningExprResult R(Actions, ParseExpression()); OwningExprResult R(Actions, ParseExpression());
if (R.isInvalid()) { // Skip to the semicolon, but don't consume it. if (R.isInvalid()) { // Skip to the semicolon, but don't consume it.
SkipUntil(tok::semi, false, true); SkipUntil(tok::semi, false, true);
return true; return StmtError();
} }
Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.release()); Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.release());
} else { } else {
Diag(Tok, diag::err_expected_ident); Diag(Tok, diag::err_expected_ident);
return true; return StmtError();
} }
return Res.result(); return move(Res);
} }
/// ParseContinueStatement /// ParseContinueStatement
@ -957,9 +960,9 @@ Parser::StmtResult Parser::ParseGotoStatement() {
/// ///
/// Note: this lets the caller parse the end ';'. /// Note: this lets the caller parse the end ';'.
/// ///
Parser::StmtResult Parser::ParseContinueStatement() { Parser::OwningStmtResult Parser::ParseContinueStatement() {
SourceLocation ContinueLoc = ConsumeToken(); // eat the 'continue'. SourceLocation ContinueLoc = ConsumeToken(); // eat the 'continue'.
return Actions.ActOnContinueStmt(ContinueLoc, CurScope); return Owned(Actions.ActOnContinueStmt(ContinueLoc, CurScope));
} }
/// ParseBreakStatement /// ParseBreakStatement
@ -968,32 +971,32 @@ Parser::StmtResult Parser::ParseContinueStatement() {
/// ///
/// Note: this lets the caller parse the end ';'. /// Note: this lets the caller parse the end ';'.
/// ///
Parser::StmtResult Parser::ParseBreakStatement() { Parser::OwningStmtResult Parser::ParseBreakStatement() {
SourceLocation BreakLoc = ConsumeToken(); // eat the 'break'. SourceLocation BreakLoc = ConsumeToken(); // eat the 'break'.
return Actions.ActOnBreakStmt(BreakLoc, CurScope); return Owned(Actions.ActOnBreakStmt(BreakLoc, CurScope));
} }
/// ParseReturnStatement /// ParseReturnStatement
/// jump-statement: /// jump-statement:
/// 'return' expression[opt] ';' /// 'return' expression[opt] ';'
Parser::StmtResult Parser::ParseReturnStatement() { Parser::OwningStmtResult Parser::ParseReturnStatement() {
assert(Tok.is(tok::kw_return) && "Not a return stmt!"); assert(Tok.is(tok::kw_return) && "Not a return stmt!");
SourceLocation ReturnLoc = ConsumeToken(); // eat the 'return'. SourceLocation ReturnLoc = ConsumeToken(); // eat the 'return'.
OwningExprResult R(Actions); OwningExprResult R(Actions);
if (Tok.isNot(tok::semi)) { if (Tok.isNot(tok::semi)) {
R = ParseExpression(); R = ParseExpression();
if (R.isInvalid()) { // Skip to the semicolon, but don't consume it. if (R.isInvalid()) { // Skip to the semicolon, but don't consume it.
SkipUntil(tok::semi, false, true); SkipUntil(tok::semi, false, true);
return true; return StmtError();
} }
} }
return Actions.ActOnReturnStmt(ReturnLoc, R.release()); return Owned(Actions.ActOnReturnStmt(ReturnLoc, R.release()));
} }
/// FuzzyParseMicrosoftAsmStatement. When -fms-extensions is enabled, this /// FuzzyParseMicrosoftAsmStatement. When -fms-extensions is enabled, this
/// routine is called to skip/ignore tokens that comprise the MS asm statement. /// routine is called to skip/ignore tokens that comprise the MS asm statement.
Parser::StmtResult Parser::FuzzyParseMicrosoftAsmStatement() { Parser::OwningStmtResult Parser::FuzzyParseMicrosoftAsmStatement() {
if (Tok.is(tok::l_brace)) { if (Tok.is(tok::l_brace)) {
unsigned short savedBraceCount = BraceCount; unsigned short savedBraceCount = BraceCount;
do { do {
@ -1012,7 +1015,7 @@ Parser::StmtResult Parser::FuzzyParseMicrosoftAsmStatement() {
Tok.isNot(tok::r_brace) && Tok.isNot(tok::semi) && Tok.isNot(tok::r_brace) && Tok.isNot(tok::semi) &&
Tok.isNot(tok::eof)); Tok.isNot(tok::eof));
} }
return Actions.ActOnNullStmt(Tok.getLocation()); return Owned(Actions.ActOnNullStmt(Tok.getLocation()));
} }
/// ParseAsmStatement - Parse a GNU extended asm statement. /// ParseAsmStatement - Parse a GNU extended asm statement.
@ -1042,10 +1045,10 @@ Parser::StmtResult Parser::FuzzyParseMicrosoftAsmStatement() {
/// assembly-instruction ';'[opt] /// assembly-instruction ';'[opt]
/// assembly-instruction-list ';' assembly-instruction ';'[opt] /// assembly-instruction-list ';' assembly-instruction ';'[opt]
/// ///
Parser::StmtResult Parser::ParseAsmStatement(bool &msAsm) { Parser::OwningStmtResult Parser::ParseAsmStatement(bool &msAsm) {
assert(Tok.is(tok::kw_asm) && "Not an asm stmt"); assert(Tok.is(tok::kw_asm) && "Not an asm stmt");
SourceLocation AsmLoc = ConsumeToken(); SourceLocation AsmLoc = ConsumeToken();
if (getLang().Microsoft && Tok.isNot(tok::l_paren) && !isTypeQualifier()) { if (getLang().Microsoft && Tok.isNot(tok::l_paren) && !isTypeQualifier()) {
msAsm = true; msAsm = true;
return FuzzyParseMicrosoftAsmStatement(); return FuzzyParseMicrosoftAsmStatement();
@ -1053,26 +1056,26 @@ Parser::StmtResult Parser::ParseAsmStatement(bool &msAsm) {
DeclSpec DS; DeclSpec DS;
SourceLocation Loc = Tok.getLocation(); SourceLocation Loc = Tok.getLocation();
ParseTypeQualifierListOpt(DS); ParseTypeQualifierListOpt(DS);
// GNU asms accept, but warn, about type-qualifiers other than volatile. // GNU asms accept, but warn, about type-qualifiers other than volatile.
if (DS.getTypeQualifiers() & DeclSpec::TQ_const) if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
Diag(Loc, diag::w_asm_qualifier_ignored) << "const"; Diag(Loc, diag::w_asm_qualifier_ignored) << "const";
if (DS.getTypeQualifiers() & DeclSpec::TQ_restrict) if (DS.getTypeQualifiers() & DeclSpec::TQ_restrict)
Diag(Loc, diag::w_asm_qualifier_ignored) << "restrict"; Diag(Loc, diag::w_asm_qualifier_ignored) << "restrict";
// Remember if this was a volatile asm. // Remember if this was a volatile asm.
bool isVolatile = DS.getTypeQualifiers() & DeclSpec::TQ_volatile; bool isVolatile = DS.getTypeQualifiers() & DeclSpec::TQ_volatile;
bool isSimple = false; bool isSimple = false;
if (Tok.isNot(tok::l_paren)) { if (Tok.isNot(tok::l_paren)) {
Diag(Tok, diag::err_expected_lparen_after) << "asm"; Diag(Tok, diag::err_expected_lparen_after) << "asm";
SkipUntil(tok::r_paren); SkipUntil(tok::r_paren);
return true; return StmtError();
} }
Loc = ConsumeParen(); Loc = ConsumeParen();
OwningExprResult AsmString(ParseAsmStringLiteral()); OwningExprResult AsmString(ParseAsmStringLiteral());
if (AsmString.isInvalid()) if (AsmString.isInvalid())
return true; return StmtError();
llvm::SmallVector<std::string, 4> Names; llvm::SmallVector<std::string, 4> Names;
ExprVector Constraints(Actions); ExprVector Constraints(Actions);
@ -1080,23 +1083,23 @@ Parser::StmtResult Parser::ParseAsmStatement(bool &msAsm) {
ExprVector Clobbers(Actions); ExprVector Clobbers(Actions);
unsigned NumInputs = 0, NumOutputs = 0; unsigned NumInputs = 0, NumOutputs = 0;
SourceLocation RParenLoc; SourceLocation RParenLoc;
if (Tok.is(tok::r_paren)) { if (Tok.is(tok::r_paren)) {
// We have a simple asm expression // We have a simple asm expression
isSimple = true; isSimple = true;
RParenLoc = ConsumeParen(); RParenLoc = ConsumeParen();
} else { } else {
// Parse Outputs, if present. // Parse Outputs, if present.
if (ParseAsmOperandsOpt(Names, Constraints, Exprs)) if (ParseAsmOperandsOpt(Names, Constraints, Exprs))
return true; return StmtError();
NumOutputs = Names.size(); NumOutputs = Names.size();
// Parse Inputs, if present. // Parse Inputs, if present.
if (ParseAsmOperandsOpt(Names, Constraints, Exprs)) if (ParseAsmOperandsOpt(Names, Constraints, Exprs))
return true; return StmtError();
assert(Names.size() == Constraints.size() && assert(Names.size() == Constraints.size() &&
Constraints.size() == Exprs.size() Constraints.size() == Exprs.size()
@ -1125,12 +1128,12 @@ Parser::StmtResult Parser::ParseAsmStatement(bool &msAsm) {
RParenLoc = MatchRHSPunctuation(tok::r_paren, Loc); RParenLoc = MatchRHSPunctuation(tok::r_paren, Loc);
} }
return Actions.ActOnAsmStmt(AsmLoc, isSimple, isVolatile, return Owned(Actions.ActOnAsmStmt(AsmLoc, isSimple, isVolatile,
NumOutputs, NumInputs, NumOutputs, NumInputs,
&Names[0], Constraints.take(), &Names[0], Constraints.take(),
Exprs.take(), AsmString.release(), Exprs.take(), AsmString.release(),
Clobbers.size(), Clobbers.take(), Clobbers.size(), Clobbers.take(),
RParenLoc); RParenLoc));
} }
/// ParseAsmOperands - Parse the asm-operands production as used by /// ParseAsmOperands - Parse the asm-operands production as used by