12 #include "clang/Basic/LLVM.h"
13 #include "llvm/ADT/SmallString.h"
14 #include "llvm/Support/Debug.h"
15 #include "llvm/Support/Errc.h"
16 #include "llvm/Support/FileSystem.h"
17 #include "llvm/Support/Path.h"
18 #include "llvm/Support/YAMLTraits.h"
19 #include "llvm/Support/raw_ostream.h"
22 #define DEBUG_TYPE "clang-tidy-options"
29 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(
FileFilter::LineRange)
31 LLVM_YAML_IS_SEQUENCE_VECTOR(std::
string)
37 template <>
struct SequenceTraits<
FileFilter::LineRange> {
38 static size_t size(IO &IO, FileFilter::LineRange &
Range) {
39 return Range.first == 0 ? 0 : Range.second == 0 ? 1 : 2;
41 static unsigned &
element(IO &IO, FileFilter::LineRange &
Range,
size_t Index) {
43 IO.setError(
"Too many elements in line range.");
44 return Index == 0 ? Range.first : Range.second;
50 IO.mapRequired(
"name", File.
Name);
54 if (File.
Name.empty())
55 return "No file name specified";
57 if (Range.first <= 0 || Range.second <= 0)
58 return "Invalid line range";
65 static void mapping(IO &IO, ClangTidyOptions::StringPair &KeyValue) {
66 IO.mapRequired(
"key", KeyValue.first);
67 IO.mapRequired(
"value", KeyValue.second);
73 NOptionMap(IO &,
const ClangTidyOptions::OptionMap &OptionMap)
74 : Options(OptionMap.begin(), OptionMap.end()) {}
76 ClangTidyOptions::OptionMap Map;
77 for (
const auto &KeyValue : Options)
78 Map[KeyValue.first] = KeyValue.second;
81 std::vector<ClangTidyOptions::StringPair>
Options;
86 MappingNormalization<NOptionMap, ClangTidyOptions::OptionMap> NOpts(
88 IO.mapOptional(
"Checks", Options.
Checks);
92 IO.mapOptional(
"User", Options.
User);
93 IO.mapOptional(
"CheckOptions", NOpts->Options);
94 IO.mapOptional(
"ExtraArgs", Options.
ExtraArgs);
112 Options.
User = llvm::None;
113 for (ClangTidyModuleRegistry::iterator I = ClangTidyModuleRegistry::begin(),
114 E = ClangTidyModuleRegistry::end();
116 Options = Options.
mergeWith(I->instantiate()->getModuleOptions());
120 template <
typename T>
124 Dest->insert(Dest->end(), Src->begin(), Src->end());
131 const Optional<std::string> &Src) {
133 Dest = (Dest && !Dest->empty() ? *Dest +
"," :
"") + *Src;
136 template <
typename T>
164 "command-line option '-checks'";
167 "command-line option '-config'";
177 std::vector<OptionsSource>
179 std::vector<OptionsSource>
Result;
190 ConfigOptions(ConfigOptions), OverrideOptions(OverrideOptions) {}
192 std::vector<OptionsSource>
194 std::vector<OptionsSource> RawOptions =
196 RawOptions.emplace_back(ConfigOptions,
198 RawOptions.emplace_back(OverrideOptions,
208 OverrideOptions(OverrideOptions) {
218 OverrideOptions(OverrideOptions), ConfigHandlers(ConfigHandlers) {}
223 std::vector<OptionsSource>
225 DEBUG(llvm::dbgs() <<
"Getting options for file " << FileName <<
"...\n");
227 std::vector<OptionsSource> RawOptions =
233 StringRef
Path = llvm::sys::path::parent_path(FileName);
234 for (StringRef CurrentPath = Path; !CurrentPath.empty();
235 CurrentPath = llvm::sys::path::parent_path(CurrentPath)) {
236 llvm::Optional<OptionsSource>
Result;
240 Result = Iter->second;
247 while (Path != CurrentPath) {
248 DEBUG(llvm::dbgs() <<
"Caching configuration for path " << Path
251 Path = llvm::sys::path::parent_path(Path);
255 RawOptions.push_back(*Result);
259 RawOptions.push_back(CommandLineOptions);
263 llvm::Optional<OptionsSource>
265 assert(!Directory.empty());
267 if (!llvm::sys::fs::is_directory(Directory)) {
268 llvm::errs() <<
"Error reading configuration from " << Directory
269 <<
": directory doesn't exist.\n";
274 SmallString<128> ConfigFile(Directory);
275 llvm::sys::path::append(ConfigFile, ConfigHandler.first);
276 DEBUG(llvm::dbgs() <<
"Trying " << ConfigFile <<
"...\n");
281 llvm::sys::fs::is_regular_file(Twine(ConfigFile), IsFile);
285 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
286 llvm::MemoryBuffer::getFile(ConfigFile.c_str());
287 if (std::error_code EC = Text.getError()) {
288 llvm::errs() <<
"Can't read " << ConfigFile <<
": " << EC.message()
295 if ((*Text)->getBuffer().empty())
297 llvm::ErrorOr<ClangTidyOptions> ParsedOptions =
298 ConfigHandler.second((*Text)->getBuffer());
299 if (!ParsedOptions) {
300 if (ParsedOptions.getError())
301 llvm::errs() <<
"Error parsing " << ConfigFile <<
": "
302 << ParsedOptions.getError().message() <<
"\n";
315 return Input.error();
323 return Input.error();
329 llvm::raw_string_ostream Stream(Text);
330 llvm::yaml::Output Output(Stream);
334 Output << NonConstValue;
llvm::Optional< std::string > Checks
Checks filter.
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.
llvm::Optional< std::string > User
Specifies the name or e-mail of the user running clang-tidy.
static void mergeVectors(Optional< T > &Dest, const Optional< T > &Src)
virtual std::vector< OptionsSource > getRawOptions(llvm::StringRef FileName)=0
Returns an ordered vector of OptionsSources, in order of increasing priority.
llvm::Optional< std::string > HeaderFilterRegex
Output warnings from headers matching this filter.
static void mapping(IO &IO, FileFilter &File)
static const char OptionsSourceTypeCheckCommandLineOption[]
Contains options for clang-tidy.
static const char OptionsSourceTypeConfigCommandLineOption[]
std::vector< OptionsSource > getRawOptions(llvm::StringRef FileName) override
Returns an ordered vector of OptionsSources, in order of increasing priority.
std::error_code parseLineFilter(StringRef LineFilter, clang::tidy::ClangTidyGlobalOptions &Options)
Parses -line-filter option and stores it to the Options.
std::vector< HeaderHandle > Path
llvm::ErrorOr< ClangTidyOptions > parseConfiguration(StringRef Config)
static StringRef validate(IO &io, FileFilter &File)
NOptionMap(IO &, const ClangTidyOptions::OptionMap &OptionMap)
OptionMap CheckOptions
Key-value mapping used to store check-specific options.
llvm::Optional< bool > SystemHeaders
Output warnings from system headers matching HeaderFilterRegex.
ClangTidyOptions OverrideOptions
ConfigFileHandlers ConfigHandlers
llvm::Optional< ArgList > ExtraArgsBefore
Add extra compilation arguments to the start of the list.
static cl::opt< std::string > Directory(cl::Positional, cl::Required, cl::desc("<Search Root Directory>"))
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))
static cl::opt< std::string > Input("input", cl::desc("YAML file to load oldname-newname pairs from."), cl::Optional, cl::cat(ClangRenameOptions))
std::vector< OptionsSource > getRawOptions(llvm::StringRef FileName) override
Returns an ordered vector of OptionsSources, in order of increasing priority.
std::string configurationAsText(const ClangTidyOptions &Options)
Serializes configuration to a YAML-encoded string.
static unsigned & element(IO &IO, FileFilter::LineRange &Range, size_t Index)
llvm::StringMap< OptionsSource > CachedOptions
static void mapping(IO &IO, ClangTidyOptions &Options)
std::vector< FileFilter > LineFilter
Output warnings from certain line ranges of certain files only.
ClangTidyOptions mergeWith(const ClangTidyOptions &Other) const
Creates a new ClangTidyOptions instance combined from all fields of this instance overridden by the f...
static void mapping(IO &IO, ClangTidyOptions::StringPair &KeyValue)
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))
std::pair< std::string, std::function< llvm::ErrorOr< ClangTidyOptions > llvm::StringRef)> > ConfigFileHandler
llvm::Optional< std::string > WarningsAsErrors
WarningsAsErrors filter.
static void mergeCommaSeparatedLists(Optional< std::string > &Dest, const Optional< std::string > &Src)
std::vector< ConfigFileHandler > ConfigFileHandlers
Configuration file handlers listed in the order of priority.
Contains a list of line ranges in a single file.
llvm::Optional< bool > AnalyzeTemporaryDtors
Turns on temporary destructor-based analysis.
CharSourceRange Range
SourceRange for the file name.
std::vector< ClangTidyOptions::StringPair > Options
static size_t size(IO &IO, FileFilter::LineRange &Range)
static void overrideValue(Optional< T > &Dest, const Optional< T > &Src)
std::pair< ClangTidyOptions, std::string > OptionsSource
ClangTidyOptions and its source.
ClangTidyOptions::OptionMap denormalize(IO &)
std::vector< LineRange > LineRanges
A list of line ranges in this file, for which we show warnings.
static ClangTidyOptions getDefaults()
These options are used for all settings that haven't been overridden by the OptionsProvider.
ClangTidyOptions getOptions(llvm::StringRef FileName)
Returns options applying to a specific translation unit with the specified FileName.
clang::tidy::ClangTidyOptionsProvider::OptionsSource OptionsSource
FileOptionsProvider(const ClangTidyGlobalOptions &GlobalOptions, const ClangTidyOptions &DefaultOptions, const ClangTidyOptions &OverrideOptions)
Initializes the FileOptionsProvider instance.
std::string Name
File name.
llvm::Optional< OptionsSource > tryReadConfigFile(llvm::StringRef Directory)
Try to read configuration files from Directory using registered ConfigHandlers.
ConfigOptionsProvider(const ClangTidyGlobalOptions &GlobalOptions, const ClangTidyOptions &DefaultOptions, const ClangTidyOptions &ConfigOptions, const ClangTidyOptions &OverrideOptions)
Implementation of the ClangTidyOptionsProvider interface, which returns the same options for all file...
static const char OptionsSourceTypeDefaultBinary[]