This revision was automatically updated to reflect the committed changes.
Closed by commit rL333878: AppleDWARFIndex: Get function method-ness directly 
from debug info (authored by labath, committed by ).
Herald added a subscriber: llvm-commits.

Repository:
  rL LLVM

https://reviews.llvm.org/D47470

Files:
  lldb/trunk/lit/SymbolFile/DWARF/find-method-local-struct.cpp
  lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
  lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
  lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
  lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp

Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -10,15 +10,29 @@
 #include "DWARFDIE.h"
 
 #include "DWARFASTParser.h"
-#include "DWARFUnit.h"
 #include "DWARFDIECollection.h"
 #include "DWARFDebugInfo.h"
-#include "DWARFDeclContext.h"
-
 #include "DWARFDebugInfoEntry.h"
+#include "DWARFDeclContext.h"
+#include "DWARFUnit.h"
 
 using namespace lldb_private;
 
+void DWARFDIE::ElaboratingDIEIterator::Next() {
+  assert(!m_worklist.empty() && "Incrementing end iterator?");
+
+  // Pop the current item from the list.
+  DWARFDIE die = m_worklist.back();
+  m_worklist.pop_back();
+
+  // And add back any items that elaborate it.
+  for (dw_attr_t attr : {DW_AT_specification, DW_AT_abstract_origin}) {
+    if (DWARFDIE d = die.GetReferencedDIE(attr))
+      if (m_seen.insert(die.GetID()).second)
+        m_worklist.push_back(d);
+  }
+}
+
 DWARFDIE
 DWARFDIE::GetParent() const {
   if (IsValid())
@@ -209,12 +223,19 @@
     return DWARFDIE();
 }
 
-bool DWARFDIE::IsStructClassOrUnion() const {
+bool DWARFDIE::IsStructUnionOrClass() const {
   const dw_tag_t tag = Tag();
   return tag == DW_TAG_class_type || tag == DW_TAG_structure_type ||
          tag == DW_TAG_union_type;
 }
 
+bool DWARFDIE::IsMethod() const {
+  for (DWARFDIE d: elaborating_dies())
+    if (d.GetParent().IsStructUnionOrClass())
+      return true;
+  return false;
+}
+
 DWARFDIE
 DWARFDIE::GetContainingDWOModuleDIE() const {
   if (IsValid()) {
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -11,15 +11,20 @@
 #define SymbolFileDWARF_DWARFDIE_h_
 
 #include "DWARFBaseDIE.h"
+#include "llvm/ADT/SmallSet.h"
 
 class DWARFDIE : public DWARFBaseDIE {
 public:
+  class ElaboratingDIEIterator;
+
   using DWARFBaseDIE::DWARFBaseDIE;
 
   //----------------------------------------------------------------------
   // Tests
   //----------------------------------------------------------------------
-  bool IsStructClassOrUnion() const;
+  bool IsStructUnionOrClass() const;
+
+  bool IsMethod() const;
 
   //----------------------------------------------------------------------
   // Accessors
@@ -29,6 +34,8 @@
   DWARFDIE
   GetContainingDWOModuleDIE() const;
 
+  inline llvm::iterator_range<ElaboratingDIEIterator> elaborating_dies() const;
+
   //----------------------------------------------------------------------
   // Accessing information about a DIE
   //----------------------------------------------------------------------
@@ -112,4 +119,58 @@
   lldb_private::CompilerDeclContext GetContainingDeclContext() const;
 };
 
+/// Iterate through all DIEs elaborating (i.e. reachable by a chain of
+/// DW_AT_specification and DW_AT_abstract_origin attributes) a given DIE. For
+/// convenience, the starting die is included in the sequence as the first
+/// item.
+class DWARFDIE::ElaboratingDIEIterator
+    : public std::iterator<std::input_iterator_tag, DWARFDIE> {
+
+  // The operating invariant is: top of m_worklist contains the "current" item
+  // and the rest of the list are items yet to be visited. An empty worklist
+  // means we've reached the end.
+  // Infinite recursion is prevented by maintaining a list of seen DIEs.
+  // Container sizes are optimized for the case of following DW_AT_specification
+  // and DW_AT_abstract_origin just once.
+  llvm::SmallVector<DWARFDIE, 2> m_worklist;
+  llvm::SmallSet<lldb::user_id_t, 3> m_seen;
+
+  void Next();
+
+public:
+  /// An iterator starting at die d.
+  explicit ElaboratingDIEIterator(DWARFDIE d) : m_worklist(1, d) {}
+
+  /// End marker
+  ElaboratingDIEIterator() {}
+
+  const DWARFDIE &operator*() const { return m_worklist.back(); }
+  ElaboratingDIEIterator &operator++() {
+    Next();
+    return *this;
+  }
+  ElaboratingDIEIterator operator++(int) {
+    ElaboratingDIEIterator I = *this;
+    Next();
+    return I;
+  }
+
+  friend bool operator==(const ElaboratingDIEIterator &a,
+                         const ElaboratingDIEIterator &b) {
+    if (a.m_worklist.empty() || b.m_worklist.empty())
+      return a.m_worklist.empty() == b.m_worklist.empty();
+    return a.m_worklist.back() == b.m_worklist.back();
+  }
+  friend bool operator!=(const ElaboratingDIEIterator &a,
+                         const ElaboratingDIEIterator &b) {
+    return !(a == b);
+  }
+};
+
+llvm::iterator_range<DWARFDIE::ElaboratingDIEIterator>
+DWARFDIE::elaborating_dies() const {
+  return llvm::make_range(ElaboratingDIEIterator(*this),
+                          ElaboratingDIEIterator());
+}
+
 #endif // SymbolFileDWARF_DWARFDIE_h_
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
@@ -146,6 +146,14 @@
     m_apple_namespaces_up->FindByName(name.GetStringRef(), offsets);
 }
 
+static bool KeepFunctionDIE(DWARFDIE die, uint32_t name_type_mask) {
+  bool looking_for_methods = name_type_mask & eFunctionNameTypeMethod;
+  bool looking_for_functions = name_type_mask & eFunctionNameTypeBase;
+  if (looking_for_methods && looking_for_functions)
+    return true;
+  return looking_for_methods == die.IsMethod();
+}
+
 void AppleDWARFIndex::GetFunctions(
     ConstString name, DWARFDebugInfo &info,
     llvm::function_ref<bool(const DWARFDIE &die, bool include_inlines,
@@ -228,47 +236,15 @@
         if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die))
           continue; // The containing decl contexts don't match
 
+        if (!KeepFunctionDIE(die, name_type_mask))
+          continue;
+
+        if (resolved_dies.find(die.GetDIE()) != resolved_dies.end())
+          continue;
+
         // If we get to here, the die is good, and we should add it:
-        if (resolved_dies.find(die.GetDIE()) == resolved_dies.end() &&
-            resolve_function(die, include_inlines, sc_list)) {
-          bool keep_die = true;
-          if ((name_type_mask &
-               (eFunctionNameTypeBase | eFunctionNameTypeMethod)) !=
-              (eFunctionNameTypeBase | eFunctionNameTypeMethod)) {
-            // We are looking for either basenames or methods, so we need
-            // to trim out the ones we won't want by looking at the type
-            SymbolContext sc;
-            if (sc_list.GetLastContext(sc)) {
-              if (sc.block) {
-                // We have an inlined function
-              } else if (sc.function) {
-                Type *type = sc.function->GetType();
-
-                if (type) {
-                  CompilerDeclContext decl_ctx =
-                      get_decl_context_containing_uid(type->GetID());
-                  if (decl_ctx.IsStructUnionOrClass()) {
-                    if (name_type_mask & eFunctionNameTypeBase) {
-                      sc_list.RemoveContextAtIndex(sc_list.GetSize() - 1);
-                      keep_die = false;
-                    }
-                  } else {
-                    if (name_type_mask & eFunctionNameTypeMethod) {
-                      sc_list.RemoveContextAtIndex(sc_list.GetSize() - 1);
-                      keep_die = false;
-                    }
-                  }
-                } else {
-                  m_module.ReportWarning(
-                      "function at die offset 0x%8.8x had no function type",
-                      die_ref.die_offset);
-                }
-              }
-            }
-          }
-          if (keep_die)
-            resolved_dies.insert(die.GetDIE());
-        }
+        if (resolve_function(die, include_inlines, sc_list))
+          resolved_dies.insert(die.GetDIE());
       } else
         ReportInvalidDIEOffset(die_ref.die_offset, name.GetStringRef());
     }
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
@@ -288,22 +288,7 @@
           }
           // If we have a mangled name, then the DW_AT_name attribute is
           // usually the method name without the class or any parameters
-          const DWARFDebugInfoEntry *parent = die.GetParent();
-          bool is_method = false;
-          if (parent) {
-            DWARFDIE parent_die(&unit, parent);
-            if (parent_die.IsStructClassOrUnion())
-              is_method = true;
-            else {
-              if (specification_die_form.IsValid()) {
-                DWARFDIE specification_die =
-                    unit.GetSymbolFileDWARF()->DebugInfo()->GetDIE(
-                        DIERef(specification_die_form));
-                if (specification_die.GetParent().IsStructClassOrUnion())
-                  is_method = true;
-              }
-            }
-          }
+          bool is_method = DWARFDIE(&unit, &die).IsMethod();
 
           if (is_method)
             set.function_methods.Insert(ConstString(name),
Index: lldb/trunk/lit/SymbolFile/DWARF/find-method-local-struct.cpp
===================================================================
--- lldb/trunk/lit/SymbolFile/DWARF/find-method-local-struct.cpp
+++ lldb/trunk/lit/SymbolFile/DWARF/find-method-local-struct.cpp
@@ -1,6 +1,3 @@
-// llvm.org/pr37537
-// XFAIL: *
-
 // RUN: clang %s -g -c -o %t --target=x86_64-apple-macosx
 // RUN: lldb-test symbols --name=foo --find=function --function-flags=method %t | \
 // RUN:   FileCheck %s
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to