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

- Removed `GetParentDeclContextForSymbol` as this is not necesssary. We can get 
the demangled names from CVSymbol and then using it to create tag decl or 
namespace decl.
- Add test cases with same base names, but with different namespace/class.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133243

Files:
  lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
  lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
  lldb/test/Shell/SymbolFile/NativePDB/icf.cpp

Index: lldb/test/Shell/SymbolFile/NativePDB/icf.cpp
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/NativePDB/icf.cpp
@@ -0,0 +1,71 @@
+// clang-format off
+// REQUIRES: lld, x86
+
+// Test lldb finds the correct parent context decl for functions and class methods when icf happens.
+// RUN: %clang_cl --target=x86_64-windows-msvc -Od -Z7 -GS- -fno-addrsig -c /Fo%t.obj -- %s
+// RUN: lld-link -opt:icf -debug:full -nodefaultlib -entry:main %t.obj -out:%t.exe -pdb:%t.pdb
+// RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols --dump-ast %t.exe | FileCheck %s
+
+struct A {
+  int f1(int x) {
+    return x * 2;
+  }
+};
+struct B {
+  int f2(int x) {
+    return x * 2;
+  }
+};
+namespace N1 {
+int f3(void*, int x) {
+  return  x * 2;
+}
+} // namespace N1
+
+namespace N2 {
+namespace N3 {
+  int f4(void*, int x) {
+    return  x * 2;
+  }
+} // namespace N3
+} // namespace N2
+
+namespace N4 {
+  // Same base name as N1::f3 but different namespaces.
+  int f3(void*, int x) {
+    return x * 2;
+  }
+  // Same base name as B::f2 but this is in namespace.
+  int f2(void*, int x) {
+    return x * 2;
+  }
+} // namespace N4
+
+
+int main() {
+  A a;
+  B b;
+  return a.f1(1) + b.f2(1) + N1::f3(nullptr, 1) + N2::N3::f4(nullptr, 1) +
+         N4::f3(nullptr, 1);
+}
+
+
+// CHECK:      namespace N1 {
+// CHECK-NEXT:     int f3(void *, int x);
+// CHECK-NEXT: }
+// CHECK-NEXT: namespace N2 {
+// CHECK-NEXT:     namespace N3 {
+// CHECK-NEXT:         int f4(void *, int x);
+// CHECK-NEXT:     }
+// CHECK-NEXT: }
+// CHECK-NEXT: namespace N4 {
+// CHECK-NEXT:     int f3(void *, int x);
+// CHECK-NEXT:     int f2(void *, int x);
+// CHECK-NEXT: }
+// CHECK-NEXT: int main();
+// CHECK-NEXT: struct A {
+// CHECK-NEXT:     int f1(int);
+// CHECK-NEXT: };
+// CHECK-NEXT: struct B {
+// CHECK-NEXT:     int f2(int);
+// CHECK-NEXT: };
Index: lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
===================================================================
--- lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
+++ lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
@@ -113,9 +113,6 @@
   clang::VarDecl *CreateVariableDecl(PdbSymUid uid,
                                      llvm::codeview::CVSymbol sym,
                                      clang::DeclContext &scope);
-  clang::DeclContext *
-  GetParentDeclContextForSymbol(const llvm::codeview::CVSymbol &sym);
-
   clang::NamespaceDecl *GetOrCreateNamespaceDecl(const char *name,
                                                  clang::DeclContext &context);
   clang::FunctionDecl *CreateFunctionDeclFromId(PdbTypeSymId func_tid,
Index: lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -456,46 +456,6 @@
   return false;
 }
 
-static std::string
-RenderScopeList(llvm::ArrayRef<llvm::ms_demangle::Node *> nodes) {
-  lldbassert(!nodes.empty());
-
-  std::string result = nodes.front()->toString();
-  nodes = nodes.drop_front();
-  while (!nodes.empty()) {
-    result += "::";
-    result += nodes.front()->toString(llvm::ms_demangle::OF_NoTagSpecifier);
-    nodes = nodes.drop_front();
-  }
-  return result;
-}
-
-static llvm::Optional<PublicSym32> FindPublicSym(const SegmentOffset &addr,
-                                                 SymbolStream &syms,
-                                                 PublicsStream &publics) {
-  llvm::FixedStreamArray<ulittle32_t> addr_map = publics.getAddressMap();
-  auto iter = std::lower_bound(
-      addr_map.begin(), addr_map.end(), addr,
-      [&](const ulittle32_t &x, const SegmentOffset &y) {
-        CVSymbol s1 = syms.readRecord(x);
-        lldbassert(s1.kind() == S_PUB32);
-        PublicSym32 p1;
-        llvm::cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(s1, p1));
-        if (p1.Segment < y.segment)
-          return true;
-        return p1.Offset < y.offset;
-      });
-  if (iter == addr_map.end())
-    return llvm::None;
-  CVSymbol sym = syms.readRecord(*iter);
-  lldbassert(sym.kind() == S_PUB32);
-  PublicSym32 p;
-  llvm::cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(sym, p));
-  if (p.Segment == addr.segment && p.Offset == addr.offset)
-    return p;
-  return llvm::None;
-}
-
 clang::Decl *PdbAstBuilder::GetOrCreateSymbolForId(PdbCompilandSymId id) {
   CVSymbol cvs = m_index.ReadSymbolRecord(id);
 
@@ -606,52 +566,6 @@
   return {context, std::string(uname)};
 }
 
-clang::DeclContext *
-PdbAstBuilder::GetParentDeclContextForSymbol(const CVSymbol &sym) {
-  if (!SymbolHasAddress(sym))
-    return CreateDeclInfoForUndecoratedName(getSymbolName(sym)).first;
-  SegmentOffset addr = GetSegmentAndOffset(sym);
-  llvm::Optional<PublicSym32> pub =
-      FindPublicSym(addr, m_index.symrecords(), m_index.publics());
-  if (!pub)
-    return CreateDeclInfoForUndecoratedName(getSymbolName(sym)).first;
-
-  llvm::ms_demangle::Demangler demangler;
-  StringView name{pub->Name.begin(), pub->Name.size()};
-  llvm::ms_demangle::SymbolNode *node = demangler.parse(name);
-  if (!node)
-    return FromCompilerDeclContext(GetTranslationUnitDecl());
-  llvm::ArrayRef<llvm::ms_demangle::Node *> name_components{
-      node->Name->Components->Nodes, node->Name->Components->Count - 1};
-
-  if (!name_components.empty()) {
-    // Render the current list of scope nodes as a fully qualified name, and
-    // look it up in the debug info as a type name.  If we find something,
-    // this is a type (which may itself be prefixed by a namespace).  If we
-    // don't, this is a list of namespaces.
-    std::string qname = RenderScopeList(name_components);
-    std::vector<TypeIndex> matches = m_index.tpi().findRecordsByName(qname);
-    while (!matches.empty()) {
-      clang::QualType qt = GetOrCreateType(matches.back());
-      if (qt.isNull())
-        continue;
-      clang::TagDecl *tag = qt->getAsTagDecl();
-      if (tag)
-        return clang::TagDecl::castToDeclContext(tag);
-      matches.pop_back();
-    }
-  }
-
-  // It's not a type.  It must be a series of namespaces.
-  auto context = FromCompilerDeclContext(GetTranslationUnitDecl());
-  while (!name_components.empty()) {
-    std::string ns = name_components.front()->toString();
-    context = GetOrCreateNamespaceDecl(ns.c_str(), *context);
-    name_components = name_components.drop_front();
-  }
-  return context;
-}
-
 clang::DeclContext *PdbAstBuilder::GetParentDeclContext(PdbSymUid uid) {
   // We must do this *without* calling GetOrCreate on the current uid, as
   // that would be an infinite recursion.
@@ -663,7 +577,7 @@
       return GetOrCreateDeclContextForUid(*scope);
 
     CVSymbol sym = m_index.ReadSymbolRecord(uid.asCompilandSym());
-    return GetParentDeclContextForSymbol(sym);
+    return CreateDeclInfoForUndecoratedName(getSymbolName(sym)).first;
   }
   case PdbSymUidKind::Type: {
     // It could be a namespace, class, or global.  We don't support nested
@@ -689,7 +603,7 @@
     switch (global.kind()) {
     case SymbolKind::S_GDATA32:
     case SymbolKind::S_LDATA32:
-      return GetParentDeclContextForSymbol(global);
+      return CreateDeclInfoForUndecoratedName(getSymbolName(global)).first;;
     case SymbolKind::S_PROCREF:
     case SymbolKind::S_LPROCREF: {
       ProcRefSym ref{global.kind()};
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to