blob: 425075df552d580a9bce317750696a97fe7da152 [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
Alexander Kornienko9ff5b6f2014-05-05 14:54:47 +000013#include "ClangTidyOptions.h"
Daniel Jasperd07c8402013-07-29 08:19:24 +000014#include "clang/Basic/Diagnostic.h"
15#include "clang/Basic/SourceManager.h"
16#include "clang/Tooling/Refactoring.h"
Alexander Kornienko41bfe8d2014-01-13 10:50:51 +000017#include "llvm/ADT/DenseMap.h"
Alexander Kornienko09952d22014-03-20 09:38:22 +000018#include "llvm/Support/Regex.h"
Daniel Jasperd07c8402013-07-29 08:19:24 +000019
20namespace clang {
21
22class CompilerInstance;
23namespace ast_matchers {
24class MatchFinder;
25}
26namespace tooling {
27class CompilationDatabase;
28}
29
30namespace tidy {
31
Manuel Klimek814f9bd2013-11-14 15:49:44 +000032/// \brief A message from a clang-tidy check.
33///
34/// Note that this is independent of a \c SourceManager.
35struct ClangTidyMessage {
36 ClangTidyMessage(StringRef Message = "");
37 ClangTidyMessage(StringRef Message, const SourceManager &Sources,
38 SourceLocation Loc);
39 std::string Message;
40 std::string FilePath;
41 unsigned FileOffset;
42};
43
44/// \brief A detected error complete with information to display diagnostic and
45/// automatic fix.
46///
47/// This is used as an intermediate format to transport Diagnostics without a
48/// dependency on a SourceManager.
49///
50/// FIXME: Make Diagnostics flexible enough to support this directly.
51struct ClangTidyError {
Alexander Kornienko6fbc6192014-03-10 13:11:17 +000052 ClangTidyError(StringRef CheckName);
Manuel Klimek814f9bd2013-11-14 15:49:44 +000053
Alexander Kornienko41bfe8d2014-01-13 10:50:51 +000054 std::string CheckName;
Manuel Klimek814f9bd2013-11-14 15:49:44 +000055 ClangTidyMessage Message;
56 tooling::Replacements Fix;
57 SmallVector<ClangTidyMessage, 1> Notes;
58};
59
Alexander Kornienko09952d22014-03-20 09:38:22 +000060/// \brief Filters checks by name.
61class ChecksFilter {
62public:
Alexander Kornienko33a9bcc2014-04-29 15:20:10 +000063 ChecksFilter(const ClangTidyOptions& Options);
Alexander Kornienko09952d22014-03-20 09:38:22 +000064 bool isCheckEnabled(StringRef Name);
65
66private:
67 llvm::Regex EnableChecks;
68 llvm::Regex DisableChecks;
69};
70
Alexander Kornienko5d174542014-05-07 09:06:53 +000071struct ClangTidyStats {
72 ClangTidyStats()
73 : ErrorsDisplayed(0), ErrorsIgnoredCheckFilter(0), ErrorsIgnoredNOLINT(0),
74 ErrorsIgnoredNonUserCode(0) {}
75
76 unsigned ErrorsDisplayed;
77 unsigned ErrorsIgnoredCheckFilter;
78 unsigned ErrorsIgnoredNOLINT;
79 unsigned ErrorsIgnoredNonUserCode;
80};
81
Manuel Klimek814f9bd2013-11-14 15:49:44 +000082/// \brief Every \c ClangTidyCheck reports errors through a \c DiagnosticEngine
83/// provided by this context.
84///
85/// A \c ClangTidyCheck always has access to the active context to report
86/// warnings like:
87/// \code
88/// Context->Diag(Loc, "Single-argument constructors must be explicit")
89/// << FixItHint::CreateInsertion(Loc, "explicit ");
90/// \endcode
91class ClangTidyContext {
92public:
Alexander Kornienko826b5ad2014-05-09 12:24:09 +000093 ClangTidyContext(const ClangTidyOptions &Options);
Manuel Klimek814f9bd2013-11-14 15:49:44 +000094
95 /// \brief Report any errors detected using this method.
96 ///
97 /// This is still under heavy development and will likely change towards using
98 /// tablegen'd diagnostic IDs.
99 /// FIXME: Figure out a way to manage ID spaces.
Alexander Kornienko41bfe8d2014-01-13 10:50:51 +0000100 DiagnosticBuilder diag(StringRef CheckName, SourceLocation Loc,
Alexander Kornienko54461eb2014-02-06 14:50:10 +0000101 StringRef Message,
102 DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
Manuel Klimek814f9bd2013-11-14 15:49:44 +0000103
104 /// \brief Sets the \c DiagnosticsEngine so that Diagnostics can be generated
105 /// correctly.
106 ///
107 /// This is called from the \c ClangTidyCheck base class.
108 void setDiagnosticsEngine(DiagnosticsEngine *Engine);
109
110 /// \brief Sets the \c SourceManager of the used \c DiagnosticsEngine.
111 ///
112 /// This is called from the \c ClangTidyCheck base class.
113 void setSourceManager(SourceManager *SourceMgr);
114
Alexander Kornienko41bfe8d2014-01-13 10:50:51 +0000115 /// \brief Returns the name of the clang-tidy check which produced this
116 /// diagnostic ID.
117 StringRef getCheckName(unsigned DiagnosticID) const;
118
Alexander Kornienko09952d22014-03-20 09:38:22 +0000119 ChecksFilter &getChecksFilter() { return Filter; }
Alexander Kornienko9ff5b6f2014-05-05 14:54:47 +0000120 const ClangTidyOptions &getOptions() const { return Options; }
Alexander Kornienko5d174542014-05-07 09:06:53 +0000121 const ClangTidyStats &getStats() const { return Stats; }
Alexander Kornienko826b5ad2014-05-09 12:24:09 +0000122 const std::vector<ClangTidyError> &getErrors() const { return Errors; }
Alexander Kornienkoc0093602014-05-09 15:50:15 +0000123 void clearErrors() { Errors.clear(); }
Alexander Kornienko09952d22014-03-20 09:38:22 +0000124
Manuel Klimek814f9bd2013-11-14 15:49:44 +0000125private:
126 friend class ClangTidyDiagnosticConsumer; // Calls storeError().
127
128 /// \brief Store a \c ClangTidyError.
129 void storeError(const ClangTidyError &Error);
130
Alexander Kornienko826b5ad2014-05-09 12:24:09 +0000131 std::vector<ClangTidyError> Errors;
NAKAMURA Takumi338eee12014-03-20 10:53:03 +0000132 DiagnosticsEngine *DiagEngine;
Alexander Kornienko9ff5b6f2014-05-05 14:54:47 +0000133 ClangTidyOptions Options;
Alexander Kornienko09952d22014-03-20 09:38:22 +0000134 ChecksFilter Filter;
Alexander Kornienko5d174542014-05-07 09:06:53 +0000135 ClangTidyStats Stats;
Alexander Kornienko09952d22014-03-20 09:38:22 +0000136
Alexander Kornienko41bfe8d2014-01-13 10:50:51 +0000137 llvm::DenseMap<unsigned, std::string> CheckNamesByDiagnosticID;
Manuel Klimek814f9bd2013-11-14 15:49:44 +0000138};
139
Daniel Jasperd07c8402013-07-29 08:19:24 +0000140/// \brief A diagnostic consumer that turns each \c Diagnostic into a
141/// \c SourceManager-independent \c ClangTidyError.
142//
143// FIXME: If we move away from unit-tests, this can be moved to a private
144// implementation file.
145class ClangTidyDiagnosticConsumer : public DiagnosticConsumer {
146public:
Alexander Kornienko0ba86b72014-01-09 16:31:25 +0000147 ClangTidyDiagnosticConsumer(ClangTidyContext &Ctx);
Daniel Jasperd07c8402013-07-29 08:19:24 +0000148
149 // FIXME: The concept of converting between FixItHints and Replacements is
150 // more generic and should be pulled out into a more useful Diagnostics
151 // library.
Alexander Kornienkocb9272f2014-02-27 13:14:51 +0000152 void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
Craig Toppera3dbe842014-03-02 10:20:11 +0000153 const Diagnostic &Info) override;
Manuel Klimek814f9bd2013-11-14 15:49:44 +0000154
Alexander Kornienkofc589872014-01-03 15:34:40 +0000155 // Flushes the internal diagnostics buffer to the ClangTidyContext.
Craig Toppera3dbe842014-03-02 10:20:11 +0000156 void finish() override;
Daniel Jasperd07c8402013-07-29 08:19:24 +0000157
158private:
Alexander Kornienko54461eb2014-02-06 14:50:10 +0000159 void finalizeLastError();
Alexander Kornienko9ff5b6f2014-05-05 14:54:47 +0000160 bool relatesToUserCode(SourceLocation Location);
Manuel Klimek814f9bd2013-11-14 15:49:44 +0000161
Daniel Jasperd07c8402013-07-29 08:19:24 +0000162 ClangTidyContext &Context;
Alexander Kornienko9ff5b6f2014-05-05 14:54:47 +0000163 llvm::Regex HeaderFilter;
Ahmed Charles6a2dc5c2014-03-09 09:24:40 +0000164 std::unique_ptr<DiagnosticsEngine> Diags;
Manuel Klimek814f9bd2013-11-14 15:49:44 +0000165 SmallVector<ClangTidyError, 8> Errors;
Alexander Kornienko54461eb2014-02-06 14:50:10 +0000166 bool LastErrorRelatesToUserCode;
Daniel Jasperd07c8402013-07-29 08:19:24 +0000167};
168
169} // end namespace tidy
170} // end namespace clang
171
172#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_DIAGNOSTIC_CONSUMER_H