[PATCH] D29886: [clangd] Wire up ASTUnit and publish diagnostics with it.
Benjamin Kramer via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Feb 15 05:42:57 PST 2017
bkramer added inline comments.
================
Comment at: clangd/ASTManager.cpp:21
+using namespace clang;
+using namespace clangd;
+
----------------
ioeric wrote:
> Any reason not to wrap code in namespaces instead?
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.
================
Comment at: clangd/ASTManager.cpp:70
+ if (!RequestIsPending && !Done)
+ ClangRequestCV.wait(Lock);
+
----------------
klimek wrote:
> arphaman wrote:
> > 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.
> Yep, +1, the general pattern is to put while loops around.
> It might actually be simpler to write that with a queue from the start (note that this would make the request queueing side somewhat less simple):
> ... 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; });
>
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 :(
================
Comment at: clangd/ASTManager.cpp:148
+ std::string Error;
+ I = tooling::CompilationDatabase::autoDetectFromSource(Uri, Error);
+ return I.get();
----------------
krasimir wrote:
> Do you have an idea about a proper error handling if Error?
For now I'll send it to logs()
================
Comment at: clangd/ASTManager.h:34
+
+ void onDocumentAdd(StringRef Uri, const DocumentStore &Docs) override;
+ // FIXME: Implement onDocumentRemove
----------------
klimek wrote:
> 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.
This is leftover from an earlier design. Removed.
================
Comment at: clangd/ASTManager.h:67
+ /// Setting Done to true will make the worker thread terminate.
+ std::atomic<bool> Done;
+};
----------------
klimek wrote:
> arphaman wrote:
> > It looks like `Done` is always accessed in a scope where `RequestLock` is locked, so `atomic` doesn't seem needed here.
> Yea, after only having read this header, it looks like we might want to pull out a Request as an abstraction.
Wrapped all the guarded variables in a struct.
================
Comment at: clangd/ClangDMain.cpp:32
+ auto *AST = new ASTManager(Out, Store);
+ Store.addListener(std::unique_ptr<ASTManager>(AST));
JSONRPCDispatcher Dispatcher(llvm::make_unique<Handler>(Out));
----------------
klimek wrote:
> krasimir wrote:
> > Why not directly `Store.addListener(llvm::make_unique<ASTManager>(Out, Store));`?
> Why's the ASTManager not on the stack?
Fixed. Lifetime is no longer managed by the DocumentStore (that was a bit weird)
================
Comment at: clangd/DocumentStore.h:39
+ for (const auto &Listener : Listeners)
+ Listener->onDocumentAdd(Uri, *this);
+ }
----------------
klimek wrote:
> krasimir wrote:
> > Is only the main thread supposed to addDocument-s? Otherwise the listener notifications might need to be guarded.
> It would always be the responsibility of the callee to guard.
Added guard for now.
================
Comment at: clangd/DocumentStore.h:42
/// Delete a document from the store.
- void removeDocument(StringRef Uri) { Docs.erase(Uri); }
+ void removeDocument(StringRef Uri) { Docs.erase(Uri);
+ for (const auto &Listener : Listeners)
----------------
klimek wrote:
> krasimir wrote:
> > cierpuchaw wrote:
> > > cierpuchaw wrote:
> > > > Shouldn't this be called under a lock_guard?
> > > I should've reworded my comment before submitting it. By 'this' I'm referring to the 'Docs.erase()' part, not the whole function.
> > >
> > Even under a guard, it may potentially still be unsafe since workers may operate on erased/modified StringRef-s.
> That depends on the guarantees made, and when we create copies :)
Added guard.
================
Comment at: clangd/DocumentStore.h:51
auto I = Docs.find(Uri);
return I == Docs.end() ? StringRef("") : StringRef(I->second);
}
----------------
krasimir wrote:
> StringRef doesn't own the underlying data, right? What if I erase it in the meantime?
I guess it makes sense to create copies here. Somewhat sad but safe.
================
Comment at: clangd/DocumentStore.h:63
+ AllDocs.emplace_back(P.first(), P.second);
+ return AllDocs;
+ }
----------------
krasimir wrote:
> Same thing, shouldn't these be strings?
Done.
https://reviews.llvm.org/D29886
More information about the cfe-commits
mailing list