clang-tools 22.0.0git
ClangTidyOptions.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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#include "ClangTidyOptions.h"
11#include "clang/Basic/DiagnosticIDs.h"
12#include "clang/Basic/LLVM.h"
13#include "llvm/ADT/SmallString.h"
14#include "llvm/ADT/StringExtras.h"
15#include "llvm/Support/Debug.h"
16#include "llvm/Support/ErrorOr.h"
17#include "llvm/Support/MemoryBufferRef.h"
18#include "llvm/Support/Path.h"
19#include "llvm/Support/YAMLTraits.h"
20#include <algorithm>
21#include <optional>
22#include <utility>
23
24#define DEBUG_TYPE "clang-tidy-options"
25
29
30LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(FileFilter)
31LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(FileFilter::LineRange)
32
33namespace llvm::yaml {
34
35// Map std::pair<int, int> to a JSON array of size 2.
36template <> struct SequenceTraits<FileFilter::LineRange> {
37 static size_t size(IO &IO, FileFilter::LineRange &Range) {
38 return Range.first == 0 ? 0 : Range.second == 0 ? 1 : 2;
39 }
40 static unsigned &element(IO &IO, FileFilter::LineRange &Range, size_t Index) {
41 if (Index > 1)
42 IO.setError("Too many elements in line range.");
43 return Index == 0 ? Range.first : Range.second;
44 }
45};
46
47template <> struct MappingTraits<FileFilter> {
48 static void mapping(IO &IO, FileFilter &File) {
49 IO.mapRequired("name", File.Name);
50 IO.mapOptional("lines", File.LineRanges);
51 }
52 static std::string validate(IO &Io, FileFilter &File) {
53 if (File.Name.empty())
54 return "No file name specified";
55 for (const FileFilter::LineRange &Range : File.LineRanges) {
56 if (Range.first <= 0 || Range.second <= 0)
57 return "Invalid line range";
58 }
59 return "";
60 }
61};
62
63template <> struct MappingTraits<ClangTidyOptions::StringPair> {
64 static void mapping(IO &IO, ClangTidyOptions::StringPair &KeyValue) {
65 IO.mapRequired("key", KeyValue.first);
66 IO.mapRequired("value", KeyValue.second);
67 }
68};
69
70struct NOptionMap {
71 NOptionMap(IO &) {}
72 NOptionMap(IO &, const ClangTidyOptions::OptionMap &OptionMap) {
73 Options.reserve(OptionMap.size());
74 for (const auto &KeyValue : OptionMap)
75 Options.emplace_back(std::string(KeyValue.getKey()),
76 KeyValue.getValue().Value);
77 }
80 for (const auto &KeyValue : Options)
81 Map[KeyValue.first] = ClangTidyOptions::ClangTidyValue(KeyValue.second);
82 return Map;
83 }
84 std::vector<ClangTidyOptions::StringPair> Options;
85};
86
87template <>
88void yamlize(IO &IO, ClangTidyOptions::OptionMap &Val, bool,
89 EmptyContext &Ctx) {
90 if (IO.outputting()) {
91 // Ensure check options are sorted
92 std::vector<std::pair<StringRef, StringRef>> SortedOptions;
93 SortedOptions.reserve(Val.size());
94 for (auto &Key : Val) {
95 SortedOptions.emplace_back(Key.getKey(), Key.getValue().Value);
96 }
97 std::sort(SortedOptions.begin(), SortedOptions.end());
98
99 IO.beginMapping();
100 // Only output as a map
101 for (auto &Option : SortedOptions) {
102 bool UseDefault = false;
103 void *SaveInfo = nullptr;
104 // Requires 'llvm::yaml::IO' to accept 'StringRef'
105 // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
106 IO.preflightKey(Option.first.data(), true, false, UseDefault, SaveInfo);
107 IO.scalarString(Option.second, needsQuotes(Option.second));
108 IO.postflightKey(SaveInfo);
109 }
110 IO.endMapping();
111 } else {
112 // We need custom logic here to support the old method of specifying check
113 // options using a list of maps containing key and value keys.
114 auto &I = reinterpret_cast<Input &>(IO);
115 if (isa<SequenceNode>(I.getCurrentNode())) {
116 MappingNormalization<NOptionMap, ClangTidyOptions::OptionMap> NOpts(IO,
117 Val);
118 EmptyContext Ctx;
119 yamlize(IO, NOpts->Options, true, Ctx);
120 } else if (isa<MappingNode>(I.getCurrentNode())) {
121 IO.beginMapping();
122 for (StringRef Key : IO.keys()) {
123 // Requires 'llvm::yaml::IO' to accept 'StringRef'
124 // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
125 IO.mapRequired(Key.data(), Val[Key].Value);
126 }
127 IO.endMapping();
128 } else {
129 IO.setError("expected a sequence or map");
130 }
131 }
132}
133
134namespace {
135struct MultiLineString {
136 std::string &S;
137};
138} // namespace
139
140template <> struct BlockScalarTraits<MultiLineString> {
141 static void output(const MultiLineString &S, void *Ctxt, raw_ostream &OS) {
142 OS << S.S;
143 }
144 static StringRef input(StringRef Str, void *Ctxt, MultiLineString &S) {
145 S.S = Str;
146 return "";
147 }
148};
149
150template <> struct ScalarEnumerationTraits<clang::DiagnosticIDs::Level> {
151 static void enumeration(IO &IO, clang::DiagnosticIDs::Level &Level) {
152 IO.enumCase(Level, "Warning", clang::DiagnosticIDs::Level::Warning);
153 IO.enumCase(Level, "Note", clang::DiagnosticIDs::Level::Note);
154 }
155};
156template <> struct SequenceElementTraits<ClangTidyOptions::CustomCheckDiag> {
157 // NOLINTNEXTLINE(readability-identifier-naming) Defined by YAMLTraits.h
158 static const bool flow = false;
159};
160template <> struct MappingTraits<ClangTidyOptions::CustomCheckDiag> {
162 IO.mapRequired("BindName", D.BindName);
163 MultiLineString MLS{D.Message};
164 IO.mapRequired("Message", MLS);
165 IO.mapOptional("Level", D.Level);
166 }
167};
168template <> struct SequenceElementTraits<ClangTidyOptions::CustomCheckValue> {
169 // NOLINTNEXTLINE(readability-identifier-naming) Defined by YAMLTraits.h
170 static const bool flow = false;
171};
172template <> struct MappingTraits<ClangTidyOptions::CustomCheckValue> {
174 IO.mapRequired("Name", V.Name);
175 MultiLineString MLS{V.Query};
176 IO.mapRequired("Query", MLS);
177 IO.mapRequired("Diagnostic", V.Diags);
178 }
179};
180
182 std::optional<std::string> AsString;
183 std::optional<std::vector<std::string>> AsVector;
184};
185
186template <> void yamlize(IO &IO, ChecksVariant &Val, bool, EmptyContext &Ctx) {
187 if (!IO.outputting()) {
188 // Special case for reading from YAML
189 // Must support reading from both a string or a list
190 auto &I = reinterpret_cast<Input &>(IO);
191 if (isa<ScalarNode, BlockScalarNode>(I.getCurrentNode())) {
192 Val.AsString = std::string();
193 yamlize(IO, *Val.AsString, true, Ctx);
194 } else if (isa<SequenceNode>(I.getCurrentNode())) {
195 Val.AsVector = std::vector<std::string>();
196 yamlize(IO, *Val.AsVector, true, Ctx);
197 } else {
198 IO.setError("expected string or sequence");
199 }
200 }
201}
202
203static void mapChecks(IO &IO, std::optional<std::string> &Checks) {
204 if (IO.outputting()) {
205 // Output always a string
206 IO.mapOptional("Checks", Checks);
207 } else {
208 // Input as either a string or a list
209 ChecksVariant ChecksAsVariant;
210 IO.mapOptional("Checks", ChecksAsVariant);
211 if (ChecksAsVariant.AsString)
212 Checks = ChecksAsVariant.AsString;
213 else if (ChecksAsVariant.AsVector)
214 Checks = llvm::join(*ChecksAsVariant.AsVector, ",");
215 }
216}
217
218template <> struct MappingTraits<ClangTidyOptions> {
219 static void mapping(IO &IO, ClangTidyOptions &Options) {
220 mapChecks(IO, Options.Checks);
221 IO.mapOptional("WarningsAsErrors", Options.WarningsAsErrors);
222 IO.mapOptional("HeaderFileExtensions", Options.HeaderFileExtensions);
223 IO.mapOptional("ImplementationFileExtensions",
225 IO.mapOptional("HeaderFilterRegex", Options.HeaderFilterRegex);
226 IO.mapOptional("ExcludeHeaderFilterRegex",
228 IO.mapOptional("FormatStyle", Options.FormatStyle);
229 IO.mapOptional("User", Options.User);
230 IO.mapOptional("CheckOptions", Options.CheckOptions);
231 IO.mapOptional("ExtraArgs", Options.ExtraArgs);
232 IO.mapOptional("ExtraArgsBefore", Options.ExtraArgsBefore);
233 IO.mapOptional("InheritParentConfig", Options.InheritParentConfig);
234 IO.mapOptional("UseColor", Options.UseColor);
235 IO.mapOptional("SystemHeaders", Options.SystemHeaders);
236 IO.mapOptional("CustomChecks", Options.CustomChecks);
237 }
238};
239
240} // namespace llvm::yaml
241
242namespace clang::tidy {
243
245 ClangTidyOptions Options;
246 Options.Checks = "";
247 Options.WarningsAsErrors = "";
248 Options.HeaderFileExtensions = {"", "h", "hh", "hpp", "hxx"};
249 Options.ImplementationFileExtensions = {"c", "cc", "cpp", "cxx"};
250 Options.HeaderFilterRegex = "";
251 Options.ExcludeHeaderFilterRegex = "";
252 Options.SystemHeaders = false;
253 Options.FormatStyle = "none";
254 Options.User = std::nullopt;
255 for (const ClangTidyModuleRegistry::entry &Module :
256 ClangTidyModuleRegistry::entries())
257 Options.mergeWith(Module.instantiate()->getModuleOptions(), 0);
258 return Options;
259}
260
261template <typename T>
262static void mergeVectors(std::optional<T> &Dest, const std::optional<T> &Src) {
263 if (Src) {
264 if (Dest)
265 Dest->insert(Dest->end(), Src->begin(), Src->end());
266 else
267 Dest = Src;
268 }
269}
270
271static void mergeCommaSeparatedLists(std::optional<std::string> &Dest,
272 const std::optional<std::string> &Src) {
273 if (Src)
274 Dest = (Dest && !Dest->empty() ? *Dest + "," : "") + *Src;
275}
276
277template <typename T>
278static void overrideValue(std::optional<T> &Dest, const std::optional<T> &Src) {
279 if (Src)
280 Dest = Src;
281}
282
284 unsigned Order) {
294 overrideValue(User, Other.User);
298 // FIXME: how to handle duplicate names check?
300 for (const auto &KeyValue : Other.CheckOptions) {
301 CheckOptions.insert_or_assign(
302 KeyValue.getKey(),
303 ClangTidyValue(KeyValue.getValue().Value,
304 KeyValue.getValue().Priority + Order));
305 }
306 return *this;
307}
308
310 unsigned Order) const {
311 ClangTidyOptions Result = *this;
312 Result.mergeWith(Other, Order);
313 return Result;
314}
315
317 "clang-tidy binary";
319 "command-line option '-checks'";
320const char
322 "command-line option '-config'";
323
325ClangTidyOptionsProvider::getOptions(llvm::StringRef FileName) {
326 ClangTidyOptions Result;
327 unsigned Priority = 0;
328 for (auto &Source : getRawOptions(FileName))
329 Result.mergeWith(Source.first, ++Priority);
330 return Result;
331}
332
333std::vector<OptionsSource>
334DefaultOptionsProvider::getRawOptions(llvm::StringRef FileName) {
335 std::vector<OptionsSource> Result;
336 Result.emplace_back(DefaultOptions, OptionsSourceTypeDefaultBinary);
337 return Result;
338}
339
341 ClangTidyGlobalOptions GlobalOptions, ClangTidyOptions DefaultOptions,
343 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS)
344 : FileOptionsBaseProvider(std::move(GlobalOptions),
345 std::move(DefaultOptions),
346 std::move(OverrideOptions), std::move(FS)),
347 ConfigOptions(std::move(ConfigOptions)) {}
348
349std::vector<OptionsSource>
350ConfigOptionsProvider::getRawOptions(llvm::StringRef FileName) {
351 std::vector<OptionsSource> RawOptions =
353 if (ConfigOptions.InheritParentConfig.value_or(false)) {
354 LLVM_DEBUG(llvm::dbgs()
355 << "Getting options for file " << FileName << "...\n");
356
357 llvm::ErrorOr<llvm::SmallString<128>> AbsoluteFilePath =
359 if (AbsoluteFilePath) {
360 addRawFileOptions(AbsoluteFilePath->str(), RawOptions);
361 }
362 }
363 RawOptions.emplace_back(ConfigOptions,
365 RawOptions.emplace_back(OverrideOptions,
367 return RawOptions;
368}
369
371 ClangTidyGlobalOptions GlobalOptions, ClangTidyOptions DefaultOptions,
373 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS)
374 : DefaultOptionsProvider(std::move(GlobalOptions),
375 std::move(DefaultOptions)),
376 OverrideOptions(std::move(OverrideOptions)), FS(std::move(VFS)) {
377 if (!FS)
378 FS = llvm::vfs::getRealFileSystem();
379 ConfigHandlers.emplace_back(".clang-tidy", parseConfiguration);
380}
381
390
391llvm::ErrorOr<llvm::SmallString<128>>
393 assert(FS && "FS must be set.");
394 llvm::SmallString<128> NormalizedAbsolutePath = {Path};
395 std::error_code Err = FS->makeAbsolute(NormalizedAbsolutePath);
396 if (Err)
397 return Err;
398 llvm::sys::path::remove_dots(NormalizedAbsolutePath, /*remove_dot_dot=*/true);
399 return NormalizedAbsolutePath;
400}
401
403 llvm::StringRef AbsolutePath, std::vector<OptionsSource> &CurOptions) {
404 auto CurSize = CurOptions.size();
405 // Look for a suitable configuration file in all parent directories of the
406 // file. Start with the immediate parent directory and move up.
407 StringRef RootPath = llvm::sys::path::parent_path(AbsolutePath);
408 auto MemorizedConfigFile =
409 [this, &RootPath](StringRef CurrentPath) -> std::optional<OptionsSource> {
410 const auto Iter = CachedOptions.Memorized.find(CurrentPath);
411 if (Iter != CachedOptions.Memorized.end())
412 return CachedOptions.Storage[Iter->second];
413 std::optional<OptionsSource> OptionsSource = tryReadConfigFile(CurrentPath);
414 if (OptionsSource) {
415 const size_t Index = CachedOptions.Storage.size();
416 CachedOptions.Storage.emplace_back(OptionsSource.value());
417 while (RootPath != CurrentPath) {
418 LLVM_DEBUG(llvm::dbgs()
419 << "Caching configuration for path " << RootPath << ".\n");
420 CachedOptions.Memorized[RootPath] = Index;
421 RootPath = llvm::sys::path::parent_path(RootPath);
422 }
423 CachedOptions.Memorized[CurrentPath] = Index;
424 RootPath = llvm::sys::path::parent_path(CurrentPath);
425 }
426 return OptionsSource;
427 };
428 for (StringRef CurrentPath = RootPath; !CurrentPath.empty();
429 CurrentPath = llvm::sys::path::parent_path(CurrentPath)) {
430 if (std::optional<OptionsSource> Result =
431 MemorizedConfigFile(CurrentPath)) {
432 CurOptions.emplace_back(Result.value());
433 if (!Result->first.InheritParentConfig.value_or(false))
434 break;
435 }
436 }
437 // Reverse order of file configs because closer configs should have higher
438 // priority.
439 std::reverse(CurOptions.begin() + CurSize, CurOptions.end());
440}
441
443 ClangTidyGlobalOptions GlobalOptions, ClangTidyOptions DefaultOptions,
445 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS)
446 : FileOptionsBaseProvider(std::move(GlobalOptions),
447 std::move(DefaultOptions),
448 std::move(OverrideOptions), std::move(VFS)) {}
449
457
458// FIXME: This method has some common logic with clang::format::getStyle().
459// Consider pulling out common bits to a findParentFileWithName function or
460// similar.
461std::vector<OptionsSource>
463 LLVM_DEBUG(llvm::dbgs() << "Getting options for file " << FileName
464 << "...\n");
465
466 llvm::ErrorOr<llvm::SmallString<128>> AbsoluteFilePath =
468 if (!AbsoluteFilePath)
469 return {};
470
471 std::vector<OptionsSource> RawOptions =
472 DefaultOptionsProvider::getRawOptions(AbsoluteFilePath->str());
473 addRawFileOptions(AbsoluteFilePath->str(), RawOptions);
474 OptionsSource CommandLineOptions(OverrideOptions,
476
477 RawOptions.push_back(CommandLineOptions);
478 return RawOptions;
479}
480
481std::optional<OptionsSource>
483 assert(!Directory.empty());
484
485 llvm::ErrorOr<llvm::vfs::Status> DirectoryStatus = FS->status(Directory);
486
487 if (!DirectoryStatus || !DirectoryStatus->isDirectory()) {
488 llvm::errs() << "Error reading configuration from " << Directory
489 << ": directory doesn't exist.\n";
490 return std::nullopt;
491 }
492
493 for (const ConfigFileHandler &ConfigHandler : ConfigHandlers) {
494 SmallString<128> ConfigFile(Directory);
495 llvm::sys::path::append(ConfigFile, ConfigHandler.first);
496 LLVM_DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
497
498 llvm::ErrorOr<llvm::vfs::Status> FileStatus = FS->status(ConfigFile);
499
500 if (!FileStatus || !FileStatus->isRegularFile())
501 continue;
502
503 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
504 FS->getBufferForFile(ConfigFile);
505 if (std::error_code EC = Text.getError()) {
506 llvm::errs() << "Can't read " << ConfigFile << ": " << EC.message()
507 << "\n";
508 continue;
509 }
510
511 // Skip empty files, e.g. files opened for writing via shell output
512 // redirection.
513 if ((*Text)->getBuffer().empty())
514 continue;
515 llvm::ErrorOr<ClangTidyOptions> ParsedOptions =
516 ConfigHandler.second({(*Text)->getBuffer(), ConfigFile});
517 if (!ParsedOptions) {
518 if (ParsedOptions.getError())
519 llvm::errs() << "Error parsing " << ConfigFile << ": "
520 << ParsedOptions.getError().message() << "\n";
521 continue;
522 }
523 return OptionsSource(*ParsedOptions, std::string(ConfigFile));
524 }
525 return std::nullopt;
526}
527
528/// Parses -line-filter option and stores it to the \c Options.
529std::error_code parseLineFilter(StringRef LineFilter,
531 llvm::yaml::Input Input(LineFilter);
532 Input >> Options.LineFilter;
533 return Input.error();
534}
535
536llvm::ErrorOr<ClangTidyOptions>
537parseConfiguration(llvm::MemoryBufferRef Config) {
538 llvm::yaml::Input Input(Config);
539 ClangTidyOptions Options;
540 Input >> Options;
541 if (Input.error())
542 return Input.error();
543 return Options;
544}
545
546static void diagHandlerImpl(const llvm::SMDiagnostic &Diag, void *Ctx) {
547 (*reinterpret_cast<DiagCallback *>(Ctx))(Diag);
548}
549
550llvm::ErrorOr<ClangTidyOptions>
552 DiagCallback Handler) {
553 llvm::yaml::Input Input(Config, nullptr, Handler ? diagHandlerImpl : nullptr,
554 &Handler);
555 ClangTidyOptions Options;
556 Input >> Options;
557 if (Input.error())
558 return Input.error();
559 return Options;
560}
561
562std::string configurationAsText(const ClangTidyOptions &Options) {
563 std::string Text;
564 llvm::raw_string_ostream Stream(Text);
565 llvm::yaml::Output Output(Stream);
566 // We use the same mapping method for input and output, so we need a non-const
567 // reference here.
568 ClangTidyOptions NonConstValue = Options;
569 Output << NonConstValue;
570 return Stream.str();
571}
572
573} // namespace clang::tidy
static cl::opt< std::string > Directory(cl::Positional, cl::Required, cl::desc("<Search Root Directory>"))
static cl::opt< std::string > ConfigFile("config-file", desc(R"( Specify the path of .clang-tidy or custom config file: e.g. --config-file=/some/path/myTidyConfigFile This option internally works exactly the same way as --config option after reading specified config file. Use either --config-file or --config, not both. )"), cl::init(""), cl::cat(ClangTidyCategory))
static cl::opt< std::string > Config("config", desc(R"( Specifies a configuration in YAML/JSON format: -config="{Checks:' *', CheckOptions:{x:y}}" When the value is empty, clang-tidy will attempt to find a file named .clang-tidy for each source file in its parent directories. )"), cl::init(""), cl::cat(ClangTidyCategory))
static cl::opt< std::string > LineFilter("line-filter", desc(R"( List of files and line ranges to output diagnostics from. The range is inclusive on both ends. Can be used together with -header-filter. The format of the list is a JSON array of objects. For example: [ {"name":"file1.cpp","lines":[[1,3],[5,7]]}, {"name":"file2.h"} ] This will output diagnostics from 'file1.cpp' only for the line ranges [1,3] and [5,7], as well as all from the entire 'file2.h'. )"), cl::init(""), cl::cat(ClangTidyCategory))
static cl::opt< std::string > Checks("checks", desc(R"( Comma-separated list of globs with optional '-' prefix. Globs are processed in order of appearance in the list. Globs without '-' prefix add checks with matching names to the set, globs with the '-' prefix remove checks with matching names from the set of enabled checks. This option's value is appended to the value of the 'Checks' option in .clang-tidy file, if any. )"), cl::init(""), cl::cat(ClangTidyCategory))
clang::tidy::ClangTidyOptionsProvider::OptionsSource OptionsSource
ClangTidyOptions getOptions(llvm::StringRef FileName)
Returns options applying to a specific translation unit with the specified FileName.
static const char OptionsSourceTypeCheckCommandLineOption[]
virtual std::vector< OptionsSource > getRawOptions(llvm::StringRef FileName)=0
Returns an ordered vector of OptionsSources, in order of increasing priority.
std::pair< ClangTidyOptions, std::string > OptionsSource
ClangTidyOptions and its source.
static const char OptionsSourceTypeConfigCommandLineOption[]
static const char OptionsSourceTypeDefaultBinary[]
ConfigOptionsProvider(ClangTidyGlobalOptions GlobalOptions, ClangTidyOptions DefaultOptions, ClangTidyOptions ConfigOptions, ClangTidyOptions OverrideOptions, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS=nullptr)
std::vector< OptionsSource > getRawOptions(llvm::StringRef FileName) override
Returns an ordered vector of OptionsSources, in order of increasing priority.
DefaultOptionsProvider(ClangTidyGlobalOptions GlobalOptions, ClangTidyOptions Options)
std::vector< OptionsSource > getRawOptions(llvm::StringRef FileName) override
Returns an ordered vector of OptionsSources, in order of increasing priority.
struct clang::tidy::FileOptionsBaseProvider::OptionsCache CachedOptions
std::pair< std::string, std::function< llvm::ErrorOr< ClangTidyOptions >( llvm::MemoryBufferRef)> > ConfigFileHandler
llvm::ErrorOr< llvm::SmallString< 128 > > getNormalizedAbsolutePath(llvm::StringRef AbsolutePath)
std::optional< OptionsSource > tryReadConfigFile(llvm::StringRef Directory)
Try to read configuration files from Directory using registered ConfigHandlers.
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS
FileOptionsBaseProvider(ClangTidyGlobalOptions GlobalOptions, ClangTidyOptions DefaultOptions, ClangTidyOptions OverrideOptions, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS)
std::vector< ConfigFileHandler > ConfigFileHandlers
Configuration file handlers listed in the order of priority.
void addRawFileOptions(llvm::StringRef AbsolutePath, std::vector< OptionsSource > &CurOptions)
std::vector< OptionsSource > getRawOptions(llvm::StringRef FileName) override
Returns an ordered vector of OptionsSources, in order of increasing priority.
FileOptionsProvider(ClangTidyGlobalOptions GlobalOptions, ClangTidyOptions DefaultOptions, ClangTidyOptions OverrideOptions, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS=nullptr)
Initializes the FileOptionsProvider instance.
std::error_code parseLineFilter(StringRef LineFilter, clang::tidy::ClangTidyGlobalOptions &Options)
Parses -line-filter option and stores it to the Options.
static void diagHandlerImpl(const llvm::SMDiagnostic &Diag, void *Ctx)
static void mergeVectors(std::optional< T > &Dest, const std::optional< T > &Src)
llvm::ErrorOr< ClangTidyOptions > parseConfigurationWithDiags(llvm::MemoryBufferRef Config, DiagCallback Handler)
llvm::function_ref< void(const llvm::SMDiagnostic &)> DiagCallback
static void mergeCommaSeparatedLists(std::optional< std::string > &Dest, const std::optional< std::string > &Src)
std::string configurationAsText(const ClangTidyOptions &Options)
Serializes configuration to a YAML-encoded string.
llvm::ErrorOr< ClangTidyOptions > parseConfiguration(llvm::MemoryBufferRef Config)
Parses configuration from JSON and returns ClangTidyOptions or an error.
static void overrideValue(std::optional< T > &Dest, const std::optional< T > &Src)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static void mapChecks(IO &IO, std::optional< std::string > &Checks)
void yamlize(IO &IO, ClangTidyOptions::OptionMap &Val, bool, EmptyContext &Ctx)
Helper structure for storing option value with priority of the value.
llvm::SmallVector< CustomCheckDiag > Diags
std::pair< std::string, std::string > StringPair
llvm::StringMap< ClangTidyValue > OptionMap
std::pair< unsigned int, unsigned int > LineRange
LineRange is a pair<start, end> (inclusive).
std::vector< FileFilter > LineFilter
Output warnings from certain line ranges of certain files only.
Helper structure for storing option value with priority of the value.
Contains options for clang-tidy.
OptionMap CheckOptions
Key-value mapping used to store check-specific options.
ClangTidyOptions merge(const ClangTidyOptions &Other, unsigned Order) const
Creates a new ClangTidyOptions instance combined from all fields of this instance overridden by the f...
std::optional< bool > InheritParentConfig
Only used in the FileOptionsProvider and ConfigOptionsProvider.
std::optional< std::string > HeaderFilterRegex
Output warnings from headers matching this filter.
std::optional< std::string > Checks
Checks filter.
std::optional< std::string > WarningsAsErrors
WarningsAsErrors filter.
std::optional< std::vector< std::string > > ImplementationFileExtensions
File extensions to consider to determine if a given diagnostic is located is located in an implementa...
ClangTidyOptions & mergeWith(const ClangTidyOptions &Other, unsigned Order)
Overwrites all fields in here by the fields of Other that have a value.
std::optional< std::string > User
Specifies the name or e-mail of the user running clang-tidy.
std::optional< std::vector< std::string > > HeaderFileExtensions
File extensions to consider to determine if a given diagnostic is located in a header file.
std::optional< bool > UseColor
Use colors in diagnostics. If missing, it will be auto detected.
std::optional< bool > SystemHeaders
Output warnings from system headers matching HeaderFilterRegex.
static ClangTidyOptions getDefaults()
These options are used for all settings that haven't been overridden by the OptionsProvider.
std::optional< CustomCheckValueList > CustomChecks
std::optional< std::string > ExcludeHeaderFilterRegex
Exclude warnings from headers matching this filter, even if they match HeaderFilterRegex.
std::optional< ArgList > ExtraArgsBefore
Add extra compilation arguments to the start of the list.
std::optional< std::string > FormatStyle
Format code around applied fixes with clang-format using this style.
std::optional< ArgList > ExtraArgs
Add extra compilation arguments to the end of the list.
Contains a list of line ranges in a single file.
static void output(const MultiLineString &S, void *Ctxt, raw_ostream &OS)
static StringRef input(StringRef Str, void *Ctxt, MultiLineString &S)
std::optional< std::string > AsString
std::optional< std::vector< std::string > > AsVector
static void mapping(IO &IO, ClangTidyOptions &Options)
static void mapping(IO &IO, ClangTidyOptions::CustomCheckDiag &D)
static void mapping(IO &IO, ClangTidyOptions::CustomCheckValue &V)
static void mapping(IO &IO, ClangTidyOptions::StringPair &KeyValue)
static std::string validate(IO &Io, FileFilter &File)
static void mapping(IO &IO, FileFilter &File)
ClangTidyOptions::OptionMap denormalize(IO &)
NOptionMap(IO &, const ClangTidyOptions::OptionMap &OptionMap)
std::vector< ClangTidyOptions::StringPair > Options
static void enumeration(IO &IO, clang::DiagnosticIDs::Level &Level)
static unsigned & element(IO &IO, FileFilter::LineRange &Range, size_t Index)
static size_t size(IO &IO, FileFilter::LineRange &Range)