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