clangd outputting relative/non-canonical URIs

Hi,

I have a question regarding how clangd returns URIs. Let's say I have a file compiled
with a relative path like this (something that can easily happen when you build
outside the source directory)

  clang++ -c ../src/repro.cpp -o repro.o -g3 -O0

The compile_commands.json (as generated with Bear) will contain this:

  "directory": "/home/simark/src/repro/build",
  "file": "../src/repro.cpp"

If I make some "goto definition" requests, clangd may return a relative URI or a non-canonical
URI:

<-- {"id":124,"jsonrpc":"2.0","method":"textDocument/definition","params":{"position":{"character":3,"line":9},"textDocument":{"uri":"file:///home/simark/src/repro/src/repro.cpp"}}}
--> {"id":124,"jsonrpc":"2.0","result":[{"range":{"end":{"character":1,"line":5},"start":{"character":0,"line":2}},"uri":"file://../src/repro.cpp"}]}
<-- {"id":125,"jsonrpc":"2.0","method":"textDocument/definition","params":{"position":{"character":3,"line":4},"textDocument":{"uri":"file:///home/simark/src/repro/src/repro.cpp"}}}
--> {"id":125,"jsonrpc":"2.0","result":[{"range":{"end":{"character":5,"line":1},"start":{"character":0,"line":0}},"uri":"file:///home/simark/src/repro/build/../src/repro.h"}]}

In the first case, is it expected for clangd to return the URI "file://../src/repro.cpp"?
First, is it even allowed to have relative URIs? If so, what is it relative to? There was
a discussion here about relative/absolute URIs, the conclusion seems to be that absolute
URIs are the way to go:

  All request/response URIs should be relative to rootPath · Issue #27 · microsoft/language-server-protocol · GitHub

In the second case, the returned URI is not normalized. Should clangd make sure to return
only normalized URIs, to avoid possibly referring to the same file using different paths?

I am attaching a simple reproducer with this message (hopefully the mailing list accepts it).
The instructions for building are in the README.

Thanks,

Simon

repro.tar.gz (823 Bytes)

Hi Simon,

This is likely a bug in the go-to-definition code path. clangd should always return URIs with absolute paths. There have also been some recent changes that make clangd produce canonical URIs. I think your example would actually cause assertion failure in a newer build of clangd. I’ll look into this.

Cheers,
Eric

Hi Eric,

Ok, thanks for confirming the problem. I opened a bug for this:

https://bugs.llvm.org/show_bug.cgi?id=36213

Simon