Handle simple asm statements correctly.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46777 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/AST/Stmt.cpp b/AST/Stmt.cpp
index 249794d..572280b 100644
--- a/AST/Stmt.cpp
+++ b/AST/Stmt.cpp
@@ -115,13 +115,14 @@
 // Constructors
 //===----------------------------------------------------------------------===//
 
-AsmStmt::AsmStmt(SourceLocation asmloc,  bool isvolatile,
+AsmStmt::AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile,
                  unsigned numoutputs, unsigned numinputs,
                  std::string *names, StringLiteral **constraints,
                  Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
                  StringLiteral **clobbers, SourceLocation rparenloc)
   : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), AsmStr(asmstr)
-  , IsVolatile(isvolatile), NumOutputs(numoutputs), NumInputs(numinputs) {
+  , IsSimple(issimple), IsVolatile(isvolatile)
+  , NumOutputs(numoutputs), NumInputs(numinputs) {
   for (unsigned i = 0, e = numinputs + numoutputs; i != e; i++) {
     Names.push_back(names[i]);
     Exprs.push_back(exprs[i]);
diff --git a/AST/StmtSerialization.cpp b/AST/StmtSerialization.cpp
index 9a03a53..f075e1c 100644
--- a/AST/StmtSerialization.cpp
+++ b/AST/StmtSerialization.cpp
@@ -229,6 +229,7 @@
   S.Emit(RParenLoc);  
 
   S.EmitBool(IsVolatile);
+  S.EmitBool(IsSimple);
   S.EmitInt(NumOutputs);
   S.EmitInt(NumInputs);
 
@@ -254,7 +255,8 @@
   SourceLocation PLoc = SourceLocation::ReadVal(D);
   
   bool IsVolatile = D.ReadBool();
-  AsmStmt *Stmt = new AsmStmt(ALoc, IsVolatile, 0, 0, 0, 0, 0,  
+  bool IsSimple = D.ReadBool();
+  AsmStmt *Stmt = new AsmStmt(ALoc, IsSimple, IsVolatile, 0, 0, 0, 0, 0,  
                               AsmStr, 
                               0, 0, PLoc);  
 
diff --git a/Parse/ParseStmt.cpp b/Parse/ParseStmt.cpp
index b6cd558..a074463 100644
--- a/Parse/ParseStmt.cpp
+++ b/Parse/ParseStmt.cpp
@@ -939,7 +939,7 @@
   
   // 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);
@@ -954,43 +954,53 @@
   llvm::SmallVector<std::string, 4> Names;
   llvm::SmallVector<ExprTy*, 4> Constraints;
   llvm::SmallVector<ExprTy*, 4> Exprs;
-  
-  // Parse Outputs, if present. 
-  ParseAsmOperandsOpt(Names, Constraints, Exprs);
-  
-  unsigned NumOutputs = Names.size();
-  
-  // Parse Inputs, if present.
-  ParseAsmOperandsOpt(Names, Constraints, Exprs);
-  assert(Names.size() == Constraints.size() &&
-         Constraints.size() == Exprs.size() 
-         && "Input operand size mismatch!");
-
-  unsigned NumInputs = Names.size() - NumOutputs;
-  
   llvm::SmallVector<ExprTy*, 4> Clobbers;
-  
-  // Parse the clobbers, if present.
-  if (Tok.is(tok::colon)) {
-    ConsumeToken();
-    
-    // Parse the asm-string list for clobbers.
-    while (1) {
-      ExprResult Clobber = ParseAsmStringLiteral();
 
-      if (Clobber.isInvalid)
-        break;
-      
-      Clobbers.push_back(Clobber.Val);
-      
-      if (Tok.isNot(tok::comma)) break;
+  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. 
+    ParseAsmOperandsOpt(Names, Constraints, Exprs);
+  
+    NumOutputs = Names.size();
+  
+    // Parse Inputs, if present.
+    ParseAsmOperandsOpt(Names, Constraints, Exprs);
+    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) {
+        ExprResult Clobber = ParseAsmStringLiteral();
+
+        if (Clobber.isInvalid)
+          break;
+      
+        Clobbers.push_back(Clobber.Val);
+      
+        if (Tok.isNot(tok::comma)) break;
+        ConsumeToken();
+      }
     }
+  
+    RParenLoc = MatchRHSPunctuation(tok::r_paren, Loc);
   }
   
-  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, Loc);
-  
-  return Actions.ActOnAsmStmt(AsmLoc, isVolatile, NumOutputs, NumInputs,
+  return Actions.ActOnAsmStmt(AsmLoc, isSimple, isVolatile,
+                              NumOutputs, NumInputs,
                               &Names[0], &Constraints[0], &Exprs[0],
                               AsmString.Val,
                               Clobbers.size(), &Clobbers[0],
diff --git a/Sema/Sema.h b/Sema/Sema.h
index ecd5ffd..3b463eb 100644
--- a/Sema/Sema.h
+++ b/Sema/Sema.h
@@ -361,6 +361,7 @@
                                      ExprTy *RetValExp);
   
   virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc,
+                                  bool IsSimple,
                                   bool IsVolatile,
                                   unsigned NumOutputs,
                                   unsigned NumInputs,
diff --git a/Sema/SemaStmt.cpp b/Sema/SemaStmt.cpp
index c84b3f3..1c84771 100644
--- a/Sema/SemaStmt.cpp
+++ b/Sema/SemaStmt.cpp
@@ -668,6 +668,7 @@
 }
 
 Sema::StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
+                                    bool IsSimple,                                    
                                     bool IsVolatile,
                                     unsigned NumOutputs,
                                     unsigned NumInputs,
@@ -765,6 +766,7 @@
   }
   
   return new AsmStmt(AsmLoc,
+                     IsSimple,
                      IsVolatile,
                      NumOutputs,
                      NumInputs, 
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 8ea6f1e..dae7fbf 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -755,6 +755,7 @@
   SourceLocation AsmLoc, RParenLoc;
   StringLiteral *AsmStr;
 
+  bool IsSimple;
   bool IsVolatile;
   
   unsigned NumOutputs;
@@ -766,13 +767,15 @@
 
   llvm::SmallVector<StringLiteral*, 4> Clobbers;
 public:
-  AsmStmt(SourceLocation asmloc,  bool isvolatile, unsigned numoutputs,
-          unsigned numinputs, std::string *names, StringLiteral **constraints,
+  AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile, 
+          unsigned numoutputs, unsigned numinputs, 
+          std::string *names, StringLiteral **constraints,
           Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
           StringLiteral **clobbers, SourceLocation rparenloc);
 
   bool isVolatile() const { return IsVolatile; }
-  
+  bool isSimple() const { return IsSimple; }
+
   unsigned getNumOutputs() const { return NumOutputs; }
   const std::string &getOutputName(unsigned i) const
     { return Names[i]; }
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index ce4781b..7a20819 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -299,6 +299,7 @@
     return 0;
   }
   virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc,
+                                  bool IsSimple,                                  
                                   bool IsVolatile,
                                   unsigned NumOutputs,
                                   unsigned NumInputs,