Index: include/llvm/DebugInfo/DWARF/DWARFDie.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFDie.h +++ include/llvm/DebugInfo/DWARF/DWARFDie.h @@ -247,8 +247,10 @@ /// DW_AT_call_line attribute in this DIE. /// \param CallColumn filled in with non-zero if successful, zero if there is /// no DW_AT_call_column attribute in this DIE. + /// \param CallDiscriminator filled in with non-zero if successful, zero if + /// there is no DW_AT_GNU_discriminator attribute in this DIE. void getCallerFrame(uint32_t &CallFile, uint32_t &CallLine, - uint32_t &CallColumn) const; + uint32_t &CallColumn, uint32_t &CallDiscriminator) const; /// Get inlined chain for a given address, rooted at the current DIE. /// Returns empty chain if address is not contained in address range Index: lib/DebugInfo/DWARF/DWARFContext.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFContext.cpp +++ lib/DebugInfo/DWARF/DWARFContext.cpp @@ -579,7 +579,7 @@ return InliningInfo; } - uint32_t CallFile = 0, CallLine = 0, CallColumn = 0; + uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0; for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) { DWARFDie &FunctionDIE = InlinedChain[i]; DILineInfo Frame; @@ -605,10 +605,12 @@ Spec.FLIKind, Frame.FileName); Frame.Line = CallLine; Frame.Column = CallColumn; + Frame.Discriminator = CallDiscriminator; } // Get call file/line/column of a current DIE. if (i + 1 < n) { - FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn); + FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn, + CallDiscriminator); } } InliningInfo.addFrame(Frame); Index: lib/DebugInfo/DWARF/DWARFDie.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFDie.cpp +++ lib/DebugInfo/DWARF/DWARFDie.cpp @@ -290,10 +290,12 @@ } void DWARFDie::getCallerFrame(uint32_t &CallFile, uint32_t &CallLine, - uint32_t &CallColumn) const { + uint32_t &CallColumn, + uint32_t &CallDiscriminator) const { CallFile = toUnsigned(find(DW_AT_call_file), 0); CallLine = toUnsigned(find(DW_AT_call_line), 0); CallColumn = toUnsigned(find(DW_AT_call_column), 0); + CallDiscriminator = toUnsigned(find(DW_AT_GNU_discriminator), 0); } void DWARFDie::dump(raw_ostream &OS, unsigned RecurseDepth, Index: test/tools/llvm-symbolizer/Inputs/discrim.c =================================================================== --- test/tools/llvm-symbolizer/Inputs/discrim.c +++ test/tools/llvm-symbolizer/Inputs/discrim.c @@ -1,8 +1,11 @@ static volatile int do_mul; -static volatile int do_inc; +static volatile int x, v; -int main () { - int x = 1; - if (do_mul) x *= 2; else x /= 2; - return do_inc ? ++x : --x; +int foo () { + if (do_mul) x *= v; else x /= v; + return x; +} + +int main() { + return foo() + foo(); } Index: test/tools/llvm-symbolizer/Inputs/discrim.inp =================================================================== --- test/tools/llvm-symbolizer/Inputs/discrim.inp +++ test/tools/llvm-symbolizer/Inputs/discrim.inp @@ -1,5 +1,8 @@ some text -0x4004f2 -0x400509 -0x40050d +0x400590 +0x4005a5 +0x4005ad +0x4005b9 +0x4005ce +0x4005d4 some more text Index: test/tools/llvm-symbolizer/sym-verbose.test =================================================================== --- test/tools/llvm-symbolizer/sym-verbose.test +++ test/tools/llvm-symbolizer/sym-verbose.test @@ -1,39 +1,97 @@ #static volatile int do_mul; -#static volatile int do_inc; +#static volatile int x, v; # -#int main () { -# int x = 1; -# if (do_mul) x *= 2; else x /= 2; -# return do_inc ? ++x : --x; +#int foo () { +# if (do_mul) x *= v; else x /= v; +# return x; #} -#Build as : clang -g -O2 discrim.c -o discrim +# +#int main() { +# return foo() + foo(); +#} +#Build as : clang -gmlt -fdebug-info-for-profiling -O2 discrim.c -o discrim RUN: llvm-symbolizer -verbose -print-address -obj=%p/Inputs/discrim < %p/Inputs/discrim.inp | FileCheck %s #CHECK: some text -#CHECK: 0x4004f2 +#CHECK: 0x400590 +#CHECK-NEXT: foo +#CHECK-NEXT: Filename: /tmp/discrim.c +#CHECK-NEXT: Function start line: 4 +#CHECK-NEXT: Line: 9 +#CHECK-NEXT: Column: 0 #CHECK-NEXT: main -#CHECK-NEXT: Filename: /tmp{{[\\/]}}discrim.c +#CHECK-NEXT: Filename: /tmp/discrim.c +#CHECK-NEXT: Function start line: 9 +#CHECK-NEXT: Line: 10 +#CHECK-NEXT: Column: 0 + +#CHECK: 0x4005a5 +#CHECK-NEXT: foo +#CHECK-NEXT: Filename: /tmp/discrim.c #CHECK-NEXT: Function start line: 4 -#CHECK-NEXT: Line: 6 -#CHECK-NEXT: Column: 7 -#CHECK-NOT: Discriminator: 0 - -#CHECK: 0x400509 +#CHECK-NEXT: Line: 5 +#CHECK-NEXT: Column: 17 +#CHECK-NEXT: Discriminator: 2 +#CHECK-NEXT: main +#CHECK-NEXT: Filename: /tmp/discrim.c +#CHECK-NEXT: Function start line: 9 +#CHECK-NEXT: Line: 10 +#CHECK-NEXT: Column: 0 + +#CHECK: 0x4005ad +#CHECK-NEXT: foo +#CHECK-NEXT: Filename: /tmp/discrim.c +#CHECK-NEXT: Function start line: 4 +#CHECK-NEXT: Line: 0 +#CHECK-NEXT: Column: 30 +#CHECK-NEXT: Discriminator: 4 #CHECK-NEXT: main -#CHECK-NEXT: Filename: /tmp{{[\\/]}}discrim.c +#CHECK-NEXT: Filename: /tmp/discrim.c +#CHECK-NEXT: Function start line: 9 +#CHECK-NEXT: Line: 10 +#CHECK-NEXT: Column: 0 + +#CHECK: 0x4005b9 +#CHECK-NEXT: foo +#CHECK-NEXT: Filename: /tmp/discrim.c #CHECK-NEXT: Function start line: 4 -#CHECK-NEXT: Line: 7 -#CHECK-NEXT: Column: 3 -#CHECK-NEXT: Discriminator: 1 +#CHECK-NEXT: Line: 5 +#CHECK-NEXT: Column: 7 +#CHECK-NEXT: main +#CHECK-NEXT: Filename: /tmp/discrim.c +#CHECK-NEXT: Function start line: 9 +#CHECK-NEXT: Line: 10 +#CHECK-NEXT: Column: 0 +#CHECK-NEXT: Discriminator: 2 -#CHECK: 0x40050d +#CHECK: 0x4005ce +#CHECK-NEXT: foo +#CHECK-NEXT: Filename: /tmp/discrim.c +#CHECK-NEXT: Function start line: 4 +#CHECK-NEXT: Line: 5 +#CHECK-NEXT: Column: 17 +#CHECK-NEXT: Discriminator: 2 #CHECK-NEXT: main -#CHECK-NEXT: Filename: /tmp{{[\\/]}}discrim.c +#CHECK-NEXT: Filename: /tmp/discrim.c +#CHECK-NEXT: Function start line: 9 +#CHECK-NEXT: Line: 10 +#CHECK-NEXT: Column: 0 +#CHECK-NEXT: Discriminator: 2 + +#CHECK: 0x4005d4 +#CHECK-NEXT: foo +#CHECK-NEXT: Filename: /tmp/discrim.c #CHECK-NEXT: Function start line: 4 -#CHECK-NEXT: Line: 7 -#CHECK-NEXT: Column: 3 +#CHECK-NEXT: Line: 5 +#CHECK-NEXT: Column: 30 +#CHECK-NEXT: Discriminator: 4 +#CHECK-NEXT: main +#CHECK-NEXT: Filename: /tmp/discrim.c +#CHECK-NEXT: Function start line: 9 +#CHECK-NEXT: Line: 10 +#CHECK-NEXT: Column: 0 #CHECK-NEXT: Discriminator: 2 #CHECK: some more text