File indexing completed on 2026-05-10 08:36:23
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYDIAGNOSTICCONSUMER_H
0010 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYDIAGNOSTICCONSUMER_H
0011
0012 #include "ClangTidyOptions.h"
0013 #include "ClangTidyProfiling.h"
0014 #include "FileExtensionsSet.h"
0015 #include "NoLintDirectiveHandler.h"
0016 #include "clang/Basic/Diagnostic.h"
0017 #include "clang/Tooling/Core/Diagnostic.h"
0018 #include "llvm/ADT/DenseMap.h"
0019 #include "llvm/ADT/StringSet.h"
0020 #include "llvm/Support/Regex.h"
0021 #include <optional>
0022
0023 namespace clang {
0024
0025 class ASTContext;
0026 class SourceManager;
0027
0028 namespace tidy {
0029 class CachedGlobList;
0030
0031
0032
0033
0034
0035
0036
0037
0038 struct ClangTidyError : tooling::Diagnostic {
0039 ClangTidyError(StringRef CheckName, Level DiagLevel, StringRef BuildDirectory,
0040 bool IsWarningAsError);
0041
0042 bool IsWarningAsError;
0043 std::vector<std::string> EnabledDiagnosticAliases;
0044 };
0045
0046
0047 struct ClangTidyStats {
0048 unsigned ErrorsDisplayed = 0;
0049 unsigned ErrorsIgnoredCheckFilter = 0;
0050 unsigned ErrorsIgnoredNOLINT = 0;
0051 unsigned ErrorsIgnoredNonUserCode = 0;
0052 unsigned ErrorsIgnoredLineFilter = 0;
0053
0054 unsigned errorsIgnored() const {
0055 return ErrorsIgnoredNOLINT + ErrorsIgnoredCheckFilter +
0056 ErrorsIgnoredNonUserCode + ErrorsIgnoredLineFilter;
0057 }
0058 };
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 class ClangTidyContext {
0070 public:
0071
0072 ClangTidyContext(std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider,
0073 bool AllowEnablingAnalyzerAlphaCheckers = false,
0074 bool EnableModuleHeadersParsing = false);
0075
0076
0077
0078 void setDiagnosticsEngine(DiagnosticsEngine *DiagEngine) {
0079 this->DiagEngine = DiagEngine;
0080 }
0081
0082 ~ClangTidyContext();
0083
0084 ClangTidyContext(const ClangTidyContext &) = delete;
0085 ClangTidyContext &operator=(const ClangTidyContext &) = delete;
0086
0087
0088
0089
0090
0091
0092 DiagnosticBuilder diag(StringRef CheckName, SourceLocation Loc,
0093 StringRef Description,
0094 DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
0095
0096 DiagnosticBuilder diag(StringRef CheckName, StringRef Description,
0097 DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
0098
0099 DiagnosticBuilder diag(const tooling::Diagnostic &Error);
0100
0101
0102 DiagnosticBuilder
0103 configurationDiag(StringRef Message,
0104 DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120 bool
0121 shouldSuppressDiagnostic(DiagnosticsEngine::Level DiagLevel,
0122 const Diagnostic &Info,
0123 SmallVectorImpl<tooling::Diagnostic> &NoLintErrors,
0124 bool AllowIO = true, bool EnableNoLintBlocks = true);
0125
0126
0127
0128
0129 void setSourceManager(SourceManager *SourceMgr);
0130
0131
0132 void setCurrentFile(StringRef File);
0133
0134
0135 StringRef getCurrentFile() const { return CurrentFile; }
0136
0137
0138 void setASTContext(ASTContext *Context);
0139
0140
0141 const LangOptions &getLangOpts() const { return LangOpts; }
0142
0143
0144
0145 std::string getCheckName(unsigned DiagnosticID) const;
0146
0147
0148
0149
0150 bool isCheckEnabled(StringRef CheckName) const;
0151
0152
0153
0154 bool treatAsError(StringRef CheckName) const;
0155
0156
0157 const ClangTidyGlobalOptions &getGlobalOptions() const;
0158
0159
0160
0161
0162 const ClangTidyOptions &getOptions() const;
0163
0164
0165
0166 ClangTidyOptions getOptionsForFile(StringRef File) const;
0167
0168 const FileExtensionsSet &getHeaderFileExtensions() const {
0169 return HeaderFileExtensions;
0170 }
0171
0172 const FileExtensionsSet &getImplementationFileExtensions() const {
0173 return ImplementationFileExtensions;
0174 }
0175
0176
0177
0178 const ClangTidyStats &getStats() const { return Stats; }
0179
0180
0181 void setEnableProfiling(bool Profile);
0182 bool getEnableProfiling() const { return Profile; }
0183
0184
0185 void setProfileStoragePrefix(StringRef ProfilePrefix);
0186 std::optional<ClangTidyProfiling::StorageParams>
0187 getProfileStorageParams() const;
0188
0189
0190 void setCurrentBuildDirectory(StringRef BuildDirectory) {
0191 CurrentBuildDirectory = std::string(BuildDirectory);
0192 }
0193
0194
0195 const std::string &getCurrentBuildDirectory() const {
0196 return CurrentBuildDirectory;
0197 }
0198
0199
0200
0201 bool canEnableAnalyzerAlphaCheckers() const {
0202 return AllowEnablingAnalyzerAlphaCheckers;
0203 }
0204
0205
0206
0207 bool canEnableModuleHeadersParsing() const {
0208 return EnableModuleHeadersParsing;
0209 }
0210
0211 void setSelfContainedDiags(bool Value) { SelfContainedDiags = Value; }
0212
0213 bool areDiagsSelfContained() const { return SelfContainedDiags; }
0214
0215 using DiagLevelAndFormatString = std::pair<DiagnosticIDs::Level, std::string>;
0216 DiagLevelAndFormatString getDiagLevelAndFormatString(unsigned DiagnosticID,
0217 SourceLocation Loc) {
0218 return {
0219 static_cast<DiagnosticIDs::Level>(
0220 DiagEngine->getDiagnosticLevel(DiagnosticID, Loc)),
0221 std::string(
0222 DiagEngine->getDiagnosticIDs()->getDescription(DiagnosticID))};
0223 }
0224
0225 void setOptionsCollector(llvm::StringSet<> *Collector) {
0226 OptionsCollector = Collector;
0227 }
0228 llvm::StringSet<> *getOptionsCollector() const { return OptionsCollector; }
0229
0230 private:
0231
0232 friend class ClangTidyDiagnosticConsumer;
0233
0234 DiagnosticsEngine *DiagEngine = nullptr;
0235 std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider;
0236
0237 std::string CurrentFile;
0238 ClangTidyOptions CurrentOptions;
0239
0240 std::unique_ptr<CachedGlobList> CheckFilter;
0241 std::unique_ptr<CachedGlobList> WarningAsErrorFilter;
0242
0243 FileExtensionsSet HeaderFileExtensions;
0244 FileExtensionsSet ImplementationFileExtensions;
0245
0246 LangOptions LangOpts;
0247
0248 ClangTidyStats Stats;
0249
0250 std::string CurrentBuildDirectory;
0251
0252 llvm::DenseMap<unsigned, std::string> CheckNamesByDiagnosticID;
0253
0254 bool Profile = false;
0255 std::string ProfilePrefix;
0256
0257 bool AllowEnablingAnalyzerAlphaCheckers;
0258 bool EnableModuleHeadersParsing;
0259
0260 bool SelfContainedDiags = false;
0261
0262 NoLintDirectiveHandler NoLintHandler;
0263 llvm::StringSet<> *OptionsCollector = nullptr;
0264 };
0265
0266
0267
0268
0269
0270 const llvm::StringMap<tooling::Replacements> *
0271 getFixIt(const tooling::Diagnostic &Diagnostic, bool AnyFix);
0272
0273
0274
0275
0276
0277 class ClangTidyDiagnosticConsumer : public DiagnosticConsumer {
0278 public:
0279
0280
0281 ClangTidyDiagnosticConsumer(ClangTidyContext &Ctx,
0282 DiagnosticsEngine *ExternalDiagEngine = nullptr,
0283 bool RemoveIncompatibleErrors = true,
0284 bool GetFixesFromNotes = false,
0285 bool EnableNolintBlocks = true);
0286
0287
0288
0289
0290 void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
0291 const Diagnostic &Info) override;
0292
0293
0294 std::vector<ClangTidyError> take();
0295
0296 private:
0297 void finalizeLastError();
0298 void removeIncompatibleErrors();
0299 void removeDuplicatedDiagnosticsOfAliasCheckers();
0300
0301
0302
0303 llvm::Regex *getHeaderFilter();
0304
0305
0306
0307 llvm::Regex *getExcludeHeaderFilter();
0308
0309
0310
0311 void checkFilters(SourceLocation Location, const SourceManager &Sources);
0312 bool passesLineFilter(StringRef FileName, unsigned LineNumber) const;
0313
0314 void forwardDiagnostic(const Diagnostic &Info);
0315
0316 ClangTidyContext &Context;
0317 DiagnosticsEngine *ExternalDiagEngine;
0318 bool RemoveIncompatibleErrors;
0319 bool GetFixesFromNotes;
0320 bool EnableNolintBlocks;
0321 std::vector<ClangTidyError> Errors;
0322 std::unique_ptr<llvm::Regex> HeaderFilter;
0323 std::unique_ptr<llvm::Regex> ExcludeHeaderFilter;
0324 bool LastErrorRelatesToUserCode = false;
0325 bool LastErrorPassesLineFilter = false;
0326 bool LastErrorWasIgnored = false;
0327 };
0328
0329 }
0330 }
0331
0332 #endif