Index: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -333,6 +333,9 @@ /// Whether to use the GNU TLS opcode (instead of the standard opcode). bool UseGNUTLSOpcode; + /// Whether to emit DW_AT_[MIPS_]linkage_name. + bool UseLinkageNames; + /// Version of dwarf we're emitting. unsigned DwarfVersion; @@ -588,6 +591,9 @@ SymSize[Sym] = Size; } + /// Returns whether to emit DW_AT_[MIPS_]linkage_name. + bool useLinkageNames() const { return UseLinkageNames; } + /// Returns whether to use DW_OP_GNU_push_tls_address, instead of the /// standard DW_OP_form_tls_address opcode bool useGNUTLSOpcode() const { return UseGNUTLSOpcode; } Index: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -116,6 +116,14 @@ clEnumVal(Disable, "Disabled"), clEnumValEnd), cl::init(Default)); +static cl::opt +DwarfLinkageNames("dwarf-linkage-names", cl::Hidden, + cl::desc("Emit DWARF linkage-name attributes."), + cl::values(clEnumVal(Default, "Default for platform"), + clEnumVal(Enable, "Enabled"), + clEnumVal(Disable, "Disabled"), clEnumValEnd), + cl::init(Default)); + static const char *const DWARFGroupName = "DWARF Emission"; static const char *const DbgTimerName = "DWARF Debug Writer"; @@ -250,6 +258,12 @@ else HasDwarfPubSections = DwarfPubSections == Enable; + // SCE does not use linkage names. + if (DwarfLinkageNames == Default) + UseLinkageNames = !tuneForSCE(); + else + UseLinkageNames = DwarfLinkageNames == Enable; + unsigned DwarfVersionNumber = Asm->TM.Options.MCOptions.DwarfVersion; DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber : MMI->getModule()->getDwarfVersion(); Index: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -667,7 +667,7 @@ } void DwarfUnit::addLinkageName(DIE &Die, StringRef LinkageName) { - if (!LinkageName.empty()) + if (!LinkageName.empty() && DD->useLinkageNames()) addString(Die, DD->getDwarfVersion() >= 4 ? dwarf::DW_AT_linkage_name : dwarf::DW_AT_MIPS_linkage_name, Index: llvm/trunk/test/DebugInfo/2010-04-06-NestedFnDbgInfo.ll =================================================================== --- llvm/trunk/test/DebugInfo/2010-04-06-NestedFnDbgInfo.ll +++ llvm/trunk/test/DebugInfo/2010-04-06-NestedFnDbgInfo.ll @@ -13,7 +13,7 @@ ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_low_pc ; CHECK-NOT: DW_TAG -; CHECK: DW_AT_linkage_name {{.*}} "_ZZN1B2fnEvEN1A3fooEv" +; CHECK: DW_AT_name {{.*}} "foo" ; And just double check that there's no out of line definition that references ; this subprogram. ; CHECK-NOT: DW_AT_specification {{.*}} {[[FOO_INL]]} Index: llvm/trunk/test/DebugInfo/PR20038.ll =================================================================== --- llvm/trunk/test/DebugInfo/PR20038.ll +++ llvm/trunk/test/DebugInfo/PR20038.ll @@ -3,7 +3,7 @@ ; For some reason, the output when targetting sparc is not quite as expected. ; XFAIL: sparc -; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s +; RUN: %llc_dwarf -O0 -filetype=obj -dwarf-linkage-names=Enable < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s ; IR generated from clang -O0 with: ; struct C { Index: llvm/trunk/test/DebugInfo/X86/dwarf-linkage-names.ll =================================================================== --- llvm/trunk/test/DebugInfo/X86/dwarf-linkage-names.ll +++ llvm/trunk/test/DebugInfo/X86/dwarf-linkage-names.ll @@ -0,0 +1,71 @@ +; DWARF linkage name attributes are optional; verify they are missing for +; PS4 triple or when tuning for SCE. + +; RUN: llc -O0 -mtriple=x86_64-unknown-unknown < %s | FileCheck %s -check-prefix LINKAGE1 +; RUN: llc -O0 -mtriple=x86_64-unknown-unknown < %s | FileCheck %s -check-prefix LINKAGE2 +; RUN: llc -O0 -mtriple=x86_64-scei-ps4 < %s | FileCheck %s -check-prefix NOLINKAGE +; RUN: llc -O0 -mtriple=x86_64-unknown-unknown -debugger-tune=sce < %s | FileCheck %s -check-prefix NOLINKAGE + +; $ clang++ -emit-llvm -S -g dwarf-linkage-names.cpp +; namespace test { +; int global_var; +; int bar() { return global_var; } +;}; + +; With linkage names, we get an attribute for the declaration (first) entry +; for the global variable, and one for the function. + +; This assumes the variable will appear before the function. +; LINKAGE1: .section .debug_info +; LINKAGE1: DW_TAG_variable +; LINKAGE1-NOT: DW_TAG +; LINKAGE1: {{DW_AT_(MIPS_)*linkage_name}} +; LINKAGE1: DW_TAG_subprogram +; LINKAGE1-NOT: DW_TAG +; LINKAGE1: {{DW_AT_(MIPS_)*linkage_name}} +; LINKAGE1: .section + +; Also verify we see the mangled names. We do this as a separate pass to +; avoid depending on the order of .debug_info and .debug_str sections. + +; LINKAGE2-DAG: .asciz "_ZN4test10global_varE" +; LINKAGE2-DAG: .asciz "_ZN4test3barEv" + +; Without linkage names, verify there aren't any linkage-name attributes, +; and no mangled names. + +; NOLINKAGE-NOT: {{DW_AT_(MIPS_)*linkage_name}} +; NOLINKAGE-NOT: .asciz "_ZN4test10global_varE" +; NOLINKAGE-NOT: .asciz "_ZN4test3barEv" + +@_ZN4test10global_varE = global i32 0, align 4 + +; Function Attrs: nounwind uwtable +define i32 @_ZN4test3barEv() #0 { +entry: + %0 = load i32, i32* @_ZN4test10global_varE, align 4, !dbg !14 + ret i32 %0, !dbg !15 +} + +attributes #0 = { nounwind uwtable "disable-tail-calls"="false" "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" "target-cpu"="x86-64" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!11, !12} +!llvm.ident = !{!13} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.8.0 (trunk 244662)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3, globals: !9) +!1 = !DIFile(filename: "dwarf-linkage-names.cpp", directory: "/home/probinson/projects/scratch") +!2 = !{} +!3 = !{!4} +!4 = !DISubprogram(name: "bar", linkageName: "_ZN4test3barEv", scope: !5, file: !1, line: 3, type: !6, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, function: i32 ()* @_ZN4test3barEv, variables: !2) +!5 = !DINamespace(name: "test", scope: null, file: !1, line: 1) +!6 = !DISubroutineType(types: !7) +!7 = !{!8} +!8 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!9 = !{!10} +!10 = !DIGlobalVariable(name: "global_var", linkageName: "_ZN4test10global_varE", scope: !5, file: !1, line: 2, type: !8, isLocal: false, isDefinition: true, variable: i32* @_ZN4test10global_varE) +!11 = !{i32 2, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{!"clang version 3.8.0 (trunk 244662)"} +!14 = !DILocation(line: 3, column: 21, scope: !4) +!15 = !DILocation(line: 3, column: 14, scope: !4) Index: llvm/trunk/test/DebugInfo/X86/recursive_inlining.ll =================================================================== --- llvm/trunk/test/DebugInfo/X86/recursive_inlining.ll +++ llvm/trunk/test/DebugInfo/X86/recursive_inlining.ll @@ -38,16 +38,16 @@ ; CHECK-NOT: {{DW_TAG|NULL}} ; CHECK: DW_TAG_member ; CHECK-NOT: {{DW_TAG|NULL}} -; CHECK: DW_TAG_subprogram +; CHECK: [[M_FN2_DECL:.*]]: DW_TAG_subprogram ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_name {{.*}} "m_fn2" ; CHECK-NOT: {{DW_TAG|NULL}} -; CHECK: [[M_FN2_THIS_DECL:.*]]: DW_TAG_formal_parameter +; CHECK: DW_TAG_formal_parameter ; The abstract definition of C::m_fn2 ; CHECK: [[M_FN2_ABS_DEF:.*]]: DW_TAG_subprogram ; CHECK-NOT: DW_TAG -; CHECK: DW_AT_specification {{.*}} "_ZN1C5m_fn2Ev" +; CHECK: DW_AT_specification {{.*}} {[[M_FN2_DECL]]} ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_inline ; CHECK-NOT: {{DW_TAG|NULL}} @@ -63,7 +63,7 @@ ; The concrete definition of C::m_fn2 ; CHECK: DW_TAG_subprogram ; CHECK-NOT: DW_TAG -; CHECK: DW_AT_abstract_origin {{.*}} {[[M_FN2_ABS_DEF]]} "_ZN1C5m_fn2Ev" +; CHECK: DW_AT_abstract_origin {{.*}} {[[M_FN2_ABS_DEF]]} ; CHECK-NOT: {{DW_TAG|NULL}} ; CHECK: DW_TAG_formal_parameter ; CHECK-NOT: DW_TAG @@ -78,7 +78,7 @@ ; Inlined C::m_fn2: ; CHECK: DW_TAG_inlined_subroutine ; CHECK-NOT: DW_TAG -; CHECK: DW_AT_abstract_origin {{.*}} {[[M_FN2_ABS_DEF]]} "_ZN1C5m_fn2Ev" +; CHECK: DW_AT_abstract_origin {{.*}} {[[M_FN2_ABS_DEF]]} ; CHECK-NOT: {{DW_TAG|NULL}} ; CHECK: DW_TAG_formal_parameter ; CHECK-NOT: DW_TAG Index: llvm/trunk/test/DebugInfo/cross-cu-inlining.ll =================================================================== --- llvm/trunk/test/DebugInfo/cross-cu-inlining.ll +++ llvm/trunk/test/DebugInfo/cross-cu-inlining.ll @@ -1,7 +1,7 @@ ; REQUIRES: object-emission -; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck -implicit-check-not=DW_TAG %s -; RUN: %llc_dwarf -dwarf-accel-tables=Enable -O0 -filetype=obj < %s | llvm-dwarfdump - | FileCheck --check-prefix=CHECK-ACCEL --check-prefix=CHECK %s +; RUN: %llc_dwarf -O0 -filetype=obj -dwarf-linkage-names=Enable < %s | llvm-dwarfdump -debug-dump=info - | FileCheck -implicit-check-not=DW_TAG %s +; RUN: %llc_dwarf -dwarf-accel-tables=Enable -dwarf-linkage-names=Enable -O0 -filetype=obj < %s | llvm-dwarfdump - | FileCheck --check-prefix=CHECK-ACCEL --check-prefix=CHECK %s ; Build from source: ; $ clang++ a.cpp b.cpp -g -c -emit-llvm Index: llvm/trunk/test/DebugInfo/enum-types.ll =================================================================== --- llvm/trunk/test/DebugInfo/enum-types.ll +++ llvm/trunk/test/DebugInfo/enum-types.ll @@ -1,6 +1,6 @@ ; REQUIRES: object-emission ; -; RUN: %llc_dwarf -filetype=obj -O0 < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s +; RUN: %llc_dwarf -filetype=obj -O0 -dwarf-linkage-names=Enable < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s ; Make sure we can handle enums with the same identifier but in enum types of ; different compile units. Index: llvm/trunk/test/DebugInfo/incorrect-variable-debugloc.ll =================================================================== --- llvm/trunk/test/DebugInfo/incorrect-variable-debugloc.ll +++ llvm/trunk/test/DebugInfo/incorrect-variable-debugloc.ll @@ -38,11 +38,11 @@ ; CHECK: DW_TAG_structure_type ; CHECK-NEXT: DW_AT_name {{.*}} "C" -; CHECK: DW_TAG_subprogram -; CHECK-NOT: DW_TAG +; CHECK: [[M_FN3_DECL:.*]]: DW_TAG_subprogram +; CHECK-NOT: {{DW_TAG|NULL}} ; CHECK: DW_AT_name {{.*}} "m_fn3" -; CHECK: DW_AT_specification {{.*}} "_ZN1C5m_fn3Ev" +; CHECK: DW_AT_specification {{.*}} {[[M_FN3_DECL]]} ; CHECK-NOT: DW_TAG ; CHECK: DW_TAG_formal_parameter ; CHECK-NOT: DW_TAG Index: llvm/trunk/test/DebugInfo/missing-abstract-variable.ll =================================================================== --- llvm/trunk/test/DebugInfo/missing-abstract-variable.ll +++ llvm/trunk/test/DebugInfo/missing-abstract-variable.ll @@ -37,7 +37,7 @@ ; x(u); ; } -; CHECK: DW_TAG_subprogram +; CHECK: [[X_DECL:.*]]: DW_TAG_subprogram ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_name {{.*}} "x" ; CHECK-NOT: {{DW_TAG|NULL}} @@ -57,7 +57,7 @@ ; CHECK-NOT: {{DW_TAG|NULL}} ; CHECK: DW_TAG_inlined_subroutine ; CHECK-NOT: DW_TAG -; CHECK: DW_AT_abstract_origin {{.*}} "_Z1xb" +; CHECK: DW_AT_abstract_origin {{.*}} {[[X_DECL]]} ; CHECK-NOT: {{DW_TAG|NULL}} ; CHECK: DW_TAG_formal_parameter ; CHECK-NOT: DW_TAG @@ -78,7 +78,7 @@ ; CHECK-NOT: {{DW_TAG|NULL}} ; CHECK: DW_TAG_inlined_subroutine ; CHECK-NOT: DW_TAG -; CHECK: DW_AT_abstract_origin {{.*}} "_Z1xb" +; CHECK: DW_AT_abstract_origin {{.*}} {[[X_DECL]]} ; CHECK-NOT: {{DW_TAG|NULL}} ; FIXME: This formal parameter goes missing at least at -O2 (& on ; mips/powerpc), maybe before that. Perhaps SelectionDAG is to blame (and Index: llvm/trunk/test/DebugInfo/namespace.ll =================================================================== --- llvm/trunk/test/DebugInfo/namespace.ll +++ llvm/trunk/test/DebugInfo/namespace.ll @@ -1,7 +1,6 @@ ; REQUIRES: object-emission -; RUN: %llc_dwarf -O0 -filetype=obj < %s > %t -; RUN: llvm-dwarfdump %t | FileCheck %s +; RUN: %llc_dwarf -O0 -filetype=obj -dwarf-linkage-names=Enable < %s | llvm-dwarfdump - | FileCheck %s ; CHECK: debug_info contents ; CHECK: [[NS1:0x[0-9a-f]*]]:{{ *}}DW_TAG_namespace ; CHECK-NEXT: DW_AT_name{{.*}} = "A" Index: llvm/trunk/test/DebugInfo/namespace_function_definition.ll =================================================================== --- llvm/trunk/test/DebugInfo/namespace_function_definition.ll +++ llvm/trunk/test/DebugInfo/namespace_function_definition.ll @@ -1,6 +1,6 @@ ; REQUIRES: object-emission -; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s +; RUN: %llc_dwarf -O0 -filetype=obj -dwarf-linkage-names=Enable < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s ; Generated from clang with the following source: ; namespace ns { Index: llvm/trunk/test/DebugInfo/namespace_inline_function_definition.ll =================================================================== --- llvm/trunk/test/DebugInfo/namespace_inline_function_definition.ll +++ llvm/trunk/test/DebugInfo/namespace_inline_function_definition.ll @@ -1,6 +1,6 @@ ; REQUIRES: object-emission -; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s +; RUN: %llc_dwarf -O0 -filetype=obj -dwarf-linkage-names=Enable < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s ; Generate from clang with the following source. Note that the definition of ; the inline function follows its use to workaround another bug that should be Index: llvm/trunk/test/Linker/type-unique-odr-a.ll =================================================================== --- llvm/trunk/test/Linker/type-unique-odr-a.ll +++ llvm/trunk/test/Linker/type-unique-odr-a.ll @@ -1,6 +1,6 @@ ; REQUIRES: object-emission, native ; -; RUN: llvm-link %s %p/type-unique-odr-b.ll -S -o - | %llc_dwarf -filetype=obj -O0 | llvm-dwarfdump -debug-dump=info - | FileCheck %s +; RUN: llvm-link %s %p/type-unique-odr-b.ll -S -o - | %llc_dwarf -dwarf-linkage-names=Enable -filetype=obj -O0 | llvm-dwarfdump -debug-dump=info - | FileCheck %s ; ; Test ODR-based type uniquing for C++ class members. ; rdar://problem/15851313. Index: llvm/trunk/test/Linker/type-unique-simple2-a.ll =================================================================== --- llvm/trunk/test/Linker/type-unique-simple2-a.ll +++ llvm/trunk/test/Linker/type-unique-simple2-a.ll @@ -18,7 +18,8 @@ ; return A().getFoo(); ; } ; -; CHECK: _ZN1A6setFooEv +; CHECK: DW_AT_name {{.*}} "setFoo" +; CHECK-NOT: DW_TAG ; CHECK: DW_AT_accessibility [DW_FORM_data1] (DW_ACCESS_public) ; CHECK-NOT: DW_AT_accessibility ; CHECK: DW_TAG Index: llvm/trunk/test/Linker/type-unique-type-array-a.ll =================================================================== --- llvm/trunk/test/Linker/type-unique-type-array-a.ll +++ llvm/trunk/test/Linker/type-unique-type-array-a.ll @@ -23,7 +23,7 @@ ; CHECK: DW_TAG_class_type ; CHECK-NEXT: DW_AT_name {{.*}} "A" ; CHECK: DW_TAG_subprogram -; CHECK: DW_AT_MIPS_linkage_name {{.*}} "_ZN1A5testAE2SA" +; CHECK: DW_AT_name {{.*}} "testA" ; CHECK: DW_TAG_formal_parameter ; CHECK: DW_TAG_formal_parameter ; CHECK-NEXT: DW_AT_type [DW_FORM_ref4] (cu + 0x{{.*}} => {0x[[STRUCT:.*]]}) @@ -34,7 +34,7 @@ ; CHECK: DW_TAG_class_type ; CHECK-NEXT: DW_AT_name {{.*}} "B" ; CHECK: DW_TAG_subprogram -; CHECK: DW_AT_MIPS_linkage_name {{.*}} "_ZN1B5testBE2SA" +; CHECK: DW_AT_name {{.*}} "testB" ; CHECK: DW_TAG_formal_parameter ; CHECK: DW_TAG_formal_parameter ; CHECK-NEXT: DW_AT_type [DW_FORM_ref_addr] {{.*}}[[STRUCT]]