refactor asm stmt parsing to avoid nesting as much, and
pull ':' eating out of ParseAsmOperandsOpt.

llvm-svn: 91801
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 4fc443c..c3595b9 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -1232,7 +1232,6 @@
 
   // Remember if this was a volatile asm.
   bool isVolatile = DS.getTypeQualifiers() & DeclSpec::TQ_volatile;
-  bool isSimple = false;
   if (Tok.isNot(tok::l_paren)) {
     Diag(Tok, diag::err_expected_lparen_after) << "asm";
     SkipUntil(tok::r_paren);
@@ -1249,53 +1248,58 @@
   ExprVector Exprs(Actions);
   ExprVector Clobbers(Actions);
 
-  unsigned NumInputs = 0, NumOutputs = 0;
-
-  SourceLocation RParenLoc;
   if (Tok.is(tok::r_paren)) {
-    // We have a simple asm expression
-    isSimple = true;
-
-    RParenLoc = ConsumeParen();
-  } else {
-    // Parse Outputs, if present.
-    if (ParseAsmOperandsOpt(Names, Constraints, Exprs))
-        return StmtError();
-
-    NumOutputs = Names.size();
-
-    // Parse Inputs, if present.
-    if (ParseAsmOperandsOpt(Names, Constraints, Exprs))
-        return StmtError();
-
-    assert(Names.size() == Constraints.size() &&
-           Constraints.size() == Exprs.size()
-           && "Input operand size mismatch!");
-
-    NumInputs = Names.size() - NumOutputs;
-
-    // Parse the clobbers, if present.
-    if (Tok.is(tok::colon)) {
-      ConsumeToken();
-
-      // Parse the asm-string list for clobbers.
-      while (1) {
-        OwningExprResult Clobber(ParseAsmStringLiteral());
-
-        if (Clobber.isInvalid())
-          break;
-
-        Clobbers.push_back(Clobber.release());
-
-        if (Tok.isNot(tok::comma)) break;
-        ConsumeToken();
-      }
-    }
-
-    RParenLoc = MatchRHSPunctuation(tok::r_paren, Loc);
+    // We have a simple asm expression like 'asm("foo")'.
+    SourceLocation RParenLoc = ConsumeParen();
+    return Actions.ActOnAsmStmt(AsmLoc, /*isSimple*/ true, isVolatile,
+                                /*NumOutputs*/ 0, /*NumInputs*/ 0, 0, 
+                                move_arg(Constraints), move_arg(Exprs),
+                                move(AsmString), move_arg(Clobbers),
+                                RParenLoc);
   }
 
-  return Actions.ActOnAsmStmt(AsmLoc, isSimple, isVolatile,
+  // Parse Outputs, if present.
+  if (Tok.is(tok::colon)) {
+    ConsumeToken();
+  
+    if (ParseAsmOperandsOpt(Names, Constraints, Exprs))
+      return StmtError();
+  }
+  unsigned NumOutputs = Names.size();
+
+  // Parse Inputs, if present.
+  if (Tok.is(tok::colon)) {
+    ConsumeToken();
+    if (ParseAsmOperandsOpt(Names, Constraints, Exprs))
+      return StmtError();
+  }
+
+  assert(Names.size() == Constraints.size() &&
+         Constraints.size() == Exprs.size() &&
+         "Input operand size mismatch!");
+
+  unsigned NumInputs = Names.size() - NumOutputs;
+
+  // Parse the clobbers, if present.
+  if (Tok.is(tok::colon)) {
+    ConsumeToken();
+
+    // Parse the asm-string list for clobbers.
+    while (1) {
+      OwningExprResult Clobber(ParseAsmStringLiteral());
+
+      if (Clobber.isInvalid())
+        break;
+
+      Clobbers.push_back(Clobber.release());
+
+      if (Tok.isNot(tok::comma)) break;
+      ConsumeToken();
+    }
+  }
+
+  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, Loc);
+  return Actions.ActOnAsmStmt(AsmLoc, false, isVolatile,
                               NumOutputs, NumInputs, Names.data(),
                               move_arg(Constraints), move_arg(Exprs),
                               move(AsmString), move_arg(Clobbers),
@@ -1303,8 +1307,7 @@
 }
 
 /// ParseAsmOperands - Parse the asm-operands production as used by
-/// asm-statement.  We also parse a leading ':' token.  If the leading colon is
-/// not present, we do not parse anything.
+/// asm-statement, assuming the leading ':' token was eaten.
 ///
 /// [GNU] asm-operands:
 ///         asm-operand
@@ -1319,10 +1322,6 @@
 bool Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
                                  llvm::SmallVectorImpl<ExprTy*> &Constraints,
                                  llvm::SmallVectorImpl<ExprTy*> &Exprs) {
-  // Only do anything if this operand is present.
-  if (Tok.isNot(tok::colon)) return false;
-  ConsumeToken();
-
   // 'asm-operands' isn't present?
   if (!isTokenStringLiteral() && Tok.isNot(tok::l_square))
     return false;