zequanwu updated this revision to Diff 392932.
zequanwu added a comment.

I found that is actually a problem in TypeList. We need to uniquify Type in
TypeList.

- Use an additional set of `Type*` to check if it exists or not.
- Print number of types in TypeList.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115308/new/

https://reviews.llvm.org/D115308

Files:
  lldb/include/lldb/Symbol/TypeList.h
  lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  lldb/source/Symbol/SymbolFile.cpp
  lldb/source/Symbol/TypeList.cpp
  lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-line-tables.s
  lldb/test/Shell/SymbolFile/DWARF/x86/dump-types.cpp
  lldb/test/Shell/SymbolFile/NativePDB/load-pdb.cpp

Index: lldb/test/Shell/SymbolFile/NativePDB/load-pdb.cpp
===================================================================
--- lldb/test/Shell/SymbolFile/NativePDB/load-pdb.cpp
+++ lldb/test/Shell/SymbolFile/NativePDB/load-pdb.cpp
@@ -24,7 +24,7 @@
 // CHECK: (lldb) b main
 // CHECK: Breakpoint 1: where = foo.exe`main + 21 at load-pdb.cpp:19, address = 0x0000000140001015
 // CHECK: (lldb) image dump symfile
-// CHECK: Types:
+// CHECK: Found 1 types:
 // CHECK: {{.*}}: Type{0x00010024} , size = 0, compiler_type = {{.*}} int (int, char **)
 // CHECK: Compile units:
 // CHECK: {{.*}}: CompileUnit{0x00000000}, language = "c++", file = '{{.*}}load-pdb.cpp'
Index: lldb/test/Shell/SymbolFile/DWARF/x86/dump-types.cpp
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/DWARF/x86/dump-types.cpp
@@ -0,0 +1,47 @@
+// REQUIRES: lld
+
+// RUN: %clang %s -g -c -o %t.o --target=x86_64-pc-linux -gno-pubnames
+// RUN: ld.lld %t.o -o %t
+// RUN: lldb-test symbols --find=none %t | FileCheck %s
+
+// RUN: %clang %s -g -c -o %t --target=x86_64-apple-macosx
+// RUN: lldb-test symbols --find=none %t | FileCheck %s
+
+// RUN: %clang %s -c -o %t.o --target=x86_64-pc-linux -gdwarf-5 -gpubnames
+// RUN: ld.lld %t.o -o %t
+// RUN: llvm-readobj --sections %t | FileCheck %s --check-prefix NAMES
+// RUN: lldb-test symbols --find=none %t | FileCheck %s
+
+// NAMES: Name: .debug_names
+
+struct foo {};
+
+namespace bar {
+int context;
+struct foo {};
+
+namespace baz {
+struct foo {};
+
+} // namespace baz
+} // namespace bar
+
+struct sbar {
+  struct foo {};
+};
+
+struct foobar {};
+
+struct Foo {};
+
+extern "C" void _start(foo, bar::foo, bar::baz::foo, sbar::foo, foobar, Foo) {}
+
+// CHECK:     Found 8 types:
+// CHECK-DAG: name = "foo", size = 1, decl = dump-types.cpp:17
+// CHECK-DAG: name = "foo", size = 1, decl = dump-types.cpp:21
+// CHECK-DAG: name = "foo", size = 1, decl = dump-types.cpp:24
+// CHECK-DAG: name = "sbar", size = 1, decl = dump-types.cpp:29
+// CHECK-DAG: name = "foo", size = 1, decl = dump-types.cpp:30
+// CHECK-DAG: name = "foobar", size = 1, decl = dump-types.cpp:33
+// CHECK-DAG: name = "Foo", size = 1, decl = dump-types.cpp:35
+// CHECK-DAG: name = "int", size = 4
Index: lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-line-tables.s
===================================================================
--- lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-line-tables.s
+++ lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-line-tables.s
@@ -5,7 +5,7 @@
 
         .section        .debug_types,"",@progbits
 
-# CHECK: Types:
+# CHECK: Found 5 types:
 # Type unit one: "struct A" defined at b.cc:1
 # CHECK-DAG: name = "A", size = 4, decl = b.cc:1
 1:
Index: lldb/source/Symbol/TypeList.cpp
===================================================================
--- lldb/source/Symbol/TypeList.cpp
+++ lldb/source/Symbol/TypeList.cpp
@@ -24,12 +24,7 @@
 // Destructor
 TypeList::~TypeList() = default;
 
-void TypeList::Insert(const TypeSP &type_sp) {
-  // Just push each type on the back for now. We will worry about uniquing
-  // later
-  if (type_sp)
-    m_types.push_back(type_sp);
-}
+void TypeList::Insert(const TypeSP &type_sp) { m_types.Insert(type_sp); }
 
 // Find a base type by its unique ID.
 // TypeSP
@@ -55,9 +50,9 @@
 //    return types;
 //}
 
-void TypeList::Clear() { m_types.clear(); }
+void TypeList::Clear() { m_types.Clear(); }
 
-uint32_t TypeList::GetSize() const { return m_types.size(); }
+uint32_t TypeList::GetSize() const { return m_types.Types().size(); }
 
 // GetTypeAtIndex isn't used a lot for large type lists, currently only for
 // type lists that are returned for "image dump -t TYPENAME" commands and other
@@ -67,7 +62,7 @@
   iterator pos, end;
   uint32_t i = idx;
   assert(i < GetSize() && "Accessing past the end of a TypeList");
-  for (pos = m_types.begin(), end = m_types.end(); pos != end; ++pos) {
+  for (pos = m_types.Begin(), end = m_types.End(); pos != end; ++pos) {
     if (i == 0)
       return *pos;
     --i;
@@ -77,7 +72,7 @@
 
 void TypeList::ForEach(
     std::function<bool(const lldb::TypeSP &type_sp)> const &callback) const {
-  for (auto pos = m_types.begin(), end = m_types.end(); pos != end; ++pos) {
+  for (auto pos = m_types.Begin(), end = m_types.End(); pos != end; ++pos) {
     if (!callback(*pos))
       break;
   }
@@ -85,14 +80,14 @@
 
 void TypeList::ForEach(
     std::function<bool(lldb::TypeSP &type_sp)> const &callback) {
-  for (auto pos = m_types.begin(), end = m_types.end(); pos != end; ++pos) {
+  for (auto pos = m_types.Begin(), end = m_types.End(); pos != end; ++pos) {
     if (!callback(*pos))
       break;
   }
 }
 
 void TypeList::Dump(Stream *s, bool show_context) {
-  for (iterator pos = m_types.begin(), end = m_types.end(); pos != end; ++pos) {
+  for (iterator pos = m_types.Begin(), end = m_types.End(); pos != end; ++pos) {
     pos->get()->Dump(s, show_context);
   }
 }
@@ -115,15 +110,9 @@
 void TypeList::RemoveMismatchedTypes(const std::string &type_scope,
                                      const std::string &type_basename,
                                      TypeClass type_class, bool exact_match) {
-  // Our "collection" type currently is a std::map which doesn't have any good
-  // way to iterate and remove items from the map so we currently just make a
-  // new list and add all of the matching types to it, and then swap it into
-  // m_types at the end
-  collection matching_types;
-
-  iterator pos, end = m_types.end();
+  iterator pos, end = m_types.End();
 
-  for (pos = m_types.begin(); pos != end; ++pos) {
+  for (pos = m_types.Begin(); pos != end;) {
     Type *the_type = pos->get();
     bool keep_match = false;
     TypeClass match_type_class = eTypeClassAny;
@@ -178,31 +167,43 @@
       }
     }
 
-    if (keep_match) {
-      matching_types.push_back(*pos);
-    }
+    if (keep_match)
+      ++pos;
+    else
+      pos = m_types.Erase(pos);
   }
-  m_types.swap(matching_types);
 }
 
 void TypeList::RemoveMismatchedTypes(TypeClass type_class) {
   if (type_class == eTypeClassAny)
     return;
 
-  // Our "collection" type currently is a std::map which doesn't have any good
-  // way to iterate and remove items from the map so we currently just make a
-  // new list and add all of the matching types to it, and then swap it into
-  // m_types at the end
-  collection matching_types;
+  iterator pos, end = m_types.End();
 
-  iterator pos, end = m_types.end();
-
-  for (pos = m_types.begin(); pos != end; ++pos) {
+  for (pos = m_types.Begin(); pos != end;) {
     Type *the_type = pos->get();
     TypeClass match_type_class =
         the_type->GetForwardCompilerType().GetTypeClass();
     if (match_type_class & type_class)
-      matching_types.push_back(*pos);
+      ++pos;
+    else
+      pos = m_types.Erase(pos);
   }
-  m_types.swap(matching_types);
+}
+
+void TypeList::TypeCollection::Clear() {
+  m_types.clear();
+  m_type_set.clear();
+}
+
+void TypeList::TypeCollection::Insert(const lldb::TypeSP &type) {
+  if (type && m_type_set.count(type.get()) == 0) {
+    m_types.push_back(type);
+    m_type_set.insert(type.get());
+  }
+}
+
+TypeList::iterator TypeList::TypeCollection::Erase(iterator iter) {
+  m_type_set.erase(iter->get());
+  return m_types.erase(iter);
 }
Index: lldb/source/Symbol/SymbolFile.cpp
===================================================================
--- lldb/source/Symbol/SymbolFile.cpp
+++ lldb/source/Symbol/SymbolFile.cpp
@@ -217,7 +217,7 @@
 void SymbolFile::Dump(Stream &s) {
   s.Format("SymbolFile {0} ({1})\n", GetPluginName(),
            GetMainObjectFile()->GetFileSpec());
-  s.PutCString("Types:\n");
+  s.Format("Found {0} types:\n", m_type_list.GetSize());
   m_type_list.Dump(&s, /*show_context*/ false);
   s.PutChar('\n');
 
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -1530,7 +1530,6 @@
     return type_sp;
 
   SymbolFileDWARF *dwarf = die.GetDWARF();
-  TypeList &type_list = dwarf->GetTypeList();
   DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
   dw_tag_t sc_parent_tag = sc_parent_die.Tag();
 
@@ -1550,10 +1549,6 @@
   if (symbol_context_scope != nullptr)
     type_sp->SetSymbolContextScope(symbol_context_scope);
 
-  // We are ready to put this type into the uniqued list up at the module
-  // level.
-  type_list.Insert(type_sp);
-
   dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
   return type_sp;
 }
Index: lldb/include/lldb/Symbol/TypeList.h
===================================================================
--- lldb/include/lldb/Symbol/TypeList.h
+++ lldb/include/lldb/Symbol/TypeList.h
@@ -42,7 +42,7 @@
   typedef AdaptedIterable<collection, lldb::TypeSP, vector_adapter>
       TypeIterable;
 
-  TypeIterable Types() { return TypeIterable(m_types); }
+  TypeIterable Types() { return TypeIterable(m_types.Types()); }
 
   void ForEach(
       std::function<bool(const lldb::TypeSP &type_sp)> const &callback) const;
@@ -61,7 +61,23 @@
   typedef collection::iterator iterator;
   typedef collection::const_iterator const_iterator;
 
-  collection m_types;
+  class TypeCollection {
+    typedef std::set<lldb_private::Type *> setCollection;
+    collection m_types;
+    setCollection m_type_set;
+
+  public:
+    const collection &Types() const { return m_types; };
+    collection &Types() { return m_types; };
+    iterator Begin() { return m_types.begin(); };
+    iterator End() { return m_types.end(); };
+    const_iterator Begin() const { return m_types.cbegin(); };
+    const_iterator End() const { return m_types.cend(); };
+    iterator Erase(iterator iter);
+    void Insert(const lldb::TypeSP &type);
+    void Clear();
+  };
+  TypeCollection m_types;
 
   TypeList(const TypeList &) = delete;
   const TypeList &operator=(const TypeList &) = delete;
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to