clang-tools 20.0.0git
ConfigFragment.h
Go to the documentation of this file.
1//===--- ConfigFragment.h - Unit of user-specified configuration -*- 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// Various clangd features have configurable behaviour (or can be disabled).
10// The configuration system allows users to control this:
11// - in a user config file, a project config file, via LSP, or via flags
12// - specifying different settings for different files
13//
14// This file defines the config::Fragment structure which models one piece of
15// configuration as obtained from a source like a file.
16//
17// This is distinct from how the config is interpreted (CompiledFragment),
18// combined (Provider) and exposed to the rest of clangd (Config).
19//
20//===----------------------------------------------------------------------===//
21//
22// To add a new configuration option, you must:
23// - add its syntactic form to Fragment
24// - update ConfigYAML.cpp to parse it
25// - add its semantic form to Config (in Config.h)
26// - update ConfigCompile.cpp to map Fragment -> Config
27// - make use of the option inside clangd
28// - document the new option (config.md in the llvm/clangd-www repository)
29//
30//===----------------------------------------------------------------------===//
31
32#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONFIGFRAGMENT_H
33#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONFIGFRAGMENT_H
34
35#include "ConfigProvider.h"
36#include "llvm/Support/SMLoc.h"
37#include "llvm/Support/SourceMgr.h"
38#include <optional>
39#include <string>
40#include <vector>
41
42namespace clang {
43namespace clangd {
44namespace config {
45
46/// An entity written in config along, with its optional location in the file.
47template <typename T> struct Located {
48 Located(T Value, llvm::SMRange Range = {})
49 : Range(Range), Value(std::move(Value)) {}
50
51 llvm::SMRange Range;
52 T *operator->() { return &Value; }
53 const T *operator->() const { return &Value; }
54 T &operator*() { return Value; }
55 const T &operator*() const { return Value; }
56
57private:
58 T Value;
59};
60
61/// A chunk of configuration obtained from a config file, LSP, or elsewhere.
62struct Fragment {
63 /// Parses fragments from a YAML file (one from each --- delimited document).
64 /// Documents that contained fatal errors are omitted from the results.
65 /// BufferName is used for the SourceMgr and diagnostics.
66 static std::vector<Fragment> parseYAML(llvm::StringRef YAML,
67 llvm::StringRef BufferName,
69
70 /// Analyzes and consumes this fragment, possibly yielding more diagnostics.
71 /// This always produces a usable result (errors are recovered).
72 ///
73 /// Typically, providers will compile a Fragment once when it's first loaded,
74 /// caching the result for reuse.
75 /// Like a compiled program, this is good for performance and also encourages
76 /// errors to be reported early and only once.
77 ///
78 /// The returned function is a cheap-copyable wrapper of refcounted internals.
80
81 /// These fields are not part of the user-specified configuration, but
82 /// instead are populated by the parser to describe the configuration source.
83 struct SourceInfo {
84 /// Retains a buffer of the original source this fragment was parsed from.
85 /// Locations within Located<T> objects point into this SourceMgr.
86 /// Shared because multiple fragments are often parsed from one (YAML) file.
87 /// May be null, then all locations should be ignored.
88 std::shared_ptr<llvm::SourceMgr> Manager;
89 /// The start of the original source for this fragment.
90 /// Only valid if SourceManager is set.
91 llvm::SMLoc Location;
92 /// Absolute path to directory the fragment is associated with. Relative
93 /// paths mentioned in the fragment are resolved against this.
94 std::string Directory;
95 /// Whether this fragment is allowed to make critical security/privacy
96 /// decisions.
97 bool Trusted = false;
98 };
100
101 /// Conditions in the If block restrict when a Fragment applies.
102 ///
103 /// Each separate condition must match (combined with AND).
104 /// When one condition has multiple values, any may match (combined with OR).
105 /// e.g. `PathMatch: [foo/.*, bar/.*]` matches files in either directory.
106 ///
107 /// Conditions based on a file's path use the following form:
108 /// - if the fragment came from a project directory, the path is relative
109 /// - if the fragment is global (e.g. user config), the path is absolute
110 /// - paths always use forward-slashes (UNIX-style)
111 /// If no file is being processed, these conditions will not match.
112 struct IfBlock {
113 /// The file being processed must fully match a regular expression.
114 std::vector<Located<std::string>> PathMatch;
115 /// The file being processed must *not* fully match a regular expression.
116 std::vector<Located<std::string>> PathExclude;
117
118 /// An unrecognized key was found while parsing the condition.
119 /// The condition will evaluate to false.
121 };
123
124 /// Conditions in the CompileFlags block affect how a file is parsed.
125 ///
126 /// clangd emulates how clang would interpret a file.
127 /// By default, it behaves roughly like `clang $FILENAME`, but real projects
128 /// usually require setting the include path (with the `-I` flag), defining
129 /// preprocessor symbols, configuring warnings etc.
130 /// Often, a compilation database specifies these compile commands. clangd
131 /// searches for compile_commands.json in parents of the source file.
132 ///
133 /// This section modifies how the compile command is constructed.
135 /// Override the compiler executable name to simulate.
136 ///
137 /// The name can affect how flags are parsed (clang++ vs clang).
138 /// If the executable name is in the --query-driver allowlist, then it will
139 /// be invoked to extract include paths.
140 ///
141 /// (That this simply replaces argv[0], and may mangle commands that use
142 /// more complicated drivers like ccache).
143 std::optional<Located<std::string>> Compiler;
144
145 /// List of flags to append to the compile command.
146 std::vector<Located<std::string>> Add;
147 /// List of flags to remove from the compile command.
148 ///
149 /// - If the value is a recognized clang flag (like "-I") then it will be
150 /// removed along with any arguments. Synonyms like --include-dir= will
151 /// also be removed.
152 /// - Otherwise, if the value ends in * (like "-DFOO=*") then any argument
153 /// with the prefix will be removed.
154 /// - Otherwise any argument exactly matching the value is removed.
155 ///
156 /// In all cases, -Xclang is also removed where needed.
157 ///
158 /// Example:
159 /// Command: clang++ --include-directory=/usr/include -DFOO=42 foo.cc
160 /// Remove: [-I, -DFOO=*]
161 /// Result: clang++ foo.cc
162 ///
163 /// Flags added by the same CompileFlags entry will not be removed.
164 std::vector<Located<std::string>> Remove;
165
166 /// Directory to search for compilation database (compile_commands.json
167 /// etc). Valid values are:
168 /// - A single path to a directory (absolute, or relative to the fragment)
169 /// - Ancestors: search all parent directories (the default)
170 /// - std::nullopt: do not use a compilation database, just default flags.
171 std::optional<Located<std::string>> CompilationDatabase;
172 };
174
175 /// Controls how clangd understands code outside the current file.
176 /// clangd's indexes provide information about symbols that isn't available
177 /// to clang's parser, such as incoming references.
178 struct IndexBlock {
179 /// Whether files are built in the background to produce a project index.
180 /// This is checked for translation units only, not headers they include.
181 /// Legal values are "Build" or "Skip".
182 std::optional<Located<std::string>> Background;
183 /// An external index uses data source outside of clangd itself. This is
184 /// usually prepared using clangd-indexer.
185 /// Exactly one source (File/Server) should be configured.
187 /// Whether the block is explicitly set to `None`. Can be used to clear
188 /// any external index specified before.
190 /// Path to an index file generated by clangd-indexer. Relative paths may
191 /// be used, if config fragment is associated with a directory.
192 std::optional<Located<std::string>> File;
193 /// Address and port number for a clangd-index-server. e.g.
194 /// `123.1.1.1:13337`.
195 std::optional<Located<std::string>> Server;
196 /// Source root governed by this index. Default is the directory
197 /// associated with the config fragment. Absolute in case of user config
198 /// and relative otherwise. Should always use forward-slashes.
199 std::optional<Located<std::string>> MountPoint;
200 };
201 std::optional<Located<ExternalBlock>> External;
202 // Whether the standard library visible from this file should be indexed.
203 // This makes all standard library symbols available, included or not.
204 std::optional<Located<bool>> StandardLibrary;
205 };
207
208 /// Controls behavior of diagnostics (errors and warnings).
210 /// Diagnostic codes that should be suppressed.
211 ///
212 /// Valid values are:
213 /// - *, to disable all diagnostics
214 /// - diagnostic codes exposed by clangd (e.g unknown_type, -Wunused-result)
215 /// - clang internal diagnostic codes (e.g. err_unknown_type)
216 /// - warning categories (e.g. unused-result)
217 /// - clang-tidy check names (e.g. bugprone-narrowing-conversions)
218 ///
219 /// This is a simple filter. Diagnostics can be controlled in other ways
220 /// (e.g. by disabling a clang-tidy check, or the -Wunused compile flag).
221 /// This often has other advantages, such as skipping some analysis.
222 std::vector<Located<std::string>> Suppress;
223
224 /// Controls how clangd will correct "unnecessary" #include directives.
225 /// clangd can warn if a header is `#include`d but not used, and suggest
226 /// removing it.
227 //
228 /// Strict means a header is unused if it does not *directly* provide any
229 /// symbol used in the file. Removing it may still break compilation if it
230 /// transitively includes headers that are used. This should be fixed by
231 /// including those headers directly.
232 ///
233 /// Valid values are:
234 /// - Strict
235 /// - std::nullopt
236 std::optional<Located<std::string>> UnusedIncludes;
237
238 /// Controls if clangd should analyze missing #include directives.
239 /// clangd will warn if no header providing a symbol is `#include`d
240 /// (missing) directly, and suggest adding it.
241 ///
242 /// Strict means a header providing a symbol is missing if it is not
243 /// *directly #include'd. The file might still compile if the header is
244 /// included transitively.
245 ///
246 /// Valid values are:
247 /// - Strict
248 /// - std::nullopt
249 std::optional<Located<std::string>> MissingIncludes;
250
251 /// Controls IncludeCleaner diagnostics.
253 /// Regexes that will be used to avoid diagnosing certain includes as
254 /// unused or missing. These can match any suffix of the header file in
255 /// question.
256 std::vector<Located<std::string>> IgnoreHeader;
257
258 /// If false (default), unused system headers will be ignored.
259 /// Standard library headers are analyzed regardless of this option.
260 std::optional<Located<bool>> AnalyzeAngledIncludes;
261 };
263
264 /// Controls how clang-tidy will run over the code base.
265 ///
266 /// The settings are merged with any settings found in .clang-tidy
267 /// configuration files with these ones taking precedence.
269 std::vector<Located<std::string>> Add;
270 /// List of checks to disable.
271 /// Takes precedence over Add. To enable all llvm checks except include
272 /// order:
273 /// Add: llvm-*
274 /// Remove: llvm-include-order
275 std::vector<Located<std::string>> Remove;
276
277 /// A Key-Value pair list of options to pass to clang-tidy checks
278 /// These take precedence over options specified in clang-tidy
279 /// configuration files. Example:
280 /// CheckOptions:
281 /// readability-braces-around-statements.ShortStatementLines: 2
282 std::vector<std::pair<Located<std::string>, Located<std::string>>>
284
285 /// Whether to run checks that may slow down clangd.
286 /// Strict: Run only checks measured to be fast. (Default)
287 /// This excludes recently-added checks we have not timed yet.
288 /// Loose: Run checks unless they are known to be slow.
289 /// None: Run checks regardless of their speed.
290 std::optional<Located<std::string>> FastCheckFilter;
291 };
293 };
295
296 // Describes the style of the codebase, beyond formatting.
297 struct StyleBlock {
298 // Namespaces that should always be fully qualified, meaning no "using"
299 // declarations, always spell out the whole name (with or without leading
300 // ::). All nested namespaces are affected as well.
301 // Affects availability of the AddUsing tweak.
302 std::vector<Located<std::string>> FullyQualifiedNamespaces;
303 };
305
306 /// Describes code completion preferences.
308 /// Whether code completion should include suggestions from scopes that are
309 /// not visible. The required scope prefix will be inserted.
310 std::optional<Located<bool>> AllScopes;
311 };
313
314 /// Describes hover preferences.
315 struct HoverBlock {
316 /// Whether hover show a.k.a type.
317 std::optional<Located<bool>> ShowAKA;
318 };
320
321 /// Configures labels shown inline with the code.
323 /// Enables/disables the inlay-hints feature.
324 std::optional<Located<bool>> Enabled;
325
326 /// Show parameter names before function arguments.
327 std::optional<Located<bool>> ParameterNames;
328 /// Show deduced types for `auto`.
329 std::optional<Located<bool>> DeducedTypes;
330 /// Show designators in aggregate initialization.
331 std::optional<Located<bool>> Designators;
332 /// Show defined symbol names at the end of a definition block.
333 std::optional<Located<bool>> BlockEnd;
334 /// Limit the length of type name hints. (0 means no limit)
335 std::optional<Located<uint32_t>> TypeNameLimit;
336 };
338
339 /// Configures semantic tokens that are produced by clangd.
341 /// Disables clangd to produce semantic tokens for the given kinds.
342 std::vector<Located<std::string>> DisabledKinds;
343 /// Disables clangd to assign semantic tokens with the given modifiers.
344 std::vector<Located<std::string>> DisabledModifiers;
345 };
347};
348
349} // namespace config
350} // namespace clangd
351} // namespace clang
352
353#endif
std::function< bool(const Params &, Config &)> CompiledFragment
A chunk of configuration that has been fully analyzed and is ready to apply.
llvm::function_ref< void(const llvm::SMDiagnostic &)> DiagnosticCallback
Used to report problems in parsing or interpreting a config.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Conditions in the CompileFlags block affect how a file is parsed.
std::vector< Located< std::string > > Remove
List of flags to remove from the compile command.
std::optional< Located< std::string > > Compiler
Override the compiler executable name to simulate.
std::vector< Located< std::string > > Add
List of flags to append to the compile command.
std::optional< Located< std::string > > CompilationDatabase
Directory to search for compilation database (compile_commands.json etc).
Describes code completion preferences.
std::optional< Located< bool > > AllScopes
Whether code completion should include suggestions from scopes that are not visible.
Controls how clang-tidy will run over the code base.
std::vector< Located< std::string > > Remove
List of checks to disable.
std::optional< Located< std::string > > FastCheckFilter
Whether to run checks that may slow down clangd.
std::vector< std::pair< Located< std::string >, Located< std::string > > > CheckOptions
A Key-Value pair list of options to pass to clang-tidy checks These take precedence over options spec...
std::optional< Located< bool > > AnalyzeAngledIncludes
If false (default), unused system headers will be ignored.
std::vector< Located< std::string > > IgnoreHeader
Regexes that will be used to avoid diagnosing certain includes as unused or missing.
Controls behavior of diagnostics (errors and warnings).
std::optional< Located< std::string > > MissingIncludes
Controls if clangd should analyze missing #include directives.
std::optional< Located< std::string > > UnusedIncludes
Controls how clangd will correct "unnecessary" #include directives.
std::vector< Located< std::string > > Suppress
Diagnostic codes that should be suppressed.
std::optional< Located< bool > > ShowAKA
Whether hover show a.k.a type.
Conditions in the If block restrict when a Fragment applies.
std::vector< Located< std::string > > PathExclude
The file being processed must not fully match a regular expression.
bool HasUnrecognizedCondition
An unrecognized key was found while parsing the condition.
std::vector< Located< std::string > > PathMatch
The file being processed must fully match a regular expression.
An external index uses data source outside of clangd itself.
std::optional< Located< std::string > > MountPoint
Source root governed by this index.
std::optional< Located< std::string > > Server
Address and port number for a clangd-index-server.
Located< bool > IsNone
Whether the block is explicitly set to None.
std::optional< Located< std::string > > File
Path to an index file generated by clangd-indexer.
Controls how clangd understands code outside the current file.
std::optional< Located< bool > > StandardLibrary
std::optional< Located< std::string > > Background
Whether files are built in the background to produce a project index.
std::optional< Located< ExternalBlock > > External
Configures labels shown inline with the code.
std::optional< Located< bool > > BlockEnd
Show defined symbol names at the end of a definition block.
std::optional< Located< bool > > Enabled
Enables/disables the inlay-hints feature.
std::optional< Located< bool > > Designators
Show designators in aggregate initialization.
std::optional< Located< bool > > ParameterNames
Show parameter names before function arguments.
std::optional< Located< bool > > DeducedTypes
Show deduced types for auto.
std::optional< Located< uint32_t > > TypeNameLimit
Limit the length of type name hints. (0 means no limit)
Configures semantic tokens that are produced by clangd.
std::vector< Located< std::string > > DisabledKinds
Disables clangd to produce semantic tokens for the given kinds.
std::vector< Located< std::string > > DisabledModifiers
Disables clangd to assign semantic tokens with the given modifiers.
These fields are not part of the user-specified configuration, but instead are populated by the parse...
bool Trusted
Whether this fragment is allowed to make critical security/privacy decisions.
std::string Directory
Absolute path to directory the fragment is associated with.
std::shared_ptr< llvm::SourceMgr > Manager
Retains a buffer of the original source this fragment was parsed from.
llvm::SMLoc Location
The start of the original source for this fragment.
std::vector< Located< std::string > > FullyQualifiedNamespaces
A chunk of configuration obtained from a config file, LSP, or elsewhere.
CompiledFragment compile(DiagnosticCallback) &&
Analyzes and consumes this fragment, possibly yielding more diagnostics.
SemanticTokensBlock SemanticTokens
static std::vector< Fragment > parseYAML(llvm::StringRef YAML, llvm::StringRef BufferName, DiagnosticCallback)
Parses fragments from a YAML file (one from each — delimited document).
Definition: ConfigYAML.cpp:457
An entity written in config along, with its optional location in the file.
Located(T Value, llvm::SMRange Range={})