clang-tools  14.0.0git
ClangTidyDiagnosticConsumer.h
Go to the documentation of this file.
1 //===--- ClangTidyDiagnosticConsumer.h - clang-tidy -------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYDIAGNOSTICCONSUMER_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYDIAGNOSTICCONSUMER_H
11 
12 #include "ClangTidyOptions.h"
13 #include "ClangTidyProfiling.h"
14 #include "clang/Basic/Diagnostic.h"
15 #include "clang/Tooling/Core/Diagnostic.h"
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/Support/Regex.h"
18 
19 namespace clang {
20 
21 class ASTContext;
22 class CompilerInstance;
23 class SourceManager;
24 namespace ast_matchers {
25 class MatchFinder;
26 }
27 namespace tooling {
28 class CompilationDatabase;
29 }
30 
31 namespace tidy {
32 
33 /// A detected error complete with information to display diagnostic and
34 /// automatic fix.
35 ///
36 /// This is used as an intermediate format to transport Diagnostics without a
37 /// dependency on a SourceManager.
38 ///
39 /// FIXME: Make Diagnostics flexible enough to support this directly.
41  ClangTidyError(StringRef CheckName, Level DiagLevel, StringRef BuildDirectory,
42  bool IsWarningAsError);
43 
45  std::vector<std::string> EnabledDiagnosticAliases;
46 };
47 
48 /// Contains displayed and ignored diagnostic counters for a ClangTidy
49 /// run.
54 
55  unsigned ErrorsDisplayed;
60 
61  unsigned errorsIgnored() const {
64  }
65 };
66 
67 /// Every \c ClangTidyCheck reports errors through a \c DiagnosticsEngine
68 /// provided by this context.
69 ///
70 /// A \c ClangTidyCheck always has access to the active context to report
71 /// warnings like:
72 /// \code
73 /// Context->Diag(Loc, "Single-argument constructors must be explicit")
74 /// << FixItHint::CreateInsertion(Loc, "explicit ");
75 /// \endcode
77 public:
78  /// Initializes \c ClangTidyContext instance.
79  ClangTidyContext(std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider,
80  bool AllowEnablingAnalyzerAlphaCheckers = false);
81  /// Sets the DiagnosticsEngine that diag() will emit diagnostics to.
82  // FIXME: this is required initialization, and should be a constructor param.
83  // Fix the context -> diag engine -> consumer -> context initialization cycle.
84  void setDiagnosticsEngine(DiagnosticsEngine *DiagEngine) {
85  this->DiagEngine = DiagEngine;
86  }
87 
89 
90  /// Report any errors detected using this method.
91  ///
92  /// This is still under heavy development and will likely change towards using
93  /// tablegen'd diagnostic IDs.
94  /// FIXME: Figure out a way to manage ID spaces.
95  DiagnosticBuilder diag(StringRef CheckName, SourceLocation Loc,
96  StringRef Message,
97  DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
98 
99  DiagnosticBuilder diag(StringRef CheckName, StringRef Message,
100  DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
101 
102  /// Report any errors to do with reading the configuration using this method.
103  DiagnosticBuilder
104  configurationDiag(StringRef Message,
105  DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
106 
107  /// Sets the \c SourceManager of the used \c DiagnosticsEngine.
108  ///
109  /// This is called from the \c ClangTidyCheck base class.
110  void setSourceManager(SourceManager *SourceMgr);
111 
112  /// Should be called when starting to process new translation unit.
113  void setCurrentFile(StringRef File);
114 
115  /// Returns the main file name of the current translation unit.
116  StringRef getCurrentFile() const { return CurrentFile; }
117 
118  /// Sets ASTContext for the current translation unit.
119  void setASTContext(ASTContext *Context);
120 
121  /// Gets the language options from the AST context.
122  const LangOptions &getLangOpts() const { return LangOpts; }
123 
124  /// Returns the name of the clang-tidy check which produced this
125  /// diagnostic ID.
126  std::string getCheckName(unsigned DiagnosticID) const;
127 
128  /// Returns \c true if the check is enabled for the \c CurrentFile.
129  ///
130  /// The \c CurrentFile can be changed using \c setCurrentFile.
131  bool isCheckEnabled(StringRef CheckName) const;
132 
133  /// Returns \c true if the check should be upgraded to error for the
134  /// \c CurrentFile.
135  bool treatAsError(StringRef CheckName) const;
136 
137  /// Returns global options.
139 
140  /// Returns options for \c CurrentFile.
141  ///
142  /// The \c CurrentFile can be changed using \c setCurrentFile.
143  const ClangTidyOptions &getOptions() const;
144 
145  /// Returns options for \c File. Does not change or depend on
146  /// \c CurrentFile.
147  ClangTidyOptions getOptionsForFile(StringRef File) const;
148 
149  /// Returns \c ClangTidyStats containing issued and ignored diagnostic
150  /// counters.
151  const ClangTidyStats &getStats() const { return Stats; }
152 
153  /// Control profile collection in clang-tidy.
154  void setEnableProfiling(bool Profile);
155  bool getEnableProfiling() const { return Profile; }
156 
157  /// Control storage of profile date.
158  void setProfileStoragePrefix(StringRef ProfilePrefix);
159  llvm::Optional<ClangTidyProfiling::StorageParams>
160  getProfileStorageParams() const;
161 
162  /// Should be called when starting to process new translation unit.
163  void setCurrentBuildDirectory(StringRef BuildDirectory) {
164  CurrentBuildDirectory = std::string(BuildDirectory);
165  }
166 
167  /// Returns build directory of the current translation unit.
168  const std::string &getCurrentBuildDirectory() {
169  return CurrentBuildDirectory;
170  }
171 
172  /// If the experimental alpha checkers from the static analyzer can be
173  /// enabled.
175  return AllowEnablingAnalyzerAlphaCheckers;
176  }
177 
178  using DiagLevelAndFormatString = std::pair<DiagnosticIDs::Level, std::string>;
180  SourceLocation Loc) {
182  static_cast<DiagnosticIDs::Level>(
183  DiagEngine->getDiagnosticLevel(DiagnosticID, Loc)),
184  std::string(
185  DiagEngine->getDiagnosticIDs()->getDescription(DiagnosticID)));
186  }
187 
188 private:
189  // Writes to Stats.
191 
192  DiagnosticsEngine *DiagEngine;
193  std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider;
194 
195  std::string CurrentFile;
196  ClangTidyOptions CurrentOptions;
197  class CachedGlobList;
198  std::unique_ptr<CachedGlobList> CheckFilter;
199  std::unique_ptr<CachedGlobList> WarningAsErrorFilter;
200 
201  LangOptions LangOpts;
202 
203  ClangTidyStats Stats;
204 
205  std::string CurrentBuildDirectory;
206 
207  llvm::DenseMap<unsigned, std::string> CheckNamesByDiagnosticID;
208 
209  bool Profile;
210  std::string ProfilePrefix;
211 
213 };
214 
215 /// Check whether a given diagnostic should be suppressed due to the presence
216 /// of a "NOLINT" suppression comment.
217 /// This is exposed so that other tools that present clang-tidy diagnostics
218 /// (such as clangd) can respect the same suppression rules as clang-tidy.
219 /// This does not handle suppression of notes following a suppressed diagnostic;
220 /// that is left to the caller is it requires maintaining state in between calls
221 /// to this function.
222 /// If `AllowIO` is false, the function does not attempt to read source files
223 /// from disk which are not already mapped into memory; such files are treated
224 /// as not containing a suppression comment.
225 bool shouldSuppressDiagnostic(DiagnosticsEngine::Level DiagLevel,
226  const Diagnostic &Info, ClangTidyContext &Context,
227  bool AllowIO = true);
228 
229 /// Gets the Fix attached to \p Diagnostic.
230 /// If there isn't a Fix attached to the diagnostic and \p AnyFix is true, Check
231 /// to see if exactly one note has a Fix and return it. Otherwise return
232 /// nullptr.
233 const llvm::StringMap<tooling::Replacements> *
234 getFixIt(const tooling::Diagnostic &Diagnostic, bool AnyFix);
235 
236 /// A diagnostic consumer that turns each \c Diagnostic into a
237 /// \c SourceManager-independent \c ClangTidyError.
238 //
239 // FIXME: If we move away from unit-tests, this can be moved to a private
240 // implementation file.
242 public:
244  DiagnosticsEngine *ExternalDiagEngine = nullptr,
245  bool RemoveIncompatibleErrors = true,
246  bool GetFixesFromNotes = false);
247 
248  // FIXME: The concept of converting between FixItHints and Replacements is
249  // more generic and should be pulled out into a more useful Diagnostics
250  // library.
251  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
252  const Diagnostic &Info) override;
253 
254  // Retrieve the diagnostics that were captured.
255  std::vector<ClangTidyError> take();
256 
257 private:
258  void finalizeLastError();
259  void removeIncompatibleErrors();
260  void removeDuplicatedDiagnosticsOfAliasCheckers();
261 
262  /// Returns the \c HeaderFilter constructed for the options set in the
263  /// context.
264  llvm::Regex *getHeaderFilter();
265 
266  /// Updates \c LastErrorRelatesToUserCode and LastErrorPassesLineFilter
267  /// according to the diagnostic \p Location.
268  void checkFilters(SourceLocation Location, const SourceManager &Sources);
269  bool passesLineFilter(StringRef FileName, unsigned LineNumber) const;
270 
271  void forwardDiagnostic(const Diagnostic &Info);
272 
273  ClangTidyContext &Context;
274  DiagnosticsEngine *ExternalDiagEngine;
275  bool RemoveIncompatibleErrors;
276  bool GetFixesFromNotes;
277  std::vector<ClangTidyError> Errors;
278  std::unique_ptr<llvm::Regex> HeaderFilter;
279  bool LastErrorRelatesToUserCode;
280  bool LastErrorPassesLineFilter;
281  bool LastErrorWasIgnored;
282 };
283 
284 } // end namespace tidy
285 } // end namespace clang
286 
287 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYDIAGNOSTICCONSUMER_H
clang::tidy::ClangTidyStats::ClangTidyStats
ClangTidyStats()
Definition: ClangTidyDiagnosticConsumer.h:51
Loc
SourceLocation Loc
Definition: KernelNameRestrictionCheck.cpp:45
clang::tidy::ClangTidyContext::setCurrentBuildDirectory
void setCurrentBuildDirectory(StringRef BuildDirectory)
Should be called when starting to process new translation unit.
Definition: ClangTidyDiagnosticConsumer.h:163
clang::tidy::ClangTidyDiagnosticConsumer::ClangTidyDiagnosticConsumer
ClangTidyDiagnosticConsumer(ClangTidyContext &Ctx, DiagnosticsEngine *ExternalDiagEngine=nullptr, bool RemoveIncompatibleErrors=true, bool GetFixesFromNotes=false)
Definition: ClangTidyDiagnosticConsumer.cpp:279
clang::tidy::ClangTidyContext::setASTContext
void setASTContext(ASTContext *Context)
Sets ASTContext for the current translation unit.
Definition: ClangTidyDiagnosticConsumer.cpp:223
clang::tidy::ClangTidyDiagnosticConsumer::take
std::vector< ClangTidyError > take()
Definition: ClangTidyDiagnosticConsumer.cpp:787
clang::tidy::ClangTidyContext::getStats
const ClangTidyStats & getStats() const
Returns ClangTidyStats containing issued and ignored diagnostic counters.
Definition: ClangTidyDiagnosticConsumer.h:151
clang::tidy::ClangTidyStats::ErrorsIgnoredCheckFilter
unsigned ErrorsIgnoredCheckFilter
Definition: ClangTidyDiagnosticConsumer.h:56
clang::tidy::ClangTidyContext::getOptionsForFile
ClangTidyOptions getOptionsForFile(StringRef File) const
Returns options for File.
Definition: ClangTidyDiagnosticConsumer.cpp:236
Location
Definition: Modularize.cpp:382
DiagnosticConsumer
clang::tidy::ClangTidyContext::DiagLevelAndFormatString
std::pair< DiagnosticIDs::Level, std::string > DiagLevelAndFormatString
Definition: ClangTidyDiagnosticConsumer.h:178
clang::tidy::ClangTidyStats
Contains displayed and ignored diagnostic counters for a ClangTidy run.
Definition: ClangTidyDiagnosticConsumer.h:50
clang::tidy::shouldSuppressDiagnostic
bool shouldSuppressDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info, ClangTidyContext &Context, bool AllowIO)
Check whether a given diagnostic should be suppressed due to the presence of a "NOLINT" suppression c...
Definition: ClangTidyDiagnosticConsumer.cpp:384
clang::tidy::ClangTidyContext::getCheckName
std::string getCheckName(unsigned DiagnosticID) const
Returns the name of the clang-tidy check which produced this diagnostic ID.
Definition: ClangTidyDiagnosticConsumer.cpp:267
clang::tidy::bugprone::Message
static const char Message[]
Definition: ReservedIdentifierCheck.cpp:31
clang::tidy::ClangTidyContext::canEnableAnalyzerAlphaCheckers
bool canEnableAnalyzerAlphaCheckers() const
If the experimental alpha checkers from the static analyzer can be enabled.
Definition: ClangTidyDiagnosticConsumer.h:174
Ctx
Context Ctx
Definition: TUScheduler.cpp:454
clang::tidy::ClangTidyDiagnosticConsumer
A diagnostic consumer that turns each Diagnostic into a SourceManager-independent ClangTidyError.
Definition: ClangTidyDiagnosticConsumer.h:241
SourceMgr
llvm::SourceMgr * SourceMgr
Definition: ConfigCompile.cpp:102
clang::tidy::ClangTidyOptions
Contains options for clang-tidy.
Definition: ClangTidyOptions.h:50
clang::tidy::ClangTidyContext::setDiagnosticsEngine
void setDiagnosticsEngine(DiagnosticsEngine *DiagEngine)
Sets the DiagnosticsEngine that diag() will emit diagnostics to.
Definition: ClangTidyDiagnosticConsumer.h:84
clang::tidy::ClangTidyContext::setSourceManager
void setSourceManager(SourceManager *SourceMgr)
Sets the SourceManager of the used DiagnosticsEngine.
Definition: ClangTidyDiagnosticConsumer.cpp:211
AllowEnablingAnalyzerAlphaCheckers
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.
clang::tidy::ClangTidyError
A detected error complete with information to display diagnostic and automatic fix.
Definition: ClangTidyDiagnosticConsumer.h:40
Diagnostic
DiagnosticCallback Diagnostic
Definition: ConfigCompile.cpp:101
clang::tidy::ClangTidyStats::ErrorsIgnoredNOLINT
unsigned ErrorsIgnoredNOLINT
Definition: ClangTidyDiagnosticConsumer.h:57
clang::tidy::ClangTidyDiagnosticConsumer::HandleDiagnostic
void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) override
Definition: ClangTidyDiagnosticConsumer.cpp:416
clang::tidy::ClangTidyStats::errorsIgnored
unsigned errorsIgnored() const
Definition: ClangTidyDiagnosticConsumer.h:61
clang::tidy::ClangTidyError::IsWarningAsError
bool IsWarningAsError
Definition: ClangTidyDiagnosticConsumer.h:44
clang::tidy::ClangTidyContext::setCurrentFile
void setCurrentFile(StringRef File)
Should be called when starting to process new translation unit.
Definition: ClangTidyDiagnosticConsumer.cpp:215
clang::tidy::ClangTidyContext
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
Definition: ClangTidyDiagnosticConsumer.h:76
clang::tidy::ClangTidyContext::getGlobalOptions
const ClangTidyGlobalOptions & getGlobalOptions() const
Returns global options.
Definition: ClangTidyDiagnosticConsumer.cpp:228
clang::tidy::ClangTidyContext::getLangOpts
const LangOptions & getLangOpts() const
Gets the language options from the AST context.
Definition: ClangTidyDiagnosticConsumer.h:122
clang::tidy::ClangTidyContext::setEnableProfiling
void setEnableProfiling(bool Profile)
Control profile collection in clang-tidy.
Definition: ClangTidyDiagnosticConsumer.cpp:243
FileName
StringRef FileName
Definition: KernelNameRestrictionCheck.cpp:46
clang::tidy::ClangTidyStats::ErrorsIgnoredLineFilter
unsigned ErrorsIgnoredLineFilter
Definition: ClangTidyDiagnosticConsumer.h:59
clang::tidy::ClangTidyStats::ErrorsIgnoredNonUserCode
unsigned ErrorsIgnoredNonUserCode
Definition: ClangTidyDiagnosticConsumer.h:58
clang::tidy::ClangTidyGlobalOptions
Global options.
Definition: ClangTidyOptions.h:42
clang::tidy::ClangTidyContext::getOptions
const ClangTidyOptions & getOptions() const
Returns options for CurrentFile.
Definition: ClangTidyDiagnosticConsumer.cpp:232
clang::tidy::ClangTidyStats::ErrorsDisplayed
unsigned ErrorsDisplayed
Definition: ClangTidyDiagnosticConsumer.h:55
clang::tidy::ClangTidyContext::~ClangTidyContext
~ClangTidyContext()
clang::tidy::ClangTidyContext::isCheckEnabled
bool isCheckEnabled(StringRef CheckName) const
Returns true if the check is enabled for the CurrentFile.
Definition: ClangTidyDiagnosticConsumer.cpp:257
clang::tidy::ClangTidyContext::getDiagLevelAndFormatString
DiagLevelAndFormatString getDiagLevelAndFormatString(unsigned DiagnosticID, SourceLocation Loc)
Definition: ClangTidyDiagnosticConsumer.h:179
Info
FunctionInfo Info
Definition: FunctionSizeCheck.cpp:120
clang::tidy::ClangTidyContext::CachedGlobList
Definition: ClangTidyDiagnosticConsumer.cpp:150
clang::tidy::ClangTidyContext::ClangTidyContext
ClangTidyContext(std::unique_ptr< ClangTidyOptionsProvider > OptionsProvider, bool AllowEnablingAnalyzerAlphaCheckers=false)
Initializes ClangTidyContext instance.
Definition: ClangTidyDiagnosticConsumer.cpp:173
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
ClangTidyProfiling.h
clang::tidy::ClangTidyContext::getEnableProfiling
bool getEnableProfiling() const
Definition: ClangTidyDiagnosticConsumer.h:155
clang::tidy::getFixIt
const llvm::StringMap< tooling::Replacements > * getFixIt(const tooling::Diagnostic &Diagnostic, bool GetFixFromNotes)
Gets the Fix attached to Diagnostic.
Definition: ClangTidyDiagnosticConsumer.cpp:396
clang::tidy::ClangTidyContext::diag
DiagnosticBuilder diag(StringRef CheckName, SourceLocation Loc, StringRef Message, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Report any errors detected using this method.
Definition: ClangTidyDiagnosticConsumer.cpp:186
clang::tidy::ClangTidyContext::getCurrentBuildDirectory
const std::string & getCurrentBuildDirectory()
Returns build directory of the current translation unit.
Definition: ClangTidyDiagnosticConsumer.h:168
ClangTidyOptions.h
clang::tidy::ClangTidyContext::getCurrentFile
StringRef getCurrentFile() const
Returns the main file name of the current translation unit.
Definition: ClangTidyDiagnosticConsumer.h:116
Warning
constexpr static llvm::SourceMgr::DiagKind Warning
Definition: ConfigCompile.cpp:501
clang::tidy::ClangTidyContext::getProfileStorageParams
llvm::Optional< ClangTidyProfiling::StorageParams > getProfileStorageParams() const
Definition: ClangTidyDiagnosticConsumer.cpp:250
clang::tidy::ClangTidyError::ClangTidyError
ClangTidyError(StringRef CheckName, Level DiagLevel, StringRef BuildDirectory, bool IsWarningAsError)
Definition: ClangTidyDiagnosticConsumer.cpp:144
clang::tidy::ClangTidyContext::treatAsError
bool treatAsError(StringRef CheckName) const
Returns true if the check should be upgraded to error for the CurrentFile.
Definition: ClangTidyDiagnosticConsumer.cpp:262
clang::tidy::ClangTidyError::EnabledDiagnosticAliases
std::vector< std::string > EnabledDiagnosticAliases
Definition: ClangTidyDiagnosticConsumer.h:45
clang::tidy::ClangTidyContext::configurationDiag
DiagnosticBuilder configurationDiag(StringRef Message, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Report any errors to do with reading the configuration using this method.
Definition: ClangTidyDiagnosticConsumer.cpp:205
clang::tidy::ClangTidyContext::setProfileStoragePrefix
void setProfileStoragePrefix(StringRef ProfilePrefix)
Control storage of profile date.
Definition: ClangTidyDiagnosticConsumer.cpp:245