1 //===--- Config.h - User configuration of clangd behavior --------*- 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 // This file defines "resolved" configuration seen by features within clangd. 11 // For example, settings may vary per-file, the resolved Config only contains 12 // settings that apply to the current file. 13 // 14 // This is distinct from how the config is specified by the user (Fragment) 15 // interpreted (CompiledFragment), and combined (Provider). 16 // ConfigFragment.h describes the steps to add a new configuration option. 17 // 18 // Because this structure is shared throughout clangd, it's a potential source 19 // of layering problems. Config should be expressed in terms of simple 20 // vocubulary types where possible. 21 // 22 //===----------------------------------------------------------------------===// 23 24 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONFIG_H 25 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONFIG_H 26 27 #include "support/Context.h" 28 #include "llvm/ADT/FunctionExtras.h" 29 #include "llvm/ADT/Optional.h" 30 #include "llvm/ADT/StringMap.h" 31 #include <string> 32 #include <vector> 33 34 namespace clang { 35 namespace clangd { 36 37 /// Settings that express user/project preferences and control clangd behavior. 38 /// 39 /// Generally, features should consume Config::current() and the caller is 40 /// responsible for setting it appropriately. In practice these callers are 41 /// ClangdServer, TUScheduler, and BackgroundQueue. 42 struct Config { 43 /// Returns the Config of the current Context, or an empty configuration. 44 static const Config ¤t(); 45 /// Context key which can be used to set the current Config. 46 static clangd::Key<Config> Key; 47 48 Config() = default; 49 Config(const Config &) = delete; 50 Config &operator=(const Config &) = delete; 51 Config(Config &&) = default; 52 Config &operator=(Config &&) = default; 53 54 /// Controls how the compile command for the current file is determined. 55 struct { 56 // Edits to apply to the compile command, in sequence. 57 std::vector<llvm::unique_function<void(std::vector<std::string> &) const>> 58 Edits; 59 } CompileFlags; 60 61 enum class BackgroundPolicy { Build, Skip }; 62 /// Describes an external index configuration. 63 struct ExternalIndexSpec { 64 enum { File, Server } Kind; 65 /// This is one of: 66 /// - Address of a clangd-index-server, in the form of "ip:port". 67 /// - Absolute path to an index produced by clangd-indexer. 68 std::string Location; 69 /// Absolute path to source root this index is associated with, uses 70 /// forward-slashes. 71 std::string MountPoint; 72 }; 73 /// Controls background-index behavior. 74 struct { 75 /// Whether this TU should be indexed. 76 BackgroundPolicy Background = BackgroundPolicy::Build; 77 llvm::Optional<ExternalIndexSpec> External; 78 } Index; 79 80 /// Style of the codebase. 81 struct { 82 // Namespaces that should always be fully qualified, meaning no "using" 83 // declarations, always spell out the whole name (with or without leading 84 // ::). All nested namespaces are affected as well. 85 std::vector<std::string> FullyQualifiedNamespaces; 86 } Style; 87 88 /// Configures what clang-tidy checks to run and options to use with them. 89 struct { 90 // A comma-seperated list of globs to specify which clang-tidy checks to 91 // run. 92 std::string Checks; 93 llvm::StringMap<std::string> CheckOptions; 94 } ClangTidy; 95 }; 96 97 } // namespace clangd 98 } // namespace clang 99 100 namespace llvm { 101 template <> struct DenseMapInfo<clang::clangd::Config::ExternalIndexSpec> { 102 using ExternalIndexSpec = clang::clangd::Config::ExternalIndexSpec; 103 static inline ExternalIndexSpec getEmptyKey() { 104 return {ExternalIndexSpec::File, "", ""}; 105 } 106 static inline ExternalIndexSpec getTombstoneKey() { 107 return {ExternalIndexSpec::File, "TOMB", "STONE"}; 108 } 109 static unsigned getHashValue(const ExternalIndexSpec &Val) { 110 return llvm::hash_combine(Val.Kind, Val.Location, Val.MountPoint); 111 } 112 static bool isEqual(const ExternalIndexSpec &LHS, 113 const ExternalIndexSpec &RHS) { 114 return std::tie(LHS.Kind, LHS.Location, LHS.MountPoint) == 115 std::tie(RHS.Kind, RHS.Location, RHS.MountPoint); 116 } 117 }; 118 } // namespace llvm 119 120 #endif 121