clang-tools 8.0.0

Logger.h
Go to the documentation of this file.
1 //===--- Logger.h - Logger interface for clangd ------------------*- C++-*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_LOGGER_H
11 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_LOGGER_H
12
13 #include "llvm/ADT/Twine.h"
14 #include "llvm/Support/Debug.h"
15 #include "llvm/Support/Error.h"
16 #include "llvm/Support/FormatAdapters.h"
17 #include "llvm/Support/FormatVariadic.h"
18 #include <mutex>
19
20 namespace clang {
21 namespace clangd {
22
23 /// Interface to allow custom logging in clangd.
24 class Logger {
25 public:
26 virtual ~Logger() = default;
27
28 enum Level { Debug, Verbose, Info, Error };
29 static char indicator(Level L) { return "DVIE"[L]; }
30
31 /// Implementations of this method must be thread-safe.
32 virtual void log(Level, const llvm::formatv_object_base &Message) = 0;
33 };
34
35 namespace detail {
36 const char *debugType(const char *Filename);
37 void log(Logger::Level, const llvm::formatv_object_base &);
38
39 // We often want to consume llvm::Errors by value when passing them to log().
40 // We automatically wrap them in llvm::fmt_consume() as formatv requires.
41 template <typename T> T &&wrap(T &&V) { return std::forward<T>(V); }
42 inline decltype(fmt_consume(llvm::Error::success())) wrap(llvm::Error &&V) {
43 return fmt_consume(std::move(V));
44 }
45 template <typename... Ts>
46 void log(Logger::Level L, const char *Fmt, Ts &&... Vals) {
47 detail::log(L, llvm::formatv(Fmt, detail::wrap(std::forward<Ts>(Vals))...));
48 }
49 } // namespace detail
50
51 // Clangd logging functions write to a global logger set by LoggingSession.
52 // If no logger is registered, writes to llvm::errs().
53 // All accept llvm::formatv()-style arguments, e.g. log("Text={0}", Text).
54
55 // elog() is used for "loud" errors and warnings.
56 // This level is often visible to users.
57 template <typename... Ts> void elog(const char *Fmt, Ts &&... Vals) {
58 detail::log(Logger::Error, Fmt, std::forward<Ts>(Vals)...);
59 }
60 // log() is used for information important to understand a clangd session.
61 // e.g. the names of LSP messages sent are logged at this level.
62 // This level could be enabled in production builds to allow later inspection.
63 template <typename... Ts> void log(const char *Fmt, Ts &&... Vals) {
64 detail::log(Logger::Info, Fmt, std::forward<Ts>(Vals)...);
65 }
66 // vlog() is used for details often needed for debugging clangd sessions.
67 // This level would typically be enabled for clangd developers.
68 template <typename... Ts> void vlog(const char *Fmt, Ts &&... Vals) {
69 detail::log(Logger::Verbose, Fmt, std::forward<Ts>(Vals)...);
70 }
71 // dlog only logs if --debug was passed, or --debug_only=Basename.
72 // This level would be enabled in a targeted way when debugging.
73 #define dlog(...) \
74 DEBUG_WITH_TYPE(::clang::clangd::detail::debugType(__FILE__), \
75 ::clang::clangd::detail::log(Logger::Debug, __VA_ARGS__))
76
77 /// Only one LoggingSession can be active at a time.
78 class LoggingSession {
79 public:
80 LoggingSession(clangd::Logger &Instance);
81 ~LoggingSession();
82
83 LoggingSession(LoggingSession &&) = delete;
84 LoggingSession &operator=(LoggingSession &&) = delete;
85
86 LoggingSession(LoggingSession const &) = delete;
87 LoggingSession &operator=(LoggingSession const &) = delete;
88 };
89
90 // Logs to an output stream, such as stderr.
91 class StreamLogger : public Logger {
92 public:
93 StreamLogger(llvm::raw_ostream &Logs, Logger::Level MinLevel)
94 : MinLevel(MinLevel), Logs(Logs) {}
95
96 /// Write a line to the logging stream.
97 void log(Level, const llvm::formatv_object_base &Message) override;
98
99 private:
100 Logger::Level MinLevel;
101 llvm::raw_ostream &Logs;
102
103 std::mutex StreamMutex;
104 };
105
106 } // namespace clangd
107 } // namespace clang
108
109 #endif
clang::clangd::Logger::Debug
Definition: Logger.h:28
llvm
Some operations such as code completion produce a set of candidates.
Definition: YAMLGenerator.cpp:28
clang::clangd::detail::log
void log(Logger::Level, const llvm::formatv_object_base &)
Definition: Logger.cpp:31
clang::tidy::modernize::Message
static const StringRef Message
Definition: UseTransparentFunctorsCheck.cpp:71
clang::clangd::Logger::indicator
static char indicator(Level L)
Definition: Logger.h:29
clang::clangd::detail::wrap
decltype(fmt_consume(llvm::Error::success())) wrap(llvm::Error &&V)
Definition: Logger.h:42
clang::clangd::vlog
void vlog(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:68
clang::clangd::elog
void elog(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:57
clang::clangd::detail::debugType
const char * debugType(const char *Filename)
Definition: Logger.cpp:42
clang::clangd::StreamLogger
Definition: Logger.h:91
clang::clangd::Logger::log
virtual void log(Level, const llvm::formatv_object_base &Message)=0
Implementations of this method must be thread-safe.
Filename
std::string Filename
Filename as a string.
Definition: IncludeOrderCheck.cpp:39
clang::clangd::Logger
Interface to allow custom logging in clangd.
Definition: Logger.h:24
clang::clangd::LoggingSession
Only one LoggingSession can be active at a time.
Definition: Logger.h:78
clang::clangd::Logger::Level
Level
Definition: Logger.h:28
clang::clangd::Logger::Info
Definition: Logger.h:28
clang::clangd::Logger::~Logger
virtual ~Logger()=default
clang::clangd::detail::wrap
T && wrap(T &&V)
Definition: Logger.h:41
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ChangeNamespace.cpp:18
clang::clangd::StreamLogger::StreamLogger
StreamLogger(llvm::raw_ostream &Logs, Logger::Level MinLevel)
Definition: Logger.h:93
clang::clangd::Logger::Verbose
Definition: Logger.h:28
clang::clangd::Logger::Error
Definition: Logger.h:28