Add more semantic analysis for inline asm statements.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44349 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/SemaStmt.cpp b/Sema/SemaStmt.cpp
index 7f5d038..d051f6b 100644
--- a/Sema/SemaStmt.cpp
+++ b/Sema/SemaStmt.cpp
@@ -659,11 +659,26 @@
                                     SourceLocation RParenLoc) {
   Expr *E = (Expr *)AsmString;
  
-  // Check that the output exprs are valid lvalues.
   for (unsigned i = 0; i < NumOutputs; i++) {
+    StringLiteral *Literal = cast<StringLiteral>((Expr *)Constraints[i]);
+    assert(!Literal->isWide() && 
+           "Output constraint strings should not be wide!");
+
+    std::string OutputConstraint(Literal->getStrData(), 
+                                 Literal->getByteLength());
+    
+    TargetInfo::ConstraintInfo info;
+    if (!Context.Target.validateOutputConstraint(OutputConstraint.c_str(),
+                                                 info)) {
+      // FIXME: We currently leak memory here.
+      Diag(Literal->getLocStart(),
+           diag::err_invalid_output_constraint_in_asm);
+      return true;
+    }
+    
+    // Check that the output exprs are valid lvalues.
     Expr *OutputExpr = (Expr *)Exprs[i];
     Expr::isLvalueResult Result = OutputExpr->isLvalue();
-    
     if (Result != Expr::LV_Valid) {
       ParenExpr *PE = cast<ParenExpr>(OutputExpr);
       
@@ -676,10 +691,26 @@
     }
   }
   
-  // Check that the input exprs aren't of type void.
   for (unsigned i = NumOutputs, e = NumOutputs + NumInputs; i != e; i++) {
-    Expr *InputExpr = (Expr *)Exprs[i];
+    StringLiteral *Literal = cast<StringLiteral>((Expr *)Constraints[i]);
+    assert(!Literal->isWide() && 
+           "Output constraint strings should not be wide!");
     
+    std::string InputConstraint(Literal->getStrData(), 
+                                Literal->getByteLength());
+    
+    TargetInfo::ConstraintInfo info;
+    if (!Context.Target.validateInputConstraint(InputConstraint.c_str(),
+                                                NumOutputs,                                                
+                                                info)) {
+      // FIXME: We currently leak memory here.
+      Diag(Literal->getLocStart(),
+           diag::err_invalid_input_constraint_in_asm);
+      return true;
+    }
+    
+    // Check that the input exprs aren't of type void.
+    Expr *InputExpr = (Expr *)Exprs[i];    
     if (InputExpr->getType()->isVoidType()) {
       ParenExpr *PE = cast<ParenExpr>(InputExpr);