clang-tools  3.8.0
ClangTidyDiagnosticConsumer.h
Go to the documentation of this file.
1 //===--- 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_CLANGTIDYDIAGNOSTICCONSUMER_H
11 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYDIAGNOSTICCONSUMER_H
12 
13 #include "ClangTidyOptions.h"
14 #include "clang/Basic/Diagnostic.h"
15 #include "clang/Basic/SourceManager.h"
16 #include "clang/Tooling/Refactoring.h"
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/ADT/StringMap.h"
19 #include "llvm/Support/Regex.h"
20 #include "llvm/Support/Timer.h"
21 
22 namespace clang {
23 
24 class ASTContext;
25 class CompilerInstance;
26 namespace ast_matchers {
27 class MatchFinder;
28 }
29 namespace tooling {
30 class CompilationDatabase;
31 }
32 
33 namespace tidy {
34 
35 /// \brief A message from a clang-tidy check.
36 ///
37 /// Note that this is independent of a \c SourceManager.
39  ClangTidyMessage(StringRef Message = "");
40  ClangTidyMessage(StringRef Message, const SourceManager &Sources,
41  SourceLocation Loc);
42  std::string Message;
43  std::string FilePath;
44  unsigned FileOffset;
45 };
46 
47 /// \brief A detected error complete with information to display diagnostic and
48 /// automatic fix.
49 ///
50 /// This is used as an intermediate format to transport Diagnostics without a
51 /// dependency on a SourceManager.
52 ///
53 /// FIXME: Make Diagnostics flexible enough to support this directly.
55  enum Level {
56  Warning = DiagnosticsEngine::Warning,
57  Error = DiagnosticsEngine::Error
58  };
59 
61 
62  std::string CheckName;
64  tooling::Replacements Fix;
65  SmallVector<ClangTidyMessage, 1> Notes;
66 
68 };
69 
70 /// \brief Read-only set of strings represented as a list of positive and
71 /// negative globs. Positive globs add all matched strings to the set, negative
72 /// globs remove them in the order of appearance in the list.
73 class GlobList {
74 public:
75  /// \brief \p GlobList is a comma-separated list of globs (only '*'
76  /// metacharacter is supported) with optional '-' prefix to denote exclusion.
77  GlobList(StringRef Globs);
78 
79  /// \brief Returns \c true if the pattern matches \p S. The result is the last
80  /// matching glob's Positive flag.
81  bool contains(StringRef S) { return contains(S, false); }
82 
83 private:
84  bool contains(StringRef S, bool Contains);
85 
86  bool Positive;
87  llvm::Regex Regex;
88  std::unique_ptr<GlobList> NextGlob;
89 };
90 
91 /// \brief Contains displayed and ignored diagnostic counters for a ClangTidy
92 /// run.
97 
98  unsigned ErrorsDisplayed;
103 
104  unsigned errorsIgnored() const {
107  }
108 };
109 
110 /// \brief Container for clang-tidy profiling data.
111 struct ProfileData {
112  llvm::StringMap<llvm::TimeRecord> Records;
113 };
114 
115 /// \brief Every \c ClangTidyCheck reports errors through a \c DiagnosticsEngine
116 /// provided by this context.
117 ///
118 /// A \c ClangTidyCheck always has access to the active context to report
119 /// warnings like:
120 /// \code
121 /// Context->Diag(Loc, "Single-argument constructors must be explicit")
122 /// << FixItHint::CreateInsertion(Loc, "explicit ");
123 /// \endcode
125 public:
126  /// \brief Initializes \c ClangTidyContext instance.
127  ClangTidyContext(std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider);
128 
129  /// \brief Report any errors detected using this method.
130  ///
131  /// This is still under heavy development and will likely change towards using
132  /// tablegen'd diagnostic IDs.
133  /// FIXME: Figure out a way to manage ID spaces.
134  DiagnosticBuilder diag(StringRef CheckName, SourceLocation Loc,
135  StringRef Message,
136  DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
137 
138  /// \brief Sets the \c SourceManager of the used \c DiagnosticsEngine.
139  ///
140  /// This is called from the \c ClangTidyCheck base class.
141  void setSourceManager(SourceManager *SourceMgr);
142 
143  /// \brief Should be called when starting to process new translation unit.
144  void setCurrentFile(StringRef File);
145 
146  /// \brief Returns the main file name of the current translation unit.
147  StringRef getCurrentFile() const { return CurrentFile; }
148 
149  /// \brief Sets ASTContext for the current translation unit.
150  void setASTContext(ASTContext *Context);
151 
152  /// \brief Gets the language options from the AST context.
153  LangOptions getLangOpts() const { return LangOpts; }
154 
155  /// \brief Returns the name of the clang-tidy check which produced this
156  /// diagnostic ID.
157  StringRef getCheckName(unsigned DiagnosticID) const;
158 
159  /// \brief Returns check filter for the \c CurrentFile.
160  ///
161  /// The \c CurrentFile can be changed using \c setCurrentFile.
163 
164  /// \brief Returns true if the check name is enabled for the \c CurrentFile.
165  bool isCheckEnabled(StringRef CheckName) const;
166 
167  /// \brief Returns global options.
169 
170  /// \brief Returns options for \c CurrentFile.
171  ///
172  /// The \c CurrentFile can be changed using \c setCurrentFile.
173  const ClangTidyOptions &getOptions() const;
174 
175  /// \brief Returns options for \c File. Does not change or depend on
176  /// \c CurrentFile.
177  ClangTidyOptions getOptionsForFile(StringRef File) const;
178 
179  /// \brief Returns \c ClangTidyStats containing issued and ignored diagnostic
180  /// counters.
181  const ClangTidyStats &getStats() const { return Stats; }
182 
183  /// \brief Returns all collected errors.
184  const std::vector<ClangTidyError> &getErrors() const { return Errors; }
185 
186  /// \brief Clears collected errors.
187  void clearErrors() { Errors.clear(); }
188 
189  /// \brief Set the output struct for profile data.
190  ///
191  /// Setting a non-null pointer here will enable profile collection in
192  /// clang-tidy.
193  void setCheckProfileData(ProfileData *Profile);
194  ProfileData *getCheckProfileData() const { return Profile; }
195 
196 private:
197  // Calls setDiagnosticsEngine() and storeError().
199 
200  /// \brief Sets the \c DiagnosticsEngine so that Diagnostics can be generated
201  /// correctly.
202  void setDiagnosticsEngine(DiagnosticsEngine *Engine);
203 
204  /// \brief Store an \p Error.
205  void storeError(const ClangTidyError &Error);
206 
207  std::vector<ClangTidyError> Errors;
208  DiagnosticsEngine *DiagEngine;
209  std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider;
210 
211  std::string CurrentFile;
212  ClangTidyOptions CurrentOptions;
213  std::unique_ptr<GlobList> CheckFilter;
214 
215  LangOptions LangOpts;
216 
217  ClangTidyStats Stats;
218 
219  llvm::DenseMap<unsigned, std::string> CheckNamesByDiagnosticID;
220 
221  ProfileData *Profile;
222 };
223 
224 /// \brief A diagnostic consumer that turns each \c Diagnostic into a
225 /// \c SourceManager-independent \c ClangTidyError.
226 //
227 // FIXME: If we move away from unit-tests, this can be moved to a private
228 // implementation file.
230 public:
232 
233  // FIXME: The concept of converting between FixItHints and Replacements is
234  // more generic and should be pulled out into a more useful Diagnostics
235  // library.
236  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
237  const Diagnostic &Info) override;
238 
239  /// \brief Flushes the internal diagnostics buffer to the ClangTidyContext.
240  void finish() override;
241 
242 private:
243  void finalizeLastError();
244 
245  void removeIncompatibleErrors(SmallVectorImpl<ClangTidyError> &Errors) const;
246 
247  /// \brief Returns the \c HeaderFilter constructed for the options set in the
248  /// context.
249  llvm::Regex *getHeaderFilter();
250 
251  /// \brief Updates \c LastErrorRelatesToUserCode and LastErrorPassesLineFilter
252  /// according to the diagnostic \p Location.
253  void checkFilters(SourceLocation Location);
254  bool passesLineFilter(StringRef FileName, unsigned LineNumber) const;
255 
256  ClangTidyContext &Context;
257  std::unique_ptr<DiagnosticsEngine> Diags;
258  SmallVector<ClangTidyError, 8> Errors;
259  std::unique_ptr<llvm::Regex> HeaderFilter;
260  bool LastErrorRelatesToUserCode;
261  bool LastErrorPassesLineFilter;
262 };
263 
264 } // end namespace tidy
265 } // end namespace clang
266 
267 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYDIAGNOSTICCONSUMER_H
SourceLocation Loc
'#' location in the include directive
LangOptions LangOpts
Definition: ClangTidy.cpp:168
Read-only set of strings represented as a list of positive and negative globs.
GlobList(StringRef Globs)
GlobList is a comma-separated list of globs (only '*' metacharacter is supported) with optional '-' p...
HeaderHandle File
void finish() override
Flushes the internal diagnostics buffer to the ClangTidyContext.
bool contains(StringRef S)
Returns true if the pattern matches S.
A message from a clang-tidy check.
Contains options for clang-tidy.
llvm::StringMap< llvm::TimeRecord > Records
StringRef getCurrentFile() const
Returns the main file name of the current translation unit.
const std::vector< ClangTidyError > & getErrors() const
Returns all collected errors.
SourceManager SourceMgr
Definition: ClangTidy.cpp:172
SmallVector< ClangTidyMessage, 1 > Notes
ClangTidyOptions getOptionsForFile(StringRef File) const
Returns options for File.
LangOptions getLangOpts() const
Gets the language options from the AST context.
void setCurrentFile(StringRef File)
Should be called when starting to process new translation unit.
const ClangTidyOptions & getOptions() const
Returns options for CurrentFile.
DiagnosticBuilder diag(StringRef CheckName, SourceLocation Loc, StringRef Message, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Report any errors detected using this method.
void setCheckProfileData(ProfileData *Profile)
Set the output struct for profile data.
ClangTidyContext(std::unique_ptr< ClangTidyOptionsProvider > OptionsProvider)
Initializes ClangTidyContext instance.
void setASTContext(ASTContext *Context)
Sets ASTContext for the current translation unit.
A diagnostic consumer that turns each Diagnostic into a SourceManager-independent ClangTidyError...
ClangTidyError(StringRef CheckName, Level DiagLevel)
const ClangTidyGlobalOptions & getGlobalOptions() const
Returns global options.
void setSourceManager(SourceManager *SourceMgr)
Sets the SourceManager of the used DiagnosticsEngine.
void clearErrors()
Clears collected errors.
const ClangTidyStats & getStats() const
Returns ClangTidyStats containing issued and ignored diagnostic counters.
StringRef getCheckName(unsigned DiagnosticID) const
Returns the name of the clang-tidy check which produced this diagnostic ID.
A detected error complete with information to display diagnostic and automatic fix.
Contains displayed and ignored diagnostic counters for a ClangTidy run.
ClangTidyContext & Context
Definition: ClangTidy.cpp:93
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) override
bool isCheckEnabled(StringRef CheckName) const
Returns true if the check name is enabled for the CurrentFile.
GlobList & getChecksFilter()
Returns check filter for the CurrentFile.
Container for clang-tidy profiling data.