This requires an accessible compilation database. The parsing is done
asynchronously on a separate thread.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
clangd/DocumentStore.h | ||
---|---|---|
42 ↗ | (On Diff #88171) | Shouldn't this be called under a lock_guard? |
clangd/DocumentStore.h | ||
---|---|---|
42 ↗ | (On Diff #88171) | I should've reworded my comment before submitting it. By 'this' I'm referring to the 'Docs.erase()' part, not the whole function. |
clangd/ASTManager.cpp | ||
---|---|---|
21 ↗ | (On Diff #88171) | Any reason not to wrap code in namespaces instead? |
clangd/DocumentStore.h | ||
---|---|---|
42 ↗ | (On Diff #88171) | Even under a guard, it may potentially still be unsafe since workers may operate on erased/modified StringRef-s. |
51 ↗ | (On Diff #88171) | StringRef doesn't own the underlying data, right? What if I erase it in the meantime? |
63 ↗ | (On Diff #88171) | Same thing, shouldn't these be strings? |
clangd/ASTManager.cpp | ||
---|---|---|
69 ↗ | (On Diff #88171) | This is just a suggestion based on personal opinion: RequestIsPending and Done can be merged into one enum value that uses an enum like this: enum ASTManagerState { Waiting, ReceivedRequest, Done } Then this condition could be rewritten as if (state == Waiting). |
70 ↗ | (On Diff #88171) | I believe std::condition_variable may also be unblocked spuriously when wait is called without a predicate, which would lead to an empty File down below. |
clangd/ASTManager.h | ||
67 ↗ | (On Diff #88171) | It looks like Done is always accessed in a scope where RequestLock is locked, so atomic doesn't seem needed here. |
clangd/ASTManager.cpp | ||
---|---|---|
148 ↗ | (On Diff #88171) | Do you have an idea about a proper error handling if Error? |
162 ↗ | (On Diff #88171) | Then maybe we need a big disclaimer comment at the declaration of createASTUnitForFile? |
clangd/ClangDMain.cpp | ||
32 ↗ | (On Diff #88171) | Why not directly Store.addListener(llvm::make_unique<ASTManager>(Out, Store));? |
clangd/DocumentStore.h | ||
39 ↗ | (On Diff #88171) | Is only the main thread supposed to addDocument-s? Otherwise the listener notifications might need to be guarded. |
clangd/ASTManager.cpp | ||
---|---|---|
69 ↗ | (On Diff #88171) | I'm not so sure. Once we have a queue (iff we ever get a queue), the "request available" is an attribute of the queue, while the "we need to exit" is an attribute of the system. |
70 ↗ | (On Diff #88171) | Yep, +1, the general pattern is to put while loops around. ... Lock(RequestLock); while (Requests.empty() && !Done) { ClangRequestCV.wait(Lock); } if (Done) return; File = Request.pop_front(); ClangRequestCV.notify_all(); ... the while loop can be written somewhat simpler with the pred version: ClangRequestCV.wait(Lock, [&] { return !Request.empty() || Done; }); |
116 ↗ | (On Diff #88171) | One question is whether we want to couple this to JSON, or have structured output that we serialize. |
clangd/ASTManager.h | ||
34 ↗ | (On Diff #88171) | At a first glance, it's weird that we have a global document store, but get a document store for each notification. This at least needs documentation. |
67 ↗ | (On Diff #88171) | Yea, after only having read this header, it looks like we might want to pull out a Request as an abstraction. |
clangd/ClangDMain.cpp | ||
32 ↗ | (On Diff #88171) | Why's the ASTManager not on the stack? |
clangd/DocumentStore.h | ||
39 ↗ | (On Diff #88171) | It would always be the responsibility of the callee to guard. |
42 ↗ | (On Diff #88171) | That depends on the guarantees made, and when we create copies :) |
- Address review comments.
clangd/ASTManager.cpp | ||
---|---|---|
21 ↗ | (On Diff #88171) | I don't really have an opinion one way or the other, but this seems to be the preferred way of doing this in LLVM. |
70 ↗ | (On Diff #88171) | Added the lambda. The current state is pretty weird, but making it a queue just to drop random elements from that queue is even weirder :( |
148 ↗ | (On Diff #88171) | For now I'll send it to logs() |
clangd/ASTManager.h | ||
34 ↗ | (On Diff #88171) | This is leftover from an earlier design. Removed. |
67 ↗ | (On Diff #88171) | Wrapped all the guarded variables in a struct. |
clangd/ClangDMain.cpp | ||
32 ↗ | (On Diff #88171) | Fixed. Lifetime is no longer managed by the DocumentStore (that was a bit weird) |
clangd/DocumentStore.h | ||
39 ↗ | (On Diff #88171) | Added guard for now. |
42 ↗ | (On Diff #88171) | Added guard. |
51 ↗ | (On Diff #88171) | I guess it makes sense to create copies here. Somewhat sad but safe. |
63 ↗ | (On Diff #88171) | Done. |
clangd/DocumentStore.h | ||
---|---|---|
42 ↗ | (On Diff #88171) | 'Docs.erase(Uri);' is still outside the critical section. It's easy to miss because of its placement directly after '{'. |
- Do not lock while running DocumentStore callbacks
- Replace fake queue with a real queue (but it still has at most one element.
clangd/ASTManager.h | ||
---|---|---|
67 ↗ | (On Diff #88171) | For me that actually makes it worse (sorry): I now read "Request.Done" and think the request is done :) |
http://lab.llvm.org:8011/builders/clang-x86_64-debian-fast/builds/2437 is broken by this revision.