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