-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Generate debug metadata for methods #1384
Conversation
...specifically in the context of function variables. Given ``` FUNCTION_BLOCK foo // ... METHOD bar // ... END_METHOD END_FUNCTION_BLOCK ``` the compiler will generate two types for `foo` and `bar` and furthermore handle method calls by passing both these generated types to some function. That is we get the following ``` %foo = type {} %foo.bar = type {} // ... define void @foo.bar(%foo* %0, %foo.bar* %1) !dbg !<...> { call void @llvm.dbg.declare(metadata %foo* %0, metadata !<...>, metadata !DIExpression()), !dbg !<...> call void @llvm.dbg.declare(metadata %foo.bar* %1, metadata !<...>, metadata !DIExpression()), !dbg !<...> // ^^^^^^ // was previously ignored } ``` Appparently when dealing with `%foo` and `%foo.bar` in the `@foo.bar` function context, we intentionally didn't create any debug information for `foo.bar`, resulting in the `metadata !<...>` field pointing to an empty member (e.g. `!<num> = {}`). As a result LLVM would segfault when dealing with this and therefore any `rusty <file> --debug` call. This commit fixes this issue, such that the metadata field points to a correct `DILocalVariable` definition for `%foo.bar`.
src/codegen/tests/debug_tests.rs
Outdated
END_METHOD | ||
END_FUNCTION_BLOCK | ||
", | ||
4, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there any particular reason to override the debug version here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None, I just copy-pasted the previous test and modified it. Good catch though, it probably should be a codegen
call
src/codegen/tests/debug_tests.rs
Outdated
assert!(codegen | ||
.contains(r#"!17 = !DILocalVariable(name: "fb.foo", scope: !15, file: !2, line: 3, type: !18)"#)); | ||
|
||
// ...for reference, it would previously point to `!4` which is empty (`!4 = {}`). `!4` shouldn't exist in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think !4
is not wrong here - it just points out that the struct fb
does not have any members and therefore no local nodes need to be retained.
For comparison, this is an example by LLVM. Here, the function foo
does not have any members, !DISubprogram
's retainedNodes
metadata points to !2
which is !2 = !{}
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you're right. I was under the impression that the !4
wasn't being used in the IR at all but that's not true.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice!
...specifically in the context of function variables. Given
the compiler will generate two types for
foo
andbar
and furthermore handle method calls by passing both these generated types to some function. That is we get the followingAppparently when dealing with
%foo
and%foo.bar
in the@foo.bar
function context, we intentionally didn't create any debug information forfoo.bar
, resulting in themetadata !<...>
field pointing to an empty member (e.g.!<num> = {}
). As a result LLVM would segfault when dealing with this and therefore anyrusty <file> --debug
call.This commit fixes this issue, such that the metadata field points to a correct
DILocalVariable
definition for%foo.bar
.