Improve behavior of DebugInfoEntryMinimal::getSubprogramName() introduced in r159512.
authorAlexey Samsonov <samsonov@google.com>
Tue, 17 Jul 2012 15:28:35 +0000 (15:28 +0000)
committerAlexey Samsonov <samsonov@google.com>
Tue, 17 Jul 2012 15:28:35 +0000 (15:28 +0000)
To fetch a subprogram name we should not only inspect the DIE for this subprogram, but optionally inspect
its specification, or its abstract origin (even if there is no inlining), or even specification of an abstract origin.

Reviewed by Benjamin Kramer.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160365 91177308-0d34-0410-b5e6-96231b3b80d8

lib/DebugInfo/DWARFContext.cpp
lib/DebugInfo/DWARFDebugInfoEntry.cpp
lib/DebugInfo/DWARFDebugInfoEntry.h
test/DebugInfo/Inputs/dwarfdump-test3.elf-x86-64 [new file with mode: 0755]
test/DebugInfo/dwarfdump-test.test
test/DebugInfo/lit.local.cfg

index 6be230e73a537fc792c52214afaa8c89658b2373..08e5db22067ed6294df6730e4dae9a30f32c3ded 100644 (file)
@@ -155,8 +155,10 @@ DILineInfo DWARFContext::getLineInfoForAddress(uint64_t address,
   if (specifier.needs(DILineInfoSpecifier::FunctionName)) {
     const DWARFDebugInfoEntryMinimal *function_die =
         cu->getFunctionDIEForAddress(address);
-    if (function_die)
-      functionName = function_die->getSubprogramName(cu);
+    if (function_die) {
+      if (const char *name = function_die->getSubprogramName(cu))
+        functionName = name;
+    }
   }
   if (specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
     // Get the line table for this compile unit.
index 1024b452551d91b3f723fc23eb14f07944527f5a..429a36c0871e095011cb7dac1c4d098f55eafa6b 100644 (file)
@@ -456,35 +456,38 @@ DWARFDebugInfoEntryMinimal::addressRangeContainsAddress(
   return false;
 }
 
-static inline const char*
-getSubprogramNameFromDie(const DWARFCompileUnit *cu,
-                         const DWARFDebugInfoEntryMinimal *die) {
-  const char *result = 0;
-  if (!die->isNULL() && die->getTag() == DW_TAG_subprogram) {
-    // Try to get mangled name if possible.
-    result = die->getAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, 0);
-    if (result == 0)
-      result = die->getAttributeValueAsString(cu, DW_AT_linkage_name, 0);
-    if (result == 0)
-      result = die->getAttributeValueAsString(cu, DW_AT_name, 0);
-  }
-  return result;
-}
-
 const char*
 DWARFDebugInfoEntryMinimal::getSubprogramName(
     const DWARFCompileUnit *cu) const {
   if (isNULL() || getTag() != DW_TAG_subprogram)
     return 0;
-  const char *name = getSubprogramNameFromDie(cu, this);
-  if (name == 0) {
-    // Try to get name from specification DIE.
-    uint32_t ref = getAttributeValueAsReference(cu, DW_AT_specification, -1U);
-    if (ref != -1U) {
-      DWARFDebugInfoEntryMinimal spec_die;
-      if (spec_die.extract(cu, &ref))
-        name = getSubprogramNameFromDie(cu, &spec_die);
+  // Try to get mangled name if possible.
+  if (const char *name =
+      getAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, 0))
+    return name;
+  if (const char *name = getAttributeValueAsString(cu, DW_AT_linkage_name, 0))
+    return name;
+  if (const char *name = getAttributeValueAsString(cu, DW_AT_name, 0))
+    return name;
+  // Try to get name from specification DIE.
+  uint32_t spec_ref =
+      getAttributeValueAsReference(cu, DW_AT_specification, -1U);
+  if (spec_ref != -1U) {
+    DWARFDebugInfoEntryMinimal spec_die;
+    if (spec_die.extract(cu, &spec_ref)) {
+      if (const char *name = spec_die.getSubprogramName(cu))
+        return name;
     }
   }
-  return name;
+  // Try to get name from abstract origin DIE.
+  uint32_t abs_origin_ref =
+      getAttributeValueAsReference(cu, DW_AT_abstract_origin, -1U);
+  if (abs_origin_ref != -1U) {
+    DWARFDebugInfoEntryMinimal abs_origin_die;
+    if (abs_origin_die.extract(cu, &abs_origin_ref)) {
+      if (const char *name = abs_origin_die.getSubprogramName(cu))
+        return name;
+    }
+  }
+  return 0;
 }
index 1a040a53a386ffd869521e272cfd2d24f4f80c31..d5d86b9ec0c1a52aae4aafc5c258a8de02759ac3 100644 (file)
@@ -132,8 +132,10 @@ public:
   bool addressRangeContainsAddress(const DWARFCompileUnit *cu,
                                    const uint64_t address) const;
 
-  // If a DIE represents a subroutine, returns its mangled name
-  // (or short name, if mangled is missing). Otherwise returns null.
+  // If a DIE represents a subprogram, returns its mangled name
+  // (or short name, if mangled is missing). This name may be fetched
+  // from specification or abstract origin for this subprogram.
+  // Returns null if no name is found.
   const char* getSubprogramName(const DWARFCompileUnit *cu) const;
 };
 
diff --git a/test/DebugInfo/Inputs/dwarfdump-test3.elf-x86-64 b/test/DebugInfo/Inputs/dwarfdump-test3.elf-x86-64
new file mode 100755 (executable)
index 0000000..fb3ca03
Binary files /dev/null and b/test/DebugInfo/Inputs/dwarfdump-test3.elf-x86-64 differ
index 84fe7f3ec82e09a17f90085ad6ab7a24d37fb314..7b01e382688e145fe07234a9b108c3873e353143 100644 (file)
@@ -8,6 +8,8 @@ RUN: llvm-dwarfdump %p/Inputs/dwarfdump-test2.elf-x86-64 \
 RUN:   --address=0x4004b8 --functions | FileCheck %s -check-prefix MANY_CU_1
 RUN: llvm-dwarfdump %p/Inputs/dwarfdump-test2.elf-x86-64 \
 RUN:   --address=0x4004c4 --functions | FileCheck %s -check-prefix MANY_CU_2
+RUN: llvm-dwarfdump %p/Inputs/dwarfdump-test3.elf-x86-64 \
+RUN:   --address=0x538 --functions | FileCheck %s -check-prefix ABS_ORIGIN_1
 
 MAIN: main
 MAIN-NEXT: dwarfdump-test.cc:16:10
@@ -23,3 +25,6 @@ MANY_CU_1-NEXT: a.cc:2:0
 
 MANY_CU_2: main
 MANY_CU_2-NEXT: main.cc:4:0
+
+ABS_ORIGIN_1: C
+ABS_ORIGIN_1-NEXT: def.cc:3:0
index 19eebc0ac7ac345747856190cdcccb57bf60eec6..00bd9b83b52500f554b8df77e0bfa0fd1da7edbb 100644 (file)
@@ -1 +1 @@
-config.suffixes = ['.ll', '.c', '.cpp']
+config.suffixes = ['.ll', '.c', '.cpp', '.test']