clang-tools  11.0.0
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  /// Sets the \c SourceManager of the used \c DiagnosticsEngine.
100  ///
101  /// This is called from the \c ClangTidyCheck base class.
102  void setSourceManager(SourceManager *SourceMgr);
103 
104  /// Should be called when starting to process new translation unit.
105  void setCurrentFile(StringRef File);
106 
107  /// Returns the main file name of the current translation unit.
108  StringRef getCurrentFile() const { return CurrentFile; }
109 
110  /// Sets ASTContext for the current translation unit.
111  void setASTContext(ASTContext *Context);
112 
113  /// Gets the language options from the AST context.
114  const LangOptions &getLangOpts() const { return LangOpts; }
115 
116  /// Returns the name of the clang-tidy check which produced this
117  /// diagnostic ID.
118  std::string getCheckName(unsigned DiagnosticID) const;
119 
120  /// Returns \c true if the check is enabled for the \c CurrentFile.
121  ///
122  /// The \c CurrentFile can be changed using \c setCurrentFile.
123  bool isCheckEnabled(StringRef CheckName) const;
124 
125  /// Returns \c true if the check should be upgraded to error for the
126  /// \c CurrentFile.
127  bool treatAsError(StringRef CheckName) const;
128 
129  /// Returns global options.
131 
132  /// Returns options for \c CurrentFile.
133  ///
134  /// The \c CurrentFile can be changed using \c setCurrentFile.
135  const ClangTidyOptions &getOptions() const;
136 
137  /// Returns options for \c File. Does not change or depend on
138  /// \c CurrentFile.
139  ClangTidyOptions getOptionsForFile(StringRef File) const;
140 
141  /// Returns \c ClangTidyStats containing issued and ignored diagnostic
142  /// counters.
143  const ClangTidyStats &getStats() const { return Stats; }
144 
145  /// Control profile collection in clang-tidy.
146  void setEnableProfiling(bool Profile);
147  bool getEnableProfiling() const { return Profile; }
148 
149  /// Control storage of profile date.
150  void setProfileStoragePrefix(StringRef ProfilePrefix);
151  llvm::Optional<ClangTidyProfiling::StorageParams>
152  getProfileStorageParams() const;
153 
154  /// Should be called when starting to process new translation unit.
155  void setCurrentBuildDirectory(StringRef BuildDirectory) {
156  CurrentBuildDirectory = std::string(BuildDirectory);
157  }
158 
159  /// Returns build directory of the current translation unit.
160  const std::string &getCurrentBuildDirectory() {
161  return CurrentBuildDirectory;
162  }
163 
164  /// If the experimental alpha checkers from the static analyzer can be
165  /// enabled.
167  return AllowEnablingAnalyzerAlphaCheckers;
168  }
169 
170  using DiagLevelAndFormatString = std::pair<DiagnosticIDs::Level, std::string>;
172  SourceLocation Loc) {
174  static_cast<DiagnosticIDs::Level>(
175  DiagEngine->getDiagnosticLevel(DiagnosticID, Loc)),
176  std::string(
177  DiagEngine->getDiagnosticIDs()->getDescription(DiagnosticID)));
178  }
179 
180 private:
181  // Writes to Stats.
183 
184  DiagnosticsEngine *DiagEngine;
185  std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider;
186 
187  std::string CurrentFile;
188  ClangTidyOptions CurrentOptions;
189  class CachedGlobList;
190  std::unique_ptr<CachedGlobList> CheckFilter;
191  std::unique_ptr<CachedGlobList> WarningAsErrorFilter;
192 
193  LangOptions LangOpts;
194 
195  ClangTidyStats Stats;
196 
197  std::string CurrentBuildDirectory;
198 
199  llvm::DenseMap<unsigned, std::string> CheckNamesByDiagnosticID;
200 
201  bool Profile;
202  std::string ProfilePrefix;
203 
205 };
206 
207 /// Check whether a given diagnostic should be suppressed due to the presence
208 /// of a "NOLINT" suppression comment.
209 /// This is exposed so that other tools that present clang-tidy diagnostics
210 /// (such as clangd) can respect the same suppression rules as clang-tidy.
211 /// This does not handle suppression of notes following a suppressed diagnostic;
212 /// that is left to the caller is it requires maintaining state in between calls
213 /// to this function.
214 /// If `AllowIO` is false, the function does not attempt to read source files
215 /// from disk which are not already mapped into memory; such files are treated
216 /// as not containing a suppression comment.
217 bool shouldSuppressDiagnostic(DiagnosticsEngine::Level DiagLevel,
218  const Diagnostic &Info, ClangTidyContext &Context,
219  bool AllowIO = true);
220 
221 /// 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  DiagnosticsEngine *ExternalDiagEngine = nullptr,
230  bool RemoveIncompatibleErrors = true);
231 
232  // FIXME: The concept of converting between FixItHints and Replacements is
233  // more generic and should be pulled out into a more useful Diagnostics
234  // library.
235  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
236  const Diagnostic &Info) override;
237 
238  // Retrieve the diagnostics that were captured.
239  std::vector<ClangTidyError> take();
240 
241 private:
242  void finalizeLastError();
243  void removeIncompatibleErrors();
244  void removeDuplicatedDiagnosticsOfAliasCheckers();
245 
246  /// Returns the \c HeaderFilter constructed for the options set in the
247  /// context.
248  llvm::Regex *getHeaderFilter();
249 
250  /// Updates \c LastErrorRelatesToUserCode and LastErrorPassesLineFilter
251  /// according to the diagnostic \p Location.
252  void checkFilters(SourceLocation Location, const SourceManager &Sources);
253  bool passesLineFilter(StringRef FileName, unsigned LineNumber) const;
254 
255  void forwardDiagnostic(const Diagnostic &Info);
256 
257  ClangTidyContext &Context;
258  DiagnosticsEngine *ExternalDiagEngine;
259  bool RemoveIncompatibleErrors;
260  std::vector<ClangTidyError> Errors;
261  std::unique_ptr<llvm::Regex> HeaderFilter;
262  bool LastErrorRelatesToUserCode;
263  bool LastErrorPassesLineFilter;
264  bool LastErrorWasIgnored;
265 };
266 
267 } // end namespace tidy
268 } // end namespace clang
269 
270 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYDIAGNOSTICCONSUMER_H
clang::tidy::ClangTidyStats::ClangTidyStats
ClangTidyStats()
Definition: ClangTidyDiagnosticConsumer.h:51
clang::tidy::ClangTidyContext::setCurrentBuildDirectory
void setCurrentBuildDirectory(StringRef BuildDirectory)
Should be called when starting to process new translation unit.
Definition: ClangTidyDiagnosticConsumer.h:155
clang::tidy::ClangTidyContext::setASTContext
void setASTContext(ASTContext *Context)
Sets ASTContext for the current translation unit.
Definition: ClangTidyDiagnosticConsumer.cpp:191
clang::tidy::ClangTidyDiagnosticConsumer::take
std::vector< ClangTidyError > take()
Definition: ClangTidyDiagnosticConsumer.cpp:729
clang::tidy::ClangTidyContext::getStats
const ClangTidyStats & getStats() const
Returns ClangTidyStats containing issued and ignored diagnostic counters.
Definition: ClangTidyDiagnosticConsumer.h:143
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:204
Location
Definition: Modularize.cpp:383
DiagnosticConsumer
clang::tidy::ClangTidyContext::DiagLevelAndFormatString
std::pair< DiagnosticIDs::Level, std::string > DiagLevelAndFormatString
Definition: ClangTidyDiagnosticConsumer.h:170
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:364
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:235
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:166
Ctx
Context Ctx
Definition: TUScheduler.cpp:324
clang::tidy::ClangTidyDiagnosticConsumer
A diagnostic consumer that turns each Diagnostic into a SourceManager-independent ClangTidyError.
Definition: ClangTidyDiagnosticConsumer.h:226
SourceMgr
llvm::SourceMgr * SourceMgr
Definition: ConfigCompile.cpp:72
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:179
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:71
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:378
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:183
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:196
clang::tidy::ClangTidyContext::getLangOpts
const LangOptions & getLangOpts() const
Gets the language options from the AST context.
Definition: ClangTidyDiagnosticConsumer.h:114
clang::tidy::ClangTidyContext::setEnableProfiling
void setEnableProfiling(bool Profile)
Control profile collection in clang-tidy.
Definition: ClangTidyDiagnosticConsumer.cpp:211
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:200
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:225
clang::tidy::ClangTidyContext::getDiagLevelAndFormatString
DiagLevelAndFormatString getDiagLevelAndFormatString(unsigned DiagnosticID, SourceLocation Loc)
Definition: ClangTidyDiagnosticConsumer.h:171
Info
FunctionInfo Info
Definition: FunctionSizeCheck.cpp:120
clang::tidy::ClangTidyContext::CachedGlobList
Definition: ClangTidyDiagnosticConsumer.cpp:133
clang::tidy::ClangTidyContext::ClangTidyContext
ClangTidyContext(std::unique_ptr< ClangTidyOptionsProvider > OptionsProvider, bool AllowEnablingAnalyzerAlphaCheckers=false)
Initializes ClangTidyContext instance.
Definition: ClangTidyDiagnosticConsumer.cpp:156
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::tidy::ClangTidyDiagnosticConsumer::ClangTidyDiagnosticConsumer
ClangTidyDiagnosticConsumer(ClangTidyContext &Ctx, DiagnosticsEngine *ExternalDiagEngine=nullptr, bool RemoveIncompatibleErrors=true)
Definition: ClangTidyDiagnosticConsumer.cpp:247
ClangTidyProfiling.h
clang::tidy::ClangTidyContext::getEnableProfiling
bool getEnableProfiling() const
Definition: ClangTidyDiagnosticConsumer.h:147
Loc
SourceLocation Loc
'#' location in the include directive
Definition: IncludeOrderCheck.cpp:37
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:169
clang::tidy::ClangTidyContext::getCurrentBuildDirectory
const std::string & getCurrentBuildDirectory()
Returns build directory of the current translation unit.
Definition: ClangTidyDiagnosticConsumer.h:160
ClangTidyOptions.h
clang::tidy::ClangTidyContext::getCurrentFile
StringRef getCurrentFile() const
Returns the main file name of the current translation unit.
Definition: ClangTidyDiagnosticConsumer.h:108
FileName
PathRef FileName
Definition: CodeComplete.cpp:1043
Warning
constexpr static llvm::SourceMgr::DiagKind Warning
Definition: ConfigCompile.cpp:212
clang::tidy::ClangTidyContext::getProfileStorageParams
llvm::Optional< ClangTidyProfiling::StorageParams > getProfileStorageParams() const
Definition: ClangTidyDiagnosticConsumer.cpp:218
clang::tidy::ClangTidyError::ClangTidyError
ClangTidyError(StringRef CheckName, Level DiagLevel, StringRef BuildDirectory, bool IsWarningAsError)
Definition: ClangTidyDiagnosticConsumer.cpp:127
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:230
clang::tidy::ClangTidyError::EnabledDiagnosticAliases
std::vector< std::string > EnabledDiagnosticAliases
Definition: ClangTidyDiagnosticConsumer.h:45
clang::tidy::ClangTidyContext::setProfileStoragePrefix
void setProfileStoragePrefix(StringRef ProfilePrefix)
Control storage of profile date.
Definition: ClangTidyDiagnosticConsumer.cpp:213