This is an archive of the discontinued LLVM Phabricator instance.

[lldb] Add valid SourceLocations to Clang declarations generated by the DWARF parser
Needs ReviewPublic

Authored by teemperor on Apr 14 2020, 3:49 AM.

Details

Summary

Clang supports having SourceLocations added to most declarations which are used for error diagnostics
to let the user know from which file/line a certain declaration came from.

Currently we assign all Clang declarations that are generated by the DWARF parser an invalid
SourceLocation, which leads to confusing error messages that tell the user things such as "previously declared here:"
but not any file path or line number that tells the user where "here" is.

This patch partly fixes the issue by assigning all declarations generated by the DWARF parser a valid SourceLocation.
The SourceLocations that are generated all point to dummy files that are just located in memory and just contain
the string <content of /path/to/file.cpp>. This is just done to keep this patch simple, but the idea is that in the
future we open the actual source files and let the SourceLocations point there to the right line/column. For now
we just display the file path which is the only thing we get correct for now.

The new diagnostics look like this:

(lldb) expr --top-level -- struct Foo {};
error: <user expression 0>:1:8: redefinition of 'Foo'
struct Foo {};
       ^
/path/to/test/loc.cpp: previous definition is here

The old diagnostics are the same but are missing the part before and after the "previous definition is here" error.

This feature can be turned off by setting plugin.symbol-file.dwarf.use-source-locations to false.

Partly fixes rdar://8670536

Diff Detail

Event Timeline

teemperor created this revision.Apr 14 2020, 3:49 AM
teemperor updated this revision to Diff 257273.Apr 14 2020, 4:01 AM
  • Added test for source locations from a header file.

This seems relatively ok-ish, though I don't really know much about this stuff. It may be good if we could get some of the clang-folks to review this, to make sure we don't do something too unsupported, which would be hard to back out from...

lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
2206–2207

Random thought: would this be cleaner if we always created a main file somewhere, which would not correspond to any of the real files we care about, but would just serve as a place to hook the other files onto?

8109

clang-format ?

lldb/test/API/commands/expression/diagnostics/TestExprDiagnostics.py
103

I suspect this path will be a problem on windows

lldb/test/API/commands/expression/diagnostics/main.cpp
2

Is this deliberately on the second line?

So if I understand correctly, everything will now have 1:1 for their location?

So if I understand correctly, everything will now have 1:1 for their location?

Kinda, it's /path/to/whatever/file/they/came/from.bar:1:1.

teemperor edited the summary of this revision. (Show Details)Apr 23 2020, 8:46 AM
teemperor planned changes to this revision.Apr 23 2020, 9:10 AM
teemperor marked an inline comment as done.

After some discussion with Shafik we ended up deciding that we should also hide the :1:1 in the diagnostic to not give the impression that this is a real line/col pair.

lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
2206–2207

That's actually a good idea, I'll change that.

teemperor updated this revision to Diff 278437.Jul 16 2020, 5:10 AM
teemperor marked an inline comment as done.
teemperor edited the summary of this revision. (Show Details)
  • Now creating one dummy main file when the ASTContext is created.
  • Now hiding line/columns and generated source code when rendering diagnostics.

Currently I don't think the DW_AT_decl_line / decl_file in DWARF type declarations are used by anything. In the Swift compiler actually started removing some of them since they caused needless churn in incremental recompilation, when someone inserted a blank line in a source file, for example. I was thinking we might want to do something similar for Clang, too. This patch would be an argument for not doing this. Since C-based languages separate interfaces into header files, the recompilation whitespace problem isn't quite as dramatic as in Swift, either. I suppose we can do this :-)

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
1367

nit: I usually spell the default return value as return {} but there's no LLVM coding style rule for this.