clang-tools  16.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/ADT/Optional.h"
37 #include "llvm/Support/SMLoc.h"
38 #include "llvm/Support/SourceMgr.h"
39 #include <string>
40 #include <vector>
41 
42 namespace clang {
43 namespace clangd {
44 namespace config {
45 
46 /// An entity written in config along, with its optional location in the file.
47 template <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 
57 private:
58  T Value;
59 };
60 
61 /// A chunk of configuration obtained from a config file, LSP, or elsewhere.
62 struct 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  llvm::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  /// - None: do not use a compilation database, just default flags.
171  llvm::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  llvm::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.
186  struct ExternalBlock {
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  llvm::Optional<Located<std::string>> File;
193  /// Address and port number for a clangd-index-server. e.g.
194  /// `123.1.1.1:13337`.
195  llvm::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  llvm::Optional<Located<std::string>> MountPoint;
200  };
201  llvm::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  llvm::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  /// - None
236  llvm::Optional<Located<std::string>> UnusedIncludes;
237 
238  /// Controls IncludeCleaner diagnostics.
239  struct IncludesBlock {
240  /// Regexes that will be used to avoid diagnosing certain includes as
241  /// unused or missing. These can match any suffix of the header file in
242  /// question.
243  std::vector<Located<std::string>> IgnoreHeader;
244  };
246 
247  /// Controls how clang-tidy will run over the code base.
248  ///
249  /// The settings are merged with any settings found in .clang-tidy
250  /// configuration files with these ones taking precedence.
251  struct ClangTidyBlock {
252  std::vector<Located<std::string>> Add;
253  /// List of checks to disable.
254  /// Takes precedence over Add. To enable all llvm checks except include
255  /// order:
256  /// Add: llvm-*
257  /// Remove: llvm-include-order
258  std::vector<Located<std::string>> Remove;
259 
260  /// A Key-Value pair list of options to pass to clang-tidy checks
261  /// These take precedence over options specified in clang-tidy
262  /// configuration files. Example:
263  /// CheckOptions:
264  /// readability-braces-around-statements.ShortStatementLines: 2
265  std::vector<std::pair<Located<std::string>, Located<std::string>>>
267  };
269  };
271 
272  // Describes the style of the codebase, beyond formatting.
273  struct StyleBlock {
274  // Namespaces that should always be fully qualified, meaning no "using"
275  // declarations, always spell out the whole name (with or without leading
276  // ::). All nested namespaces are affected as well.
277  // Affects availability of the AddUsing tweak.
278  std::vector<Located<std::string>> FullyQualifiedNamespaces;
279  };
281 
282  /// Describes code completion preferences.
284  /// Whether code completion should include suggestions from scopes that are
285  /// not visible. The required scope prefix will be inserted.
286  llvm::Optional<Located<bool>> AllScopes;
287  };
289 
290  /// Describes hover preferences.
291  struct HoverBlock {
292  /// Whether hover show a.k.a type.
293  llvm::Optional<Located<bool>> ShowAKA;
294  };
296 
297  /// Configures labels shown inline with the code.
299  /// Enables/disables the inlay-hints feature.
300  llvm::Optional<Located<bool>> Enabled;
301 
302  /// Show parameter names before function arguments.
303  llvm::Optional<Located<bool>> ParameterNames;
304  /// Show deduced types for `auto`.
305  llvm::Optional<Located<bool>> DeducedTypes;
306  /// Show designators in aggregate initialization.
307  llvm::Optional<Located<bool>> Designators;
308  };
310 };
311 
312 } // namespace config
313 } // namespace clangd
314 } // namespace clang
315 
316 #endif
clang::clangd::config::Fragment::SourceInfo::Location
llvm::SMLoc Location
The start of the original source for this fragment.
Definition: ConfigFragment.h:91
clang::clangd::IndexFileFormat::YAML
@ YAML
clang::clangd::config::Fragment::parseYAML
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:413
clang::clangd::config::Fragment::CompileFlags
CompileFlagsBlock CompileFlags
Definition: ConfigFragment.h:173
clang::clangd::config::Fragment::IndexBlock::ExternalBlock::Server
llvm::Optional< Located< std::string > > Server
Address and port number for a clangd-index-server.
Definition: ConfigFragment.h:195
clang::clangd::config::Fragment::CompileFlagsBlock
Conditions in the CompileFlags block affect how a file is parsed.
Definition: ConfigFragment.h:134
clang::clangd::config::Fragment::CompileFlagsBlock::Compiler
llvm::Optional< Located< std::string > > Compiler
Override the compiler executable name to simulate.
Definition: ConfigFragment.h:143
clang::clangd::config::Fragment::DiagnosticsBlock::ClangTidyBlock::CheckOptions
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...
Definition: ConfigFragment.h:266
clang::clangd::config::Fragment::IndexBlock
Controls how clangd understands code outside the current file.
Definition: ConfigFragment.h:178
clang::clangd::config::Fragment::IndexBlock::Background
llvm::Optional< Located< std::string > > Background
Whether files are built in the background to produce a project index.
Definition: ConfigFragment.h:182
ConfigProvider.h
clang::clangd::config::Fragment::compile
CompiledFragment compile(DiagnosticCallback) &&
Analyzes and consumes this fragment, possibly yielding more diagnostics.
Definition: ConfigCompile.cpp:605
clang::clangd::config::Fragment::IfBlock::PathMatch
std::vector< Located< std::string > > PathMatch
The file being processed must fully match a regular expression.
Definition: ConfigFragment.h:114
clang::clangd::config::Located::Range
llvm::SMRange Range
Definition: ConfigFragment.h:51
clang::clangd::config::Fragment::DiagnosticsBlock
Controls behavior of diagnostics (errors and warnings).
Definition: ConfigFragment.h:209
clang::clangd::config::Fragment::IfBlock
Conditions in the If block restrict when a Fragment applies.
Definition: ConfigFragment.h:112
clang::clangd::config::Fragment::Completion
CompletionBlock Completion
Definition: ConfigFragment.h:288
clang::clangd::config::Fragment::DiagnosticsBlock::IncludesBlock::IgnoreHeader
std::vector< Located< std::string > > IgnoreHeader
Regexes that will be used to avoid diagnosing certain includes as unused or missing.
Definition: ConfigFragment.h:243
clang::clangd::config::Located
An entity written in config along, with its optional location in the file.
Definition: ConfigFragment.h:47
clang::clangd::config::Located::operator->
T * operator->()
Definition: ConfigFragment.h:52
clang::clangd::config::Fragment::Diagnostics
DiagnosticsBlock Diagnostics
Definition: ConfigFragment.h:270
clang::clangd::config::Located::Located
Located(T Value, llvm::SMRange Range={})
Definition: ConfigFragment.h:48
clang::clangd::config::Fragment::IndexBlock::ExternalBlock
An external index uses data source outside of clangd itself.
Definition: ConfigFragment.h:186
clang::clangd::config::Fragment::StyleBlock::FullyQualifiedNamespaces
std::vector< Located< std::string > > FullyQualifiedNamespaces
Definition: ConfigFragment.h:278
clang::clangd::config::Fragment::DiagnosticsBlock::IncludesBlock
Controls IncludeCleaner diagnostics.
Definition: ConfigFragment.h:239
clang::clangd::config::Fragment::CompileFlagsBlock::CompilationDatabase
llvm::Optional< Located< std::string > > CompilationDatabase
Directory to search for compilation database (compile_commands.json etc).
Definition: ConfigFragment.h:171
clang::clangd::config::Fragment::CompletionBlock
Describes code completion preferences.
Definition: ConfigFragment.h:283
clang::clangd::config::Fragment::InlayHintsBlock::ParameterNames
llvm::Optional< Located< bool > > ParameterNames
Show parameter names before function arguments.
Definition: ConfigFragment.h:303
clang::clangd::config::Fragment::DiagnosticsBlock::Includes
IncludesBlock Includes
Definition: ConfigFragment.h:245
clang::clangd::config::Fragment::IndexBlock::External
llvm::Optional< Located< ExternalBlock > > External
Definition: ConfigFragment.h:201
clang::clangd::config::Fragment::DiagnosticsBlock::UnusedIncludes
llvm::Optional< Located< std::string > > UnusedIncludes
Controls how clangd will correct "unnecessary #include directives.
Definition: ConfigFragment.h:236
clang::clangd::config::Fragment::DiagnosticsBlock::ClangTidyBlock
Controls how clang-tidy will run over the code base.
Definition: ConfigFragment.h:251
clang::clangd::config::Fragment::DiagnosticsBlock::ClangTidyBlock::Add
std::vector< Located< std::string > > Add
Definition: ConfigFragment.h:252
clang::clangd::config::Fragment::Source
SourceInfo Source
Definition: ConfigFragment.h:99
clang::clangd::config::Fragment::InlayHintsBlock::DeducedTypes
llvm::Optional< Located< bool > > DeducedTypes
Show deduced types for auto.
Definition: ConfigFragment.h:305
clang::clangd::config::Fragment::InlayHintsBlock::Enabled
llvm::Optional< Located< bool > > Enabled
Enables/disables the inlay-hints feature.
Definition: ConfigFragment.h:300
clang::clangd::config::Fragment::Index
IndexBlock Index
Definition: ConfigFragment.h:206
clang::clangd::config::Located::operator*
T & operator*()
Definition: ConfigFragment.h:54
clang::clangd::config::Fragment::Hover
HoverBlock Hover
Definition: ConfigFragment.h:295
clang::clangd::config::CompiledFragment
std::function< bool(const Params &, Config &)> CompiledFragment
A chunk of configuration that has been fully analyzed and is ready to apply.
Definition: ConfigProvider.h:56
clang::clangd::config::Fragment::IndexBlock::ExternalBlock::IsNone
Located< bool > IsNone
Whether the block is explicitly set to None.
Definition: ConfigFragment.h:189
clang::clangd::config::Fragment::SourceInfo::Directory
std::string Directory
Absolute path to directory the fragment is associated with.
Definition: ConfigFragment.h:94
clang::clangd::config::Fragment::DiagnosticsBlock::Suppress
std::vector< Located< std::string > > Suppress
Diagnostic codes that should be suppressed.
Definition: ConfigFragment.h:222
clang::clangd::config::Fragment::HoverBlock
Describes hover preferences.
Definition: ConfigFragment.h:291
clang::clangd::config::Fragment::DiagnosticsBlock::ClangTidyBlock::Remove
std::vector< Located< std::string > > Remove
List of checks to disable.
Definition: ConfigFragment.h:258
clang::clangd::config::Fragment::IndexBlock::StandardLibrary
llvm::Optional< Located< bool > > StandardLibrary
Definition: ConfigFragment.h:204
clang::clangd::config::Fragment::Style
StyleBlock Style
Definition: ConfigFragment.h:280
clang::clangd::config::Fragment::InlayHints
InlayHintsBlock InlayHints
Definition: ConfigFragment.h:309
clang::clangd::config::Fragment::SourceInfo::Manager
std::shared_ptr< llvm::SourceMgr > Manager
Retains a buffer of the original source this fragment was parsed from.
Definition: ConfigFragment.h:88
clang::clangd::Range
Definition: Protocol.h:185
clang::clangd::config::Fragment::HoverBlock::ShowAKA
llvm::Optional< Located< bool > > ShowAKA
Whether hover show a.k.a type.
Definition: ConfigFragment.h:293
clang::clangd::config::Fragment::StyleBlock
Definition: ConfigFragment.h:273
clang::clangd::config::Fragment::CompletionBlock::AllScopes
llvm::Optional< Located< bool > > AllScopes
Whether code completion should include suggestions from scopes that are not visible.
Definition: ConfigFragment.h:286
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::clangd::config::Fragment::IfBlock::HasUnrecognizedCondition
bool HasUnrecognizedCondition
An unrecognized key was found while parsing the condition.
Definition: ConfigFragment.h:120
clang::clangd::config::Fragment::SourceInfo
These fields are not part of the user-specified configuration, but instead are populated by the parse...
Definition: ConfigFragment.h:83
clang::clangd::config::Fragment::InlayHintsBlock::Designators
llvm::Optional< Located< bool > > Designators
Show designators in aggregate initialization.
Definition: ConfigFragment.h:307
clang::clangd::config::Fragment::IfBlock::PathExclude
std::vector< Located< std::string > > PathExclude
The file being processed must not fully match a regular expression.
Definition: ConfigFragment.h:116
clang::clangd::config::Fragment::DiagnosticsBlock::ClangTidy
ClangTidyBlock ClangTidy
Definition: ConfigFragment.h:268
clang::clangd::config::Fragment
A chunk of configuration obtained from a config file, LSP, or elsewhere.
Definition: ConfigFragment.h:62
clang::clangd::config::Fragment::SourceInfo::Trusted
bool Trusted
Whether this fragment is allowed to make critical security/privacy decisions.
Definition: ConfigFragment.h:97
clang::clangd::config::Fragment::IndexBlock::ExternalBlock::MountPoint
llvm::Optional< Located< std::string > > MountPoint
Source root governed by this index.
Definition: ConfigFragment.h:199
clang::clangd::config::Fragment::If
IfBlock If
Definition: ConfigFragment.h:122
clang::clangd::config::Fragment::CompileFlagsBlock::Remove
std::vector< Located< std::string > > Remove
List of flags to remove from the compile command.
Definition: ConfigFragment.h:164
clang::clangd::config::Fragment::InlayHintsBlock
Configures labels shown inline with the code.
Definition: ConfigFragment.h:298
clang::clangd::config::Fragment::IndexBlock::ExternalBlock::File
llvm::Optional< Located< std::string > > File
Path to an index file generated by clangd-indexer.
Definition: ConfigFragment.h:192
clang::clangd::config::Fragment::CompileFlagsBlock::Add
std::vector< Located< std::string > > Add
List of flags to append to the compile command.
Definition: ConfigFragment.h:146
clang::clangd::config::DiagnosticCallback
llvm::function_ref< void(const llvm::SMDiagnostic &)> DiagnosticCallback
Used to report problems in parsing or interpreting a config.
Definition: ConfigProvider.h:49