add a new MCAsmStreamer::GetCommentOS method to simplify stuff

that doesn't want to use twines.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@94199 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2010-01-22 19:17:48 +00:00
parent 8a23e0b07b
commit d79d9dce47
6 changed files with 57 additions and 16 deletions

View File

@@ -90,6 +90,11 @@ namespace llvm {
/// prefix as appropriate. The added comment should not end with a \n. /// prefix as appropriate. The added comment should not end with a \n.
virtual void AddComment(const Twine &T) {} virtual void AddComment(const Twine &T) {}
/// GetCommentOS - Return a raw_ostream that comments can be written to.
/// Unlike AddComment, you are required to terminate comments with \n if you
/// use this method.
virtual raw_ostream &GetCommentOS();
/// @name Symbol & Section Management /// @name Symbol & Section Management
/// @{ /// @{

View File

@@ -456,6 +456,9 @@ public:
explicit raw_svector_ostream(SmallVectorImpl<char> &O); explicit raw_svector_ostream(SmallVectorImpl<char> &O);
~raw_svector_ostream(); ~raw_svector_ostream();
/// clear - Flush the stream and clear the underlying vector.
void clear();
/// str - Flushes the stream contents to the target vector and return a /// str - Flushes the stream contents to the target vector and return a
/// StringRef for the vector contents. /// StringRef for the vector contents.
StringRef str(); StringRef str();

View File

@@ -1126,16 +1126,12 @@ static void EmitGlobalConstantStruct(const ConstantStruct *CS,
static void EmitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace, static void EmitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace,
AsmPrinter &AP) { AsmPrinter &AP) {
SmallString<128> TmpBuffer;
// FP Constants are printed as integer constants to avoid losing // FP Constants are printed as integer constants to avoid losing
// precision. // precision.
if (CFP->getType()->isDoubleTy()) { if (CFP->getType()->isDoubleTy()) {
if (AP.VerboseAsm) { if (AP.VerboseAsm) {
raw_svector_ostream OS(TmpBuffer); double Val = CFP->getValueAPF().convertToDouble();
double Val = CFP->getValueAPF().convertToDouble(); // for comment only AP.OutStreamer.GetCommentOS() << "double " << Val << '\n';
OS << "double " << Val;
AP.OutStreamer.AddComment(OS.str());
} }
uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue(); uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue();

View File

@@ -34,20 +34,23 @@ class MCAsmStreamer : public MCStreamer {
MCCodeEmitter *Emitter; MCCodeEmitter *Emitter;
SmallString<128> CommentToEmit; SmallString<128> CommentToEmit;
raw_svector_ostream CommentStream;
public: public:
MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os, MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os,
const MCAsmInfo &mai, const MCAsmInfo &mai,
bool isLittleEndian, bool isVerboseAsm, MCInstPrinter *printer, bool isLittleEndian, bool isVerboseAsm, MCInstPrinter *printer,
MCCodeEmitter *emitter) MCCodeEmitter *emitter)
: MCStreamer(Context), OS(os), MAI(mai), IsLittleEndian(isLittleEndian), : MCStreamer(Context), OS(os), MAI(mai), IsLittleEndian(isLittleEndian),
IsVerboseAsm(isVerboseAsm), InstPrinter(printer), Emitter(emitter) {} IsVerboseAsm(isVerboseAsm), InstPrinter(printer), Emitter(emitter),
CommentStream(CommentToEmit) {}
~MCAsmStreamer() {} ~MCAsmStreamer() {}
bool isLittleEndian() const { return IsLittleEndian; } bool isLittleEndian() const { return IsLittleEndian; }
inline void EmitEOL() { inline void EmitEOL() {
if (CommentToEmit.empty()) { // If we don't have any comments, just emit a \n.
if (!IsVerboseAsm) {
OS << '\n'; OS << '\n';
return; return;
} }
@@ -61,6 +64,15 @@ public:
/// verbose assembly output is enabled. /// verbose assembly output is enabled.
virtual void AddComment(const Twine &T); virtual void AddComment(const Twine &T);
/// GetCommentOS - Return a raw_ostream that comments can be written to.
/// Unlike AddComment, you are required to terminate comments with \n if you
/// use this method.
virtual raw_ostream &GetCommentOS() {
if (!IsVerboseAsm)
return nulls(); // Discard comments unless in verbose asm mode.
return CommentStream;
}
/// @name MCStreamer Interface /// @name MCStreamer Interface
/// @{ /// @{
@@ -112,25 +124,36 @@ public:
/// verbose assembly output is enabled. /// verbose assembly output is enabled.
void MCAsmStreamer::AddComment(const Twine &T) { void MCAsmStreamer::AddComment(const Twine &T) {
if (!IsVerboseAsm) return; if (!IsVerboseAsm) return;
// Each comment goes on its own line.
if (!CommentToEmit.empty()) // Make sure that CommentStream is flushed.
CommentToEmit.push_back('\n'); CommentStream.flush();
T.toVector(CommentToEmit); T.toVector(CommentToEmit);
// Each comment goes on its own line.
CommentToEmit.push_back('\n');
} }
void MCAsmStreamer::EmitCommentsAndEOL() { void MCAsmStreamer::EmitCommentsAndEOL() {
if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
OS << '\n';
return;
}
CommentStream.flush();
StringRef Comments = CommentToEmit.str(); StringRef Comments = CommentToEmit.str();
while (!Comments.empty()) {
assert(Comments.back() == '\n' &&
"Comment array not newline terminated");
do {
// Emit a line of comments. // Emit a line of comments.
OS.PadToColumn(MAI.getCommentColumn()); OS.PadToColumn(MAI.getCommentColumn());
size_t Position = Comments.find('\n'); size_t Position = Comments.find('\n');
OS << MAI.getCommentString() << ' ' << Comments.substr(0, Position) << '\n'; OS << MAI.getCommentString() << ' ' << Comments.substr(0, Position) << '\n';
if (Position == StringRef::npos) break;
Comments = Comments.substr(Position+1); Comments = Comments.substr(Position+1);
} } while (!Comments.empty());
CommentToEmit.clear(); CommentStream.clear();
} }

View File

@@ -9,7 +9,7 @@
#include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCExpr.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm; using namespace llvm;
MCStreamer::MCStreamer(MCContext &_Context) : Context(_Context), CurSection(0) { MCStreamer::MCStreamer(MCContext &_Context) : Context(_Context), CurSection(0) {
@@ -18,6 +18,12 @@ MCStreamer::MCStreamer(MCContext &_Context) : Context(_Context), CurSection(0) {
MCStreamer::~MCStreamer() { MCStreamer::~MCStreamer() {
} }
raw_ostream &MCStreamer::GetCommentOS() {
// By default, discard comments.
return nulls();
}
/// EmitIntValue - Special case of EmitValue that avoids the client having to /// EmitIntValue - Special case of EmitValue that avoids the client having to
/// pass in a MCExpr for constant integers. /// pass in a MCExpr for constant integers.
void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size, void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size,

View File

@@ -562,6 +562,14 @@ raw_svector_ostream::~raw_svector_ostream() {
flush(); flush();
} }
/// clear - Flush the stream and clear the underlying vector.
void raw_svector_ostream::clear() {
if (GetNumBytesInBuffer() == 0) flush();
OS.clear();
SetBuffer(OS.end(), OS.capacity() - OS.size());
}
void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) { void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) {
assert(Ptr == OS.end() && OS.size() + Size <= OS.capacity() && assert(Ptr == OS.end() && OS.size() + Size <= OS.capacity() &&
"Invalid write_impl() call!"); "Invalid write_impl() call!");