102 lines · c
1//===- CLog.h - Logging Interface -------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_CLANG_TOOLS_LIBCLANG_CLOG_H10#define LLVM_CLANG_TOOLS_LIBCLANG_CLOG_H11 12#include "clang-c/Index.h"13#include "clang/Basic/FileEntry.h"14#include "clang/Basic/LLVM.h"15#include "llvm/ADT/IntrusiveRefCntPtr.h"16#include "llvm/ADT/SmallString.h"17#include "llvm/ADT/StringRef.h"18#include "llvm/Support/Compiler.h"19#include "llvm/Support/raw_ostream.h"20#include <string>21 22namespace llvm {23class format_object_base;24}25 26namespace clang {27namespace cxindex {28 29class Logger;30typedef IntrusiveRefCntPtr<Logger> LogRef;31 32/// Collects logging output and writes it to stderr when it's destructed.33/// Common use case:34/// \code35/// if (LogRef Log = Logger::make(__func__)) {36/// *Log << "stuff";37/// }38/// \endcode39class Logger : public RefCountedBase<Logger> {40 std::string Name;41 bool Trace;42 SmallString<64> Msg;43 llvm::raw_svector_ostream LogOS;44public:45 static const char *getEnvVar() {46 static const char *sCachedVar = ::getenv("LIBCLANG_LOGGING");47 return sCachedVar;48 }49 static bool isLoggingEnabled() { return getEnvVar() != nullptr; }50 static bool isStackTracingEnabled() {51 if (const char *EnvOpt = Logger::getEnvVar())52 return llvm::StringRef(EnvOpt) == "2";53 return false;54 }55 static LogRef make(llvm::StringRef name,56 bool trace = isStackTracingEnabled()) {57 if (isLoggingEnabled())58 return new Logger(name, trace);59 return nullptr;60 }61 62 explicit Logger(llvm::StringRef name, bool trace)63 : Name(std::string(name)), Trace(trace), LogOS(Msg) {}64 ~Logger();65 66 Logger &operator<<(CXTranslationUnit);67 Logger &operator<<(FileEntryRef FE);68 Logger &operator<<(CXCursor cursor);69 Logger &operator<<(CXSourceLocation);70 Logger &operator<<(CXSourceRange);71 Logger &operator<<(CXString);72 Logger &operator<<(llvm::StringRef Str) { LogOS << Str; return *this; }73 Logger &operator<<(const char *Str) {74 if (Str)75 LogOS << Str;76 return *this;77 }78 Logger &operator<<(unsigned long N) { LogOS << N; return *this; }79 Logger &operator<<(long N) { LogOS << N ; return *this; }80 Logger &operator<<(unsigned int N) { LogOS << N; return *this; }81 Logger &operator<<(int N) { LogOS << N; return *this; }82 Logger &operator<<(char C) { LogOS << C; return *this; }83 Logger &operator<<(unsigned char C) { LogOS << C; return *this; }84 Logger &operator<<(signed char C) { LogOS << C; return *this; }85 Logger &operator<<(const llvm::format_object_base &Fmt);86};87 88}89}90 91/// Macros to automate common uses of Logger. Like this:92/// \code93/// LOG_FUNC_SECTION {94/// *Log << "blah";95/// }96/// \endcode97#define LOG_SECTION(NAME) \98 if (clang::cxindex::LogRef Log = clang::cxindex::Logger::make(NAME))99#define LOG_FUNC_SECTION LOG_SECTION(__func__)100 101#endif102