MaskRay / ccls

C/C++/ObjC language server supporting cross references, hierarchies, completion and semantic highlighting
Apache License 2.0
3.75k stars 258 forks source link

ccls not working in template inline files #777

Open TobyBrull opened 3 years ago

TobyBrull commented 3 years ago

When working with templates, it's common practice to put the implementation of template functions into an "inline" header file that is #includeed at the end of the header. I prefer the *.ipp extension for these files, but *.inl is probably more commonly used.

I've attached a little toy example here: inline_template.zip.

I've played with a .ccls file. I also have a larger project for which I generate a compile_commands.json. But I always get the same behaviour: In the *.hpp file and in the *.cpp file everything works fine, but in the *.ipp file I only get rudimentary support and (in my larger project) ccls also flags a lot of errors (which aren't really errors).

Any ideas for how I could make this work?

Couldn't really find anything on this in the docs. This FAQ entry seems to be what is most related to my question, but I didn't find it really answers it.

System information

jeffzjzhang commented 3 years ago

Same here. I also tried clangd, which doesn't work as well. However, cpptools of VSCode works fantastic under this situation. Didn't figure out how VSC handle this problem.

RedBeard0531 commented 3 years ago

One trick is to #include "foo.hpp" from inside of foo.ipp. This ensures that foo.ipp is independently compilable, which makes many things work better.

jdrouhard commented 3 years ago

You can add a build post-process step that modifies compile_commands.json file to add additional entries for the inline files that have some additional flags:

{
    "directory": "<same-as-some-cpp-from-same-subproj>",
    "command": "<same-as-some-cpp-from-same-subproj-without-o-c-args> -include /path/to/parent/header.hpp -x c++-header -o /path/for/subproj/inline_file.gch -c /path/to/inline_file.inl",
    "file": "/path/to/inline_file.inl"
}

This has worked well ever since I came up with this trick.

jeffzjzhang commented 3 years ago

You can add a build post-process step that modifies compile_commands.json file to add additional entries for the inline files that have some additional flags:

{
    "directory": "<same-as-some-cpp-from-same-subproj>",
    "command": "<same-as-some-cpp-from-same-subproj-without-o-c-args> -include /path/to/parent/header.hpp -x c++-header -o /path/for/subproj/inline_file.gch -c /path/to/inline_file.inl",
    "file": "/path/to/inline_file.inl"
}

This has worked well ever since I came up with this trick.

Thank you for sharing this trick! Can we automate this process if we have many .inl files in a project? I think compilation process must resolve these dependencies. Is there anyway to extract it?