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