This is an archive of the discontinued LLVM Phabricator instance.

[clangd] Make in-memory CDB always available as an overlay, refactor.
ClosedPublic

Authored by sammccall on Oct 24 2018, 8:39 PM.

Details

Summary

The new implementation is a GlobalCompilationDatabase that overlays a base.
Normally this is the directory-based CDB.
To preserve the behavior of compile_args_from=LSP, the base may be null.

The OverlayCDB is always present, and so the extensions to populate it
are always supported.

It also allows overriding the flags of the fallback command. This is
just unit-tested for now, but the plan is to expose this as an extension
on the initialize message. This addresses use cases like
https://github.com/thomasjo/atom-ide-cpp/issues/16

Diff Detail

Repository
rL LLVM

Event Timeline

sammccall created this revision.Oct 24 2018, 8:39 PM

FWIW, the old implementation of the CDB looked simpler (which makes sense, since it only allowed the in-memory compile commands, but the new implementation also falls back to the base CDB, i.e. it's now doing two things).
However, if we can't avoid this protocol extension, the change LG and the model behind it should hopefully make sense from the user's perspective.
Still not sure whether overriding the normal command (not the fallback command) when we also read from the CDB is a useful feature.

clangd/ClangdLSPServer.cpp
670 ↗(On Diff #171034)

Is this an optimization to not trigger compile command changes?
Can we perform it on the CDB level to make sure we hit it in the future if more code calling setCompileCommand is added?

clangd/ClangdLSPServer.h
42 ↗(On Diff #171034)

NIT: the negative variable names might cause confusion (i.e. the double negations are hard to read). Maybe use the name of the corresponding field (UseDirectoryCDB)?

139 ↗(On Diff #171034)

Maybe add a comment on how the two compilation databases are combined?

clangd/GlobalCompilationDatabase.h
79 ↗(On Diff #171034)

The name does not seem to fully capture what this class does, i.e. allowing to override compile commands for some files.
Maybe use OverridenCDB or something similar?

sammccall marked 2 inline comments as done.Oct 25 2018, 7:44 AM

FWIW, the old implementation of the CDB looked simpler (which makes sense, since it only allowed the in-memory compile commands, but the new implementation also falls back to the base CDB, i.e. it's now doing two things).

Yeah, this is more complicated than the old InMemoryCompilationDatabase, but simpler than InMemoryCompilationDatabase + ClangdLSPServer::CompilationDb together, which it's replacing.

clangd/ClangdLSPServer.cpp
670 ↗(On Diff #171034)

Is this an optimization to not trigger compile command changes?

This is my attempt to preserve the optimization from rL338597, without having to keep the more complex interface to setCompileCommand.
(And fix a bug in it: if there was an old command and you change it, you should refresh).

The optimisation seems kind of suspect to me to be honest (if it's worth doing, it's probably worth doing right - i.e. per-file, not globally), but it's easy enough to preserve for now.

Can we perform it on the CDB level to make sure we hit it in the future if more code calling setCompileCommand is added?

Not quite sure what you mean: ClangdLSPServer needs to check whether there were changes in order to decide whether to invalidate. Having CompilationDatabase *also* aware of changes seems more complex/coupled and no less error-prone.

clangd/ClangdLSPServer.h
42 ↗(On Diff #171034)

I was reluctant to replace a bool constructor parameter with a bool that does the exact opposite, but we do only have one callsite...

clangd/GlobalCompilationDatabase.h
79 ↗(On Diff #171034)

Hmm, I feel the opposite way about these names - overlaying is exactly selective overriding of some elements, and overriding is more vague.

I did try to think of some other names, I almost like "mutable" but it's not actually essential, e.g. we don't allow the fallback flags to be mutated.

sammccall updated this revision to Diff 171098.Oct 25 2018, 7:44 AM
sammccall marked an inline comment as done.

Switch boolean parameters to positive sense, rebase.

ilya-biryukov accepted this revision.Oct 25 2018, 8:37 AM

LGTM

clangd/ClangdLSPServer.cpp
670 ↗(On Diff #171034)

Reparsing the files if compile commands did not change is (almost) a no-op now, so not sure it is worth it either.
SG to keep it for now, though.

Not quite sure what you mean: ClangdLSPServer needs to check whether there were changes in order to decide whether to invalidate. Having CompilationDatabase *also* aware of changes seems more complex/coupled and no less error-prone.

I initially thought this patch also adds watches for changes to compile commands (we discussed those yesterday), but the assumption was wrong, please ignore the comment.

clangd/GlobalCompilationDatabase.h
79 ↗(On Diff #171034)

Well, the comment is there so it's probably fine either way.
My reasoning behind "Overlay" is that it's usually a thing that combines two or more "layers", calling one after another, without introducing any extra functionality on its own.

This revision is now accepted and ready to land.Oct 25 2018, 8:37 AM
This revision was automatically updated to reflect the committed changes.
This revision was automatically updated to reflect the committed changes.