diff 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
line wrap: on
line diff
--- a/gen/logger.h	Tue Jun 16 15:37:40 2009 +0200
+++ b/gen/logger.h	Tue Jun 16 19:31:10 2009 +0200
@@ -1,7 +1,12 @@
 #ifndef _llvmd_gen_logger_h_
 #define _llvmd_gen_logger_h_
 
-#include "llvm/Support/Streams.h"
+#include <iosfwd>
+
+namespace llvm {
+    class Type;
+    class Value;
+}
 
 #ifndef IS_PRINTF
 # ifdef __GNUC__
@@ -13,11 +18,69 @@
 
 struct Loc;
 
+class Stream {
+    std::ostream* OS;
+    
+public:
+    Stream() : OS(0) {}
+    Stream(std::ostream* S) : OS(S) {}
+    Stream(std::ostream& S) : OS(&S) {}
+    
+    Stream operator << (std::ios_base &(*Func)(std::ios_base&)) {
+      if (OS) *OS << Func;
+      return *this;
+    }
+    
+    Stream operator << (std::ostream &(*Func)(std::ostream&)) {
+      if (OS) *OS << Func;
+      return *this;
+    }
+    
+    template<typename Ty>
+    Stream& operator << (const Ty& Thing) {
+        if (OS)
+            Writer<Ty, sizeof(sfinae_bait(Thing))>::write(*OS, Thing);
+        return *this;
+    }
+    
+private:
+    // Implementation details to treat llvm::Value, llvm::Type and their
+    // subclasses specially (to pretty-print types).
+    
+    static void writeType(std::ostream& OS, const llvm::Type& Ty);
+    static void writeValue(std::ostream& OS, const llvm::Value& Ty);
+    
+    template<typename Ty, int N> friend struct Writer;
+    // error: function template partial specialization is not allowed
+    // So I guess type partial specialization + member function will have to do...
+    template<typename Ty, int N>
+    struct Writer {
+        static void write(std::ostream& OS, const Ty& Thing) {
+            OS << Thing;
+        }
+    };
+    
+    template<typename Ty>
+    struct Writer<Ty, 1> {
+        static void write(std::ostream& OS, const llvm::Type& Thing) {
+            Stream::writeType(OS, Thing);
+        }
+        static void write(std::ostream& OS, const llvm::Value& Thing) {
+            Stream::writeValue(OS, Thing);
+        }
+    };
+    
+    // NOT IMPLEMENTED
+    char sfinae_bait(const llvm::Type&);
+    char sfinae_bait(const llvm::Value&);
+    short sfinae_bait(...);
+};
+
 namespace Logger
 {
     void indent();
     void undent();
-    llvm::OStream cout();
+    Stream cout();
     void println(const char* fmt, ...) IS_PRINTF(1);
     void print(const char* fmt, ...) IS_PRINTF(1);
     void enable();