clang-tools  8.0.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 "ClangTidyProfiling.h"
15 #include "clang/Basic/Diagnostic.h"
16 #include "clang/Basic/SourceManager.h"
17 #include "clang/Tooling/Core/Diagnostic.h"
18 #include "clang/Tooling/Refactoring.h"
19 #include "llvm/ADT/DenseMap.h"
20 #include "llvm/ADT/StringMap.h"
21 #include "llvm/Support/Regex.h"
22 #include "llvm/Support/Timer.h"
23 
24 namespace clang {
25 
26 class ASTContext;
27 class CompilerInstance;
28 namespace ast_matchers {
29 class MatchFinder;
30 }
31 namespace tooling {
32 class CompilationDatabase;
33 }
34 
35 namespace tidy {
36 
37 /// \brief A detected error complete with information to display diagnostic and
38 /// automatic fix.
39 ///
40 /// This is used as an intermediate format to transport Diagnostics without a
41 /// dependency on a SourceManager.
42 ///
43 /// FIXME: Make Diagnostics flexible enough to support this directly.
44 struct ClangTidyError : tooling::Diagnostic {
45  ClangTidyError(StringRef CheckName, Level DiagLevel, StringRef BuildDirectory,
46  bool IsWarningAsError);
47 
49 };
50 
51 /// \brief Read-only set of strings represented as a list of positive and
52 /// negative globs. Positive globs add all matched strings to the set, negative
53 /// globs remove them in the order of appearance in the list.
54 class GlobList {
55 public:
56  /// \brief \p GlobList is a comma-separated list of globs (only '*'
57  /// metacharacter is supported) with optional '-' prefix to denote exclusion.
58  GlobList(StringRef Globs);
59 
60  /// \brief Returns \c true if the pattern matches \p S. The result is the last
61  /// matching glob's Positive flag.
62  bool contains(StringRef S) { return contains(S, false); }
63 
64 private:
65  bool contains(StringRef S, bool Contains);
66 
67  bool Positive;
68  llvm::Regex Regex;
69  std::unique_ptr<GlobList> NextGlob;
70 };
71 
72 /// \brief Contains displayed and ignored diagnostic counters for a ClangTidy
73 /// run.
76  : ErrorsDisplayed(0), ErrorsIgnoredCheckFilter(0), ErrorsIgnoredNOLINT(0),
77  ErrorsIgnoredNonUserCode(0), ErrorsIgnoredLineFilter(0) {}
78 
79  unsigned ErrorsDisplayed;
84 
85  unsigned errorsIgnored() const {
86  return ErrorsIgnoredNOLINT + ErrorsIgnoredCheckFilter +
87  ErrorsIgnoredNonUserCode + ErrorsIgnoredLineFilter;
88  }
89 };
90 
91 /// \brief Every \c ClangTidyCheck reports errors through a \c DiagnosticsEngine
92 /// provided by this context.
93 ///
94 /// A \c ClangTidyCheck always has access to the active context to report
95 /// warnings like:
96 /// \code
97 /// Context->Diag(Loc, "Single-argument constructors must be explicit")
98 /// << FixItHint::CreateInsertion(Loc, "explicit ");
99 /// \endcode
101 public:
102  /// \brief Initializes \c ClangTidyContext instance.
103  ClangTidyContext(std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider,
105  /// Sets the DiagnosticsEngine that diag() will emit diagnostics to.
106  // FIXME: this is required initialization, and should be a constructor param.
107  // Fix the context -> diag engine -> consumer -> context initialization cycle.
108  void setDiagnosticsEngine(DiagnosticsEngine *DiagEngine) {
109  this->DiagEngine = DiagEngine;
110  }
111 
112  ~ClangTidyContext();
113 
114  /// \brief Report any errors detected using this method.
115  ///
116  /// This is still under heavy development and will likely change towards using
117  /// tablegen'd diagnostic IDs.
118  /// FIXME: Figure out a way to manage ID spaces.
119  DiagnosticBuilder diag(StringRef CheckName, SourceLocation Loc,
120  StringRef Message,
121  DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
122 
123  /// \brief Sets the \c SourceManager of the used \c DiagnosticsEngine.
124  ///
125  /// This is called from the \c ClangTidyCheck base class.
126  void setSourceManager(SourceManager *SourceMgr);
127 
128  /// \brief Should be called when starting to process new translation unit.
129  void setCurrentFile(StringRef File);
130 
131  /// \brief Returns the main file name of the current translation unit.
132  StringRef getCurrentFile() const { return CurrentFile; }
133 
134  /// \brief Sets ASTContext for the current translation unit.
135  void setASTContext(ASTContext *Context);
136 
137  /// \brief Gets the language options from the AST context.
138  const LangOptions &getLangOpts() const { return LangOpts; }
139 
140  /// \brief Returns the name of the clang-tidy check which produced this
141  /// diagnostic ID.
142  StringRef getCheckName(unsigned DiagnosticID) const;
143 
144  /// \brief Returns \c true if the check is enabled for the \c CurrentFile.
145  ///
146  /// The \c CurrentFile can be changed using \c setCurrentFile.
147  bool isCheckEnabled(StringRef CheckName) const;
148 
149  /// \brief Returns \c true if the check should be upgraded to error for the
150  /// \c CurrentFile.
151  bool treatAsError(StringRef CheckName) const;
152 
153  /// \brief Returns global options.
154  const ClangTidyGlobalOptions &getGlobalOptions() const;
155 
156  /// \brief Returns options for \c CurrentFile.
157  ///
158  /// The \c CurrentFile can be changed using \c setCurrentFile.
159  const ClangTidyOptions &getOptions() const;
160 
161  /// \brief Returns options for \c File. Does not change or depend on
162  /// \c CurrentFile.
163  ClangTidyOptions getOptionsForFile(StringRef File) const;
164 
165  /// \brief Returns \c ClangTidyStats containing issued and ignored diagnostic
166  /// counters.
167  const ClangTidyStats &getStats() const { return Stats; }
168 
169  /// \brief Control profile collection in clang-tidy.
170  void setEnableProfiling(bool Profile);
171  bool getEnableProfiling() const { return Profile; }
172 
173  /// \brief Control storage of profile date.
174  void setProfileStoragePrefix(StringRef ProfilePrefix);
175  llvm::Optional<ClangTidyProfiling::StorageParams>
176  getProfileStorageParams() const;
177 
178  /// \brief Should be called when starting to process new translation unit.
179  void setCurrentBuildDirectory(StringRef BuildDirectory) {
180  CurrentBuildDirectory = BuildDirectory;
181  }
182 
183  /// \brief Returns build directory of the current translation unit.
184  const std::string &getCurrentBuildDirectory() {
185  return CurrentBuildDirectory;
186  }
187 
188  /// \brief If the experimental alpha checkers from the static analyzer can be
189  /// enabled.
192  }
193 
194 private:
195  // Writes to Stats.
197 
198  DiagnosticsEngine *DiagEngine;
199  std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider;
200 
201  std::string CurrentFile;
202  ClangTidyOptions CurrentOptions;
203  class CachedGlobList;
204  std::unique_ptr<CachedGlobList> CheckFilter;
205  std::unique_ptr<CachedGlobList> WarningAsErrorFilter;
206 
207  LangOptions LangOpts;
208 
209  ClangTidyStats Stats;
210 
211  std::string CurrentBuildDirectory;
212 
213  llvm::DenseMap<unsigned, std::string> CheckNamesByDiagnosticID;
214 
215  bool Profile;
216  std::string ProfilePrefix;
217 
219 };
220 
221 /// \brief A diagnostic consumer that turns each \c Diagnostic into a
222 /// \c SourceManager-independent \c ClangTidyError.
223 //
224 // FIXME: If we move away from unit-tests, this can be moved to a private
225 // implementation file.
227 public:
229  bool RemoveIncompatibleErrors = true);
230 
231  // FIXME: The concept of converting between FixItHints and Replacements is
232  // more generic and should be pulled out into a more useful Diagnostics
233  // library.
234  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
235  const Diagnostic &Info) override;
236 
237  // Retrieve the diagnostics that were captured.
238  std::vector<ClangTidyError> take();
239 
240 private:
241  void finalizeLastError();
242  void removeIncompatibleErrors();
243 
244  /// \brief Returns the \c HeaderFilter constructed for the options set in the
245  /// context.
246  llvm::Regex *getHeaderFilter();
247 
248  /// \brief Updates \c LastErrorRelatesToUserCode and LastErrorPassesLineFilter
249  /// according to the diagnostic \p Location.
250  void checkFilters(SourceLocation Location, const SourceManager& Sources);
251  bool passesLineFilter(StringRef FileName, unsigned LineNumber) const;
252 
253  ClangTidyContext &Context;
254  bool RemoveIncompatibleErrors;
255  std::vector<ClangTidyError> Errors;
256  std::unique_ptr<llvm::Regex> HeaderFilter;
257  bool LastErrorRelatesToUserCode;
258  bool LastErrorPassesLineFilter;
259  bool LastErrorWasIgnored;
260 };
261 
262 } // end namespace tidy
263 } // end namespace clang
264 
265 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYDIAGNOSTICCONSUMER_H
SourceLocation Loc
&#39;#&#39; location in the include directive
bool canEnableAnalyzerAlphaCheckers() const
If the experimental alpha checkers from the static analyzer can be enabled.
Read-only set of strings represented as a list of positive and negative globs.
static cl::opt< std::string > HeaderFilter("header-filter", cl::desc(R"( Regular expression matching the names of the headers to output diagnostics from. Diagnostics from the main file of each translation unit are always displayed. Can be used together with -line-filter. This option overrides the 'HeaderFilter' option in .clang-tidy file, if any. )"), cl::init(""), cl::cat(ClangTidyCategory))
bool contains(StringRef S)
Returns true if the pattern matches S.
Contains options for clang-tidy.
Context Ctx
static cl::opt< bool > AllowEnablingAnalyzerAlphaCheckers("allow-enabling-analyzer-alpha-checkers", cl::init(false), cl::Hidden, cl::cat(ClangTidyCategory))
This option allows enabling the experimental alpha checkers from the static analyzer.
const LangOptions & getLangOpts() const
Gets the language options from the AST context.
StringRef getCurrentFile() const
Returns the main file name of the current translation unit.
A diagnostic consumer that turns each Diagnostic into a SourceManager-independent ClangTidyError...
PathRef FileName
FunctionInfo Info
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
void setDiagnosticsEngine(DiagnosticsEngine *DiagEngine)
Sets the DiagnosticsEngine that diag() will emit diagnostics to.
A detected error complete with information to display diagnostic and automatic fix.
Contains displayed and ignored diagnostic counters for a ClangTidy run.
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
const ClangTidyStats & getStats() const
Returns ClangTidyStats containing issued and ignored diagnostic counters.
void setCurrentBuildDirectory(StringRef BuildDirectory)
Should be called when starting to process new translation unit.
const std::string & getCurrentBuildDirectory()
Returns build directory of the current translation unit.