Go to the documentation of this file.
11 #include "clang/Basic/LLVM.h"
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/Support/Debug.h"
14 #include "llvm/Support/Errc.h"
15 #include "llvm/Support/FileSystem.h"
16 #include "llvm/Support/MemoryBufferRef.h"
17 #include "llvm/Support/Path.h"
18 #include "llvm/Support/YAMLTraits.h"
21 #define DEBUG_TYPE "clang-tidy-options"
28 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(FileFilter::LineRange)
34 template <>
struct SequenceTraits<
FileFilter::LineRange> {
35 static size_t size(IO &IO, FileFilter::LineRange &
Range) {
36 return Range.first == 0 ? 0 :
Range.second == 0 ? 1 : 2;
40 IO.setError(
"Too many elements in line range.");
47 IO.mapRequired(
"name", File.Name);
48 IO.mapOptional(
"lines", File.LineRanges);
51 if (File.Name.empty())
52 return "No file name specified";
53 for (
const FileFilter::LineRange &
Range : File.LineRanges) {
55 return "Invalid line range";
62 static void mapping(IO &IO, ClangTidyOptions::StringPair &KeyValue) {
63 IO.mapRequired(
"key", KeyValue.first);
64 IO.mapRequired(
"value", KeyValue.second);
70 NOptionMap(IO &,
const ClangTidyOptions::OptionMap &OptionMap) {
71 Options.reserve(OptionMap.size());
72 for (
const auto &KeyValue : OptionMap)
73 Options.emplace_back(std::string(KeyValue.getKey()), KeyValue.getValue().Value);
76 ClangTidyOptions::OptionMap Map;
77 for (
const auto &KeyValue :
Options)
78 Map[KeyValue.first] = ClangTidyOptions::ClangTidyValue(KeyValue.second);
81 std::vector<ClangTidyOptions::StringPair>
Options;
86 MappingNormalization<NOptionMap, ClangTidyOptions::OptionMap> NOpts(
89 IO.mapOptional(
"Checks", Options.
Checks);
92 IO.mapOptional(
"AnalyzeTemporaryDtors", Ignored);
94 IO.mapOptional(
"User", Options.
User);
95 IO.mapOptional(
"CheckOptions", NOpts->Options);
96 IO.mapOptional(
"ExtraArgs", Options.
ExtraArgs);
99 IO.mapOptional(
"UseColor", Options.
UseColor);
116 Options.
User = llvm::None;
117 for (
const ClangTidyModuleRegistry::entry &Module :
118 ClangTidyModuleRegistry::entries())
119 Options.
mergeWith(Module.instantiate()->getModuleOptions(), 0);
123 template <
typename T>
127 Dest->insert(Dest->end(), Src->begin(), Src->end());
134 const Optional<std::string> &Src) {
136 Dest = (Dest && !Dest->empty() ? *Dest +
"," :
"") + *Src;
139 template <
typename T>
161 KeyValue.getValue().Priority + Order));
167 unsigned Order)
const {
169 Result.mergeWith(Other, Order);
176 "command-line option '-checks'";
179 "command-line option '-config'";
184 unsigned Priority = 0;
186 Result.mergeWith(Source.first, ++Priority);
190 std::vector<OptionsSource>
192 std::vector<OptionsSource> Result;
200 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS)
202 std::move(DefaultOptions),
203 std::move(OverrideOptions), std::move(FS)),
204 ConfigOptions(std::move(ConfigOptions)) {}
206 std::vector<OptionsSource>
208 std::vector<OptionsSource> RawOptions =
211 LLVM_DEBUG(llvm::dbgs()
212 <<
"Getting options for file " <<
FileName <<
"...\n");
213 assert(
FS &&
"FS must be set.");
215 llvm::SmallString<128> AbsoluteFilePath(
FileName);
217 if (!
FS->makeAbsolute(AbsoluteFilePath)) {
221 RawOptions.emplace_back(ConfigOptions,
231 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS)
233 std::move(DefaultOptions)),
234 OverrideOptions(std::move(OverrideOptions)), FS(std::move(VFS)) {
236 FS = llvm::vfs::getRealFileSystem();
245 std::move(DefaultOptions)),
246 OverrideOptions(std::move(OverrideOptions)),
247 ConfigHandlers(std::move(ConfigHandlers)) {}
250 llvm::StringRef AbsolutePath, std::vector<OptionsSource> &CurOptions) {
251 auto CurSize = CurOptions.size();
255 StringRef
Path = llvm::sys::path::parent_path(AbsolutePath);
256 for (StringRef CurrentPath =
Path; !CurrentPath.empty();
257 CurrentPath = llvm::sys::path::parent_path(CurrentPath)) {
258 llvm::Optional<OptionsSource> Result;
262 Result = Iter->second;
269 while (
Path != CurrentPath) {
270 LLVM_DEBUG(llvm::dbgs()
271 <<
"Caching configuration for path " <<
Path <<
".\n");
274 Path = llvm::sys::path::parent_path(
Path);
278 CurOptions.push_back(*Result);
279 if (!Result->first.InheritParentConfig.getValueOr(
false))
285 std::reverse(CurOptions.begin() + CurSize, CurOptions.end());
291 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS)
293 std::move(DefaultOptions),
294 std::move(OverrideOptions), std::move(VFS)) {}
301 std::move(GlobalOptions), std::move(DefaultOptions),
302 std::move(OverrideOptions), std::move(ConfigHandlers)) {}
307 std::vector<OptionsSource>
309 LLVM_DEBUG(llvm::dbgs() <<
"Getting options for file " <<
FileName
311 assert(
FS &&
"FS must be set.");
313 llvm::SmallString<128> AbsoluteFilePath(
FileName);
315 if (
FS->makeAbsolute(AbsoluteFilePath))
318 std::vector<OptionsSource> RawOptions =
324 RawOptions.push_back(CommandLineOptions);
328 llvm::Optional<OptionsSource>
332 llvm::ErrorOr<llvm::vfs::Status> DirectoryStatus =
FS->status(
Directory);
334 if (!DirectoryStatus || !DirectoryStatus->isDirectory()) {
335 llvm::errs() <<
"Error reading configuration from " <<
Directory
336 <<
": directory doesn't exist.\n";
342 llvm::sys::path::append(
ConfigFile, ConfigHandler.first);
343 LLVM_DEBUG(llvm::dbgs() <<
"Trying " <<
ConfigFile <<
"...\n");
345 llvm::ErrorOr<llvm::vfs::Status> FileStatus =
FS->status(
ConfigFile);
347 if (!FileStatus || !FileStatus->isRegularFile())
350 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
352 if (std::error_code EC =
Text.getError()) {
353 llvm::errs() <<
"Can't read " <<
ConfigFile <<
": " << EC.message()
360 if ((*Text)->getBuffer().empty())
362 llvm::ErrorOr<ClangTidyOptions> ParsedOptions =
363 ConfigHandler.second({(*Text)->getBuffer(),
ConfigFile});
364 if (!ParsedOptions) {
365 if (ParsedOptions.getError())
366 llvm::errs() <<
"Error parsing " <<
ConfigFile <<
": "
367 << ParsedOptions.getError().message() <<
"\n";
380 return Input.error();
383 llvm::ErrorOr<ClangTidyOptions>
385 llvm::yaml::Input Input(
Config);
389 return Input.error();
397 llvm::ErrorOr<ClangTidyOptions>
405 return Input.error();
411 llvm::raw_string_ostream Stream(
Text);
CharSourceRange Range
SourceRange for the file name.
llvm::ErrorOr< ClangTidyOptions > parseConfiguration(llvm::MemoryBufferRef Config)
Parses configuration from JSON and returns ClangTidyOptions or an error.
std::vector< OptionsSource > getRawOptions(llvm::StringRef FileName) override
Returns an ordered vector of OptionsSources, in order of increasing priority.
Some operations such as code completion produce a set of candidates.
Implementation of the ClangTidyOptionsProvider interface, which returns the same options for all file...
llvm::Optional< std::string > Checks
Checks filter.
ConfigFileHandlers ConfigHandlers
std::error_code parseLineFilter(StringRef LineFilter, clang::tidy::ClangTidyGlobalOptions &Options)
Parses -line-filter option and stores it to the Options.
static unsigned & element(IO &IO, FileFilter::LineRange &Range, size_t Index)
static const char OptionsSourceTypeCheckCommandLineOption[]
void addRawFileOptions(llvm::StringRef AbsolutePath, std::vector< OptionsSource > &CurOptions)
Helper structure for storing option value with priority of the value.
Contains a list of line ranges in a single file.
llvm::Optional< ArgList > ExtraArgsBefore
Add extra compilation arguments to the start of the list.
static void mapping(IO &IO, ClangTidyOptions::StringPair &KeyValue)
llvm::Optional< std::string > User
Specifies the name or e-mail of the user running clang-tidy.
OptionMap CheckOptions
Key-value mapping used to store check-specific options.
static cl::opt< std::string > ConfigFile("config-file", cl::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))
ConfigOptionsProvider(ClangTidyGlobalOptions GlobalOptions, ClangTidyOptions DefaultOptions, ClangTidyOptions ConfigOptions, ClangTidyOptions OverrideOptions, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS=nullptr)
static size_t size(IO &IO, FileFilter::LineRange &Range)
llvm::ErrorOr< ClangTidyOptions > parseConfigurationWithDiags(llvm::MemoryBufferRef Config, DiagCallback Handler)
static void mergeVectors(Optional< T > &Dest, const Optional< T > &Src)
Contains options for clang-tidy.
static const char OptionsSourceTypeDefaultBinary[]
llvm::Optional< bool > InheritParentConfig
Only used in the FileOptionsProvider and ConfigOptionsProvider.
llvm::Optional< std::string > FormatStyle
Format code around applied fixes with clang-format using this style.
llvm::Optional< bool > UseColor
Use colors in diagnostics. If missing, it will be auto detected.
clang::tidy::ClangTidyOptionsProvider::OptionsSource OptionsSource
std::pair< ClangTidyOptions, std::string > OptionsSource
ClangTidyOptions and its source.
static void diagHandlerImpl(const llvm::SMDiagnostic &Diag, void *Ctx)
llvm::Optional< std::string > HeaderFilterRegex
Output warnings from headers matching this filter.
llvm::Optional< bool > SystemHeaders
Output warnings from system headers matching HeaderFilterRegex.
std::vector< FileFilter > LineFilter
Output warnings from certain line ranges of certain files only.
ClangTidyOptions & mergeWith(const ClangTidyOptions &Other, unsigned Order)
Overwrites all fields in here by the fields of Other that have a value.
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS
std::vector< ClangTidyOptions::StringPair > Options
static std::string validate(IO &Io, FileFilter &File)
std::vector< OptionsSource > getRawOptions(llvm::StringRef FileName) override
Returns an ordered vector of OptionsSources, in order of increasing priority.
llvm::StringRef Directory
llvm::StringMap< OptionsSource > CachedOptions
std::pair< std::string, std::function< llvm::ErrorOr< ClangTidyOptions > llvm::MemoryBufferRef)> > ConfigFileHandler
std::string configurationAsText(const ClangTidyOptions &Options)
Serializes configuration to a YAML-encoded string.
llvm::Optional< OptionsSource > tryReadConfigFile(llvm::StringRef Directory)
Try to read configuration files from Directory using registered ConfigHandlers.
FileOptionsProvider(ClangTidyGlobalOptions GlobalOptions, ClangTidyOptions DefaultOptions, ClangTidyOptions OverrideOptions, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS=nullptr)
Initializes the FileOptionsProvider instance.
static void mapping(IO &IO, FileFilter &File)
static const char OptionsSourceTypeConfigCommandLineOption[]
static cl::opt< std::string > Config("config", cl::desc(R"(
Specifies a configuration in YAML/JSON format:
-config="{Checks:' *', CheckOptions:[{key:x, value: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))
const SymbolIndex * Index
static void mergeCommaSeparatedLists(Optional< std::string > &Dest, const Optional< std::string > &Src)
llvm::Optional< std::string > WarningsAsErrors
WarningsAsErrors filter.
static void overrideValue(Optional< T > &Dest, const Optional< T > &Src)
llvm::function_ref< void(const llvm::SMDiagnostic &)> DiagCallback
ClangTidyOptions getOptions(llvm::StringRef FileName)
Returns options applying to a specific translation unit with the specified FileName.
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.
static cl::opt< std::string > LineFilter("line-filter", cl::desc(R"(
List of files with line ranges to filter the
warnings. Can be used together with
-header-filter. The format of the list is a
JSON array of objects:
[
{"name":"file1.cpp","lines":[[1,3],[5,7]]},
{"name":"file2.h"}
]
)"), cl::init(""), cl::cat(ClangTidyCategory))
ClangTidyOptions::OptionMap denormalize(IO &)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
virtual std::vector< OptionsSource > getRawOptions(llvm::StringRef FileName)=0
Returns an ordered vector of OptionsSources, in order of increasing priority.
ClangTidyOptions OverrideOptions
LLVM_NODISCARD ClangTidyOptions merge(const ClangTidyOptions &Other, unsigned Order) const
Creates a new ClangTidyOptions instance combined from all fields of this instance overridden by the f...
static ClangTidyOptions getDefaults()
These options are used for all settings that haven't been overridden by the OptionsProvider.
static void mapping(IO &IO, ClangTidyOptions &Options)
std::vector< OptionsSource > getRawOptions(llvm::StringRef FileName) override
Returns an ordered vector of OptionsSources, in order of increasing priority.
llvm::Optional< ArgList > ExtraArgs
Add extra compilation arguments to the end of the list.
NOptionMap(IO &, const ClangTidyOptions::OptionMap &OptionMap)
std::vector< HeaderHandle > Path