labath updated this revision to Diff 149253.
labath added a comment.

Implement recursive search in IsMethod()


https://reviews.llvm.org/D47470

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

Index: source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
+++ 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: source/Plugins/SymbolFile/DWARF/DWARFDIE.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -19,7 +19,9 @@
   //----------------------------------------------------------------------
   // Tests
   //----------------------------------------------------------------------
-  bool IsStructClassOrUnion() const;
+  bool IsStructUnionOrClass() const;
+
+  bool IsMethod() const;
 
   //----------------------------------------------------------------------
   // Accessors
Index: source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -10,12 +10,12 @@
 #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"
+#include "llvm/ADT/SmallSet.h"
 
 using namespace lldb_private;
 
@@ -209,12 +209,37 @@
     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 {
+  // Prevent infinite recursion 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> worklist(1, *this);
+  llvm::SmallSet<lldb::user_id_t, 3> seen;
+
+  while (!worklist.empty()) {
+    DWARFDIE die = worklist.back();
+    worklist.pop_back();
+    if (!seen.insert(die.GetID()).second)
+      continue;
+
+    DWARFDIE parent = die.GetParent();
+    if (parent.IsStructUnionOrClass())
+      return true;
+
+    if (DWARFDIE d = die.GetReferencedDIE(DW_AT_specification))
+      worklist.push_back(d);
+    if (DWARFDIE d = die.GetReferencedDIE(DW_AT_abstract_origin))
+      worklist.push_back(d);
+  }
+  return false;
+}
+
 DWARFDIE
 DWARFDIE::GetContainingDWOModuleDIE() const {
   if (IsValid()) {
Index: source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
+++ 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: lit/SymbolFile/DWARF/find-method-local-struct.cpp
===================================================================
--- lit/SymbolFile/DWARF/find-method-local-struct.cpp
+++ 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