Greg Clayton via llvm-dev
2018-Jun-18 16:17 UTC
[llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm
> On Jun 15, 2018, at 1:48 PM, Pavel Labath <labath at google.com> wrote: > > On Fri, 15 Jun 2018 at 20:14, David Blaikie <dblaikie at gmail.com> 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.
via llvm-dev
2018-Jun-18 16:54 UTC
[llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm
> Greg wrote: > > Pavel wrote: > > 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.I'm curious what utility this has, other than tidying up the Clang AST interface part (because you know what templates exist inside the class). I mean, you can't instantiate new functions; and if you're trying to call an existing instance, you have to go find it anyway, in whichever CU it happens to have been instantiated. Feel free to start a new thread if this is straying too far from the discussion that already strayed from the original topic. :-) Thanks, --paulr
Greg Clayton via llvm-dev
2018-Jun-18 16:57 UTC
[llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm
> On Jun 18, 2018, at 9:54 AM, <paul.robinson at sony.com> <paul.robinson at sony.com> wrote: > >> Greg wrote: >>> Pavel wrote: >>> 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. > > I'm curious what utility this has, other than tidying up the Clang AST > interface part (because you know what templates exist inside the class). > I mean, you can't instantiate new functions; and if you're trying to > call an existing instance, you have to go find it anyway, in whichever > CU it happens to have been instantiated. > > Feel free to start a new thread if this is straying too far from the > discussion that already strayed from the original topic. :-)I do agree. Probably no one else will want/need this in DWARF except us as I don't believe anyone else is re-creating compiler types with DWARF. Not that I don't think it is a good idea for debuggers to do as it allows the compiler to be used in the debugger. That being said, we should probably look for solutions that are better for all DWARF clients or just fix things in our debugger.> Thanks, > --paulr >
David Blaikie via llvm-dev
2018-Jun-18 17:04 UTC
[llvm-dev] [lldb-dev] Adding DWARF5 accelerator table support to llvm
On Mon, Jun 18, 2018 at 9:54 AM <paul.robinson at sony.com> wrote:> > Greg wrote: > > > Pavel wrote: > > > 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. > > I'm curious what utility this has, other than tidying up the Clang AST > interface part (because you know what templates exist inside the class). > I mean, you can't instantiate new functions; and if you're trying to > call an existing instance, you have to go find it anyway, in whichever > CU it happens to have been instantiated. >A couple of questionable reasons: 1) name/overload resolution - having the names of functions you can't call (because they've been inlined away, never instantiated, etc) means that if a debugger is evaluating an expression it won't accidentally resolve a call to a different function from the one that would've been used in the source language. (eg: a class with foo(int) and foo(T) - if you call foo(true) - but the debugger doesn't know any foo(T) exists, so it calls foo(int), which could be varying degrees of unfortunate) This could happen for any function though, and it'd certainly be impractical to include all function declarations (especially for non-members), all types, etc, to ensure that all names are available to validate any ambiguities, etc. 2) Possible that there are libraries linked in that themselves don't have debug info - but include specializations of a template (or definitions of any declared function, really) - so having the debug info could be used to know about those functions (given at least Itanium mangling, though - I'm not sure the debug info would be necessary, maybe looking at the mangled name would be sufficient for a debugger to know "oh, this function is a member of this class and has these parameter types" - hmm, guess it wouldn't know the return type without debug info, perhaps)> > Feel free to start a new thread if this is straying too far from the > discussion that already strayed from the original topic. :-) > Thanks, > --paulr > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180618/2a825799/attachment-0001.html>