1111
1212#include " ClangTidyOptions.h"
1313#include " ClangTidyProfiling.h"
14+ #include " NoLintDirectiveHandler.h"
1415#include " clang/Basic/Diagnostic.h"
1516#include " clang/Tooling/Core/Diagnostic.h"
1617#include " llvm/ADT/DenseMap.h"
18+ #include " llvm/ADT/StringSet.h"
1719#include " llvm/Support/Regex.h"
1820
1921namespace clang {
2022
2123class ASTContext ;
22- class CompilerInstance ;
2324class SourceManager ;
24- namespace ast_matchers {
25- class MatchFinder ;
26- }
27- namespace tooling {
28- class CompilationDatabase ;
29- }
3025
3126namespace tidy {
27+ class CachedGlobList ;
3228
3329// / A detected error complete with information to display diagnostic and
3430// / automatic fix.
@@ -45,18 +41,13 @@ struct ClangTidyError : tooling::Diagnostic {
4541 std::vector<std::string> EnabledDiagnosticAliases;
4642};
4743
48- // / Contains displayed and ignored diagnostic counters for a ClangTidy
49- // / run.
44+ // / Contains displayed and ignored diagnostic counters for a ClangTidy run.
5045struct ClangTidyStats {
51- ClangTidyStats ()
52- : ErrorsDisplayed(0 ), ErrorsIgnoredCheckFilter(0 ), ErrorsIgnoredNOLINT(0 ),
53- ErrorsIgnoredNonUserCode (0 ), ErrorsIgnoredLineFilter(0 ) {}
54-
55- unsigned ErrorsDisplayed;
56- unsigned ErrorsIgnoredCheckFilter;
57- unsigned ErrorsIgnoredNOLINT;
58- unsigned ErrorsIgnoredNonUserCode;
59- unsigned ErrorsIgnoredLineFilter;
46+ unsigned ErrorsDisplayed = 0 ;
47+ unsigned ErrorsIgnoredCheckFilter = 0 ;
48+ unsigned ErrorsIgnoredNOLINT = 0 ;
49+ unsigned ErrorsIgnoredNonUserCode = 0 ;
50+ unsigned ErrorsIgnoredLineFilter = 0 ;
6051
6152 unsigned errorsIgnored () const {
6253 return ErrorsIgnoredNOLINT + ErrorsIgnoredCheckFilter +
@@ -99,11 +90,33 @@ class ClangTidyContext {
9990 DiagnosticBuilder diag (StringRef CheckName, StringRef Message,
10091 DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
10192
93+ DiagnosticBuilder diag (const tooling::Diagnostic &Error);
94+
10295 // / Report any errors to do with reading the configuration using this method.
10396 DiagnosticBuilder
10497 configurationDiag (StringRef Message,
10598 DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
10699
100+ // / Check whether a given diagnostic should be suppressed due to the presence
101+ // / of a "NOLINT" suppression comment.
102+ // / This is exposed so that other tools that present clang-tidy diagnostics
103+ // / (such as clangd) can respect the same suppression rules as clang-tidy.
104+ // / This does not handle suppression of notes following a suppressed
105+ // / diagnostic; that is left to the caller as it requires maintaining state in
106+ // / between calls to this function.
107+ // / If any NOLINT is malformed, e.g. a BEGIN without a subsequent END, output
108+ // / \param NoLintErrors will return an error about it.
109+ // / If \param AllowIO is false, the function does not attempt to read source
110+ // / files from disk which are not already mapped into memory; such files are
111+ // / treated as not containing a suppression comment.
112+ // / \param EnableNoLintBlocks controls whether to honor NOLINTBEGIN/NOLINTEND
113+ // / blocks; if false, only considers line-level disabling.
114+ bool
115+ shouldSuppressDiagnostic (DiagnosticsEngine::Level DiagLevel,
116+ const Diagnostic &Info,
117+ SmallVectorImpl<tooling::Diagnostic> &NoLintErrors,
118+ bool AllowIO = true , bool EnableNoLintBlocks = true );
119+
107120 // / Sets the \c SourceManager of the used \c DiagnosticsEngine.
108121 // /
109122 // / This is called from the \c ClangTidyCheck base class.
@@ -165,7 +178,7 @@ class ClangTidyContext {
165178 }
166179
167180 // / Returns build directory of the current translation unit.
168- const std::string &getCurrentBuildDirectory () {
181+ const std::string &getCurrentBuildDirectory () const {
169182 return CurrentBuildDirectory;
170183 }
171184
@@ -175,6 +188,10 @@ class ClangTidyContext {
175188 return AllowEnablingAnalyzerAlphaCheckers;
176189 }
177190
191+ void setSelfContainedDiags (bool Value) { SelfContainedDiags = Value; }
192+
193+ bool areDiagsSelfContained () const { return SelfContainedDiags; }
194+
178195 using DiagLevelAndFormatString = std::pair<DiagnosticIDs::Level, std::string>;
179196 DiagLevelAndFormatString getDiagLevelAndFormatString (unsigned DiagnosticID,
180197 SourceLocation Loc) {
@@ -185,6 +202,11 @@ class ClangTidyContext {
185202 DiagEngine->getDiagnosticIDs ()->getDescription (DiagnosticID)));
186203 }
187204
205+ void setOptionsCollector (llvm::StringSet<> *Collector) {
206+ OptionsCollector = Collector;
207+ }
208+ llvm::StringSet<> *getOptionsCollector () const { return OptionsCollector; }
209+
188210private:
189211 // Writes to Stats.
190212 friend class ClangTidyDiagnosticConsumer ;
@@ -194,7 +216,7 @@ class ClangTidyContext {
194216
195217 std::string CurrentFile;
196218 ClangTidyOptions CurrentOptions;
197- class CachedGlobList ;
219+
198220 std::unique_ptr<CachedGlobList> CheckFilter;
199221 std::unique_ptr<CachedGlobList> WarningAsErrorFilter;
200222
@@ -210,21 +232,12 @@ class ClangTidyContext {
210232 std::string ProfilePrefix;
211233
212234 bool AllowEnablingAnalyzerAlphaCheckers;
213- };
214235
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 );
236+ bool SelfContainedDiags;
237+
238+ NoLintDirectiveHandler NoLintHandler;
239+ llvm::StringSet<> *OptionsCollector = nullptr ;
240+ };
228241
229242// / Gets the Fix attached to \p Diagnostic.
230243// / If there isn't a Fix attached to the diagnostic and \p AnyFix is true, Check
@@ -235,15 +248,17 @@ getFixIt(const tooling::Diagnostic &Diagnostic, bool AnyFix);
235248
236249// / A diagnostic consumer that turns each \c Diagnostic into a
237250// / \c SourceManager-independent \c ClangTidyError.
238- //
239251// FIXME: If we move away from unit-tests, this can be moved to a private
240252// implementation file.
241253class ClangTidyDiagnosticConsumer : public DiagnosticConsumer {
242254public:
255+ // / \param EnableNolintBlocks Enables diagnostic-disabling inside blocks of
256+ // / code, delimited by NOLINTBEGIN and NOLINTEND.
243257 ClangTidyDiagnosticConsumer (ClangTidyContext &Ctx,
244258 DiagnosticsEngine *ExternalDiagEngine = nullptr ,
245259 bool RemoveIncompatibleErrors = true ,
246- bool GetFixesFromNotes = false );
260+ bool GetFixesFromNotes = false ,
261+ bool EnableNolintBlocks = true );
247262
248263 // FIXME: The concept of converting between FixItHints and Replacements is
249264 // more generic and should be pulled out into a more useful Diagnostics
@@ -274,6 +289,7 @@ class ClangTidyDiagnosticConsumer : public DiagnosticConsumer {
274289 DiagnosticsEngine *ExternalDiagEngine;
275290 bool RemoveIncompatibleErrors;
276291 bool GetFixesFromNotes;
292+ bool EnableNolintBlocks;
277293 std::vector<ClangTidyError> Errors;
278294 std::unique_ptr<llvm::Regex> HeaderFilter;
279295 bool LastErrorRelatesToUserCode;
0 commit comments