#line directives not considered in clangd


I am currently using the clangd for writing my own language server implementation for a new programming language, let's call it newlang.

In this new programming language, it is possible to write C++ source code in specific places, so it is possible to embed C++ code in specific syntax constructs. Afterwards the files are compiled to C++ to use the normal C++ toolchain.

As you can imagine, the embedded C++ from the original file is now also contained in the generated C++ file but in other places (at other line numbers etc because of additional generated C++ code). So, the embedded C++ source code which was at, for example, line 52 (in the original file of the new programming language) is now at line 132 in the generated C++ file.

To generate meaningful compiler messages, those places in the C++ file are annotated with #line directives which link back to the original file because you do not want to edit and analyze *generated* files but the original source file in the new programming language.

So, if I am using the standalone clang compiler, everything is correct and as expected:

benedikt@fedora:~$ clang /path/to/example_file.cxx
/path/to/example_file.newlang:39:9: warning: expression result unused [-Wunused-value]

because of something like

#line 22 "/path/to/example_file.newlang"

in the generated example_file.cxx. This is correct because the example_file.cxx is generated from the example_file.newlang and "links back" to the original location of the C++ source code, via those #line directives.

Now my question is: How can I get the *clangd* to recognize/consider #line directives? I could not get it to work. clangd seems to ignore them. clangd compiles the file correctly and generates "publishDiagnostics" with the same warning and error messages etc but without considering the #line directives, it only considers the line numbers from the C++ file (in this example_file.cxx it would be like line 132).

I also tried "-fuse-line-directives" but without success.

Thanks you for your time.

With kind regards,

Benedikt Weiß

FYI this mailing list is going away very soon (hours), replaced by llvm.discourse.group.

Clangd handles locations in many places for various features - are you only concerned about diagnostic locations or other features too?
It’d be useful to file a bug with details (a minimal example, how you expect it to behave).

However I can imagine what you want may be a lot of work/infeasible:

  • Clang only needs to print the filenames where it claims the source is from, while clangd needs to point at a location in an actual file that the editor will display. In general #line directives can (and do!) point at files that don’t exist or are out-of-sync with the files we’re parsing.

  • Clangd is designed to be used interactively while editing. If diagnostics appear in foo.newlang, but editing foo.newlang doesn’t cause them to update, this is confusing.

  • Clangd manipulates locations for output in many places for various features. It’s likely we’d need to add #line handling on a case-by-case basis to each feature (many features require locations/ranges to properly nest, which #line doesn’t guarantee).

  • Clangd really targets C-family languages supported by clang - doing small cleanups to better support other use cases makes sense, but we can’t really justify adding much complexity for this.