llvm-6502/test/DebugInfo/member-order.ll

67 lines
3.8 KiB
LLVM
Raw Permalink Normal View History

DebugInfo: Fix ordering of members after r191928 In the case (shown in the attached test) where a member function definition was emitted into debug info the following could occur: 1) build the debug info for the member function definition 2) in (1), build the debug info for the member function declaration 3) construct and add the member function declaration DIE 4) add it to its context 5) build its context (the type it is a member of) 6) construct the members and add them to the type 7) except don't add member functions because "getOrCreateSubprogram" adds the function to its parent anyway 8) except we're only partway through building this subprogram declaration so it hasn't been added yet - but we returned the partially constructed DIE (since it's already in the MDNode->DIE mapping to avoid infinitely recursing trying to create the member function DIE) 9) once the type is constructed, add the member function to it 10) now the members are out of order (the member function being defined is listed as the last member, even though it was declared as the first) To avoid this, construct the context of the subprogram DIE before we query to see if it exists. That way we never end up creating it before creating its context and ending up in this situation. Alternatively, the type construction that visits/builds all the members could call something like getOrCreateSubprogram, but that doesn't ever do the "add to context" step. Then the type building code would always be responsible for adding members (and the subprogram "addToContextDIE" would no-op because the context building would have added the subprogram declaration to the type/context DIE already). (the test cases updated were overly-sensitive to offsets or abbreviation numbers. We don't have a nice way to make these tests more robust as yet - multiline FileCheck matches would be required) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191939 91177308-0d34-0410-b5e6-96231b3b80d8
2013-10-04 01:39:59 +00:00
; REQUIRES: object-emission
; RUN: %llc_dwarf -filetype=obj -O0 < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s
DebugInfo: Fix ordering of members after r191928 In the case (shown in the attached test) where a member function definition was emitted into debug info the following could occur: 1) build the debug info for the member function definition 2) in (1), build the debug info for the member function declaration 3) construct and add the member function declaration DIE 4) add it to its context 5) build its context (the type it is a member of) 6) construct the members and add them to the type 7) except don't add member functions because "getOrCreateSubprogram" adds the function to its parent anyway 8) except we're only partway through building this subprogram declaration so it hasn't been added yet - but we returned the partially constructed DIE (since it's already in the MDNode->DIE mapping to avoid infinitely recursing trying to create the member function DIE) 9) once the type is constructed, add the member function to it 10) now the members are out of order (the member function being defined is listed as the last member, even though it was declared as the first) To avoid this, construct the context of the subprogram DIE before we query to see if it exists. That way we never end up creating it before creating its context and ending up in this situation. Alternatively, the type construction that visits/builds all the members could call something like getOrCreateSubprogram, but that doesn't ever do the "add to context" step. Then the type building code would always be responsible for adding members (and the subprogram "addToContextDIE" would no-op because the context building would have added the subprogram declaration to the type/context DIE already). (the test cases updated were overly-sensitive to offsets or abbreviation numbers. We don't have a nice way to make these tests more robust as yet - multiline FileCheck matches would be required) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191939 91177308-0d34-0410-b5e6-96231b3b80d8
2013-10-04 01:39:59 +00:00
; generated by clang from:
; struct foo {
; void f1();
; void f2();
; };
;
; void foo::f1() {
; }
; CHECK: DW_TAG_structure_type
; CHECK-NEXT: DW_AT_name {{.*}} "foo"
; CHECK-NOT: NULL
; CHECK: DW_TAG_subprogram
; CHECK-NOT: NULL
; CHECK: DW_AT_name {{.*}} "f1"
; CHECK: DW_TAG_subprogram
; CHECK-NOT: NULL
; CHECK: DW_AT_name {{.*}} "f2"
%struct.foo = type { i8 }
; Function Attrs: nounwind uwtable
define void @_ZN3foo2f1Ev(%struct.foo* %this) #0 align 2 {
entry:
%this.addr = alloca %struct.foo*, align 8
store %struct.foo* %this, %struct.foo** %this.addr, align 8
call void @llvm.dbg.declare(metadata !{%struct.foo** %this.addr}, metadata !16), !dbg !18
%this1 = load %struct.foo** %this.addr
ret void, !dbg !19
}
; Function Attrs: nounwind readnone
declare void @llvm.dbg.declare(metadata, metadata) #1
attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind readnone }
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!15, !20}
DebugInfo: Fix ordering of members after r191928 In the case (shown in the attached test) where a member function definition was emitted into debug info the following could occur: 1) build the debug info for the member function definition 2) in (1), build the debug info for the member function declaration 3) construct and add the member function declaration DIE 4) add it to its context 5) build its context (the type it is a member of) 6) construct the members and add them to the type 7) except don't add member functions because "getOrCreateSubprogram" adds the function to its parent anyway 8) except we're only partway through building this subprogram declaration so it hasn't been added yet - but we returned the partially constructed DIE (since it's already in the MDNode->DIE mapping to avoid infinitely recursing trying to create the member function DIE) 9) once the type is constructed, add the member function to it 10) now the members are out of order (the member function being defined is listed as the last member, even though it was declared as the first) To avoid this, construct the context of the subprogram DIE before we query to see if it exists. That way we never end up creating it before creating its context and ending up in this situation. Alternatively, the type construction that visits/builds all the members could call something like getOrCreateSubprogram, but that doesn't ever do the "add to context" step. Then the type building code would always be responsible for adding members (and the subprogram "addToContextDIE" would no-op because the context building would have added the subprogram declaration to the type/context DIE already). (the test cases updated were overly-sensitive to offsets or abbreviation numbers. We don't have a nice way to make these tests more robust as yet - multiline FileCheck matches would be required) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191939 91177308-0d34-0410-b5e6-96231b3b80d8
2013-10-04 01:39:59 +00:00
!0 = metadata !{i32 786449, metadata !1, i32 4, metadata !"clang version 3.4 ", i1 false, metadata !"", i32 0, metadata !2, metadata !3, metadata !13, metadata !2, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [/tmp/dbginfo/member-order.cpp] [DW_LANG_C_plus_plus]
!1 = metadata !{metadata !"member-order.cpp", metadata !"/tmp/dbginfo"}
!2 = metadata !{}
DebugInfo: Fix ordering of members after r191928 In the case (shown in the attached test) where a member function definition was emitted into debug info the following could occur: 1) build the debug info for the member function definition 2) in (1), build the debug info for the member function declaration 3) construct and add the member function declaration DIE 4) add it to its context 5) build its context (the type it is a member of) 6) construct the members and add them to the type 7) except don't add member functions because "getOrCreateSubprogram" adds the function to its parent anyway 8) except we're only partway through building this subprogram declaration so it hasn't been added yet - but we returned the partially constructed DIE (since it's already in the MDNode->DIE mapping to avoid infinitely recursing trying to create the member function DIE) 9) once the type is constructed, add the member function to it 10) now the members are out of order (the member function being defined is listed as the last member, even though it was declared as the first) To avoid this, construct the context of the subprogram DIE before we query to see if it exists. That way we never end up creating it before creating its context and ending up in this situation. Alternatively, the type construction that visits/builds all the members could call something like getOrCreateSubprogram, but that doesn't ever do the "add to context" step. Then the type building code would always be responsible for adding members (and the subprogram "addToContextDIE" would no-op because the context building would have added the subprogram declaration to the type/context DIE already). (the test cases updated were overly-sensitive to offsets or abbreviation numbers. We don't have a nice way to make these tests more robust as yet - multiline FileCheck matches would be required) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191939 91177308-0d34-0410-b5e6-96231b3b80d8
2013-10-04 01:39:59 +00:00
!3 = metadata !{metadata !4}
!4 = metadata !{i32 786451, metadata !1, null, metadata !"foo", i32 1, i64 8, i64 8, i32 0, i32 0, null, metadata !5, i32 0, null, null, metadata !"_ZTS3foo"} ; [ DW_TAG_structure_type ] [foo] [line 1, size 8, align 8, offset 0] [def] [from ]
!5 = metadata !{metadata !6, metadata !11}
!6 = metadata !{i32 786478, metadata !1, metadata !4, metadata !"f1", metadata !"f1", metadata !"_ZN3foo2f1Ev", i32 2, metadata !7, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null, i32 0, metadata !10, i32 2} ; [ DW_TAG_subprogram ] [line 2] [f1]
!7 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !8, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
!8 = metadata !{null, metadata !9}
!9 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 1088, metadata !"_ZTS3foo"} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [artificial] [from _ZTS3foo]
!10 = metadata !{i32 786468}
!11 = metadata !{i32 786478, metadata !1, metadata !4, metadata !"f2", metadata !"f2", metadata !"_ZN3foo2f2Ev", i32 3, metadata !7, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null, i32 0, metadata !12, i32 3} ; [ DW_TAG_subprogram ] [line 3] [f2]
!12 = metadata !{i32 786468}
!13 = metadata !{metadata !14}
!14 = metadata !{i32 786478, metadata !1, null, metadata !"f1", metadata !"f1", metadata !"_ZN3foo2f1Ev", i32 6, metadata !7, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (%struct.foo*)* @_ZN3foo2f1Ev, null, metadata !6, metadata !2, i32 6} ; [ DW_TAG_subprogram ] [line 6] [def] [f1]
!15 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
!16 = metadata !{i32 786689, metadata !14, metadata !"this", null, i32 16777216, metadata !17, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [this] [line 0]
!17 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 0, metadata !"_ZTS3foo"} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from _ZTS3foo]
!18 = metadata !{i32 0, i32 0, metadata !14, null}
!19 = metadata !{i32 7, i32 0, metadata !14, null}
!20 = metadata !{i32 1, metadata !"Debug Info Version", i32 1}