<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jul 21, 2015 at 3:41 PM, Frederic Riss <span dir="ltr"><<a href="mailto:friss@apple.com" target="_blank">friss@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: friss<br>
Date: Tue Jul 21 17:41:43 2015<br>
New Revision: 242847<br>
<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D242847-26view-3Drev&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=f0ccjAQ4wb3ZK7FcrcHBOSKBUW63z2e5YTIFz2fVr7M&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=242847&view=rev</a><br>
Log:<br>
[dsymutil] Implement ODR uniquing for C++ code.<br>
<br>
This optimization allows the DWARF linker to reuse definition of<br>
types it has emitted in previous CUs rather than reemitting them<br>
in each CU that references them. The size and link time gains are<br>
huge. For example when linking the DWARF for a debug build of<br>
clang, this generates a ~150M dwarf file instead of a ~700M one<br>
(the numbers date back a bit and must not be totally accurate<br>
these days).<br>
<br>
As with all the other parts of the llvm-dsymutil codebase, the<br>
goal is to keep bit-for-bit compatibility with dsymutil-classic.<br>
The code is littered with a lot of FIXMEs that should be<br>
addressed once we can get rid of the compatibilty goal.<br></blockquote><div><br></div><div>Did dsymutil-classic do this ODR uniquing too? (not quite clear to me from your description here - where you mention compatibility, etc) How does its implementation compare?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Added:<br>
    llvm/trunk/test/tools/dsymutil/Inputs/odr-types.h<br>
    llvm/trunk/test/tools/dsymutil/Inputs/odr1.cpp<br>
    llvm/trunk/test/tools/dsymutil/Inputs/odr1.ll<br></blockquote><div><br></div><div>Might be useful to have more distinguishing names for the test files here? (I assume each ODR test only needs two files - or do some need more than that?)<br><br>I see it's all in odr-1.test - it's a bit monolithic, isn't it? I'm not sure I understand the motivation for 7 different inputs and then checking all together. Could you explain it?<br><br>- Dave<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
    llvm/trunk/test/tools/dsymutil/Inputs/odr2.cpp<br>
    llvm/trunk/test/tools/dsymutil/Inputs/odr2.ll<br>
    llvm/trunk/test/tools/dsymutil/Inputs/odr3.cpp<br>
    llvm/trunk/test/tools/dsymutil/Inputs/odr3.ll<br>
    llvm/trunk/test/tools/dsymutil/Inputs/odr4.cpp<br>
    llvm/trunk/test/tools/dsymutil/Inputs/odr4.ll<br>
    llvm/trunk/test/tools/dsymutil/Inputs/odr5.cpp<br>
    llvm/trunk/test/tools/dsymutil/Inputs/odr5.ll<br>
    llvm/trunk/test/tools/dsymutil/Inputs/odr6.cpp<br>
    llvm/trunk/test/tools/dsymutil/Inputs/odr6.ll<br>
    llvm/trunk/test/tools/dsymutil/Inputs/odr7.cpp<br>
    llvm/trunk/test/tools/dsymutil/Inputs/odr7.ll<br>
    llvm/trunk/test/tools/dsymutil/X86/odr-1.test<br>
Modified:<br>
    llvm/trunk/tools/dsymutil/DwarfLinker.cpp<br>
    llvm/trunk/tools/dsymutil/dsymutil.cpp<br>
    llvm/trunk/tools/dsymutil/dsymutil.h<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/odr-types.h<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_tools_dsymutil_Inputs_odr-2Dtypes.h-3Frev-3D242847-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=m-DV7k0rpuXNWSjezzmTjcw3n1hzXJItX-QkKZmMHyY&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr-types.h?rev=242847&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/dsymutil/Inputs/odr-types.h (added)<br>
+++ llvm/trunk/test/tools/dsymutil/Inputs/odr-types.h Tue Jul 21 17:41:43 2015<br>
@@ -0,0 +1,51 @@<br>
+struct S {<br>
+       int I;<br>
+<br>
+       void incr() __attribute__((always_inline)) { I++; }<br>
+       void incr(int Add) __attribute__((always_inline)) { I += Add; }<br>
+<br>
+       typedef int SInt;<br>
+<br>
+       struct Nested {<br>
+               double D;<br>
+<br>
+               template<typename T> void init(T Val) { D = double(Val); }<br>
+       };<br>
+<br>
+       Nested D;<br>
+<br>
+public:<br>
+       int foo() { return I; }<br>
+};<br>
+<br>
+typedef S AliasForS;<br>
+<br>
+namespace N {<br>
+class C {<br>
+       AliasForS S;<br>
+};<br>
+}<br>
+<br>
+namespace N {<br>
+namespace N {<br>
+class C {<br>
+        int S;<br>
+};<br>
+}<br>
+}<br>
+<br>
+namespace {<br>
+       class AnonC {<br>
+       };<br>
+}<br>
+<br>
+union U {<br>
+       class C {} C;<br>
+       struct S {} S;<br>
+};<br>
+<br>
+inline int func() {<br>
+       struct CInsideFunc { int i; };<br>
+       auto functor = []() { CInsideFunc dummy; return dummy.i; };<br>
+       return functor();<br>
+}<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/odr1.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_tools_dsymutil_Inputs_odr1.cpp-3Frev-3D242847-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=JsSK_388fOn0_EYApJgGMl25_IyNN0qMudJqGb4_0TA&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr1.cpp?rev=242847&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/dsymutil/Inputs/odr1.cpp (added)<br>
+++ llvm/trunk/test/tools/dsymutil/Inputs/odr1.cpp Tue Jul 21 17:41:43 2015<br>
@@ -0,0 +1,11 @@<br>
+#include "odr-types.h"<br>
+<br>
+int foo() {<br>
+       AliasForS s;<br>
+       N::C nc;<br>
+       N::N::C nnc;<br>
+       AnonC ac;<br>
+       U u;<br>
+<br>
+       return func();<br>
+}<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/odr1.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_tools_dsymutil_Inputs_odr1.ll-3Frev-3D242847-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=Cy7MjYyeA9vCxf7yGbvumnh_ZJ81S9jb0JOdWglQniQ&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr1.ll?rev=242847&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/dsymutil/Inputs/odr1.ll (added)<br>
+++ llvm/trunk/test/tools/dsymutil/Inputs/odr1.ll Tue Jul 21 17:41:43 2015<br>
@@ -0,0 +1,153 @@<br>
+; Generated from odr1.cpp and odr-types.h by running:<br>
+; clang -emit-llvm -g -S -std=c++11 odr1.cpp<br>
+; ModuleID = 'odr1.cpp'<br>
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"<br>
+target triple = "x86_64-apple-macosx10.11.0"<br>
+<br>
+%struct.S = type { i32, %"struct.S::Nested" }<br>
+%"struct.S::Nested" = type { double }<br>
+%"class.N::C" = type { %struct.S }<br>
+%"class.N::N::C" = type { i32 }<br>
+%"class.(anonymous namespace)::AnonC" = type { i8 }<br>
+%union.U = type { %"class.U::C" }<br>
+%"class.U::C" = type { i8 }<br>
+%class.anon = type { i8 }<br>
+%struct.CInsideFunc = type { i32 }<br>
+<br>
+; Function Attrs: ssp uwtable<br>
+define i32 @_Z3foov() #0 {<br>
+entry:<br>
+  %s = alloca %struct.S, align 8<br>
+  %nc = alloca %"class.N::C", align 8<br>
+  %nnc = alloca %"class.N::N::C", align 4<br>
+  %ac = alloca %"class.(anonymous namespace)::AnonC", align 1<br>
+  %u = alloca %union.U, align 1<br>
+  call void @llvm.dbg.declare(metadata %struct.S* %s, metadata !59, metadata !60), !dbg !61<br>
+  call void @llvm.dbg.declare(metadata %"class.N::C"* %nc, metadata !62, metadata !60), !dbg !63<br>
+  call void @llvm.dbg.declare(metadata %"class.N::N::C"* %nnc, metadata !64, metadata !60), !dbg !65<br>
+  call void @llvm.dbg.declare(metadata %"class.(anonymous namespace)::AnonC"* %ac, metadata !66, metadata !60), !dbg !69<br>
+  call void @llvm.dbg.declare(metadata %union.U* %u, metadata !70, metadata !60), !dbg !71<br>
+  %call = call i32 @_Z4funcv(), !dbg !72<br>
+  ret i32 %call, !dbg !73<br>
+}<br>
+<br>
+; Function Attrs: nounwind readnone<br>
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #1<br>
+<br>
+; Function Attrs: inlinehint ssp uwtable<br>
+define linkonce_odr i32 @_Z4funcv() #2 {<br>
+entry:<br>
+  %functor = alloca %class.anon, align 1<br>
+  call void @llvm.dbg.declare(metadata %class.anon* %functor, metadata !74, metadata !60), !dbg !75<br>
+  %call = call i32 @_ZZ4funcvENKUlvE_clEv(%class.anon* %functor), !dbg !76<br>
+  ret i32 %call, !dbg !77<br>
+}<br>
+<br>
+; Function Attrs: inlinehint nounwind ssp uwtable<br>
+define linkonce_odr i32 @_ZZ4funcvENKUlvE_clEv(%class.anon* %this) #3 align 2 {<br>
+entry:<br>
+  %this.addr = alloca %class.anon*, align 8<br>
+  %dummy = alloca %struct.CInsideFunc, align 4<br>
+  store %class.anon* %this, %class.anon** %this.addr, align 8<br>
+  call void @llvm.dbg.declare(metadata %class.anon** %this.addr, metadata !78, metadata !60), !dbg !80<br>
+  %this1 = load %class.anon*, %class.anon** %this.addr<br>
+  call void @llvm.dbg.declare(metadata %struct.CInsideFunc* %dummy, metadata !81, metadata !60), !dbg !82<br>
+  %i = getelementptr inbounds %struct.CInsideFunc, %struct.CInsideFunc* %dummy, i32 0, i32 0, !dbg !83<br>
+  %0 = load i32, i32* %i, align 4, !dbg !83<br>
+  ret i32 %0, !dbg !84<br>
+}<br>
+<br>
+attributes #0 = { ssp 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"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
+attributes #1 = { nounwind readnone }<br>
+attributes #2 = { inlinehint ssp 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"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
+attributes #3 = { inlinehint nounwind ssp 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"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
+<br>
+!<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.dbg.cu&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=dbcJ5M0NA_xTsY_090OxqRRWqj--MtMcixPHgFJRic0&e=" rel="noreferrer" target="_blank">llvm.dbg.cu</a> = !{!0}<br>
+!llvm.module.flags = !{!55, !56, !57}<br>
+!llvm.ident = !{!58}<br>
+<br>
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.8.0 (trunk 242534)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !3, subprograms: !52)<br>
+!1 = !DIFile(filename: "odr1.cpp", directory: "/Inputs")<br>
+!2 = !{}<br>
+!3 = !{!4, !20, !24, !29, !33, !37, !38, !39, !49}<br>
+!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "S", file: !5, line: 1, size: 128, align: 64, elements: !6, identifier: "_ZTS1S")<br>
+!5 = !DIFile(filename: "./odr-types.h", directory: "/Inputs")<br>
+!6 = !{!7, !9, !10, !14, !17}<br>
+!7 = !DIDerivedType(tag: DW_TAG_member, name: "I", scope: !"_ZTS1S", file: !5, line: 2, baseType: !8, size: 32, align: 32)<br>
+!8 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)<br>
+!9 = !DIDerivedType(tag: DW_TAG_member, name: "D", scope: !"_ZTS1S", file: !5, line: 15, baseType: !"_ZTSN1S6NestedE", size: 64, align: 64, offset: 64)<br>
+!10 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEv", scope: !"_ZTS1S", file: !5, line: 4, type: !11, isLocal: false, isDefinition: false, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false)<br>
+!11 = !DISubroutineType(types: !12)<br>
+!12 = !{null, !13}<br>
+!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTS1S", size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer)<br>
+!14 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEi", scope: !"_ZTS1S", file: !5, line: 5, type: !15, isLocal: false, isDefinition: false, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false)<br>
+!15 = !DISubroutineType(types: !16)<br>
+!16 = !{null, !13, !8}<br>
+!17 = !DISubprogram(name: "foo", linkageName: "_ZN1S3fooEv", scope: !"_ZTS1S", file: !5, line: 18, type: !18, isLocal: false, isDefinition: false, scopeLine: 18, flags: DIFlagPrototyped, isOptimized: false)<br>
+!18 = !DISubroutineType(types: !19)<br>
+!19 = !{!8, !13}<br>
+!20 = !DICompositeType(tag: DW_TAG_structure_type, name: "Nested", scope: !"_ZTS1S", file: !5, line: 9, size: 64, align: 64, elements: !21, identifier: "_ZTSN1S6NestedE")<br>
+!21 = !{!22}<br>
+!22 = !DIDerivedType(tag: DW_TAG_member, name: "D", scope: !"_ZTSN1S6NestedE", file: !5, line: 10, baseType: !23, size: 64, align: 64)<br>
+!23 = !DIBasicType(name: "double", size: 64, align: 64, encoding: DW_ATE_float)<br>
+!24 = !DICompositeType(tag: DW_TAG_class_type, name: "C", scope: !25, file: !5, line: 24, size: 128, align: 64, elements: !26, identifier: "_ZTSN1N1CE")<br>
+!25 = !DINamespace(name: "N", scope: null, file: !5, line: 23)<br>
+!26 = !{!27}<br>
+!27 = !DIDerivedType(tag: DW_TAG_member, name: "S", scope: !"_ZTSN1N1CE", file: !5, line: 25, baseType: !28, size: 128, align: 64)<br>
+!28 = !DIDerivedType(tag: DW_TAG_typedef, name: "AliasForS", file: !5, line: 21, baseType: !"_ZTS1S")<br>
+!29 = !DICompositeType(tag: DW_TAG_class_type, name: "C", scope: !30, file: !5, line: 31, size: 32, align: 32, elements: !31, identifier: "_ZTSN1N1N1CE")<br>
+!30 = !DINamespace(name: "N", scope: !25, file: !5, line: 30)<br>
+!31 = !{!32}<br>
+!32 = !DIDerivedType(tag: DW_TAG_member, name: "S", scope: !"_ZTSN1N1N1CE", file: !5, line: 32, baseType: !8, size: 32, align: 32)<br>
+!33 = !DICompositeType(tag: DW_TAG_union_type, name: "U", file: !5, line: 42, size: 8, align: 8, elements: !34, identifier: "_ZTS1U")<br>
+!34 = !{!35, !36}<br>
+!35 = !DIDerivedType(tag: DW_TAG_member, name: "C", scope: !"_ZTS1U", file: !5, line: 43, baseType: !"_ZTSN1U1CE", size: 8, align: 8)<br>
+!36 = !DIDerivedType(tag: DW_TAG_member, name: "S", scope: !"_ZTS1U", file: !5, line: 44, baseType: !"_ZTSN1U1SE", size: 8, align: 8)<br>
+!37 = !DICompositeType(tag: DW_TAG_class_type, name: "C", scope: !"_ZTS1U", file: !5, line: 43, size: 8, align: 8, elements: !2, identifier: "_ZTSN1U1CE")<br>
+!38 = !DICompositeType(tag: DW_TAG_structure_type, name: "S", scope: !"_ZTS1U", file: !5, line: 44, size: 8, align: 8, elements: !2, identifier: "_ZTSN1U1SE")<br>
+!39 = !DICompositeType(tag: DW_TAG_class_type, scope: !40, file: !5, line: 49, size: 8, align: 8, elements: !43, identifier: "_ZTSZ4funcvEUlvE_")<br>
+!40 = !DISubprogram(name: "func", linkageName: "_Z4funcv", scope: !5, file: !5, line: 47, type: !41, isLocal: false, isDefinition: true, scopeLine: 47, flags: DIFlagPrototyped, isOptimized: false, function: i32 ()* @_Z4funcv, variables: !2)<br>
+!41 = !DISubroutineType(types: !42)<br>
+!42 = !{!8}<br>
+!43 = !{!44}<br>
+!44 = !DISubprogram(name: "operator()", scope: !"_ZTSZ4funcvEUlvE_", file: !5, line: 49, type: !45, isLocal: false, isDefinition: false, scopeLine: 49, flags: DIFlagPublic | DIFlagPrototyped, isOptimized: false)<br>
+!45 = !DISubroutineType(types: !46)<br>
+!46 = !{!8, !47}<br>
+!47 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !48, size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer)<br>
+!48 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !"_ZTSZ4funcvEUlvE_")<br>
+!49 = !DICompositeType(tag: DW_TAG_structure_type, name: "CInsideFunc", scope: !40, file: !5, line: 48, size: 32, align: 32, elements: !50, identifier: "_ZTSZ4funcvE11CInsideFunc")<br>
+!50 = !{!51}<br>
+!51 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !"_ZTSZ4funcvE11CInsideFunc", file: !5, line: 48, baseType: !8, size: 32, align: 32)<br>
+!52 = !{!53, !40, !54}<br>
+!53 = !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !1, file: !1, line: 3, type: !41, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, function: i32 ()* @_Z3foov, variables: !2)<br>
+!54 = !DISubprogram(name: "operator()", linkageName: "_ZZ4funcvENKUlvE_clEv", scope: !"_ZTSZ4funcvEUlvE_", file: !5, line: 49, type: !45, isLocal: false, isDefinition: true, scopeLine: 49, flags: DIFlagPrototyped, isOptimized: false, function: i32 (%class.anon*)* @_ZZ4funcvENKUlvE_clEv, declaration: !44, variables: !2)<br>
+!55 = !{i32 2, !"Dwarf Version", i32 2}<br>
+!56 = !{i32 2, !"Debug Info Version", i32 3}<br>
+!57 = !{i32 1, !"PIC Level", i32 2}<br>
+!58 = !{!"clang version 3.8.0 (trunk 242534)"}<br>
+!59 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "s", scope: !53, file: !1, line: 4, type: !28)<br>
+!60 = !DIExpression()<br>
+!61 = !DILocation(line: 4, column: 12, scope: !53)<br>
+!62 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "nc", scope: !53, file: !1, line: 5, type: !"_ZTSN1N1CE")<br>
+!63 = !DILocation(line: 5, column: 7, scope: !53)<br>
+!64 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "nnc", scope: !53, file: !1, line: 6, type: !"_ZTSN1N1N1CE")<br>
+!65 = !DILocation(line: 6, column: 10, scope: !53)<br>
+!66 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "ac", scope: !53, file: !1, line: 7, type: !67)<br>
+!67 = !DICompositeType(tag: DW_TAG_class_type, name: "AnonC", scope: !68, file: !5, line: 38, size: 8, align: 8, elements: !2)<br>
+!68 = !DINamespace(scope: null, file: !5, line: 37)<br>
+!69 = !DILocation(line: 7, column: 8, scope: !53)<br>
+!70 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "u", scope: !53, file: !1, line: 8, type: !"_ZTS1U")<br>
+!71 = !DILocation(line: 8, column: 4, scope: !53)<br>
+!72 = !DILocation(line: 10, column: 9, scope: !53)<br>
+!73 = !DILocation(line: 10, column: 2, scope: !53)<br>
+!74 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "functor", scope: !40, file: !5, line: 49, type: !"_ZTSZ4funcvEUlvE_")<br>
+!75 = !DILocation(line: 49, column: 7, scope: !40)<br>
+!76 = !DILocation(line: 50, column: 9, scope: !40)<br>
+!77 = !DILocation(line: 50, column: 2, scope: !40)<br>
+!78 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "this", arg: 1, scope: !54, type: !79, flags: DIFlagArtificial | DIFlagObjectPointer)<br>
+!79 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !48, size: 64, align: 64)<br>
+!80 = !DILocation(line: 0, scope: !54)<br>
+!81 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "dummy", scope: !54, file: !5, line: 49, type: !"_ZTSZ4funcvE11CInsideFunc")<br>
+!82 = !DILocation(line: 49, column: 36, scope: !54)<br>
+!83 = !DILocation(line: 49, column: 56, scope: !54)<br>
+!84 = !DILocation(line: 49, column: 43, scope: !54)<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/odr2.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_tools_dsymutil_Inputs_odr2.cpp-3Frev-3D242847-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=ZSdC_emlEdUsgsH92XX7wwlK8Krv2EPfdTJ1Wdxwt2w&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr2.cpp?rev=242847&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/dsymutil/Inputs/odr2.cpp (added)<br>
+++ llvm/trunk/test/tools/dsymutil/Inputs/odr2.cpp Tue Jul 21 17:41:43 2015<br>
@@ -0,0 +1,7 @@<br>
+#include "odr-types.h"<br>
+<br>
+int bar() {<br>
+       S s;<br>
+       s.incr();<br>
+       return s.foo();<br>
+}<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/odr2.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_tools_dsymutil_Inputs_odr2.ll-3Frev-3D242847-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=96Ou4YTZ34FHZkC1MWXRHK4Zai3h-sMJpnRvLnsK1gQ&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr2.ll?rev=242847&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/dsymutil/Inputs/odr2.ll (added)<br>
+++ llvm/trunk/test/tools/dsymutil/Inputs/odr2.ll Tue Jul 21 17:41:43 2015<br>
@@ -0,0 +1,99 @@<br>
+; Generated from odr2.cpp and odr-types.h by running:<br>
+; clang -emit-llvm -g -S -std=c++11 odr2.cpp<br>
+; ModuleID = 'odr2.cpp'<br>
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"<br>
+target triple = "x86_64-apple-macosx10.11.0"<br>
+<br>
+%struct.S = type { i32, %"struct.S::Nested" }<br>
+%"struct.S::Nested" = type { double }<br>
+<br>
+; Function Attrs: ssp uwtable<br>
+define i32 @_Z3barv() #0 {<br>
+entry:<br>
+  %this.addr.i = alloca %struct.S*, align 8<br>
+  %s = alloca %struct.S, align 8<br>
+  call void @llvm.dbg.declare(metadata %struct.S* %s, metadata !34, metadata !35), !dbg !36<br>
+  store %struct.S* %s, %struct.S** %this.addr.i, align 8, !dbg !37<br>
+  %this1.i = load %struct.S*, %struct.S** %this.addr.i, !dbg !37<br>
+  %I.i = getelementptr inbounds %struct.S, %struct.S* %this1.i, i32 0, i32 0, !dbg !38<br>
+  %0 = load i32, i32* %I.i, align 4, !dbg !40<br>
+  %inc.i = add nsw i32 %0, 1, !dbg !40<br>
+  store i32 %inc.i, i32* %I.i, align 4, !dbg !40<br>
+  %call = call i32 @_ZN1S3fooEv(%struct.S* %s), !dbg !41<br>
+  call void @llvm.dbg.declare(metadata %struct.S** %this.addr.i, metadata !42, metadata !35), !dbg !44<br>
+  ret i32 %call, !dbg !45<br>
+}<br>
+<br>
+; Function Attrs: nounwind readnone<br>
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #1<br>
+<br>
+; Function Attrs: nounwind ssp uwtable<br>
+define linkonce_odr i32 @_ZN1S3fooEv(%struct.S* %this) #2 align 2 {<br>
+entry:<br>
+  %this.addr = alloca %struct.S*, align 8<br>
+  store %struct.S* %this, %struct.S** %this.addr, align 8<br>
+  call void @llvm.dbg.declare(metadata %struct.S** %this.addr, metadata !46, metadata !35), !dbg !47<br>
+  %this1 = load %struct.S*, %struct.S** %this.addr<br>
+  %I = getelementptr inbounds %struct.S, %struct.S* %this1, i32 0, i32 0, !dbg !48<br>
+  %0 = load i32, i32* %I, align 4, !dbg !48<br>
+  ret i32 %0, !dbg !49<br>
+}<br>
+<br>
+attributes #0 = { ssp 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"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
+attributes #1 = { nounwind readnone }<br>
+attributes #2 = { nounwind ssp 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"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
+<br>
+!<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.dbg.cu&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=dbcJ5M0NA_xTsY_090OxqRRWqj--MtMcixPHgFJRic0&e=" rel="noreferrer" target="_blank">llvm.dbg.cu</a> = !{!0}<br>
+!llvm.module.flags = !{!30, !31, !32}<br>
+!llvm.ident = !{!33}<br>
+<br>
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.8.0 (trunk 242534)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !3, subprograms: !24)<br>
+!1 = !DIFile(filename: "odr2.cpp", directory: "/Inputs")<br>
+!2 = !{}<br>
+!3 = !{!4, !20}<br>
+!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "S", file: !5, line: 1, size: 128, align: 64, elements: !6, identifier: "_ZTS1S")<br>
+!5 = !DIFile(filename: "./odr-types.h", directory: "/Inputs")<br>
+!6 = !{!7, !9, !10, !14, !17}<br>
+!7 = !DIDerivedType(tag: DW_TAG_member, name: "I", scope: !"_ZTS1S", file: !5, line: 2, baseType: !8, size: 32, align: 32)<br>
+!8 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)<br>
+!9 = !DIDerivedType(tag: DW_TAG_member, name: "D", scope: !"_ZTS1S", file: !5, line: 15, baseType: !"_ZTSN1S6NestedE", size: 64, align: 64, offset: 64)<br>
+!10 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEv", scope: !"_ZTS1S", file: !5, line: 4, type: !11, isLocal: false, isDefinition: false, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false)<br>
+!11 = !DISubroutineType(types: !12)<br>
+!12 = !{null, !13}<br>
+!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTS1S", size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer)<br>
+!14 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEi", scope: !"_ZTS1S", file: !5, line: 5, type: !15, isLocal: false, isDefinition: false, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false)<br>
+!15 = !DISubroutineType(types: !16)<br>
+!16 = !{null, !13, !8}<br>
+!17 = !DISubprogram(name: "foo", linkageName: "_ZN1S3fooEv", scope: !"_ZTS1S", file: !5, line: 18, type: !18, isLocal: false, isDefinition: false, scopeLine: 18, flags: DIFlagPrototyped, isOptimized: false)<br>
+!18 = !DISubroutineType(types: !19)<br>
+!19 = !{!8, !13}<br>
+!20 = !DICompositeType(tag: DW_TAG_structure_type, name: "Nested", scope: !"_ZTS1S", file: !5, line: 9, size: 64, align: 64, elements: !21, identifier: "_ZTSN1S6NestedE")<br>
+!21 = !{!22}<br>
+!22 = !DIDerivedType(tag: DW_TAG_member, name: "D", scope: !"_ZTSN1S6NestedE", file: !5, line: 10, baseType: !23, size: 64, align: 64)<br>
+!23 = !DIBasicType(name: "double", size: 64, align: 64, encoding: DW_ATE_float)<br>
+!24 = !{!25, !28, !29}<br>
+!25 = !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !1, file: !1, line: 3, type: !26, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, function: i32 ()* @_Z3barv, variables: !2)<br>
+!26 = !DISubroutineType(types: !27)<br>
+!27 = !{!8}<br>
+!28 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEv", scope: !"_ZTS1S", file: !5, line: 4, type: !11, isLocal: false, isDefinition: true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false, declaration: !10, variables: !2)<br>
+!29 = !DISubprogram(name: "foo", linkageName: "_ZN1S3fooEv", scope: !"_ZTS1S", file: !5, line: 18, type: !18, isLocal: false, isDefinition: true, scopeLine: 18, flags: DIFlagPrototyped, isOptimized: false, function: i32 (%struct.S*)* @_ZN1S3fooEv, declaration: !17, variables: !2)<br>
+!30 = !{i32 2, !"Dwarf Version", i32 2}<br>
+!31 = !{i32 2, !"Debug Info Version", i32 3}<br>
+!32 = !{i32 1, !"PIC Level", i32 2}<br>
+!33 = !{!"clang version 3.8.0 (trunk 242534)"}<br>
+!34 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "s", scope: !25, file: !1, line: 4, type: !"_ZTS1S")<br>
+!35 = !DIExpression()<br>
+!36 = !DILocation(line: 4, column: 4, scope: !25)<br>
+!37 = !DILocation(line: 5, column: 2, scope: !25)<br>
+!38 = !DILocation(line: 4, column: 47, scope: !28, inlinedAt: !39)<br>
+!39 = distinct !DILocation(line: 5, column: 2, scope: !25)<br>
+!40 = !DILocation(line: 4, column: 48, scope: !28, inlinedAt: !39)<br>
+!41 = !DILocation(line: 6, column: 9, scope: !25)<br>
+!42 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "this", arg: 1, scope: !28, type: !43, flags: DIFlagArtificial | DIFlagObjectPointer)<br>
+!43 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTS1S", size: 64, align: 64)<br>
+!44 = !DILocation(line: 0, scope: !28, inlinedAt: !39)<br>
+!45 = !DILocation(line: 6, column: 2, scope: !25)<br>
+!46 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "this", arg: 1, scope: !29, type: !43, flags: DIFlagArtificial | DIFlagObjectPointer)<br>
+!47 = !DILocation(line: 0, scope: !29)<br>
+!48 = !DILocation(line: 18, column: 21, scope: !29)<br>
+!49 = !DILocation(line: 18, column: 14, scope: !29)<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/odr3.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_tools_dsymutil_Inputs_odr3.cpp-3Frev-3D242847-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=RilqrA-f8_f8vTw5NOSOOhgO8N7Flr76hbnhlKYJGyY&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr3.cpp?rev=242847&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/dsymutil/Inputs/odr3.cpp (added)<br>
+++ llvm/trunk/test/tools/dsymutil/Inputs/odr3.cpp Tue Jul 21 17:41:43 2015<br>
@@ -0,0 +1,7 @@<br>
+#include "odr-types.h"<br>
+<br>
+int bar() {<br>
+       S s;<br>
+       s.incr(42);<br>
+       return s.foo();<br>
+}<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/odr3.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_tools_dsymutil_Inputs_odr3.ll-3Frev-3D242847-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=VjNuyO3rcAwGhdTmeXtQn1wFQulHXOKIzyccuZiuBFw&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr3.ll?rev=242847&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/dsymutil/Inputs/odr3.ll (added)<br>
+++ llvm/trunk/test/tools/dsymutil/Inputs/odr3.ll Tue Jul 21 17:41:43 2015<br>
@@ -0,0 +1,106 @@<br>
+; Generated from odr3.cpp and odr-types.h by running:<br>
+; clang -emit-llvm -g -S -std=c++11 odr3.cpp<br>
+; ModuleID = 'odr3.cpp'<br>
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"<br>
+target triple = "x86_64-apple-macosx10.11.0"<br>
+<br>
+%struct.S = type { i32, %"struct.S::Nested" }<br>
+%"struct.S::Nested" = type { double }<br>
+<br>
+; Function Attrs: ssp uwtable<br>
+define i32 @_Z3barv() #0 {<br>
+entry:<br>
+  %this.addr.i = alloca %struct.S*, align 8<br>
+  %Add.addr.i = alloca i32, align 4<br>
+  %s = alloca %struct.S, align 8<br>
+  call void @llvm.dbg.declare(metadata %struct.S* %s, metadata !34, metadata !35), !dbg !36<br>
+  store %struct.S* %s, %struct.S** %this.addr.i, align 8, !dbg !37<br>
+  store i32 42, i32* %Add.addr.i, align 4, !dbg !37<br>
+  %this1.i = load %struct.S*, %struct.S** %this.addr.i, !dbg !37<br>
+  %0 = load i32, i32* %Add.addr.i, align 4, !dbg !38<br>
+  %I.i = getelementptr inbounds %struct.S, %struct.S* %this1.i, i32 0, i32 0, !dbg !40<br>
+  %1 = load i32, i32* %I.i, align 4, !dbg !41<br>
+  %add.i = add nsw i32 %1, %0, !dbg !41<br>
+  store i32 %add.i, i32* %I.i, align 4, !dbg !41<br>
+  %call = call i32 @_ZN1S3fooEv(%struct.S* %s), !dbg !42<br>
+  call void @llvm.dbg.declare(metadata %struct.S** %this.addr.i, metadata !43, metadata !35), !dbg !45<br>
+  call void @llvm.dbg.declare(metadata i32* %Add.addr.i, metadata !46, metadata !35), !dbg !47<br>
+  ret i32 %call, !dbg !48<br>
+}<br>
+<br>
+; Function Attrs: nounwind readnone<br>
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #1<br>
+<br>
+; Function Attrs: nounwind ssp uwtable<br>
+define linkonce_odr i32 @_ZN1S3fooEv(%struct.S* %this) #2 align 2 {<br>
+entry:<br>
+  %this.addr = alloca %struct.S*, align 8<br>
+  store %struct.S* %this, %struct.S** %this.addr, align 8<br>
+  call void @llvm.dbg.declare(metadata %struct.S** %this.addr, metadata !49, metadata !35), !dbg !50<br>
+  %this1 = load %struct.S*, %struct.S** %this.addr<br>
+  %I = getelementptr inbounds %struct.S, %struct.S* %this1, i32 0, i32 0, !dbg !51<br>
+  %0 = load i32, i32* %I, align 4, !dbg !51<br>
+  ret i32 %0, !dbg !52<br>
+}<br>
+<br>
+attributes #0 = { ssp 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"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
+attributes #1 = { nounwind readnone }<br>
+attributes #2 = { nounwind ssp 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"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
+<br>
+!<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.dbg.cu&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=dbcJ5M0NA_xTsY_090OxqRRWqj--MtMcixPHgFJRic0&e=" rel="noreferrer" target="_blank">llvm.dbg.cu</a> = !{!0}<br>
+!llvm.module.flags = !{!30, !31, !32}<br>
+!llvm.ident = !{!33}<br>
+<br>
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.8.0 (trunk 242534)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !3, subprograms: !24)<br>
+!1 = !DIFile(filename: "odr3.cpp", directory: "/Inputs")<br>
+!2 = !{}<br>
+!3 = !{!4, !20}<br>
+!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "S", file: !5, line: 1, size: 128, align: 64, elements: !6, identifier: "_ZTS1S")<br>
+!5 = !DIFile(filename: "./odr-types.h", directory: "/Inputs")<br>
+!6 = !{!7, !9, !10, !14, !17}<br>
+!7 = !DIDerivedType(tag: DW_TAG_member, name: "I", scope: !"_ZTS1S", file: !5, line: 2, baseType: !8, size: 32, align: 32)<br>
+!8 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)<br>
+!9 = !DIDerivedType(tag: DW_TAG_member, name: "D", scope: !"_ZTS1S", file: !5, line: 15, baseType: !"_ZTSN1S6NestedE", size: 64, align: 64, offset: 64)<br>
+!10 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEv", scope: !"_ZTS1S", file: !5, line: 4, type: !11, isLocal: false, isDefinition: false, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false)<br>
+!11 = !DISubroutineType(types: !12)<br>
+!12 = !{null, !13}<br>
+!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTS1S", size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer)<br>
+!14 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEi", scope: !"_ZTS1S", file: !5, line: 5, type: !15, isLocal: false, isDefinition: false, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false)<br>
+!15 = !DISubroutineType(types: !16)<br>
+!16 = !{null, !13, !8}<br>
+!17 = !DISubprogram(name: "foo", linkageName: "_ZN1S3fooEv", scope: !"_ZTS1S", file: !5, line: 18, type: !18, isLocal: false, isDefinition: false, scopeLine: 18, flags: DIFlagPrototyped, isOptimized: false)<br>
+!18 = !DISubroutineType(types: !19)<br>
+!19 = !{!8, !13}<br>
+!20 = !DICompositeType(tag: DW_TAG_structure_type, name: "Nested", scope: !"_ZTS1S", file: !5, line: 9, size: 64, align: 64, elements: !21, identifier: "_ZTSN1S6NestedE")<br>
+!21 = !{!22}<br>
+!22 = !DIDerivedType(tag: DW_TAG_member, name: "D", scope: !"_ZTSN1S6NestedE", file: !5, line: 10, baseType: !23, size: 64, align: 64)<br>
+!23 = !DIBasicType(name: "double", size: 64, align: 64, encoding: DW_ATE_float)<br>
+!24 = !{!25, !28, !29}<br>
+!25 = !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !1, file: !1, line: 3, type: !26, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, function: i32 ()* @_Z3barv, variables: !2)<br>
+!26 = !DISubroutineType(types: !27)<br>
+!27 = !{!8}<br>
+!28 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEi", scope: !"_ZTS1S", file: !5, line: 5, type: !15, isLocal: false, isDefinition: true, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false, declaration: !14, variables: !2)<br>
+!29 = !DISubprogram(name: "foo", linkageName: "_ZN1S3fooEv", scope: !"_ZTS1S", file: !5, line: 18, type: !18, isLocal: false, isDefinition: true, scopeLine: 18, flags: DIFlagPrototyped, isOptimized: false, function: i32 (%struct.S*)* @_ZN1S3fooEv, declaration: !17, variables: !2)<br>
+!30 = !{i32 2, !"Dwarf Version", i32 2}<br>
+!31 = !{i32 2, !"Debug Info Version", i32 3}<br>
+!32 = !{i32 1, !"PIC Level", i32 2}<br>
+!33 = !{!"clang version 3.8.0 (trunk 242534)"}<br>
+!34 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "s", scope: !25, file: !1, line: 4, type: !"_ZTS1S")<br>
+!35 = !DIExpression()<br>
+!36 = !DILocation(line: 4, column: 4, scope: !25)<br>
+!37 = !DILocation(line: 5, column: 2, scope: !25)<br>
+!38 = !DILocation(line: 5, column: 59, scope: !28, inlinedAt: !39)<br>
+!39 = distinct !DILocation(line: 5, column: 2, scope: !25)<br>
+!40 = !DILocation(line: 5, column: 54, scope: !28, inlinedAt: !39)<br>
+!41 = !DILocation(line: 5, column: 56, scope: !28, inlinedAt: !39)<br>
+!42 = !DILocation(line: 6, column: 9, scope: !25)<br>
+!43 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "this", arg: 1, scope: !28, type: !44, flags: DIFlagArtificial | DIFlagObjectPointer)<br>
+!44 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTS1S", size: 64, align: 64)<br>
+!45 = !DILocation(line: 0, scope: !28, inlinedAt: !39)<br>
+!46 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "Add", arg: 2, scope: !28, file: !5, line: 5, type: !8)<br>
+!47 = !DILocation(line: 5, column: 16, scope: !28, inlinedAt: !39)<br>
+!48 = !DILocation(line: 6, column: 2, scope: !25)<br>
+!49 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "this", arg: 1, scope: !29, type: !44, flags: DIFlagArtificial | DIFlagObjectPointer)<br>
+!50 = !DILocation(line: 0, scope: !29)<br>
+!51 = !DILocation(line: 18, column: 21, scope: !29)<br>
+!52 = !DILocation(line: 18, column: 14, scope: !29)<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/odr4.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_tools_dsymutil_Inputs_odr4.cpp-3Frev-3D242847-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=xnCIcVgpTaFZAwVPFd4DILs9IRuxSxuaUBqYqqwqcNk&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr4.cpp?rev=242847&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/dsymutil/Inputs/odr4.cpp (added)<br>
+++ llvm/trunk/test/tools/dsymutil/Inputs/odr4.cpp Tue Jul 21 17:41:43 2015<br>
@@ -0,0 +1,8 @@<br>
+namespace {<br>
+       class AnonC {<br>
+       };<br>
+}<br>
+<br>
+void baz() {<br>
+       AnonC ac;<br>
+}<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/odr4.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_tools_dsymutil_Inputs_odr4.ll-3Frev-3D242847-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=oQ-FmN4euv-kinQ5W5jTlB5w8O_VvhFqplFtMkjup4k&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr4.ll?rev=242847&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/dsymutil/Inputs/odr4.ll (added)<br>
+++ llvm/trunk/test/tools/dsymutil/Inputs/odr4.ll Tue Jul 21 17:41:43 2015<br>
@@ -0,0 +1,43 @@<br>
+; Generated from odr4.cpp and odr-types.h by running:<br>
+; clang -emit-llvm -g -S -std=c++11 odr4.cpp<br>
+; ModuleID = 'odr4.cpp'<br>
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"<br>
+target triple = "x86_64-apple-macosx10.11.0"<br>
+<br>
+%"class.(anonymous namespace)::AnonC" = type { i8 }<br>
+<br>
+; Function Attrs: nounwind ssp uwtable<br>
+define void @_Z3bazv() #0 {<br>
+entry:<br>
+  %ac = alloca %"class.(anonymous namespace)::AnonC", align 1<br>
+  call void @llvm.dbg.declare(metadata %"class.(anonymous namespace)::AnonC"* %ac, metadata !11, metadata !14), !dbg !15<br>
+  ret void, !dbg !16<br>
+}<br>
+<br>
+; Function Attrs: nounwind readnone<br>
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #1<br>
+<br>
+attributes #0 = { nounwind ssp 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"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
+attributes #1 = { nounwind readnone }<br>
+<br>
+!<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.dbg.cu&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=dbcJ5M0NA_xTsY_090OxqRRWqj--MtMcixPHgFJRic0&e=" rel="noreferrer" target="_blank">llvm.dbg.cu</a> = !{!0}<br>
+!llvm.module.flags = !{!7, !8, !9}<br>
+!llvm.ident = !{!10}<br>
+<br>
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.8.0 (trunk 242534)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3)<br>
+!1 = !DIFile(filename: "odr4.cpp", directory: "/Inputs")<br>
+!2 = !{}<br>
+!3 = !{!4}<br>
+!4 = !DISubprogram(name: "baz", linkageName: "_Z3bazv", scope: !1, file: !1, line: 6, type: !5, isLocal: false, isDefinition: true, scopeLine: 6, flags: DIFlagPrototyped, isOptimized: false, function: void ()* @_Z3bazv, variables: !2)<br>
+!5 = !DISubroutineType(types: !6)<br>
+!6 = !{null}<br>
+!7 = !{i32 2, !"Dwarf Version", i32 2}<br>
+!8 = !{i32 2, !"Debug Info Version", i32 3}<br>
+!9 = !{i32 1, !"PIC Level", i32 2}<br>
+!10 = !{!"clang version 3.8.0 (trunk 242534)"}<br>
+!11 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "ac", scope: !4, file: !1, line: 7, type: !12)<br>
+!12 = !DICompositeType(tag: DW_TAG_class_type, name: "AnonC", scope: !13, file: !1, line: 2, size: 8, align: 8, elements: !2)<br>
+!13 = !DINamespace(scope: null, file: !1, line: 1)<br>
+!14 = !DIExpression()<br>
+!15 = !DILocation(line: 7, column: 8, scope: !4)<br>
+!16 = !DILocation(line: 8, column: 1, scope: !4)<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/odr5.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_tools_dsymutil_Inputs_odr5.cpp-3Frev-3D242847-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=XNG5nEWiAadpPehtr1nzvRA6HB_3z3U5AGharNOVdzw&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr5.cpp?rev=242847&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/dsymutil/Inputs/odr5.cpp (added)<br>
+++ llvm/trunk/test/tools/dsymutil/Inputs/odr5.cpp Tue Jul 21 17:41:43 2015<br>
@@ -0,0 +1,7 @@<br>
+#include "odr-types.h"<br>
+<br>
+double baz() {<br>
+       S::Nested d;<br>
+       d.init(0);<br>
+       return d.D;<br>
+}<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/odr5.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_tools_dsymutil_Inputs_odr5.ll-3Frev-3D242847-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=b8z7cCodIx1NExNjbUHi85e4UeiGIDQ0-rhCuqDGpNU&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr5.ll?rev=242847&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/dsymutil/Inputs/odr5.ll (added)<br>
+++ llvm/trunk/test/tools/dsymutil/Inputs/odr5.ll Tue Jul 21 17:41:43 2015<br>
@@ -0,0 +1,101 @@<br>
+; Generated from odr5.cpp and odr-types.h by running:<br>
+; clang -emit-llvm -g -S -std=c++11 odr5.cpp<br>
+; ModuleID = 'odr5.cpp'<br>
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"<br>
+target triple = "x86_64-apple-macosx10.11.0"<br>
+<br>
+%"struct.S::Nested" = type { double }<br>
+<br>
+; Function Attrs: ssp uwtable<br>
+define double @_Z3bazv() #0 {<br>
+entry:<br>
+  %d = alloca %"struct.S::Nested", align 8<br>
+  call void @llvm.dbg.declare(metadata %"struct.S::Nested"* %d, metadata !39, metadata !40), !dbg !41<br>
+  call void @_ZN1S6Nested4initIiEEvT_(%"struct.S::Nested"* %d, i32 0), !dbg !42<br>
+  %D = getelementptr inbounds %"struct.S::Nested", %"struct.S::Nested"* %d, i32 0, i32 0, !dbg !43<br>
+  %0 = load double, double* %D, align 8, !dbg !43<br>
+  ret double %0, !dbg !44<br>
+}<br>
+<br>
+; Function Attrs: nounwind readnone<br>
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #1<br>
+<br>
+; Function Attrs: nounwind ssp uwtable<br>
+define linkonce_odr void @_ZN1S6Nested4initIiEEvT_(%"struct.S::Nested"* %this, i32 %Val) #2 align 2 {<br>
+entry:<br>
+  %this.addr = alloca %"struct.S::Nested"*, align 8<br>
+  %Val.addr = alloca i32, align 4<br>
+  store %"struct.S::Nested"* %this, %"struct.S::Nested"** %this.addr, align 8<br>
+  call void @llvm.dbg.declare(metadata %"struct.S::Nested"** %this.addr, metadata !45, metadata !40), !dbg !47<br>
+  store i32 %Val, i32* %Val.addr, align 4<br>
+  call void @llvm.dbg.declare(metadata i32* %Val.addr, metadata !48, metadata !40), !dbg !49<br>
+  %this1 = load %"struct.S::Nested"*, %"struct.S::Nested"** %this.addr<br>
+  %0 = load i32, i32* %Val.addr, align 4, !dbg !50<br>
+  %conv = sitofp i32 %0 to double, !dbg !50<br>
+  %D = getelementptr inbounds %"struct.S::Nested", %"struct.S::Nested"* %this1, i32 0, i32 0, !dbg !51<br>
+  store double %conv, double* %D, align 8, !dbg !52<br>
+  ret void, !dbg !53<br>
+}<br>
+<br>
+attributes #0 = { ssp 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"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
+attributes #1 = { nounwind readnone }<br>
+attributes #2 = { nounwind ssp 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"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
+<br>
+!<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.dbg.cu&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=dbcJ5M0NA_xTsY_090OxqRRWqj--MtMcixPHgFJRic0&e=" rel="noreferrer" target="_blank">llvm.dbg.cu</a> = !{!0}<br>
+!llvm.module.flags = !{!35, !36, !37}<br>
+!llvm.ident = !{!38}<br>
+<br>
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.8.0 (trunk 242534)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !3, subprograms: !24)<br>
+!1 = !DIFile(filename: "odr5.cpp", directory: "/Inputs")<br>
+!2 = !{}<br>
+!3 = !{!4, !20, !23}<br>
+!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "S", file: !5, line: 1, size: 128, align: 64, elements: !6, identifier: "_ZTS1S")<br>
+!5 = !DIFile(filename: "./odr-types.h", directory: "/Inputs")<br>
+!6 = !{!7, !9, !10, !14, !17}<br>
+!7 = !DIDerivedType(tag: DW_TAG_member, name: "I", scope: !"_ZTS1S", file: !5, line: 2, baseType: !8, size: 32, align: 32)<br>
+!8 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)<br>
+!9 = !DIDerivedType(tag: DW_TAG_member, name: "D", scope: !"_ZTS1S", file: !5, line: 15, baseType: !"_ZTSN1S6NestedE", size: 64, align: 64, offset: 64)<br>
+!10 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEv", scope: !"_ZTS1S", file: !5, line: 4, type: !11, isLocal: false, isDefinition: false, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false)<br>
+!11 = !DISubroutineType(types: !12)<br>
+!12 = !{null, !13}<br>
+!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTS1S", size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer)<br>
+!14 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEi", scope: !"_ZTS1S", file: !5, line: 5, type: !15, isLocal: false, isDefinition: false, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false)<br>
+!15 = !DISubroutineType(types: !16)<br>
+!16 = !{null, !13, !8}<br>
+!17 = !DISubprogram(name: "foo", linkageName: "_ZN1S3fooEv", scope: !"_ZTS1S", file: !5, line: 18, type: !18, isLocal: false, isDefinition: false, scopeLine: 18, flags: DIFlagPrototyped, isOptimized: false)<br>
+!18 = !DISubroutineType(types: !19)<br>
+!19 = !{!8, !13}<br>
+!20 = !DICompositeType(tag: DW_TAG_structure_type, name: "Nested", scope: !"_ZTS1S", file: !5, line: 9, size: 64, align: 64, elements: !21, identifier: "_ZTSN1S6NestedE")<br>
+!21 = !{!22}<br>
+!22 = !DIDerivedType(tag: DW_TAG_member, name: "D", scope: !"_ZTSN1S6NestedE", file: !5, line: 10, baseType: !23, size: 64, align: 64)<br>
+!23 = !DIBasicType(name: "double", size: 64, align: 64, encoding: DW_ATE_float)<br>
+!24 = !{!25, !28}<br>
+!25 = !DISubprogram(name: "baz", linkageName: "_Z3bazv", scope: !1, file: !1, line: 3, type: !26, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, function: double ()* @_Z3bazv, variables: !2)<br>
+!26 = !DISubroutineType(types: !27)<br>
+!27 = !{!23}<br>
+!28 = !DISubprogram(name: "init<int>", linkageName: "_ZN1S6Nested4initIiEEvT_", scope: !"_ZTSN1S6NestedE", file: !5, line: 12, type: !29, isLocal: false, isDefinition: true, scopeLine: 12, flags: DIFlagPrototyped, isOptimized: false, function: void (%"struct.S::Nested"*, i32)* @_ZN1S6Nested4initIiEEvT_, templateParams: !32, declaration: !34, variables: !2)<br>
+!29 = !DISubroutineType(types: !30)<br>
+!30 = !{null, !31, !8}<br>
+!31 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTSN1S6NestedE", size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer)<br>
+!32 = !{!33}<br>
+!33 = !DITemplateTypeParameter(name: "T", type: !8)<br>
+!34 = !DISubprogram(name: "init<int>", linkageName: "_ZN1S6Nested4initIiEEvT_", scope: !"_ZTSN1S6NestedE", file: !5, line: 12, type: !29, isLocal: false, isDefinition: false, scopeLine: 12, flags: DIFlagPrototyped, isOptimized: false, templateParams: !32)<br>
+!35 = !{i32 2, !"Dwarf Version", i32 2}<br>
+!36 = !{i32 2, !"Debug Info Version", i32 3}<br>
+!37 = !{i32 1, !"PIC Level", i32 2}<br>
+!38 = !{!"clang version 3.8.0 (trunk 242534)"}<br>
+!39 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "d", scope: !25, file: !1, line: 4, type: !"_ZTSN1S6NestedE")<br>
+!40 = !DIExpression()<br>
+!41 = !DILocation(line: 4, column: 12, scope: !25)<br>
+!42 = !DILocation(line: 5, column: 2, scope: !25)<br>
+!43 = !DILocation(line: 6, column: 11, scope: !25)<br>
+!44 = !DILocation(line: 6, column: 2, scope: !25)<br>
+!45 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "this", arg: 1, scope: !28, type: !46, flags: DIFlagArtificial | DIFlagObjectPointer)<br>
+!46 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTSN1S6NestedE", size: 64, align: 64)<br>
+!47 = !DILocation(line: 0, scope: !28)<br>
+!48 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "Val", arg: 2, scope: !28, file: !5, line: 12, type: !8)<br>
+!49 = !DILocation(line: 12, column: 36, scope: !28)<br>
+!50 = !DILocation(line: 12, column: 54, scope: !28)<br>
+!51 = !DILocation(line: 12, column: 43, scope: !28)<br>
+!52 = !DILocation(line: 12, column: 45, scope: !28)<br>
+!53 = !DILocation(line: 12, column: 60, scope: !28)<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/odr6.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_tools_dsymutil_Inputs_odr6.cpp-3Frev-3D242847-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=UA5Iu_u1dVddQWxFdoSWPpyp0v8eQ83DbDDQJaFwC_Q&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr6.cpp?rev=242847&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/dsymutil/Inputs/odr6.cpp (added)<br>
+++ llvm/trunk/test/tools/dsymutil/Inputs/odr6.cpp Tue Jul 21 17:41:43 2015<br>
@@ -0,0 +1,7 @@<br>
+#include "odr-types.h"<br>
+<br>
+double baz() {<br>
+       S::Nested d;<br>
+       d.init(0.0);<br>
+       return d.D;<br>
+}<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/odr6.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_tools_dsymutil_Inputs_odr6.ll-3Frev-3D242847-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=u1GiOZt3XlxE-61QowIoXi_ecVe-D-C02m_k9Ru1jk4&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr6.ll?rev=242847&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/dsymutil/Inputs/odr6.ll (added)<br>
+++ llvm/trunk/test/tools/dsymutil/Inputs/odr6.ll Tue Jul 21 17:41:43 2015<br>
@@ -0,0 +1,100 @@<br>
+; Generated from odr6.cpp and odr-types.h by running:<br>
+; clang -emit-llvm -g -S -std=c++11 odr6.cpp<br>
+; ModuleID = 'odr6.cpp'<br>
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"<br>
+target triple = "x86_64-apple-macosx10.11.0"<br>
+<br>
+%"struct.S::Nested" = type { double }<br>
+<br>
+; Function Attrs: ssp uwtable<br>
+define double @_Z3bazv() #0 {<br>
+entry:<br>
+  %d = alloca %"struct.S::Nested", align 8<br>
+  call void @llvm.dbg.declare(metadata %"struct.S::Nested"* %d, metadata !39, metadata !40), !dbg !41<br>
+  call void @_ZN1S6Nested4initIdEEvT_(%"struct.S::Nested"* %d, double 0.000000e+00), !dbg !42<br>
+  %D = getelementptr inbounds %"struct.S::Nested", %"struct.S::Nested"* %d, i32 0, i32 0, !dbg !43<br>
+  %0 = load double, double* %D, align 8, !dbg !43<br>
+  ret double %0, !dbg !44<br>
+}<br>
+<br>
+; Function Attrs: nounwind readnone<br>
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #1<br>
+<br>
+; Function Attrs: nounwind ssp uwtable<br>
+define linkonce_odr void @_ZN1S6Nested4initIdEEvT_(%"struct.S::Nested"* %this, double %Val) #2 align 2 {<br>
+entry:<br>
+  %this.addr = alloca %"struct.S::Nested"*, align 8<br>
+  %Val.addr = alloca double, align 8<br>
+  store %"struct.S::Nested"* %this, %"struct.S::Nested"** %this.addr, align 8<br>
+  call void @llvm.dbg.declare(metadata %"struct.S::Nested"** %this.addr, metadata !45, metadata !40), !dbg !47<br>
+  store double %Val, double* %Val.addr, align 8<br>
+  call void @llvm.dbg.declare(metadata double* %Val.addr, metadata !48, metadata !40), !dbg !49<br>
+  %this1 = load %"struct.S::Nested"*, %"struct.S::Nested"** %this.addr<br>
+  %0 = load double, double* %Val.addr, align 8, !dbg !50<br>
+  %D = getelementptr inbounds %"struct.S::Nested", %"struct.S::Nested"* %this1, i32 0, i32 0, !dbg !51<br>
+  store double %0, double* %D, align 8, !dbg !52<br>
+  ret void, !dbg !53<br>
+}<br>
+<br>
+attributes #0 = { ssp 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"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
+attributes #1 = { nounwind readnone }<br>
+attributes #2 = { nounwind ssp 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"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
+<br>
+!<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.dbg.cu&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=dbcJ5M0NA_xTsY_090OxqRRWqj--MtMcixPHgFJRic0&e=" rel="noreferrer" target="_blank">llvm.dbg.cu</a> = !{!0}<br>
+!llvm.module.flags = !{!35, !36, !37}<br>
+!llvm.ident = !{!38}<br>
+<br>
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.8.0 (trunk 242534)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !3, subprograms: !24)<br>
+!1 = !DIFile(filename: "odr6.cpp", directory: "/Inputs")<br>
+!2 = !{}<br>
+!3 = !{!4, !20, !23}<br>
+!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "S", file: !5, line: 1, size: 128, align: 64, elements: !6, identifier: "_ZTS1S")<br>
+!5 = !DIFile(filename: "./odr-types.h", directory: "/Inputs")<br>
+!6 = !{!7, !9, !10, !14, !17}<br>
+!7 = !DIDerivedType(tag: DW_TAG_member, name: "I", scope: !"_ZTS1S", file: !5, line: 2, baseType: !8, size: 32, align: 32)<br>
+!8 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)<br>
+!9 = !DIDerivedType(tag: DW_TAG_member, name: "D", scope: !"_ZTS1S", file: !5, line: 15, baseType: !"_ZTSN1S6NestedE", size: 64, align: 64, offset: 64)<br>
+!10 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEv", scope: !"_ZTS1S", file: !5, line: 4, type: !11, isLocal: false, isDefinition: false, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false)<br>
+!11 = !DISubroutineType(types: !12)<br>
+!12 = !{null, !13}<br>
+!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTS1S", size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer)<br>
+!14 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEi", scope: !"_ZTS1S", file: !5, line: 5, type: !15, isLocal: false, isDefinition: false, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false)<br>
+!15 = !DISubroutineType(types: !16)<br>
+!16 = !{null, !13, !8}<br>
+!17 = !DISubprogram(name: "foo", linkageName: "_ZN1S3fooEv", scope: !"_ZTS1S", file: !5, line: 18, type: !18, isLocal: false, isDefinition: false, scopeLine: 18, flags: DIFlagPrototyped, isOptimized: false)<br>
+!18 = !DISubroutineType(types: !19)<br>
+!19 = !{!8, !13}<br>
+!20 = !DICompositeType(tag: DW_TAG_structure_type, name: "Nested", scope: !"_ZTS1S", file: !5, line: 9, size: 64, align: 64, elements: !21, identifier: "_ZTSN1S6NestedE")<br>
+!21 = !{!22}<br>
+!22 = !DIDerivedType(tag: DW_TAG_member, name: "D", scope: !"_ZTSN1S6NestedE", file: !5, line: 10, baseType: !23, size: 64, align: 64)<br>
+!23 = !DIBasicType(name: "double", size: 64, align: 64, encoding: DW_ATE_float)<br>
+!24 = !{!25, !28}<br>
+!25 = !DISubprogram(name: "baz", linkageName: "_Z3bazv", scope: !1, file: !1, line: 3, type: !26, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, function: double ()* @_Z3bazv, variables: !2)<br>
+!26 = !DISubroutineType(types: !27)<br>
+!27 = !{!23}<br>
+!28 = !DISubprogram(name: "init<double>", linkageName: "_ZN1S6Nested4initIdEEvT_", scope: !"_ZTSN1S6NestedE", file: !5, line: 12, type: !29, isLocal: false, isDefinition: true, scopeLine: 12, flags: DIFlagPrototyped, isOptimized: false, function: void (%"struct.S::Nested"*, double)* @_ZN1S6Nested4initIdEEvT_, templateParams: !32, declaration: !34, variables: !2)<br>
+!29 = !DISubroutineType(types: !30)<br>
+!30 = !{null, !31, !23}<br>
+!31 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTSN1S6NestedE", size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer)<br>
+!32 = !{!33}<br>
+!33 = !DITemplateTypeParameter(name: "T", type: !23)<br>
+!34 = !DISubprogram(name: "init<double>", linkageName: "_ZN1S6Nested4initIdEEvT_", scope: !"_ZTSN1S6NestedE", file: !5, line: 12, type: !29, isLocal: false, isDefinition: false, scopeLine: 12, flags: DIFlagPrototyped, isOptimized: false, templateParams: !32)<br>
+!35 = !{i32 2, !"Dwarf Version", i32 2}<br>
+!36 = !{i32 2, !"Debug Info Version", i32 3}<br>
+!37 = !{i32 1, !"PIC Level", i32 2}<br>
+!38 = !{!"clang version 3.8.0 (trunk 242534)"}<br>
+!39 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "d", scope: !25, file: !1, line: 4, type: !"_ZTSN1S6NestedE")<br>
+!40 = !DIExpression()<br>
+!41 = !DILocation(line: 4, column: 12, scope: !25)<br>
+!42 = !DILocation(line: 5, column: 2, scope: !25)<br>
+!43 = !DILocation(line: 6, column: 11, scope: !25)<br>
+!44 = !DILocation(line: 6, column: 2, scope: !25)<br>
+!45 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "this", arg: 1, scope: !28, type: !46, flags: DIFlagArtificial | DIFlagObjectPointer)<br>
+!46 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTSN1S6NestedE", size: 64, align: 64)<br>
+!47 = !DILocation(line: 0, scope: !28)<br>
+!48 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "Val", arg: 2, scope: !28, file: !5, line: 12, type: !23)<br>
+!49 = !DILocation(line: 12, column: 36, scope: !28)<br>
+!50 = !DILocation(line: 12, column: 54, scope: !28)<br>
+!51 = !DILocation(line: 12, column: 43, scope: !28)<br>
+!52 = !DILocation(line: 12, column: 45, scope: !28)<br>
+!53 = !DILocation(line: 12, column: 60, scope: !28)<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/odr7.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_tools_dsymutil_Inputs_odr7.cpp-3Frev-3D242847-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=1xgnZPN3R3dkINfldydTdwvHmJ4umUqlwnxRi32YzVQ&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr7.cpp?rev=242847&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/dsymutil/Inputs/odr7.cpp (added)<br>
+++ llvm/trunk/test/tools/dsymutil/Inputs/odr7.cpp Tue Jul 21 17:41:43 2015<br>
@@ -0,0 +1,5 @@<br>
+#include "odr-types.h"<br>
+<br>
+void foo() {<br>
+       S::Nested N;<br>
+}<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/odr7.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_tools_dsymutil_Inputs_odr7.ll-3Frev-3D242847-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=W7XljTqVkP-sXxXjLy2qF2BdUp_Qyzr15VR3kPKR2zM&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr7.ll?rev=242847&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/dsymutil/Inputs/odr7.ll (added)<br>
+++ llvm/trunk/test/tools/dsymutil/Inputs/odr7.ll Tue Jul 21 17:41:43 2015<br>
@@ -0,0 +1,62 @@<br>
+; Generated from odr7.cpp and odr-types.h by running:<br>
+; clang -emit-llvm -g -S -std=c++11 odr7.cpp<br>
+; ModuleID = 'odr7.cpp'<br>
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"<br>
+target triple = "x86_64-apple-macosx10.11.0"<br>
+<br>
+%"struct.S::Nested" = type { double }<br>
+<br>
+; Function Attrs: nounwind ssp uwtable<br>
+define void @_Z3foov() #0 {<br>
+entry:<br>
+  %N = alloca %"struct.S::Nested", align 8<br>
+  call void @llvm.dbg.declare(metadata %"struct.S::Nested"* %N, metadata !32, metadata !33), !dbg !34<br>
+  ret void, !dbg !35<br>
+}<br>
+<br>
+; Function Attrs: nounwind readnone<br>
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #1<br>
+<br>
+attributes #0 = { nounwind ssp 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"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
+attributes #1 = { nounwind readnone }<br>
+<br>
+!<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.dbg.cu&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=dbcJ5M0NA_xTsY_090OxqRRWqj--MtMcixPHgFJRic0&e=" rel="noreferrer" target="_blank">llvm.dbg.cu</a> = !{!0}<br>
+!llvm.module.flags = !{!28, !29, !30}<br>
+!llvm.ident = !{!31}<br>
+<br>
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.8.0 (trunk 242534)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !3, subprograms: !24)<br>
+!1 = !DIFile(filename: "odr7.cpp", directory: "/Inputs")<br>
+!2 = !{}<br>
+!3 = !{!4, !20}<br>
+!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "S", file: !5, line: 1, size: 128, align: 64, elements: !6, identifier: "_ZTS1S")<br>
+!5 = !DIFile(filename: "./odr-types.h", directory: "/Inputs")<br>
+!6 = !{!7, !9, !10, !14, !17}<br>
+!7 = !DIDerivedType(tag: DW_TAG_member, name: "I", scope: !"_ZTS1S", file: !5, line: 2, baseType: !8, size: 32, align: 32)<br>
+!8 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)<br>
+!9 = !DIDerivedType(tag: DW_TAG_member, name: "D", scope: !"_ZTS1S", file: !5, line: 15, baseType: !"_ZTSN1S6NestedE", size: 64, align: 64, offset: 64)<br>
+!10 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEv", scope: !"_ZTS1S", file: !5, line: 4, type: !11, isLocal: false, isDefinition: false, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false)<br>
+!11 = !DISubroutineType(types: !12)<br>
+!12 = !{null, !13}<br>
+!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTS1S", size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer)<br>
+!14 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEi", scope: !"_ZTS1S", file: !5, line: 5, type: !15, isLocal: false, isDefinition: false, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false)<br>
+!15 = !DISubroutineType(types: !16)<br>
+!16 = !{null, !13, !8}<br>
+!17 = !DISubprogram(name: "foo", linkageName: "_ZN1S3fooEv", scope: !"_ZTS1S", file: !5, line: 18, type: !18, isLocal: false, isDefinition: false, scopeLine: 18, flags: DIFlagPrototyped, isOptimized: false)<br>
+!18 = !DISubroutineType(types: !19)<br>
+!19 = !{!8, !13}<br>
+!20 = !DICompositeType(tag: DW_TAG_structure_type, name: "Nested", scope: !"_ZTS1S", file: !5, line: 9, size: 64, align: 64, elements: !21, identifier: "_ZTSN1S6NestedE")<br>
+!21 = !{!22}<br>
+!22 = !DIDerivedType(tag: DW_TAG_member, name: "D", scope: !"_ZTSN1S6NestedE", file: !5, line: 10, baseType: !23, size: 64, align: 64)<br>
+!23 = !DIBasicType(name: "double", size: 64, align: 64, encoding: DW_ATE_float)<br>
+!24 = !{!25}<br>
+!25 = !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !1, file: !1, line: 3, type: !26, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, function: void ()* @_Z3foov, variables: !2)<br>
+!26 = !DISubroutineType(types: !27)<br>
+!27 = !{null}<br>
+!28 = !{i32 2, !"Dwarf Version", i32 2}<br>
+!29 = !{i32 2, !"Debug Info Version", i32 3}<br>
+!30 = !{i32 1, !"PIC Level", i32 2}<br>
+!31 = !{!"clang version 3.8.0 (trunk 242534)"}<br>
+!32 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "N", scope: !25, file: !1, line: 4, type: !"_ZTSN1S6NestedE")<br>
+!33 = !DIExpression()<br>
+!34 = !DILocation(line: 4, column: 12, scope: !25)<br>
+!35 = !DILocation(line: 5, column: 1, scope: !25)<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/X86/odr-1.test<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_tools_dsymutil_X86_odr-2D1.test-3Frev-3D242847-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=tzkq91VlwnzPmzHKm_G0BTFIHVoEihXf7ltLQZSd_IA&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/X86/odr-1.test?rev=242847&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/dsymutil/X86/odr-1.test (added)<br>
+++ llvm/trunk/test/tools/dsymutil/X86/odr-1.test Tue Jul 21 17:41:43 2015<br>
@@ -0,0 +1,423 @@<br>
+# REQUIRES: object-emission<br>
+# RUN: rm -rf %t<br>
+# RUN: mkdir -p %t<br>
+# RUN: llc -filetype=obj %p/../Inputs/odr1.ll -o %t/odr1.o<br>
+# RUN: llc -filetype=obj %p/../Inputs/odr2.ll -o %t/odr2.o<br>
+# RUN: llc -filetype=obj %p/../Inputs/odr3.ll -o %t/odr3.o<br>
+# RUN: llc -filetype=obj %p/../Inputs/odr4.ll -o %t/odr4.o<br>
+# RUN: llc -filetype=obj %p/../Inputs/odr5.ll -o %t/odr5.o<br>
+# RUN: llc -filetype=obj %p/../Inputs/odr6.ll -o %t/odr6.o<br>
+# RUN: llc -filetype=obj %p/../Inputs/odr7.ll -o %t/odr7.o<br>
+# RUN: llvm-dsymutil -oso-prepend-path=%t -y %s -o - | llvm-dwarfdump -debug-dump=info - | FileCheck -check-prefix=ODR -check-prefix=CHECK %s<br>
+# RUN: llvm-dsymutil -oso-prepend-path=%t -y %s -no-odr -o - | llvm-dwarfdump -debug-dump=info - | FileCheck -check-prefix=NOODR -check-prefix=CHECK %s<br>
+<br>
+# Totally made up debug map to test ODR uniquing<br>
+<br>
+---<br>
+triple:          'x86_64-unknown-unknown-macho'<br>
+objects:<br>
+  - filename: odr1.o<br>
+    symbols:<br>
+      - { sym: __Z3foov, objAddr: 0x0, binAddr: 0x1000, size: 0x12 }<br>
+      - { sym: __Z4funcv, objAddr: 0x0, binAddr: 0x2000, size: 0x12 }<br>
+      - { sym: __ZZ4funcvENKUlvE_clEv,  objAddr: 0x0, binAddr: 0x3000, size: 0x12 }<br>
+<br>
+# Check that all our types are in the first CU.<br>
+<br>
+# CHECK: TAG_compile_unit<br>
+# CHECK-NOT: {{DW_TAG|NULL}}<br>
+# CHECK: AT_name{{.*}}"odr1.cpp"<br>
+<br>
+# This is "struct S"<br>
+<br>
+# CHECK: 0x[[S:[0-9a-f]*]]:{{.*}}DW_TAG_structure_type<br>
+# CHECK-NEXT: DW_AT_name{{.*}}"S"<br>
+# CHECK-NOT: NULL<br>
+# CHECK: 0x[[NESTED:[0-9a-f]*]]:{{.*}}DW_TAG_structure_type<br>
+# CHECK-NOT: {{DW_TAG|NULL}}<br>
+# CHECK: DW_AT_name{{.*}}"Nested"<br>
+# CHECK: NULL<br>
+# CHECK: DW_TAG_subprogram<br>
+# CHECK: DW_AT_MIPS_linkage_name{{.*}}"_ZN1S4incrEv"<br>
+# CHECK: NULL<br>
+# CHECK: DW_TAG_subprogram<br>
+# CHECK: DW_AT_MIPS_linkage_name{{.*}}"_ZN1S4incrEi"<br>
+# CHECK: NULL<br>
+# CHECK: DW_TAG_subprogram<br>
+# CHECK: DW_AT_MIPS_linkage_name{{.*}}"_ZN1S3fooEv"<br>
+# CHECK: NULL<br>
+# CHECK: NULL<br>
+<br>
+# This is "class N::C"<br>
+<br>
+# CHECK: DW_TAG_namespace<br>
+# CHECK-NEXT: DW_AT_name{{.*}}"N"<br>
+# CHECK-NOT: NULL<br>
+# CHECK: 0x[[NC:[0-9a-f]*]]:{{.*}}DW_TAG_class_type<br>
+# CHECK-NEXT: DW_AT_name{{.*}}"C"<br>
+# CHECK: NULL<br>
+<br>
+# This is "class N::N::C"<br>
+<br>
+# CHECK: DW_TAG_namespace<br>
+# CHECK-NEXT: DW_AT_name{{.*}}"N"<br>
+# CHECK-NOT: NULL<br>
+# CHECK: 0x[[NNC:[0-9a-f]*]]:{{.*}}DW_TAG_class_type<br>
+# CHECK-NEXT: DW_AT_name{{.*}}"C"<br>
+# CHECK: NULL<br>
+# CHECK: NULL<br>
+# CHECK: NULL<br>
+<br>
+# This is "AliasForS"<br>
+# CHECK: 0x[[ALIASFORS:[0-9a-f]*]]:{{.*}}DW_TAG_typedef<br>
+# CHECK-NEXT: DW_AT_type{{.*}}[[S]]<br>
+# CHECK-NEXT: DW_AT_name{{.*}}"AliasForS"<br>
+<br>
+# This is "union U"<br>
+<br>
+# CHECK:  0x[[U:[0-9a-f]*]]:{{.*}}DW_TAG_union_type<br>
+# CHECK-NEXT: DW_AT_name{{.*}}"U"<br>
+# CHECK-NOT: NULL<br>
+# CHECK:  0x[[UC:[0-9a-f]*]]:{{.*}}DW_TAG_class_type<br>
+# CHECK-NOT: NULL<br>
+# CHECK:  0x[[US:[0-9a-f]*]]:{{.*}}DW_TAG_structure_type<br>
+# CHECK: NULL<br>
+<br>
+# This is "func" free function<br>
+<br>
+# CHECK: DW_TAG_subprogram<br>
+# CHECK-NOT: {{DW_TAG|NULL}}<br>
+# CHECK: DW_AT_name{{.*}}"func"<br>
+# CHECK: 0x[[CINSIDEFUNC:[0-9a-f]*]]:{{.*}}DW_TAG_structure_type<br>
+# CHECK-NEXT: DW_AT_name{{.*}}"CInsideFunc"<br>
+<br>
+# This is "(anonymous namespace)::AnonC"<br>
+<br>
+# CHECK: DW_TAG_namespace<br>
+# CHECK-NOT: {{DW_AT_name|NULL|DW_TAG}}<br>
+# CHECK: 0x[[ANONC:[0-9a-f]*]]:{{.*}}DW_TAG_class_type<br>
+# CHECK-NEXT: DW_AT_name{{.*}}"AnonC"<br>
+<br>
+  - filename: odr1.o<br>
+    symbols:<br>
+      - { sym: __Z3foov, objAddr: 0x0, binAddr: 0x4000, size: 0x12 }<br>
+      - { sym: __Z4funcv, objAddr: 0x0, binAddr: 0x5000, size: 0x12 }<br>
+      - { sym: __ZZ4funcvENKUlvE_clEv,  objAddr: 0x0, binAddr: 0x6000, size: 0x12 }<br>
+<br>
+# We relink the same file a second time. In the ODR case, everything (except for the<br>
+# union for now) should be uniqued. In the non-ODR case, we should get every type<br>
+# duplicated.<br>
+<br>
+# CHECK: TAG_compile_unit<br>
+# CHECK-NOT: {{DW_TAG|NULL}}<br>
+# CHECK: AT_name{{.*}}"odr1.cpp"<br>
+<br>
+# ODR: DW_TAG_union_type<br>
+# ODR-NEXT: DW_AT_name{{.*}}"U"<br>
+# Types defined inside the union should be uniqued:<br>
+# ODR: DW_TAG_member<br>
+# ODR-NEXT: DW_AT_name{{.*}}"C"<br>
+# ODR-NOT: {{NULL|DW_TAG}}<br>
+# ODR: DW_AT_type{{.*}}[[UC]]<br>
+# ODR: DW_TAG_member<br>
+# ODR-NEXT: DW_AT_name{{.*}}"S"<br>
+# ODR-NOT: {{NULL|DW_TAG}}<br>
+# ODR: DW_AT_type{{.*}}[[US]]<br>
+<br>
+# Skip func<br>
+# ODR: DW_TAG_subprogram<br>
+# ODR-NOT: {{NULL|DW_TAG}}<br>
+# ODR: DW_AT_name{{.*}}"func"<br>
+# ODR: NULL<br>
+<br>
+# ODR: DW_TAG_subprogram<br>
+# ODR-NOT: {{NULL|DW_TAG}}<br>
+# ODR: DW_AT_name{{.*}}"foo"<br>
+# ODR-NOT: NULL<br>
+# ODR: DW_TAG_variable<br>
+# ODR-NOT: {{DW_TAG|NULL}}<br>
+# ODR: DW_AT_name{{.*}}"s"<br>
+# ODR-NOT: {{DW_TAG|NULL}}<br>
+# ODR: DW_AT_type{{.*}}[[ALIASFORS]]<br>
+# ODR: DW_TAG_variable<br>
+# ODR-NOT: {{DW_TAG|NULL}}<br>
+# ODR: DW_AT_name{{.*}}"nc"<br>
+# ODR-NOT: {{DW_TAG|NULL}}<br>
+# ODR: DW_AT_type{{.*}}[[NC]]<br>
+# ODR: DW_TAG_variable<br>
+# ODR-NOT: {{DW_TAG|NULL}}<br>
+# ODR: DW_AT_name{{.*}}"nnc"<br>
+# ODR-NOT: {{DW_TAG|NULL}}<br>
+# ODR: DW_AT_type{{.*}}[[NNC]]<br>
+# ODR: DW_TAG_variable<br>
+# ODR-NOT: {{DW_TAG|NULL}}<br>
+# ODR: DW_AT_name{{.*}}"ac"<br>
+# ODR-NOT: {{DW_TAG|NULL}}<br>
+# ODR: DW_AT_type{{.*}}[[ANONC]]<br>
+<br>
+# ODR: DW_TAG_subprogram<br>
+# ODR-NOT: {{NULL|DW_TAG}}<br>
+# ODR: linkage_name{{.*}}"_ZZ4funcvENKUlvE_clEv"<br>
+# ODR-NOT: NULL<br>
+# ODR: DW_TAG_variable<br>
+# ODR-NOT: DW_TAG<br>
+# ODR: DW_AT_name{{.*}}"dummy"<br>
+# ODR-NOT: NULL<br>
+# ODR: DW_AT_type{{.*}}[[CINSIDEFUNC]]<br>
+<br>
+# With no ODR uniquing, we should get copies of all the types:<br>
+<br>
+# This is "struct S"<br>
+# NOODR: 0x[[DUP_S:[0-9a-f]*]]:{{.*}}DW_TAG_structure_type<br>
+# NOODR-NEXT: DW_AT_name{{.*}}"S"<br>
+<br>
+# This is "class N::C"<br>
+# NOODR: DW_TAG_namespace<br>
+# NOODR-NEXT: DW_AT_name{{.*}}"N"<br>
+# NOODR: 0x[[DUP_NC:[0-9a-f]*]]:{{.*}}DW_TAG_class_type<br>
+# NOODR-NEXT: DW_AT_name{{.*}}"C"<br>
+<br>
+# This is "class N::N::C"<br>
+# NOODR: DW_TAG_namespace<br>
+# NOODR-NEXT: DW_AT_name{{.*}}"N"<br>
+# NOODR: 0x[[DUP_NNC:[0-9a-f]*]]:{{.*}}DW_TAG_class_type<br>
+# NOODR-NEXT: DW_AT_name{{.*}}"C"<br>
+<br>
+# This is "AliasForS"<br>
+# NOODR: 0x[[DUP_ALIASFORS:[0-9a-f]*]]:{{.*}}DW_TAG_typedef<br>
+# NOODR-NOT: {{NULL|DW_TAG}}<br>
+# NOODR: DW_AT_name{{.*}}"AliasForS"<br>
+<br>
+# This is "union U"<br>
+<br>
+# NOODR:  0x[[U:[0-9a-f]*]]:{{.*}}DW_TAG_union_type<br>
+# NOODR-NEXT: DW_AT_name{{.*}}"U"<br>
+# NOODR-NOT: NULL<br>
+# NOODR:  0x[[DUP_UC:[0-9a-f]*]]:{{.*}}DW_TAG_class_type<br>
+# NOODR-NOT: NULL<br>
+# NOODR:  0x[[DUP_US:[0-9a-f]*]]:{{.*}}DW_TAG_structure_type<br>
+# NOODR: NULL<br>
+<br>
+# This is "func" free function<br>
+<br>
+# NOODR: DW_TAG_subprogram<br>
+# NOODR-NOT: {{DW_TAG|NULL}}<br>
+# NOODR: DW_AT_name{{.*}}"func"<br>
+# NOODR: 0x[[DUP_CINSIDEFUNC:[0-9a-f]*]]:{{.*}}DW_TAG_structure_type<br>
+# NOODR-NEXT: DW_AT_name{{.*}}"CInsideFunc"<br>
+<br>
+# NOODR: DW_TAG_subprogram<br>
+# NOODR-NOT: {{NULL|DW_TAG}}<br>
+# NOODR: DW_AT_name{{.*}}"foo"<br>
+# NOODR-NOT: NULL<br>
+# NOODR: DW_TAG_variable<br>
+# NOODR-NOT: {{DW_TAG|NULL}}<br>
+# NOODR: DW_AT_name{{.*}}"s"<br>
+# NOODR-NOT: {{DW_TAG|NULL}}<br>
+# NOODR: DW_AT_type{{.*}}[[DUP_ALIASFORS]]<br>
+# NOODR: DW_TAG_variable<br>
+# NOODR-NOT: {{DW_TAG|NULL}}<br>
+# NOODR: DW_AT_name{{.*}}"nc"<br>
+# NOODR-NOT: {{DW_TAG|NULL}}<br>
+# NOODR: DW_AT_type{{.*}}[[DUP_NC]]<br>
+# NOODR: DW_TAG_variable<br>
+# NOODR-NOT: {{DW_TAG|NULL}}<br>
+# NOODR: DW_AT_name{{.*}}"nnc"<br>
+# NOODR-NOT: {{DW_TAG|NULL}}<br>
+# NOODR: DW_AT_type{{.*}}[[DUP_NNC]]<br>
+# NOODR: DW_TAG_variable<br>
+# NOODR-NOT: {{DW_TAG|NULL}}<br>
+# NOODR: DW_AT_name{{.*}}"ac"<br>
+# NOODR-NOT: {{DW_TAG|NULL}}<br>
+# NOODR: DW_AT_type{{.*}}0x[[DUP_ANONC:[0-9a-f]*]]<br>
+<br>
+# This is the lanbda inside func<br>
+<br>
+# NOODR: DW_TAG_subprogram<br>
+# NOODR-NOT: {{NULL|DW_TAG}}<br>
+# NOODR: linkage_name{{.*}}"_ZZ4funcvENKUlvE_clEv"<br>
+# NOODR-NOT: NULL<br>
+# NOODR: DW_TAG_variable<br>
+# NOODR-NOT: DW_TAG<br>
+# NOODR: DW_AT_name{{.*}}"dummy"<br>
+# NOODR-NOT: NULL<br>
+# NOODR: DW_AT_type{{.*}}[[DUP_CINSIDEFUNC]]<br>
+<br>
+# This is "(anonymous namespace)::AnonC"<br>
+<br>
+# NOODR: DW_TAG_namespace<br>
+# NOODR-NOT: {{DW_AT_name|NULL|DW_TAG}}<br>
+# NOODR: 0x[[DUP_ANONC]]:{{.*}}DW_TAG_class_type<br>
+# NOODR-NEXT: DW_AT_name{{.*}}"AnonC"<br>
+<br>
+  - filename: odr2.o<br>
+    symbols:<br>
+      - { sym: __ZN1S3fooEv, objAddr: 0x0, binAddr: 0x7000, size: 0x12 }<br>
+      - { sym: __Z3barv, objAddr: 0x0, binAddr: 0x8000, size: 0x12 }<br>
+  - filename: odr3.o<br>
+    symbols:<br>
+      - { sym: __ZN1S3fooEv, objAddr: 0x0, binAddr: 0x8000, size: 0x12 }<br>
+      - { sym: __Z3barv, objAddr: 0x0, binAddr: 0x9000, size: 0x12 }<br>
+<br>
+# odr2.cpp and odr3.cpp test that a simple overloaded function doesn't break the<br>
+# uniquing (contrary to what we'll see with template/artificial) functions.<br>
+<br>
+# CHECK: TAG_compile_unit<br>
+# CHECK-NOT: {{DW_TAG|NULL}}<br>
+# CHECK: AT_name{{.*}}"odr2.cpp"<br>
+<br>
+# NO-ODR: DW_TAG_structure_type<br>
+# ODR-NOT: DW_TAG_structure_type<br>
+<br>
+# ODR: DW_TAG_subprogram<br>
+# ODR: DW_AT_specification{{.*}}4incr<br>
+# ODR: DW_TAG_formal_parameter<br>
+# ODR-NEXT: DW_AT_name{{.*}}"this"<br>
+# ODR-NEXT: DW_AT_type{{.*}}0x00000000[[S_PTR:[0-9a-f]*]]<br>
+# ODR: 0x[[S_PTR]]:{{.*}}DW_TAG_pointer_type<br>
+# ODR-NEXT: DW_AT_type{{.*}}[[S]]<br>
+# ODR: DW_TAG_subprogram<br>
+# ODR-NOT: {{DW_TAG|NULL}}<br>
+# ODR: DW_AT_name{{.*}}"bar"<br>
+# ODR-NOT: NULL<br>
+# ODR: DW_TAG_variable<br>
+# ODR-NOT: {{DW_TAG|NULL}}<br>
+# ODR: DW_AT_type{{.*}}[[S]]<br>
+# ODR-NOT NULL<br>
+# DOR: DW_TAG_inlined_subroutine<br>
+# ODR-NOT NULL<br>
+# ODR: DW_TAG_formal_parameter<br>
+# ODR-NOT {{NULL|DW_TAG}}<br>
+# ODR: DW_AT_type{{.*}}[[S_PTR]]<br>
+<br>
+# CHECK: TAG_compile_unit<br>
+# CHECK-NOT: {{DW_TAG|NULL}}<br>
+# CHECK: AT_name{{.*}}"odr3.cpp"<br>
+<br>
+# NO-ODR: DW_TAG_structure_type<br>
+# ODR-NOT: DW_TAG_structure_type<br>
+<br>
+# ODR: DW_TAG_subprogram<br>
+# ODR: DW_AT_specification{{.*}}4incr<br>
+# ODR: DW_TAG_formal_parameter<br>
+# ODR-NEXT: DW_AT_name{{.*}}"this"<br>
+# ODR-NEXT: DW_AT_type{{.*}}0x00000000[[S_PTR2:[0-9a-f]*]]<br>
+# ODR: 0x[[S_PTR2]]:{{.*}}DW_TAG_pointer_type<br>
+# ODR-NEXT: DW_AT_type{{.*}}[[S]]<br>
+# ODR: DW_TAG_subprogram<br>
+# ODR-NOT: {{DW_TAG|NULL}}<br>
+# ODR: DW_AT_name{{.*}}"bar"<br>
+# ODR-NOT: NULL<br>
+# ODR: DW_TAG_variable<br>
+# ODR-NOT: {{DW_TAG|NULL}}<br>
+# ODR: DW_AT_type{{.*}}[[S]]<br>
+# ODR-NOT NULL<br>
+# DOR: DW_TAG_inlined_subroutine<br>
+# ODR-NOT NULL<br>
+# ODR: DW_TAG_formal_parameter<br>
+# ODR-NOT {{NULL|DW_TAG}}<br>
+# ODR: DW_AT_type{{.*}}[[S_PTR2]]<br>
+<br>
+  - filename: odr4.o<br>
+    symbols:<br>
+      - { sym: __Z3bazv, objAddr: 0x0, binAddr: 0xa000, size: 0x12 }<br>
+<br>
+# odr4.cpp helps check that anonymous namespaces with similarly named contents do<br>
+# not get uniqued.<br>
+<br>
+# CHECK: TAG_compile_unit<br>
+# CHECK-NOT: {{DW_TAG|NULL}}<br>
+# CHECK: AT_name{{.*}}"odr4.cpp"<br>
+<br>
+# CHECK: DW_TAG_subprogram<br>
+# CHECK-NOT: NULL<br>
+# CHECK: DW_TAG_variable<br>
+# CHECK-NOT: DW_TAG<br>
+# ODR: DW_AT_type{{.*}}[[LOCALANONC:........]])<br>
+# NOODR: DW_AT_type{{.*}}[[LOCALANONC:........]]})<br>
+<br>
+# CHECK: DW_TAG_namespace<br>
+# CHECK-NOT: DW_AT_name<br>
+# CHECK: [[LOCALANONC]]{{.*}}DW_TAG_class_type<br>
+# CHECK-NOT: {{NULL|DW_TAG}}<br>
+# CHECK: DW_AT_name{{.*}}"AnonC"<br>
+<br>
+  - filename: odr5.o<br>
+    symbols:<br>
+      - { sym: __Z3bazv, objAddr: 0x0, binAddr: 0xb000, size: 0x12 }<br>
+      - { sym: __ZN1S6Nested4initIiEEvT_, objAddr: 0x0, binAddr: 0xc000, size: 0x12 }<br>
+  - filename: odr6.o<br>
+    symbols:<br>
+      - { sym: __Z3bazv, objAddr: 0x0, binAddr: 0xd000, size: 0x12 }<br>
+      - { sym: __ZN1S6Nested4initIdEEvT_, objAddr: 0x0, binAddr: 0xe000, size: 0x12 }<br>
+<br>
+# odr5.cpp and odr6.cpp instanciate a template member function of the S class.<br>
+# They instanciate it with different types. As DWARF only describes the actual<br>
+# intances, these members aren't described in the uniqued class definition of<br>
+# odr1.cpp. Both these files should contain a new copy of S' definition with<br>
+# the template instance included.<br>
+<br>
+# CHECK: TAG_compile_unit<br>
+# CHECK-NOT: {{DW_TAG|NULL}}<br>
+# CHECK: AT_name{{.*}}"odr5.cpp"<br>
+<br>
+# CHECK: 0x{{[0-9a-f]*}}:{{.*}}DW_TAG_structure_type<br>
+# CHECK-NEXT: DW_AT_name{{.*}}"S"<br>
+# CHECK-NOT: NULL<br>
+# CHECK: 0x[[NESTED2:[0-9a-f]*]]:{{.*}}DW_TAG_structure_type<br>
+# CHECK-NOT: {{DW_TAG|NULL}}<br>
+# CHECK: DW_AT_name{{.*}}"Nested"<br>
+# CHECK-NOT: NULL<br>
+# CHECK: 0x[[INITTEMPLATE:[0-9a-f]*]]:{{.*}}DW_TAG_subprogram<br>
+# CHECK-NEXT:{{.*}}"_ZN1S6Nested4init<br>
+<br>
+# CHECK: DW_AT_specification{{.*}}[[INITTEMPLATE]]<br>
+# CHECK: DW_TAG_formal_parameter<br>
+# CHECK-NOT: DW_TAG<br>
+# CHECK: DW_AT_type{{.*}}[[NESTED_PTR:[0-9a-f]{8}]]{{[}]?}})<br>
+<br>
+# CHECK: 0x[[NESTED_PTR]]{{.*}}DW_TAG_pointer_type<br>
+# ODR-NEXT: DW_AT_type{{.*}}[[NESTED]]<br>
+# NOODR-NEXT: DW_AT_type{{.*}}[[NESTED2]]<br>
+<br>
+# CHECK: TAG_compile_unit<br>
+# CHECK-NOT: {{DW_TAG|NULL}}<br>
+# CHECK: AT_name{{.*}}"odr6.cpp"<br>
+<br>
+# CHECK: 0x{{[0-9a-f]*}}:{{.*}}DW_TAG_structure_type<br>
+# CHECK-NEXT: DW_AT_name{{.*}}"S"<br>
+# CHECK-NOT: NULL<br>
+# CHECK: 0x[[NESTED3:[0-9a-f]*]]:{{.*}}DW_TAG_structure_type<br>
+# CHECK-NOT: {{DW_TAG|NULL}}<br>
+# CHECK: DW_AT_name{{.*}}"Nested"<br>
+# CHECK-NOT: NULL<br>
+# CHECK: 0x[[INITTEMPLATE2:[0-9a-f]*]]:{{.*}}DW_TAG_subprogram<br>
+# CHECK-NEXT:{{.*}}"_ZN1S6Nested4init<br>
+<br>
+# CHECK: DW_AT_specification{{.*}}[[INITTEMPLATE2]]<br>
+# CHECK: DW_TAG_formal_parameter<br>
+# CHECK-NOT: DW_TAG<br>
+# CHECK: DW_AT_type{{.*}}[[NESTED_PTR2:[0-9a-f]{8}]]{{[}]?}})<br>
+<br>
+# CHECK: 0x[[NESTED_PTR2]]{{.*}}DW_TAG_pointer_type<br>
+# ODR-NEXT: DW_AT_type{{.*}}[[NESTED]]<br>
+# NOODR-NEXT: DW_AT_type{{.*}}[[NESTED3]]<br>
+<br>
+  - filename: odr7.o<br>
+    symbols:<br>
+      - { sym: __Z3foov, objAddr: 0x0, binAddr: 0xf000, size: 0x12 }<br>
+<br>
+# Check that a reference to a nested class correctly refers to the original<br>
+# definition<br>
+<br>
+# CHECK: TAG_compile_unit<br>
+# CHECK-NOT: {{DW_TAG|NULL}}<br>
+# CHECK: AT_name{{.*}}"odr7.cpp"<br>
+<br>
+# ODR: DW_TAG_subprogram<br>
+# ODR-NOT: NULL<br>
+# ODR: DW_TAG_variable<br>
+# ODR-NOT: DW_TAG<br>
+# ODR: DW_AT_type{{.*}}[[NESTED]]<br>
+...<br>
+<br>
<br>
Modified: llvm/trunk/tools/dsymutil/DwarfLinker.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_tools_dsymutil_DwarfLinker.cpp-3Frev-3D242847-26r1-3D242846-26r2-3D242847-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=1QVFzUUgkrJKO85G6tEGJHyiS42V4sMPbyVUTS_Gw1w&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfLinker.cpp?rev=242847&r1=242846&r2=242847&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/dsymutil/DwarfLinker.cpp (original)<br>
+++ llvm/trunk/tools/dsymutil/DwarfLinker.cpp Tue Jul 21 17:41:43 2015<br>
@@ -15,6 +15,7 @@<br>
 #include "llvm/ADT/STLExtras.h"<br>
 #include "llvm/CodeGen/AsmPrinter.h"<br>
 #include "llvm/CodeGen/DIE.h"<br>
+#include "llvm/Config/config.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"<br>
@@ -80,6 +81,112 @@ struct PatchLocation {<br>
   }<br>
 };<br>
<br>
+class CompileUnit;<br>
+struct DeclMapInfo;<br>
+class NonRelocatableStringpool;<br>
+<br>
+/// A DeclContext is a named program scope that is used for ODR<br>
+/// uniquing of types.<br>
+/// The set of DeclContext for the ODR-subject parts of a Dwarf link<br>
+/// is expanded (and uniqued) with each new object file processed. We<br>
+/// need to determine the context of each DIE in an linked object file<br>
+/// to see if the corresponding type has already been emitted.<br>
+///<br>
+/// The contexts are conceptually organised as a tree (eg. a function<br>
+/// scope is contained in a namespace scope that contains other<br>
+/// scopes), but storing/accessing them in an actual tree is too<br>
+/// inefficient: we need to be able to very quickly query a context<br>
+/// for a given child context by name. Storing a StringMap in each<br>
+/// DeclContext would be too space inefficient.<br>
+/// The solution here is to give each DeclContext a link to its parent<br>
+/// (this allows to walk up the tree), but to query the existance of a<br>
+/// specific DeclContext using a separate DenseMap keyed on the hash<br>
+/// of the fully qualified name of the context.<br>
+class DeclContext {<br>
+  unsigned QualifiedNameHash;<br>
+  uint32_t Line;<br>
+  uint32_t ByteSize;<br>
+  uint16_t Tag;<br>
+  StringRef Name;<br>
+  StringRef File;<br>
+  const DeclContext &Parent;<br>
+  const DWARFDebugInfoEntryMinimal *LastSeenDIE;<br>
+  uint32_t LastSeenCompileUnitID;<br>
+  uint32_t CanonicalDIEOffset;<br>
+<br>
+  friend DeclMapInfo;<br>
+<br>
+public:<br>
+  typedef DenseSet<DeclContext *, DeclMapInfo> Map;<br>
+<br>
+  DeclContext()<br>
+      : QualifiedNameHash(0), Line(0), ByteSize(0),<br>
+        Tag(dwarf::DW_TAG_compile_unit), Name(), File(), Parent(*this),<br>
+        LastSeenDIE(nullptr), LastSeenCompileUnitID(0), CanonicalDIEOffset(0) {}<br>
+<br>
+  DeclContext(unsigned Hash, uint32_t Line, uint32_t ByteSize, uint16_t Tag,<br>
+              StringRef Name, StringRef File, const DeclContext &Parent,<br>
+              const DWARFDebugInfoEntryMinimal *LastSeenDIE = nullptr,<br>
+              unsigned CUId = 0)<br>
+      : QualifiedNameHash(Hash), Line(Line), ByteSize(ByteSize), Tag(Tag),<br>
+        Name(Name), File(File), Parent(Parent), LastSeenDIE(LastSeenDIE),<br>
+        LastSeenCompileUnitID(CUId), CanonicalDIEOffset(0) {}<br>
+<br>
+  uint32_t getQualifiedNameHash() const { return QualifiedNameHash; }<br>
+<br>
+  bool setLastSeenDIE(CompileUnit &U, const DWARFDebugInfoEntryMinimal *Die);<br>
+<br>
+  uint32_t getCanonicalDIEOffset() const { return CanonicalDIEOffset; }<br>
+  void setCanonicalDIEOffset(uint32_t Offset) { CanonicalDIEOffset = Offset; }<br>
+<br>
+  uint16_t getTag() const { return Tag; }<br>
+  StringRef getName() const { return Name; }<br>
+};<br>
+<br>
+/// Info type for the DenseMap storing the DeclContext pointers.<br>
+struct DeclMapInfo : private DenseMapInfo<DeclContext *> {<br>
+  using DenseMapInfo<DeclContext *>::getEmptyKey;<br>
+  using DenseMapInfo<DeclContext *>::getTombstoneKey;<br>
+<br>
+  static unsigned getHashValue(const DeclContext *Ctxt) {<br>
+    return Ctxt->QualifiedNameHash;<br>
+  }<br>
+<br>
+  static bool isEqual(const DeclContext *LHS, const DeclContext *RHS) {<br>
+    if (RHS == getEmptyKey() || RHS == getTombstoneKey())<br>
+      return RHS == LHS;<br>
+    return LHS->QualifiedNameHash == RHS->QualifiedNameHash &&<br>
+           LHS->Line == RHS->Line && LHS->ByteSize == RHS->ByteSize &&<br>
+           LHS->Name.data() == RHS->Name.data() &&<br>
+           LHS->File.data() == RHS->File.data() &&<br>
+           LHS->Parent.QualifiedNameHash == RHS->Parent.QualifiedNameHash;<br>
+  }<br>
+};<br>
+<br>
+/// This class gives a tree-like API to the DenseMap that stores the<br>
+/// DeclContext objects. It also holds the BumpPtrAllocator where<br>
+/// these objects will be allocated.<br>
+class DeclContextTree {<br>
+  BumpPtrAllocator Allocator;<br>
+  DeclContext Root;<br>
+  DeclContext::Map Contexts;<br>
+<br>
+public:<br>
+  /// Get the child of \a Context described by \a DIE in \a Unit. The<br>
+  /// required strings will be interned in \a StringPool.<br>
+  /// \returns The child DeclContext along with one bit that is set if<br>
+  /// this context is invalid.<br>
+  /// FIXME: the invalid bit along the return value is to emulate some<br>
+  /// dsymutil-classic functionality. See the fucntion definition for<br>
+  /// a more thorough discussion of its use.<br>
+  PointerIntPair<DeclContext *, 1><br>
+  getChildDeclContext(DeclContext &Context,<br>
+                      const DWARFDebugInfoEntryMinimal *DIE, CompileUnit &Unit,<br>
+                      NonRelocatableStringpool &StringPool);<br>
+<br>
+  DeclContext &getRoot() { return Root; }<br>
+};<br>
+<br>
 /// \brief Stores all information relating to a compile unit, be it in<br>
 /// its original instance in the object file to its brand new cloned<br>
 /// and linked DIE tree.<br>
@@ -88,16 +195,26 @@ public:<br>
   /// \brief Information gathered about a DIE in the object file.<br>
   struct DIEInfo {<br>
     int64_t AddrAdjust; ///< Address offset to apply to the described entity.<br>
+    DeclContext *Ctxt;  ///< ODR Declaration context.<br>
     DIE *Clone;         ///< Cloned version of that DIE.<br>
     uint32_t ParentIdx; ///< The index of this DIE's parent.<br>
     bool Keep;          ///< Is the DIE part of the linked output?<br>
     bool InDebugMap;    ///< Was this DIE's entity found in the map?<br>
   };<br>
<br>
-  CompileUnit(DWARFUnit &OrigUnit, unsigned ID)<br>
+  CompileUnit(DWARFUnit &OrigUnit, unsigned ID, bool CanUseODR)<br>
       : OrigUnit(OrigUnit), ID(ID), LowPc(UINT64_MAX), HighPc(0), RangeAlloc(),<br>
         Ranges(RangeAlloc) {<br>
     Info.resize(OrigUnit.getNumDIEs());<br>
+<br>
+    const auto *CUDie = OrigUnit.getUnitDIE(false);<br>
+    unsigned Lang = CUDie->getAttributeValueAsUnsignedConstant(<br>
+        &OrigUnit, dwarf::DW_AT_language, 0);<br>
+    HasODR = CanUseODR && (Lang == dwarf::DW_LANG_C_plus_plus ||<br>
+                           Lang == dwarf::DW_LANG_C_plus_plus_03 ||<br>
+                           Lang == dwarf::DW_LANG_C_plus_plus_11 ||<br>
+                           Lang == dwarf::DW_LANG_C_plus_plus_14 ||<br>
+                           Lang == dwarf::DW_LANG_ObjC_plus_plus);<br>
   }<br>
<br>
   CompileUnit(CompileUnit &&RHS)<br>
@@ -116,6 +233,8 @@ public:<br>
   DIE *getOutputUnitDIE() const { return CUDie; }<br>
   void setOutputUnitDIE(DIE *Die) { CUDie = Die; }<br>
<br>
+  bool hasODR() const { return HasODR; }<br>
+<br>
   DIEInfo &getInfo(unsigned Idx) { return Info[Idx]; }<br>
   const DIEInfo &getInfo(unsigned Idx) const { return Info[Idx]; }<br>
<br>
@@ -147,9 +266,10 @@ public:<br>
<br>
   /// \brief Keep track of a forward reference to DIE \p Die in \p<br>
   /// RefUnit by \p Attr. The attribute should be fixed up later to<br>
-  /// point to the absolute offset of \p Die in the debug_info section.<br>
+  /// point to the absolute offset of \p Die in the debug_info section<br>
+  /// or to the canonical offset of \p Ctxt if it is non-null.<br>
   void noteForwardReference(DIE *Die, const CompileUnit *RefUnit,<br>
-                            PatchLocation Attr);<br>
+                            DeclContext *Ctxt, PatchLocation Attr);<br>
<br>
   /// \brief Apply all fixups recored by noteForwardReference().<br>
   void fixupForwardReferences();<br>
@@ -190,11 +310,27 @@ public:<br>
   const std::vector<AccelInfo> &getPubnames() const { return Pubnames; }<br>
   const std::vector<AccelInfo> &getPubtypes() const { return Pubtypes; }<br>
<br>
+  /// Get the full path for file \a FileNum in the line table<br>
+  const char *getResolvedPath(unsigned FileNum) {<br>
+    if (FileNum >= ResolvedPaths.size())<br>
+      return nullptr;<br>
+    return ResolvedPaths[FileNum].size() ? ResolvedPaths[FileNum].c_str()<br>
+                                         : nullptr;<br>
+  }<br>
+<br>
+  /// Set the fully resolved path for the line-table's file \a FileNum<br>
+  /// to \a Path.<br>
+  void setResolvedPath(unsigned FileNum, const std::string &Path) {<br>
+    if (ResolvedPaths.size() <= FileNum)<br>
+      ResolvedPaths.resize(FileNum + 1);<br>
+    ResolvedPaths[FileNum] = Path;<br>
+  }<br>
+<br>
 private:<br>
   DWARFUnit &OrigUnit;<br>
   unsigned ID;<br>
-  std::vector<DIEInfo> Info;  ///< DIE info indexed by DIE index.<br>
-  DIE *CUDie;                 ///< Root of the linked DIE tree.<br>
+  std::vector<DIEInfo> Info; ///< DIE info indexed by DIE index.<br>
+  DIE *CUDie;                ///< Root of the linked DIE tree.<br>
<br>
   uint64_t StartOffset;<br>
   uint64_t NextUnitOffset;<br>
@@ -208,8 +344,8 @@ private:<br>
   /// The offsets for the attributes in this array couldn't be set while<br>
   /// cloning because for cross-cu forward refences the target DIE's<br>
   /// offset isn't known you emit the reference attribute.<br>
-  std::vector<std::tuple<DIE *, const CompileUnit *, PatchLocation>><br>
-      ForwardDIEReferences;<br>
+  std::vector<std::tuple<DIE *, const CompileUnit *, DeclContext *,<br>
+                         PatchLocation>> ForwardDIEReferences;<br>
<br>
   FunctionIntervals::Allocator RangeAlloc;<br>
   /// \brief The ranges in that interval map are the PC ranges for<br>
@@ -236,6 +372,12 @@ private:<br>
   std::vector<AccelInfo> Pubnames;<br>
   std::vector<AccelInfo> Pubtypes;<br>
   /// @}<br>
+<br>
+  /// Cached resolved paths from the line table.<br>
+  std::vector<std::string> ResolvedPaths;<br>
+<br>
+  /// Is this unit subject to the ODR rule?<br>
+  bool HasODR;<br>
 };<br>
<br>
 uint64_t CompileUnit::computeNextUnitOffset() {<br>
@@ -251,8 +393,8 @@ uint64_t CompileUnit::computeNextUnitOff<br>
 /// \brief Keep track of a forward cross-cu reference from this unit<br>
 /// to \p Die that lives in \p RefUnit.<br>
 void CompileUnit::noteForwardReference(DIE *Die, const CompileUnit *RefUnit,<br>
-                                       PatchLocation Attr) {<br>
-  ForwardDIEReferences.emplace_back(Die, RefUnit, Attr);<br>
+                                       DeclContext *Ctxt, PatchLocation Attr) {<br>
+  ForwardDIEReferences.emplace_back(Die, RefUnit, Ctxt, Attr);<br>
 }<br>
<br>
 /// \brief Apply all fixups recorded by noteForwardReference().<br>
@@ -261,8 +403,12 @@ void CompileUnit::fixupForwardReferences<br>
     DIE *RefDie;<br>
     const CompileUnit *RefUnit;<br>
     PatchLocation Attr;<br>
-    std::tie(RefDie, RefUnit, Attr) = Ref;<br>
-    Attr.set(RefDie->getOffset() + RefUnit->getStartOffset());<br>
+    DeclContext *Ctxt;<br>
+    std::tie(RefDie, RefUnit, Ctxt, Attr) = Ref;<br>
+    if (Ctxt && Ctxt->getCanonicalDIEOffset())<br>
+      Attr.set(Ctxt->getCanonicalDIEOffset());<br>
+    else<br>
+      Attr.set(RefDie->getOffset() + RefUnit->getStartOffset());<br>
   }<br>
 }<br>
<br>
@@ -324,6 +470,12 @@ public:<br>
   /// one.<br>
   uint32_t getStringOffset(StringRef S);<br>
<br>
+  /// \brief Get permanent storage for \p S (but do not necessarily<br>
+  /// emit \p S in the output section).<br>
+  /// \returns The StringRef that points to permanent storage to use<br>
+  /// in place of \p S.<br>
+  StringRef internString(StringRef S);<br>
+<br>
   // \brief Return the first entry of the string table.<br>
   const MapTy::MapEntryTy *getFirstEntry() const {<br>
     return getNextEntry(&Sentinel);<br>
@@ -367,6 +519,16 @@ uint32_t NonRelocatableStringpool::getSt<br>
   return It->getValue().first;<br>
 }<br>
<br>
+/// \brief Put \p S into the StringMap so that it gets permanent<br>
+/// storage, but do not actually link it in the chain of elements<br>
+/// that go into the output section. A latter call to<br>
+/// getStringOffset() with the same string will chain it though.<br>
+StringRef NonRelocatableStringpool::internString(StringRef S) {<br>
+  std::pair<uint32_t, StringMapEntryBase *> Entry(0, nullptr);<br>
+  auto InsertResult = Strings.insert(std::make_pair(S, Entry));<br>
+  return InsertResult.first->getKey();<br>
+};<br>
+<br>
 /// \brief The Dwarf streaming logic<br>
 ///<br>
 /// All interactions with the MC layer that is used to build the debug<br>
@@ -1089,6 +1251,7 @@ private:<br>
     TF_InFunctionScope = 1 << 1, ///< Current scope is a fucntion scope.<br>
     TF_DependencyWalk = 1 << 2,  ///< Walking the dependencies of a kept DIE.<br>
     TF_ParentWalk = 1 << 3,      ///< Walking up the parents of a kept DIE.<br>
+    TF_ODR = 1 << 4,             ///< Use the ODR whhile keeping dependants.<br>
   };<br>
<br>
   /// \brief Mark the passed DIE as well as all the ones it depends on<br>
@@ -1096,7 +1259,7 @@ private:<br>
   void keepDIEAndDenpendencies(const DWARFDebugInfoEntryMinimal &DIE,<br>
                                CompileUnit::DIEInfo &MyInfo,<br>
                                const DebugMapObject &DMO, CompileUnit &CU,<br>
-                               unsigned Flags);<br>
+                               bool UseODR);<br>
<br>
   unsigned shouldKeepDIE(const DWARFDebugInfoEntryMinimal &DIE,<br>
                          CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo,<br>
@@ -1227,11 +1390,14 @@ private:<br>
   BumpPtrAllocator DIEAlloc;<br>
   /// @}<br>
<br>
+  /// ODR Contexts for that link.<br>
+  DeclContextTree ODRContexts;<br>
+<br>
   /// \defgroup Helpers Various helper methods.<br>
   ///<br>
   /// @{<br>
   const DWARFDebugInfoEntryMinimal *<br>
-  resolveDIEReference(DWARFFormValue &RefValue, const DWARFUnit &Unit,<br>
+  resolveDIEReference(const DWARFFormValue &RefValue, const DWARFUnit &Unit,<br>
                       const DWARFDebugInfoEntryMinimal &DIE,<br>
                       CompileUnit *&ReferencedCU);<br>
<br>
@@ -1296,7 +1462,7 @@ CompileUnit *DwarfLinker::getUnitForOffs<br>
 /// CompileUnit which is stored into \p ReferencedCU.<br>
 /// \returns null if resolving fails for any reason.<br>
 const DWARFDebugInfoEntryMinimal *DwarfLinker::resolveDIEReference(<br>
-    DWARFFormValue &RefValue, const DWARFUnit &Unit,<br>
+    const DWARFFormValue &RefValue, const DWARFUnit &Unit,<br>
     const DWARFDebugInfoEntryMinimal &DIE, CompileUnit *&RefCU) {<br>
   assert(RefValue.isFormClass(DWARFFormValue::FC_Reference));<br>
   uint64_t RefOffset = *RefValue.getAsReference(&Unit);<br>
@@ -1309,6 +1475,220 @@ const DWARFDebugInfoEntryMinimal *DwarfL<br>
   return nullptr;<br>
 }<br>
<br>
+/// \returns whether the passed \a Attr type might contain a DIE<br>
+/// reference suitable for ODR uniquing.<br>
+static bool isODRAttribute(uint16_t Attr) {<br>
+  switch (Attr) {<br>
+  default:<br>
+    return false;<br>
+  case dwarf::DW_AT_type:<br>
+  case dwarf::DW_AT_containing_type:<br>
+  case dwarf::DW_AT_specification:<br>
+  case dwarf::DW_AT_abstract_origin:<br>
+  case dwarf::DW_AT_import:<br>
+    return true;<br>
+  }<br>
+  llvm_unreachable("Improper attribute.");<br>
+}<br>
+<br>
+/// Set the last DIE/CU a context was seen in and, possibly invalidate<br>
+/// the context if it is ambiguous.<br>
+///<br>
+/// In the current implementation, we don't handle overloaded<br>
+/// functions well, because the argument types are not taken into<br>
+/// account when computing the DeclContext tree.<br>
+///<br>
+/// Some of this is mitigated byt using mangled names that do contain<br>
+/// the arguments types, but sometimes (eg. with function templates)<br>
+/// we don't have that. In that case, just do not unique anything that<br>
+/// refers to the contexts we are not able to distinguish.<br>
+///<br>
+/// If a context that is not a namespace appears twice in the same CU,<br>
+/// we know it is ambiguous. Make it invalid.<br>
+bool DeclContext::setLastSeenDIE(CompileUnit &U,<br>
+                                 const DWARFDebugInfoEntryMinimal *Die) {<br>
+  if (LastSeenCompileUnitID == U.getUniqueID()) {<br>
+    DWARFUnit &OrigUnit = U.getOrigUnit();<br>
+    uint32_t FirstIdx = OrigUnit.getDIEIndex(LastSeenDIE);<br>
+    U.getInfo(FirstIdx).Ctxt = nullptr;<br>
+    return false;<br>
+  }<br>
+<br>
+  LastSeenCompileUnitID = U.getUniqueID();<br>
+  LastSeenDIE = Die;<br>
+  return true;<br>
+}<br>
+<br>
+/// Get the child context of \a Context corresponding to \a DIE.<br>
+///<br>
+/// \returns the child context or null if we shouldn't track children<br>
+/// contexts. It also returns an additional bit meaning 'invalid'. An<br>
+/// invalid context means it shouldn't be considered for uniquing, but<br>
+/// its not returning null, because some children of that context<br>
+/// might be uniquing candidates.<br>
+/// FIXME: this is for dsymutil-classic compatibility, I don't think<br>
+/// it buys us much.<br>
+PointerIntPair<DeclContext *, 1> DeclContextTree::getChildDeclContext(<br>
+    DeclContext &Context, const DWARFDebugInfoEntryMinimal *DIE, CompileUnit &U,<br>
+    NonRelocatableStringpool &StringPool) {<br>
+  unsigned Tag = DIE->getTag();<br>
+<br>
+  // FIXME: dsymutil-classic compat: We should bail out here if we<br>
+  // have a specification or an abstract_origin. We will get the<br>
+  // parent context wrong here.<br>
+<br>
+  switch (Tag) {<br>
+  default:<br>
+    // By default stop gathering child contexts.<br>
+    return PointerIntPair<DeclContext *, 1>(nullptr);<br>
+  case dwarf::DW_TAG_compile_unit:<br>
+    // FIXME: Add support for DW_TAG_module.<br>
+    return PointerIntPair<DeclContext *, 1>(&Context);<br>
+  case dwarf::DW_TAG_subprogram:<br>
+    // Do not unique anything inside CU local functions.<br>
+    if ((Context.getTag() == dwarf::DW_TAG_namespace ||<br>
+         Context.getTag() == dwarf::DW_TAG_compile_unit) &&<br>
+        !DIE->getAttributeValueAsUnsignedConstant(&U.getOrigUnit(),<br>
+                                                  dwarf::DW_AT_external, 0))<br>
+      return PointerIntPair<DeclContext *, 1>(nullptr);<br>
+  // Fallthrough<br>
+  case dwarf::DW_TAG_member:<br>
+  case dwarf::DW_TAG_namespace:<br>
+  case dwarf::DW_TAG_structure_type:<br>
+  case dwarf::DW_TAG_class_type:<br>
+  case dwarf::DW_TAG_union_type:<br>
+  case dwarf::DW_TAG_enumeration_type:<br>
+  case dwarf::DW_TAG_typedef:<br>
+    // Artificial things might be ambiguous, because they might be<br>
+    // created on demand. For example implicitely defined constructors<br>
+    // are ambiguous because of the way we identify contexts, and they<br>
+    // won't be generated everytime everywhere.<br>
+    if (DIE->getAttributeValueAsUnsignedConstant(&U.getOrigUnit(),<br>
+                                                 dwarf::DW_AT_artificial, 0))<br>
+      return PointerIntPair<DeclContext *, 1>(nullptr);<br>
+    break;<br>
+  }<br>
+<br>
+  const char *Name = DIE->getName(&U.getOrigUnit(), DINameKind::LinkageName);<br>
+  const char *ShortName = DIE->getName(&U.getOrigUnit(), DINameKind::ShortName);<br>
+  StringRef NameRef;<br>
+  StringRef ShortNameRef;<br>
+  StringRef FileRef;<br>
+<br>
+  if (Name)<br>
+    NameRef = StringPool.internString(Name);<br>
+  else if (Tag == dwarf::DW_TAG_namespace)<br>
+    // FIXME: For dsymutil-classic compatibility. I think uniquing<br>
+    // within anonymous namespaces is wrong. There is no ODR guarantee<br>
+    // there.<br>
+    NameRef = StringPool.internString("(anonymous namespace)");<br>
+<br>
+  if (ShortName && ShortName != Name)<br>
+    ShortNameRef = StringPool.internString(ShortName);<br>
+  else<br>
+    ShortNameRef = NameRef;<br>
+<br>
+  if (Tag != dwarf::DW_TAG_class_type && Tag != dwarf::DW_TAG_structure_type &&<br>
+      Tag != dwarf::DW_TAG_union_type &&<br>
+      Tag != dwarf::DW_TAG_enumeration_type && NameRef.empty())<br>
+    return PointerIntPair<DeclContext *, 1>(nullptr);<br>
+<br>
+  std::string File;<br>
+  unsigned Line = 0;<br>
+  unsigned ByteSize = 0;<br>
+<br>
+  // Gather some discriminating data about the DeclContext we will be<br>
+  // creating: File, line number and byte size. This shouldn't be<br>
+  // necessary, because the ODR is just about names, but given that we<br>
+  // do some approximations with overloaded functions and anonymous<br>
+  // namespaces, use these additional data points to make the process safer.<br>
+  ByteSize = DIE->getAttributeValueAsUnsignedConstant(<br>
+      &U.getOrigUnit(), dwarf::DW_AT_byte_size, UINT64_MAX);<br>
+  if (Tag != dwarf::DW_TAG_namespace || !Name) {<br>
+    if (unsigned FileNum = DIE->getAttributeValueAsUnsignedConstant(<br>
+            &U.getOrigUnit(), dwarf::DW_AT_decl_file, 0)) {<br>
+      if (const auto *LT = U.getOrigUnit().getContext().getLineTableForUnit(<br>
+              &U.getOrigUnit())) {<br>
+        // FIXME: dsymutil-classic compatibility. I'd rather not<br>
+        // unique anything in anonymous namespaces, but if we do, then<br>
+        // verify that the file and line correspond.<br>
+        if (!Name && Tag == dwarf::DW_TAG_namespace)<br>
+          FileNum = 1;<br>
+<br>
+        // FIXME: Passing U.getOrigUnit().getCompilationDir()<br>
+        // instead of "" would allow more uniquing, but for now, do<br>
+        // it this way to match dsymutil-classic.<br>
+        if (LT->getFileNameByIndex(<br>
+                FileNum, "",<br>
+                DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,<br>
+                File)) {<br>
+          Line = DIE->getAttributeValueAsUnsignedConstant(<br>
+              &U.getOrigUnit(), dwarf::DW_AT_decl_line, 0);<br>
+#ifdef HAVE_REALPATH<br>
+          // Cache the resolved paths, because calling realpath is expansive.<br>
+          if (const char *ResolvedPath = U.getResolvedPath(FileNum)) {<br>
+            File = ResolvedPath;<br>
+          } else {<br>
+            char RealPath[PATH_MAX + 1];<br>
+            RealPath[PATH_MAX] = 0;<br>
+            if (::realpath(File.c_str(), RealPath))<br>
+              File = RealPath;<br>
+            U.setResolvedPath(FileNum, File);<br>
+          }<br>
+#endif<br>
+          FileRef = StringPool.internString(File);<br>
+        }<br>
+      }<br>
+    }<br>
+  }<br>
+<br>
+  if (!Line && NameRef.empty())<br>
+    return PointerIntPair<DeclContext *, 1>(nullptr);<br>
+<br>
+  // FIXME: dsymutil-classic compat won't unique the same type<br>
+  // presented once as a struct and once as a class. Use the Tag in<br>
+  // the fully qualified name hash to get the same effect.<br>
+  // We hash NameRef, which is the mangled name, in order to get most<br>
+  // overloaded functions resolvec correctly.<br>
+  unsigned Hash = hash_combine(Context.getQualifiedNameHash(), Tag, NameRef);<br>
+<br>
+  // FIXME: dsymutil-classic compatibility: when we don't have a name,<br>
+  // use the filename.<br>
+  if (Tag == dwarf::DW_TAG_namespace && NameRef == "(anonymous namespace)")<br>
+    Hash = hash_combine(Hash, FileRef);<br>
+<br>
+  // Now look if this context already exists.<br>
+  DeclContext Key(Hash, Line, ByteSize, Tag, NameRef, FileRef, Context);<br>
+  auto ContextIter = Contexts.find(&Key);<br>
+<br>
+  if (ContextIter == Contexts.end()) {<br>
+    // The context wasn't found.<br>
+    bool Inserted;<br>
+    DeclContext *NewContext =<br>
+        new (Allocator) DeclContext(Hash, Line, ByteSize, Tag, NameRef, FileRef,<br>
+                                    Context, DIE, U.getUniqueID());<br>
+    std::tie(ContextIter, Inserted) = Contexts.insert(NewContext);<br>
+    assert(Inserted && "Failed to insert DeclContext");<br>
+    (void)Inserted;<br>
+  } else if (Tag != dwarf::DW_TAG_namespace &&<br>
+             !(*ContextIter)->setLastSeenDIE(U, DIE)) {<br>
+    // The context was found, but it is ambiguous with another context<br>
+    // in the same file. Mark it invalid.<br>
+    return PointerIntPair<DeclContext *, 1>(*ContextIter, /* Invalid= */ 1);<br>
+  }<br>
+<br>
+  assert(ContextIter != Contexts.end());<br>
+  // FIXME: dsymutil-classic compatibility. Union types aren't<br>
+  // uniques, but their children might be.<br>
+  if ((Tag == dwarf::DW_TAG_subprogram &&<br>
+       Context.getTag() != dwarf::DW_TAG_structure_type &&<br>
+       Context.getTag() != dwarf::DW_TAG_class_type) ||<br>
+      (Tag == dwarf::DW_TAG_union_type))<br>
+    return PointerIntPair<DeclContext *, 1>(*ContextIter, /* Invalid= */ 1);<br>
+<br>
+  return PointerIntPair<DeclContext *, 1>(*ContextIter);<br>
+}<br>
+<br>
 /// \brief Get the potential name and mangled name for the entity<br>
 /// described by \p Die and store them in \Info if they are not<br>
 /// already there.<br>
@@ -1355,14 +1735,30 @@ bool DwarfLinker::createStreamer(Triple<br>
 /// \brief Recursive helper to gather the child->parent relationships in the<br>
 /// original compile unit.<br>
 static void gatherDIEParents(const DWARFDebugInfoEntryMinimal *DIE,<br>
-                             unsigned ParentIdx, CompileUnit &CU) {<br>
+                             unsigned ParentIdx, CompileUnit &CU,<br>
+                             DeclContext *CurrentDeclContext,<br>
+                             NonRelocatableStringpool &StringPool,<br>
+                             DeclContextTree &Contexts) {<br>
   unsigned MyIdx = CU.getOrigUnit().getDIEIndex(DIE);<br>
-  CU.getInfo(MyIdx).ParentIdx = ParentIdx;<br>
+  CompileUnit::DIEInfo &Info = CU.getInfo(MyIdx);<br>
+<br>
+  Info.ParentIdx = ParentIdx;<br>
+  if (CU.hasODR()) {<br>
+    if (CurrentDeclContext) {<br>
+      auto PtrInvalidPair = Contexts.getChildDeclContext(*CurrentDeclContext,<br>
+                                                         DIE, CU, StringPool);<br>
+      CurrentDeclContext = PtrInvalidPair.getPointer();<br>
+      Info.Ctxt =<br>
+          PtrInvalidPair.getInt() ? nullptr : PtrInvalidPair.getPointer();<br>
+    } else<br>
+      Info.Ctxt = CurrentDeclContext = nullptr;<br>
+  }<br>
<br>
   if (DIE->hasChildren())<br>
     for (auto *Child = DIE->getFirstChild(); Child && !Child->isNULL();<br>
          Child = Child->getSibling())<br>
-      gatherDIEParents(Child, MyIdx, CU);<br>
+      gatherDIEParents(Child, MyIdx, CU, CurrentDeclContext, StringPool,<br>
+                       Contexts);<br>
 }<br>
<br>
 static bool dieNeedsChildrenToBeMeaningful(uint32_t Tag) {<br>
@@ -1380,6 +1776,12 @@ static bool dieNeedsChildrenToBeMeaningf<br>
   llvm_unreachable("Invalid Tag");<br>
 }<br>
<br>
+static unsigned getRefAddrSize(const DWARFUnit &U) {<br>
+  if (U.getVersion() == 2)<br>
+    return U.getAddressByteSize();<br>
+  return 4;<br>
+}<br>
+<br>
 void DwarfLinker::startDebugObject(DWARFContext &Dwarf, DebugMapObject &Obj) {<br>
   Units.reserve(Dwarf.getNumCompileUnits());<br>
   NextValidReloc = 0;<br>
@@ -1686,15 +2088,16 @@ unsigned DwarfLinker::shouldKeepDIE(cons<br>
 void DwarfLinker::keepDIEAndDenpendencies(const DWARFDebugInfoEntryMinimal &DIE,<br>
                                           CompileUnit::DIEInfo &MyInfo,<br>
                                           const DebugMapObject &DMO,<br>
-                                          CompileUnit &CU, unsigned Flags) {<br>
+                                          CompileUnit &CU, bool UseODR) {<br>
   const DWARFUnit &Unit = CU.getOrigUnit();<br>
   MyInfo.Keep = true;<br>
<br>
   // First mark all the parent chain as kept.<br>
   unsigned AncestorIdx = MyInfo.ParentIdx;<br>
   while (!CU.getInfo(AncestorIdx).Keep) {<br>
+    unsigned ODRFlag = UseODR ? TF_ODR : 0;<br>
     lookForDIEsToKeep(*Unit.getDIEAtIndex(AncestorIdx), DMO, CU,<br>
-                      TF_ParentWalk | TF_Keep | TF_DependencyWalk);<br>
+                      TF_ParentWalk | TF_Keep | TF_DependencyWalk | ODRFlag);<br>
     AncestorIdx = CU.getInfo(AncestorIdx).ParentIdx;<br>
   }<br>
<br>
@@ -1715,9 +2118,27 @@ void DwarfLinker::keepDIEAndDenpendencie<br>
<br>
     Val.extractValue(Data, &Offset, &Unit);<br>
     CompileUnit *ReferencedCU;<br>
-    if (const auto *RefDIE = resolveDIEReference(Val, Unit, DIE, ReferencedCU))<br>
+    if (const auto *RefDIE =<br>
+            resolveDIEReference(Val, Unit, DIE, ReferencedCU)) {<br>
+      uint32_t RefIdx = ReferencedCU->getOrigUnit().getDIEIndex(RefDIE);<br>
+      CompileUnit::DIEInfo &Info = ReferencedCU->getInfo(RefIdx);<br>
+      // If the referenced DIE has a DeclContext that has already been<br>
+      // emitted, then do not keep the one in this CU. We'll link to<br>
+      // the canonical DIE in cloneDieReferenceAttribute.<br>
+      // FIXME: compatibility with dsymutil-classic. UseODR shouldn't<br>
+      // be necessary and could be advantageously replaced by<br>
+      // ReferencedCU->hasODR() && CU.hasODR().<br>
+      // FIXME: compatibility with dsymutil-classic. There is no<br>
+      // reason not to unique ref_addr references.<br>
+      if (AttrSpec.Form != dwarf::DW_FORM_ref_addr && UseODR && Info.Ctxt &&<br>
+          Info.Ctxt != ReferencedCU->getInfo(Info.ParentIdx).Ctxt &&<br>
+          Info.Ctxt->getCanonicalDIEOffset() && isODRAttribute(AttrSpec.Attr))<br>
+        continue;<br>
+<br>
+      unsigned ODRFlag = UseODR ? TF_ODR : 0;<br>
       lookForDIEsToKeep(*RefDIE, DMO, *ReferencedCU,<br>
-                        TF_Keep | TF_DependencyWalk);<br>
+                        TF_Keep | TF_DependencyWalk | ODRFlag);<br>
+    }<br>
   }<br>
 }<br>
<br>
@@ -1752,9 +2173,10 @@ void DwarfLinker::lookForDIEsToKeep(cons<br>
     Flags = shouldKeepDIE(DIE, CU, MyInfo, Flags);<br>
<br>
   // If it is a newly kept DIE mark it as well as all its dependencies as kept.<br>
-  if (!AlreadyKept && (Flags & TF_Keep))<br>
-    keepDIEAndDenpendencies(DIE, MyInfo, DMO, CU, Flags);<br>
-<br>
+  if (!AlreadyKept && (Flags & TF_Keep)) {<br>
+    bool UseOdr = (Flags & TF_DependencyWalk) ? (Flags & TF_ODR) : CU.hasODR();<br>
+    keepDIEAndDenpendencies(DIE, MyInfo, DMO, CU, UseOdr);<br>
+  }<br>
   // The TF_ParentWalk flag tells us that we are currently walking up<br>
   // the parent chain of a required DIE, and we don't want to mark all<br>
   // the children of the parents as kept (consider for example a<br>
@@ -1823,24 +2245,34 @@ unsigned DwarfLinker::cloneDieReferenceA<br>
     DIE &Die, const DWARFDebugInfoEntryMinimal &InputDIE,<br>
     AttributeSpec AttrSpec, unsigned AttrSize, const DWARFFormValue &Val,<br>
     CompileUnit &Unit) {<br>
-  uint32_t Ref = *Val.getAsReference(&Unit.getOrigUnit());<br>
+  const DWARFUnit &U = Unit.getOrigUnit();<br>
+  uint32_t Ref = *Val.getAsReference(&U);<br>
   DIE *NewRefDie = nullptr;<br>
   CompileUnit *RefUnit = nullptr;<br>
-  const DWARFDebugInfoEntryMinimal *RefDie = nullptr;<br>
+  DeclContext *Ctxt = nullptr;<br>
<br>
-  if (!(RefUnit = getUnitForOffset(Ref)) ||<br>
-      !(RefDie = RefUnit->getOrigUnit().getDIEForOffset(Ref))) {<br>
-    const char *AttributeString = dwarf::AttributeString(AttrSpec.Attr);<br>
-    if (!AttributeString)<br>
-      AttributeString = "DW_AT_???";<br>
-    reportWarning(Twine("Missing DIE for ref in attribute ") + AttributeString +<br>
-                      ". Dropping.",<br>
-                  &Unit.getOrigUnit(), &InputDIE);<br>
+  const DWARFDebugInfoEntryMinimal *RefDie =<br>
+      resolveDIEReference(Val, U, InputDIE, RefUnit);<br>
+<br>
+  // If the referenced DIE is not found,  drop the attribute.<br>
+  if (!RefDie)<br>
     return 0;<br>
-  }<br>
<br>
   unsigned Idx = RefUnit->getOrigUnit().getDIEIndex(RefDie);<br>
   CompileUnit::DIEInfo &RefInfo = RefUnit->getInfo(Idx);<br>
+<br>
+  // If we already have emitted an equivalent DeclContext, just point<br>
+  // at it.<br>
+  if (isODRAttribute(AttrSpec.Attr)) {<br>
+    Ctxt = RefInfo.Ctxt;<br>
+    if (Ctxt && Ctxt->getCanonicalDIEOffset()) {<br>
+      DIEInteger Attr(Ctxt->getCanonicalDIEOffset());<br>
+      Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),<br>
+                   dwarf::DW_FORM_ref_addr, Attr);<br>
+      return getRefAddrSize(U);<br>
+    }<br>
+  }<br>
+<br>
   if (!RefInfo.Clone) {<br>
     assert(Ref > InputDIE.getOffset());<br>
     // We haven't cloned this DIE yet. Just create an empty one and<br>
@@ -1849,7 +2281,8 @@ unsigned DwarfLinker::cloneDieReferenceA<br>
   }<br>
   NewRefDie = RefInfo.Clone;<br>
<br>
-  if (AttrSpec.Form == dwarf::DW_FORM_ref_addr) {<br>
+  if (AttrSpec.Form == dwarf::DW_FORM_ref_addr ||<br>
+      (Unit.hasODR() && isODRAttribute(AttrSpec.Attr))) {<br>
     // We cannot currently rely on a DIEEntry to emit ref_addr<br>
     // references, because the implementation calls back to DwarfDebug<br>
     // to find the unit offset. (We don't have a DwarfDebug)<br>
@@ -1867,11 +2300,11 @@ unsigned DwarfLinker::cloneDieReferenceA<br>
       // A forward reference. Note and fixup later.<br>
       Attr = 0xBADDEF;<br>
       Unit.noteForwardReference(<br>
-          NewRefDie, RefUnit,<br>
+          NewRefDie, RefUnit, Ctxt,<br>
           Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),<br>
                        dwarf::DW_FORM_ref_addr, DIEInteger(Attr)));<br>
     }<br>
-    return AttrSize;<br>
+    return getRefAddrSize(U);<br>
   }<br>
<br>
   Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),<br>
@@ -2150,6 +2583,14 @@ DIE *DwarfLinker::cloneDIE(const DWARFDe<br>
     Die = Info.Clone = DIE::get(DIEAlloc, dwarf::Tag(InputDIE.getTag()));<br>
   assert(Die->getTag() == InputDIE.getTag());<br>
   Die->setOffset(OutOffset);<br>
+  if (Unit.hasODR() && Die->getTag() != dwarf::DW_TAG_namespace && Info.Ctxt &&<br>
+      Info.Ctxt != Unit.getInfo(Info.ParentIdx).Ctxt &&<br>
+      !Info.Ctxt->getCanonicalDIEOffset()) {<br>
+    // We are about to emit a DIE that is the root of its own valid<br>
+    // DeclContext tree. Make the current offset the canonical offset<br>
+    // for this context.<br>
+    Info.Ctxt->setCanonicalDIEOffset(OutOffset + Unit.getStartOffset());<br>
+  }<br>
<br>
   // Extract and clone every attribute.<br>
   DataExtractor Data = U.getDebugInfoExtractor();<br>
@@ -2611,8 +3052,9 @@ bool DwarfLinker::link(const DebugMap &M<br>
         outs() << "Input compilation unit:";<br>
         CUDie->dump(outs(), CU.get(), 0);<br>
       }<br>
-      Units.emplace_back(*CU, UnitID++);<br>
-      gatherDIEParents(CUDie, 0, Units.back());<br>
+      Units.emplace_back(*CU, UnitID++, !Options.NoODR);<br>
+      gatherDIEParents(CUDie, 0, Units.back(), &ODRContexts.getRoot(),<br>
+                       StringPool, ODRContexts);<br>
     }<br>
<br>
     // Then mark all the DIEs that need to be present in the linked<br>
<br>
Modified: llvm/trunk/tools/dsymutil/dsymutil.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_tools_dsymutil_dsymutil.cpp-3Frev-3D242847-26r1-3D242846-26r2-3D242847-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=KTiYwQSNODI0NhSac9S56i3n3QsVZZFA8xtATBXXHVA&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/dsymutil.cpp?rev=242847&r1=242846&r2=242847&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/dsymutil/dsymutil.cpp (original)<br>
+++ llvm/trunk/tools/dsymutil/dsymutil.cpp Tue Jul 21 17:41:43 2015<br>
@@ -47,6 +47,11 @@ static opt<bool><br>
              desc("Do the link in memory, but do not emit the result file."),<br>
              init(false));<br>
<br>
+static opt<bool><br>
+    NoODR("no-odr",<br>
+          desc("Do not use ODR (One Definition Rule) for type uniquing."),<br>
+          init(false));<br>
+<br>
 static opt<bool> DumpDebugMap(<br>
     "dump-debug-map",<br>
     desc("Parse and dump the debug map to standard output. Not DWARF link "<br>
@@ -71,6 +76,7 @@ int main(int argc, char **argv) {<br>
<br>
   Options.Verbose = Verbose;<br>
   Options.NoOutput = NoOutput;<br>
+  Options.NoODR = NoODR;<br>
<br>
   llvm::InitializeAllTargetInfos();<br>
   llvm::InitializeAllTargetMCs();<br>
<br>
Modified: llvm/trunk/tools/dsymutil/dsymutil.h<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_tools_dsymutil_dsymutil.h-3Frev-3D242847-26r1-3D242846-26r2-3D242847-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=FlQnrG_HGV6P1Dqro0ZHTYtB3F4Cauzn8zdEtqZ7hZs&s=v7GKxdb6INaZRTS952t5t3LVBjr4L2Di9XlgqKcx_78&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/dsymutil.h?rev=242847&r1=242846&r2=242847&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/dsymutil/dsymutil.h (original)<br>
+++ llvm/trunk/tools/dsymutil/dsymutil.h Tue Jul 21 17:41:43 2015<br>
@@ -27,6 +27,7 @@ namespace dsymutil {<br>
 struct LinkOptions {<br>
   bool Verbose;  ///< Verbosity<br>
   bool NoOutput; ///< Skip emitting output<br>
+  bool NoODR;    ///< Do not unique types according to ODR<br>
<br>
   LinkOptions() : Verbose(false), NoOutput(false) {}<br>
 };<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>