Add the ability for MCStreamer to emit comments on the same line as directives.
authorChris Lattner <sabre@nondot.org>
Fri, 22 Jan 2010 07:29:22 +0000 (07:29 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 22 Jan 2010 07:29:22 +0000 (07:29 +0000)
Switch over the asm-verbose comment for double values to use it.  We now get:

_x:
.long 343597384                                   ## double 1.231200e+02
.long 1079953326

For example, note that the comment is on the same line as the .long.  Woo.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@94166 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCStreamer.h
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/MC/MCAsmStreamer.cpp

index 1afa6dcdf68c3cb1b2243eb990e463903c0f470d..6afe1bf6cea05b4de7eb9eb0dd45a907528d6617 100644 (file)
@@ -26,7 +26,9 @@ namespace llvm {
   class MCSection;
   class MCSymbol;
   class StringRef;
+  class Twine;
   class raw_ostream;
+  class formatted_raw_ostream;
 
   /// MCStreamer - Streaming machine code generation interface.  This interface
   /// is intended to provide a programatic interface that is very similar to the
@@ -79,6 +81,15 @@ namespace llvm {
 
     MCContext &getContext() const { return Context; }
 
+    /// addComment - Add a comment that can be emitted to the generated .s
+    /// file if applicable as a QoI issue to make the output of the compiler
+    /// more readable.  This only affects the MCAsmStreamer, and only when
+    /// verbose assembly output is enabled.
+    ///
+    /// If the comment includes embedded \n's, they will each get the comment
+    /// prefix as appropriate.  The added comment should not end with a \n.
+    virtual void addComment(const Twine &T) {}
+    
     /// @name Symbol & Section Management
     /// @{
     
@@ -234,7 +245,7 @@ namespace llvm {
   /// createAsmStreamer - Create a machine code streamer which will print out
   /// assembly for the native target, suitable for compiling with a native
   /// assembler.
-  MCStreamer *createAsmStreamer(MCContext &Ctx, raw_ostream &OS,
+  MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
                                 const MCAsmInfo &MAI, bool isLittleEndian,
                                 bool isVerboseAsm,
                                 MCInstPrinter *InstPrint = 0,
index d5ae71f8ea25c2dda662f47c529bfbb1914e5dc0..e12a66e7e41f278cac29b79c40981215c16de3de 100644 (file)
@@ -1126,13 +1126,16 @@ static void EmitGlobalConstantStruct(const ConstantStruct *CS,
 
 static void EmitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace,
                                  AsmPrinter &AP) {
+  SmallString<128> TmpBuffer;
+  
   // FP Constants are printed as integer constants to avoid losing
   // precision.
   if (CFP->getType()->isDoubleTy()) {
     if (AP.VerboseAsm) {
+      raw_svector_ostream OS(TmpBuffer);
       double Val = CFP->getValueAPF().convertToDouble();  // for comment only
-      AP.O.PadToColumn(AP.MAI->getCommentColumn());
-      AP.O << AP.MAI->getCommentString() << " double " << Val << '\n';
+      OS << "double " << Val;
+      AP.OutStreamer.addComment(OS.str());
     }
 
     uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
index 79cb647429506296c5499d80b4b513ae2ed0a1da..82d7fdbdf9429cdb37b4fa3636e6d02f0b3163c1 100644 (file)
@@ -8,7 +8,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/MC/MCStreamer.h"
-#include "llvm/ADT/SmallString.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCCodeEmitter.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCInstPrinter.h"
 #include "llvm/MC/MCSectionMachO.h"
 #include "llvm/MC/MCSymbol.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Twine.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/FormattedStream.h"
 using namespace llvm;
 
 namespace {
 
 class MCAsmStreamer : public MCStreamer {
-  raw_ostream &OS;
+  formatted_raw_ostream &OS;
   const MCAsmInfo &MAI;
   bool IsLittleEndian, IsVerboseAsm;
   MCInstPrinter *InstPrinter;
   MCCodeEmitter *Emitter;
+  
+  SmallString<128> CommentToEmit;
 public:
-  MCAsmStreamer(MCContext &Context, raw_ostream &os, const MCAsmInfo &mai,
+  MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os,
+                const MCAsmInfo &mai,
                 bool isLittleEndian, bool isVerboseAsm, MCInstPrinter *printer,
                 MCCodeEmitter *emitter)
     : MCStreamer(Context), OS(os), MAI(mai), IsLittleEndian(isLittleEndian),
@@ -41,6 +45,22 @@ public:
 
   bool isLittleEndian() const { return IsLittleEndian; }
   
+  
+  inline void EmitEOL() {
+    if (CommentToEmit.empty()) {
+      OS << '\n';
+      return;
+    }
+    EmitCommentsAndEOL();
+  }
+  void EmitCommentsAndEOL();
+  
+  /// addComment - Add a comment that can be emitted to the generated .s
+  /// file if applicable as a QoI issue to make the output of the compiler
+  /// more readable.  This only affects the MCAsmStreamer, and only when
+  /// verbose assembly output is enabled.
+  virtual void addComment(const Twine &T);
+  
   /// @name MCStreamer Interface
   /// @{
 
@@ -86,6 +106,34 @@ public:
 
 } // end anonymous namespace.
 
+/// addComment - Add a comment that can be emitted to the generated .s
+/// file if applicable as a QoI issue to make the output of the compiler
+/// more readable.  This only affects the MCAsmStreamer, and only when
+/// verbose assembly output is enabled.
+void MCAsmStreamer::addComment(const Twine &T) {
+  if (!IsVerboseAsm) return;
+  // Each comment goes on its own line.
+  if (!CommentToEmit.empty())
+    CommentToEmit.push_back('\n');
+  T.toVector(CommentToEmit);
+}
+
+void MCAsmStreamer::EmitCommentsAndEOL() {
+  StringRef Comments = CommentToEmit.str();
+  while (!Comments.empty()) {
+    // Emit a line of comments.
+    OS.PadToColumn(MAI.getCommentColumn());
+    size_t Position = Comments.find('\n');
+    OS << MAI.getCommentString() << ' ' << Comments.substr(0, Position) << '\n';
+    
+    if (Position == StringRef::npos) break;
+    Comments = Comments.substr(Position+1);
+  }
+  
+  CommentToEmit.clear();
+}
+
+
 static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
   assert(Bytes && "Invalid size!");
   return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
@@ -219,7 +267,8 @@ void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size,
   }
   
   assert(Directive && "Invalid size for machine code value!");
-  OS << Directive << truncateToSize(Value, Size) << '\n';
+  OS << Directive << truncateToSize(Value, Size);
+  EmitEOL();
 }
 
 void MCAsmStreamer::EmitValue(const MCExpr *Value, unsigned Size,
@@ -235,7 +284,8 @@ void MCAsmStreamer::EmitValue(const MCExpr *Value, unsigned Size,
   }
   
   assert(Directive && "Invalid size for machine code value!");
-  OS << Directive << *truncateToSize(Value, Size) << '\n';
+  OS << Directive << *truncateToSize(Value, Size);
+  EmitEOL();
 }
 
 /// EmitFill - Emit NumBytes bytes worth of the value specified by
@@ -249,7 +299,7 @@ void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
       OS << ZeroDirective << NumBytes;
       if (FillValue != 0)
         OS << ',' << (int)FillValue;
-      OS << '\n';
+      EmitEOL();
       return;
     }
 
@@ -349,7 +399,8 @@ void MCAsmStreamer::Finish() {
   OS.flush();
 }
     
-MCStreamer *llvm::createAsmStreamer(MCContext &Context, raw_ostream &OS,
+MCStreamer *llvm::createAsmStreamer(MCContext &Context,
+                                    formatted_raw_ostream &OS,
                                     const MCAsmInfo &MAI, bool isLittleEndian,
                                     bool isVerboseAsm, MCInstPrinter *IP,
                                     MCCodeEmitter *CE) {