This is an archive of the discontinued LLVM Phabricator instance.

[clangd] Resolve driver symlinks, and look up unknown relative drivers in PATH.
ClosedPublic

Authored by sammccall on Feb 29 2020, 4:06 PM.

Details

Summary

This fixes a reported bug: if clang and libc++ are installed under
/usr/lib/llvm-11/... but there'- a symlink /usr/bin/clang++-11, then a
compile_commands.json with "/usr/bin/clang++-11 -stdlib=libc++" would previously
look for libc++ under /usr/include instead of /usr/lib/llvm-11/include.
The PATH change makes this work if the compiler is just "clang++-11" too.

As this is now doing IO potentially on every getCompileCommand(), we cache
the results for each distinct driver.

While here:

  • Added a Memoize helper for this as multithreaded caching is a bit noisy.
  • Used this helper to simplify QueryDriverDatabase and reduce blocking there. (This makes use of the fact that llvm::Regex is now threadsafe)

Diff Detail

Event Timeline

sammccall created this revision.Feb 29 2020, 4:06 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 29 2020, 4:06 PM
kadircet added inline comments.Mar 2 2020, 3:26 AM
clang-tools-extra/clangd/CompileCommands.cpp
145

findProgramByName is evil :/ it is not guaranteed to return an absolute path.

for example if you've got toolchain/clang as your argv[0] (not sure if it is possible, but it is a non-absoltue path...) then it will return the argument directly, even though it is not an absolute path :(.

156

what about taking a VFS instead and calling VFS.getRealPath?

It should make testing easier and commandmangler vfs friendly.

clang-tools-extra/clangd/CompileCommands.h
49

maybe just ResolvedDriver?

clang-tools-extra/clangd/QueryDriverDatabase.cpp
286

nit: QueriedDrivers

clang-tools-extra/clangd/Threading.h
154 ↗(On Diff #247469)

what about an explicit getOrCreate method instead?

clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp
223

irrelevant to the patch:

any reason for adjust to mutate its parameter in-place instead of returning it(I believe callers can do std::move(Cmd) if need be) ?

227

can we rather move the ifdef here the rest previous part should hopefully work on other platforms as well (at least after VFS)?

kadircet added inline comments.Mar 2 2020, 3:28 AM
clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp
110

i suppose you rather want testPath("fake/unknown-binary");

Per @jyknight on discord: we -no-canonical-prefixes disables this behavior in clang.
Maybe we should scan for that and not resolve if it's present...

sammccall marked 10 inline comments as done.May 28 2020, 6:51 AM
sammccall added inline comments.
clang-tools-extra/clangd/CompileCommands.cpp
156

That's a more invasive change I don't feel up to at the moment.
CommandMangler doesn't make much sense if you don't make assumptions about the FS being real (e.g. looking up things on the PATH, using the output of xcrun...)
I don't think testing alone is a strong reason to VFSify it.

clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp
223

Not a strong reason either way I think.

227

I don't think they'll work: create_link doesn't create a symlink on windows, PATHEXT is a thing, etc.

sammccall updated this revision to Diff 266861.May 28 2020, 7:00 AM
sammccall marked an inline comment as done.

Handle -no-canonical-prefixes
Make memoize map-like instead of functor-like
Address other comments.

kadircet accepted this revision.May 28 2020, 2:13 PM
kadircet added inline comments.
clang-tools-extra/clangd/support/Threading.h
134

nit: triple slashes?

This revision is now accepted and ready to land.May 28 2020, 2:13 PM
This revision was automatically updated to reflect the committed changes.

Sorry, got interrupted right after landing this. Thanks for the revert.