[Lldb-commits] [lldb] r350888 - [NativePDB] Add support for parsing typedef records.

Zachary Turner via lldb-commits lldb-commits at lists.llvm.org
Thu Jan 10 12:57:32 PST 2019


Author: zturner
Date: Thu Jan 10 12:57:32 2019
New Revision: 350888

URL: http://llvm.org/viewvc/llvm-project?rev=350888&view=rev
Log:
[NativePDB] Add support for parsing typedef records.

Typedefs are represented as S_UDT records in the globals stream. This
creates a strange situation where "types" are actually represented as
"symbols", so they need special handling.

In order to test this, we don't just use lldb and print out some
variables causing the AST to get created, because variables whose type
is a typedef will have debug info referencing the original type, not the
typedef. So we use lldb-test instead which will parse all debug info in
the entire file. This exposed some problems with lldb-test and the
native reader, mainly that certain types of obscure symbols which we can
find when iterating every single record would trigger crashes. These
have been fixed as well so that lldb-test can be used to test this
functionality.

Differential Revision: https://reviews.llvm.org/D56461

Added:
    lldb/trunk/lit/SymbolFile/NativePDB/typedefs.cpp
Modified:
    lldb/trunk/include/lldb/Symbol/CompileUnit.h
    lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
    lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
    lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
    lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
    lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
    lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h

Modified: lldb/trunk/include/lldb/Symbol/CompileUnit.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/CompileUnit.h?rev=350888&r1=350887&r2=350888&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/CompileUnit.h (original)
+++ lldb/trunk/include/lldb/Symbol/CompileUnit.h Thu Jan 10 12:57:32 2019
@@ -409,6 +409,11 @@ public:
   //------------------------------------------------------------------
   bool GetIsOptimized();
 
+  //------------------------------------------------------------------
+  /// Returns the number of functions in this compile unit
+  //------------------------------------------------------------------
+  size_t GetNumFunctions() const { return m_functions_by_uid.size(); }
+
 protected:
   void *m_user_data; ///< User data for the SymbolFile parser to store
                      ///information into.

Added: lldb/trunk/lit/SymbolFile/NativePDB/typedefs.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/NativePDB/typedefs.cpp?rev=350888&view=auto
==============================================================================
--- lldb/trunk/lit/SymbolFile/NativePDB/typedefs.cpp (added)
+++ lldb/trunk/lit/SymbolFile/NativePDB/typedefs.cpp Thu Jan 10 12:57:32 2019
@@ -0,0 +1,71 @@
+// clang-format off
+
+// REQUIRES: system-windows
+// RUN: %build --compiler=clang-cl --nodefaultlib -o %t.exe -- %s
+// RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols -dump-ast %t.exe | FileCheck %s
+
+namespace A {
+  namespace B {
+    using NamespaceTypedef = double;
+  }
+  template<typename T>
+  class C {
+  public:
+    using ClassTypedef = T;
+  };
+  using ClassTypedef = C<char>::ClassTypedef;
+  using ClassTypedef2 = C<wchar_t>::ClassTypedef;
+  
+  template<typename T>
+  using AliasTemplate = typename C<T>::ClassTypedef;
+}
+
+namespace {
+  using AnonNamespaceTypedef = bool;
+}
+
+using IntTypedef = int;
+
+using ULongArrayTypedef = unsigned long[10];
+
+using RefTypedef = long double*&;
+
+using FuncPtrTypedef = long long(*)(int&, unsigned char**, short[], const double, volatile bool);
+
+using VarArgsFuncTypedef = char(*)(void*, long, unsigned short, unsigned int, ...);
+
+using VarArgsFuncTypedefA = float(*)(...);
+
+int main(int argc, char **argv) {
+  long double *Ptr;
+  
+  A::B::NamespaceTypedef *X0;
+  A::C<char>::ClassTypedef *X1;
+  A::C<wchar_t>::ClassTypedef *X2;
+  AnonNamespaceTypedef *X3;
+  IntTypedef *X4;
+  ULongArrayTypedef *X5;
+  RefTypedef X6 = Ptr;
+  FuncPtrTypedef X7;
+  VarArgsFuncTypedef X8;
+  VarArgsFuncTypedefA X9;
+  A::AliasTemplate<float> X10;
+  return 0;
+}
+
+
+// CHECK:      namespace `anonymous namespace' {
+// CHECK-NEXT:     typedef bool AnonNamespaceTypedef;
+// CHECK-NEXT: }
+// CHECK-NEXT: typedef unsigned long ULongArrayTypedef[10];
+// CHECK-NEXT: typedef double *&RefTypedef;
+// CHECK-NEXT: namespace A {
+// CHECK-NEXT:     namespace B {
+// CHECK-NEXT:         typedef double NamespaceTypedef;
+// CHECK-NEXT:     }
+// CHECK-NEXT:     typedef float AliasTemplate<float>;
+// CHECK-NEXT: }
+// CHECK-NEXT: typedef long long (*FuncPtrTypedef)(int &, unsigned char **, short *, const double, volatile bool);
+// CHECK-NEXT: typedef char (*VarArgsFuncTypedef)(void *, long, unsigned short, unsigned int, ...);
+// CHECK-NEXT: typedef float (*VarArgsFuncTypedefA)(...);
+// CHECK-NEXT: typedef int IntTypedef;

Modified: lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp?rev=350888&r1=350887&r2=350888&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp Thu Jan 10 12:57:32 2019
@@ -2,6 +2,7 @@
 
 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
 #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
+#include "llvm/DebugInfo/CodeView/RecordName.h"
 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
 #include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
@@ -13,6 +14,7 @@
 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
 #include "llvm/Demangle/MicrosoftDemangle.h"
 
+#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/ClangExternalASTSourceCommon.h"
@@ -215,10 +217,15 @@ clang::DeclContext &PdbAstBuilder::GetTr
 std::pair<clang::DeclContext *, std::string>
 PdbAstBuilder::CreateDeclInfoForType(const TagRecord &record, TypeIndex ti) {
   // FIXME: Move this to GetDeclContextContainingUID.
+  if (!record.hasUniqueName())
+    return CreateDeclInfoForUndecoratedName(record.Name);
 
   llvm::ms_demangle::Demangler demangler;
   StringView sv(record.UniqueName.begin(), record.UniqueName.size());
   llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv);
+  if (demangler.Error)
+    return {m_clang.GetTranslationUnitDecl(), record.UniqueName};
+
   llvm::ms_demangle::IdentifierNode *idn =
       ttn->QualifiedName->getUnqualifiedIdentifier();
   std::string uname = idn->toString(llvm::ms_demangle::OF_NoTagSpecifier);
@@ -491,6 +498,82 @@ clang::DeclContext *PdbAstBuilder::GetOr
   return clang::Decl::castToDeclContext(decl);
 }
 
+std::pair<clang::DeclContext *, std::string>
+PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) {
+  MSVCUndecoratedNameParser parser(name);
+  llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
+
+  clang::DeclContext *context = &GetTranslationUnitDecl();
+
+  llvm::StringRef uname = specs.back().GetBaseName();
+  specs = specs.drop_back();
+  if (specs.empty())
+    return {context, name};
+
+  llvm::StringRef scope_name = specs.back().GetFullName();
+
+  // It might be a class name, try that first.
+  std::vector<TypeIndex> types = m_index.tpi().findRecordsByName(scope_name);
+  while (!types.empty()) {
+    clang::QualType qt = GetOrCreateType(types.back());
+    clang::TagDecl *tag = qt->getAsTagDecl();
+    if (tag)
+      return {clang::TagDecl::castToDeclContext(tag), uname};
+    types.pop_back();
+  }
+
+  // If that fails, treat it as a series of namespaces.
+  for (const MSVCUndecoratedNameSpecifier &spec : specs) {
+    std::string ns_name = spec.GetBaseName().str();
+    context = m_clang.GetUniqueNamespaceDeclaration(ns_name.c_str(), context);
+  }
+  return {context, 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 &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());
+      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.
+  clang::DeclContext *context = &GetTranslationUnitDecl();
+  while (!name_components.empty()) {
+    std::string ns = name_components.front()->toString();
+    context = m_clang.GetUniqueNamespaceDeclaration(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.
@@ -502,46 +585,7 @@ clang::DeclContext *PdbAstBuilder::GetPa
       return GetOrCreateDeclContextForUid(*scope);
 
     CVSymbol sym = m_index.ReadSymbolRecord(uid.asCompilandSym());
-    if (!SymbolHasAddress(sym))
-      return &GetTranslationUnitDecl();
-    SegmentOffset addr = GetSegmentAndOffset(sym);
-    llvm::Optional<PublicSym32> pub =
-        FindPublicSym(addr, m_index.symrecords(), m_index.publics());
-    if (!pub)
-      return &GetTranslationUnitDecl();
-
-    llvm::ms_demangle::Demangler demangler;
-    StringView name{pub->Name.begin(), pub->Name.size()};
-    llvm::ms_demangle::SymbolNode *node = demangler.parse(name);
-    if (!node)
-      return &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());
-        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.
-    clang::DeclContext *context = &GetTranslationUnitDecl();
-    while (!name_components.empty()) {
-      std::string ns = name_components.front()->toString();
-      context = m_clang.GetUniqueNamespaceDeclaration(ns.c_str(), context);
-      name_components = name_components.drop_front();
-    }
-    return context;
+    return GetParentDeclContextForSymbol(sym);
   }
   case PdbSymUidKind::Type: {
     // It could be a namespace, class, or global.  We don't support nested
@@ -556,6 +600,34 @@ clang::DeclContext *PdbAstBuilder::GetPa
     // In this case the parent DeclContext is the one for the class that this
     // member is inside of.
     break;
+  case PdbSymUidKind::GlobalSym: {
+    // If this refers to a compiland symbol, just recurse in with that symbol.
+    // The only other possibilities are S_CONSTANT and S_UDT, in which case we
+    // need to parse the undecorated name to figure out the scope, then look
+    // that up in the TPI stream.  If it's found, it's a type, othewrise it's
+    // a series of namespaces.
+    // FIXME: do this.
+    CVSymbol global = m_index.ReadSymbolRecord(uid.asGlobalSym());
+    switch (global.kind()) {
+    case SymbolKind::S_GDATA32:
+    case SymbolKind::S_LDATA32:
+      return GetParentDeclContextForSymbol(global);
+    case SymbolKind::S_PROCREF:
+    case SymbolKind::S_LPROCREF: {
+      ProcRefSym ref{global.kind()};
+      llvm::cantFail(
+          SymbolDeserializer::deserializeAs<ProcRefSym>(global, ref));
+      PdbCompilandSymId cu_sym_id{ref.modi(), ref.SymOffset};
+      return GetParentDeclContext(cu_sym_id);
+    }
+    case SymbolKind::S_CONSTANT:
+    case SymbolKind::S_UDT:
+      return CreateDeclInfoForUndecoratedName(getSymbolName(global)).first;
+    default:
+      break;
+    }
+    break;
+  }
   default:
     break;
   }
@@ -645,6 +717,11 @@ clang::QualType PdbAstBuilder::CreateSim
 clang::QualType PdbAstBuilder::CreatePointerType(const PointerRecord &pointer) {
   clang::QualType pointee_type = GetOrCreateType(pointer.ReferentType);
 
+  // This can happen for pointers to LF_VTSHAPE records, which we shouldn't
+  // create in the AST.
+  if (pointee_type.isNull())
+    return {};
+
   if (pointer.isPointerToMember()) {
     MemberPointerInfo mpi = pointer.getMemberInfo();
     clang::QualType class_type = GetOrCreateType(mpi.ContainingType);
@@ -677,8 +754,9 @@ clang::QualType PdbAstBuilder::CreatePoi
 
 clang::QualType
 PdbAstBuilder::CreateModifierType(const ModifierRecord &modifier) {
-
   clang::QualType unmodified_type = GetOrCreateType(modifier.ModifiedType);
+  if (unmodified_type.isNull())
+    return {};
 
   if ((modifier.Modifiers & ModifierOptions::Const) != ModifierOptions::None)
     unmodified_type.addConst();
@@ -786,6 +864,32 @@ clang::VarDecl *PdbAstBuilder::GetOrCrea
   return CreateVariableDecl(PdbSymUid(var_id), sym, GetTranslationUnitDecl());
 }
 
+clang::TypedefNameDecl *
+PdbAstBuilder::GetOrCreateTypedefDecl(PdbGlobalSymId id) {
+  if (clang::Decl *decl = TryGetDecl(id))
+    return llvm::dyn_cast<clang::TypedefNameDecl>(decl);
+
+  CVSymbol sym = m_index.ReadSymbolRecord(id);
+  lldbassert(sym.kind() == S_UDT);
+  UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym));
+
+  clang::DeclContext *scope = GetParentDeclContext(id);
+
+  PdbTypeSymId real_type_id{udt.Type, false};
+  clang::QualType qt = GetOrCreateType(real_type_id);
+
+  std::string uname = DropNameScope(udt.Name);
+
+  CompilerType ct = m_clang.CreateTypedefType(ToCompilerType(qt), uname.c_str(),
+                                              ToCompilerDeclContext(*scope));
+  clang::TypedefNameDecl *tnd = m_clang.GetAsTypedefDecl(ct);
+  DeclStatus status;
+  status.resolved = true;
+  status.uid = toOpaqueUid(id);
+  m_decl_to_status.insert({tnd, status});
+  return tnd;
+}
+
 clang::QualType PdbAstBuilder::GetBasicType(lldb::BasicType type) {
   CompilerType ct = m_clang.GetBasicType(type);
   return clang::QualType::getFromOpaquePtr(ct.GetOpaqueQualType());

Modified: lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h?rev=350888&r1=350887&r2=350888&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h Thu Jan 10 12:57:32 2019
@@ -69,6 +69,7 @@ public:
   clang::VarDecl *GetOrCreateVariableDecl(PdbCompilandSymId scope_id,
                                           PdbCompilandSymId var_id);
   clang::VarDecl *GetOrCreateVariableDecl(PdbGlobalSymId var_id);
+  clang::TypedefNameDecl *GetOrCreateTypedefDecl(PdbGlobalSymId id);
   void ParseDeclsForContext(clang::DeclContext &context);
 
   clang::QualType GetBasicType(lldb::BasicType type);
@@ -112,6 +113,8 @@ private:
   clang::VarDecl *CreateVariableDecl(PdbSymUid uid,
                                      llvm::codeview::CVSymbol sym,
                                      clang::DeclContext &scope);
+  clang::DeclContext *
+  GetParentDeclContextForSymbol(const llvm::codeview::CVSymbol &sym);
 
   void ParseAllNamespacesPlusChildrenOf(llvm::Optional<llvm::StringRef> parent);
   void ParseDeclsForSimpleContext(clang::DeclContext &context);
@@ -120,6 +123,8 @@ private:
   void BuildParentMap();
   std::pair<clang::DeclContext *, std::string>
   CreateDeclInfoForType(const llvm::codeview::TagRecord &record, TypeIndex ti);
+  std::pair<clang::DeclContext *, std::string>
+  CreateDeclInfoForUndecoratedName(llvm::StringRef uname);
   clang::QualType CreateSimpleType(TypeIndex ti);
 
   PdbIndex &m_index;

Modified: lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp?rev=350888&r1=350887&r2=350888&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp Thu Jan 10 12:57:32 2019
@@ -17,8 +17,8 @@
 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
 
+#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
 #include "lldb/Utility/LLDBAssert.h"
-
 #include "lldb/lldb-enumerations.h"
 
 using namespace lldb_private;
@@ -449,16 +449,7 @@ TypeIndex lldb_private::npdb::LookThroug
 }
 
 llvm::StringRef lldb_private::npdb::DropNameScope(llvm::StringRef name) {
-  // Not all PDB names can be parsed with CPlusPlusNameParser.
-  // E.g. it fails on names containing `anonymous namespace'.
-  // So we simply drop everything before '::'
-
-  auto offset = name.rfind("::");
-  if (offset == llvm::StringRef::npos)
-    return name;
-  assert(offset + 2 <= name.size());
-
-  return name.substr(offset + 2);
+  return MSVCUndecoratedNameParser::DropScope(name);
 }
 
 VariableInfo lldb_private::npdb::GetVariableNameInfo(CVSymbol sym) {
@@ -558,10 +549,6 @@ VariableInfo lldb_private::npdb::GetVari
       result.ranges = MakeRangeList(index, loc.Range, loc.Gaps);
     } else {
       // FIXME: Handle other kinds
-      llvm::APSInt value;
-      value = 42;
-      result.location = MakeConstantLocationExpression(
-          TypeIndex::Int32(), index.tpi(), value, module);
     }
     return result;
   }

Modified: lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbUtil.h?rev=350888&r1=350887&r2=350888&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbUtil.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbUtil.h Thu Jan 10 12:57:32 2019
@@ -66,6 +66,14 @@ struct CVTagRecord {
     return cvunion;
   }
 
+  llvm::StringRef name() const {
+    if (m_kind == Struct || m_kind == Union)
+      return cvclass.Name;
+    if (m_kind == Enum)
+      return cvenum.Name;
+    return cvunion.Name;
+  }
+
 private:
   CVTagRecord(llvm::codeview::ClassRecord &&c);
   CVTagRecord(llvm::codeview::UnionRecord &&u);

Modified: lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp?rev=350888&r1=350887&r2=350888&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp Thu Jan 10 12:57:32 2019
@@ -15,6 +15,7 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/Type.h"
 
+#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/StreamBuffer.h"
@@ -394,7 +395,11 @@ lldb::FunctionSP SymbolFileNativePDB::Cr
 
   ProcSym proc(static_cast<SymbolRecordKind>(sym_record.kind()));
   cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc));
+  if (proc.FunctionType == TypeIndex::None())
+    return nullptr;
   TypeSP func_type = GetOrCreateType(proc.FunctionType);
+  if (!func_type)
+    return nullptr;
 
   PdbTypeSymId sig_id(proc.FunctionType, false);
   Mangled mangled(proc.Name);
@@ -515,9 +520,19 @@ lldb::TypeSP SymbolFileNativePDB::Create
 }
 
 static std::string GetUnqualifiedTypeName(const TagRecord &record) {
+  if (!record.hasUniqueName()) {
+    MSVCUndecoratedNameParser parser(record.Name);
+    llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
+
+    return specs.back().GetBaseName();
+  }
+
   llvm::ms_demangle::Demangler demangler;
   StringView sv(record.UniqueName.begin(), record.UniqueName.size());
   llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv);
+  if (demangler.Error)
+    return record.Name;
+
   llvm::ms_demangle::IdentifierNode *idn =
       ttn->QualifiedName->getUnqualifiedIdentifier();
   return idn->toString();
@@ -696,7 +711,10 @@ TypeSP SymbolFileNativePDB::GetOrCreateT
   if (iter != m_types.end())
     return iter->second;
 
-  return CreateAndCacheType(type_id);
+  TypeSP type = CreateAndCacheType(type_id);
+  if (type)
+    m_obj_file->GetModule()->GetTypeList()->Insert(type);
+  return type;
 }
 
 VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) {
@@ -821,7 +839,6 @@ FunctionSP SymbolFileNativePDB::GetOrCre
   if (emplace_result.second)
     emplace_result.first->second = CreateFunction(func_id, comp_unit);
 
-  lldbassert(emplace_result.first->second);
   return emplace_result.first->second;
 }
 
@@ -887,7 +904,26 @@ void SymbolFileNativePDB::AddSymbols(Sym
 
 size_t SymbolFileNativePDB::ParseCompileUnitFunctions(const SymbolContext &sc) {
   lldbassert(sc.comp_unit);
-  return false;
+
+  PdbSymUid uid{sc.comp_unit->GetID()};
+  lldbassert(uid.kind() == PdbSymUidKind::Compiland);
+  uint16_t modi = uid.asCompiland().modi;
+  CompilandIndexItem &cii = m_index->compilands().GetOrCreateCompiland(modi);
+
+  size_t count = sc.comp_unit->GetNumFunctions();
+  const CVSymbolArray &syms = cii.m_debug_stream.getSymbolArray();
+  for (auto iter = syms.begin(); iter != syms.end(); ++iter) {
+    if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32)
+      continue;
+
+    PdbCompilandSymId sym_id{modi, iter.offset()};
+
+    FunctionSP func = GetOrCreateFunction(sym_id, *sc.comp_unit);
+  }
+
+  size_t new_count = sc.comp_unit->GetNumFunctions();
+  lldbassert(new_count >= count);
+  return new_count - count;
 }
 
 static bool NeedsResolvedCompileUnit(uint32_t resolve_scope) {
@@ -1238,7 +1274,47 @@ size_t SymbolFileNativePDB::FindTypesByN
   return match_count;
 }
 
-size_t SymbolFileNativePDB::ParseTypes(const SymbolContext &sc) { return 0; }
+size_t SymbolFileNativePDB::ParseTypes(const SymbolContext &sc) {
+  // Only do the full type scan the first time.
+  if (m_done_full_type_scan)
+    return 0;
+
+  size_t old_count = m_obj_file->GetModule()->GetTypeList()->GetSize();
+  LazyRandomTypeCollection &types = m_index->tpi().typeCollection();
+
+  // First process the entire TPI stream.
+  for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {
+    TypeSP type = GetOrCreateType(*ti);
+    if (type)
+      (void)type->GetFullCompilerType();
+  }
+
+  // Next look for S_UDT records in the globals stream.
+  for (const uint32_t gid : m_index->globals().getGlobalsTable()) {
+    PdbGlobalSymId global{gid, false};
+    CVSymbol sym = m_index->ReadSymbolRecord(global);
+    if (sym.kind() != S_UDT)
+      continue;
+
+    UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym));
+    bool is_typedef = true;
+    if (IsTagRecord(PdbTypeSymId{udt.Type, false}, m_index->tpi())) {
+      CVType cvt = m_index->tpi().getType(udt.Type);
+      llvm::StringRef name = CVTagRecord::create(cvt).name();
+      if (name == udt.Name)
+        is_typedef = false;
+    }
+
+    if (is_typedef)
+      GetOrCreateTypedef(global);
+  }
+
+  size_t new_count = m_obj_file->GetModule()->GetTypeList()->GetSize();
+
+  m_done_full_type_scan = true;
+
+  return new_count - old_count;
+}
 
 size_t
 SymbolFileNativePDB::ParseVariablesForCompileUnit(CompileUnit &comp_unit,
@@ -1253,6 +1329,8 @@ VariableSP SymbolFileNativePDB::CreateLo
                                                     bool is_param) {
   ModuleSP module = GetObjectFile()->GetModule();
   VariableInfo var_info = GetVariableLocationInfo(*m_index, var_id, module);
+  if (!var_info.location || !var_info.ranges)
+    return nullptr;
 
   CompilandIndexItem *cii = m_index->compilands().GetCompiland(var_id.modi);
   CompUnitSP comp_unit_sp = GetOrCreateCompileUnit(*cii);
@@ -1285,6 +1363,32 @@ VariableSP SymbolFileNativePDB::GetOrCre
   return CreateLocalVariable(scope_id, var_id, is_param);
 }
 
+TypeSP SymbolFileNativePDB::CreateTypedef(PdbGlobalSymId id) {
+  CVSymbol sym = m_index->ReadSymbolRecord(id);
+  lldbassert(sym.kind() == SymbolKind::S_UDT);
+
+  UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym));
+
+  TypeSP target_type = GetOrCreateType(udt.Type);
+
+  (void)m_ast->GetOrCreateTypedefDecl(id);
+
+  Declaration decl;
+  return std::make_shared<lldb_private::Type>(
+      toOpaqueUid(id), this, ConstString(udt.Name), target_type->GetByteSize(),
+      nullptr, target_type->GetID(), lldb_private::Type::eEncodingIsTypedefUID,
+      decl, target_type->GetForwardCompilerType(),
+      lldb_private::Type::eResolveStateForward);
+}
+
+TypeSP SymbolFileNativePDB::GetOrCreateTypedef(PdbGlobalSymId id) {
+  auto iter = m_types.find(toOpaqueUid(id));
+  if (iter != m_types.end())
+    return iter->second;
+
+  return CreateTypedef(id);
+}
+
 size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) {
   Block &block = GetOrCreateBlock(block_id);
 
@@ -1349,7 +1453,8 @@ size_t SymbolFileNativePDB::ParseVariabl
       variable = GetOrCreateLocalVariable(block_id, child_sym_id, is_param);
       if (is_param)
         --params_remaining;
-      variables->AddVariableIfUnique(variable);
+      if (variable)
+        variables->AddVariableIfUnique(variable);
       break;
     default:
       break;

Modified: lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h?rev=350888&r1=350887&r2=350888&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h Thu Jan 10 12:57:32 2019
@@ -203,12 +203,14 @@ private:
   lldb::VariableSP GetOrCreateLocalVariable(PdbCompilandSymId scope_id,
                                             PdbCompilandSymId var_id,
                                             bool is_param);
+  lldb::TypeSP GetOrCreateTypedef(PdbGlobalSymId id);
 
   lldb::FunctionSP CreateFunction(PdbCompilandSymId func_id,
                                   CompileUnit &comp_unit);
   Block &CreateBlock(PdbCompilandSymId block_id);
   lldb::VariableSP CreateLocalVariable(PdbCompilandSymId scope_id,
                                        PdbCompilandSymId var_id, bool is_param);
+  lldb::TypeSP CreateTypedef(PdbGlobalSymId id);
   lldb::CompUnitSP CreateCompileUnit(const CompilandIndexItem &cci);
   lldb::TypeSP CreateType(PdbTypeSymId type_id, CompilerType ct);
   lldb::TypeSP CreateAndCacheType(PdbTypeSymId type_id);
@@ -222,6 +224,7 @@ private:
   llvm::BumpPtrAllocator m_allocator;
 
   lldb::addr_t m_obj_load_address = 0;
+  bool m_done_full_type_scan = false;
 
   std::unique_ptr<PdbIndex> m_index;
 




More information about the lldb-commits mailing list