Skip to content

Commit 7a9194a

Browse files
authored
Merge pull request #164 from llvm/main
[pull] autopr from llvm:main
2 parents dd3ccf3 + f00a20e commit 7a9194a

File tree

641 files changed

+785890
-6925
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

641 files changed

+785890
-6925
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
#OS X specific files.
2222
.DS_store
2323

24+
# Ignore the user specified CMake presets in subproject directories.
25+
/*/CMakeUserPresets.json
26+
2427
# Nested build directory
2528
/build*
2629

clang-tools-extra/clangd/ClangdLSPServer.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1469,6 +1469,12 @@ ClangdLSPServer::ClangdLSPServer(class Transport &Transp,
14691469
MsgHandler(new MessageHandler(*this)), TFS(TFS),
14701470
SupportedSymbolKinds(defaultSymbolKinds()),
14711471
SupportedCompletionItemKinds(defaultCompletionItemKinds()), Opts(Opts) {
1472+
if (Opts.ConfigProvider) {
1473+
assert(!Opts.ContextProvider &&
1474+
"Only one of ConfigProvider and ContextProvider allowed!");
1475+
this->Opts.ContextProvider = ClangdServer::createConfiguredContextProvider(
1476+
Opts.ConfigProvider, this);
1477+
}
14721478

14731479
// clang-format off
14741480
MsgHandler->bind("initialize", &ClangdLSPServer::onInitialize);

clang-tools-extra/clangd/ClangdLSPServer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ class SymbolIndex;
4141
class ClangdLSPServer : private ClangdServer::Callbacks {
4242
public:
4343
struct Options : ClangdServer::Options {
44+
/// Supplies configuration (overrides ClangdServer::ContextProvider).
45+
config::Provider *ConfigProvider = nullptr;
4446
/// Look for compilation databases, rather than using compile commands
4547
/// set via LSP (extensions) only.
4648
bool UseDirBasedCDB = true;

clang-tools-extra/clangd/ClangdServer.cpp

Lines changed: 81 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -133,14 +133,14 @@ ClangdServer::Options::operator TUScheduler::Options() const {
133133
Opts.StorePreamblesInMemory = StorePreamblesInMemory;
134134
Opts.UpdateDebounce = UpdateDebounce;
135135
Opts.AsyncPreambleBuilds = AsyncPreambleBuilds;
136+
Opts.ContextProvider = ContextProvider;
136137
return Opts;
137138
}
138139

139140
ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB,
140141
const ThreadsafeFS &TFS, const Options &Opts,
141142
Callbacks *Callbacks)
142-
: ConfigProvider(Opts.ConfigProvider), CDB(CDB), TFS(TFS),
143-
ServerCallbacks(Callbacks),
143+
: CDB(CDB), TFS(TFS),
144144
DynamicIdx(Opts.BuildDynamicSymbolIndex
145145
? new FileIndex(Opts.HeavyweightDynamicSymbolIndex,
146146
Opts.CollectMainFileRefs)
@@ -153,14 +153,7 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB,
153153
// FIXME(ioeric): this can be slow and we may be able to index on less
154154
// critical paths.
155155
WorkScheduler(
156-
CDB,
157-
[&, this] {
158-
TUScheduler::Options O(Opts);
159-
O.ContextProvider = [this](PathRef P) {
160-
return createProcessingContext(P);
161-
};
162-
return O;
163-
}(),
156+
CDB, TUScheduler::Options(Opts),
164157
std::make_unique<UpdateIndexCallbacks>(
165158
DynamicIdx.get(), Callbacks, Opts.TheiaSemanticHighlighting)) {
166159
// Adds an index to the stack, at higher priority than existing indexes.
@@ -181,9 +174,7 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB,
181174
if (Callbacks)
182175
Callbacks->onBackgroundIndexProgress(S);
183176
};
184-
BGOpts.ContextProvider = [this](PathRef P) {
185-
return createProcessingContext(P);
186-
};
177+
BGOpts.ContextProvider = Opts.ContextProvider;
187178
BGOpts.CollectMainFileRefs = Opts.CollectMainFileRefs;
188179
BackgroundIdx = std::make_unique<BackgroundIndex>(
189180
TFS, CDB,
@@ -216,6 +207,83 @@ void ClangdServer::addDocument(PathRef File, llvm::StringRef Contents,
216207
BackgroundIdx->boostRelated(File);
217208
}
218209

210+
std::function<Context(PathRef)>
211+
ClangdServer::createConfiguredContextProvider(const config::Provider *Provider,
212+
Callbacks *Publish) {
213+
if (!Provider)
214+
return [](llvm::StringRef) { return Context::current().clone(); };
215+
216+
struct Impl {
217+
const config::Provider *Provider;
218+
ClangdServer::Callbacks *Publish;
219+
std::mutex PublishMu;
220+
221+
Impl(const config::Provider *Provider, ClangdServer::Callbacks *Publish)
222+
: Provider(Provider), Publish(Publish) {}
223+
224+
Context operator()(llvm::StringRef File) {
225+
config::Params Params;
226+
// Don't reread config files excessively often.
227+
// FIXME: when we see a config file change event, use the event timestamp?
228+
Params.FreshTime =
229+
std::chrono::steady_clock::now() - std::chrono::seconds(5);
230+
llvm::SmallString<256> PosixPath;
231+
if (!File.empty()) {
232+
assert(llvm::sys::path::is_absolute(File));
233+
llvm::sys::path::native(File, PosixPath, llvm::sys::path::Style::posix);
234+
Params.Path = PosixPath.str();
235+
}
236+
237+
llvm::StringMap<std::vector<Diag>> ReportableDiagnostics;
238+
Config C = Provider->getConfig(Params, [&](const llvm::SMDiagnostic &D) {
239+
// Create the map entry even for note diagnostics we don't report.
240+
// This means that when the file is parsed with no warnings, we
241+
// publish an empty set of diagnostics, clearing any the client has.
242+
handleDiagnostic(D, !Publish || D.getFilename().empty()
243+
? nullptr
244+
: &ReportableDiagnostics[D.getFilename()]);
245+
});
246+
// Blindly publish diagnostics for the (unopened) parsed config files.
247+
// We must avoid reporting diagnostics for *the same file* concurrently.
248+
// Source diags are published elsewhere, but those are different files.
249+
if (!ReportableDiagnostics.empty()) {
250+
std::lock_guard<std::mutex> Lock(PublishMu);
251+
for (auto &Entry : ReportableDiagnostics)
252+
Publish->onDiagnosticsReady(Entry.first(), /*Version=*/"",
253+
std::move(Entry.second));
254+
}
255+
return Context::current().derive(Config::Key, std::move(C));
256+
}
257+
258+
void handleDiagnostic(const llvm::SMDiagnostic &D,
259+
std::vector<Diag> *ClientDiagnostics) {
260+
switch (D.getKind()) {
261+
case llvm::SourceMgr::DK_Error:
262+
elog("config error at {0}:{1}:{2}: {3}", D.getFilename(), D.getLineNo(),
263+
D.getColumnNo(), D.getMessage());
264+
break;
265+
case llvm::SourceMgr::DK_Warning:
266+
log("config warning at {0}:{1}:{2}: {3}", D.getFilename(),
267+
D.getLineNo(), D.getColumnNo(), D.getMessage());
268+
break;
269+
case llvm::SourceMgr::DK_Note:
270+
case llvm::SourceMgr::DK_Remark:
271+
vlog("config note at {0}:{1}:{2}: {3}", D.getFilename(), D.getLineNo(),
272+
D.getColumnNo(), D.getMessage());
273+
ClientDiagnostics = nullptr; // Don't emit notes as LSP diagnostics.
274+
break;
275+
}
276+
if (ClientDiagnostics)
277+
ClientDiagnostics->push_back(toDiag(D, Diag::ClangdConfig));
278+
}
279+
};
280+
281+
// Copyable wrapper.
282+
return [I(std::make_shared<Impl>(Provider, Publish))](llvm::StringRef Path) {
283+
return (*I)(Path);
284+
};
285+
}
286+
219287
void ClangdServer::removeDocument(PathRef File) { WorkScheduler.remove(File); }
220288

221289
void ClangdServer::codeComplete(PathRef File, Position Pos,
@@ -802,62 +870,6 @@ llvm::StringMap<TUScheduler::FileStats> ClangdServer::fileStats() const {
802870
return WorkScheduler.fileStats();
803871
}
804872

805-
Context ClangdServer::createProcessingContext(PathRef File) const {
806-
if (!ConfigProvider)
807-
return Context::current().clone();
808-
809-
config::Params Params;
810-
// Don't reread config files excessively often.
811-
// FIXME: when we see a config file change event, use the event timestamp.
812-
Params.FreshTime = std::chrono::steady_clock::now() - std::chrono::seconds(5);
813-
llvm::SmallString<256> PosixPath;
814-
if (!File.empty()) {
815-
assert(llvm::sys::path::is_absolute(File));
816-
llvm::sys::path::native(File, PosixPath, llvm::sys::path::Style::posix);
817-
Params.Path = PosixPath.str();
818-
}
819-
820-
llvm::StringMap<std::vector<Diag>> ReportableDiagnostics;
821-
auto ConfigDiagnosticHandler = [&](const llvm::SMDiagnostic &D) {
822-
// Ensure we create the map entry even for note diagnostics we don't report.
823-
// This means that when the file is parsed with no warnings, we'll
824-
// publish an empty set of diagnostics, clearing any the client has.
825-
auto *Reportable = D.getFilename().empty()
826-
? nullptr
827-
: &ReportableDiagnostics[D.getFilename()];
828-
switch (D.getKind()) {
829-
case llvm::SourceMgr::DK_Error:
830-
elog("config error at {0}:{1}:{2}: {3}", D.getFilename(), D.getLineNo(),
831-
D.getColumnNo(), D.getMessage());
832-
if (Reportable)
833-
Reportable->push_back(toDiag(D, Diag::ClangdConfig));
834-
break;
835-
case llvm::SourceMgr::DK_Warning:
836-
log("config warning at {0}:{1}:{2}: {3}", D.getFilename(), D.getLineNo(),
837-
D.getColumnNo(), D.getMessage());
838-
if (Reportable)
839-
Reportable->push_back(toDiag(D, Diag::ClangdConfig));
840-
break;
841-
case llvm::SourceMgr::DK_Note:
842-
case llvm::SourceMgr::DK_Remark:
843-
vlog("config note at {0}:{1}:{2}: {3}", D.getFilename(), D.getLineNo(),
844-
D.getColumnNo(), D.getMessage());
845-
break;
846-
}
847-
};
848-
Config C = ConfigProvider->getConfig(Params, ConfigDiagnosticHandler);
849-
// Blindly publish diagnostics for the (unopened) parsed config files.
850-
// We must avoid reporting diagnostics for *the same file* concurrently.
851-
// Source file diags are published elsewhere, but those are different files.
852-
if (!ReportableDiagnostics.empty()) {
853-
std::lock_guard<std::mutex> Lock(ConfigDiagnosticsMu);
854-
for (auto &Entry : ReportableDiagnostics)
855-
ServerCallbacks->onDiagnosticsReady(Entry.first(), /*Version=*/"",
856-
std::move(Entry.second));
857-
}
858-
return Context::current().derive(Config::Key, std::move(C));
859-
}
860-
861873
LLVM_NODISCARD bool
862874
ClangdServer::blockUntilIdleForTest(llvm::Optional<double> TimeoutSeconds) {
863875
return WorkScheduler.blockUntilIdle(timeoutSeconds(TimeoutSeconds)) &&

clang-tools-extra/clangd/ClangdServer.h

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,12 @@ class ClangdServer {
8080
virtual void
8181
onBackgroundIndexProgress(const BackgroundQueue::Stats &Stats) {}
8282
};
83+
/// Creates a context provider that loads and installs config.
84+
/// Errors in loading config are reported as diagnostics via Callbacks.
85+
/// (This is typically used as ClangdServer::Options::ContextProvider).
86+
static std::function<Context(PathRef)>
87+
createConfiguredContextProvider(const config::Provider *Provider,
88+
ClangdServer::Callbacks *);
8389

8490
struct Options {
8591
/// To process requests asynchronously, ClangdServer spawns worker threads.
@@ -111,8 +117,16 @@ class ClangdServer {
111117
/// If set, use this index to augment code completion results.
112118
SymbolIndex *StaticIndex = nullptr;
113119

114-
/// If set, queried to obtain the configuration to handle each request.
115-
config::Provider *ConfigProvider = nullptr;
120+
/// If set, queried to derive a processing context for some work.
121+
/// Usually used to inject Config (see createConfiguredContextProvider).
122+
///
123+
/// When the provider is called, the active context will be that inherited
124+
/// from the request (e.g. addDocument()), or from the ClangdServer
125+
/// constructor if there is no such request (e.g. background indexing).
126+
///
127+
/// The path is an absolute path of the file being processed.
128+
/// If there is no particular file (e.g. project loading) then it is empty.
129+
std::function<Context(PathRef)> ContextProvider;
116130

117131
/// The Options provider to use when running clang-tidy. If null, clang-tidy
118132
/// checks will be disabled.
@@ -343,19 +357,8 @@ class ClangdServer {
343357
ArrayRef<tooling::Range> Ranges,
344358
Callback<tooling::Replacements> CB);
345359

346-
/// Derives a context for a task processing the specified source file.
347-
/// This includes the current configuration (see Options::ConfigProvider).
348-
/// The empty string means no particular file is the target.
349-
/// Rather than called by each feature, this is exposed to the components
350-
/// that control worker threads, like TUScheduler and BackgroundIndex.
351-
/// This means it's OK to do some IO here, and it cuts across all features.
352-
Context createProcessingContext(PathRef) const;
353-
config::Provider *ConfigProvider = nullptr;
354-
355360
const GlobalCompilationDatabase &CDB;
356361
const ThreadsafeFS &TFS;
357-
Callbacks *ServerCallbacks = nullptr;
358-
mutable std::mutex ConfigDiagnosticsMu;
359362

360363
Path ResourceDir;
361364
// The index used to look up symbols. This could be:

clang-tools-extra/clangd/index/Index.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,13 @@ void SwapIndex::relations(
7878

7979
llvm::unique_function<bool(llvm::StringRef) const>
8080
SwapIndex::indexedFiles() const {
81-
return snapshot()->indexedFiles();
81+
// The index snapshot should outlive this method return value.
82+
auto SnapShot = snapshot();
83+
auto IndexedFiles = SnapShot->indexedFiles();
84+
return [KeepAlive{std::move(SnapShot)},
85+
IndexContainsFile{std::move(IndexedFiles)}](llvm::StringRef File) {
86+
return IndexContainsFile(File);
87+
};
8288
}
8389

8490
size_t SwapIndex::estimateMemoryUsage() const {

clang-tools-extra/clangd/index/Merge.cpp

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,23 @@ bool MergedIndex::fuzzyFind(
4444
SymbolSlab Dyn = std::move(DynB).build();
4545

4646
llvm::DenseSet<SymbolID> SeenDynamicSymbols;
47-
auto DynamicContainsFile = Dynamic->indexedFiles();
48-
More |= Static->fuzzyFind(Req, [&](const Symbol &S) {
49-
// We expect the definition to see the canonical declaration, so it seems
50-
// to be enough to check only the definition if it exists.
51-
if (DynamicContainsFile(S.Definition ? S.Definition.FileURI
52-
: S.CanonicalDeclaration.FileURI))
53-
return;
54-
auto DynS = Dyn.find(S.ID);
55-
++StaticCount;
56-
if (DynS == Dyn.end())
57-
return Callback(S);
58-
++MergedCount;
59-
SeenDynamicSymbols.insert(S.ID);
60-
Callback(mergeSymbol(*DynS, S));
61-
});
47+
{
48+
auto DynamicContainsFile = Dynamic->indexedFiles();
49+
More |= Static->fuzzyFind(Req, [&](const Symbol &S) {
50+
// We expect the definition to see the canonical declaration, so it seems
51+
// to be enough to check only the definition if it exists.
52+
if (DynamicContainsFile(S.Definition ? S.Definition.FileURI
53+
: S.CanonicalDeclaration.FileURI))
54+
return;
55+
auto DynS = Dyn.find(S.ID);
56+
++StaticCount;
57+
if (DynS == Dyn.end())
58+
return Callback(S);
59+
++MergedCount;
60+
SeenDynamicSymbols.insert(S.ID);
61+
Callback(mergeSymbol(*DynS, S));
62+
});
63+
}
6264
SPAN_ATTACH(Tracer, "dynamic", DynamicCount);
6365
SPAN_ATTACH(Tracer, "static", StaticCount);
6466
SPAN_ATTACH(Tracer, "merged", MergedCount);
@@ -77,20 +79,22 @@ void MergedIndex::lookup(
7779
Dynamic->lookup(Req, [&](const Symbol &S) { B.insert(S); });
7880

7981
auto RemainingIDs = Req.IDs;
80-
auto DynamicContainsFile = Dynamic->indexedFiles();
81-
Static->lookup(Req, [&](const Symbol &S) {
82-
// We expect the definition to see the canonical declaration, so it seems
83-
// to be enough to check only the definition if it exists.
84-
if (DynamicContainsFile(S.Definition ? S.Definition.FileURI
85-
: S.CanonicalDeclaration.FileURI))
86-
return;
87-
const Symbol *Sym = B.find(S.ID);
88-
RemainingIDs.erase(S.ID);
89-
if (!Sym)
90-
Callback(S);
91-
else
92-
Callback(mergeSymbol(*Sym, S));
93-
});
82+
{
83+
auto DynamicContainsFile = Dynamic->indexedFiles();
84+
Static->lookup(Req, [&](const Symbol &S) {
85+
// We expect the definition to see the canonical declaration, so it seems
86+
// to be enough to check only the definition if it exists.
87+
if (DynamicContainsFile(S.Definition ? S.Definition.FileURI
88+
: S.CanonicalDeclaration.FileURI))
89+
return;
90+
const Symbol *Sym = B.find(S.ID);
91+
RemainingIDs.erase(S.ID);
92+
if (!Sym)
93+
Callback(S);
94+
else
95+
Callback(mergeSymbol(*Sym, S));
96+
});
97+
}
9498
for (const auto &ID : RemainingIDs)
9599
if (const Symbol *Sym = B.find(ID))
96100
Callback(*Sym);

clang-tools-extra/clangd/unittests/ClangdTests.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,8 @@ TEST(ClangdServerTest, RespectsConfig) {
348348
} CfgProvider;
349349

350350
auto Opts = ClangdServer::optsForTest();
351-
Opts.ConfigProvider = &CfgProvider;
351+
Opts.ContextProvider =
352+
ClangdServer::createConfiguredContextProvider(&CfgProvider, nullptr);
352353
OverlayCDB CDB(/*Base=*/nullptr, /*FallbackFlags=*/{},
353354
tooling::ArgumentsAdjuster(CommandMangler::forTests()));
354355
MockFS FS;

clang/docs/ClangCommandLineReference.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,9 +1143,9 @@ Set directory to include search path with prefix
11431143

11441144
Add directory to SYSTEM include search path, absolute paths are relative to -isysroot
11451145

1146-
.. option:: --libomptarget-nvptx-path=<arg>
1146+
.. option:: --libomptarget-nvptx-bc-path=<arg>
11471147

1148-
Path to libomptarget-nvptx libraries
1148+
Path to libomptarget-nvptx bitcode library
11491149

11501150
.. option:: --ptxas-path=<arg>
11511151

0 commit comments

Comments
 (0)