This is an archive of the discontinued LLVM Phabricator instance.

[clangd] Command line arg to specify compile_commands.json path
ClosedPublic

Authored by Nebiroth on Aug 25 2017, 8:54 AM.

Diff Detail

Repository
rL LLVM

Event Timeline

Nebiroth created this revision.Aug 25 2017, 8:54 AM
ilya-biryukov added inline comments.Aug 28 2017, 4:32 AM
clangd/GlobalCompilationDatabase.cpp
29 ↗(On Diff #112701)

Please place this flag in ClangdMain.cpp.

29 ↗(On Diff #112701)

Following naming convention for flags, this should be compile-commands.
Given the semantics of the flag, maybe it's better to name it compile-commands-dir?

30 ↗(On Diff #112701)

A description is somewhat vague. What is the intention of this flag?

  • Always look for compile_commands.json only inside specified directory?
  • First look inside specified directory, then proceed as normal (i.e. looking at the parent paths of each source file)?

It looks like the code also looks at the parent directories of compile-commands. Is that the original intention? Maybe consider making it look only inside the directory itself and not its parents?

57 ↗(On Diff #112701)

Incidental whitespace change?

89 ↗(On Diff #112701)

Please check command arguments for validity in main().
What is the purpose of find_first_of("/")? Checking for absolute paths? If yes, you could use llvm::sys::path::is_absolute.

97 ↗(On Diff #112701)

Naming: local variables should be UpperCamelCase

99 ↗(On Diff #112701)

Maybe extract a function from the for loop body instead of copying it here?
Could be named tryLoadDatabaseFromPath.

113 ↗(On Diff #112701)

Maybe rewrite to avoid extra nesting?

For example,

if (!badPath) {
    auto result = CDB.get();
    CompilationDatabases.insert(std::make_pair(File, std::move(CDB)));
    return result;
}
// Proceed as before...
138 ↗(On Diff #112701)

Please consider removing this code duplication by extracting a function from the loop body (also see my previous comment).

ilya-biryukov edited edge metadata.Aug 29 2017, 4:17 AM

BTW, if you're only looking for providing extra compilation flags for some files, you could use an extension to LSP that is already in clangd source tree. (See tests from https://reviews.llvm.org/D34947 for more details).
But your change is also useful, as it allows to override the whole compilation database. Would be interested in this change to land regardless of whether the extra flags thing suits you well.

krasimir added inline comments.Aug 30 2017, 3:21 AM
clangd/GlobalCompilationDatabase.cpp
89 ↗(On Diff #112701)

Please make CompileCommands a member variable and pass it through the constructor of DirectoryBasedGlobalCompilationDatabase. This is more flexible and, among other things, allows for easier unit testing.

94 ↗(On Diff #112701)

LLVM style uses no braces for single statement if's.

Nebiroth marked 11 inline comments as done.Sep 5 2017, 12:35 PM
Nebiroth updated this revision to Diff 113895.Sep 5 2017, 12:36 PM

Added function to avoid code reuse and extra nesting.

See my comments.
Could you also clang-format the code please?

clangd/ClangdServer.cpp
150 ↗(On Diff #113895)

Could you pass llvm::Optional<Path> instead (Path is just a descriptive typedef that we use in place of std::string) and check for empty string in main()?

clangd/GlobalCompilationDatabase.cpp
14 ↗(On Diff #113895)

There are definitely unneeded includes here. Remove most of them and leave only the required ones?

93 ↗(On Diff #113895)

Let's simply lookup only inside CompileCommandsDir if it was set.
Otherwise, fallback into looking at parent_paths of the file.

30 ↗(On Diff #112701)

How about chaning semantics of the flag to only look inside "--compile-commands-dir" and not its parent paths?
I think it makes the behavior much less surprising. The whole point of looking in parent paths is that typically compile_commands.json is put inside the project root.

The flag that you propose seems to have a different purpose of providing clangd with custom compilation flags.

clangd/GlobalCompilationDatabase.h
38 ↗(On Diff #113895)

GlobalCompilationDatabase is an interface class and is designed specifically to not contain any fields.
Could you please do the following?

  • Move this field into DirectoryBasedGlobalCompilationDatabase.
  • Make it private and initialize it in constructor.
clangd/tool/ClangdMain.cpp
29 ↗(On Diff #113895)

Could you use descriptive Path typedef instead of std::string here and in other places?

30 ↗(On Diff #113895)

Maybe rename this (and other occurences) to CompileCommandsDir?

43 ↗(On Diff #113895)
  • CompileCommands is empty by default, don't show the error message in that case.
  • If value of CompileCommands is not absolute or the path does not exist, set CompileCommands to empty string after reporting an error.
44 ↗(On Diff #113895)

Maybe rephrase the message a little bit, mentioning the name of the flag. Something like:
"Value of --compile-commands-dir must be an absolute path. The argument will be ignored."

Nebiroth updated this revision to Diff 114199.Sep 7 2017, 10:09 AM
Nebiroth marked 7 inline comments as done.

Modified CompileCommandsDir to only look in the specified path if the value is set.
Moved CompileCommandsDir field to DirectoryBasedGlobalCompilationDatabase class.
Minor refactoring.

Could you also clang-format the code please?

clangd/GlobalCompilationDatabase.cpp
87 ↗(On Diff #114199)

Why do we use parent_path of CompilerCommandsDir, not CompilerCommandsDir itself?
Why do we need to reassign the File parameter?

Maybe simply do
auto CDB = tryLoadDatabaseFromPath(CompileCommandsDir, Error)?

92 ↗(On Diff #114199)
clangd/tool/ClangdMain.cpp
40 ↗(On Diff #114199)

Replace --CompileCommandsDir with --compile-commands-dir.

ilya-biryukov added inline comments.Sep 8 2017, 2:09 AM
clangd/ClangdServer.cpp
150 ↗(On Diff #114199)

Remove CompileCommandsDir from ClangdServer parameters, it is hanlded by DirectoryBasedGlobalCompilationDatabase.

clangd/GlobalCompilationDatabase.cpp
70 ↗(On Diff #114199)

Restore this assertion, move it to tryLoadDatabaseFromPath.

84 ↗(On Diff #114199)

Maybe move this local variable into tryLoadDatabaseFromPath and remove Error parameter from tryLoadDatabaseFromPath?
Please make sure to move the TODO about logging into tryLoadDatabaseFromPath as well.

clangd/GlobalCompilationDatabase.h
48 ↗(On Diff #114199)

Rename parameter to CompileCommandsDir, change type to llvm::Optional<Path>.

53 ↗(On Diff #114199)

Make this function private.

clangd/tool/ClangdMain.cpp
45 ↗(On Diff #114199)

Use Out.log() instead of Logs << for consistency with other logging code.

51 ↗(On Diff #114199)

Maybe also rephrase to mention the name of the flag? Something like:
"Path specified by --compile-commands-dir does not exist. The argument will be ignored.\n"

58 ↗(On Diff #114199)

Accept llvm::Optional in ClangdLSPServer, pass llvm::None if CompileCommandsDir == "" here.

ilya-biryukov requested changes to this revision.Sep 8 2017, 2:09 AM
This revision now requires changes to proceed.Sep 8 2017, 2:09 AM
Nebiroth updated this revision to Diff 114371.Sep 8 2017, 8:59 AM
Nebiroth edited edge metadata.
Nebiroth marked 10 inline comments as done.

Ran clang-format on modified files.
More minor refactoring.

klimek added a subscriber: klimek.Sep 11 2017, 1:05 AM
klimek added inline comments.
clangd/GlobalCompilationDatabase.cpp
98–100 ↗(On Diff #114371)

Isn't that the same as "return CDB"?

Nebiroth marked an inline comment as done.Sep 11 2017, 12:42 PM
Nebiroth updated this revision to Diff 114654.Sep 11 2017, 12:43 PM

Simpilified a pointer return value.

ilya-biryukov added inline comments.Sep 12 2017, 7:33 AM
clangd/GlobalCompilationDatabase.cpp
75 ↗(On Diff #114654)

Parentheses seem redundant.

78 ↗(On Diff #114654)

Code style: local variable are UpperCamelCase

96 ↗(On Diff #114654)

Even better: return tryLoadDatabaseFromPath(CompileCommandsDir);

clangd/GlobalCompilationDatabase.h
50 ↗(On Diff #114654)

getValue() will fail if NewCompileCommandsDir does not have a value.
The original suggestion was to change type of the field 'CompileCommandsDir` to llvm::Optional<Path> and check if Optional has a value instead of checking for empty string.

58 ↗(On Diff #114654)

Could you please move this to other fields?

Mixing functions and fields is a bit confusing.

clangd/tool/ClangdMain.cpp
52 ↗(On Diff #114654)

Message does not mention that path does not exist. Probably incidental.

59 ↗(On Diff #114654)

Could you please move this out of the logic that validates CompileCommandsDir parameter?
It's very easy to miss while reading the code. Probably ok to put it right after JSONOutput Out(... line

Nebiroth marked 5 inline comments as done.Sep 15 2017, 10:00 AM
Nebiroth updated this revision to Diff 115462.Sep 15 2017, 12:46 PM
Nebiroth marked an inline comment as done.

Fixed a few comments.
Rebased on latest clangd version.

All lit test for clangd are currently failing if I apply your change.
Generally, please run make check-clang-tools to make sure your changes do not introduce any regressions.

The tests are failing because when --compile-commands-dir is not specified clangd now shows the cmd arg validation errors ("path not absolute", "path does not exist").

clangd/tool/ClangdMain.cpp
78 ↗(On Diff #115462)

The code doing command line argument validation shows errors using llvm::errs() and not Out.log(). Could you do the same for consistency?

Also, could you put your new code that does argument validation right after the previous checks (to line 65)? So that we have a clear structure in the code:

/// Validate command line arguments.
...

/// Initialize and run ClangdLSPServer.
...
ilya-biryukov requested changes to this revision.Sep 18 2017, 2:09 AM
This revision now requires changes to proceed.Sep 18 2017, 2:09 AM
Nebiroth marked an inline comment as done.Sep 20 2017, 1:03 PM
Nebiroth updated this revision to Diff 116198.Sep 21 2017, 8:35 AM
Nebiroth edited edge metadata.

More consistent logging in clangdmain.
Restructured argument checking in ClangdMain
Fixed empty compile-commands-dir triggering error messages.
Fixed failing standard tests.

Could you please run clang-format on every submission?

clangd/GlobalCompilationDatabase.cpp
98 ↗(On Diff #116198)

Is this some kind of accidental change? Why do we need to assign "/" to CompileCommandsDir?

clangd/tool/ClangdMain.cpp
20 ↗(On Diff #116198)

We certainly don't need that include.

79 ↗(On Diff #116198)

This should be something like:

if (CompileCommandsDir.empty()) {
  //...
  CompileCommandsDirPath = llvm::None;
} else if (!is_absolute(...)) {
  //....
  CompileCommandsDirPath = llvm::None;
} else if (!exists(...)) {
  // ....
  CompileCommandsDirPath = llvm::None;
} else {
  CompileCommandsDirPath = CompileCommandsDir;
}
  • It will have less nesting, therefore making code more readable.
  • It will fix an error in the current implementation. (Currently, exists check will run on an empty string if -compile-commands-dir is not an absolute path).
ilya-biryukov requested changes to this revision.Sep 21 2017, 7:14 PM
This revision now requires changes to proceed.Sep 21 2017, 7:14 PM
Nebiroth updated this revision to Diff 116559.Sep 25 2017, 7:52 AM
Nebiroth edited edge metadata.

Fixed inverted compile_commands check logic that made tests fail.
More readable command arg checks.

malaperle requested changes to this revision.Sep 27 2017, 8:46 PM
malaperle added inline comments.
clangd/tool/ClangdMain.cpp
20 ↗(On Diff #116559)

William, did you perhaps miss this comment? I don't think unistd.h makes sense here.

This revision now requires changes to proceed.Sep 27 2017, 8:46 PM
Nebiroth added inline comments.Sep 28 2017, 6:17 AM
clangd/tool/ClangdMain.cpp
20 ↗(On Diff #116559)

I indeed missed it.

ilya-biryukov added inline comments.Sep 28 2017, 9:02 AM
clangd/GlobalCompilationDatabase.cpp
82 ↗(On Diff #116198)

Why remove this FIXME?

clangd/tool/ClangdMain.cpp
86 ↗(On Diff #116559)

NIT: maybe join this with previous line?

89 ↗(On Diff #116559)

NIT: don't mix branches with and without {}. Simply use {} on all branches in that case.

Nebiroth marked 4 inline comments as done.Sep 29 2017, 1:58 PM
Nebiroth updated this revision to Diff 117217.Sep 29 2017, 2:01 PM
Nebiroth edited edge metadata.

Fixed missed comments and suggstions.

ilya-biryukov requested changes to this revision.EditedOct 2 2017, 3:53 AM

It seems some changes were be lost while merging with head.

clangd/GlobalCompilationDatabase.cpp
75 ↗(On Diff #117217)

Maybe move Error closer to its usage (line 84: auto CDB = tooling::CompilationDatabase::loadFromDirectory ...)?

90 ↗(On Diff #117217)

Please remove this FIXME, it is already deleted in head.

97 ↗(On Diff #117217)

Please restore this logging statement.

This revision now requires changes to proceed.Oct 2 2017, 3:53 AM
Nebiroth marked 3 inline comments as done.Oct 2 2017, 5:03 AM
Nebiroth updated this revision to Diff 117327.Oct 2 2017, 5:09 AM
Nebiroth edited edge metadata.

Fixed changes that were lost while merging with head.

ilya-biryukov requested changes to this revision.Oct 2 2017, 5:34 AM
ilya-biryukov added inline comments.
clangd/GlobalCompilationDatabase.cpp
90 ↗(On Diff #117327)

This logging statement is misplaced, in the current HEAD it's outside of the loop.
(i.e. it should be in the getCompilationDatabase, not in tryLoadDatabaseFromPath).

Otherwise the output of clangd gets really spammy.

100 ↗(On Diff #117327)

We should also log if we can't find compilation database in this code path.

This revision now requires changes to proceed.Oct 2 2017, 5:34 AM
Nebiroth updated this revision to Diff 117337.Oct 2 2017, 6:10 AM
Nebiroth edited edge metadata.
Nebiroth marked 2 inline comments as done.

Changed placement of logging instruction to reduce logging output.

ilya-biryukov accepted this revision.Oct 2 2017, 6:47 AM

Thanks. LGTM modulo minor NIT (see other inline comment).
Do you need help to land this?

clangd/GlobalCompilationDatabase.cpp
102 ↗(On Diff #117337)

Message should probably mention that's clangd was looking for compile commands in an overridden directory.

Nebiroth updated this revision to Diff 117340.Oct 2 2017, 7:06 AM

Improved logging message when unable to find compilation database in specified overriden directory.

Thanks for fixing the last comment.
Do you want me to land this for you?

clangd/GlobalCompilationDatabase.cpp
103 ↗(On Diff #117340)

NIT: missing a space at the start of "in overriden...". Otherwise filename will be concatenated with "in"

Thanks for fixing the last comment.
Do you want me to land this for you?

Yes please!

This revision was automatically updated to reflect the committed changes.

Did a minor rename and added a few std::moves before submitting. Was not worth another round of code review.