raw_ostream.h revision 524dea4d4ca6ecafa18e1e011934a2129c770f4f
148534b31d8bc5a68ba152fcdb905bf266def5268Daniel Dunbar//===--- raw_ostream.h - Raw output stream ----------------------*- C++ -*-===// 260d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner// 360d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner// The LLVM Compiler Infrastructure 460d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner// 560d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner// This file is distributed under the University of Illinois Open Source 660d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner// License. See LICENSE.TXT for details. 760d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner// 860d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner//===----------------------------------------------------------------------===// 960d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner// 1060d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner// This file defines the raw_ostream class. 1160d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner// 1260d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner//===----------------------------------------------------------------------===// 1360d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner 1460d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner#ifndef LLVM_SUPPORT_RAW_OSTREAM_H 1560d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner#define LLVM_SUPPORT_RAW_OSTREAM_H 1660d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner 17cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson#include "llvm/ADT/StringExtras.h" 18dbe77cfa0bcae10d91fbdbf118a97ec212afc88eDaniel Dunbar#include "llvm/ADT/StringRef.h" 19b6c8a4098fd23c21d6cda33b09b99b5a0ac1e13fNick Lewycky#include <cassert> 20b6c8a4098fd23c21d6cda33b09b99b5a0ac1e13fNick Lewycky#include <cstring> 2160d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner#include <string> 2207f51f788e1dff2982ff0aae7c2ea3d00e48cc61Chris Lattner#include <iosfwd> 2360d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner 2460d396262460f0613175e52c00be5e8bfb89d8fbChris Lattnernamespace llvm { 25097af7fc8f8688cc21453a5561347f14ca7c5771Chris Lattner class format_object_base; 2678a2812538d871a62d90f53ed66d26198876d011Chris Lattner template <typename T> 2778a2812538d871a62d90f53ed66d26198876d011Chris Lattner class SmallVectorImpl; 28fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 2960d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner/// raw_ostream - This class implements an extremely fast bulk output stream 3060d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner/// that can *only* output to a stream. It does not support seeking, reopening, 3160d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner/// rewinding, line buffered disciplines etc. It is a simple buffer that outputs 3260d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner/// a chunk at a time. 3360d396262460f0613175e52c00be5e8bfb89d8fbChris Lattnerclass raw_ostream { 3489a66a96fed75796bc5e079217130b62105cb438Daniel Dunbarprivate: 35d17d74bb80d9da1712a066df40122e8584dad227Daniel Dunbar /// The buffer is handled in such a way that the buffer is 36d17d74bb80d9da1712a066df40122e8584dad227Daniel Dunbar /// uninitialized, unbuffered, or out of space when OutBufCur >= 37d17d74bb80d9da1712a066df40122e8584dad227Daniel Dunbar /// OutBufEnd. Thus a single comparison suffices to determine if we 38d17d74bb80d9da1712a066df40122e8584dad227Daniel Dunbar /// need to take the slow path to write a single character. 39d17d74bb80d9da1712a066df40122e8584dad227Daniel Dunbar /// 40d17d74bb80d9da1712a066df40122e8584dad227Daniel Dunbar /// The buffer is in one of three states: 41d17d74bb80d9da1712a066df40122e8584dad227Daniel Dunbar /// 1. Unbuffered (Unbuffered == true) 42d17d74bb80d9da1712a066df40122e8584dad227Daniel Dunbar /// 1. Uninitialized (Unbuffered == false && OutBufStart == 0). 43d17d74bb80d9da1712a066df40122e8584dad227Daniel Dunbar /// 2. Buffered (Unbuffered == false && OutBufStart != 0 && 44d17d74bb80d9da1712a066df40122e8584dad227Daniel Dunbar /// OutBufEnd - OutBufStart >= 64). 4560d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner char *OutBufStart, *OutBufEnd, *OutBufCur; 46e77e434bc96f2935dcf337909c4009324fe24eafDaniel Dunbar bool Unbuffered; 47e77e434bc96f2935dcf337909c4009324fe24eafDaniel Dunbar 48e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman /// Error This flag is true if an error of any kind has been detected. 49e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman /// 50e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman bool Error; 51e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman 5260d396262460f0613175e52c00be5e8bfb89d8fbChris Lattnerpublic: 53e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin // color order matches ANSI escape sequence, don't change 54e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin enum Colors { 55e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin BLACK=0, 56e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin RED, 57e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin GREEN, 58e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin YELLOW, 59e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin BLUE, 60e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin MAGENTA, 61e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin CYAN, 62e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin WHITE, 63e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin SAVEDCOLOR 64e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin }; 65e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin 66e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman explicit raw_ostream(bool unbuffered=false) 67e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman : Unbuffered(unbuffered), Error(false) { 6860d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner // Start out ready to flush. 6960d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner OutBufStart = OutBufEnd = OutBufCur = 0; 7060d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner } 715b8dbf839ba8f586e2823744dc695acf57480c5fNuno Lopes 72e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman virtual ~raw_ostream(); 73fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 748f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor /// tell - Return the current offset with the file. 758f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor uint64_t tell() { return current_pos() + GetNumBytesInBuffer(); } 768f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor 77e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman /// has_error - Return the value of the flag in this raw_ostream indicating 78e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman /// whether an output error has been encountered. 79e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman bool has_error() const { 80e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman return Error; 81996b9d6aa9864c24178891adf29eeafd3f34d90cDan Gohman } 82e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman 83e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman /// clear_error - Set the flag read by has_error() to false. If the error 84e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman /// flag is set at the time when this raw_ostream's destructor is called, 85e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman /// llvm_report_error is called to report the error. Use clear_error() 86e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman /// after handling the error to avoid this behavior. 87e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman void clear_error() { 88e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman Error = false; 89996b9d6aa9864c24178891adf29eeafd3f34d90cDan Gohman } 90e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman 9160d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner //===--------------------------------------------------------------------===// 9260d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner // Configuration Interface 9360d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner //===--------------------------------------------------------------------===// 94fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 9560d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner /// SetBufferSize - Set the internal buffer size to the specified amount 9660d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner /// instead of the default. 97524dea4d4ca6ecafa18e1e011934a2129c770f4fDan Gohman void SetBufferSize(size_t Size=4096); 98fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 99f3e488476e1bdfe9de6daddcd1cd452c9d874b56Dan Gohman size_t GetBufferSize() const { 100f3e488476e1bdfe9de6daddcd1cd452c9d874b56Dan Gohman return OutBufEnd - OutBufStart; 101f3e488476e1bdfe9de6daddcd1cd452c9d874b56Dan Gohman } 102f3e488476e1bdfe9de6daddcd1cd452c9d874b56Dan Gohman 103e77e434bc96f2935dcf337909c4009324fe24eafDaniel Dunbar /// SetUnbuffered - Set the streams buffering status. When 104e77e434bc96f2935dcf337909c4009324fe24eafDaniel Dunbar /// unbuffered the stream will flush after every write. This routine 105e77e434bc96f2935dcf337909c4009324fe24eafDaniel Dunbar /// will also flush the buffer immediately when the stream is being 106e77e434bc96f2935dcf337909c4009324fe24eafDaniel Dunbar /// set to unbuffered. 107524dea4d4ca6ecafa18e1e011934a2129c770f4fDan Gohman void SetUnbuffered(); 108e77e434bc96f2935dcf337909c4009324fe24eafDaniel Dunbar 109ad60f660c6fd1999a3e21823128d37aca62e9285Dan Gohman size_t GetNumBytesInBuffer() const { 11089a66a96fed75796bc5e079217130b62105cb438Daniel Dunbar return OutBufCur - OutBufStart; 11189a66a96fed75796bc5e079217130b62105cb438Daniel Dunbar } 11289a66a96fed75796bc5e079217130b62105cb438Daniel Dunbar 11360d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner //===--------------------------------------------------------------------===// 11460d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner // Data Output Interface 11560d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner //===--------------------------------------------------------------------===// 116fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 11760d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner void flush() { 11860d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner if (OutBufCur != OutBufStart) 119cf2a2c6a26427733f31dd539c6ee6486ea191da2Daniel Dunbar flush_nonempty(); 12060d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner } 121fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 122f46dc79ac502f6ed06dea3ba558bcfcc49061114Nicolas Geoffray raw_ostream &operator<<(char C) { 123f46dc79ac502f6ed06dea3ba558bcfcc49061114Nicolas Geoffray if (OutBufCur >= OutBufEnd) 124de75d7ffcd5ed315240cfe0c52a821cf66411edaDaniel Dunbar return write(C); 125f46dc79ac502f6ed06dea3ba558bcfcc49061114Nicolas Geoffray *OutBufCur++ = C; 126f46dc79ac502f6ed06dea3ba558bcfcc49061114Nicolas Geoffray return *this; 127f46dc79ac502f6ed06dea3ba558bcfcc49061114Nicolas Geoffray } 128fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 1291f83b02c62380f5ac5502eccc45d7b6203a7ea93Owen Anderson raw_ostream &operator<<(unsigned char C) { 1301f83b02c62380f5ac5502eccc45d7b6203a7ea93Owen Anderson if (OutBufCur >= OutBufEnd) 131de75d7ffcd5ed315240cfe0c52a821cf66411edaDaniel Dunbar return write(C); 1321f83b02c62380f5ac5502eccc45d7b6203a7ea93Owen Anderson *OutBufCur++ = C; 1331f83b02c62380f5ac5502eccc45d7b6203a7ea93Owen Anderson return *this; 1341f83b02c62380f5ac5502eccc45d7b6203a7ea93Owen Anderson } 135fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 1361f83b02c62380f5ac5502eccc45d7b6203a7ea93Owen Anderson raw_ostream &operator<<(signed char C) { 13760d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner if (OutBufCur >= OutBufEnd) 138de75d7ffcd5ed315240cfe0c52a821cf66411edaDaniel Dunbar return write(C); 13960d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner *OutBufCur++ = C; 14060d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner return *this; 14160d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner } 142fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 143dbe77cfa0bcae10d91fbdbf118a97ec212afc88eDaniel Dunbar raw_ostream &operator<<(const StringRef &Str) { 144dbe77cfa0bcae10d91fbdbf118a97ec212afc88eDaniel Dunbar // Inline fast path, particularly for strings with a known length. 145dbe77cfa0bcae10d91fbdbf118a97ec212afc88eDaniel Dunbar size_t Size = Str.size(); 14638f4dd7b5e333aee8f89cee85d1c79378fee0ffcDaniel Dunbar 14738f4dd7b5e333aee8f89cee85d1c79378fee0ffcDaniel Dunbar // Make sure we can use the fast path. 14838f4dd7b5e333aee8f89cee85d1c79378fee0ffcDaniel Dunbar if (OutBufCur+Size > OutBufEnd) 149dbe77cfa0bcae10d91fbdbf118a97ec212afc88eDaniel Dunbar return write(Str.data(), Size); 15038f4dd7b5e333aee8f89cee85d1c79378fee0ffcDaniel Dunbar 151dbe77cfa0bcae10d91fbdbf118a97ec212afc88eDaniel Dunbar memcpy(OutBufCur, Str.data(), Size); 15238f4dd7b5e333aee8f89cee85d1c79378fee0ffcDaniel Dunbar OutBufCur += Size; 153c39b80fdfc606f5df118288f4fc6b5e9c0b5ee41Daniel Dunbar return *this; 15460d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner } 155fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 156dbe77cfa0bcae10d91fbdbf118a97ec212afc88eDaniel Dunbar raw_ostream &operator<<(const char *Str) { 157dbe77cfa0bcae10d91fbdbf118a97ec212afc88eDaniel Dunbar // Inline fast path, particulary for constant strings where a sufficiently 158dbe77cfa0bcae10d91fbdbf118a97ec212afc88eDaniel Dunbar // smart compiler will simplify strlen. 159dbe77cfa0bcae10d91fbdbf118a97ec212afc88eDaniel Dunbar 160dbe77cfa0bcae10d91fbdbf118a97ec212afc88eDaniel Dunbar this->operator<<(StringRef(Str)); 161dbe77cfa0bcae10d91fbdbf118a97ec212afc88eDaniel Dunbar return *this; 162dbe77cfa0bcae10d91fbdbf118a97ec212afc88eDaniel Dunbar } 163dbe77cfa0bcae10d91fbdbf118a97ec212afc88eDaniel Dunbar 164cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson raw_ostream &operator<<(const std::string& Str) { 165c39b80fdfc606f5df118288f4fc6b5e9c0b5ee41Daniel Dunbar write(Str.data(), Str.length()); 166c39b80fdfc606f5df118288f4fc6b5e9c0b5ee41Daniel Dunbar return *this; 167cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson } 168fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 16966b17ba0d263442b8b4e82aaa08acc0df85e1787Owen Anderson raw_ostream &operator<<(unsigned long N); 17066b17ba0d263442b8b4e82aaa08acc0df85e1787Owen Anderson raw_ostream &operator<<(long N); 17166b17ba0d263442b8b4e82aaa08acc0df85e1787Owen Anderson raw_ostream &operator<<(unsigned long long N); 17266b17ba0d263442b8b4e82aaa08acc0df85e1787Owen Anderson raw_ostream &operator<<(long long N); 173944fac71e082cc2664cc71b4d3f6c72bab7143fbChris Lattner raw_ostream &operator<<(const void *P); 17489a1a85913fb559c7e0266570738fd9cdf616fa3Owen Anderson raw_ostream &operator<<(unsigned int N) { 175c39b80fdfc606f5df118288f4fc6b5e9c0b5ee41Daniel Dunbar this->operator<<(static_cast<unsigned long>(N)); 176c39b80fdfc606f5df118288f4fc6b5e9c0b5ee41Daniel Dunbar return *this; 177cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson } 178fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 17989a1a85913fb559c7e0266570738fd9cdf616fa3Owen Anderson raw_ostream &operator<<(int N) { 180c39b80fdfc606f5df118288f4fc6b5e9c0b5ee41Daniel Dunbar this->operator<<(static_cast<long>(N)); 181c39b80fdfc606f5df118288f4fc6b5e9c0b5ee41Daniel Dunbar return *this; 182cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson } 183afc802dc7d963a2cb46f1b0c1f1b0faa5e1dca2aEli Friedman 184cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson raw_ostream &operator<<(double N) { 185c39b80fdfc606f5df118288f4fc6b5e9c0b5ee41Daniel Dunbar this->operator<<(ftostr(N)); 186c39b80fdfc606f5df118288f4fc6b5e9c0b5ee41Daniel Dunbar return *this; 187cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson } 188fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 18948018e08f0d47331e72e5dcfcde2173217091b0eDaniel Dunbar /// write_hex - Output \arg N in hexadecimal, without any prefix or padding. 19048018e08f0d47331e72e5dcfcde2173217091b0eDaniel Dunbar raw_ostream &write_hex(unsigned long long N); 19148018e08f0d47331e72e5dcfcde2173217091b0eDaniel Dunbar 192de75d7ffcd5ed315240cfe0c52a821cf66411edaDaniel Dunbar raw_ostream &write(unsigned char C); 193ad60f660c6fd1999a3e21823128d37aca62e9285Dan Gohman raw_ostream &write(const char *Ptr, size_t Size); 194fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 195b2560526d5f6d2f9cc3698244dbb1f4861dc8efcChris Lattner // Formatted output, see the format() function in Support/Format.h. 196097af7fc8f8688cc21453a5561347f14ca7c5771Chris Lattner raw_ostream &operator<<(const format_object_base &Fmt); 197fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 198e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin /// Changes the foreground color of text that will be output from this point 199e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin /// forward. 200e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin /// @param colors ANSI color to use, the special SAVEDCOLOR can be used to 201e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin /// change only the bold attribute, and keep colors untouched 202e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin /// @param bold bold/brighter text, default false 203e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin /// @param bg if true change the background, default: change foreground 204e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin /// @returns itself so it can be used within << invocations 205e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin virtual raw_ostream &changeColor(enum Colors colors, bool bold=false, 206e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin bool bg=false) { return *this; } 207e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin 208e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin /// Resets the colors to terminal defaults. Call this when you are done 209e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin /// outputting colored text, or before program exit. 210e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin virtual raw_ostream &resetColor() { return *this; } 211e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin 21260d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner //===--------------------------------------------------------------------===// 21360d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner // Subclass Interface 21460d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner //===--------------------------------------------------------------------===// 21560d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner 216cf2a2c6a26427733f31dd539c6ee6486ea191da2Daniel Dunbarprivate: 21789a66a96fed75796bc5e079217130b62105cb438Daniel Dunbar /// write_impl - The is the piece of the class that is implemented 21889a66a96fed75796bc5e079217130b62105cb438Daniel Dunbar /// by subclasses. This writes the \args Size bytes starting at 21989a66a96fed75796bc5e079217130b62105cb438Daniel Dunbar /// \arg Ptr to the underlying stream. 22089a66a96fed75796bc5e079217130b62105cb438Daniel Dunbar /// 22189a66a96fed75796bc5e079217130b62105cb438Daniel Dunbar /// \invariant { Size > 0 } 222ad60f660c6fd1999a3e21823128d37aca62e9285Dan Gohman virtual void write_impl(const char *Ptr, size_t Size) = 0; 223fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 22460d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner // An out of line virtual method to provide a home for the class vtable. 22560d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner virtual void handle(); 226cf2a2c6a26427733f31dd539c6ee6486ea191da2Daniel Dunbar 2278f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor /// current_pos - Return the current position within the stream, not 2288f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor /// counting the bytes currently in the buffer. 2298f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor virtual uint64_t current_pos() = 0; 2308f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor 231e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohmanprotected: 232e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman /// error_detected - Set the flag indicating that an output error has 233e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman /// been encountered. 234e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman void error_detected() { Error = true; } 235e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman 236fd29440c07f195d7c059efeb50fe0c5905d88b3bDavid Greene typedef char * iterator; 237a9ad04191cb56c42944b17980b8b2bb2afe11ab2Dan Gohman iterator begin() { return OutBufStart; } 238a9ad04191cb56c42944b17980b8b2bb2afe11ab2Dan Gohman iterator end() { return OutBufCur; } 239fd29440c07f195d7c059efeb50fe0c5905d88b3bDavid Greene 240cf2a2c6a26427733f31dd539c6ee6486ea191da2Daniel Dunbar //===--------------------------------------------------------------------===// 241cf2a2c6a26427733f31dd539c6ee6486ea191da2Daniel Dunbar // Private Interface 242cf2a2c6a26427733f31dd539c6ee6486ea191da2Daniel Dunbar //===--------------------------------------------------------------------===// 243cf2a2c6a26427733f31dd539c6ee6486ea191da2Daniel Dunbarprivate: 244cf2a2c6a26427733f31dd539c6ee6486ea191da2Daniel Dunbar /// flush_nonempty - Flush the current buffer, which is known to be 245cf2a2c6a26427733f31dd539c6ee6486ea191da2Daniel Dunbar /// non-empty. This outputs the currently buffered data and resets 246cf2a2c6a26427733f31dd539c6ee6486ea191da2Daniel Dunbar /// the buffer to empty. 247cf2a2c6a26427733f31dd539c6ee6486ea191da2Daniel Dunbar void flush_nonempty(); 24833e49ef5e5dc2d3e65bcd4fc1f20874bf3847829Dan Gohman 24933e49ef5e5dc2d3e65bcd4fc1f20874bf3847829Dan Gohman /// copy_to_buffer - Copy data into the buffer. Size must not be 25033e49ef5e5dc2d3e65bcd4fc1f20874bf3847829Dan Gohman /// greater than the number of unused bytes in the buffer. 25133e49ef5e5dc2d3e65bcd4fc1f20874bf3847829Dan Gohman void copy_to_buffer(const char *Ptr, size_t Size); 25260d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner}; 253fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 254097af7fc8f8688cc21453a5561347f14ca7c5771Chris Lattner//===----------------------------------------------------------------------===// 255097af7fc8f8688cc21453a5561347f14ca7c5771Chris Lattner// File Output Streams 256097af7fc8f8688cc21453a5561347f14ca7c5771Chris Lattner//===----------------------------------------------------------------------===// 257fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 25860d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner/// raw_fd_ostream - A raw_ostream that writes to a file descriptor. 25960d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner/// 26060d396262460f0613175e52c00be5e8bfb89d8fbChris Lattnerclass raw_fd_ostream : public raw_ostream { 26160d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner int FD; 26260d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner bool ShouldClose; 263d75ba1c3573d3d5146d0abe8cb376dca94be94d5Ted Kremenek uint64_t pos; 26489a66a96fed75796bc5e079217130b62105cb438Daniel Dunbar 26589a66a96fed75796bc5e079217130b62105cb438Daniel Dunbar /// write_impl - See raw_ostream::write_impl. 266ad60f660c6fd1999a3e21823128d37aca62e9285Dan Gohman virtual void write_impl(const char *Ptr, size_t Size); 2678f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor 2688f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor /// current_pos - Return the current position within the stream, not 2698f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor /// counting the bytes currently in the buffer. 2708f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor virtual uint64_t current_pos() { return pos; } 2718f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor 27260d396262460f0613175e52c00be5e8bfb89d8fbChris Lattnerpublic: 27348534b31d8bc5a68ba152fcdb905bf266def5268Daniel Dunbar /// raw_fd_ostream - Open the specified file for writing. If an 27448534b31d8bc5a68ba152fcdb905bf266def5268Daniel Dunbar /// error occurs, information about the error is put into ErrorInfo, 27548534b31d8bc5a68ba152fcdb905bf266def5268Daniel Dunbar /// and the stream should be immediately destroyed; the string will 27648534b31d8bc5a68ba152fcdb905bf266def5268Daniel Dunbar /// be empty if no error occurred. 2770d9eb9b4917340acbfc831890655b8e9724959f6Daniel Dunbar /// 2780d9eb9b4917340acbfc831890655b8e9724959f6Daniel Dunbar /// \param Filename - The file to open. If this is "-" then the 2790d9eb9b4917340acbfc831890655b8e9724959f6Daniel Dunbar /// stream will use stdout instead. 2800d9eb9b4917340acbfc831890655b8e9724959f6Daniel Dunbar /// \param Binary - The file should be opened in binary mode on 2810d9eb9b4917340acbfc831890655b8e9724959f6Daniel Dunbar /// platforms that support this distinction. 282a1bdcedc3879510a874d24c450e07feb170d9cd6Dan Gohman /// \param Force - Don't consider the case where the file already 283a1bdcedc3879510a874d24c450e07feb170d9cd6Dan Gohman /// exists to be an error. 284a1bdcedc3879510a874d24c450e07feb170d9cd6Dan Gohman raw_fd_ostream(const char *Filename, bool Binary, bool Force, 285a1bdcedc3879510a874d24c450e07feb170d9cd6Dan Gohman std::string &ErrorInfo); 286fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 28760d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner /// raw_fd_ostream ctor - FD is the file descriptor that this writes to. If 288e77e434bc96f2935dcf337909c4009324fe24eafDaniel Dunbar /// ShouldClose is true, this closes the file when the stream is destroyed. 289e77e434bc96f2935dcf337909c4009324fe24eafDaniel Dunbar raw_fd_ostream(int fd, bool shouldClose, 290e77e434bc96f2935dcf337909c4009324fe24eafDaniel Dunbar bool unbuffered=false) : raw_ostream(unbuffered), FD(fd), 291e77e434bc96f2935dcf337909c4009324fe24eafDaniel Dunbar ShouldClose(shouldClose) {} 292e77e434bc96f2935dcf337909c4009324fe24eafDaniel Dunbar 29360d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner ~raw_fd_ostream(); 294fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 29543d1f02b547b146d81abeb0ed0f88628f0fdc7dcTed Kremenek /// close - Manually flush the stream and close the file. 2965984680c1fe7ad98381154c26f9c009e4c91b08cTed Kremenek void close(); 297fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 2985984680c1fe7ad98381154c26f9c009e4c91b08cTed Kremenek /// tell - Return the current offset with the file. 29989a66a96fed75796bc5e079217130b62105cb438Daniel Dunbar uint64_t tell() { return pos + GetNumBytesInBuffer(); } 300fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 3019c27886dd5d504f2b03c6fcb57aba23e5e44c4faTed Kremenek /// seek - Flushes the stream and repositions the underlying file descriptor 3029c27886dd5d504f2b03c6fcb57aba23e5e44c4faTed Kremenek /// positition to the offset specified from the beginning of the file. 3039c27886dd5d504f2b03c6fcb57aba23e5e44c4faTed Kremenek uint64_t seek(uint64_t off); 304e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin 305e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin virtual raw_ostream &changeColor(enum Colors colors, bool bold=false, 306e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin bool bg=false); 307e8ebb0fe1bba0fdff7475d98e1f8a04804b0b056Torok Edwin virtual raw_ostream &resetColor(); 30860d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner}; 309fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 31007f51f788e1dff2982ff0aae7c2ea3d00e48cc61Chris Lattner/// raw_stdout_ostream - This is a stream that always prints to stdout. 31107f51f788e1dff2982ff0aae7c2ea3d00e48cc61Chris Lattner/// 31260d396262460f0613175e52c00be5e8bfb89d8fbChris Lattnerclass raw_stdout_ostream : public raw_fd_ostream { 31360d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner // An out of line virtual method to provide a home for the class vtable. 31460d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner virtual void handle(); 31560d396262460f0613175e52c00be5e8bfb89d8fbChris Lattnerpublic: 31660d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner raw_stdout_ostream(); 31760d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner}; 31860d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner 31907f51f788e1dff2982ff0aae7c2ea3d00e48cc61Chris Lattner/// raw_stderr_ostream - This is a stream that always prints to stderr. 32007f51f788e1dff2982ff0aae7c2ea3d00e48cc61Chris Lattner/// 32160d396262460f0613175e52c00be5e8bfb89d8fbChris Lattnerclass raw_stderr_ostream : public raw_fd_ostream { 32260d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner // An out of line virtual method to provide a home for the class vtable. 32360d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner virtual void handle(); 32460d396262460f0613175e52c00be5e8bfb89d8fbChris Lattnerpublic: 32560d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner raw_stderr_ostream(); 32660d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner}; 327fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 32807f51f788e1dff2982ff0aae7c2ea3d00e48cc61Chris Lattner/// outs() - This returns a reference to a raw_ostream for standard output. 32907f51f788e1dff2982ff0aae7c2ea3d00e48cc61Chris Lattner/// Use it like: outs() << "foo" << "bar"; 33007f51f788e1dff2982ff0aae7c2ea3d00e48cc61Chris Lattnerraw_ostream &outs(); 33107f51f788e1dff2982ff0aae7c2ea3d00e48cc61Chris Lattner 33207f51f788e1dff2982ff0aae7c2ea3d00e48cc61Chris Lattner/// errs() - This returns a reference to a raw_ostream for standard error. 33307f51f788e1dff2982ff0aae7c2ea3d00e48cc61Chris Lattner/// Use it like: errs() << "foo" << "bar"; 33407f51f788e1dff2982ff0aae7c2ea3d00e48cc61Chris Lattnerraw_ostream &errs(); 335fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 33634ccf037fea3d83dcb18f72496775ec4c7dcd3d3Daniel Dunbar/// nulls() - This returns a reference to a raw_ostream which simply discards 33734ccf037fea3d83dcb18f72496775ec4c7dcd3d3Daniel Dunbar/// output. 33834ccf037fea3d83dcb18f72496775ec4c7dcd3d3Daniel Dunbarraw_ostream &nulls(); 339fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 340097af7fc8f8688cc21453a5561347f14ca7c5771Chris Lattner//===----------------------------------------------------------------------===// 34178a2812538d871a62d90f53ed66d26198876d011Chris Lattner// Output Stream Adaptors 342097af7fc8f8688cc21453a5561347f14ca7c5771Chris Lattner//===----------------------------------------------------------------------===// 343fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 34407f51f788e1dff2982ff0aae7c2ea3d00e48cc61Chris Lattner/// raw_os_ostream - A raw_ostream that writes to an std::ostream. This is a 345e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman/// simple adaptor class. It does not check for output errors; clients should 346e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman/// use the underlying stream to detect errors. 34707f51f788e1dff2982ff0aae7c2ea3d00e48cc61Chris Lattnerclass raw_os_ostream : public raw_ostream { 34807f51f788e1dff2982ff0aae7c2ea3d00e48cc61Chris Lattner std::ostream &OS; 34989a66a96fed75796bc5e079217130b62105cb438Daniel Dunbar 35089a66a96fed75796bc5e079217130b62105cb438Daniel Dunbar /// write_impl - See raw_ostream::write_impl. 351ad60f660c6fd1999a3e21823128d37aca62e9285Dan Gohman virtual void write_impl(const char *Ptr, size_t Size); 3528f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor 3538f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor /// current_pos - Return the current position within the stream, not 3548f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor /// counting the bytes currently in the buffer. 3558f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor virtual uint64_t current_pos(); 3568f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor 35707f51f788e1dff2982ff0aae7c2ea3d00e48cc61Chris Lattnerpublic: 35807f51f788e1dff2982ff0aae7c2ea3d00e48cc61Chris Lattner raw_os_ostream(std::ostream &O) : OS(O) {} 359944fac71e082cc2664cc71b4d3f6c72bab7143fbChris Lattner ~raw_os_ostream(); 3608f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor 3618f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor /// tell - Return the current offset with the stream. 3628f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor uint64_t tell(); 36307f51f788e1dff2982ff0aae7c2ea3d00e48cc61Chris Lattner}; 36478a2812538d871a62d90f53ed66d26198876d011Chris Lattner 36578a2812538d871a62d90f53ed66d26198876d011Chris Lattner/// raw_string_ostream - A raw_ostream that writes to an std::string. This is a 366e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman/// simple adaptor class. This class does not encounter output errors. 36778a2812538d871a62d90f53ed66d26198876d011Chris Lattnerclass raw_string_ostream : public raw_ostream { 36878a2812538d871a62d90f53ed66d26198876d011Chris Lattner std::string &OS; 36989a66a96fed75796bc5e079217130b62105cb438Daniel Dunbar 37089a66a96fed75796bc5e079217130b62105cb438Daniel Dunbar /// write_impl - See raw_ostream::write_impl. 371ad60f660c6fd1999a3e21823128d37aca62e9285Dan Gohman virtual void write_impl(const char *Ptr, size_t Size); 3728f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor 3738f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor /// current_pos - Return the current position within the stream, not 3748f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor /// counting the bytes currently in the buffer. 3758f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor virtual uint64_t current_pos() { return OS.size(); } 37678a2812538d871a62d90f53ed66d26198876d011Chris Lattnerpublic: 3772a993f2cc44dc1113d67df03562866eb65337ff1Dan Gohman explicit raw_string_ostream(std::string &O) : OS(O) {} 37878a2812538d871a62d90f53ed66d26198876d011Chris Lattner ~raw_string_ostream(); 379fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 3808f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor /// tell - Return the current offset with the stream. 3818f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor uint64_t tell() { return OS.size() + GetNumBytesInBuffer(); } 3828f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor 3833d4866e68338c5c5d7b9a3130a3db5b12658776cTed Kremenek /// str - Flushes the stream contents to the target string and returns 3844ac67ef47ada2160d2a6f2340743b624c6e16424Ted Kremenek /// the string's reference. 3853d4866e68338c5c5d7b9a3130a3db5b12658776cTed Kremenek std::string& str() { 3863d4866e68338c5c5d7b9a3130a3db5b12658776cTed Kremenek flush(); 3873d4866e68338c5c5d7b9a3130a3db5b12658776cTed Kremenek return OS; 3883d4866e68338c5c5d7b9a3130a3db5b12658776cTed Kremenek } 38978a2812538d871a62d90f53ed66d26198876d011Chris Lattner}; 390fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 39178a2812538d871a62d90f53ed66d26198876d011Chris Lattner/// raw_svector_ostream - A raw_ostream that writes to an SmallVector or 392e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman/// SmallString. This is a simple adaptor class. This class does not 393e87b2abe91fc44bb9875188d80e3a43a9dfc41ebDan Gohman/// encounter output errors. 39478a2812538d871a62d90f53ed66d26198876d011Chris Lattnerclass raw_svector_ostream : public raw_ostream { 39578a2812538d871a62d90f53ed66d26198876d011Chris Lattner SmallVectorImpl<char> &OS; 39689a66a96fed75796bc5e079217130b62105cb438Daniel Dunbar 39789a66a96fed75796bc5e079217130b62105cb438Daniel Dunbar /// write_impl - See raw_ostream::write_impl. 398ad60f660c6fd1999a3e21823128d37aca62e9285Dan Gohman virtual void write_impl(const char *Ptr, size_t Size); 3998f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor 4008f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor /// current_pos - Return the current position within the stream, not 4018f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor /// counting the bytes currently in the buffer. 4028f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor virtual uint64_t current_pos(); 40378a2812538d871a62d90f53ed66d26198876d011Chris Lattnerpublic: 4042a993f2cc44dc1113d67df03562866eb65337ff1Dan Gohman explicit raw_svector_ostream(SmallVectorImpl<char> &O) : OS(O) {} 40578a2812538d871a62d90f53ed66d26198876d011Chris Lattner ~raw_svector_ostream(); 4068f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor 4078f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor /// tell - Return the current offset with the stream. 4088f7be4731e979255c54eb8951b7a06ed4fd6ce45Douglas Gregor uint64_t tell(); 40978a2812538d871a62d90f53ed66d26198876d011Chris Lattner}; 410fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 41134ccf037fea3d83dcb18f72496775ec4c7dcd3d3Daniel Dunbar/// raw_null_ostream - A raw_ostream that discards all output. 41234ccf037fea3d83dcb18f72496775ec4c7dcd3d3Daniel Dunbarclass raw_null_ostream : public raw_ostream { 41334ccf037fea3d83dcb18f72496775ec4c7dcd3d3Daniel Dunbar /// write_impl - See raw_ostream::write_impl. 41434ccf037fea3d83dcb18f72496775ec4c7dcd3d3Daniel Dunbar virtual void write_impl(const char *Ptr, size_t size); 41534ccf037fea3d83dcb18f72496775ec4c7dcd3d3Daniel Dunbar 41634ccf037fea3d83dcb18f72496775ec4c7dcd3d3Daniel Dunbar /// current_pos - Return the current position within the stream, not 41734ccf037fea3d83dcb18f72496775ec4c7dcd3d3Daniel Dunbar /// counting the bytes currently in the buffer. 41834ccf037fea3d83dcb18f72496775ec4c7dcd3d3Daniel Dunbar virtual uint64_t current_pos(); 41934ccf037fea3d83dcb18f72496775ec4c7dcd3d3Daniel Dunbar 42034ccf037fea3d83dcb18f72496775ec4c7dcd3d3Daniel Dunbarpublic: 42134ccf037fea3d83dcb18f72496775ec4c7dcd3d3Daniel Dunbar explicit raw_null_ostream() {} 422f78c835faa97a6f5c8021923c05f7514a550619fDan Gohman ~raw_null_ostream(); 42334ccf037fea3d83dcb18f72496775ec4c7dcd3d3Daniel Dunbar}; 42434ccf037fea3d83dcb18f72496775ec4c7dcd3d3Daniel Dunbar 42560d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner} // end llvm namespace 42660d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner 42760d396262460f0613175e52c00be5e8bfb89d8fbChris Lattner#endif 428