1//===--- ClangTidyOptions.h - clang-tidy ------------------------*- C++ -*-===//
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#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYOPTIONS_H
10#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYOPTIONS_H
11
12#include "llvm/ADT/IntrusiveRefCntPtr.h"
13#include "llvm/ADT/SmallString.h"
14#include "llvm/ADT/StringMap.h"
15#include "llvm/ADT/StringRef.h"
16#include "llvm/Support/ErrorOr.h"
17#include "llvm/Support/MemoryBufferRef.h"
18#include "llvm/Support/VirtualFileSystem.h"
19#include <functional>
20#include <optional>
21#include <string>
22#include <system_error>
23#include <utility>
24#include <vector>
25
26namespace clang::tidy {
27
28/// Contains a list of line ranges in a single file.
29struct FileFilter {
30 /// File name.
31 std::string Name;
32
33 /// LineRange is a pair<start, end> (inclusive).
34 using LineRange = std::pair<unsigned int, unsigned int>;
35
36 /// A list of line ranges in this file, for which we show warnings.
37 std::vector<LineRange> LineRanges;
38};
39
40/// Global options. These options are neither stored nor read from
41/// configuration files.
42struct ClangTidyGlobalOptions {
43 /// Output warnings from certain line ranges of certain files only.
44 /// If empty, no warnings will be filtered.
45 std::vector<FileFilter> LineFilter;
46};
47
48/// Contains options for clang-tidy. These options may be read from
49/// configuration files, and may be different for different translation units.
50struct ClangTidyOptions {
51 /// These options are used for all settings that haven't been
52 /// overridden by the \c OptionsProvider.
53 ///
54 /// Allow no checks and no headers by default. This method initializes
55 /// check-specific options by calling \c ClangTidyModule::getModuleOptions()
56 /// of each registered \c ClangTidyModule.
57 static ClangTidyOptions getDefaults();
58
59 /// Overwrites all fields in here by the fields of \p Other that have a value.
60 /// \p Order specifies precedence of \p Other option.
61 ClangTidyOptions &mergeWith(const ClangTidyOptions &Other, unsigned Order);
62
63 /// Creates a new \c ClangTidyOptions instance combined from all fields
64 /// of this instance overridden by the fields of \p Other that have a value.
65 /// \p Order specifies precedence of \p Other option.
66 [[nodiscard]] ClangTidyOptions merge(const ClangTidyOptions &Other,
67 unsigned Order) const;
68
69 /// Checks filter.
70 std::optional<std::string> Checks;
71
72 /// WarningsAsErrors filter.
73 std::optional<std::string> WarningsAsErrors;
74
75 /// File extensions to consider to determine if a given diagnostic is located
76 /// in a header file.
77 std::optional<std::vector<std::string>> HeaderFileExtensions;
78
79 /// File extensions to consider to determine if a given diagnostic is located
80 /// is located in an implementation file.
81 std::optional<std::vector<std::string>> ImplementationFileExtensions;
82
83 /// Output warnings from headers matching this filter. Warnings from
84 /// main files will always be displayed.
85 std::optional<std::string> HeaderFilterRegex;
86
87 /// \brief Exclude warnings from headers matching this filter, even if they
88 /// match \c HeaderFilterRegex.
89 std::optional<std::string> ExcludeHeaderFilterRegex;
90
91 /// Output warnings from system headers matching \c HeaderFilterRegex.
92 std::optional<bool> SystemHeaders;
93
94 /// Format code around applied fixes with clang-format using this
95 /// style.
96 ///
97 /// Can be one of:
98 /// * 'none' - don't format code around applied fixes;
99 /// * 'llvm', 'google', 'mozilla' or other predefined clang-format style
100 /// names;
101 /// * 'file' - use the .clang-format file in the closest parent directory of
102 /// each source file;
103 /// * '{inline-formatting-style-in-yaml-format}'.
104 ///
105 /// See clang-format documentation for more about configuring format style.
106 std::optional<std::string> FormatStyle;
107
108 /// Specifies the name or e-mail of the user running clang-tidy.
109 ///
110 /// This option is used, for example, to place the correct user name in TODO()
111 /// comments in the relevant check.
112 std::optional<std::string> User;
113
114 /// Helper structure for storing option value with priority of the value.
115 struct ClangTidyValue {
116 ClangTidyValue() = default;
117 ClangTidyValue(const char *Value) : Value(Value) {}
118 ClangTidyValue(llvm::StringRef Value, unsigned Priority = 0)
119 : Value(Value), Priority(Priority) {}
120
121 std::string Value;
122 /// Priority stores relative precedence of the value loaded from config
123 /// files to disambiguate local vs global value from different levels.
124 unsigned Priority = 0;
125 };
126 using StringPair = std::pair<std::string, std::string>;
127 using OptionMap = llvm::StringMap<ClangTidyValue>;
128
129 /// Key-value mapping used to store check-specific options.
130 OptionMap CheckOptions;
131
132 using ArgList = std::vector<std::string>;
133
134 /// Add extra compilation arguments to the end of the list.
135 std::optional<ArgList> ExtraArgs;
136
137 /// Add extra compilation arguments to the start of the list.
138 std::optional<ArgList> ExtraArgsBefore;
139
140 /// Only used in the FileOptionsProvider and ConfigOptionsProvider. If true
141 /// and using a FileOptionsProvider, it will take a configuration file in the
142 /// parent directory (if any exists) and apply this config file on top of the
143 /// parent one. IF true and using a ConfigOptionsProvider, it will apply this
144 /// config on top of any configuration file it finds in the directory using
145 /// the same logic as FileOptionsProvider. If false or missing, only this
146 /// configuration file will be used.
147 std::optional<bool> InheritParentConfig;
148
149 /// Use colors in diagnostics. If missing, it will be auto detected.
150 std::optional<bool> UseColor;
151};
152
153/// Abstract interface for retrieving various ClangTidy options.
154class ClangTidyOptionsProvider {
155public:
156 static const char OptionsSourceTypeDefaultBinary[];
157 static const char OptionsSourceTypeCheckCommandLineOption[];
158 static const char OptionsSourceTypeConfigCommandLineOption[];
159
160 virtual ~ClangTidyOptionsProvider() {}
161
162 /// Returns global options, which are independent of the file.
163 virtual const ClangTidyGlobalOptions &getGlobalOptions() = 0;
164
165 /// ClangTidyOptions and its source.
166 //
167 /// clang-tidy has 3 types of the sources in order of increasing priority:
168 /// * clang-tidy binary.
169 /// * '-config' commandline option or a specific configuration file. If the
170 /// commandline option is specified, clang-tidy will ignore the
171 /// configuration file.
172 /// * '-checks' commandline option.
173 using OptionsSource = std::pair<ClangTidyOptions, std::string>;
174
175 /// Returns an ordered vector of OptionsSources, in order of increasing
176 /// priority.
177 virtual std::vector<OptionsSource>
178 getRawOptions(llvm::StringRef FileName) = 0;
179
180 /// Returns options applying to a specific translation unit with the
181 /// specified \p FileName.
182 ClangTidyOptions getOptions(llvm::StringRef FileName);
183};
184
185/// Implementation of the \c ClangTidyOptionsProvider interface, which
186/// returns the same options for all files.
187class DefaultOptionsProvider : public ClangTidyOptionsProvider {
188public:
189 DefaultOptionsProvider(ClangTidyGlobalOptions GlobalOptions,
190 ClangTidyOptions Options)
191 : GlobalOptions(std::move(GlobalOptions)),
192 DefaultOptions(std::move(Options)) {}
193 const ClangTidyGlobalOptions &getGlobalOptions() override {
194 return GlobalOptions;
195 }
196 std::vector<OptionsSource> getRawOptions(llvm::StringRef FileName) override;
197
198private:
199 ClangTidyGlobalOptions GlobalOptions;
200 ClangTidyOptions DefaultOptions;
201};
202
203class FileOptionsBaseProvider : public DefaultOptionsProvider {
204protected:
205 // A pair of configuration file base name and a function parsing
206 // configuration from text in the corresponding format.
207 using ConfigFileHandler =
208 std::pair<std::string, std::function<llvm::ErrorOr<ClangTidyOptions>(
209 llvm::MemoryBufferRef)>>;
210
211 /// Configuration file handlers listed in the order of priority.
212 ///
213 /// Custom configuration file formats can be supported by constructing the
214 /// list of handlers and passing it to the appropriate \c FileOptionsProvider
215 /// constructor. E.g. initialization of a \c FileOptionsProvider with support
216 /// of a custom configuration file format for files named ".my-tidy-config"
217 /// could look similar to this:
218 /// \code
219 /// FileOptionsProvider::ConfigFileHandlers ConfigHandlers;
220 /// ConfigHandlers.emplace_back(".my-tidy-config", parseMyConfigFormat);
221 /// ConfigHandlers.emplace_back(".clang-tidy", parseConfiguration);
222 /// return std::make_unique<FileOptionsProvider>(
223 /// GlobalOptions, DefaultOptions, OverrideOptions, ConfigHandlers);
224 /// \endcode
225 ///
226 /// With the order of handlers shown above, the ".my-tidy-config" file would
227 /// take precedence over ".clang-tidy" if both reside in the same directory.
228 using ConfigFileHandlers = std::vector<ConfigFileHandler>;
229
230 FileOptionsBaseProvider(ClangTidyGlobalOptions GlobalOptions,
231 ClangTidyOptions DefaultOptions,
232 ClangTidyOptions OverrideOptions,
233 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS);
234
235 FileOptionsBaseProvider(ClangTidyGlobalOptions GlobalOptions,
236 ClangTidyOptions DefaultOptions,
237 ClangTidyOptions OverrideOptions,
238 ConfigFileHandlers ConfigHandlers);
239
240 void addRawFileOptions(llvm::StringRef AbsolutePath,
241 std::vector<OptionsSource> &CurOptions);
242
243 llvm::ErrorOr<llvm::SmallString<128>>
244 getNormalizedAbsolutePath(llvm::StringRef AbsolutePath);
245
246 /// Try to read configuration files from \p Directory using registered
247 /// \c ConfigHandlers.
248 std::optional<OptionsSource> tryReadConfigFile(llvm::StringRef Directory);
249
250 struct OptionsCache {
251 llvm::StringMap<size_t> Memorized;
252 llvm::SmallVector<OptionsSource, 4U> Storage;
253 } CachedOptions;
254 ClangTidyOptions OverrideOptions;
255 ConfigFileHandlers ConfigHandlers;
256 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
257};
258
259/// Implementation of ClangTidyOptions interface, which is used for
260/// '-config' command-line option.
261class ConfigOptionsProvider : public FileOptionsBaseProvider {
262public:
263 ConfigOptionsProvider(
264 ClangTidyGlobalOptions GlobalOptions, ClangTidyOptions DefaultOptions,
265 ClangTidyOptions ConfigOptions, ClangTidyOptions OverrideOptions,
266 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = nullptr);
267 std::vector<OptionsSource> getRawOptions(llvm::StringRef FileName) override;
268
269private:
270 ClangTidyOptions ConfigOptions;
271};
272
273/// Implementation of the \c ClangTidyOptionsProvider interface, which
274/// tries to find a configuration file in the closest parent directory of each
275/// source file.
276///
277/// By default, files named ".clang-tidy" will be considered, and the
278/// \c clang::tidy::parseConfiguration function will be used for parsing, but a
279/// custom set of configuration file names and parsing functions can be
280/// specified using the appropriate constructor.
281class FileOptionsProvider : public FileOptionsBaseProvider {
282public:
283 /// Initializes the \c FileOptionsProvider instance.
284 ///
285 /// \param GlobalOptions are just stored and returned to the caller of
286 /// \c getGlobalOptions.
287 ///
288 /// \param DefaultOptions are used for all settings not specified in a
289 /// configuration file.
290 ///
291 /// If any of the \param OverrideOptions fields are set, they will override
292 /// whatever options are read from the configuration file.
293 FileOptionsProvider(
294 ClangTidyGlobalOptions GlobalOptions, ClangTidyOptions DefaultOptions,
295 ClangTidyOptions OverrideOptions,
296 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = nullptr);
297
298 /// Initializes the \c FileOptionsProvider instance with a custom set
299 /// of configuration file handlers.
300 ///
301 /// \param GlobalOptions are just stored and returned to the caller of
302 /// \c getGlobalOptions.
303 ///
304 /// \param DefaultOptions are used for all settings not specified in a
305 /// configuration file.
306 ///
307 /// If any of the \param OverrideOptions fields are set, they will override
308 /// whatever options are read from the configuration file.
309 ///
310 /// \param ConfigHandlers specifies a custom set of configuration file
311 /// handlers. Each handler is a pair of configuration file name and a function
312 /// that can parse configuration from this file type. The configuration files
313 /// in each directory are searched for in the order of appearance in
314 /// \p ConfigHandlers.
315 FileOptionsProvider(ClangTidyGlobalOptions GlobalOptions,
316 ClangTidyOptions DefaultOptions,
317 ClangTidyOptions OverrideOptions,
318 ConfigFileHandlers ConfigHandlers);
319
320 std::vector<OptionsSource> getRawOptions(llvm::StringRef FileName) override;
321};
322
323/// Parses LineFilter from JSON and stores it to the \p Options.
324std::error_code parseLineFilter(llvm::StringRef LineFilter,
325 ClangTidyGlobalOptions &Options);
326
327/// Parses configuration from JSON and returns \c ClangTidyOptions or an
328/// error.
329llvm::ErrorOr<ClangTidyOptions>
330parseConfiguration(llvm::MemoryBufferRef Config);
331
332using DiagCallback = llvm::function_ref<void(const llvm::SMDiagnostic &)>;
333
334llvm::ErrorOr<ClangTidyOptions>
335parseConfigurationWithDiags(llvm::MemoryBufferRef Config, DiagCallback Handler);
336
337/// Serializes configuration to a YAML-encoded string.
338std::string configurationAsText(const ClangTidyOptions &Options);
339
340} // namespace clang::tidy
341
342#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYOPTIONS_H
343

source code of clang-tools-extra/clang-tidy/ClangTidyOptions.h

/body>