Store inline asm code in the AST.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44255 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/AST/StmtPrinter.cpp b/AST/StmtPrinter.cpp
index fa3eb84..306bfcb 100644
--- a/AST/StmtPrinter.cpp
+++ b/AST/StmtPrinter.cpp
@@ -326,7 +326,9 @@
 
 
 void StmtPrinter::VisitAsmStmt(AsmStmt *Node) {
-  Indent() << "asm (/*todo*/);\n";
+  Indent() << "asm (";
+  VisitStringLiteral(Node->getAsmString());
+  OS << ");\n";
 }
 
 void StmtPrinter::VisitObjcAtTryStmt(ObjcAtTryStmt *Node) {
diff --git a/AST/StmtSerialization.cpp b/AST/StmtSerialization.cpp
index 24733eb..f2c7834 100644
--- a/AST/StmtSerialization.cpp
+++ b/AST/StmtSerialization.cpp
@@ -197,14 +197,16 @@
 
 void AsmStmt::EmitImpl(Serializer& S) const {
   S.Emit(AsmLoc);
+  getAsmString()->EmitImpl(S);
   S.Emit(RParenLoc);  
 }
 
 AsmStmt* AsmStmt::CreateImpl(Deserializer& D) {
   SourceLocation ALoc = SourceLocation::ReadVal(D);
+  StringLiteral *AsmStr = StringLiteral::CreateImpl(D);
   SourceLocation PLoc = SourceLocation::ReadVal(D);
   
-  return new AsmStmt(ALoc,PLoc);  
+  return new AsmStmt(ALoc, AsmStr, PLoc);  
 }
 
 void BinaryOperator::EmitImpl(Serializer& S) const {
diff --git a/Parse/ParseStmt.cpp b/Parse/ParseStmt.cpp
index cb2a691..8d5be68 100644
--- a/Parse/ParseStmt.cpp
+++ b/Parse/ParseStmt.cpp
@@ -943,8 +943,10 @@
   }
   Loc = ConsumeParen();
   
-  ParseAsmStringLiteral();
-  
+  ExprResult AsmString = ParseAsmStringLiteral();
+  if (AsmString.isInvalid)
+    return true;
+    
   // Parse Outputs, if present.
   ParseAsmOperandsOpt();
   
@@ -969,7 +971,7 @@
   SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, Loc);
   
   // FIXME: Pass all the details down to the action.
-  return Actions.ActOnAsmStmt(AsmLoc, RParenLoc);
+  return Actions.ActOnAsmStmt(AsmLoc, AsmString.Val, RParenLoc);
 }
 
 /// ParseAsmOperands - Parse the asm-operands production as used by
diff --git a/Parse/Parser.cpp b/Parse/Parser.cpp
index b571703..8a0d8c7 100644
--- a/Parse/Parser.cpp
+++ b/Parse/Parser.cpp
@@ -575,16 +575,18 @@
 /// [GNU] asm-string-literal:
 ///         string-literal
 ///
-void Parser::ParseAsmStringLiteral() {
+Parser::ExprResult Parser::ParseAsmStringLiteral() {
   if (!isTokenStringLiteral()) {
     Diag(Tok, diag::err_expected_string_literal);
-    return;
+    return true;
   }
   
   ExprResult Res = ParseStringLiteralExpression();
-  if (Res.isInvalid) return;
+  if (Res.isInvalid) return true;
   
   // TODO: Diagnose: wide string literal in 'asm'
+    
+  return Res;
 }
 
 /// ParseSimpleAsm
diff --git a/Sema/Sema.h b/Sema/Sema.h
index 4ed71f7..78cc888 100644
--- a/Sema/Sema.h
+++ b/Sema/Sema.h
@@ -346,7 +346,8 @@
   virtual StmtResult ActOnReturnStmt(SourceLocation ReturnLoc,
                                      ExprTy *RetValExp);
   
-  virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc, 
+  virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc,
+                                  ExprTy *AsmString,
                                   SourceLocation RParenLoc);
   
   virtual StmtResult ActOnObjcAtCatchStmt(SourceLocation AtLoc, 
diff --git a/Sema/SemaStmt.cpp b/Sema/SemaStmt.cpp
index 65acf0b..ad3d2e4 100644
--- a/Sema/SemaStmt.cpp
+++ b/Sema/SemaStmt.cpp
@@ -644,9 +644,12 @@
   return new ReturnStmt(ReturnLoc, (Expr*)RetValExp);
 }
 
-Sema::StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, 
+Sema::StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
+                                    ExprTy *AsmString,
                                     SourceLocation RParenLoc) {
-  return new AsmStmt(AsmLoc, RParenLoc);
+  Expr *E = (Expr *)AsmString;
+    
+  return new AsmStmt(AsmLoc, cast<StringLiteral>(E), RParenLoc);
 }
 
 Action::StmtResult
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 2034482..802c025 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -30,6 +30,7 @@
   class ScopedDecl;
   class IdentifierInfo;
   class SourceManager;
+  class StringLiteral;
   class SwitchStmt;
   class PrinterHelper;
     
@@ -704,11 +705,17 @@
 ///
 class AsmStmt : public Stmt {
   SourceLocation AsmLoc, RParenLoc;
+  StringLiteral *AsmStr;
   // FIXME: This doesn't capture most of the interesting pieces.
 public:
-  AsmStmt(SourceLocation asmloc, SourceLocation rparenloc)
-    : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc) {}
+  AsmStmt(SourceLocation asmloc, StringLiteral *asmstr, 
+          SourceLocation rparenloc)
+    : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc),
+      AsmStr(asmstr) {}
   
+  const StringLiteral *getAsmString() const { return AsmStr; }
+  StringLiteral *getAsmString() { return AsmStr; }
+
   virtual SourceRange getSourceRange() const {
     return SourceRange(AsmLoc, RParenLoc);
   }
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index 2e8b4de..2da8e01 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -286,7 +286,8 @@
                                      ExprTy *RetValExp) {
     return 0;
   }
-  virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc, 
+  virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc,
+                                  ExprTy *AsmString,
                                   SourceLocation RParenLoc) {
     return 0;
   }
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 57fd4e1..9d7f27e 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -244,7 +244,10 @@
   }
   bool SkipUntil(const tok::TokenKind *Toks, unsigned NumToks,
                  bool StopAtSemi = true, bool DontConsume = false);
-   
+ 
+  typedef Action::ExprResult ExprResult;
+  typedef Action::StmtResult StmtResult;
+    
   //===--------------------------------------------------------------------===//
   // C99 6.9: External Definitions.
   DeclTy *ParseExternalDeclaration();
@@ -252,7 +255,7 @@
   DeclTy *ParseFunctionDefinition(Declarator &D);
   void ParseKNRParamDeclarations(Declarator &D);
   void ParseSimpleAsm();
-  void ParseAsmStringLiteral();
+  ExprResult ParseAsmStringLiteral();
 
   // Objective-C External Declarations
   DeclTy *ParseObjCAtDirectives(); 
@@ -305,9 +308,6 @@
   //===--------------------------------------------------------------------===//
   // C99 6.5: Expressions.
 
-  typedef Action::ExprResult ExprResult;
-  typedef Action::StmtResult StmtResult;
-  
   ExprResult ParseExpression();
   ExprResult ParseConstantExpression();
   ExprResult ParseAssignmentExpression();  // Expr that doesn't include commas.