[ms-inline asm] Hoist more common code into the AsmStmt base class.  Add stubs
with FIXMEs for unimplemented features.  No functional change intended.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162716 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 3c060ba..455a24f 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -1426,6 +1426,24 @@
     return StringRef();
   }
 
+  /// getOutputConstraint - Return the constraint string for the specified
+  /// output operand.  All output constraints are known to be non-empty (either
+  /// '=' or '+').
+  virtual StringRef getOutputConstraint(unsigned i) const = 0;
+
+  /// isOutputPlusConstraint - Return true if the specified output constraint
+  /// is a "+" constraint (which is both an input and an output) or false if it
+  /// is an "=" constraint (just an output).
+  bool isOutputPlusConstraint(unsigned i) const {
+    return getOutputConstraint(i)[0] == '+';
+  }
+
+  virtual const Expr *getOutputExpr(unsigned i) const = 0;
+
+  /// getNumPlusOperands - Return the number of output operands that have a "+"
+  /// constraint.
+  unsigned getNumPlusOperands() const;
+
   //===--- Input operands ---===//
 
   unsigned getNumInputs() const { return NumInputs; }
@@ -1441,6 +1459,12 @@
     return StringRef();
   }
 
+  /// getInputConstraint - Return the specified input constraint.  Unlike output
+  /// constraints, these can be empty.
+  virtual StringRef getInputConstraint(unsigned i) const = 0;
+
+  virtual const Expr *getInputExpr(unsigned i) const = 0;
+
   //===--- Other ---===//
 
   unsigned getNumClobbers() const { return NumClobbers; }
@@ -1581,9 +1605,6 @@
 
   //===--- Output operands ---===//
 
-  /// getOutputConstraint - Return the constraint string for the specified
-  /// output operand.  All output constraints are known to be non-empty (either
-  /// '=' or '+').
   StringRef getOutputConstraint(unsigned i) const;
 
   const StringLiteral *getOutputConstraintLiteral(unsigned i) const {
@@ -1599,21 +1620,8 @@
     return const_cast<GCCAsmStmt*>(this)->getOutputExpr(i);
   }
 
-  /// isOutputPlusConstraint - Return true if the specified output constraint
-  /// is a "+" constraint (which is both an input and an output) or false if it
-  /// is an "=" constraint (just an output).
-  bool isOutputPlusConstraint(unsigned i) const {
-    return getOutputConstraint(i)[0] == '+';
-  }
-
-  /// getNumPlusOperands - Return the number of output operands that have a "+"
-  /// constraint.
-  unsigned getNumPlusOperands() const;
-
   //===--- Input operands ---===//
 
-  /// getInputConstraint - Return the specified input constraint.  Unlike output
-  /// constraints, these can be empty.
   StringRef getInputConstraint(unsigned i) const;
 
   const StringLiteral *getInputConstraintLiteral(unsigned i) const {
@@ -1706,6 +1714,8 @@
 
   //===--- Output operands ---===//
 
+  StringRef getOutputConstraint(unsigned i) const;
+
   Expr *getOutputExpr(unsigned i);
 
   const Expr *getOutputExpr(unsigned i) const {
@@ -1714,6 +1724,8 @@
 
   //===--- Input operands ---===//
 
+  StringRef getInputConstraint(unsigned i) const;
+
   Expr *getInputExpr(unsigned i);
   void setInputExpr(unsigned i, Expr *E);
 
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index fc66202..b7c2b39 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -321,6 +321,16 @@
   }
 }
 
+/// getNumPlusOperands - Return the number of output operands that have a "+"
+/// constraint.
+unsigned AsmStmt::getNumPlusOperands() const {
+  unsigned Res = 0;
+  for (unsigned i = 0, e = getNumOutputs(); i != e; ++i)
+    if (isOutputPlusConstraint(i))
+      ++Res;
+  return Res;
+}
+
 StringRef GCCAsmStmt::getClobber(unsigned i) const {
   return getClobberStringLiteral(i)->getString();
 }
@@ -336,16 +346,6 @@
   return getOutputConstraintLiteral(i)->getString();
 }
 
-/// getNumPlusOperands - Return the number of output operands that have a "+"
-/// constraint.
-unsigned GCCAsmStmt::getNumPlusOperands() const {
-  unsigned Res = 0;
-  for (unsigned i = 0, e = getNumOutputs(); i != e; ++i)
-    if (isOutputPlusConstraint(i))
-      ++Res;
-  return Res;
-}
-
 Expr *GCCAsmStmt::getInputExpr(unsigned i) {
   return cast<Expr>(Exprs[i + NumOutputs]);
 }
@@ -353,14 +353,12 @@
   Exprs[i + NumOutputs] = E;
 }
 
-
 /// getInputConstraint - Return the specified input constraint.  Unlike output
 /// constraints, these can be empty.
 StringRef GCCAsmStmt::getInputConstraint(unsigned i) const {
   return getInputConstraintLiteral(i)->getString();
 }
 
-
 void GCCAsmStmt::setOutputsAndInputsAndClobbers(ASTContext &C,
                                              IdentifierInfo **Names,
                                              StringLiteral **Constraints,
@@ -584,6 +582,14 @@
   return cast<Expr>(Exprs[i]);
 }
 
+/// getOutputConstraint - Return the constraint string for the specified
+/// output operand.  All output constraints are known to be non-empty (either
+/// '=' or '+').
+StringRef MSAsmStmt::getOutputConstraint(unsigned i) const {
+  // FIXME: Compute constraints.
+  return StringRef();
+}
+
 Expr *MSAsmStmt::getInputExpr(unsigned i) {
   return cast<Expr>(Exprs[i + NumOutputs]);
 }
@@ -591,6 +597,13 @@
   Exprs[i + NumOutputs] = E;
 }
 
+/// getInputConstraint - Return the specified input constraint.  Unlike output
+/// constraints, these can be empty.
+StringRef MSAsmStmt::getInputConstraint(unsigned i) const {
+  // FIXME: Compute constraints.
+  return StringRef();
+}
+
 QualType CXXCatchStmt::getCaughtType() const {
   if (ExceptionDecl)
     return ExceptionDecl->getType();