Eric Christopher
2013-Apr-16 22:04 UTC
[LLVMdev] Passing DW_TAG_typedef as the type to DIBuilder's createFunction
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 :) I've been unable to come up with any way to use foo as a type for a function. If you can come up with one... -eric
David Blaikie
2013-Apr-16 23:54 UTC
[LLVMdev] Passing DW_TAG_typedef as the type to DIBuilder's createFunction
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... 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); }; ) 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.> I've been unable to come up with any way to use foo as a type for a > function. If you can come up with one... > > -eric
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
Maybe Matching 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