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