xref: /minix3/external/bsd/llvm/dist/clang/tools/libclang/CLog.h (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===- CLog.h - Logging Interface -------------------------------*- C++ -*-===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc 
10*0a6a1f1dSLionel Sambuc #ifndef LLVM_CLANG_TOOLS_LIBCLANG_CLOG_H
11*0a6a1f1dSLionel Sambuc #define LLVM_CLANG_TOOLS_LIBCLANG_CLOG_H
12f4a2713aSLionel Sambuc 
13*0a6a1f1dSLionel Sambuc #include "clang-c/Index.h"
14f4a2713aSLionel Sambuc #include "clang/Basic/LLVM.h"
15f4a2713aSLionel Sambuc #include "llvm/ADT/IntrusiveRefCntPtr.h"
16f4a2713aSLionel Sambuc #include "llvm/ADT/SmallString.h"
17f4a2713aSLionel Sambuc #include "llvm/ADT/StringRef.h"
18f4a2713aSLionel Sambuc #include "llvm/Support/Compiler.h"
19f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
20f4a2713aSLionel Sambuc #include <string>
21f4a2713aSLionel Sambuc 
22f4a2713aSLionel Sambuc namespace llvm {
23f4a2713aSLionel Sambuc class format_object_base;
24f4a2713aSLionel Sambuc }
25f4a2713aSLionel Sambuc 
26f4a2713aSLionel Sambuc namespace clang {
27f4a2713aSLionel Sambuc   class FileEntry;
28f4a2713aSLionel Sambuc 
29f4a2713aSLionel Sambuc namespace cxindex {
30f4a2713aSLionel Sambuc 
31f4a2713aSLionel Sambuc class Logger;
32f4a2713aSLionel Sambuc typedef IntrusiveRefCntPtr<Logger> LogRef;
33f4a2713aSLionel Sambuc 
34f4a2713aSLionel Sambuc /// \brief Collects logging output and writes it to stderr when it's destructed.
35f4a2713aSLionel Sambuc /// Common use case:
36f4a2713aSLionel Sambuc /// \code
37f4a2713aSLionel Sambuc ///   if (LogRef Log = Logger::make(__func__)) {
38f4a2713aSLionel Sambuc ///     *Log << "stuff";
39f4a2713aSLionel Sambuc ///   }
40f4a2713aSLionel Sambuc /// \endcode
41f4a2713aSLionel Sambuc class Logger : public RefCountedBase<Logger> {
42f4a2713aSLionel Sambuc   std::string Name;
43f4a2713aSLionel Sambuc   bool Trace;
44f4a2713aSLionel Sambuc   SmallString<64> Msg;
45f4a2713aSLionel Sambuc   llvm::raw_svector_ostream LogOS;
46f4a2713aSLionel Sambuc public:
getEnvVar()47f4a2713aSLionel Sambuc   static const char *getEnvVar() {
48f4a2713aSLionel Sambuc     static const char *sCachedVar = ::getenv("LIBCLANG_LOGGING");
49f4a2713aSLionel Sambuc     return sCachedVar;
50f4a2713aSLionel Sambuc   }
isLoggingEnabled()51*0a6a1f1dSLionel Sambuc   static bool isLoggingEnabled() { return getEnvVar() != nullptr; }
isStackTracingEnabled()52f4a2713aSLionel Sambuc   static bool isStackTracingEnabled() {
53f4a2713aSLionel Sambuc     if (const char *EnvOpt = Logger::getEnvVar())
54f4a2713aSLionel Sambuc       return llvm::StringRef(EnvOpt) == "2";
55f4a2713aSLionel Sambuc     return false;
56f4a2713aSLionel Sambuc   }
57f4a2713aSLionel Sambuc   static LogRef make(llvm::StringRef name,
58f4a2713aSLionel Sambuc                      bool trace = isStackTracingEnabled()) {
59f4a2713aSLionel Sambuc     if (isLoggingEnabled())
60f4a2713aSLionel Sambuc       return new Logger(name, trace);
61*0a6a1f1dSLionel Sambuc     return nullptr;
62f4a2713aSLionel Sambuc   }
63f4a2713aSLionel Sambuc 
Logger(llvm::StringRef name,bool trace)64f4a2713aSLionel Sambuc   explicit Logger(llvm::StringRef name, bool trace)
65f4a2713aSLionel Sambuc     : Name(name), Trace(trace), LogOS(Msg) { }
66f4a2713aSLionel Sambuc   ~Logger();
67f4a2713aSLionel Sambuc 
68f4a2713aSLionel Sambuc   Logger &operator<<(CXTranslationUnit);
69f4a2713aSLionel Sambuc   Logger &operator<<(const FileEntry *FE);
70f4a2713aSLionel Sambuc   Logger &operator<<(CXCursor cursor);
71f4a2713aSLionel Sambuc   Logger &operator<<(CXSourceLocation);
72f4a2713aSLionel Sambuc   Logger &operator<<(CXSourceRange);
73f4a2713aSLionel Sambuc   Logger &operator<<(CXString);
74f4a2713aSLionel Sambuc   Logger &operator<<(llvm::StringRef Str) { LogOS << Str; return *this; }
75f4a2713aSLionel Sambuc   Logger &operator<<(const char *Str) {
76f4a2713aSLionel Sambuc     if (Str)
77f4a2713aSLionel Sambuc       LogOS << Str;
78f4a2713aSLionel Sambuc     return *this;
79f4a2713aSLionel Sambuc   }
80f4a2713aSLionel Sambuc   Logger &operator<<(unsigned long N) { LogOS << N; return *this; }
81f4a2713aSLionel Sambuc   Logger &operator<<(long N) { LogOS << N ; return *this; }
82f4a2713aSLionel Sambuc   Logger &operator<<(unsigned int N) { LogOS << N; return *this; }
83f4a2713aSLionel Sambuc   Logger &operator<<(int N) { LogOS << N; return *this; }
84f4a2713aSLionel Sambuc   Logger &operator<<(char C) { LogOS << C; return *this; }
85f4a2713aSLionel Sambuc   Logger &operator<<(unsigned char C) { LogOS << C; return *this; }
86f4a2713aSLionel Sambuc   Logger &operator<<(signed char C) { LogOS << C; return *this; }
87f4a2713aSLionel Sambuc   Logger &operator<<(const llvm::format_object_base &Fmt);
88f4a2713aSLionel Sambuc };
89f4a2713aSLionel Sambuc 
90f4a2713aSLionel Sambuc }
91f4a2713aSLionel Sambuc }
92f4a2713aSLionel Sambuc 
93f4a2713aSLionel Sambuc /// \brief Macros to automate common uses of Logger. Like this:
94f4a2713aSLionel Sambuc /// \code
95f4a2713aSLionel Sambuc ///   LOG_FUNC_SECTION {
96f4a2713aSLionel Sambuc ///     *Log << "blah";
97f4a2713aSLionel Sambuc ///   }
98f4a2713aSLionel Sambuc /// \endcode
99*0a6a1f1dSLionel Sambuc #define LOG_SECTION(NAME) \
100*0a6a1f1dSLionel Sambuc     if (clang::cxindex::LogRef Log = clang::cxindex::Logger::make(NAME))
101f4a2713aSLionel Sambuc #define LOG_FUNC_SECTION LOG_SECTION(LLVM_FUNCTION_NAME)
102f4a2713aSLionel Sambuc 
103f4a2713aSLionel Sambuc #endif
104