[ms-inline asm] Hoist common logic into the AsmStmt base class.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162692 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index dd26732..048f1ae 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -1367,16 +1367,28 @@
 ///
 class AsmStmt : public Stmt {
 protected:
+  SourceLocation AsmLoc;
   bool IsSimple;
   bool IsVolatile;
 
-  AsmStmt(StmtClass SC, bool issimple, bool isvolatile) :
-    Stmt (SC), IsSimple(issimple), IsVolatile(isvolatile) { }
+  unsigned NumOutputs;
+  unsigned NumInputs;
+  unsigned NumClobbers;
+
+  IdentifierInfo **Names;
+
+  AsmStmt(StmtClass SC, SourceLocation asmloc, bool issimple, bool isvolatile,
+          unsigned numoutputs, unsigned numinputs, unsigned numclobbers) :
+    Stmt (SC), AsmLoc(asmloc), IsSimple(issimple), IsVolatile(isvolatile),
+    NumOutputs(numoutputs), NumInputs(numinputs), NumClobbers(numclobbers) { }
 
 public:
   /// \brief Build an empty inline-assembly statement.
   explicit AsmStmt(StmtClass SC, EmptyShell Empty) :
-    Stmt(SC, Empty) { }
+    Stmt(SC, Empty), Names(0) { }
+
+  SourceLocation getAsmLoc() const { return AsmLoc; }
+  void setAsmLoc(SourceLocation L) { AsmLoc = L; }
 
   bool isSimple() const { return IsSimple; }
   void setSimple(bool V) { IsSimple = V; }
@@ -1386,6 +1398,38 @@
 
   SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(); }
 
+  //===--- Output operands ---===//
+
+  unsigned getNumOutputs() const { return NumOutputs; }
+
+  IdentifierInfo *getOutputIdentifier(unsigned i) const {
+    return Names[i];
+  }
+
+  StringRef getOutputName(unsigned i) const {
+    if (IdentifierInfo *II = getOutputIdentifier(i))
+      return II->getName();
+
+    return StringRef();
+  }
+
+  //===--- Input operands ---===//
+
+  unsigned getNumInputs() const { return NumInputs; }
+
+  IdentifierInfo *getInputIdentifier(unsigned i) const {
+    return Names[i + NumOutputs];
+  }
+
+  StringRef getInputName(unsigned i) const {
+    if (IdentifierInfo *II = getInputIdentifier(i))
+      return II->getName();
+
+    return StringRef();
+  }
+
+  //===--- Other ---===//
+
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == GCCAsmStmtClass ||
       T->getStmtClass() == MSAsmStmtClass;
@@ -1396,15 +1440,10 @@
 /// This represents a GCC inline-assembly statement extension.
 ///
 class GCCAsmStmt : public AsmStmt {
-  SourceLocation AsmLoc, RParenLoc;
+  SourceLocation RParenLoc;
   StringLiteral *AsmStr;
 
-  unsigned NumOutputs;
-  unsigned NumInputs;
-  unsigned NumClobbers;
-
   // FIXME: If we wanted to, we could allocate all of these in one big array.
-  IdentifierInfo **Names;
   StringLiteral **Constraints;
   Stmt **Exprs;
   StringLiteral **Clobbers;
@@ -1418,10 +1457,8 @@
 
   /// \brief Build an empty inline-assembly statement.
   explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty),
-    Names(0), Constraints(0), Exprs(0), Clobbers(0) { }
+    Constraints(0), Exprs(0), Clobbers(0) { }
 
-  SourceLocation getAsmLoc() const { return AsmLoc; }
-  void setAsmLoc(SourceLocation L) { AsmLoc = L; }
   SourceLocation getRParenLoc() const { return RParenLoc; }
   void setRParenLoc(SourceLocation L) { RParenLoc = L; }
 
@@ -1485,19 +1522,6 @@
 
   //===--- Output operands ---===//
 
-  unsigned getNumOutputs() const { return NumOutputs; }
-
-  IdentifierInfo *getOutputIdentifier(unsigned i) const {
-    return Names[i];
-  }
-
-  StringRef getOutputName(unsigned i) const {
-    if (IdentifierInfo *II = getOutputIdentifier(i))
-      return II->getName();
-
-    return StringRef();
-  }
-
   /// getOutputConstraint - Return the constraint string for the specified
   /// output operand.  All output constraints are known to be non-empty (either
   /// '=' or '+').
@@ -1641,12 +1665,8 @@
   std::string AsmStr;
 
   unsigned NumAsmToks;
-  unsigned NumInputs;
-  unsigned NumOutputs;
-  unsigned NumClobbers;
 
   Token *AsmToks;
-  IdentifierInfo **Names;
   Stmt **Exprs;
   StringRef *Clobbers;
 
@@ -1660,11 +1680,8 @@
 
   /// \brief Build an empty MS-style inline-assembly statement.
   explicit MSAsmStmt(EmptyShell Empty) : AsmStmt(MSAsmStmtClass, Empty),
-    NumAsmToks(0), NumInputs(0), NumOutputs(0), NumClobbers(0), AsmToks(0),
-    Names(0), Exprs(0), Clobbers(0) { }
+    NumAsmToks(0), AsmToks(0), Exprs(0), Clobbers(0) { }
 
-  SourceLocation getAsmLoc() const { return AsmLoc; }
-  void setAsmLoc(SourceLocation L) { AsmLoc = L; }
   SourceLocation getLBraceLoc() const { return LBraceLoc; }
   void setLBraceLoc(SourceLocation L) { LBraceLoc = L; }
   SourceLocation getEndLoc() const { return EndLoc; }
@@ -1683,19 +1700,6 @@
 
   //===--- Output operands ---===//
 
-  unsigned getNumOutputs() const { return NumOutputs; }
-
-  IdentifierInfo *getOutputIdentifier(unsigned i) const {
-    return Names[i];
-  }
-
-  StringRef getOutputName(unsigned i) const {
-    if (IdentifierInfo *II = getOutputIdentifier(i))
-      return II->getName();
-
-    return StringRef();
-  }
-
   Expr *getOutputExpr(unsigned i);
 
   const Expr *getOutputExpr(unsigned i) const {
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index 8c76a9c..bed288b 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -596,9 +596,8 @@
                        Expr **exprs, StringLiteral *asmstr,
                        unsigned numclobbers, StringLiteral **clobbers,
                        SourceLocation rparenloc)
-  : AsmStmt(GCCAsmStmtClass, issimple, isvolatile), AsmLoc(asmloc)
-  , RParenLoc(rparenloc), AsmStr(asmstr), NumOutputs(numoutputs)
-  , NumInputs(numinputs), NumClobbers(numclobbers) {
+  : AsmStmt(GCCAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
+            numinputs, numclobbers), RParenLoc(rparenloc), AsmStr(asmstr) {
 
   unsigned NumExprs = NumOutputs + NumInputs;
 
@@ -622,10 +621,9 @@
                      ArrayRef<Expr*> inputexprs, ArrayRef<Expr*> outputexprs,
                      StringRef asmstr, ArrayRef<StringRef> clobbers,
                      SourceLocation endloc)
-  : AsmStmt(MSAsmStmtClass, issimple, isvolatile), AsmLoc(asmloc),
-    LBraceLoc(lbraceloc), EndLoc(endloc), AsmStr(asmstr.str()),
-    NumAsmToks(asmtoks.size()), NumInputs(inputs.size()),
-    NumOutputs(outputs.size()), NumClobbers(clobbers.size()) {
+  : AsmStmt(MSAsmStmtClass, asmloc, issimple, isvolatile, outputs.size(), inputs.size(),
+            clobbers.size()), LBraceLoc(lbraceloc), EndLoc(endloc),
+    AsmStr(asmstr.str()), NumAsmToks(asmtoks.size()) {
   assert (inputs.size() == inputexprs.size() && "Input expr size mismatch!");
   assert (outputs.size() == outputexprs.size() && "Input expr size mismatch!");