From 7ee78e9d5c84f7ceb84177ce35d50ef2639b6b8b Mon Sep 17 00:00:00 2001 From: David Greene Date: Thu, 9 Jul 2009 23:56:35 +0000 Subject: [PATCH] Redesign this to avoid standard stream classes. This stream class provides pretty -printing of comments and other such things in asm files. llvm-svn: 75202 --- include/llvm/CodeGen/AsmStream.h | 179 +++++++++++++++++++++++++++++++ lib/CodeGen/AsmStream.cpp | 21 ++++ 2 files changed, 200 insertions(+) create mode 100644 include/llvm/CodeGen/AsmStream.h create mode 100644 lib/CodeGen/AsmStream.cpp diff --git a/include/llvm/CodeGen/AsmStream.h b/include/llvm/CodeGen/AsmStream.h new file mode 100644 index 00000000000..939a3e078ff --- /dev/null +++ b/include/llvm/CodeGen/AsmStream.h @@ -0,0 +1,179 @@ +//===-- llvm/CodeGen/AsmStream.h - AsmStream Framework --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains raw_ostream implementations for ASM printers to +// do things like pretty-print comments. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_ASMSTREAM_H +#define LLVM_CODEGEN_ASMSTREAM_H + +#include "llvm/Target/TargetAsmInfo.h" +#include + +namespace llvm +{ + /// raw_asm_fd_ostream - Formatted raw_fd_ostream to handle + /// asm-specific constructs + /// + class raw_asm_fd_ostream : public raw_fd_ostream { + private: + bool formatted; + int column; + + protected: + void ComputeColumn(void) { + if (formatted) { + // Keep track of the current column by scanning the string for + // special characters + + // Find the last newline. This is our column start. If there + // is no newline, start with the current column. + char *nlpos = NULL; + for (char *pos = CurBufPtr(), *epos = StartBufPtr(); pos > epos; --pos) { + if (*(pos-1) == '\n') { + nlpos = pos-1; + // The newline will be counted, setting this to zero. We + // need to do it this way in case nlpos is CurBufPtr(). + column = -1; + break; + } + } + + if (nlpos == NULL) { + nlpos = StartBufPtr(); + } + + // Walk through looking for tabs and advance column as appropriate + for (char *pos = nlpos, *epos = CurBufPtr(); pos != epos; ++pos) { + ++column; + if (*pos == '\t') { + // Advance to next tab stop (every eight characters) + column += ((8 - (column & 0x7)) & 0x7); + assert(!(column & 0x3) && "Column out of alignment"); + } + } + } + } + + virtual void AboutToFlush(void) { + ComputeColumn(); + } + + public: + /// raw_asm_fd_ostream - Open the specified file for writing. If + /// an error occurs, information about the error is put into + /// ErrorInfo, and the stream should be immediately destroyed; the + /// string will be empty if no error occurred. + /// + /// \param Filename - The file to open. If this is "-" then the + /// stream will use stdout instead. + /// \param Binary - The file should be opened in binary mode on + /// platforms that support this distinction. + raw_asm_fd_ostream(const char *Filename, bool Binary, std::string &ErrorInfo) + : raw_fd_ostream(Filename, Binary, ErrorInfo), + formatted(!Binary), column(0) {} + + /// raw_asm_fd_ostream ctor - FD is the file descriptor that this + /// writes to. If ShouldClose is true, this closes the file when + /// the stream is destroyed. + raw_asm_fd_ostream(int fd, bool shouldClose, + bool unbuffered=false) + : raw_fd_ostream(fd, shouldClose, unbuffered), + formatted(true), column(0) { + if (unbuffered) { + assert(0 && "asm stream must be buffered"); + // Force buffering + SetBufferSize(); + } + } + + + /// SetColumn - Align the output to some column number + /// + void setColumn(int newcol, int minpad = 0) { + if (formatted) { + flush(); + + // Output spaces until we reach the desired column + int num = newcol - column; + if (num <= 0) { + num = minpad; + } + + // TODO: Write a whole string at a time + while (num-- > 0) { + write(' '); + } + } + }; + }; + + /// Column - An I/O manipulator to advance the output to a certain column + /// + class Column { + private: + int column; + + public: + explicit Column(int c) + : column(c) {} + + raw_asm_fd_ostream &operator()(raw_asm_fd_ostream &out) const { + // Make at least one space before the comment + out.setColumn(column, 1); + return(out); + } + }; + + inline raw_asm_fd_ostream &operator<<(raw_asm_fd_ostream &out, const Column &column) + { + return(column(out)); + } + + /// Comment - An I/O manipulator to output an end-of-line comment + /// + class Comment + : public Column { + private: + static const int CommentColumn = 60; + std::string text; + const TargetAsmInfo &TAI; + + public: + Comment(const std::string &comment, + const TargetAsmInfo &tai) + : Column(CommentColumn), text(comment), TAI(tai) {} + + raw_asm_fd_ostream &operator()(raw_asm_fd_ostream &out) const { + Column::operator()(out); + out << TAI.getCommentString() << " " << text; + return(out); + } + }; + + inline raw_asm_fd_ostream &operator<<(raw_asm_fd_ostream &out, + const Comment &comment) + { + return(comment(out)); + } + + /// Asm stream equivalent for std streams + /// + + /// WARNING: Do NOT use these streams in the constructors of global + /// objects. There is no mechanism to ensure they are initialized + /// before other global objects. + /// + extern raw_asm_fd_ostream asmouts; + extern raw_asm_fd_ostream asmerrs; +} + +#endif diff --git a/lib/CodeGen/AsmStream.cpp b/lib/CodeGen/AsmStream.cpp new file mode 100644 index 00000000000..4e9c56140d0 --- /dev/null +++ b/lib/CodeGen/AsmStream.cpp @@ -0,0 +1,21 @@ +//===-- llvm/CodeGen/AsmStream.cpp - AsmStream Framework --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains instantiations of "standard" AsmOStreams. +// +//===----------------------------------------------------------------------===// + +#include "llvm/CodeGen/AsmStream.h" + +#include + +namespace llvm { + raw_asm_fd_ostream asmouts(STDOUT_FILENO, false); + raw_asm_fd_ostream asmerrs(STDERR_FILENO, false); +}