AsmWriter should not print LLVM constant in comment. Assembler won't like
[oota-llvm.git] / lib / VMCore / AsmWriter.cpp
index 45be28df724663a5b112a8c4668ca1808f9cb360..6b644219e13ac306dd98d24e9960ea095deff419 100644 (file)
 #include "llvm/CallingConv.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
+#include "llvm/InlineAsm.h"
 #include "llvm/Instruction.h"
 #include "llvm/Instructions.h"
 #include "llvm/Module.h"
 #include "llvm/SymbolTable.h"
-#include "llvm/Assembly/Writer.h"
 #include "llvm/Support/CFG.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/STLExtras.h"
@@ -398,11 +398,28 @@ std::ostream &llvm::WriteTypeSymbolic(std::ostream &Out, const Type *Ty,
   }
 }
 
+// PrintEscapedString - Print each character of the specified string, escaping
+// it if it is not printable or if it is an escape char.
+static void PrintEscapedString(const std::string &Str, std::ostream &Out) {
+  for (unsigned i = 0, e = Str.size(); i != e; ++i) {
+    unsigned char C = Str[i];
+    if (isprint(C) && C != '"' && C != '\\') {
+      Out << C;
+    } else {
+      Out << '\\'
+          << (char) ((C/16  < 10) ? ( C/16 +'0') : ( C/16 -10+'A'))
+          << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A'));
+    }
+  }
+}
+
 /// @brief Internal constant writer.
 static void WriteConstantInt(std::ostream &Out, const Constant *CV,
                              bool PrintName,
                              std::map<const Type *, std::string> &TypeTable,
                              SlotMachine *Machine) {
+  const int IndentSize = 4;
+  static std::string Indent = "\n";
   if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV)) {
     Out << (CB == ConstantBool::True ? "true" : "false");
   } else if (const ConstantSInt *CI = dyn_cast<ConstantSInt>(CV)) {
@@ -443,29 +460,9 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV,
     // ubytes or an array of sbytes with positive values.
     //
     const Type *ETy = CA->getType()->getElementType();
-    bool isString = (ETy == Type::SByteTy || ETy == Type::UByteTy);
-
-    if (ETy == Type::SByteTy)
-      for (unsigned i = 0; i < CA->getNumOperands(); ++i)
-        if (cast<ConstantSInt>(CA->getOperand(i))->getValue() < 0) {
-          isString = false;
-          break;
-        }
-
-    if (isString) {
+    if (CA->isString()) {
       Out << "c\"";
-      for (unsigned i = 0; i < CA->getNumOperands(); ++i) {
-        unsigned char C =
-          (unsigned char)cast<ConstantInt>(CA->getOperand(i))->getRawValue();
-
-        if (isprint(C) && C != '"' && C != '\\') {
-          Out << C;
-        } else {
-          Out << '\\'
-              << (char) ((C/16  < 10) ? ( C/16 +'0') : ( C/16 -10+'A'))
-              << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A'));
-        }
-      }
+      PrintEscapedString(CA->getAsString(), Out);
       Out << "\"";
 
     } else {                // Cannot output in string format...
@@ -486,22 +483,30 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV,
     }
   } else if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) {
     Out << '{';
-    if (CS->getNumOperands()) {
-      Out << ' ';
+    unsigned N = CS->getNumOperands();
+    if (N) {
+      if (N > 2) {
+        Indent += std::string(IndentSize, ' ');
+        Out << Indent;
+      } else {
+        Out << ' ';
+      }
       printTypeInt(Out, CS->getOperand(0)->getType(), TypeTable);
 
       WriteAsOperandInternal(Out, CS->getOperand(0),
                              PrintName, TypeTable, Machine);
 
-      for (unsigned i = 1; i < CS->getNumOperands(); i++) {
+      for (unsigned i = 1; i < N; i++) {
         Out << ", ";
+        if (N > 2) Out << Indent;
         printTypeInt(Out, CS->getOperand(i)->getType(), TypeTable);
 
         WriteAsOperandInternal(Out, CS->getOperand(i),
                                PrintName, TypeTable, Machine);
       }
+      if (N > 2) Indent.resize(Indent.size() - IndentSize);
     }
-
     Out << " }";
   } else if (const ConstantPacked *CP = dyn_cast<ConstantPacked>(CV)) {
       const Type *ETy = CP->getType()->getElementType();
@@ -560,9 +565,18 @@ static void WriteAsOperandInternal(std::ostream &Out, const Value *V,
     Out << getLLVMName(V->getName());
   else {
     const Constant *CV = dyn_cast<Constant>(V);
-    if (CV && !isa<GlobalValue>(CV))
+    if (CV && !isa<GlobalValue>(CV)) {
       WriteConstantInt(Out, CV, PrintName, TypeTable, Machine);
-    else {
+    } else if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
+      Out << "asm ";
+      if (IA->hasSideEffects())
+        Out << "sideeffect ";
+      Out << '"';
+      PrintEscapedString(IA->getAsmString(), Out);
+      Out << "\", \"";
+      PrintEscapedString(IA->getConstraintString(), Out);
+      Out << '"';
+    } else {
       int Slot;
       if (Machine) {
         Slot = Machine->getSlot(V);
@@ -780,6 +794,26 @@ void AssemblyWriter::printModule(const Module *M) {
   if (!M->getTargetTriple().empty())
     Out << "target triple = \"" << M->getTargetTriple() << "\"\n";
 
+  if (!M->getModuleInlineAsm().empty()) {
+    // Split the string into lines, to make it easier to read the .ll file.
+    std::string Asm = M->getModuleInlineAsm();
+    size_t CurPos = 0;
+    size_t NewLine = Asm.find_first_of('\n', CurPos);
+    while (NewLine != std::string::npos) {
+      // We found a newline, print the portion of the asm string from the
+      // last newline up to this newline.
+      Out << "module asm \"";
+      PrintEscapedString(std::string(Asm.begin()+CurPos, Asm.begin()+NewLine),
+                         Out);
+      Out << "\"\n";
+      CurPos = NewLine+1;
+      NewLine = Asm.find_first_of('\n', CurPos);
+    }
+    Out << "module asm \"";
+    PrintEscapedString(std::string(Asm.begin()+CurPos, Asm.end()), Out);
+    Out << "\"\n";
+  }
+  
   // Loop over the dependent libraries and emit them.
   Module::lib_iterator LI = M->lib_begin();
   Module::lib_iterator LE = M->lib_end();
@@ -832,7 +866,12 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
     assert(C &&  "GlobalVar initializer isn't constant?");
     writeOperand(GV->getInitializer(), false, isa<GlobalValue>(C));
   }
-
+  
+  if (GV->hasSection())
+    Out << ", section \"" << GV->getSection() << '"';
+  if (GV->getAlignment())
+    Out << ", align " << GV->getAlignment();
+  
   printInfoComment(*GV);
   Out << "\n";
 }
@@ -940,6 +979,11 @@ void AssemblyWriter::printFunction(const Function *F) {
   }
   Out << ')';
 
+  if (F->hasSection())
+    Out << " section \"" << F->getSection() << '"';
+  if (F->getAlignment())
+    Out << " align " << F->getAlignment();
+
   if (F->isExternal()) {
     Out << "\n";
   } else {
@@ -1173,7 +1217,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
       writeOperand(AI->getArraySize(), true);
     }
     if (AI->getAlignment()) {
-      Out << ", " << AI->getAlignment();
+      Out << ", align " << AI->getAlignment();
     }
   } else if (isa<CastInst>(I)) {
     if (Operand) writeOperand(Operand, true);   // Work with broken code
@@ -1244,6 +1288,10 @@ void Function::print(std::ostream &o, AssemblyAnnotationWriter *AAW) const {
   W.write(this);
 }
 
+void InlineAsm::print(std::ostream &o, AssemblyAnnotationWriter *AAW) const {
+  WriteAsOperand(o, this, true, true, 0);
+}
+
 void BasicBlock::print(std::ostream &o, AssemblyAnnotationWriter *AAW) const {
   SlotMachine SlotTable(getParent());
   AssemblyWriter W(o, SlotTable,
@@ -1263,9 +1311,6 @@ void Constant::print(std::ostream &o) const {
   if (this == 0) { o << "<null> constant value\n"; return; }
 
   o << ' ' << getType()->getDescription() << ' ';
-
-  std::map<const Type *, std::string> TypeTable;
-  WriteConstantInt(o, this, false, TypeTable, 0);
 }
 
 void Type::print(std::ostream &o) const {