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

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