LLVM Discussion Forums

Clangd not working correctly with emacs+eglot

Hello everyone,

I am new to clangd but not new to language servers. I experimented lsp using emacs with the backends such as cquery and ccls. This time I tried clangd. However, after setup following your documentation https://clangd.llvm.org/installation.html it does not work as the documentation described.

I tried both lsp and eglot, but there are some issues.

I am using emacs in Ubuntu, which is a Windows Subsystem for Linux. I installed clangd-10 using the package management system, apt. After the eglot is enabled, there is no diagnostics and fixes. Finding definitions and hover information does not behave correctly.

I was experimenting with one simple cpp code file. For example, I defined an int variable x. I wrote another line of code which assigns a string literal to the variable x. There is no diagnostics and if I invoke x-ref-find-definitions on x in this line there is a message “No definitions found for: LSP identifier at point.” in the mini buffer. Finally the hover information does not show up as well.

Could I get any help about this here?

Did you also follow the instructions for setting up a project? https://clangd.llvm.org/installation.html#project-setup What does your compile_commands.json look like?

Actually I was doing experiment using a single cpp file. So I did not have a compile_commands.json at first. After you mentioned that, I tried use CMake to generate one.

Here is my compile_commands.json

[
{
  "directory": "/home/drcxd/test_proj/build",
  "command": "/usr/bin/c++      -o CMakeFiles/Tutorial.dir/test.cpp.o -c /home/drcxd/test_proj/test.cpp",
  "file": "/home/drcxd/test_proj/test.cpp"
}
]

This is my source code, could you try this in your environment and tell me if it works correctly?

#include <vector>
#include <string>

int main() {
    int i = 0;

    i = 1;
    i = "string";

    return void;

}

Just try to jump to definition on the second assignment of i.

I’m not an emacs person, so can’t help you with why the diagnostics aren’t showing up. It sounds to me like things are working apart from that though.

As of clangd-10 this is expected behaviour: after emitting an error (wrong type) we don’t “recover” so the whole line is discarded from the AST and operations like hover, go-to-definition, find-refs won’t work.

Clangd 11 (due in August or so) will have a fix for this called “recovery AST”. You can try it out by using a recent snapshot of clangd and passing -recovery-ast.

(Do cquery and ccls really handle this case? Maybe they’re using heuristics, I don’t know how you can handle this correctly without hooking into the guts of clang, which we only added recently)

While, actually ccls could not handle this correctly in this case. But if I define a variable of type std::string and assign a integer to it, ccls could find the correct definition. Well, clangd could also handle this case correctly.

That’s (surprisingly) valid code: it converts the integer to a char and calls the operator= overload which sets the string to a single char. So that’s why it’s different.

Well, then I guess it is working correctly. Although emacs does not show the diagnostics, the server actually knows where the error is. I just have to invoke a command to manually find that error.

But for some larger project, like DOOM-3, I found that clangd has some problem parsing the template classes. ccls could find the definition but could not show the hover info. What is more strange is, the server could find definition of a symbol but it still report an syntax error on it. These things are too complicated for me. I almost going to give up using these language servers with emacs…

This part is definitely not working correctly! Errors should be marked inline somehow, with details when you place the point there. I just don’t know enough about emacs/eglot to know the details, others might (or could ask an eglot support channel)

Are you on windows by any chance? We’re fixed some windows template problems recently. But it’ll be easier to understand what’s going on once diagnostics are shown.

Yes, I am on windows. But I am using emacs and all these things in Windows Subsystem for Linux(WSL). So you can consider it as a Linux environment? Well, by manually checking the errors prompted by the language server, I could not find anything useful. All it said were something like you can’t assign a variable of one type to one of another type.

Do you know any video/blog having an successful example using clangd/ccls with emacs on a reasonably complicated project? I saw many people in some forums said they could use those things. However, I have been trying to set these up for about two years and I never succeeded. I also never saw anyone gives instruction or example of using lsp on a real c++ project.

For me, it is really difficult to use these tools.