Skip to content

Commit ccdb56a

Browse files
committed
Reland "[clangd] Indexing of standard library"
This reverts commit 76ddbb1.
1 parent 854c273 commit ccdb56a

18 files changed

+713
-21
lines changed

clang-tools-extra/clangd/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ add_clang_library(clangDaemon
119119
index/Ref.cpp
120120
index/Relation.cpp
121121
index/Serialization.cpp
122+
index/StdLib.cpp
122123
index/Symbol.cpp
123124
index/SymbolCollector.cpp
124125
index/SymbolID.cpp

clang-tools-extra/clangd/ClangdServer.cpp

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "index/CanonicalIncludes.h"
2727
#include "index/FileIndex.h"
2828
#include "index/Merge.h"
29+
#include "index/StdLib.h"
2930
#include "refactor/Rename.h"
3031
#include "refactor/Tweak.h"
3132
#include "support/Cancellation.h"
@@ -59,16 +60,39 @@ namespace {
5960
// Update the FileIndex with new ASTs and plumb the diagnostics responses.
6061
struct UpdateIndexCallbacks : public ParsingCallbacks {
6162
UpdateIndexCallbacks(FileIndex *FIndex,
62-
ClangdServer::Callbacks *ServerCallbacks)
63-
: FIndex(FIndex), ServerCallbacks(ServerCallbacks) {}
63+
ClangdServer::Callbacks *ServerCallbacks,
64+
const ThreadsafeFS &TFS, AsyncTaskRunner *Tasks)
65+
: FIndex(FIndex), ServerCallbacks(ServerCallbacks), TFS(TFS),
66+
Tasks(Tasks) {}
6467

65-
void onPreambleAST(PathRef Path, llvm::StringRef Version, ASTContext &Ctx,
68+
void onPreambleAST(PathRef Path, llvm::StringRef Version,
69+
const CompilerInvocation &CI, ASTContext &Ctx,
6670
Preprocessor &PP,
6771
const CanonicalIncludes &CanonIncludes) override {
72+
// If this preamble uses a standard library we haven't seen yet, index it.
73+
if (FIndex)
74+
if (auto Loc = Stdlib.add(*CI.getLangOpts(), PP.getHeaderSearchInfo()))
75+
indexStdlib(CI, std::move(*Loc));
76+
6877
if (FIndex)
6978
FIndex->updatePreamble(Path, Version, Ctx, PP, CanonIncludes);
7079
}
7180

81+
void indexStdlib(const CompilerInvocation &CI, StdLibLocation Loc) {
82+
auto Task = [this, LO(*CI.getLangOpts()), Loc(std::move(Loc)),
83+
CI(std::make_unique<CompilerInvocation>(CI))]() mutable {
84+
IndexFileIn IF;
85+
IF.Symbols = indexStandardLibrary(std::move(CI), Loc, TFS);
86+
if (Stdlib.isBest(LO))
87+
FIndex->updatePreamble(std::move(IF));
88+
};
89+
if (Tasks)
90+
// This doesn't have a semaphore to enforce -j, but it's rare.
91+
Tasks->runAsync("IndexStdlib", std::move(Task));
92+
else
93+
Task();
94+
}
95+
7296
void onMainAST(PathRef Path, ParsedAST &AST, PublishFn Publish) override {
7397
if (FIndex)
7498
FIndex->updateMain(Path, AST);
@@ -103,6 +127,9 @@ struct UpdateIndexCallbacks : public ParsingCallbacks {
103127
private:
104128
FileIndex *FIndex;
105129
ClangdServer::Callbacks *ServerCallbacks;
130+
const ThreadsafeFS &TFS;
131+
StdLibSet Stdlib;
132+
AsyncTaskRunner *Tasks;
106133
};
107134

108135
class DraftStoreFS : public ThreadsafeFS {
@@ -154,12 +181,15 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB,
154181
Transient(Opts.ImplicitCancellation ? TUScheduler::InvalidateOnUpdate
155182
: TUScheduler::NoInvalidation),
156183
DirtyFS(std::make_unique<DraftStoreFS>(TFS, DraftMgr)) {
184+
if (Opts.AsyncThreadsCount != 0)
185+
IndexTasks.emplace();
157186
// Pass a callback into `WorkScheduler` to extract symbols from a newly
158187
// parsed file and rebuild the file index synchronously each time an AST
159188
// is parsed.
160-
WorkScheduler.emplace(
161-
CDB, TUScheduler::Options(Opts),
162-
std::make_unique<UpdateIndexCallbacks>(DynamicIdx.get(), Callbacks));
189+
WorkScheduler.emplace(CDB, TUScheduler::Options(Opts),
190+
std::make_unique<UpdateIndexCallbacks>(
191+
DynamicIdx.get(), Callbacks, TFS,
192+
IndexTasks ? IndexTasks.getPointer() : nullptr));
163193
// Adds an index to the stack, at higher priority than existing indexes.
164194
auto AddIndex = [&](SymbolIndex *Idx) {
165195
if (this->Index != nullptr) {
@@ -975,6 +1005,9 @@ ClangdServer::blockUntilIdleForTest(llvm::Optional<double> TimeoutSeconds) {
9751005
// and we're blocking the main thread.
9761006
if (!WorkScheduler->blockUntilIdle(timeoutSeconds(TimeoutSeconds)))
9771007
return false;
1008+
// TUScheduler is the only thing that starts background indexing work.
1009+
if (IndexTasks && !IndexTasks->wait(timeoutSeconds(TimeoutSeconds)))
1010+
return false;
9781011

9791012
// Unfortunately we don't have strict topological order between the rest of
9801013
// the components. E.g. CDB broadcast triggers backrgound indexing.

clang-tools-extra/clangd/ClangdServer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,7 @@ class ClangdServer {
428428
mutable std::mutex CachedCompletionFuzzyFindRequestMutex;
429429

430430
llvm::Optional<std::string> WorkspaceRoot;
431+
llvm::Optional<AsyncTaskRunner> IndexTasks; // for stdlib indexing.
431432
llvm::Optional<TUScheduler> WorkScheduler;
432433
// Invalidation policy used for actions that we assume are "transient".
433434
TUScheduler::ASTActionInvalidation Transient;

clang-tools-extra/clangd/Config.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,12 @@ struct Config {
8181
/// forward-slashes.
8282
std::string MountPoint;
8383
};
84-
/// Controls background-index behavior.
84+
/// Controls index behavior.
8585
struct {
86-
/// Whether this TU should be indexed.
86+
/// Whether this TU should be background-indexed.
8787
BackgroundPolicy Background = BackgroundPolicy::Build;
8888
ExternalIndexSpec External;
89+
bool StandardLibrary = false;
8990
} Index;
9091

9192
enum UnusedIncludesPolicy { Strict, None };

clang-tools-extra/clangd/ConfigCompile.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,11 @@ struct FragmentCompiler {
332332
}
333333
if (F.External)
334334
compile(std::move(**F.External), F.External->Range);
335+
if (F.StandardLibrary)
336+
Out.Apply.push_back(
337+
[Val(**F.StandardLibrary)](const Params &, Config &C) {
338+
C.Index.StandardLibrary = Val;
339+
});
335340
}
336341

337342
void compile(Fragment::IndexBlock::ExternalBlock &&External,

clang-tools-extra/clangd/ConfigFragment.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,9 @@ struct Fragment {
199199
llvm::Optional<Located<std::string>> MountPoint;
200200
};
201201
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;
202205
};
203206
IndexBlock Index;
204207

clang-tools-extra/clangd/ConfigYAML.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,10 @@ class Parser {
184184
F.External.emplace(std::move(External));
185185
F.External->Range = N.getSourceRange();
186186
});
187+
Dict.handle("StandardLibrary", [&](Node &N) {
188+
if (auto StandardLibrary = boolValue(N, "StandardLibrary"))
189+
F.StandardLibrary = *StandardLibrary;
190+
});
187191
Dict.parse(N);
188192
}
189193

clang-tools-extra/clangd/TUScheduler.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,9 +1013,10 @@ void PreambleThread::build(Request Req) {
10131013
bool IsFirstPreamble = !LatestBuild;
10141014
LatestBuild = clang::clangd::buildPreamble(
10151015
FileName, *Req.CI, Inputs, StoreInMemory,
1016-
[this, Version(Inputs.Version)](ASTContext &Ctx, Preprocessor &PP,
1017-
const CanonicalIncludes &CanonIncludes) {
1018-
Callbacks.onPreambleAST(FileName, Version, Ctx, PP, CanonIncludes);
1016+
[&](ASTContext &Ctx, Preprocessor &PP,
1017+
const CanonicalIncludes &CanonIncludes) {
1018+
Callbacks.onPreambleAST(FileName, Inputs.Version, *Req.CI, Ctx, PP,
1019+
CanonIncludes);
10191020
},
10201021
&Stats);
10211022
if (!LatestBuild)

clang-tools-extra/clangd/TUScheduler.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,8 @@ class ParsingCallbacks {
133133
/// contains only AST nodes from the #include directives at the start of the
134134
/// file. AST node in the current file should be observed on onMainAST call.
135135
virtual void onPreambleAST(PathRef Path, llvm::StringRef Version,
136-
ASTContext &Ctx, Preprocessor &PP,
137-
const CanonicalIncludes &) {}
136+
const CompilerInvocation &CI, ASTContext &Ctx,
137+
Preprocessor &PP, const CanonicalIncludes &) {}
138138

139139
/// The argument function is run under the critical section guarding against
140140
/// races when closing the files.

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

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -425,12 +425,7 @@ FileIndex::FileIndex()
425425
MainFileSymbols(IndexContents::All),
426426
MainFileIndex(std::make_unique<MemIndex>()) {}
427427

428-
void FileIndex::updatePreamble(PathRef Path, llvm::StringRef Version,
429-
ASTContext &AST, Preprocessor &PP,
430-
const CanonicalIncludes &Includes) {
431-
IndexFileIn IF;
432-
std::tie(IF.Symbols, std::ignore, IF.Relations) =
433-
indexHeaderSymbols(Version, AST, PP, Includes);
428+
void FileIndex::updatePreamble(IndexFileIn IF) {
434429
FileShardedIndex ShardedIndex(std::move(IF));
435430
for (auto Uri : ShardedIndex.getAllSources()) {
436431
auto IF = ShardedIndex.getShard(Uri);
@@ -461,6 +456,15 @@ void FileIndex::updatePreamble(PathRef Path, llvm::StringRef Version,
461456
}
462457
}
463458

459+
void FileIndex::updatePreamble(PathRef Path, llvm::StringRef Version,
460+
ASTContext &AST, Preprocessor &PP,
461+
const CanonicalIncludes &Includes) {
462+
IndexFileIn IF;
463+
std::tie(IF.Symbols, std::ignore, IF.Relations) =
464+
indexHeaderSymbols(Version, AST, PP, Includes);
465+
updatePreamble(std::move(IF));
466+
}
467+
464468
void FileIndex::updateMain(PathRef Path, ParsedAST &AST) {
465469
auto Contents = indexMainDecls(AST);
466470
MainFileSymbols.update(

clang-tools-extra/clangd/index/FileIndex.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ class FileIndex : public MergedIndex {
114114
/// and macros in \p PP.
115115
void updatePreamble(PathRef Path, llvm::StringRef Version, ASTContext &AST,
116116
Preprocessor &PP, const CanonicalIncludes &Includes);
117+
void updatePreamble(IndexFileIn);
117118

118119
/// Update symbols and references from main file \p Path with
119120
/// `indexMainDecls`.

0 commit comments

Comments
 (0)