clang-tools  3.9.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  StringRef BuildDirectory);
62 
63  std::string CheckName;
65  tooling::Replacements Fix;
66  SmallVector<ClangTidyMessage, 1> Notes;
67 
68  // A build directory of the diagnostic source file.
69  //
70  // It's an absolute path which is `directory` field of the source file in
71  // compilation database. If users don't specify the compilation database
72  // directory, it is the current directory where clang-tidy runs.
73  //
74  // Note: it is empty in unittest.
75  std::string BuildDirectory;
76 
79 };
80 
81 /// \brief Read-only set of strings represented as a list of positive and
82 /// negative globs. Positive globs add all matched strings to the set, negative
83 /// globs remove them in the order of appearance in the list.
84 class GlobList {
85 public:
86  /// \brief \p GlobList is a comma-separated list of globs (only '*'
87  /// metacharacter is supported) with optional '-' prefix to denote exclusion.
88  GlobList(StringRef Globs);
89 
90  /// \brief Returns \c true if the pattern matches \p S. The result is the last
91  /// matching glob's Positive flag.
92  bool contains(StringRef S) { return contains(S, false); }
93 
94 private:
95  bool contains(StringRef S, bool Contains);
96 
97  bool Positive;
98  llvm::Regex Regex;
99  std::unique_ptr<GlobList> NextGlob;
100 };
101 
102 /// \brief Contains displayed and ignored diagnostic counters for a ClangTidy
103 /// run.
108 
109  unsigned ErrorsDisplayed;
114 
115  unsigned errorsIgnored() const {
118  }
119 };
120 
121 /// \brief Container for clang-tidy profiling data.
122 struct ProfileData {
123  llvm::StringMap<llvm::TimeRecord> Records;
124 };
125 
126 /// \brief Every \c ClangTidyCheck reports errors through a \c DiagnosticsEngine
127 /// provided by this context.
128 ///
129 /// A \c ClangTidyCheck always has access to the active context to report
130 /// warnings like:
131 /// \code
132 /// Context->Diag(Loc, "Single-argument constructors must be explicit")
133 /// << FixItHint::CreateInsertion(Loc, "explicit ");
134 /// \endcode
136 public:
137  /// \brief Initializes \c ClangTidyContext instance.
138  ClangTidyContext(std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider);
139 
140  /// \brief Report any errors detected using this method.
141  ///
142  /// This is still under heavy development and will likely change towards using
143  /// tablegen'd diagnostic IDs.
144  /// FIXME: Figure out a way to manage ID spaces.
145  DiagnosticBuilder diag(StringRef CheckName, SourceLocation Loc,
146  StringRef Message,
147  DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
148 
149  /// \brief Sets the \c SourceManager of the used \c DiagnosticsEngine.
150  ///
151  /// This is called from the \c ClangTidyCheck base class.
152  void setSourceManager(SourceManager *SourceMgr);
153 
154  /// \brief Should be called when starting to process new translation unit.
155  void setCurrentFile(StringRef File);
156 
157  /// \brief Returns the main file name of the current translation unit.
158  StringRef getCurrentFile() const { return CurrentFile; }
159 
160  /// \brief Sets ASTContext for the current translation unit.
161  void setASTContext(ASTContext *Context);
162 
163  /// \brief Gets the language options from the AST context.
164  const LangOptions &getLangOpts() const { return LangOpts; }
165 
166  /// \brief Returns the name of the clang-tidy check which produced this
167  /// diagnostic ID.
168  StringRef getCheckName(unsigned DiagnosticID) const;
169 
170  /// \brief Returns check filter for the \c CurrentFile.
171  ///
172  /// The \c CurrentFile can be changed using \c setCurrentFile.
174 
175  /// \brief Returns check filter for the \c CurrentFile which
176  /// selects checks for upgrade to error.
178 
179  /// \brief Returns global options.
181 
182  /// \brief Returns options for \c CurrentFile.
183  ///
184  /// The \c CurrentFile can be changed using \c setCurrentFile.
185  const ClangTidyOptions &getOptions() const;
186 
187  /// \brief Returns options for \c File. Does not change or depend on
188  /// \c CurrentFile.
189  ClangTidyOptions getOptionsForFile(StringRef File) const;
190 
191  /// \brief Returns \c ClangTidyStats containing issued and ignored diagnostic
192  /// counters.
193  const ClangTidyStats &getStats() const { return Stats; }
194 
195  /// \brief Returns all collected errors.
196  const std::vector<ClangTidyError> &getErrors() const { return Errors; }
197 
198  /// \brief Clears collected errors.
199  void clearErrors() { Errors.clear(); }
200 
201  /// \brief Set the output struct for profile data.
202  ///
203  /// Setting a non-null pointer here will enable profile collection in
204  /// clang-tidy.
205  void setCheckProfileData(ProfileData *Profile);
206  ProfileData *getCheckProfileData() const { return Profile; }
207 
208  /// \brief Should be called when starting to process new translation unit.
209  void setCurrentBuildDirectory(StringRef BuildDirectory) {
210  CurrentBuildDirectory = BuildDirectory;
211  }
212 
213  /// \brief Returns build directory of the current translation unit.
214  const std::string &getCurrentBuildDirectory() {
215  return CurrentBuildDirectory;
216  }
217 
218 private:
219  // Calls setDiagnosticsEngine() and storeError().
221  friend class ClangTidyPluginAction;
222 
223  /// \brief Sets the \c DiagnosticsEngine so that Diagnostics can be generated
224  /// correctly.
225  void setDiagnosticsEngine(DiagnosticsEngine *Engine);
226 
227  /// \brief Store an \p Error.
228  void storeError(const ClangTidyError &Error);
229 
230  std::vector<ClangTidyError> Errors;
231  DiagnosticsEngine *DiagEngine;
232  std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider;
233 
234  std::string CurrentFile;
235  ClangTidyOptions CurrentOptions;
236  std::unique_ptr<GlobList> CheckFilter;
237  std::unique_ptr<GlobList> WarningAsErrorFilter;
238 
239  LangOptions LangOpts;
240 
241  ClangTidyStats Stats;
242 
243  std::string CurrentBuildDirectory;
244 
245  llvm::DenseMap<unsigned, std::string> CheckNamesByDiagnosticID;
246 
247  ProfileData *Profile;
248 };
249 
250 /// \brief A diagnostic consumer that turns each \c Diagnostic into a
251 /// \c SourceManager-independent \c ClangTidyError.
252 //
253 // FIXME: If we move away from unit-tests, this can be moved to a private
254 // implementation file.
256 public:
258 
259  // FIXME: The concept of converting between FixItHints and Replacements is
260  // more generic and should be pulled out into a more useful Diagnostics
261  // library.
262  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
263  const Diagnostic &Info) override;
264 
265  /// \brief Flushes the internal diagnostics buffer to the ClangTidyContext.
266  void finish() override;
267 
268 private:
269  void finalizeLastError();
270 
271  void removeIncompatibleErrors(SmallVectorImpl<ClangTidyError> &Errors) const;
272 
273  /// \brief Returns the \c HeaderFilter constructed for the options set in the
274  /// context.
275  llvm::Regex *getHeaderFilter();
276 
277  /// \brief Updates \c LastErrorRelatesToUserCode and LastErrorPassesLineFilter
278  /// according to the diagnostic \p Location.
279  void checkFilters(SourceLocation Location);
280  bool passesLineFilter(StringRef FileName, unsigned LineNumber) const;
281 
282  ClangTidyContext &Context;
283  std::unique_ptr<DiagnosticsEngine> Diags;
284  SmallVector<ClangTidyError, 8> Errors;
285  std::unique_ptr<llvm::Regex> HeaderFilter;
286  bool LastErrorRelatesToUserCode;
287  bool LastErrorPassesLineFilter;
288 };
289 
290 } // end namespace tidy
291 } // end namespace clang
292 
293 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYDIAGNOSTICCONSUMER_H
SourceLocation Loc
'#' location in the include directive
LangOptions LangOpts
Definition: ClangTidy.cpp:189
ClangTidyError(StringRef CheckName, Level DiagLevel, bool IsWarningAsError, StringRef BuildDirectory)
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:193
SmallVector< ClangTidyMessage, 1 > Notes
ClangTidyOptions getOptionsForFile(StringRef File) const
Returns options for File.
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...
GlobList & getWarningAsErrorFilter()
Returns check filter for the CurrentFile which selects checks for upgrade to error.
const ClangTidyGlobalOptions & getGlobalOptions() const
Returns global options.
const LangOptions & getLangOpts() const
Gets the language options from the AST context.
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.
The core clang tidy plugin action.
void setCurrentBuildDirectory(StringRef BuildDirectory)
Should be called when starting to process new translation unit.
void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) override
GlobList & getChecksFilter()
Returns check filter for the CurrentFile.
Container for clang-tidy profiling data.
const std::string & getCurrentBuildDirectory()
Returns build directory of the current translation unit.