blob: ab934e4221e9fb070b5aa8d2c73ac554c18ef4cf [file] [log] [blame]
Daniel Jasperd07c8402013-07-29 08:19:24 +00001//===--- ClangTidyDiagnosticConsumer.h - clang-tidy -------------*- 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_CLANG_TIDY_CLANG_TIDY_DIAGNOSTIC_CONSUMER_H
11#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_DIAGNOSTIC_CONSUMER_H
12
13#include "clang/Basic/Diagnostic.h"
14#include "clang/Basic/SourceManager.h"
15#include "clang/Tooling/Refactoring.h"
Alexander Kornienko41bfe8d2014-01-13 10:50:51 +000016#include "llvm/ADT/DenseMap.h"
Alexander Kornienko09952d22014-03-20 09:38:22 +000017#include "llvm/Support/Regex.h"
Daniel Jasperd07c8402013-07-29 08:19:24 +000018
19namespace clang {
20
21class CompilerInstance;
22namespace ast_matchers {
23class MatchFinder;
24}
25namespace tooling {
26class CompilationDatabase;
27}
28
29namespace tidy {
30
Manuel Klimek814f9bd2013-11-14 15:49:44 +000031/// \brief A message from a clang-tidy check.
32///
33/// Note that this is independent of a \c SourceManager.
34struct ClangTidyMessage {
35 ClangTidyMessage(StringRef Message = "");
36 ClangTidyMessage(StringRef Message, const SourceManager &Sources,
37 SourceLocation Loc);
38 std::string Message;
39 std::string FilePath;
40 unsigned FileOffset;
41};
42
43/// \brief A detected error complete with information to display diagnostic and
44/// automatic fix.
45///
46/// This is used as an intermediate format to transport Diagnostics without a
47/// dependency on a SourceManager.
48///
49/// FIXME: Make Diagnostics flexible enough to support this directly.
50struct ClangTidyError {
Alexander Kornienko6fbc6192014-03-10 13:11:17 +000051 ClangTidyError(StringRef CheckName);
Manuel Klimek814f9bd2013-11-14 15:49:44 +000052
Alexander Kornienko41bfe8d2014-01-13 10:50:51 +000053 std::string CheckName;
Manuel Klimek814f9bd2013-11-14 15:49:44 +000054 ClangTidyMessage Message;
55 tooling::Replacements Fix;
56 SmallVector<ClangTidyMessage, 1> Notes;
57};
58
Alexander Kornienko09952d22014-03-20 09:38:22 +000059/// \brief Filters checks by name.
60class ChecksFilter {
61public:
62 ChecksFilter(StringRef EnableChecksRegex, StringRef DisableChecksRegex);
63 bool isCheckEnabled(StringRef Name);
64
65private:
66 llvm::Regex EnableChecks;
67 llvm::Regex DisableChecks;
68};
69
Manuel Klimek814f9bd2013-11-14 15:49:44 +000070/// \brief Every \c ClangTidyCheck reports errors through a \c DiagnosticEngine
71/// provided by this context.
72///
73/// A \c ClangTidyCheck always has access to the active context to report
74/// warnings like:
75/// \code
76/// Context->Diag(Loc, "Single-argument constructors must be explicit")
77/// << FixItHint::CreateInsertion(Loc, "explicit ");
78/// \endcode
79class ClangTidyContext {
80public:
Alexander Kornienko09952d22014-03-20 09:38:22 +000081 ClangTidyContext(SmallVectorImpl<ClangTidyError> *Errors,
82 StringRef EnableChecksRegex, StringRef DisableChecksRegex);
Manuel Klimek814f9bd2013-11-14 15:49:44 +000083
84 /// \brief Report any errors detected using this method.
85 ///
86 /// This is still under heavy development and will likely change towards using
87 /// tablegen'd diagnostic IDs.
88 /// FIXME: Figure out a way to manage ID spaces.
Alexander Kornienko41bfe8d2014-01-13 10:50:51 +000089 DiagnosticBuilder diag(StringRef CheckName, SourceLocation Loc,
Alexander Kornienko54461eb2014-02-06 14:50:10 +000090 StringRef Message,
91 DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
Manuel Klimek814f9bd2013-11-14 15:49:44 +000092
93 /// \brief Sets the \c DiagnosticsEngine so that Diagnostics can be generated
94 /// correctly.
95 ///
96 /// This is called from the \c ClangTidyCheck base class.
97 void setDiagnosticsEngine(DiagnosticsEngine *Engine);
98
99 /// \brief Sets the \c SourceManager of the used \c DiagnosticsEngine.
100 ///
101 /// This is called from the \c ClangTidyCheck base class.
102 void setSourceManager(SourceManager *SourceMgr);
103
Alexander Kornienko41bfe8d2014-01-13 10:50:51 +0000104 /// \brief Returns the name of the clang-tidy check which produced this
105 /// diagnostic ID.
106 StringRef getCheckName(unsigned DiagnosticID) const;
107
Alexander Kornienko09952d22014-03-20 09:38:22 +0000108 ChecksFilter &getChecksFilter() { return Filter; }
109
Manuel Klimek814f9bd2013-11-14 15:49:44 +0000110private:
111 friend class ClangTidyDiagnosticConsumer; // Calls storeError().
112
113 /// \brief Store a \c ClangTidyError.
114 void storeError(const ClangTidyError &Error);
115
116 SmallVectorImpl<ClangTidyError> *Errors;
NAKAMURA Takumi338eee12014-03-20 10:53:03 +0000117 DiagnosticsEngine *DiagEngine;
Alexander Kornienko09952d22014-03-20 09:38:22 +0000118 ChecksFilter Filter;
119
Alexander Kornienko41bfe8d2014-01-13 10:50:51 +0000120 llvm::DenseMap<unsigned, std::string> CheckNamesByDiagnosticID;
Manuel Klimek814f9bd2013-11-14 15:49:44 +0000121};
122
Daniel Jasperd07c8402013-07-29 08:19:24 +0000123/// \brief A diagnostic consumer that turns each \c Diagnostic into a
124/// \c SourceManager-independent \c ClangTidyError.
125//
126// FIXME: If we move away from unit-tests, this can be moved to a private
127// implementation file.
128class ClangTidyDiagnosticConsumer : public DiagnosticConsumer {
129public:
Alexander Kornienko0ba86b72014-01-09 16:31:25 +0000130 ClangTidyDiagnosticConsumer(ClangTidyContext &Ctx);
Daniel Jasperd07c8402013-07-29 08:19:24 +0000131
132 // FIXME: The concept of converting between FixItHints and Replacements is
133 // more generic and should be pulled out into a more useful Diagnostics
134 // library.
Alexander Kornienkocb9272f2014-02-27 13:14:51 +0000135 void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
Craig Toppera3dbe842014-03-02 10:20:11 +0000136 const Diagnostic &Info) override;
Manuel Klimek814f9bd2013-11-14 15:49:44 +0000137
Alexander Kornienkofc589872014-01-03 15:34:40 +0000138 // Flushes the internal diagnostics buffer to the ClangTidyContext.
Craig Toppera3dbe842014-03-02 10:20:11 +0000139 void finish() override;
Daniel Jasperd07c8402013-07-29 08:19:24 +0000140
141private:
Alexander Kornienko54461eb2014-02-06 14:50:10 +0000142 void finalizeLastError();
Manuel Klimek814f9bd2013-11-14 15:49:44 +0000143
Daniel Jasperd07c8402013-07-29 08:19:24 +0000144 ClangTidyContext &Context;
Ahmed Charles6a2dc5c2014-03-09 09:24:40 +0000145 std::unique_ptr<DiagnosticsEngine> Diags;
Manuel Klimek814f9bd2013-11-14 15:49:44 +0000146 SmallVector<ClangTidyError, 8> Errors;
Alexander Kornienko54461eb2014-02-06 14:50:10 +0000147 bool LastErrorRelatesToUserCode;
Daniel Jasperd07c8402013-07-29 08:19:24 +0000148};
149
150} // end namespace tidy
151} // end namespace clang
152
153#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_DIAGNOSTIC_CONSUMER_H