[ms-inline asm] Add the basic APIs for Exprs to the MSAsmStmt AST.  Next we need
generate the Input/Output expressions using Sema::ActOnIdExpression().

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162509 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index ed2d78f..58de1e9 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -1631,6 +1631,7 @@
   MSAsmStmt(ASTContext &C, SourceLocation asmloc, SourceLocation lbraceloc,
             bool issimple, bool isvolatile, ArrayRef<Token> asmtoks,
             ArrayRef<IdentifierInfo*> inputs, ArrayRef<IdentifierInfo*> outputs,
+            ArrayRef<Expr*> inputexprs, ArrayRef<Expr*> outputexprs,
             StringRef asmstr, ArrayRef<StringRef> clobbers,
             SourceLocation endloc);
 
@@ -1672,6 +1673,8 @@
     return StringRef();
   }
 
+  Expr *getOutputExpr(unsigned i);
+
   const Expr *getOutputExpr(unsigned i) const {
     return const_cast<MSAsmStmt*>(this)->getOutputExpr(i);
   }
@@ -1691,6 +1694,9 @@
     return StringRef();
   }
 
+  Expr *getInputExpr(unsigned i);
+  void setInputExpr(unsigned i, Expr *E);
+
   const Expr *getInputExpr(unsigned i) const {
     return const_cast<MSAsmStmt*>(this)->getInputExpr(i);
   }
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index 963a20c..6b14ae5 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -548,6 +548,17 @@
   }
 }
 
+Expr *MSAsmStmt::getOutputExpr(unsigned i) {
+  return cast<Expr>(Exprs[i]);
+}
+
+Expr *MSAsmStmt::getInputExpr(unsigned i) {
+  return cast<Expr>(Exprs[i + NumOutputs]);
+}
+void MSAsmStmt::setInputExpr(unsigned i, Expr *E) {
+  Exprs[i + NumOutputs] = E;
+}
+
 QualType CXXCatchStmt::getCaughtType() const {
   if (ExceptionDecl)
     return ExceptionDecl->getType();
@@ -585,12 +596,16 @@
 MSAsmStmt::MSAsmStmt(ASTContext &C, SourceLocation asmloc,
                      SourceLocation lbraceloc, bool issimple, bool isvolatile,
                      ArrayRef<Token> asmtoks, ArrayRef<IdentifierInfo*> inputs,
-                     ArrayRef<IdentifierInfo*> outputs, StringRef asmstr,
-                     ArrayRef<StringRef> clobbers, SourceLocation endloc)
+                     ArrayRef<IdentifierInfo*> outputs,
+                     ArrayRef<Expr*> inputexprs, ArrayRef<Expr*> outputexprs,
+                     StringRef asmstr, ArrayRef<StringRef> clobbers,
+                     SourceLocation endloc)
   : Stmt(MSAsmStmtClass), AsmLoc(asmloc), LBraceLoc(lbraceloc), EndLoc(endloc),
     AsmStr(asmstr.str()), IsSimple(issimple), IsVolatile(isvolatile),
     NumAsmToks(asmtoks.size()), NumInputs(inputs.size()),
     NumOutputs(outputs.size()), NumClobbers(clobbers.size()) {
+  assert (inputs.size() == inputexprs.size() && "Input expr size mismatch!");
+  assert (outputs.size() == outputexprs.size() && "Input expr size mismatch!");
 
   unsigned NumExprs = NumOutputs + NumInputs;
 
@@ -600,6 +615,12 @@
   for (unsigned i = NumOutputs, e = NumExprs; i != e; ++i)
     Names[i] = inputs[i];
 
+  Exprs = new (C) Stmt*[NumExprs];
+  for (unsigned i = 0, e = NumOutputs; i != e; ++i)
+    Exprs[i] = outputexprs[i];
+  for (unsigned i = NumOutputs, e = NumExprs; i != e; ++i)
+    Exprs[i] = inputexprs[i];
+
   AsmToks = new (C) Token[NumAsmToks];
   for (unsigned i = 0, e = NumAsmToks; i != e; ++i)
     AsmToks[i] = asmtoks[i];
diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp
index 38bc254..039aa1e 100644
--- a/lib/Sema/SemaStmtAsm.cpp
+++ b/lib/Sema/SemaStmtAsm.cpp
@@ -458,7 +458,8 @@
   MSAsmStmt *NS =                                                          \
     new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, /*IsSimple*/ true, \
                             /*IsVolatile*/ true, AsmToks, Inputs, Outputs, \
-                            AsmString, Clobbers, EndLoc);
+                            InputExprs, OutputExprs, AsmString, Clobbers,  \
+                            EndLoc);
 
 StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc,
                                 SourceLocation LBraceLoc,
@@ -470,6 +471,8 @@
   std::set<std::string> ClobberRegs;
   SmallVector<IdentifierInfo*, 4> Inputs;
   SmallVector<IdentifierInfo*, 4> Outputs;
+  SmallVector<Expr*, 4> InputExprs;
+  SmallVector<Expr*, 4> OutputExprs;
 
   // Empty asm statements don't need to instantiate the AsmParser, etc.
   if (AsmToks.empty()) {
@@ -593,8 +596,16 @@
           IdentifierInfo *II = getIdentifierInfo(Name, AsmToks,
                                                  AsmTokRanges[StrIdx].first,
                                                  AsmTokRanges[StrIdx].second);
-          if (II)
-            isDef ? Outputs.push_back(II) : Inputs.push_back(II);
+          if (II) {
+            // FIXME: Compute the InputExpr/OutputExpr using ActOnIdExpression().
+            if (isDef) {
+              Outputs.push_back(II);
+              OutputExprs.push_back(0);
+            } else {
+              Inputs.push_back(II);
+              InputExprs.push_back(0);
+            }
+          }
         }
       }
     }
@@ -606,6 +617,7 @@
   MSAsmStmt *NS =
     new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, IsSimple,
                             /*IsVolatile*/ true, AsmToks, Inputs, Outputs,
-                            AsmString, Clobbers, EndLoc);
+                            InputExprs, OutputExprs, AsmString, Clobbers,
+                            EndLoc);
   return Owned(NS);
 }