Eric Christopher
2013-Apr-17 00:01 UTC
[LLVMdev] Passing DW_TAG_typedef as the type to DIBuilder's createFunction
On Tue, Apr 16, 2013 at 4:54 PM, David Blaikie <dblaikie at gmail.com> wrote:> On Tue, Apr 16, 2013 at 3:04 PM, Eric Christopher <echristo at gmail.com> wrote: >> On Mon, Apr 15, 2013 at 6:20 PM, David Blaikie <dblaikie at gmail.com> wrote: >>> On Wed, Apr 10, 2013 at 4:48 AM, Duncan Sands <baldrick at free.fr> wrote: >>>> Hi Eric, >>>> >>>> On 10/04/13 00:20, Eric Christopher wrote: >>>>> >>>>> On Tue, Apr 9, 2013 at 1:53 AM, Duncan Sands <baldrick at free.fr> wrote: >>>>>> >>>>>> Hi David, I'm seeing an assertion failure when passing this node >>>>>> >>>>>> !{i32 786454, metadata <badref>, metadata <badref>, metadata !"fn_t", >>>>>> i32 >>>>>> 5, i64 0, i64 0, i64 0, i32 0, metadata <badref>} ; [ DW_TAG_typedef ] >>>>>> [fn_t] [line 5, size 0, align 0, offset 0] [from ] >>>>>> >>>>>> as the function type parameter to DIBuilder::createFunction, due to this >>>>>> check >>>>>> in DebugInfo.cpp: >>>>>> >>>>>> 486 DICompositeType Ty = getType(); >>>>>> 487 if (!Ty.Verify()) >>>>>> 488 return false; >>>>>> >>>>>> Is it in fact wrong to pass a typedef here? >>>>>> >>>>> >>>>> I can't come up with a way that'd be correct, no. You should be using >>>>> createSubroutineType and passing that into the builder. Have example >>>>> code where this is coming up? >>>> >>>> >>>> OK, it looks like a DW_TAG_typedef node defines a new type. If the original >>>> type is a subroutine type, I don't see why a typedef of it shouldn't be used >>>> anywhere the original could. After all, it is just an alternative name for >>>> the same thing. You clearly have a different mental model of what a typedef >>>> is, but what is it? >>> >>> I think you might be ascribing more rigor to the debug info IR than is >>> due. It's a fairly pragmatic implementation without much thought (so >>> far as I can tell) to high level principles of types, etc. It's >>> essentially "how do we describe the stuff we need to produce debug >>> info". >>> >>> If the function's type just needs to be a type, then that's all it is >>> (a function type) & all that's supported by the backend most likely - >>> there's no particular merit in providing the possibility for that type >>> to be indirected through a typedef or anything of the sort. >>> >>> If there's any case where we actually produce different/inferior debug >>> info because of this representation, then that's a bug worth >>> considering that might necessitate a change in the IR representation >>> to allow a function's type to be a typedef. >>> >>> eg: I wonder what this looks like in GCC debug info, Clang debug info, >>> and what is correct/good: >>> >>> typedef int foo(int); >>> foo bar; >>> >>> is 'bar' a function of type "int(int)" or a function of type "foo" >>> which is a typedef of type "int(int)". I suppose it could be the >>> latter, in which case we should be usincg/allowing a function's type >>> to be a typedef. >> >> It's not going to come up with anything since bar is unused :) > > Sure, so make it used... >Sure.. but...> But then we still don't emit anything about the function (& neither does GCC). > So make it a member function (so we are forced to emit the declaration > even without complicating the example by having to add a definition > (which by necessity cannot use the typedef))... and then we see that > the subprogram description doesn't refer to a function type at all. It > refers to a return type and it has its own parameters directly. ( > typedef int foo(int); struct bar { foo f; }; int main() { bar b; > b.f(3); }; ) >I couldn't come up with any code to make it the type of a function rather than a function pointer or a member variable that happens to be a function pointer. :)> So that's probably why then: it's irrelevant to DWARF how the function > type is written, the DWARF representation decomposes this & describes > the return type and its parameters separately - whether or not there > is a typedef there. It's possible that some other debug info format we > might support in the future could have greater fidelity here & we'd > have to change/improve the way we represent this in IR, but until then > I think it's simple/safe enough to just describe a function type > directly, ignoring any typedefs. >*nod* -eric
Duncan Sands
2013-Apr-17 05:39 UTC
[LLVMdev] Passing DW_TAG_typedef as the type to DIBuilder's createFunction
Hi Eric,>> But then we still don't emit anything about the function (& neither does GCC). >> So make it a member function (so we are forced to emit the declaration >> even without complicating the example by having to add a definition >> (which by necessity cannot use the typedef))... and then we see that >> the subprogram description doesn't refer to a function type at all. It >> refers to a return type and it has its own parameters directly. ( >> typedef int foo(int); struct bar { foo f; }; int main() { bar b; >> b.f(3); }; ) >> > > I couldn't come up with any code to make it the type of a function > rather than a function pointer or a member variable that happens to be > a function pointer. :)I guess you only tried obscure languages like C and C++ :) I don't see why it shouldn't be theoretically possible, for some language. But as David explained to me, the current design is pragmatic: do something that works for the front-ends we have; extend when necessary. I've got to admit that as far as dragonegg is concerned, it looks like there will always be an appropriate function type floating around that can be used, so I plan to just fix this up in dragonegg and worry about funky languages when and if they show up one day. Ciao, Duncan.
Eric Christopher
2013-Apr-17 05:40 UTC
[LLVMdev] Passing DW_TAG_typedef as the type to DIBuilder's createFunction
On Tue, Apr 16, 2013 at 10:39 PM, Duncan Sands <baldrick at free.fr> wrote:> Hi Eric, > >>> But then we still don't emit anything about the function (& neither does >>> GCC). >>> So make it a member function (so we are forced to emit the declaration >>> even without complicating the example by having to add a definition >>> (which by necessity cannot use the typedef))... and then we see that >>> the subprogram description doesn't refer to a function type at all. It >>> refers to a return type and it has its own parameters directly. ( >>> typedef int foo(int); struct bar { foo f; }; int main() { bar b; >>> b.f(3); }; ) >>> >> >> I couldn't come up with any code to make it the type of a function >> rather than a function pointer or a member variable that happens to be >> a function pointer. :) > > > I guess you only tried obscure languages like C and C++ :) I don't see why > it > shouldn't be theoretically possible, for some language. But as DavidExactly! :)> explained > to me, the current design is pragmatic: do something that works for the > front-ends we have; extend when necessary. I've got to admit that as far as > dragonegg is concerned, it looks like there will always be an appropriate > function type floating around that can be used, so I plan to just fix this > up > in dragonegg and worry about funky languages when and if they show up one > day. >No worries. I just wanted to see how it went and how to create something that made sense to me. Thanks! -eric
Possibly Parallel Threads
- [LLVMdev] Passing DW_TAG_typedef as the type to DIBuilder's createFunction
- [LLVMdev] Passing DW_TAG_typedef as the type to DIBuilder's createFunction
- [LLVMdev] Passing DW_TAG_typedef as the type to DIBuilder's createFunction
- [LLVMdev] Passing DW_TAG_typedef as the type to DIBuilder's createFunction
- [LLVMdev] Passing DW_TAG_typedef as the type to DIBuilder's createFunction