Replace UniqueSectionForGlobal with getSectionPrefixForUniqueGlobal.
[oota-llvm.git] / lib / Support / raw_ostream.cpp
1 //===--- raw_ostream.cpp - Implement the raw_ostream classes --------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This implements support for bulk buffered stream output.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/Support/raw_ostream.h"
15 #include "llvm/Support/Format.h"
16 #include "llvm/System/Program.h"
17 #include "llvm/System/Process.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/Config/config.h"
20 #include "llvm/Support/Compiler.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include <ostream>
23
24 #if defined(HAVE_UNISTD_H)
25 # include <unistd.h>
26 #endif
27 #if defined(HAVE_FCNTL_H)
28 # include <fcntl.h>
29 #endif
30
31 #if defined(_MSC_VER)
32 #include <io.h>
33 #include <fcntl.h>
34 #ifndef STDIN_FILENO
35 # define STDIN_FILENO 0
36 #endif
37 #ifndef STDOUT_FILENO
38 # define STDOUT_FILENO 1
39 #endif
40 #ifndef STDERR_FILENO
41 # define STDERR_FILENO 2
42 #endif
43 #endif
44
45 using namespace llvm;
46
47 raw_ostream::~raw_ostream() {
48   delete [] OutBufStart;
49
50   // If there are any pending errors, report them now. Clients wishing
51   // to avoid llvm_report_error calls should check for errors with
52   // has_error() and clear the error flag with clear_error() before
53   // destructing raw_ostream objects which may have errors.
54   if (Error)
55     llvm_report_error("IO failure on output stream.");
56 }
57
58 // An out of line virtual method to provide a home for the class vtable.
59 void raw_ostream::handle() {}
60
61 raw_ostream &raw_ostream::operator<<(unsigned long N) {
62   // Zero is a special case.
63   if (N == 0)
64     return *this << '0';
65   
66   char NumberBuffer[20];
67   char *EndPtr = NumberBuffer+sizeof(NumberBuffer);
68   char *CurPtr = EndPtr;
69   
70   while (N) {
71     *--CurPtr = '0' + char(N % 10);
72     N /= 10;
73   }
74   return write(CurPtr, EndPtr-CurPtr);
75 }
76
77 raw_ostream &raw_ostream::operator<<(long N) {
78   if (N <  0) {
79     *this << '-';
80     N = -N;
81   }
82   
83   return this->operator<<(static_cast<unsigned long>(N));
84 }
85
86 raw_ostream &raw_ostream::operator<<(unsigned long long N) {
87   // Zero is a special case.
88   if (N == 0)
89     return *this << '0';
90   
91   char NumberBuffer[20];
92   char *EndPtr = NumberBuffer+sizeof(NumberBuffer);
93   char *CurPtr = EndPtr;
94   
95   while (N) {
96     *--CurPtr = '0' + char(N % 10);
97     N /= 10;
98   }
99   return write(CurPtr, EndPtr-CurPtr);
100 }
101
102 raw_ostream &raw_ostream::operator<<(long long N) {
103   if (N <  0) {
104     *this << '-';
105     N = -N;
106   }
107   
108   return this->operator<<(static_cast<unsigned long long>(N));
109 }
110
111 raw_ostream &raw_ostream::operator<<(const void *P) {
112   uintptr_t N = (uintptr_t) P;
113   *this << '0' << 'x';
114   
115   // Zero is a special case.
116   if (N == 0)
117     return *this << '0';
118
119   char NumberBuffer[20];
120   char *EndPtr = NumberBuffer+sizeof(NumberBuffer);
121   char *CurPtr = EndPtr;
122
123   while (N) {
124     uintptr_t x = N % 16;
125     *--CurPtr = (x < 10 ? '0' + x : 'a' + x - 10);
126     N /= 16;
127   }
128
129   return write(CurPtr, EndPtr-CurPtr);
130 }
131
132 void raw_ostream::flush_nonempty() {
133   assert(OutBufCur > OutBufStart && "Invalid call to flush_nonempty.");
134   write_impl(OutBufStart, OutBufCur - OutBufStart);
135   OutBufCur = OutBufStart;    
136 }
137
138 raw_ostream &raw_ostream::write(unsigned char C) {
139   // Group exceptional cases into a single branch.
140   if (OutBufCur >= OutBufEnd) {
141     if (Unbuffered) {
142       write_impl(reinterpret_cast<char*>(&C), 1);
143       return *this;
144     }
145     
146     if (!OutBufStart)
147       SetBufferSize();
148     else
149       flush_nonempty();
150   }
151
152   *OutBufCur++ = C;
153   return *this;
154 }
155
156 raw_ostream &raw_ostream::write(const char *Ptr, size_t Size) {
157   // Group exceptional cases into a single branch.
158   if (BUILTIN_EXPECT(OutBufCur+Size > OutBufEnd, false)) {
159     if (Unbuffered) {
160       write_impl(Ptr, Size);
161       return *this;
162     }
163     
164     if (!OutBufStart)
165       SetBufferSize();
166     else
167       flush_nonempty();
168   }
169   
170   // Handle short strings specially, memcpy isn't very good at very short
171   // strings.
172   switch (Size) {
173   case 4: OutBufCur[3] = Ptr[3]; // FALL THROUGH
174   case 3: OutBufCur[2] = Ptr[2]; // FALL THROUGH
175   case 2: OutBufCur[1] = Ptr[1]; // FALL THROUGH
176   case 1: OutBufCur[0] = Ptr[0]; // FALL THROUGH
177   case 0: break;
178   default:
179     // Normally the string to emit is shorter than the buffer.
180     if (Size <= unsigned(OutBufEnd-OutBufCur)) {
181       memcpy(OutBufCur, Ptr, Size);
182       break;
183     } 
184
185     // Otherwise we are emitting a string larger than our buffer. We
186     // know we already flushed, so just write it out directly.
187     write_impl(Ptr, Size);
188     Size = 0;
189     break;
190   }
191   OutBufCur += Size;
192
193   return *this;
194 }
195
196 // Formatted output.
197 raw_ostream &raw_ostream::operator<<(const format_object_base &Fmt) {
198   // If we have more than a few bytes left in our output buffer, try
199   // formatting directly onto its end.
200   //
201   // FIXME: This test is a bit silly, since if we don't have enough
202   // space in the buffer we will have to flush the formatted output
203   // anyway. We should just flush upfront in such cases, and use the
204   // whole buffer as our scratch pad. Note, however, that this case is
205   // also necessary for correctness on unbuffered streams.
206   size_t NextBufferSize = 127;
207   if (OutBufEnd-OutBufCur > 3) {
208     size_t BufferBytesLeft = OutBufEnd-OutBufCur;
209     size_t BytesUsed = Fmt.print(OutBufCur, BufferBytesLeft);
210     
211     // Common case is that we have plenty of space.
212     if (BytesUsed < BufferBytesLeft) {
213       OutBufCur += BytesUsed;
214       return *this;
215     }
216     
217     // Otherwise, we overflowed and the return value tells us the size to try
218     // again with.
219     NextBufferSize = BytesUsed;
220   }
221   
222   // If we got here, we didn't have enough space in the output buffer for the
223   // string.  Try printing into a SmallVector that is resized to have enough
224   // space.  Iterate until we win.
225   SmallVector<char, 128> V;
226   
227   while (1) {
228     V.resize(NextBufferSize);
229     
230     // Try formatting into the SmallVector.
231     size_t BytesUsed = Fmt.print(&V[0], NextBufferSize);
232     
233     // If BytesUsed fit into the vector, we win.
234     if (BytesUsed <= NextBufferSize)
235       return write(&V[0], BytesUsed);
236     
237     // Otherwise, try again with a new size.
238     assert(BytesUsed > NextBufferSize && "Didn't grow buffer!?");
239     NextBufferSize = BytesUsed;
240   }
241 }
242
243 //===----------------------------------------------------------------------===//
244 //  Formatted Output
245 //===----------------------------------------------------------------------===//
246
247 // Out of line virtual method.
248 void format_object_base::home() {
249 }
250
251 //===----------------------------------------------------------------------===//
252 //  raw_fd_ostream
253 //===----------------------------------------------------------------------===//
254
255 /// raw_fd_ostream - Open the specified file for writing. If an error
256 /// occurs, information about the error is put into ErrorInfo, and the
257 /// stream should be immediately destroyed; the string will be empty
258 /// if no error occurred.
259 raw_fd_ostream::raw_fd_ostream(const char *Filename, bool Binary, bool Force,
260                                std::string &ErrorInfo) : pos(0) {
261   ErrorInfo.clear();
262
263   // Handle "-" as stdout.
264   if (Filename[0] == '-' && Filename[1] == 0) {
265     FD = STDOUT_FILENO;
266     // If user requested binary then put stdout into binary mode if
267     // possible.
268     if (Binary)
269       sys::Program::ChangeStdoutToBinary();
270     ShouldClose = false;
271     return;
272   }
273   
274   int Flags = O_WRONLY|O_CREAT|O_TRUNC;
275 #ifdef O_BINARY
276   if (Binary)
277     Flags |= O_BINARY;
278 #endif
279   if (!Force)
280     Flags |= O_EXCL;
281   FD = open(Filename, Flags, 0664);
282   if (FD < 0) {
283     ErrorInfo = "Error opening output file '" + std::string(Filename) + "'";
284     ShouldClose = false;
285   } else {
286     ShouldClose = true;
287   }
288 }
289
290 raw_fd_ostream::~raw_fd_ostream() {
291   if (FD >= 0) {
292     flush();
293     if (ShouldClose)
294       if (::close(FD) != 0)
295         error_detected();
296   }
297 }
298
299 void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
300   assert (FD >= 0 && "File already closed.");
301   pos += Size;
302   if (::write(FD, Ptr, Size) != (ssize_t) Size)
303     error_detected();
304 }
305
306 void raw_fd_ostream::close() {
307   assert (ShouldClose);
308   ShouldClose = false;
309   flush();
310   if (::close(FD) != 0)
311     error_detected();
312   FD = -1;
313 }
314
315 uint64_t raw_fd_ostream::seek(uint64_t off) {
316   flush();
317   pos = ::lseek(FD, off, SEEK_SET);
318   if (pos != off)
319     error_detected();
320   return pos;  
321 }
322
323 raw_ostream &raw_fd_ostream::changeColor(enum Colors colors, bool bold,
324                                          bool bg) {
325   if (sys::Process::ColorNeedsFlush())
326     flush();
327   const char *colorcode =
328     (colors == SAVEDCOLOR) ? sys::Process::OutputBold(bg)
329     : sys::Process::OutputColor(colors, bold, bg);
330   if (colorcode) {
331     size_t len = strlen(colorcode);
332     write(colorcode, len);
333     // don't account colors towards output characters
334     pos -= len;
335   }
336   return *this;
337 }
338
339 raw_ostream &raw_fd_ostream::resetColor() {
340   if (sys::Process::ColorNeedsFlush())
341     flush();
342   const char *colorcode = sys::Process::ResetColor();
343   if (colorcode) {
344     size_t len = strlen(colorcode);
345     write(colorcode, len);
346     // don't account colors towards output characters
347     pos -= len;
348   }
349   return *this;
350 }
351
352 //===----------------------------------------------------------------------===//
353 //  raw_stdout/err_ostream
354 //===----------------------------------------------------------------------===//
355
356 raw_stdout_ostream::raw_stdout_ostream():raw_fd_ostream(STDOUT_FILENO, false) {}
357 raw_stderr_ostream::raw_stderr_ostream():raw_fd_ostream(STDERR_FILENO, false, 
358                                                         true) {}
359
360 // An out of line virtual method to provide a home for the class vtable.
361 void raw_stdout_ostream::handle() {}
362 void raw_stderr_ostream::handle() {}
363
364 /// outs() - This returns a reference to a raw_ostream for standard output.
365 /// Use it like: outs() << "foo" << "bar";
366 raw_ostream &llvm::outs() {
367   static raw_stdout_ostream S;
368   return S;
369 }
370
371 /// errs() - This returns a reference to a raw_ostream for standard error.
372 /// Use it like: errs() << "foo" << "bar";
373 raw_ostream &llvm::errs() {
374   static raw_stderr_ostream S;
375   return S;
376 }
377
378 /// nulls() - This returns a reference to a raw_ostream which discards output.
379 raw_ostream &llvm::nulls() {
380   static raw_null_ostream S;
381   return S;
382 }
383
384 //===----------------------------------------------------------------------===//
385 //  raw_os_ostream
386 //===----------------------------------------------------------------------===//
387
388 raw_os_ostream::~raw_os_ostream() {
389   flush();
390 }
391
392 void raw_os_ostream::write_impl(const char *Ptr, size_t Size) {
393   OS.write(Ptr, Size);
394 }
395
396 uint64_t raw_os_ostream::current_pos() { return OS.tellp(); }
397
398 uint64_t raw_os_ostream::tell() { 
399   return (uint64_t)OS.tellp() + GetNumBytesInBuffer(); 
400 }
401
402 //===----------------------------------------------------------------------===//
403 //  raw_string_ostream
404 //===----------------------------------------------------------------------===//
405
406 raw_string_ostream::~raw_string_ostream() {
407   flush();
408 }
409
410 void raw_string_ostream::write_impl(const char *Ptr, size_t Size) {
411   OS.append(Ptr, Size);
412 }
413
414 //===----------------------------------------------------------------------===//
415 //  raw_svector_ostream
416 //===----------------------------------------------------------------------===//
417
418 raw_svector_ostream::~raw_svector_ostream() {
419   flush();
420 }
421
422 void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) {
423   OS.append(Ptr, Ptr + Size);
424 }
425
426 uint64_t raw_svector_ostream::current_pos() { return OS.size(); }
427
428 uint64_t raw_svector_ostream::tell() { 
429   return OS.size() + GetNumBytesInBuffer(); 
430 }
431
432 //===----------------------------------------------------------------------===//
433 //  raw_null_ostream
434 //===----------------------------------------------------------------------===//
435
436 void raw_null_ostream::write_impl(const char *Ptr, size_t Size) {
437 }
438
439 uint64_t raw_null_ostream::current_pos() {
440   return 0;
441 }