[llvm-dev] Adding DWARF5 accelerator table support to llvm

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
45 messages Options
123
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm

Jonathan Wakely via llvm-dev


On Jun 13, 2018, at 11:18 AM, Jonas Devlieghere via lldb-dev <[hidden email]> wrote:

Hi Pavel,

On Jun 13, 2018, at 6:56 AM, Pavel Labath <[hidden email]> wrote:

Hello again,

It's been nearly six months since my first email, so it's a good time
to recap what has been done here so far. I am happy to report that
stages 1-3 (i.e. producer/consumer in llvm and integration with lldb)
of my original plan are now complete with one caveat.

Awesome!

The caveat is that the .debug_names section is presently not a full
drop-in replacement for the .apple_*** sections. The reason for that
is that there is no equivalent to the .apple_objc section (which links
an objc class/category name  to all of its methods). I did not
implement that, because I do not see a way to embed that kind of
information to this section without some sort of an extension. Given
that this was not required for my use case, I felt it would be best to
leave this to the people working on objc support (*looks at Jonas*) to
work out the details of how to represent that.

Definitely :-) I plan to start working on this (+ dsymutil support) very soon. 

It would be great to add "dsymutil --update" support so it can handle both mach-o files and ELF files. What this does is update the accelerator tables of any files that are specified. That way the accelerator tables can be added to any object file that contains DWARF after the fact.

As David Blaike suggested, maybe we can emit the .apple_objc section as a work around for now. 


Nonetheless, I believe that the emitted .debug_names section contains
all the data that is required by the standard, and it is sufficient to
pass all tests in the lldb integration test suite on linux (this
doesn't include objc tests).

How did you (or do you plan to) add this (and DWARF5 in general) in the lldb test suite? It sounds like this might require a new dimension in the test matrix if we want to test all the variants with both Apple and DWARF style accelerator tables. 

Simple benchmarks also show a large
performance improvement.I have some numbers to illustrate that
(measurements taken by using a release build of lldb to debug a debug
build of clang, clang was built with -mllvm -accel-tables=Dwarf to
enable the accelerator generation, usage of the tables was controlled
by a setting in lldb):
- setting a breakpoint on a non-existing function without the use of
accelerator tables:
real    0m5.554s
user    0m43.764s
sys     0m6.748s
(The majority of this time is spend on building a debug info index,
which is a one-shot thing. subsequent breakpoints would be fast)

- setting a breakpoint on a non-existing function with accelerator tables:
real    0m3.517s
user    0m3.136s
sys     0m0.376s
(With the index already present, we are able to quickly determine that
there is no match and finish)

- setting a breakpoint on all "dump" functions without the use of
accelerator tables:
real    0m21.544s
user    0m59.588s
sys     0m6.796s
(Apart from building the index, now we must also parse a bunch of
compile units and line tables to resolve the breakpoint locations)

- setting a breakpoint on all "dump" functions with accelerator tables:
real    0m23.644s
user    0m22.692s
sys     0m0.948s
(Here we see that this extra work is actually the bottleneck now.
Preliminary analysis shows that majority of this time is spend
inserting line table entries into the middle of a vector, which means
it should be possible to fix this with a smarter implementation).

As far as object file sizes go, in the resulting clang binary (2.3GB),
the new .debug_names section takes up about 160MB (7%), which isn't
negligible, but considering that it supersedes the
.debug_pubnames/.debug_pubtypes tables whose combined size is 490MB
(21% of the binary), switching to this table (and dropping the other
two) will have a positive impact on the binary size. Further
reductions can be made by merging the individual indexes into one
large index as a part of the link step (which will also increase
debugger speed), but it's hard to quantify the exact impact of that.

With all of this in mind, I'd like to encourage you to give the new
tables a try. All you need to do is pass -mllvm -accel-tables=Dwarf to
clang while building your project. lldb should use the generated
tables automatically. I'm particularly interested in the interop
scenario. I've checked that readelf is able to make sense of the
generated tables, but if you have any other producer/consumer of these
tables which is independent of llvm, I'd like to know whether we are
compatible with it.

I know of one internal consumer but it ignores the accelerator tables so I don’t expect any issues there.

I'd also like to make the new functionality more easily accessible to
users. I am not sure what our policy here is, but I was thinking of
either including this functionality in -glldb (on non-apple targets);
or by adding a separate -g flag for it (-gdebug-names-section?), with
the goal of eventual inclusion into -glldb. I exclude apple targets
because: a) they already have a thing that works and the lack of
.apple_objc would be a pessimization; b) the different debug info
distribution model means it requires more testing and code (dsymutil).

Changing the default on non-Apple targets sounds good. Once we have Objective-C support I’ll do some additional (internal) testing after which we can consider flipping the switch globally. 

For other targets this should bring a big performance improvement when
debugging with lldb. The lack of .apple_objc will mean lldb will have
to either index the objc compile units manually, or implement a more
complicated lookup using other information in the section. However,
Objective C is not that widespread outside of apple platforms, so the
impact of this should be minimal.

What do you think?

regards,
pavel

_______________________________________________
lldb-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev


_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm

Jonathan Wakely via llvm-dev
Thank you all. I am going to try to reply to all comments in a single email.

Regarding the  .apple_objc idea, I am afraid the situation is not as
simple as just flipping a switch. (If it was, I don't think I would
have embarked on this adventure in the first place -- I would just
emit .apple_*** everywhere and call it done :)). The issue is that the
apple tables have assumptions about the macos debug info distribution
model hardcoded in them -- they assume they will either stay in the .o
file or be linked by a smart debug-info-aware linker (dsymutil). In
particular, this means they are not self-delimiting (no length field
as is typical for other dwarf artifacts), so if a linker which is not
aware of them would simply concatenate individual .o tables (which elf
linkers are really good at), the debugger would have no way to pry
them apart. And even if it somehow managed that, it still wouldn't
know if the indexes covered all of the compile units in the linked
file or only some of them (in case some of the object files were
compiled with the tables and some without).

In light of that, I don't think it's worth trying to combine
.apple_objc with .debug_names in some way, and it would be much
simpler to just extend .debug_names with the necessary information. I
think the simplest way of achieving this (one which would require
least amount of standard-bending) is to take the index entry for the
objc class and add a special attribute to it (DW_IDX_method_list?)
with form DW_FORM_blockXXX and just have the references to the method
DIEs in the block data. This should make the implementation an almost
drop-in for the current .apple_objc functionality (we would still need
to figure out what to do with category methods, but it's not clear to
me whether lldb actually uses those anywhere).

But, other options may be possible as well. What's not clear to me is
whether these tables couldn't be replaced by extra information in the
.debug_info section. It seems to me that these tables are trying to
work around the issue that there is no straight way to go from a
DW_TAG_structure type DIE describing an ObjC class to it's methods. If
these methods (their forward declarations) were be present as children
of the type DIE (as they are for c++ classes), then these tables may
not be necessary. But maybe (probably) that has already been
considered and deemed infeasible for some reason. In any case this
seemed like a thing best left for people who actually work on ObjC
support to figure out.


As far as the .debug_names size goes, I should also point out that the
binary in question was built with -fno-limit-debug-info, which isn't a
default setup on linux. I have tried measuring the sizes without that
flag and with fission enabled (-gsplit-dwarf) and the results are:
without compression:
- clang binary: 960 MB
- .debug_names: 130 MB (13%)
- debug_pubnames: 175 MB (18%)
- debug_pubtypes: 204 MB (21%)
- median time for setting a breakpoint on non-existent function
(variance +/- 2%):
real 0m3.526s
user 0m3.156s
sys 0m0.364s

with -Wl,--compress-debug-sections=zlib:
- clang binary: 440 MB
- .debug_names: 80MB (18%)
- .debug_pubnames: 31 MB (7.2%)
- .debug_pubtypes: 42MB (9.5%)
- median time for setting a breakpoint on non-existent function:
real 0m4.369s
user 0m3.948s
sys 0m0.416s

So, .debug_names indeed compresses worse than .debug_pubnames/types,
but that is not surprising as it has a more condensed encoding to
begin with (no inline strings). However, even in it's compressed form
its size is only slightly larger that the two other sections combined
(while being infinitely more useful). As for the compression, my
takeaway from this is that compression definitely has a measurable
impact on startup time, but, on the grand scale of things, the impact
is not actually that big. And if a user deliberately adds the
compression flag to his command line, I would assume he really cares
about binary size, and is willing to sacrifice some debug performance
in return. So, I would honor his request and compress .debug_names as
well.


I have tried David Anderson's dwarfdump (after Paul pointed it out to
me), but as far as I can tell, it has no support from printing out the
.debug_names section (the print_debug_names function is stubbed out).
**I think** I got the correct source repository
(git://git.code.sf.net/p/libdwarf/code) as the last commit there is
dated yesterday.


For testing on the lldb side I have been deliberately trying to avoid
adding another dimensions to the ever-growing test matrix. I don't
think this functionality is worth it, especially not if you view the
test suite as a regression test suite. The entire functionality of
this in lldb is encompassed in a single .cpp file which is about 250
LOC. The class has about a dozen entry points and most of them are
accessible through the lldb-test tool, which I've used to write
targeted regression tests for this (it could probably use more of
those). I did use the "dotest" suite as an integration test suite, but
I did that by simply passing --env CFLAGS_EXTRAS="-mllvm
-accel-tables=Dwarf" to dotest (I also tried hacking clang to always
emit the new tables to make sure I'm not missing anything).
Ironically, if you try that now, you will see one test failing, but
that's because I have already added one test passing that flag
explicitly (I couldn't find a way to test this functionality through
lldb-test) and clang then complains about a duplicate argument. This
should go away once we have better -g flag to control this behavior. I
haven't yet figured out whether I want to set up a bot to run the
tests in this configuration, but I know I don't want to inflict that
extra overhead on developers running tests during day-to-day
development.

regards,
pavel
_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm

Jonathan Wakely via llvm-dev


> On Jun 14, 2018, at 7:01 AM, Pavel Labath via llvm-dev <[hidden email]> wrote:
>
> Thank you all. I am going to try to reply to all comments in a single email.
>
> Regarding the  .apple_objc idea, I am afraid the situation is not as
> simple as just flipping a switch.

Jonas is currently working on adding the support for DWARF5-style Objective-C accelerator tables to LLVM/LLDB/dsymutil. Based on the assumption that DWARF 4 and earlier are unaffected by any of this, I don't think it's necessary to spend any effort of making the transition smooth. I'm fine with having Objective-C on DWARF 5 broken on trunk for two weeks until Jonas is done adding Objective-C support to the DWARF 5 implementation.


> (If it was, I don't think I would
> have embarked on this adventure in the first place -- I would just
> emit .apple_*** everywhere and call it done :)). The issue is that the
> apple tables have assumptions about the macos debug info distribution
> model hardcoded in them -- they assume they will either stay in the .o
> file or be linked by a smart debug-info-aware linker (dsymutil). In
> particular, this means they are not self-delimiting (no length field
> as is typical for other dwarf artifacts), so if a linker which is not
> aware of them would simply concatenate individual .o tables (which elf
> linkers are really good at), the debugger would have no way to pry
> them apart. And even if it somehow managed that, it still wouldn't
> know if the indexes covered all of the compile units in the linked
> file or only some of them (in case some of the object files were
> compiled with the tables and some without).
>
> In light of that, I don't think it's worth trying to combine
> .apple_objc with .debug_names in some way, and it would be much
> simpler to just extend .debug_names with the necessary information. I
> think the simplest way of achieving this (one which would require
> least amount of standard-bending) is to take the index entry for the
> objc class and add a special attribute to it (DW_IDX_method_list?)
> with form DW_FORM_blockXXX and just have the references to the method
> DIEs in the block data. This should make the implementation an almost
> drop-in for the current .apple_objc functionality (we would still need
> to figure out what to do with category methods, but it's not clear to
> me whether lldb actually uses those anywhere).
>
> But, other options may be possible as well. What's not clear to me is
> whether these tables couldn't be replaced by extra information in the
> .debug_info section. It seems to me that these tables are trying to
> work around the issue that there is no straight way to go from a
> DW_TAG_structure type DIE describing an ObjC class to it's methods. If
> these methods (their forward declarations) were be present as children
> of the type DIE (as they are for c++ classes), then these tables may
> not be necessary. But maybe (probably) that has already been
> considered and deemed infeasible for some reason. In any case this
> seemed like a thing best left for people who actually work on ObjC
> support to figure out.

That's really a question for Greg or Jim — I don't know why the current representation has the Objective-C methods outside of the structs. One reason might be that an interface's implementation can define more methods than are visible in its public interface in the header file, but we already seem to be aware of this and mark the implementation with DW_AT_APPLE_objc_complete_type. I also am not sure that this is the *only* reason for the objc accelerator table. But I'd like to learn.

-- adrian

> As far as the .debug_names size goes, I should also point out that the
> binary in question was built with -fno-limit-debug-info, which isn't a
> default setup on linux. I have tried measuring the sizes without that
> flag and with fission enabled (-gsplit-dwarf) and the results are:
> without compression:
> - clang binary: 960 MB
> - .debug_names: 130 MB (13%)
> - debug_pubnames: 175 MB (18%)
> - debug_pubtypes: 204 MB (21%)
> - median time for setting a breakpoint on non-existent function
> (variance +/- 2%):
> real 0m3.526s
> user 0m3.156s
> sys 0m0.364s
>
> with -Wl,--compress-debug-sections=zlib:
> - clang binary: 440 MB
> - .debug_names: 80MB (18%)
> - .debug_pubnames: 31 MB (7.2%)
> - .debug_pubtypes: 42MB (9.5%)
> - median time for setting a breakpoint on non-existent function:
> real 0m4.369s
> user 0m3.948s
> sys 0m0.416s
>
> So, .debug_names indeed compresses worse than .debug_pubnames/types,
> but that is not surprising as it has a more condensed encoding to
> begin with (no inline strings). However, even in it's compressed form
> its size is only slightly larger that the two other sections combined
> (while being infinitely more useful). As for the compression, my
> takeaway from this is that compression definitely has a measurable
> impact on startup time, but, on the grand scale of things, the impact
> is not actually that big. And if a user deliberately adds the
> compression flag to his command line, I would assume he really cares
> about binary size, and is willing to sacrifice some debug performance
> in return. So, I would honor his request and compress .debug_names as
> well.
>
>
> I have tried David Anderson's dwarfdump (after Paul pointed it out to
> me), but as far as I can tell, it has no support from printing out the
> .debug_names section (the print_debug_names function is stubbed out).
> **I think** I got the correct source repository
> (git://git.code.sf.net/p/libdwarf/code) as the last commit there is
> dated yesterday.
>
>
> For testing on the lldb side I have been deliberately trying to avoid
> adding another dimensions to the ever-growing test matrix. I don't
> think this functionality is worth it, especially not if you view the
> test suite as a regression test suite. The entire functionality of
> this in lldb is encompassed in a single .cpp file which is about 250
> LOC. The class has about a dozen entry points and most of them are
> accessible through the lldb-test tool, which I've used to write
> targeted regression tests for this (it could probably use more of
> those). I did use the "dotest" suite as an integration test suite, but
> I did that by simply passing --env CFLAGS_EXTRAS="-mllvm
> -accel-tables=Dwarf" to dotest (I also tried hacking clang to always
> emit the new tables to make sure I'm not missing anything).
> Ironically, if you try that now, you will see one test failing, but
> that's because I have already added one test passing that flag
> explicitly (I couldn't find a way to test this functionality through
> lldb-test) and clang then complains about a duplicate argument. This
> should go away once we have better -g flag to control this behavior. I
> haven't yet figured out whether I want to set up a bot to run the
> tests in this configuration, but I know I don't want to inflict that
> extra overhead on developers running tests during day-to-day
> development.
>
> regards,
> pavel
> _______________________________________________
> LLVM Developers mailing list
> [hidden email]
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm

Jonathan Wakely via llvm-dev


On Jun 14, 2018, at 9:36 AM, Adrian Prantl <[hidden email]> wrote:



On Jun 14, 2018, at 7:01 AM, Pavel Labath via llvm-dev <[hidden email]> wrote:

Thank you all. I am going to try to reply to all comments in a single email.

Regarding the  .apple_objc idea, I am afraid the situation is not as
simple as just flipping a switch.

Jonas is currently working on adding the support for DWARF5-style Objective-C accelerator tables to LLVM/LLDB/dsymutil. Based on the assumption that DWARF 4 and earlier are unaffected by any of this, I don't think it's necessary to spend any effort of making the transition smooth. I'm fine with having Objective-C on DWARF 5 broken on trunk for two weeks until Jonas is done adding Objective-C support to the DWARF 5 implementation.


(If it was, I don't think I would
have embarked on this adventure in the first place -- I would just
emit .apple_*** everywhere and call it done :)). The issue is that the
apple tables have assumptions about the macos debug info distribution
model hardcoded in them -- they assume they will either stay in the .o
file or be linked by a smart debug-info-aware linker (dsymutil). In
particular, this means they are not self-delimiting (no length field
as is typical for other dwarf artifacts), so if a linker which is not
aware of them would simply concatenate individual .o tables (which elf
linkers are really good at), the debugger would have no way to pry
them apart. And even if it somehow managed that, it still wouldn't
know if the indexes covered all of the compile units in the linked
file or only some of them (in case some of the object files were
compiled with the tables and some without).

In light of that, I don't think it's worth trying to combine
.apple_objc with .debug_names in some way, and it would be much
simpler to just extend .debug_names with the necessary information. I
think the simplest way of achieving this (one which would require
least amount of standard-bending) is to take the index entry for the
objc class and add a special attribute to it (DW_IDX_method_list?)
with form DW_FORM_blockXXX and just have the references to the method
DIEs in the block data. This should make the implementation an almost
drop-in for the current .apple_objc functionality (we would still need
to figure out what to do with category methods, but it's not clear to
me whether lldb actually uses those anywhere).

But, other options may be possible as well. What's not clear to me is
whether these tables couldn't be replaced by extra information in the
.debug_info section. It seems to me that these tables are trying to
work around the issue that there is no straight way to go from a
DW_TAG_structure type DIE describing an ObjC class to it's methods. If
these methods (their forward declarations) were be present as children
of the type DIE (as they are for c++ classes), then these tables may
not be necessary. But maybe (probably) that has already been
considered and deemed infeasible for some reason. In any case this
seemed like a thing best left for people who actually work on ObjC
support to figure out.

That's really a question for Greg or Jim — I don't know why the current representation has the Objective-C methods outside of the structs. One reason might be that an interface's implementation can define more methods than are visible in its public interface in the header file, but we already seem to be aware of this and mark the implementation with DW_AT_APPLE_objc_complete_type. I also am not sure that this is the *only* reason for the objc accelerator table. But I'd like to learn.

New categories to objective C classes can be added and I believe that implementations can be spread across multiple files. Not sure why objective C doesn't contain its DW_TAG_subprogram inside of its DW_TAG_class_type, but that is the way things have been for a while.


-- adrian

As far as the .debug_names size goes, I should also point out that the
binary in question was built with -fno-limit-debug-info, which isn't a
default setup on linux. I have tried measuring the sizes without that
flag and with fission enabled (-gsplit-dwarf) and the results are:
without compression:
- clang binary: 960 MB
- .debug_names: 130 MB (13%)
- debug_pubnames: 175 MB (18%)
- debug_pubtypes: 204 MB (21%)
- median time for setting a breakpoint on non-existent function
(variance +/- 2%):
real 0m3.526s
user 0m3.156s
sys 0m0.364s

with -Wl,--compress-debug-sections=zlib:
- clang binary: 440 MB
- .debug_names: 80MB (18%)
- .debug_pubnames: 31 MB (7.2%)
- .debug_pubtypes: 42MB (9.5%)
- median time for setting a breakpoint on non-existent function:
real 0m4.369s
user 0m3.948s
sys 0m0.416s

So, .debug_names indeed compresses worse than .debug_pubnames/types,
but that is not surprising as it has a more condensed encoding to
begin with (no inline strings). However, even in it's compressed form
its size is only slightly larger that the two other sections combined
(while being infinitely more useful). As for the compression, my
takeaway from this is that compression definitely has a measurable
impact on startup time, but, on the grand scale of things, the impact
is not actually that big. And if a user deliberately adds the
compression flag to his command line, I would assume he really cares
about binary size, and is willing to sacrifice some debug performance
in return. So, I would honor his request and compress .debug_names as
well.


I have tried David Anderson's dwarfdump (after Paul pointed it out to
me), but as far as I can tell, it has no support from printing out the
.debug_names section (the print_debug_names function is stubbed out).
**I think** I got the correct source repository
(<a href="git://git.code.sf.net/p/libdwarf/code" class="">git://git.code.sf.net/p/libdwarf/code) as the last commit there is
dated yesterday.


For testing on the lldb side I have been deliberately trying to avoid
adding another dimensions to the ever-growing test matrix. I don't
think this functionality is worth it, especially not if you view the
test suite as a regression test suite. The entire functionality of
this in lldb is encompassed in a single .cpp file which is about 250
LOC. The class has about a dozen entry points and most of them are
accessible through the lldb-test tool, which I've used to write
targeted regression tests for this (it could probably use more of
those). I did use the "dotest" suite as an integration test suite, but
I did that by simply passing --env CFLAGS_EXTRAS="-mllvm
-accel-tables=Dwarf" to dotest (I also tried hacking clang to always
emit the new tables to make sure I'm not missing anything).
Ironically, if you try that now, you will see one test failing, but
that's because I have already added one test passing that flag
explicitly (I couldn't find a way to test this functionality through
lldb-test) and clang then complains about a duplicate argument. This
should go away once we have better -g flag to control this behavior. I
haven't yet figured out whether I want to set up a bot to run the
tests in this configuration, but I know I don't want to inflict that
extra overhead on developers running tests during day-to-day
development.

regards,
pavel
_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev


_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm

Jonathan Wakely via llvm-dev
On Thu, 14 Jun 2018 at 17:58, Greg Clayton <[hidden email]> wrote:

>
>
>
> On Jun 14, 2018, at 9:36 AM, Adrian Prantl <[hidden email]> wrote:
>
>
>
> On Jun 14, 2018, at 7:01 AM, Pavel Labath via llvm-dev <[hidden email]> wrote:
>
> Thank you all. I am going to try to reply to all comments in a single email.
>
> Regarding the  .apple_objc idea, I am afraid the situation is not as
> simple as just flipping a switch.
>
>
> Jonas is currently working on adding the support for DWARF5-style Objective-C accelerator tables to LLVM/LLDB/dsymutil. Based on the assumption that DWARF 4 and earlier are unaffected by any of this, I don't think it's necessary to spend any effort of making the transition smooth. I'm fine with having Objective-C on DWARF 5 broken on trunk for two weeks until Jonas is done adding Objective-C support to the DWARF 5 implementation.

Ideally, I would like to enable the accelerator tables (possibly with
a different version number or something) on DWARF 4 too (on non-apple
targets only). The reason for this is that their absence if causing
large slowdowns when debugging on non-apple platforms, and I wouldn't
want to wait for dwarf 5 for that to go away (I mean no disrespect to
Paul and DWARF 5 effort in general, but even if all of DWARF 5 in llvm
was done tomorrow, there would still be lldb, which hasn't even begun
to look at this version).

That said, if you are working on the Objective C support right now,
then I am happy to wait two weeks or so that we have a full
implementation from the get-go.

> But, other options may be possible as well. What's not clear to me is
> whether these tables couldn't be replaced by extra information in the
> .debug_info section. It seems to me that these tables are trying to
> work around the issue that there is no straight way to go from a
> DW_TAG_structure type DIE describing an ObjC class to it's methods. If
> these methods (their forward declarations) were be present as children
> of the type DIE (as they are for c++ classes), then these tables may
> not be necessary. But maybe (probably) that has already been
> considered and deemed infeasible for some reason. In any case this
> seemed like a thing best left for people who actually work on ObjC
> support to figure out.
>
>
> That's really a question for Greg or Jim — I don't know why the current representation has the Objective-C methods outside of the structs. One reason might be that an interface's implementation can define more methods than are visible in its public interface in the header file, but we already seem to be aware of this and mark the implementation with DW_AT_APPLE_objc_complete_type. I also am not sure that this is the *only* reason for the objc accelerator table. But I'd like to learn.

My observation was based on studying lldb code. The only place where
the objc table is used is in the AppleDWARFIndex::GetObjCMethods
function, which is called from
SymbolFileDWARF::GetObjCMethodDIEOffsets, whose only caller is
DWARFASTParserClang::CompleteTypeFromDWARF, which seems to have a
class DIE as an argument. However, if not all declarations of a
class/interface have access to the full list of methods then this
might be a problem for the approach I suggested.
_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm

Jonathan Wakely via llvm-dev
In reply to this post by Jonathan Wakely via llvm-dev
If you end up revisiting the design/representation here - I'd be glad to be involved. It reminds me of some of the tradeoffs/issues around how even plain C++ types vary between translation units (eg: member function template implicit specializations - necessarily different ones can appear in different translation units (because they were instantiated in those places/the set of implicit specializations isn't closed)). So maybe there's some lessons to draw between these situations.

On Thu, Jun 14, 2018 at 9:36 AM Adrian Prantl <[hidden email]> wrote:


> On Jun 14, 2018, at 7:01 AM, Pavel Labath via llvm-dev <[hidden email]> wrote:
>
> Thank you all. I am going to try to reply to all comments in a single email.
>
> Regarding the  .apple_objc idea, I am afraid the situation is not as
> simple as just flipping a switch.

Jonas is currently working on adding the support for DWARF5-style Objective-C accelerator tables to LLVM/LLDB/dsymutil. Based on the assumption that DWARF 4 and earlier are unaffected by any of this, I don't think it's necessary to spend any effort of making the transition smooth. I'm fine with having Objective-C on DWARF 5 broken on trunk for two weeks until Jonas is done adding Objective-C support to the DWARF 5 implementation.


> (If it was, I don't think I would
> have embarked on this adventure in the first place -- I would just
> emit .apple_*** everywhere and call it done :)). The issue is that the
> apple tables have assumptions about the macos debug info distribution
> model hardcoded in them -- they assume they will either stay in the .o
> file or be linked by a smart debug-info-aware linker (dsymutil). In
> particular, this means they are not self-delimiting (no length field
> as is typical for other dwarf artifacts), so if a linker which is not
> aware of them would simply concatenate individual .o tables (which elf
> linkers are really good at), the debugger would have no way to pry
> them apart. And even if it somehow managed that, it still wouldn't
> know if the indexes covered all of the compile units in the linked
> file or only some of them (in case some of the object files were
> compiled with the tables and some without).
>
> In light of that, I don't think it's worth trying to combine
> .apple_objc with .debug_names in some way, and it would be much
> simpler to just extend .debug_names with the necessary information. I
> think the simplest way of achieving this (one which would require
> least amount of standard-bending) is to take the index entry for the
> objc class and add a special attribute to it (DW_IDX_method_list?)
> with form DW_FORM_blockXXX and just have the references to the method
> DIEs in the block data. This should make the implementation an almost
> drop-in for the current .apple_objc functionality (we would still need
> to figure out what to do with category methods, but it's not clear to
> me whether lldb actually uses those anywhere).
>
> But, other options may be possible as well. What's not clear to me is
> whether these tables couldn't be replaced by extra information in the
> .debug_info section. It seems to me that these tables are trying to
> work around the issue that there is no straight way to go from a
> DW_TAG_structure type DIE describing an ObjC class to it's methods. If
> these methods (their forward declarations) were be present as children
> of the type DIE (as they are for c++ classes), then these tables may
> not be necessary. But maybe (probably) that has already been
> considered and deemed infeasible for some reason. In any case this
> seemed like a thing best left for people who actually work on ObjC
> support to figure out.

That's really a question for Greg or Jim — I don't know why the current representation has the Objective-C methods outside of the structs. One reason might be that an interface's implementation can define more methods than are visible in its public interface in the header file, but we already seem to be aware of this and mark the implementation with DW_AT_APPLE_objc_complete_type. I also am not sure that this is the *only* reason for the objc accelerator table. But I'd like to learn.

-- adrian

> As far as the .debug_names size goes, I should also point out that the
> binary in question was built with -fno-limit-debug-info, which isn't a
> default setup on linux. I have tried measuring the sizes without that
> flag and with fission enabled (-gsplit-dwarf) and the results are:
> without compression:
> - clang binary: 960 MB
> - .debug_names: 130 MB (13%)
> - debug_pubnames: 175 MB (18%)
> - debug_pubtypes: 204 MB (21%)
> - median time for setting a breakpoint on non-existent function
> (variance +/- 2%):
> real 0m3.526s
> user 0m3.156s
> sys 0m0.364s
>
> with -Wl,--compress-debug-sections=zlib:
> - clang binary: 440 MB
> - .debug_names: 80MB (18%)
> - .debug_pubnames: 31 MB (7.2%)
> - .debug_pubtypes: 42MB (9.5%)
> - median time for setting a breakpoint on non-existent function:
> real 0m4.369s
> user 0m3.948s
> sys 0m0.416s
>
> So, .debug_names indeed compresses worse than .debug_pubnames/types,
> but that is not surprising as it has a more condensed encoding to
> begin with (no inline strings). However, even in it's compressed form
> its size is only slightly larger that the two other sections combined
> (while being infinitely more useful). As for the compression, my
> takeaway from this is that compression definitely has a measurable
> impact on startup time, but, on the grand scale of things, the impact
> is not actually that big. And if a user deliberately adds the
> compression flag to his command line, I would assume he really cares
> about binary size, and is willing to sacrifice some debug performance
> in return. So, I would honor his request and compress .debug_names as
> well.
>
>
> I have tried David Anderson's dwarfdump (after Paul pointed it out to
> me), but as far as I can tell, it has no support from printing out the
> .debug_names section (the print_debug_names function is stubbed out).
> **I think** I got the correct source repository
> (git://git.code.sf.net/p/libdwarf/code) as the last commit there is
> dated yesterday.
>
>
> For testing on the lldb side I have been deliberately trying to avoid
> adding another dimensions to the ever-growing test matrix. I don't
> think this functionality is worth it, especially not if you view the
> test suite as a regression test suite. The entire functionality of
> this in lldb is encompassed in a single .cpp file which is about 250
> LOC. The class has about a dozen entry points and most of them are
> accessible through the lldb-test tool, which I've used to write
> targeted regression tests for this (it could probably use more of
> those). I did use the "dotest" suite as an integration test suite, but
> I did that by simply passing --env CFLAGS_EXTRAS="-mllvm
> -accel-tables=Dwarf" to dotest (I also tried hacking clang to always
> emit the new tables to make sure I'm not missing anything).
> Ironically, if you try that now, you will see one test failing, but
> that's because I have already added one test passing that flag
> explicitly (I couldn't find a way to test this functionality through
> lldb-test) and clang then complains about a duplicate argument. This
> should go away once we have better -g flag to control this behavior. I
> haven't yet figured out whether I want to set up a bot to run the
> tests in this configuration, but I know I don't want to inflict that
> extra overhead on developers running tests during day-to-day
> development.
>
> regards,
> pavel
> _______________________________________________
> LLVM Developers mailing list
> [hidden email]
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev


_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm

Jonathan Wakely via llvm-dev
In reply to this post by Jonathan Wakely via llvm-dev


On Thu, Jun 14, 2018 at 11:24 AM Pavel Labath <[hidden email]> wrote:
On Thu, 14 Jun 2018 at 17:58, Greg Clayton <[hidden email]> wrote:
>
>
>
> On Jun 14, 2018, at 9:36 AM, Adrian Prantl <[hidden email]> wrote:
>
>
>
> On Jun 14, 2018, at 7:01 AM, Pavel Labath via llvm-dev <[hidden email]> wrote:
>
> Thank you all. I am going to try to reply to all comments in a single email.
>
> Regarding the  .apple_objc idea, I am afraid the situation is not as
> simple as just flipping a switch.
>
>
> Jonas is currently working on adding the support for DWARF5-style Objective-C accelerator tables to LLVM/LLDB/dsymutil. Based on the assumption that DWARF 4 and earlier are unaffected by any of this, I don't think it's necessary to spend any effort of making the transition smooth. I'm fine with having Objective-C on DWARF 5 broken on trunk for two weeks until Jonas is done adding Objective-C support to the DWARF 5 implementation.

Ideally, I would like to enable the accelerator tables (possibly with
a different version number or something) on DWARF 4 too (on non-apple
targets only). The reason for this is that their absence if causing
large slowdowns when debugging on non-apple platforms, and I wouldn't
want to wait for dwarf 5 for that to go away (I mean no disrespect to
Paul and DWARF 5 effort in general, but even if all of DWARF 5 in llvm
was done tomorrow, there would still be lldb, which hasn't even begun
to look at this version).

That said, if you are working on the Objective C support right now,
then I am happy to wait two weeks or so that we have a full
implementation from the get-go.

> But, other options may be possible as well. What's not clear to me is
> whether these tables couldn't be replaced by extra information in the
> .debug_info section. It seems to me that these tables are trying to
> work around the issue that there is no straight way to go from a
> DW_TAG_structure type DIE describing an ObjC class to it's methods. If
> these methods (their forward declarations) were be present as children
> of the type DIE (as they are for c++ classes), then these tables may
> not be necessary. But maybe (probably) that has already been
> considered and deemed infeasible for some reason. In any case this
> seemed like a thing best left for people who actually work on ObjC
> support to figure out.
>
>
> That's really a question for Greg or Jim — I don't know why the current representation has the Objective-C methods outside of the structs. One reason might be that an interface's implementation can define more methods than are visible in its public interface in the header file, but we already seem to be aware of this and mark the implementation with DW_AT_APPLE_objc_complete_type. I also am not sure that this is the *only* reason for the objc accelerator table. But I'd like to learn.

My observation was based on studying lldb code. The only place where
the objc table is used is in the AppleDWARFIndex::GetObjCMethods
function, which is called from
SymbolFileDWARF::GetObjCMethodDIEOffsets, whose only caller is
DWARFASTParserClang::CompleteTypeFromDWARF, which seems to have a
class DIE as an argument. However, if not all declarations of a
class/interface have access to the full list of methods then this
might be a problem for the approach I suggested.

Maybe, but the same is actually true for C++ classes too (see my comments in another reply about implicit specializations of class member templates (and there are a couple of other examples)) - so might be worth considering how those are handled/could be improved, and maybe in fixing those we could improve/normalize the ObjC representation and avoid the need for ObjC tables... maybe.
 

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm

Jonathan Wakely via llvm-dev
On Thu, 14 Jun 2018 at 19:26, David Blaikie <[hidden email]> wrote:

>
>
>
> On Thu, Jun 14, 2018 at 11:24 AM Pavel Labath <[hidden email]> wrote:
>>
>> On Thu, 14 Jun 2018 at 17:58, Greg Clayton <[hidden email]> wrote:
>> >
>> >
>> >
>> > On Jun 14, 2018, at 9:36 AM, Adrian Prantl <[hidden email]> wrote:
>> >
>> >
>> >
>> > On Jun 14, 2018, at 7:01 AM, Pavel Labath via llvm-dev <[hidden email]> wrote:
>> >
>> > Thank you all. I am going to try to reply to all comments in a single email.
>> >
>> > Regarding the  .apple_objc idea, I am afraid the situation is not as
>> > simple as just flipping a switch.
>> >
>> >
>> > Jonas is currently working on adding the support for DWARF5-style Objective-C accelerator tables to LLVM/LLDB/dsymutil. Based on the assumption that DWARF 4 and earlier are unaffected by any of this, I don't think it's necessary to spend any effort of making the transition smooth. I'm fine with having Objective-C on DWARF 5 broken on trunk for two weeks until Jonas is done adding Objective-C support to the DWARF 5 implementation.
>>
>> Ideally, I would like to enable the accelerator tables (possibly with
>> a different version number or something) on DWARF 4 too (on non-apple
>> targets only). The reason for this is that their absence if causing
>> large slowdowns when debugging on non-apple platforms, and I wouldn't
>> want to wait for dwarf 5 for that to go away (I mean no disrespect to
>> Paul and DWARF 5 effort in general, but even if all of DWARF 5 in llvm
>> was done tomorrow, there would still be lldb, which hasn't even begun
>> to look at this version).
>>
>> That said, if you are working on the Objective C support right now,
>> then I am happy to wait two weeks or so that we have a full
>> implementation from the get-go.
>>
>> > But, other options may be possible as well. What's not clear to me is
>> > whether these tables couldn't be replaced by extra information in the
>> > .debug_info section. It seems to me that these tables are trying to
>> > work around the issue that there is no straight way to go from a
>> > DW_TAG_structure type DIE describing an ObjC class to it's methods. If
>> > these methods (their forward declarations) were be present as children
>> > of the type DIE (as they are for c++ classes), then these tables may
>> > not be necessary. But maybe (probably) that has already been
>> > considered and deemed infeasible for some reason. In any case this
>> > seemed like a thing best left for people who actually work on ObjC
>> > support to figure out.
>> >
>> >
>> > That's really a question for Greg or Jim — I don't know why the current representation has the Objective-C methods outside of the structs. One reason might be that an interface's implementation can define more methods than are visible in its public interface in the header file, but we already seem to be aware of this and mark the implementation with DW_AT_APPLE_objc_complete_type. I also am not sure that this is the *only* reason for the objc accelerator table. But I'd like to learn.
>>
>> My observation was based on studying lldb code. The only place where
>> the objc table is used is in the AppleDWARFIndex::GetObjCMethods
>> function, which is called from
>> SymbolFileDWARF::GetObjCMethodDIEOffsets, whose only caller is
>> DWARFASTParserClang::CompleteTypeFromDWARF, which seems to have a
>> class DIE as an argument. However, if not all declarations of a
>> class/interface have access to the full list of methods then this
>> might be a problem for the approach I suggested.
>
>
> Maybe, but the same is actually true for C++ classes too (see my comments in another reply about implicit specializations of class member templates (and there are a couple of other examples)) - so might be worth considering how those are handled/could be improved, and maybe in fixing those we could improve/normalize the ObjC representation and avoid the need for ObjC tables... maybe.
>

That's a good point! I need to check out how we handle that right now.
_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm

Jonathan Wakely via llvm-dev
On Thu, 14 Jun 2018 at 19:29, Pavel Labath <[hidden email]> wrote:

>
> On Thu, 14 Jun 2018 at 19:26, David Blaikie <[hidden email]> wrote:
> >
> >
> >
> > On Thu, Jun 14, 2018 at 11:24 AM Pavel Labath <[hidden email]> wrote:
> >>
> >> On Thu, 14 Jun 2018 at 17:58, Greg Clayton <[hidden email]> wrote:
> >> >
> >> >
> >> >
> >> > On Jun 14, 2018, at 9:36 AM, Adrian Prantl <[hidden email]> wrote:
> >> >
> >> >
> >> >
> >> > On Jun 14, 2018, at 7:01 AM, Pavel Labath via llvm-dev <[hidden email]> wrote:
> >> >
> >> > Thank you all. I am going to try to reply to all comments in a single email.
> >> >
> >> > Regarding the  .apple_objc idea, I am afraid the situation is not as
> >> > simple as just flipping a switch.
> >> >
> >> >
> >> > Jonas is currently working on adding the support for DWARF5-style Objective-C accelerator tables to LLVM/LLDB/dsymutil. Based on the assumption that DWARF 4 and earlier are unaffected by any of this, I don't think it's necessary to spend any effort of making the transition smooth. I'm fine with having Objective-C on DWARF 5 broken on trunk for two weeks until Jonas is done adding Objective-C support to the DWARF 5 implementation.
> >>
> >> Ideally, I would like to enable the accelerator tables (possibly with
> >> a different version number or something) on DWARF 4 too (on non-apple
> >> targets only). The reason for this is that their absence if causing
> >> large slowdowns when debugging on non-apple platforms, and I wouldn't
> >> want to wait for dwarf 5 for that to go away (I mean no disrespect to
> >> Paul and DWARF 5 effort in general, but even if all of DWARF 5 in llvm
> >> was done tomorrow, there would still be lldb, which hasn't even begun
> >> to look at this version).
> >>
> >> That said, if you are working on the Objective C support right now,
> >> then I am happy to wait two weeks or so that we have a full
> >> implementation from the get-go.
> >>
> >> > But, other options may be possible as well. What's not clear to me is
> >> > whether these tables couldn't be replaced by extra information in the
> >> > .debug_info section. It seems to me that these tables are trying to
> >> > work around the issue that there is no straight way to go from a
> >> > DW_TAG_structure type DIE describing an ObjC class to it's methods. If
> >> > these methods (their forward declarations) were be present as children
> >> > of the type DIE (as they are for c++ classes), then these tables may
> >> > not be necessary. But maybe (probably) that has already been
> >> > considered and deemed infeasible for some reason. In any case this
> >> > seemed like a thing best left for people who actually work on ObjC
> >> > support to figure out.
> >> >
> >> >
> >> > That's really a question for Greg or Jim — I don't know why the current representation has the Objective-C methods outside of the structs. One reason might be that an interface's implementation can define more methods than are visible in its public interface in the header file, but we already seem to be aware of this and mark the implementation with DW_AT_APPLE_objc_complete_type. I also am not sure that this is the *only* reason for the objc accelerator table. But I'd like to learn.
> >>
> >> My observation was based on studying lldb code. The only place where
> >> the objc table is used is in the AppleDWARFIndex::GetObjCMethods
> >> function, which is called from
> >> SymbolFileDWARF::GetObjCMethodDIEOffsets, whose only caller is
> >> DWARFASTParserClang::CompleteTypeFromDWARF, which seems to have a
> >> class DIE as an argument. However, if not all declarations of a
> >> class/interface have access to the full list of methods then this
> >> might be a problem for the approach I suggested.
> >
> >
> > Maybe, but the same is actually true for C++ classes too (see my comments in another reply about implicit specializations of class member templates (and there are a couple of other examples)) - so might be worth considering how those are handled/could be improved, and maybe in fixing those we could improve/normalize the ObjC representation and avoid the need for ObjC tables... maybe.
> >
>
> That's a good point! I need to check out how we handle that right now.

Apparently we handle that very poorly. :/ I wasn't even able to call
the instantiation which was present in the CU I was stopped in. I
didn't even get to the part about trying an instantiation from a
different CU.
_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm

Jonathan Wakely via llvm-dev
oh, awesome.

Were you using type units? (I imagine that'd make the situation worse - since the way clang emits DWARF for a type with a member function template implicit specialization is to emit the type unit without any mention of this, and to emit the implicit specialization declaration into the stub type in the CU (that references the type unit)) Without type units I'd be pretty surprised if you couldn't call the implicit specialization at least from the CU in which it was instantiated.

On Thu, Jun 14, 2018 at 11:41 AM Pavel Labath <[hidden email]> wrote:
On Thu, 14 Jun 2018 at 19:29, Pavel Labath <[hidden email]> wrote:
>
> On Thu, 14 Jun 2018 at 19:26, David Blaikie <[hidden email]> wrote:
> >
> >
> >
> > On Thu, Jun 14, 2018 at 11:24 AM Pavel Labath <[hidden email]> wrote:
> >>
> >> On Thu, 14 Jun 2018 at 17:58, Greg Clayton <[hidden email]> wrote:
> >> >
> >> >
> >> >
> >> > On Jun 14, 2018, at 9:36 AM, Adrian Prantl <[hidden email]> wrote:
> >> >
> >> >
> >> >
> >> > On Jun 14, 2018, at 7:01 AM, Pavel Labath via llvm-dev <[hidden email]> wrote:
> >> >
> >> > Thank you all. I am going to try to reply to all comments in a single email.
> >> >
> >> > Regarding the  .apple_objc idea, I am afraid the situation is not as
> >> > simple as just flipping a switch.
> >> >
> >> >
> >> > Jonas is currently working on adding the support for DWARF5-style Objective-C accelerator tables to LLVM/LLDB/dsymutil. Based on the assumption that DWARF 4 and earlier are unaffected by any of this, I don't think it's necessary to spend any effort of making the transition smooth. I'm fine with having Objective-C on DWARF 5 broken on trunk for two weeks until Jonas is done adding Objective-C support to the DWARF 5 implementation.
> >>
> >> Ideally, I would like to enable the accelerator tables (possibly with
> >> a different version number or something) on DWARF 4 too (on non-apple
> >> targets only). The reason for this is that their absence if causing
> >> large slowdowns when debugging on non-apple platforms, and I wouldn't
> >> want to wait for dwarf 5 for that to go away (I mean no disrespect to
> >> Paul and DWARF 5 effort in general, but even if all of DWARF 5 in llvm
> >> was done tomorrow, there would still be lldb, which hasn't even begun
> >> to look at this version).
> >>
> >> That said, if you are working on the Objective C support right now,
> >> then I am happy to wait two weeks or so that we have a full
> >> implementation from the get-go.
> >>
> >> > But, other options may be possible as well. What's not clear to me is
> >> > whether these tables couldn't be replaced by extra information in the
> >> > .debug_info section. It seems to me that these tables are trying to
> >> > work around the issue that there is no straight way to go from a
> >> > DW_TAG_structure type DIE describing an ObjC class to it's methods. If
> >> > these methods (their forward declarations) were be present as children
> >> > of the type DIE (as they are for c++ classes), then these tables may
> >> > not be necessary. But maybe (probably) that has already been
> >> > considered and deemed infeasible for some reason. In any case this
> >> > seemed like a thing best left for people who actually work on ObjC
> >> > support to figure out.
> >> >
> >> >
> >> > That's really a question for Greg or Jim — I don't know why the current representation has the Objective-C methods outside of the structs. One reason might be that an interface's implementation can define more methods than are visible in its public interface in the header file, but we already seem to be aware of this and mark the implementation with DW_AT_APPLE_objc_complete_type. I also am not sure that this is the *only* reason for the objc accelerator table. But I'd like to learn.
> >>
> >> My observation was based on studying lldb code. The only place where
> >> the objc table is used is in the AppleDWARFIndex::GetObjCMethods
> >> function, which is called from
> >> SymbolFileDWARF::GetObjCMethodDIEOffsets, whose only caller is
> >> DWARFASTParserClang::CompleteTypeFromDWARF, which seems to have a
> >> class DIE as an argument. However, if not all declarations of a
> >> class/interface have access to the full list of methods then this
> >> might be a problem for the approach I suggested.
> >
> >
> > Maybe, but the same is actually true for C++ classes too (see my comments in another reply about implicit specializations of class member templates (and there are a couple of other examples)) - so might be worth considering how those are handled/could be improved, and maybe in fixing those we could improve/normalize the ObjC representation and avoid the need for ObjC tables... maybe.
> >
>
> That's a good point! I need to check out how we handle that right now.

Apparently we handle that very poorly. :/ I wasn't even able to call
the instantiation which was present in the CU I was stopped in. I
didn't even get to the part about trying an instantiation from a
different CU.

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm

Jonathan Wakely via llvm-dev
I wasn't using type units (those don't work at all right now).

I've done a bit of digging, and i found this patch
<https://reviews.llvm.org/rL260308> which explicitly disables template
member function parsing (though it seems it didn't really work before
either). The patch contains a quite long explanation of why is this
not working. I can't say I understand all of it (this is getting a bit
out of my league), but the core of the issue seems to be that when we
start to mix classes from two CU which have different sets of
instantiations in a single expression, things quickly go south because
the recycled clang ASTs from the two dwarf versions do not match.

For better or worse, it seems gdb is having similar issues as well, as
I couldn't get it to grok my member template expressions either..

On Thu, 14 Jun 2018 at 19:47, David Blaikie <[hidden email]> wrote:

>
> oh, awesome.
>
> Were you using type units? (I imagine that'd make the situation worse - since the way clang emits DWARF for a type with a member function template implicit specialization is to emit the type unit without any mention of this, and to emit the implicit specialization declaration into the stub type in the CU (that references the type unit)) Without type units I'd be pretty surprised if you couldn't call the implicit specialization at least from the CU in which it was instantiated.
>
> On Thu, Jun 14, 2018 at 11:41 AM Pavel Labath <[hidden email]> wrote:
>>
>> On Thu, 14 Jun 2018 at 19:29, Pavel Labath <[hidden email]> wrote:
>> >
>> > On Thu, 14 Jun 2018 at 19:26, David Blaikie <[hidden email]> wrote:
>> > >
>> > >
>> > >
>> > > On Thu, Jun 14, 2018 at 11:24 AM Pavel Labath <[hidden email]> wrote:
>> > >>
>> > >> On Thu, 14 Jun 2018 at 17:58, Greg Clayton <[hidden email]> wrote:
>> > >> >
>> > >> >
>> > >> >
>> > >> > On Jun 14, 2018, at 9:36 AM, Adrian Prantl <[hidden email]> wrote:
>> > >> >
>> > >> >
>> > >> >
>> > >> > On Jun 14, 2018, at 7:01 AM, Pavel Labath via llvm-dev <[hidden email]> wrote:
>> > >> >
>> > >> > Thank you all. I am going to try to reply to all comments in a single email.
>> > >> >
>> > >> > Regarding the  .apple_objc idea, I am afraid the situation is not as
>> > >> > simple as just flipping a switch.
>> > >> >
>> > >> >
>> > >> > Jonas is currently working on adding the support for DWARF5-style Objective-C accelerator tables to LLVM/LLDB/dsymutil. Based on the assumption that DWARF 4 and earlier are unaffected by any of this, I don't think it's necessary to spend any effort of making the transition smooth. I'm fine with having Objective-C on DWARF 5 broken on trunk for two weeks until Jonas is done adding Objective-C support to the DWARF 5 implementation.
>> > >>
>> > >> Ideally, I would like to enable the accelerator tables (possibly with
>> > >> a different version number or something) on DWARF 4 too (on non-apple
>> > >> targets only). The reason for this is that their absence if causing
>> > >> large slowdowns when debugging on non-apple platforms, and I wouldn't
>> > >> want to wait for dwarf 5 for that to go away (I mean no disrespect to
>> > >> Paul and DWARF 5 effort in general, but even if all of DWARF 5 in llvm
>> > >> was done tomorrow, there would still be lldb, which hasn't even begun
>> > >> to look at this version).
>> > >>
>> > >> That said, if you are working on the Objective C support right now,
>> > >> then I am happy to wait two weeks or so that we have a full
>> > >> implementation from the get-go.
>> > >>
>> > >> > But, other options may be possible as well. What's not clear to me is
>> > >> > whether these tables couldn't be replaced by extra information in the
>> > >> > .debug_info section. It seems to me that these tables are trying to
>> > >> > work around the issue that there is no straight way to go from a
>> > >> > DW_TAG_structure type DIE describing an ObjC class to it's methods. If
>> > >> > these methods (their forward declarations) were be present as children
>> > >> > of the type DIE (as they are for c++ classes), then these tables may
>> > >> > not be necessary. But maybe (probably) that has already been
>> > >> > considered and deemed infeasible for some reason. In any case this
>> > >> > seemed like a thing best left for people who actually work on ObjC
>> > >> > support to figure out.
>> > >> >
>> > >> >
>> > >> > That's really a question for Greg or Jim — I don't know why the current representation has the Objective-C methods outside of the structs. One reason might be that an interface's implementation can define more methods than are visible in its public interface in the header file, but we already seem to be aware of this and mark the implementation with DW_AT_APPLE_objc_complete_type. I also am not sure that this is the *only* reason for the objc accelerator table. But I'd like to learn.
>> > >>
>> > >> My observation was based on studying lldb code. The only place where
>> > >> the objc table is used is in the AppleDWARFIndex::GetObjCMethods
>> > >> function, which is called from
>> > >> SymbolFileDWARF::GetObjCMethodDIEOffsets, whose only caller is
>> > >> DWARFASTParserClang::CompleteTypeFromDWARF, which seems to have a
>> > >> class DIE as an argument. However, if not all declarations of a
>> > >> class/interface have access to the full list of methods then this
>> > >> might be a problem for the approach I suggested.
>> > >
>> > >
>> > > Maybe, but the same is actually true for C++ classes too (see my comments in another reply about implicit specializations of class member templates (and there are a couple of other examples)) - so might be worth considering how those are handled/could be improved, and maybe in fixing those we could improve/normalize the ObjC representation and avoid the need for ObjC tables... maybe.
>> > >
>> >
>> > That's a good point! I need to check out how we handle that right now.
>>
>> Apparently we handle that very poorly. :/ I wasn't even able to call
>> the instantiation which was present in the CU I was stopped in. I
>> didn't even get to the part about trying an instantiation from a
>> different CU.
_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm

Jonathan Wakely via llvm-dev
To elaborate a bit more on the issue that is detailed in https://reviews.llvm.org/rL260308:

There are many clang AST contexts that are used in LLDB:
- one for each lldb_private::Module that contains type definitions as we know them in the module and its symbol vendor
- one for each expression
- one for results of expressions in the lldb_private::Target

As we run expressions we end up copying classes around between the Module ASTs and the expression and Target ASTs. If a class has templated functions, they will only be in the DWARF is a specialization was created and used. If you have a class that looks like:

class A {
   A();
   <template T> void Foo(T t);
};


And then you have main.cpp that has a "double" and "int" specialization, the class definition in DWARF looks like:

class A {
   A();
   <int> void Foo(int t);
   <double> void Foo(double t);
};

In another source file, say foo.cpp, if its use of class A doesn't specialize Foo, we have a class definition in DWARF that looks like:

class A {
   A();
};

With the C++ ODR rules, we can pick any of the "class A" definitions whose qualified name matches ("::A") and has the same decl file + decl line. So when parsing "class A", the DWARF parser will use the accelerator tables to find all instances of "class A", and it will pick on and use it and this will become the one true definition for "class A". This is because DWARF is only emitted for template functions when there is a specialization, that mean any definition of "class A" might or might not include any definition for "<template T> A::Foo(T t);". When we copy types between ASTs, everything is fine if the classes match (no copy needs to be made), but things go wrong if things don't match and this causes expression errors. 

Some ways to fix this:
1 - anytime we need _any_ C++ class, we must dig up all definitions and check _all_ DW_TAG_subprogram DIEs within the class to check if any functions have templates and use the class with the most specializations
2 - have DWARF actually emit the template function info all the time as a type T, not a specialization, so we always have the full definition
3 - have some accelerator table that explicitly points us to all specializations of class methods given a class name

Solution #1 would cause us to dig through all definitions of all C++ classes all the time when parsing DWARF to check if definitions of the classes had template methods. And we would need to find the class that has the most template methods. This would cause us to parse much more of the debug info all of the time and cause increased memory consumption and performance regressions.

Solution #2: not sure if DWARF even supports generic template definitions where the template isn't specialized. And, how would we be able to tell DWARF that emits only specialized templates vs one that has generic definitions...

Solution #3 will require compiler changes.

So this is another vote to support the ability for a given class to be able to locate all of its functions, kind of like we need for Objective C where the class definition doesn't contain all of methods, so we have the .apple_objc section that provides this mapping for us. We would need something similar for C++.

So maybe a possible solution is some sort of section that can specify all of the DIEs related to a class that are not contained in the class hierarchy itself. This would work for Objective C and for C++.

Thoughts?

Greg

On Jun 15, 2018, at 3:34 AM, Pavel Labath <[hidden email]> wrote:

I wasn't using type units (those don't work at all right now).

I've done a bit of digging, and i found this patch
<https://reviews.llvm.org/rL260308> which explicitly disables template
member function parsing (though it seems it didn't really work before
either). The patch contains a quite long explanation of why is this
not working. I can't say I understand all of it (this is getting a bit
out of my league), but the core of the issue seems to be that when we
start to mix classes from two CU which have different sets of
instantiations in a single expression, things quickly go south because
the recycled clang ASTs from the two dwarf versions do not match.

For better or worse, it seems gdb is having similar issues as well, as
I couldn't get it to grok my member template expressions either..

On Thu, 14 Jun 2018 at 19:47, David Blaikie <[hidden email]> wrote:

oh, awesome.

Were you using type units? (I imagine that'd make the situation worse - since the way clang emits DWARF for a type with a member function template implicit specialization is to emit the type unit without any mention of this, and to emit the implicit specialization declaration into the stub type in the CU (that references the type unit)) Without type units I'd be pretty surprised if you couldn't call the implicit specialization at least from the CU in which it was instantiated.

On Thu, Jun 14, 2018 at 11:41 AM Pavel Labath <[hidden email]> wrote:

On Thu, 14 Jun 2018 at 19:29, Pavel Labath <[hidden email]> wrote:

On Thu, 14 Jun 2018 at 19:26, David Blaikie <[hidden email]> wrote:



On Thu, Jun 14, 2018 at 11:24 AM Pavel Labath <[hidden email]> wrote:

On Thu, 14 Jun 2018 at 17:58, Greg Clayton <[hidden email]> wrote:



On Jun 14, 2018, at 9:36 AM, Adrian Prantl <[hidden email]> wrote:



On Jun 14, 2018, at 7:01 AM, Pavel Labath via llvm-dev <[hidden email]> wrote:

Thank you all. I am going to try to reply to all comments in a single email.

Regarding the  .apple_objc idea, I am afraid the situation is not as
simple as just flipping a switch.


Jonas is currently working on adding the support for DWARF5-style Objective-C accelerator tables to LLVM/LLDB/dsymutil. Based on the assumption that DWARF 4 and earlier are unaffected by any of this, I don't think it's necessary to spend any effort of making the transition smooth. I'm fine with having Objective-C on DWARF 5 broken on trunk for two weeks until Jonas is done adding Objective-C support to the DWARF 5 implementation.

Ideally, I would like to enable the accelerator tables (possibly with
a different version number or something) on DWARF 4 too (on non-apple
targets only). The reason for this is that their absence if causing
large slowdowns when debugging on non-apple platforms, and I wouldn't
want to wait for dwarf 5 for that to go away (I mean no disrespect to
Paul and DWARF 5 effort in general, but even if all of DWARF 5 in llvm
was done tomorrow, there would still be lldb, which hasn't even begun
to look at this version).

That said, if you are working on the Objective C support right now,
then I am happy to wait two weeks or so that we have a full
implementation from the get-go.

But, other options may be possible as well. What's not clear to me is
whether these tables couldn't be replaced by extra information in the
.debug_info section. It seems to me that these tables are trying to
work around the issue that there is no straight way to go from a
DW_TAG_structure type DIE describing an ObjC class to it's methods. If
these methods (their forward declarations) were be present as children
of the type DIE (as they are for c++ classes), then these tables may
not be necessary. But maybe (probably) that has already been
considered and deemed infeasible for some reason. In any case this
seemed like a thing best left for people who actually work on ObjC
support to figure out.


That's really a question for Greg or Jim — I don't know why the current representation has the Objective-C methods outside of the structs. One reason might be that an interface's implementation can define more methods than are visible in its public interface in the header file, but we already seem to be aware of this and mark the implementation with DW_AT_APPLE_objc_complete_type. I also am not sure that this is the *only* reason for the objc accelerator table. But I'd like to learn.

My observation was based on studying lldb code. The only place where
the objc table is used is in the AppleDWARFIndex::GetObjCMethods
function, which is called from
SymbolFileDWARF::GetObjCMethodDIEOffsets, whose only caller is
DWARFASTParserClang::CompleteTypeFromDWARF, which seems to have a
class DIE as an argument. However, if not all declarations of a
class/interface have access to the full list of methods then this
might be a problem for the approach I suggested.


Maybe, but the same is actually true for C++ classes too (see my comments in another reply about implicit specializations of class member templates (and there are a couple of other examples)) - so might be worth considering how those are handled/could be improved, and maybe in fixing those we could improve/normalize the ObjC representation and avoid the need for ObjC tables... maybe.


That's a good point! I need to check out how we handle that right now.

Apparently we handle that very poorly. :/ I wasn't even able to call
the instantiation which was present in the CU I was stopped in. I
didn't even get to the part about trying an instantiation from a
different CU.


_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm

Jonathan Wakely via llvm-dev
> From: Greg Clayton [mailto:[hidden email]]
>
> ...
> If a class has templated functions, they will only be in the DWARF is a
> specialization was created and used. If you have a class that looks like:
>
> class A {
>   A();
>   <template T> void Foo(T t);
> };
>
> And then you have main.cpp that has a "double" and "int" specialization,
> the class definition in DWARF looks like:
>
> class A {
>   A();
>   <int> void Foo(int t);
>   <double> void Foo(double t);
> };
>
> In another source file, say foo.cpp, if its use of class A doesn't
> specialize Foo, we have a class definition in DWARF that looks like:
>
> class A {
>   A();
> };
>

I think it would be more instructive to think about a case where
main.cpp had Foo<int> and foo.cpp had Foo<double>.

> With the C++ ODR rules, we can pick any of the "class A" definitions
> whose qualified name matches ("::A") and has the same decl file +
> decl line. So when parsing "class A", the DWARF parser will use the
> accelerator tables to find all instances of "class A", and it will
> pick on and use it and this will become the one true definition for
> "class A".

FTR, the Sony debugger finds them all and then merges them into the one
true definition, because there's no promise that any one description is
a superset of the rest.

> This is because DWARF is only emitted for template functions when
> there is a specialization, that mean any definition of "class A" might
> or might not include any definition for "<template T> A::Foo(T t);".

It's not just template functions, you know; the implicit ctors/dtors
might or might not be in any given description.  Those are also only
instantiated and described in CUs that require them.

> When we copy types between ASTs, everything is fine if the classes
> match (no copy needs to be made), but things go wrong if things
> don't match and this causes expression errors. 
>
> Some ways to fix this:
> 1 - anytime we need _any_ C++ class, we must dig up all definitions
> and check _all_ DW_TAG_subprogram DIEs within the class to check if
> any functions have templates and use the class with the most
> specializations

This still fails in my "more instructive" case.  The accelerator table
does make it fast to find all the classes with the same name, and you
can then merge them.

> 2 - have DWARF actually emit the template function info all the time
> as a type T, not a specialization, so we always have the full definition

Hm.  You mean a subroutine_type with template_parameter children that
don't have actual values?  That would give you a pattern, but not tell
you what/where definitions exist.  I don't see how that can help?

> 3 - have some accelerator table that explicitly points us to all
> specializations of class methods given a class name

So you want an accelerator to tell you what bits you need to pick up
from the various descriptions in order to construct the overall
superset definition, which would be a little cheaper than parsing
each entire class description (which you can already find through
the existing accelerator tables).  I can see that.

> Solution #1 would cause us to dig through all definitions of all C++
> classes all the time when parsing DWARF to check if definitions of
> the classes had template methods. And we would need to find the class
> that has the most template methods. This would cause us to parse much
> more of the debug info all of the time and cause increased memory
> consumption and performance regressions.

It would be cheap to put a flag on the class DIE that tells you there
are template methods to go look for.  Then you incur the cost only
when necessary.  And the accelerator table makes it fast to find the
other class descriptions.

> Solution #2: not sure if DWARF even supports generic template
> definitions where the template isn't specialized. And, how would we
> be able to tell DWARF that emits only specialized templates vs one
> that has generic definitions...

Right, DWARF today doesn't do that, although as I mentioned earlier
conjuring up a subroutine_type with template parameters would not
appear to be any more helpful than a simple flag on the class.

>
> Solution #3 will require compiler changes.

Well, so does #2.

> So this is another vote to support the ability for a given class
> to be able to locate all of its functions, kind of like we need
> for Objective C where the class definition doesn't contain all of
> methods, so we have the .apple_objc section that provides this
> mapping for us. We would need something similar for C++.
>
> So maybe a possible solution is some sort of section that can
> specify all of the DIEs related to a class that are not contained
> in the class hierarchy itself. This would work for Objective C
> and for C++.
>
> Thoughts?
>
> Greg

So, would it be helpful to have a flag on the class that tells you
whether there are method instantiations to go look for?  My
impression is that templated class methods are unusual so it would
save the performance cost a lot of the time right there.

I don't know enough about Obj-C to say whether it can know up front
there are potentially other methods elsewhere.

--paulr
_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm

Jonathan Wakely via llvm-dev


> On Jun 15, 2018, at 9:23 AM, <[hidden email]> <[hidden email]> wrote:
>
>> From: Greg Clayton [mailto:[hidden email]]
>>
>> ...
>> If a class has templated functions, they will only be in the DWARF is a
>> specialization was created and used. If you have a class that looks like:
>>
>> class A {
>>    A();
>>    <template T> void Foo(T t);
>> };
>>
>> And then you have main.cpp that has a "double" and "int" specialization,
>> the class definition in DWARF looks like:
>>
>> class A {
>>    A();
>>    <int> void Foo(int t);
>>    <double> void Foo(double t);
>> };
>>
>> In another source file, say foo.cpp, if its use of class A doesn't
>> specialize Foo, we have a class definition in DWARF that looks like:
>>
>> class A {
>>    A();
>> };
>>
>
> I think it would be more instructive to think about a case where
> main.cpp had Foo<int> and foo.cpp had Foo<double>.

Any difference is the problem here for clang ASTs, so it just matters that they are different. We make a CXXRecordDecl in the clang AST and if we see even one specialization, then we add the generic version to the CXXRecordDecl and we are good to go. So the main.cpp had Foo<int> and foo.cpp had Foo<double> is actually fine. If I make a CXXRecordDecl from either of these then the two definitions match since the clang AST CXXRecordDecl just needs to have the templated function declaration.

>
>> With the C++ ODR rules, we can pick any of the "class A" definitions
>> whose qualified name matches ("::A") and has the same decl file +
>> decl line. So when parsing "class A", the DWARF parser will use the
>> accelerator tables to find all instances of "class A", and it will
>> pick on and use it and this will become the one true definition for
>> "class A".
>
> FTR, the Sony debugger finds them all and then merges them into the one
> true definition, because there's no promise that any one description is
> a superset of the rest.

At the expense of parsing every definition for a class within each file.
>
>> This is because DWARF is only emitted for template functions when
>> there is a specialization, that mean any definition of "class A" might
>> or might not include any definition for "<template T> A::Foo(T t);".
>
> It's not just template functions, you know; the implicit ctors/dtors
> might or might not be in any given description.  Those are also only
> instantiated and described in CUs that require them.

We don't care about those as those are marked as DW_AT_artificial and we leave those out of the clang AST Context CXXRecordDecl because they are implicit and the compiler can add those back in if needed since it knows if a class can have the constructors implicitly created.

>
>> When we copy types between ASTs, everything is fine if the classes
>> match (no copy needs to be made), but things go wrong if things
>> don't match and this causes expression errors.
>>
>> Some ways to fix this:
>> 1 - anytime we need _any_ C++ class, we must dig up all definitions
>> and check _all_ DW_TAG_subprogram DIEs within the class to check if
>> any functions have templates and use the class with the most
>> specializations
>
> This still fails in my "more instructive" case.  The accelerator table
> does make it fast to find all the classes with the same name, and you
> can then merge them.

That is a lot of DWARF parsing and logic to try and figure out what the full set of DW_TAG_subprograms are.

>
>> 2 - have DWARF actually emit the template function info all the time
>> as a type T, not a specialization, so we always have the full definition
>
> Hm.  You mean a subroutine_type with template_parameter children that
> don't have actual values?  That would give you a pattern, but not tell
> you what/where definitions exist.  I don't see how that can help?

Right now DWARF does only specializations, so DWARF would need to be extended to be able to specify the template details without requiring a specialization. Not easy for sure.

>
>> 3 - have some accelerator table that explicitly points us to all
>> specializations of class methods given a class name
>
> So you want an accelerator to tell you what bits you need to pick up
> from the various descriptions in order to construct the overall
> superset definition, which would be a little cheaper than parsing
> each entire class description (which you can already find through
> the existing accelerator tables).  I can see that.

Yes. This is the most appealing to me as well.

>
>> Solution #1 would cause us to dig through all definitions of all C++
>> classes all the time when parsing DWARF to check if definitions of
>> the classes had template methods. And we would need to find the class
>> that has the most template methods. This would cause us to parse much
>> more of the debug info all of the time and cause increased memory
>> consumption and performance regressions.
>
> It would be cheap to put a flag on the class DIE that tells you there
> are template methods to go look for.  Then you incur the cost only
> when necessary.  And the accelerator table makes it fast to find the
> other class descriptions.

That is a fine solution. But we still run into the problem where we don't know if the DWARF knows about that flag. If we do a flag, it would be nice if it were mandatory on all classes to indicate support for the flag. But this would be a fine solution and not hard to implement.
>
>> Solution #2: not sure if DWARF even supports generic template
>> definitions where the template isn't specialized. And, how would we
>> be able to tell DWARF that emits only specialized templates vs one
>> that has generic definitions...
>
> Right, DWARF today doesn't do that, although as I mentioned earlier
> conjuring up a subroutine_type with template parameters would not
> appear to be any more helpful than a simple flag on the class.

Yeah, there would have to be new DWARF and a lot of DW_AT_specification or DW_AT_abstract_origin references involved...

>
>>
>> Solution #3 will require compiler changes.
>
> Well, so does #2.

Indeed.

>
>> So this is another vote to support the ability for a given class
>> to be able to locate all of its functions, kind of like we need
>> for Objective C where the class definition doesn't contain all of
>> methods, so we have the .apple_objc section that provides this
>> mapping for us. We would need something similar for C++.
>>
>> So maybe a possible solution is some sort of section that can
>> specify all of the DIEs related to a class that are not contained
>> in the class hierarchy itself. This would work for Objective C
>> and for C++.
>>
>> Thoughts?
>>
>> Greg
>
> So, would it be helpful to have a flag on the class that tells you
> whether there are method instantiations to go look for?  

That would be a great start to solution #1 if that is the way we choose to go.

> My
> impression is that templated class methods are unusual so it would
> save the performance cost a lot of the time right there.
>
> I don't know enough about Obj-C to say whether it can know up front
> there are potentially other methods elsewhere.

Another way to do the objective C solution would be to have an attribute on a DW_TAG_class_type that could specify a list of DIEs that are not contained in the class definition that are required for the class. In Objective C, the DW_TAG_subprogram for methods are outside of the class itself. This would involve DWARF changes, but it could be an attribute that specifies a section offset into a new section that contains a DIE offset list.

So the Objective C case is still different enough from the C++ case because in the C++ case all functions are still contained within the DW_TAG_class_type DIE IIRC.


Greg
_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm

Jonathan Wakely via llvm-dev


> -----Original Message-----
> From: Greg Clayton [mailto:[hidden email]]
> Sent: Friday, June 15, 2018 12:46 PM
> To: Robinson, Paul
> Cc: [hidden email]; [hidden email]; [hidden email];
> [hidden email]; [hidden email]; [hidden email];
> [hidden email]; [hidden email]; Jim Ingham
> Subject: Re: [llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support
> to llvm
>
>
>
> > On Jun 15, 2018, at 9:23 AM, <[hidden email]>
> <[hidden email]> wrote:
> >
> >> From: Greg Clayton [mailto:[hidden email]]
> >>
> >> ...
> >> If a class has templated functions, they will only be in the DWARF is a
> >> specialization was created and used. If you have a class that looks
> like:
> >>
> >> class A {
> >>    A();
> >>    <template T> void Foo(T t);
> >> };
> >>
> >> And then you have main.cpp that has a "double" and "int"
> specialization,
> >> the class definition in DWARF looks like:
> >>
> >> class A {
> >>    A();
> >>    <int> void Foo(int t);
> >>    <double> void Foo(double t);
> >> };
> >>
> >> In another source file, say foo.cpp, if its use of class A doesn't
> >> specialize Foo, we have a class definition in DWARF that looks like:
> >>
> >> class A {
> >>    A();
> >> };
> >>
> >
> > I think it would be more instructive to think about a case where
> > main.cpp had Foo<int> and foo.cpp had Foo<double>.
>
> Any difference is the problem here for clang ASTs, so it just matters that
> they are different. We make a CXXRecordDecl in the clang AST and if we see
> even one specialization, then we add the generic version to the
> CXXRecordDecl and we are good to go. So the main.cpp had Foo<int> and
> foo.cpp had Foo<double> is actually fine. If I make a CXXRecordDecl from
> either of these then the two definitions match since the clang AST
> CXXRecordDecl just needs to have the templated function declaration.

Got it, good to know.
You don't actually care what instantiations exist? That seems odd.

>
> >
> >> With the C++ ODR rules, we can pick any of the "class A" definitions
> >> whose qualified name matches ("::A") and has the same decl file +
> >> decl line. So when parsing "class A", the DWARF parser will use the
> >> accelerator tables to find all instances of "class A", and it will
> >> pick on and use it and this will become the one true definition for
> >> "class A".
> >
> > FTR, the Sony debugger finds them all and then merges them into the one
> > true definition, because there's no promise that any one description is
> > a superset of the rest.
>
> At the expense of parsing every definition for a class within each file.
> >
> >> This is because DWARF is only emitted for template functions when
> >> there is a specialization, that mean any definition of "class A" might
> >> or might not include any definition for "<template T> A::Foo(T t);".
> >
> > It's not just template functions, you know; the implicit ctors/dtors
> > might or might not be in any given description.  Those are also only
> > instantiated and described in CUs that require them.
>
> We don't care about those as those are marked as DW_AT_artificial and we
> leave those out of the clang AST Context CXXRecordDecl because they are
> implicit and the compiler can add those back in if needed since it knows
> if a class can have the constructors implicitly created.
>
> >
> >> When we copy types between ASTs, everything is fine if the classes
> >> match (no copy needs to be made), but things go wrong if things
> >> don't match and this causes expression errors.
> >>
> >> Some ways to fix this:
> >> 1 - anytime we need _any_ C++ class, we must dig up all definitions
> >> and check _all_ DW_TAG_subprogram DIEs within the class to check if
> >> any functions have templates and use the class with the most
> >> specializations
> >
> > This still fails in my "more instructive" case.  The accelerator table
> > does make it fast to find all the classes with the same name, and you
> > can then merge them.
>
> That is a lot of DWARF parsing and logic to try and figure out what the
> full set of DW_TAG_subprograms are.
>
> >
> >> 2 - have DWARF actually emit the template function info all the time
> >> as a type T, not a specialization, so we always have the full
> definition
> >
> > Hm.  You mean a subroutine_type with template_parameter children that
> > don't have actual values?  That would give you a pattern, but not tell
> > you what/where definitions exist.  I don't see how that can help?
>
> Right now DWARF does only specializations, so DWARF would need to be
> extended to be able to specify the template details without requiring a
> specialization. Not easy for sure.
>
> >
> >> 3 - have some accelerator table that explicitly points us to all
> >> specializations of class methods given a class name
> >
> > So you want an accelerator to tell you what bits you need to pick up
> > from the various descriptions in order to construct the overall
> > superset definition, which would be a little cheaper than parsing
> > each entire class description (which you can already find through
> > the existing accelerator tables).  I can see that.
>
> Yes. This is the most appealing to me as well.
>
> >
> >> Solution #1 would cause us to dig through all definitions of all C++
> >> classes all the time when parsing DWARF to check if definitions of
> >> the classes had template methods. And we would need to find the class
> >> that has the most template methods. This would cause us to parse much
> >> more of the debug info all of the time and cause increased memory
> >> consumption and performance regressions.
> >
> > It would be cheap to put a flag on the class DIE that tells you there
> > are template methods to go look for.  Then you incur the cost only
> > when necessary.  And the accelerator table makes it fast to find the
> > other class descriptions.
>
> That is a fine solution. But we still run into the problem where we don't
> know if the DWARF knows about that flag. If we do a flag, it would be nice
> if it were mandatory on all classes to indicate support for the flag. But
> this would be a fine solution and not hard to implement.

So what you really want is not a flag, but a count, so you can tell when
you've found all the different templates.  If the count is zero, there's
nothing to look for.  If the count is two, you look around at all the
various definitions of the class until you find two different templates,
then you stop.  If there's no count attribute, your producer doesn't
know you want this information and you do it the hard way.  Or, we've
invented a way to describe the templates directly in the class.

How's that?
--paulr

> >
> >> Solution #2: not sure if DWARF even supports generic template
> >> definitions where the template isn't specialized. And, how would we
> >> be able to tell DWARF that emits only specialized templates vs one
> >> that has generic definitions...
> >
> > Right, DWARF today doesn't do that, although as I mentioned earlier
> > conjuring up a subroutine_type with template parameters would not
> > appear to be any more helpful than a simple flag on the class.
>
> Yeah, there would have to be new DWARF and a lot of DW_AT_specification or
> DW_AT_abstract_origin references involved...
>
> >
> >>
> >> Solution #3 will require compiler changes.
> >
> > Well, so does #2.
>
> Indeed.
>
> >
> >> So this is another vote to support the ability for a given class
> >> to be able to locate all of its functions, kind of like we need
> >> for Objective C where the class definition doesn't contain all of
> >> methods, so we have the .apple_objc section that provides this
> >> mapping for us. We would need something similar for C++.
> >>
> >> So maybe a possible solution is some sort of section that can
> >> specify all of the DIEs related to a class that are not contained
> >> in the class hierarchy itself. This would work for Objective C
> >> and for C++.
> >>
> >> Thoughts?
> >>
> >> Greg
> >
> > So, would it be helpful to have a flag on the class that tells you
> > whether there are method instantiations to go look for?
>
> That would be a great start to solution #1 if that is the way we choose to
> go.
>
> > My
> > impression is that templated class methods are unusual so it would
> > save the performance cost a lot of the time right there.
> >
> > I don't know enough about Obj-C to say whether it can know up front
> > there are potentially other methods elsewhere.
>
> Another way to do the objective C solution would be to have an attribute
> on a DW_TAG_class_type that could specify a list of DIEs that are not
> contained in the class definition that are required for the class. In
> Objective C, the DW_TAG_subprogram for methods are outside of the class
> itself. This would involve DWARF changes, but it could be an attribute
> that specifies a section offset into a new section that contains a DIE
> offset list.
>
> So the Objective C case is still different enough from the C++ case
> because in the C++ case all functions are still contained within the
> DW_TAG_class_type DIE IIRC.
>
>
> Greg
_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm

Jonathan Wakely via llvm-dev


On Jun 15, 2018, at 10:40 AM, <[hidden email]> <[hidden email]> wrote:



-----Original Message-----
From: Greg Clayton [[hidden email]]
Sent: Friday, June 15, 2018 12:46 PM
To: Robinson, Paul
Cc: [hidden email]; [hidden email]; [hidden email];
[hidden email]; [hidden email]; [hidden email];
[hidden email]; [hidden email]; Jim Ingham
Subject: Re: [llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support
to llvm



On Jun 15, 2018, at 9:23 AM, <[hidden email]>
<[hidden email]> wrote:

From: Greg Clayton [[hidden email]]

...
If a class has templated functions, they will only be in the DWARF is a
specialization was created and used. If you have a class that looks
like:

class A {
  A();
  <template T> void Foo(T t);
};

And then you have main.cpp that has a "double" and "int"
specialization,
the class definition in DWARF looks like:

class A {
  A();
  <int> void Foo(int t);
  <double> void Foo(double t);
};

In another source file, say foo.cpp, if its use of class A doesn't
specialize Foo, we have a class definition in DWARF that looks like:

class A {
  A();
};


I think it would be more instructive to think about a case where
main.cpp had Foo<int> and foo.cpp had Foo<double>.

Any difference is the problem here for clang ASTs, so it just matters that
they are different. We make a CXXRecordDecl in the clang AST and if we see
even one specialization, then we add the generic version to the
CXXRecordDecl and we are good to go. So the main.cpp had Foo<int> and
foo.cpp had Foo<double> is actually fine. If I make a CXXRecordDecl from
either of these then the two definitions match since the clang AST
CXXRecordDecl just needs to have the templated function declaration.

Got it, good to know.
You don't actually care what instantiations exist? That seems odd.

The compiler will use the generic type and ask where the specialized version lives. For the template method type, we will in the right stuff when we make the function type, but the class itself just has the generic definition. 



With the C++ ODR rules, we can pick any of the "class A" definitions
whose qualified name matches ("::A") and has the same decl file +
decl line. So when parsing "class A", the DWARF parser will use the
accelerator tables to find all instances of "class A", and it will
pick on and use it and this will become the one true definition for
"class A".

FTR, the Sony debugger finds them all and then merges them into the one
true definition, because there's no promise that any one description is
a superset of the rest.

At the expense of parsing every definition for a class within each file.

This is because DWARF is only emitted for template functions when
there is a specialization, that mean any definition of "class A" might
or might not include any definition for "<template T> A::Foo(T t);".

It's not just template functions, you know; the implicit ctors/dtors
might or might not be in any given description.  Those are also only
instantiated and described in CUs that require them.

We don't care about those as those are marked as DW_AT_artificial and we
leave those out of the clang AST Context CXXRecordDecl because they are
implicit and the compiler can add those back in if needed since it knows
if a class can have the constructors implicitly created.


When we copy types between ASTs, everything is fine if the classes
match (no copy needs to be made), but things go wrong if things
don't match and this causes expression errors.

Some ways to fix this:
1 - anytime we need _any_ C++ class, we must dig up all definitions
and check _all_ DW_TAG_subprogram DIEs within the class to check if
any functions have templates and use the class with the most
specializations

This still fails in my "more instructive" case.  The accelerator table
does make it fast to find all the classes with the same name, and you
can then merge them.

That is a lot of DWARF parsing and logic to try and figure out what the
full set of DW_TAG_subprograms are.


2 - have DWARF actually emit the template function info all the time
as a type T, not a specialization, so we always have the full
definition

Hm.  You mean a subroutine_type with template_parameter children that
don't have actual values?  That would give you a pattern, but not tell
you what/where definitions exist.  I don't see how that can help?

Right now DWARF does only specializations, so DWARF would need to be
extended to be able to specify the template details without requiring a
specialization. Not easy for sure.


3 - have some accelerator table that explicitly points us to all
specializations of class methods given a class name

So you want an accelerator to tell you what bits you need to pick up
from the various descriptions in order to construct the overall
superset definition, which would be a little cheaper than parsing
each entire class description (which you can already find through
the existing accelerator tables).  I can see that.

Yes. This is the most appealing to me as well.


Solution #1 would cause us to dig through all definitions of all C++
classes all the time when parsing DWARF to check if definitions of
the classes had template methods. And we would need to find the class
that has the most template methods. This would cause us to parse much
more of the debug info all of the time and cause increased memory
consumption and performance regressions.

It would be cheap to put a flag on the class DIE that tells you there
are template methods to go look for.  Then you incur the cost only
when necessary.  And the accelerator table makes it fast to find the
other class descriptions.

That is a fine solution. But we still run into the problem where we don't
know if the DWARF knows about that flag. If we do a flag, it would be nice
if it were mandatory on all classes to indicate support for the flag. But
this would be a fine solution and not hard to implement.

So what you really want is not a flag, but a count, so you can tell when
you've found all the different templates.  If the count is zero, there's
nothing to look for.  If the count is two, you look around at all the
various definitions of the class until you find two different templates,
then you stop.  If there's no count attribute, your producer doesn't 
know you want this information and you do it the hard way.  Or, we've
invented a way to describe the templates directly in the class.

How's that?

that would work fine.

--paulr


Solution #2: not sure if DWARF even supports generic template
definitions where the template isn't specialized. And, how would we
be able to tell DWARF that emits only specialized templates vs one
that has generic definitions...

Right, DWARF today doesn't do that, although as I mentioned earlier
conjuring up a subroutine_type with template parameters would not
appear to be any more helpful than a simple flag on the class.

Yeah, there would have to be new DWARF and a lot of DW_AT_specification or
DW_AT_abstract_origin references involved...



Solution #3 will require compiler changes.

Well, so does #2.

Indeed.


So this is another vote to support the ability for a given class
to be able to locate all of its functions, kind of like we need
for Objective C where the class definition doesn't contain all of
methods, so we have the .apple_objc section that provides this
mapping for us. We would need something similar for C++.

So maybe a possible solution is some sort of section that can
specify all of the DIEs related to a class that are not contained
in the class hierarchy itself. This would work for Objective C
and for C++.

Thoughts?

Greg

So, would it be helpful to have a flag on the class that tells you
whether there are method instantiations to go look for?

That would be a great start to solution #1 if that is the way we choose to
go.

My
impression is that templated class methods are unusual so it would
save the performance cost a lot of the time right there.

I don't know enough about Obj-C to say whether it can know up front
there are potentially other methods elsewhere.

Another way to do the objective C solution would be to have an attribute
on a DW_TAG_class_type that could specify a list of DIEs that are not
contained in the class definition that are required for the class. In
Objective C, the DW_TAG_subprogram for methods are outside of the class
itself. This would involve DWARF changes, but it could be an attribute
that specifies a section offset into a new section that contains a DIE
offset list.

So the Objective C case is still different enough from the C++ case
because in the C++ case all functions are still contained within the
DW_TAG_class_type DIE IIRC.


Greg


_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm

Jonathan Wakely via llvm-dev
gc> Solution #1 would cause us to dig through all definitions of all C++
gc> classes all the time when parsing DWARF to check if definitions of
gc> the classes had template methods. And we would need to find the class
gc> that has the most template methods. This would cause us to parse much
gc> more of the debug info all of the time and cause increased memory
gc> consumption and performance regressions.

pr> It would be cheap to put a flag on the class DIE that tells you there
pr> are template methods to go look for.  Then you incur the cost only
pr> when necessary.  And the accelerator table makes it fast to find the
pr> other class descriptions.

gc> That is a fine solution. But we still run into the problem where we don't
gc> know if the DWARF knows about that flag. If we do a flag, it would be nice
gc> if it were mandatory on all classes to indicate support for the flag. But
gc> this would be a fine solution and not hard to implement.

pr> So what you really want is not a flag, but a count, so you can tell when
pr> you've found all the different templates.  If the count is zero, there's
pr> nothing to look for.  If the count is two, you look around at all the
pr> various definitions of the class until you find two different templates,
pr> then you stop.  If there's no count attribute, your producer doesn't 
pr> know you want this information and you do it the hard way.  Or, we've
pr> invented a way to describe the templates directly in the class.
pr>
pr> How's that?

gc> that would work fine.

I filed PR37816 to track this idea.

The other ideas:

 - accelerator to point to the actual instantiations
 - emitting template definitions not just instantiations

would be trickier to define and harder to implement correctly.
I won't say they can't be done, but somebody else would have to do
the heavy lifting here, unless it turns out that our debugger folks
like the idea.

--paulr

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm

Jonathan Wakely via llvm-dev
How do you handle name lookup for nested classes? They have the same problem (they don't appear in all definitions) - don't appear in all descriptions of the outer/parent class. (in theory we could ensure there's always at least a declaration of the nested class - but we don't even do that if the nested class is unused)

Is it just the case that Clang doesn't mind you adding a new nested class but it does mind you adding a new member function template? If so, maybe we could change Clang to support adding new member function templates instead of extending DWARF?

On Fri, Jun 15, 2018 at 11:59 AM <[hidden email]> wrote:
gc> Solution #1 would cause us to dig through all definitions of all C++
gc> classes all the time when parsing DWARF to check if definitions of
gc> the classes had template methods. And we would need to find the class
gc> that has the most template methods. This would cause us to parse much
gc> more of the debug info all of the time and cause increased memory
gc> consumption and performance regressions.

pr> It would be cheap to put a flag on the class DIE that tells you there
pr> are template methods to go look for.  Then you incur the cost only
pr> when necessary.  And the accelerator table makes it fast to find the
pr> other class descriptions.

gc> That is a fine solution. But we still run into the problem where we don't
gc> know if the DWARF knows about that flag. If we do a flag, it would be nice
gc> if it were mandatory on all classes to indicate support for the flag. But
gc> this would be a fine solution and not hard to implement.

pr> So what you really want is not a flag, but a count, so you can tell when
pr> you've found all the different templates.  If the count is zero, there's
pr> nothing to look for.  If the count is two, you look around at all the
pr> various definitions of the class until you find two different templates,
pr> then you stop.  If there's no count attribute, your producer doesn't 
pr> know you want this information and you do it the hard way.  Or, we've
pr> invented a way to describe the templates directly in the class.
pr>
pr> How's that?

gc> that would work fine.

I filed PR37816 to track this idea.

The other ideas:

 - accelerator to point to the actual instantiations
 - emitting template definitions not just instantiations

would be trickier to define and harder to implement correctly.
I won't say they can't be done, but somebody else would have to do
the heavy lifting here, unless it turns out that our debugger folks
like the idea.

--paulr


_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm

Jonathan Wakely via llvm-dev
On Fri, 15 Jun 2018 at 20:14, David Blaikie <[hidden email]> wrote:
>
> How do you handle name lookup for nested classes? They have the same problem (they don't appear in all definitions) - don't appear in all descriptions of the outer/parent class. (in theory we could ensure there's always at least a declaration of the nested class - but we don't even do that if the nested class is unused)
>
> Is it just the case that Clang doesn't mind you adding a new nested class but it does mind you adding a new member function template? If so, maybe we could change Clang to support adding new member function templates instead of extending DWARF?


I was thinking about the same thing. It seems to me that this could be
viewed as a deficiency of our implementation of dwarf parsing. (It's a
pretty understandable deficiency, given that we are based on clang
(compiler), and it thinks of the types in the same way as C++ does --
incomplete; or complete with template members and all). However, these
template member functions should not impact anything "important" in
the class (data member layout, vtables, ...) so one could conceivably
have an implementation which allows member addition on the fly. And in
this case the existing accelerator tables would work perfectly -- we
would get a query "does this class have method X", we would look at
the accel table, and it would point us straight to X. However, I have
no idea how hard would it be to fit this scheme into the existing
clang/lldb design.



That said, having DWARF be able to represent the template member
functions in an abstract way also sounds like nice thing to have from
a debug info format.

pl
_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm

Jonathan Wakely via llvm-dev


> On Jun 15, 2018, at 1:48 PM, Pavel Labath <[hidden email]> wrote:
>
> On Fri, 15 Jun 2018 at 20:14, David Blaikie <[hidden email]> wrote:
>>
>> How do you handle name lookup for nested classes? They have the same problem (they don't appear in all definitions) - don't appear in all descriptions of the outer/parent class. (in theory we could ensure there's always at least a declaration of the nested class - but we don't even do that if the nested class is unused)
>>
>> Is it just the case that Clang doesn't mind you adding a new nested class but it does mind you adding a new member function template? If so, maybe we could change Clang to support adding new member function templates instead of extending DWARF?
>
>
> I was thinking about the same thing. It seems to me that this could be
> viewed as a deficiency of our implementation of dwarf parsing. (It's a
> pretty understandable deficiency, given that we are based on clang
> (compiler), and it thinks of the types in the same way as C++ does --
> incomplete; or complete with template members and all). However, these
> template member functions should not impact anything "important" in
> the class (data member layout, vtables, ...) so one could conceivably
> have an implementation which allows member addition on the fly. And in
> this case the existing accelerator tables would work perfectly -- we
> would get a query "does this class have method X", we would look at
> the accel table, and it would point us straight to X. However, I have
> no idea how hard would it be to fit this scheme into the existing
> clang/lldb design.

For a little background on how the DWARF parsing works. When anything has a type "class A" in LLDB (variable, method in class A, etc), we first create a forward declaration to class A in the clang AST. Each symbol file installs itself as an external AST source that can complete any types when requested. This uses the functionality that mimics each symbol file being a precompiled header. Since we have an external AST source, clang can ask for the type to be completed at any time (just like clang does with PCH files), which will call back into the external AST source and cause the type to be completed.

In LLDB, we have 3 distinct states of a type: forward declaration to type, completed type, the type we need for layout. If a variable has a type "class A*", then when displaying this variable in the output of "frame var", we don't need to know the full definition of class A. If the user expands a type in say an IDE variable view or types an expression that results in a class A instance or reference, we will get the complete version of the type. When we are making other types that include class A through inheritance or as a member variable, we may or may not need get the full definition for class A. For example if we have a "class A* m_a_ptr;" member variable, we don't need to know about A since we only need to know what type we need in order to layout the type which is a pointer here. If we inherit from class A or have a "class A m_a;" then the layout type needed here would be the full type. So we are very careful to only expand the type when and if needed in LLDB.

That being said we currently only have two versions of the type as far as clang know: forward and complete. I think this is how clang expects things to be as well. So the above approach could work as long as we can teach clang to ask the external AST source about addition names when doing method lookups, but that will take some clang modifications that will probably only need to be enabled in debugger mode. Also if we did add this ability, we will want to limit it to classes that have templated functions we don't want to always ask a class we have completed to continually look for things when the user types an expression wrong like "a.this_method_never_will_exist_in_a()". Maybe that is ok though.

If we are able to make the above approach work, then there will need to be an additional fix where we would need to teach AST importer to be able to compare two classes and ignore any template methods when doing the compare when in debugger mode only. We might have two shared libraries that each have a class A, one with one specialized function and one with another, and when one or both of those get imported into the expression or target AST, they would need to merge the type correctly when importing it. Right now if there are two class trying be to imported at the same decl context layer the import will fail if the class exists at the same level and isn't exactly the same.

So quite a bit of clang work if we want to make this work.

Each symbol file installs itself as an external AST source so if we wanted to add the template member functions on the fly, hopefully we would get a request that says in the DeclContext "class A" what is "Foo" if you type something like:

A a;
(lldb) a.Foo<int>()

But I am not sure what clang will do if it already thinks it knows the definition for class A, so we might need to teach clang, that in debugger mode only, check the external AST source if there is one to see.


>
>
> That said, having DWARF be able to represent the template member
> functions in an abstract way also sounds like nice thing to have from
> a debug info format.

Yes, that would be great, but will require DWARF changes and is much more long term.
_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
123