|
| 1 | +; REQUIRES: object-emission |
| 2 | + |
| 3 | +; RUN: %llc_dwarf -O0 -filetype=obj < %s > %t |
| 4 | +; RUN: llvm-dwarfdump -debug-dump=info %t | FileCheck %s |
| 5 | + |
| 6 | +; Check that any type can have a vtable holder. |
| 7 | +; CHECK: [[SP:.*]]: DW_TAG_structure_type |
| 8 | +; CHECK-NOT: TAG |
| 9 | +; CHECK: DW_AT_containing_type [DW_FORM_ref4] |
| 10 | +; CHECK: DW_AT_name [DW_FORM_strp] {{.*}}= "vtable") |
| 11 | + |
| 12 | +; This was compiled using |
| 13 | +; rustc -g --emit=llvm-ir t2.rs |
| 14 | +; ... and then edited by hand, because rustc is using a somewhat older llvm. |
| 15 | +; |
| 16 | +; t2.rs is: |
| 17 | +; |
| 18 | +; // trait object test case |
| 19 | +; |
| 20 | +; pub trait T { |
| 21 | +; } |
| 22 | +; |
| 23 | +; impl T for f64 { |
| 24 | +; } |
| 25 | +; |
| 26 | +; pub fn main() { |
| 27 | +; let tu = &23.0f64 as &T; |
| 28 | +; } |
| 29 | +; t2.rs ends here ^^^ |
| 30 | + |
| 31 | +; ModuleID = 't2.cgu-0.rs' |
| 32 | +source_filename = "t2.cgu-0.rs" |
| 33 | +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
| 34 | +target triple = "x86_64-unknown-linux-gnu" |
| 35 | + |
| 36 | +@ref.0 = internal unnamed_addr constant double 2.300000e+01, align 8 |
| 37 | +@vtable.1 = internal unnamed_addr constant { void (double*)*, i64, i64 } { void (double*)* @_ZN4core3ptr13drop_in_place17h2818a933abde117eE, i64 8, i64 8 }, align 8, !dbg !0 |
| 38 | +@__rustc_debug_gdb_scripts_section__ = linkonce_odr unnamed_addr constant [34 x i8] c"\01gdb_load_rust_pretty_printers.py\00", section ".debug_gdb_scripts", align 1 |
| 39 | + |
| 40 | +; core::ptr::drop_in_place |
| 41 | +; Function Attrs: uwtable |
| 42 | +define internal void @_ZN4core3ptr13drop_in_place17h2818a933abde117eE(double*) unnamed_addr #0 !dbg !11 { |
| 43 | +start: |
| 44 | + %arg0 = alloca double* |
| 45 | + store double* %0, double** %arg0 |
| 46 | + call void @llvm.dbg.declare(metadata double** %arg0, metadata !20, metadata !22), !dbg !23 |
| 47 | + ret void, !dbg !24 |
| 48 | +} |
| 49 | + |
| 50 | +; t2::main |
| 51 | +; Function Attrs: uwtable |
| 52 | +define internal void @_ZN2t24main17h6319e6ac7de3a097E() unnamed_addr #0 !dbg !25 { |
| 53 | +start: |
| 54 | + %tu = alloca { i8*, void (i8*)** } |
| 55 | + call void @llvm.dbg.declare(metadata { i8*, void (i8*)** }* %tu, metadata !29, metadata !22), !dbg !37 |
| 56 | + %0 = getelementptr inbounds { i8*, void (i8*)** }, { i8*, void (i8*)** }* %tu, i32 0, i32 0, !dbg !37 |
| 57 | + store i8* bitcast (double* @ref.0 to i8*), i8** %0, !dbg !37 |
| 58 | + %1 = getelementptr inbounds { i8*, void (i8*)** }, { i8*, void (i8*)** }* %tu, i32 0, i32 1, !dbg !37 |
| 59 | + store void (i8*)** bitcast ({ void (double*)*, i64, i64 }* @vtable.1 to void (i8*)**), void (i8*)*** %1, !dbg !37 |
| 60 | + ret void, !dbg !38 |
| 61 | +} |
| 62 | + |
| 63 | +; Function Attrs: nounwind readnone |
| 64 | +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 |
| 65 | + |
| 66 | +define i32 @main(i32, i8**) unnamed_addr #2 { |
| 67 | +top: |
| 68 | + %2 = load volatile i8, i8* getelementptr inbounds ([34 x i8], [34 x i8]* @__rustc_debug_gdb_scripts_section__, i32 0, i32 0), align 1 |
| 69 | + %3 = sext i32 %0 to i64 |
| 70 | +; call std::rt::lang_start |
| 71 | + %4 = call i64 @_ZN3std2rt10lang_start17h2626caf1112a00beE(void ()* @_ZN2t24main17h6319e6ac7de3a097E, i64 %3, i8** %1) |
| 72 | + %5 = trunc i64 %4 to i32 |
| 73 | + ret i32 %5 |
| 74 | +} |
| 75 | + |
| 76 | +; std::rt::lang_start |
| 77 | +declare i64 @_ZN3std2rt10lang_start17h2626caf1112a00beE(void ()*, i64, i8**) unnamed_addr #3 |
| 78 | + |
| 79 | +attributes #0 = { uwtable "no-frame-pointer-elim"="true" "probe-stack"="__rust_probestack" } |
| 80 | +attributes #1 = { nounwind readnone } |
| 81 | +attributes #2 = { "no-frame-pointer-elim"="true" } |
| 82 | +attributes #3 = { "no-frame-pointer-elim"="true" "probe-stack"="__rust_probestack" } |
| 83 | + |
| 84 | +!llvm.module.flags = !{!6, !7} |
| 85 | +!llvm.dbg.cu = !{!8} |
| 86 | + |
| 87 | +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) |
| 88 | +!1 = distinct !DIGlobalVariable(name: "vtable", scope: null, file: !2, type: !3, isLocal: true, isDefinition: true) |
| 89 | +!2 = !DIFile(filename: "<unknown>", directory: "") |
| 90 | +!3 = !DICompositeType(tag: DW_TAG_structure_type, name: "vtable", file: !2, size: 64, align: 64, flags: DIFlagArtificial, elements: !4, vtableHolder: !5, identifier: "vtable") |
| 91 | +!4 = !{} |
| 92 | +!5 = !DIBasicType(name: "f64", size: 64, encoding: DW_ATE_float) |
| 93 | +!6 = !{i32 1, !"PIE Level", i32 2} |
| 94 | +!7 = !{i32 2, !"Debug Info Version", i32 3} |
| 95 | +!8 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !9, producer: "clang LLVM (rustc version 1.22.0-dev)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !10) |
| 96 | +!9 = !DIFile(filename: "t2.rs", directory: "/home/tromey/Rust") |
| 97 | +!10 = !{!0} |
| 98 | +!11 = distinct !DISubprogram(name: "drop_in_place<f64>", linkageName: "_ZN4core3ptr18drop_in_place<f64>E", scope: !13, file: !12, line: 59, type: !15, isLocal: false, isDefinition: true, scopeLine: 59, flags: DIFlagPrototyped, isOptimized: false, unit: !8, templateParams: !18, variables: !4) |
| 99 | +!12 = !DIFile(filename: "/home/tromey/Rust/rust/src/libcore/ptr.rs", directory: "") |
| 100 | +!13 = !DINamespace(name: "ptr", scope: !14) |
| 101 | +!14 = !DINamespace(name: "core", scope: null) |
| 102 | +!15 = !DISubroutineType(types: !16) |
| 103 | +!16 = !{null, !17} |
| 104 | +!17 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "*mut f64", baseType: !5, size: 64, align: 64) |
| 105 | +!18 = !{!19} |
| 106 | +!19 = !DITemplateTypeParameter(name: "T", type: !5) |
| 107 | +!20 = !DILocalVariable(arg: 1, scope: !11, file: !21, line: 1, type: !17) |
| 108 | +!21 = !DIFile(filename: "t2.rs", directory: "") |
| 109 | +!22 = !DIExpression() |
| 110 | +!23 = !DILocation(line: 1, scope: !11) |
| 111 | +!24 = !DILocation(line: 59, scope: !11) |
| 112 | +!25 = distinct !DISubprogram(name: "main", linkageName: "_ZN2t24mainE", scope: !26, file: !9, line: 9, type: !27, isLocal: true, isDefinition: true, scopeLine: 9, flags: DIFlagPrototyped | DIFlagMainSubprogram, isOptimized: false, unit: !8, templateParams: !4, variables: !4) |
| 113 | +!26 = !DINamespace(name: "t2", scope: null) |
| 114 | +!27 = !DISubroutineType(types: !28) |
| 115 | +!28 = !{null} |
| 116 | +!29 = !DILocalVariable(name: "tu", scope: !30, file: !9, line: 10, type: !31, align: 8) |
| 117 | +!30 = distinct !DILexicalBlock(scope: !25, file: !9, line: 10, column: 4) |
| 118 | +!31 = !DICompositeType(tag: DW_TAG_structure_type, name: "&T", scope: !26, file: !2, size: 128, align: 64, elements: !32, identifier: "b9f642b757d8ad3984c1e721e3ce6016d14d9322") |
| 119 | +!32 = !{!33, !36} |
| 120 | +!33 = !DIDerivedType(tag: DW_TAG_member, name: "pointer", scope: !31, file: !2, baseType: !34, size: 64, align: 64, flags: DIFlagArtificial) |
| 121 | +!34 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "*const u8", baseType: !35, size: 64, align: 64) |
| 122 | +!35 = !DIBasicType(name: "u8", size: 8, encoding: DW_ATE_unsigned) |
| 123 | +!36 = !DIDerivedType(tag: DW_TAG_member, name: "vtable", scope: !31, file: !2, baseType: !34, size: 64, align: 64, offset: 64, flags: DIFlagArtificial) |
| 124 | +!37 = !DILocation(line: 10, scope: !30) |
| 125 | +!38 = !DILocation(line: 11, scope: !25) |
0 commit comments