comparison gen/logger.h @ 1502:2292878925f4

Add an `llvm::OStream` workalike class for use with `Logger::cout()`, with the crucial difference being special handling of `llvm::Type`s so they get printed by name rather than printing their full representation (which can be positively *huge*). This allows re-enabling some logger calls that were disabled due to extreme verbosity.
author Frits van Bommel <fvbommel wxs.nl>
date Tue, 16 Jun 2009 19:31:10 +0200
parents 229e02867307
children 40bd4a0d4870
comparison
equal deleted inserted replaced
1501:8b9f236dd051 1502:2292878925f4
1 #ifndef _llvmd_gen_logger_h_ 1 #ifndef _llvmd_gen_logger_h_
2 #define _llvmd_gen_logger_h_ 2 #define _llvmd_gen_logger_h_
3 3
4 #include "llvm/Support/Streams.h" 4 #include <iosfwd>
5
6 namespace llvm {
7 class Type;
8 class Value;
9 }
5 10
6 #ifndef IS_PRINTF 11 #ifndef IS_PRINTF
7 # ifdef __GNUC__ 12 # ifdef __GNUC__
8 # define IS_PRINTF(FMTARG) __attribute((__format__ (__printf__, (FMTARG), (FMTARG)+1) )) 13 # define IS_PRINTF(FMTARG) __attribute((__format__ (__printf__, (FMTARG), (FMTARG)+1) ))
9 # else 14 # else
11 # endif 16 # endif
12 #endif 17 #endif
13 18
14 struct Loc; 19 struct Loc;
15 20
21 class Stream {
22 std::ostream* OS;
23
24 public:
25 Stream() : OS(0) {}
26 Stream(std::ostream* S) : OS(S) {}
27 Stream(std::ostream& S) : OS(&S) {}
28
29 Stream operator << (std::ios_base &(*Func)(std::ios_base&)) {
30 if (OS) *OS << Func;
31 return *this;
32 }
33
34 Stream operator << (std::ostream &(*Func)(std::ostream&)) {
35 if (OS) *OS << Func;
36 return *this;
37 }
38
39 template<typename Ty>
40 Stream& operator << (const Ty& Thing) {
41 if (OS)
42 Writer<Ty, sizeof(sfinae_bait(Thing))>::write(*OS, Thing);
43 return *this;
44 }
45
46 private:
47 // Implementation details to treat llvm::Value, llvm::Type and their
48 // subclasses specially (to pretty-print types).
49
50 static void writeType(std::ostream& OS, const llvm::Type& Ty);
51 static void writeValue(std::ostream& OS, const llvm::Value& Ty);
52
53 template<typename Ty, int N> friend struct Writer;
54 // error: function template partial specialization is not allowed
55 // So I guess type partial specialization + member function will have to do...
56 template<typename Ty, int N>
57 struct Writer {
58 static void write(std::ostream& OS, const Ty& Thing) {
59 OS << Thing;
60 }
61 };
62
63 template<typename Ty>
64 struct Writer<Ty, 1> {
65 static void write(std::ostream& OS, const llvm::Type& Thing) {
66 Stream::writeType(OS, Thing);
67 }
68 static void write(std::ostream& OS, const llvm::Value& Thing) {
69 Stream::writeValue(OS, Thing);
70 }
71 };
72
73 // NOT IMPLEMENTED
74 char sfinae_bait(const llvm::Type&);
75 char sfinae_bait(const llvm::Value&);
76 short sfinae_bait(...);
77 };
78
16 namespace Logger 79 namespace Logger
17 { 80 {
18 void indent(); 81 void indent();
19 void undent(); 82 void undent();
20 llvm::OStream cout(); 83 Stream cout();
21 void println(const char* fmt, ...) IS_PRINTF(1); 84 void println(const char* fmt, ...) IS_PRINTF(1);
22 void print(const char* fmt, ...) IS_PRINTF(1); 85 void print(const char* fmt, ...) IS_PRINTF(1);
23 void enable(); 86 void enable();
24 void disable(); 87 void disable();
25 bool enabled(); 88 bool enabled();