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)
35 template <>
struct SequenceTraits<
FileFilter::LineRange> {
36 static size_t size(IO &IO, FileFilter::LineRange &
Range) {
37 return Range.first == 0 ? 0 : Range.second == 0 ? 1 : 2;
41 IO.setError(
"Too many elements in line range.");
42 return Index == 0 ? Range.first : Range.second;
48 IO.mapRequired(
"name", File.
Name);
52 if (File.
Name.empty())
53 return "No file name specified";
55 if (Range.first <= 0 || Range.second <= 0)
56 return "Invalid line range";
63 static void mapping(IO &IO, ClangTidyOptions::StringPair &KeyValue) {
64 IO.mapRequired(
"key", KeyValue.first);
65 IO.mapRequired(
"value", KeyValue.second);
71 NOptionMap(IO &,
const ClangTidyOptions::OptionMap &OptionMap)
72 : Options(OptionMap.begin(), OptionMap.end()) {}
74 ClangTidyOptions::OptionMap Map;
75 for (
const auto &KeyValue : Options)
76 Map[KeyValue.first] = KeyValue.second;
79 std::vector<ClangTidyOptions::StringPair>
Options;
84 MappingNormalization<NOptionMap, ClangTidyOptions::OptionMap> NOpts(
87 IO.mapOptional(
"Checks", Options.
Checks);
90 IO.mapOptional(
"AnalyzeTemporaryDtors", Ignored);
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>
161 const char ClangTidyOptionsProvider::OptionsSourceTypeDefaultBinary[] =
163 const char ClangTidyOptionsProvider::OptionsSourceTypeCheckCommandLineOption[] =
164 "command-line option '-checks'";
166 ClangTidyOptionsProvider::OptionsSourceTypeConfigCommandLineOption[] =
167 "command-line option '-config'";
170 ClangTidyOptionsProvider::getOptions(llvm::StringRef
FileName) {
172 for (
const auto &Source : getRawOptions(FileName))
177 std::vector<OptionsSource>
178 DefaultOptionsProvider::getRawOptions(llvm::StringRef
FileName) {
179 std::vector<OptionsSource>
Result;
180 Result.emplace_back(DefaultOptions, OptionsSourceTypeDefaultBinary);
184 ConfigOptionsProvider::ConfigOptionsProvider(
190 ConfigOptions(ConfigOptions), OverrideOptions(OverrideOptions) {}
192 std::vector<OptionsSource>
194 std::vector<OptionsSource> RawOptions =
196 RawOptions.emplace_back(ConfigOptions,
198 RawOptions.emplace_back(OverrideOptions,
207 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
VFS)
209 OverrideOptions(OverrideOptions), FS(std::move(VFS)) {
211 FS = llvm::vfs::getRealFileSystem();
221 OverrideOptions(OverrideOptions), ConfigHandlers(ConfigHandlers) {}
226 std::vector<OptionsSource>
228 LLVM_DEBUG(llvm::dbgs() <<
"Getting options for file " << FileName
230 assert(
FS &&
"FS must be set.");
232 llvm::SmallString<128> AbsoluteFilePath(FileName);
234 if (
FS->makeAbsolute(AbsoluteFilePath))
237 std::vector<OptionsSource> RawOptions =
243 StringRef
Path = llvm::sys::path::parent_path(AbsoluteFilePath.str());
244 for (StringRef CurrentPath = Path; !CurrentPath.empty();
245 CurrentPath = llvm::sys::path::parent_path(CurrentPath)) {
246 llvm::Optional<OptionsSource>
Result;
250 Result = Iter->second;
257 while (Path != CurrentPath) {
258 LLVM_DEBUG(llvm::dbgs()
259 <<
"Caching configuration for path " << Path <<
".\n");
261 Path = llvm::sys::path::parent_path(Path);
265 RawOptions.push_back(*Result);
269 RawOptions.push_back(CommandLineOptions);
273 llvm::Optional<OptionsSource>
275 assert(!Directory.empty());
277 if (!llvm::sys::fs::is_directory(Directory)) {
278 llvm::errs() <<
"Error reading configuration from " << Directory
279 <<
": directory doesn't exist.\n";
284 SmallString<128> ConfigFile(Directory);
285 llvm::sys::path::append(ConfigFile, ConfigHandler.first);
286 LLVM_DEBUG(llvm::dbgs() <<
"Trying " << ConfigFile <<
"...\n");
291 llvm::sys::fs::is_regular_file(Twine(ConfigFile), IsFile);
295 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
296 llvm::MemoryBuffer::getFile(ConfigFile.c_str());
297 if (std::error_code EC = Text.getError()) {
298 llvm::errs() <<
"Can't read " << ConfigFile <<
": " << EC.message()
305 if ((*Text)->getBuffer().empty())
307 llvm::ErrorOr<ClangTidyOptions> ParsedOptions =
308 ConfigHandler.second((*Text)->getBuffer());
309 if (!ParsedOptions) {
310 if (ParsedOptions.getError())
311 llvm::errs() <<
"Error parsing " << ConfigFile <<
": " 312 << ParsedOptions.getError().message() <<
"\n";
323 llvm::yaml::Input Input(LineFilter);
325 return Input.error();
329 llvm::yaml::Input Input(Config);
333 return Input.error();
339 llvm::raw_string_ostream Stream(Text);
340 llvm::yaml::Output Output(Stream);
344 Output << NonConstValue;
llvm::Optional< std::string > Checks
Checks filter.
ClangTidyOptions mergeWith(const ClangTidyOptions &Other) const
Creates a new ClangTidyOptions instance combined from all fields of this instance overridden by the f...
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.
Some operations such as code completion produce a set of candidates.
llvm::Optional< std::string > User
Specifies the name or e-mail of the user running clang-tidy.
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS
static void mergeVectors(Optional< T > &Dest, const Optional< T > &Src)
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))
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
FileOptionsProvider(const ClangTidyGlobalOptions &GlobalOptions, const ClangTidyOptions &DefaultOptions, const ClangTidyOptions &OverrideOptions, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS=nullptr)
Initializes the FileOptionsProvider instance.
ConfigFileHandlers ConfigHandlers
llvm::Optional< ArgList > ExtraArgsBefore
Add extra compilation arguments to the start of the list.
llvm::Optional< std::string > FormatStyle
Format code around applied fixes with clang-format using this style.
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))
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS
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.
static void mapping(IO &IO, ClangTidyOptions::StringPair &KeyValue)
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
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.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
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.
clang::tidy::ClangTidyOptionsProvider::OptionsSource OptionsSource
std::string Name
File name.
llvm::Optional< OptionsSource > tryReadConfigFile(llvm::StringRef Directory)
Try to read configuration files from Directory using registered ConfigHandlers.
Implementation of the ClangTidyOptionsProvider interface, which returns the same options for all file...
const SymbolIndex * Index