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

Seperate refactor and the chang that fix class layout.
This just hooks PdbAstBuilder to TypeSystem to use class layout from native 
pdb, but it's still broken because the layout bitsize is missing.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D134509

Files:
  lldb/include/lldb/Symbol/TypeSystem.h
  lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
  lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
  lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
  lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
  lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
  lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
  lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h

Index: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
===================================================================
--- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -441,6 +441,7 @@
   // TypeSystem methods
   DWARFASTParser *GetDWARFParser() override;
   PDBASTParser *GetPDBParser() override;
+  npdb::PdbAstBuilder *GetNativePDBParser() override;
 
   // TypeSystemClang callbacks for external source lookups.
   void CompleteTagDecl(clang::TagDecl *);
@@ -1069,6 +1070,7 @@
   std::unique_ptr<clang::ModuleMap> m_module_map_up;
   std::unique_ptr<DWARFASTParserClang> m_dwarf_ast_parser_up;
   std::unique_ptr<PDBASTParser> m_pdb_ast_parser_up;
+  std::unique_ptr<npdb::PdbAstBuilder> m_native_pdb_ast_parser_up;
   std::unique_ptr<clang::MangleContext> m_mangle_ctx_up;
   uint32_t m_pointer_byte_size = 0;
   bool m_ast_owned = false;
Index: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
===================================================================
--- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -73,6 +73,7 @@
 #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
 #include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h"
 #include "Plugins/SymbolFile/PDB/PDBASTParser.h"
+#include "Plugins/SymbolFile/NativePDB/PdbAstBuilder.h"
 
 #include <cstdio>
 
@@ -9363,6 +9364,12 @@
   return m_pdb_ast_parser_up.get();
 }
 
+npdb::PdbAstBuilder *TypeSystemClang::GetNativePDBParser() {
+  if (!m_native_pdb_ast_parser_up)
+    m_native_pdb_ast_parser_up = std::make_unique<npdb::PdbAstBuilder>(*this);
+  return m_native_pdb_ast_parser_up.get();
+}
+
 bool TypeSystemClang::LayoutRecordType(
     const clang::RecordDecl *record_decl, uint64_t &bit_size,
     uint64_t &alignment,
@@ -9376,6 +9383,8 @@
     importer = &m_dwarf_ast_parser_up->GetClangASTImporter();
   if (!importer && m_pdb_ast_parser_up)
     importer = &m_pdb_ast_parser_up->GetClangASTImporter();
+  if (!importer && m_native_pdb_ast_parser_up)
+    importer = &m_native_pdb_ast_parser_up->GetClangASTImporter();
   if (!importer)
     return false;
 
Index: lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
+++ lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
@@ -312,6 +312,6 @@
   TypeSystemClang::CompleteTagDeclarationDefinition(m_derived_ct);
 
   if (auto *record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(&m_tag_decl)) {
-    m_ast_builder.importer().SetRecordLayout(record_decl, m_layout);
+    m_ast_builder.GetClangASTImporter().SetRecordLayout(record_decl, m_layout);
   }
 }
Index: lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
===================================================================
--- lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -19,6 +19,7 @@
 
 #include "CompileUnitIndex.h"
 #include "PdbIndex.h"
+#include "PdbAstBuilder.h"
 
 namespace clang {
 class TagDecl;
@@ -37,7 +38,6 @@
 namespace lldb_private {
 
 namespace npdb {
-class PdbAstBuilder;
 
 class SymbolFileNativePDB : public SymbolFileCommon {
   friend class UdtRecordCompleter;
@@ -137,6 +137,8 @@
   void FindFunctions(const RegularExpression &regex, bool include_inlines,
                      SymbolContextList &sc_list) override;
 
+  llvm::Optional<PdbCompilandSymId> FindSymbolScope(PdbCompilandSymId id);
+
   void FindTypes(ConstString name, const CompilerDeclContext &parent_decl_ctx,
                  uint32_t max_matches,
                  llvm::DenseSet<SymbolFile *> &searched_symbol_files,
@@ -158,8 +160,13 @@
   llvm::pdb::PDBFile &GetPDBFile() { return m_index->pdb(); }
   const llvm::pdb::PDBFile &GetPDBFile() const { return m_index->pdb(); }
 
+  PdbIndex &GetIndex() { return *m_index; };
+
   void DumpClangAST(Stream &s) override;
 
+  llvm::Optional<llvm::codeview::TypeIndex>
+  GetParentType(llvm::codeview::TypeIndex ti);
+
 private:
   struct LineTableEntryComparator {
     bool operator()(const lldb_private::LineTable::Entry &lhs,
@@ -180,6 +187,8 @@
     InlineSite(PdbCompilandSymId parent_id) : parent_id(parent_id){};
   };
 
+  void BuildParentMap();
+
   uint32_t CalculateNumCompileUnits() override;
 
   lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
@@ -262,8 +271,6 @@
   std::unique_ptr<llvm::pdb::PDBFile> m_file_up;
   std::unique_ptr<PdbIndex> m_index;
 
-  std::unique_ptr<PdbAstBuilder> m_ast;
-
   llvm::DenseMap<lldb::user_id_t, lldb::VariableSP> m_global_vars;
   llvm::DenseMap<lldb::user_id_t, lldb::VariableSP> m_local_variables;
   llvm::DenseMap<lldb::user_id_t, lldb::BlockSP> m_blocks;
@@ -271,6 +278,8 @@
   llvm::DenseMap<lldb::user_id_t, lldb::CompUnitSP> m_compilands;
   llvm::DenseMap<lldb::user_id_t, lldb::TypeSP> m_types;
   llvm::DenseMap<lldb::user_id_t, std::shared_ptr<InlineSite>> m_inline_sites;
+  llvm::DenseMap<llvm::codeview::TypeIndex, llvm::codeview::TypeIndex>
+      m_parent_types;
 };
 
 } // namespace npdb
Index: lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -8,12 +8,6 @@
 
 #include "SymbolFileNativePDB.h"
 
-#include "clang/AST/Attr.h"
-#include "clang/AST/CharUnits.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/Type.h"
-
 #include "Plugins/ExpressionParser/Clang/ClangUtil.h"
 #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
 #include "Plugins/ObjectFile/PDB/ObjectFilePDB.h"
@@ -59,7 +53,6 @@
 #include "llvm/Support/MemoryBuffer.h"
 
 #include "DWARFLocationExpression.h"
-#include "PdbAstBuilder.h"
 #include "PdbSymUid.h"
 #include "PdbUtil.h"
 #include "UdtRecordCompleter.h"
@@ -233,6 +226,57 @@
   }
 }
 
+static llvm::Optional<CVTagRecord>
+GetNestedTagDefinition(const NestedTypeRecord &Record,
+                       const CVTagRecord &parent, TpiStream &tpi) {
+  // An LF_NESTTYPE is essentially a nested typedef / using declaration, but it
+  // is also used to indicate the primary definition of a nested class.  That is
+  // to say, if you have:
+  // struct A {
+  //   struct B {};
+  //   using C = B;
+  // };
+  // Then in the debug info, this will appear as:
+  // LF_STRUCTURE `A::B` [type index = N]
+  // LF_STRUCTURE `A`
+  //   LF_NESTTYPE [name = `B`, index = N]
+  //   LF_NESTTYPE [name = `C`, index = N]
+  // In order to accurately reconstruct the decl context hierarchy, we need to
+  // know which ones are actual definitions and which ones are just aliases.
+
+  // If it's a simple type, then this is something like `using foo = int`.
+  if (Record.Type.isSimple())
+    return llvm::None;
+
+  CVType cvt = tpi.getType(Record.Type);
+
+  if (!IsTagRecord(cvt))
+    return llvm::None;
+
+  // If it's an inner definition, then treat whatever name we have here as a
+  // single component of a mangled name.  So we can inject it into the parent's
+  // mangled name to see if it matches.
+  CVTagRecord child = CVTagRecord::create(cvt);
+  std::string qname = std::string(parent.asTag().getUniqueName());
+  if (qname.size() < 4 || child.asTag().getUniqueName().size() < 4)
+    return llvm::None;
+
+  // qname[3] is the tag type identifier (struct, class, union, etc).  Since the
+  // inner tag type is not necessarily the same as the outer tag type, re-write
+  // it to match the inner tag type.
+  qname[3] = child.asTag().getUniqueName()[3];
+  std::string piece;
+  if (qname[3] == 'W')
+    piece = "4";
+  piece += Record.Name;
+  piece.push_back('@');
+  qname.insert(4, std::move(piece));
+  if (qname != child.asTag().UniqueName)
+    return llvm::None;
+
+  return std::move(child);
+}
+
 void SymbolFileNativePDB::Initialize() {
   PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                 GetPluginDescriptionStatic(), CreateInstance,
@@ -311,9 +355,7 @@
                    "Failed to initialize");
   } else {
     ts_or_err->SetSymbolFile(this);
-    auto *clang = llvm::cast_or_null<TypeSystemClang>(&ts_or_err.get());
-    lldbassert(clang);
-    m_ast = std::make_unique<PdbAstBuilder>(*m_objfile_sp, *m_index, *clang);
+    BuildParentMap();
   }
 }
 
@@ -338,6 +380,10 @@
   CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii);
   lldb::user_id_t opaque_block_uid = toOpaqueUid(block_id);
   BlockSP child_block = std::make_shared<Block>(opaque_block_uid);
+  auto ts_or_err = GetTypeSystemForLanguage(comp_unit->GetLanguage());
+  if (auto err = ts_or_err.takeError())
+    return *child_block;
+  PdbAstBuilder* ast_builder = ts_or_err->GetNativePDBParser();
 
   switch (sym.kind()) {
   case S_GPROC32:
@@ -381,7 +427,7 @@
           block_base + block.CodeSize, func_base);
     }
     parent_block.AddChild(child_block);
-    m_ast->GetOrCreateBlockDecl(block_id);
+    ast_builder->GetOrCreateBlockDecl(block_id);
     m_blocks.insert({opaque_block_uid, child_block});
     break;
   }
@@ -392,7 +438,7 @@
     std::shared_ptr<InlineSite> inline_site = m_inline_sites[opaque_block_uid];
     Block &parent_block = GetOrCreateBlock(inline_site->parent_id);
     parent_block.AddChild(child_block);
-    m_ast->GetOrCreateInlinedFunctionDecl(block_id);
+    ast_builder->GetOrCreateInlinedFunctionDecl(block_id);
     // Copy ranges from InlineSite to Block.
     for (size_t i = 0; i < inline_site->ranges.GetSize(); ++i) {
       auto *entry = inline_site->ranges.GetEntryAtIndex(i);
@@ -453,7 +499,10 @@
 
   comp_unit.AddFunction(func_sp);
 
-  m_ast->GetOrCreateFunctionDecl(func_id);
+  auto ts_or_err = GetTypeSystemForLanguage(comp_unit.GetLanguage());
+  if (auto err = ts_or_err.takeError())
+    return func_sp;
+  ts_or_err->GetNativePDBParser()->GetOrCreateFunctionDecl(func_id);
 
   return func_sp;
 }
@@ -746,12 +795,15 @@
   }
 
   PdbTypeSymId best_decl_id = full_decl_uid ? *full_decl_uid : type_id;
-
-  clang::QualType qt = m_ast->GetOrCreateType(best_decl_id);
+  auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+  if (auto err = ts_or_err.takeError())
+    return nullptr;
+  PdbAstBuilder* ast_builder = ts_or_err->GetNativePDBParser();
+  clang::QualType qt = ast_builder->GetOrCreateType(best_decl_id);
   if (qt.isNull())
     return nullptr;
 
-  TypeSP result = CreateType(best_decl_id, m_ast->ToCompilerType(qt));
+  TypeSP result = CreateType(best_decl_id, ast_builder->ToCompilerType(qt));
   if (!result)
     return nullptr;
 
@@ -840,8 +892,10 @@
   SymbolFileTypeSP type_sp =
       std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid));
   Variable::RangeList ranges;
-
-  m_ast->GetOrCreateVariableDecl(var_id);
+  auto ts_or_err = GetTypeSystemForLanguage(comp_unit->GetLanguage());
+  if (auto err = ts_or_err.takeError())
+    return nullptr;
+  ts_or_err->GetNativePDBParser()->GetOrCreateVariableDecl(var_id);
 
   ModuleSP module_sp = GetObjectFile()->GetModule();
   DWARFExpressionList location(
@@ -941,10 +995,14 @@
 
 void SymbolFileNativePDB::ParseDeclsForContext(
     lldb_private::CompilerDeclContext decl_ctx) {
-  clang::DeclContext *context = m_ast->FromCompilerDeclContext(decl_ctx);
+  TypeSystem* ts_or_err = decl_ctx.GetTypeSystem();
+  if (!ts_or_err)
+    return;
+  PdbAstBuilder* ast_builder = ts_or_err->GetNativePDBParser();
+  clang::DeclContext *context = ast_builder->FromCompilerDeclContext(decl_ctx);
   if (!context)
     return;
-  m_ast->ParseDeclsForContext(*context);
+  ast_builder->ParseDeclsForContext(*context);
 }
 
 lldb::CompUnitSP SymbolFileNativePDB::ParseCompileUnitAtIndex(uint32_t index) {
@@ -1563,7 +1621,16 @@
   return count;
 }
 
-void SymbolFileNativePDB::DumpClangAST(Stream &s) { m_ast->Dump(s); }
+void SymbolFileNativePDB::DumpClangAST(Stream &s) {
+  auto ts_or_err = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
+  if (!ts_or_err)
+    return;
+  TypeSystemClang *clang =
+      llvm::dyn_cast_or_null<TypeSystemClang>(&ts_or_err.get());
+  if (!clang)
+    return;
+  clang->GetNativePDBParser()->Dump(s);
+}
 
 void SymbolFileNativePDB::FindGlobalVariables(
     ConstString name, const CompilerDeclContext &parent_decl_ctx,
@@ -1767,8 +1834,12 @@
       toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope,
       &block, scope_ranges, &decl, var_info.location, external, artificial,
       location_is_constant_data, static_member);
-  if (!is_param)
-    m_ast->GetOrCreateVariableDecl(scope_id, var_id);
+  if (!is_param) {
+    auto ts_or_err = GetTypeSystemForLanguage(comp_unit_sp->GetLanguage());
+    if (auto err = ts_or_err.takeError())
+      return nullptr;
+    ts_or_err->GetNativePDBParser()->GetOrCreateVariableDecl(scope_id, var_id);
+  }
   m_local_variables[toOpaqueUid(var_id)] = var_sp;
   return var_sp;
 }
@@ -1790,7 +1861,10 @@
 
   TypeSP target_type = GetOrCreateType(udt.Type);
 
-  (void)m_ast->GetOrCreateTypedefDecl(id);
+  auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+  if (auto err = ts_or_err.takeError())
+    return nullptr;
+  ts_or_err->GetNativePDBParser()->GetOrCreateTypedefDecl(id);
 
   Declaration decl;
   return std::make_shared<lldb_private::Type>(
@@ -1924,28 +1998,38 @@
 }
 
 CompilerDecl SymbolFileNativePDB::GetDeclForUID(lldb::user_id_t uid) {
-  if (auto decl = m_ast->GetOrCreateDeclForUid(uid))
-    return *decl;
-  else
+  auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+  if (auto err = ts_or_err.takeError())
     return CompilerDecl();
+  if (auto decl = ts_or_err->GetNativePDBParser()->GetOrCreateDeclForUid(uid))
+    return *decl;
+  return CompilerDecl();
 }
 
 CompilerDeclContext
 SymbolFileNativePDB::GetDeclContextForUID(lldb::user_id_t uid) {
+  auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+  if (auto err = ts_or_err.takeError())
+    return {};
+  PdbAstBuilder *ast_builder = ts_or_err->GetNativePDBParser();
   clang::DeclContext *context =
-      m_ast->GetOrCreateDeclContextForUid(PdbSymUid(uid));
+      ast_builder->GetOrCreateDeclContextForUid(PdbSymUid(uid));
   if (!context)
     return {};
 
-  return m_ast->ToCompilerDeclContext(*context);
+  return ast_builder->ToCompilerDeclContext(*context);
 }
 
 CompilerDeclContext
 SymbolFileNativePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
-  clang::DeclContext *context = m_ast->GetParentDeclContext(PdbSymUid(uid));
+  auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+  if (auto err = ts_or_err.takeError())
+    return CompilerDeclContext();
+  PdbAstBuilder *ast_builder = ts_or_err->GetNativePDBParser();
+  clang::DeclContext *context = ast_builder->GetParentDeclContext(PdbSymUid(uid));
   if (!context)
     return CompilerDeclContext();
-  return m_ast->ToCompilerDeclContext(*context);
+  return ast_builder->ToCompilerDeclContext(*context);
 }
 
 Type *SymbolFileNativePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
@@ -1977,12 +2061,23 @@
   return llvm::None;
 }
 
-
 bool SymbolFileNativePDB::CompleteType(CompilerType &compiler_type) {
+  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+
+  TypeSystemClang *clang_type_system =
+      llvm::dyn_cast_or_null<TypeSystemClang>(compiler_type.GetTypeSystem());
+  if (!clang_type_system)
+    return false;
+
+  PdbAstBuilder *ast_builder =
+      static_cast<PdbAstBuilder *>(clang_type_system->GetNativePDBParser());
+  if (ast_builder &&
+      ast_builder->GetClangASTImporter().CanImport(compiler_type))
+    return ast_builder->GetClangASTImporter().CompleteType(compiler_type);
   clang::QualType qt =
       clang::QualType::getFromOpaquePtr(compiler_type.GetOpaqueQualType());
 
-  return m_ast->CompleteType(qt);
+  return ast_builder->CompleteType(qt);
 }
 
 void SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
@@ -2009,3 +2104,176 @@
   // PDB files are a separate file that contains all debug info.
   return m_index->pdb().getFileSize();
 }
+
+void SymbolFileNativePDB::BuildParentMap() {
+  LazyRandomTypeCollection &types = m_index->tpi().typeCollection();
+
+  llvm::DenseMap<TypeIndex, TypeIndex> forward_to_full;
+  llvm::DenseMap<TypeIndex, TypeIndex> full_to_forward;
+
+  struct RecordIndices {
+    TypeIndex forward;
+    TypeIndex full;
+  };
+
+  llvm::StringMap<RecordIndices> record_indices;
+
+  for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {
+    CVType type = types.getType(*ti);
+    if (!IsTagRecord(type))
+      continue;
+
+    CVTagRecord tag = CVTagRecord::create(type);
+
+    RecordIndices &indices = record_indices[tag.asTag().getUniqueName()];
+    if (tag.asTag().isForwardRef())
+      indices.forward = *ti;
+    else
+      indices.full = *ti;
+
+    if (indices.full != TypeIndex::None() &&
+        indices.forward != TypeIndex::None()) {
+      forward_to_full[indices.forward] = indices.full;
+      full_to_forward[indices.full] = indices.forward;
+    }
+
+    // We're looking for LF_NESTTYPE records in the field list, so ignore
+    // forward references (no field list), and anything without a nested class
+    // (since there won't be any LF_NESTTYPE records).
+    if (tag.asTag().isForwardRef() || !tag.asTag().containsNestedClass())
+      continue;
+
+    struct ProcessTpiStream : public TypeVisitorCallbacks {
+      ProcessTpiStream(PdbIndex &index, TypeIndex parent,
+                       const CVTagRecord &parent_cvt,
+                       llvm::DenseMap<TypeIndex, TypeIndex> &parents)
+          : index(index), parents(parents), parent(parent),
+            parent_cvt(parent_cvt) {}
+
+      PdbIndex &index;
+      llvm::DenseMap<TypeIndex, TypeIndex> &parents;
+
+      unsigned unnamed_type_index = 1;
+      TypeIndex parent;
+      const CVTagRecord &parent_cvt;
+
+      llvm::Error visitKnownMember(CVMemberRecord &CVR,
+                                   NestedTypeRecord &Record) override {
+        std::string unnamed_type_name;
+        if (Record.Name.empty()) {
+          unnamed_type_name =
+              llvm::formatv("<unnamed-type-$S{0}>", unnamed_type_index).str();
+          Record.Name = unnamed_type_name;
+          ++unnamed_type_index;
+        }
+        llvm::Optional<CVTagRecord> tag =
+            GetNestedTagDefinition(Record, parent_cvt, index.tpi());
+        if (!tag)
+          return llvm::ErrorSuccess();
+
+        parents[Record.Type] = parent;
+        return llvm::ErrorSuccess();
+      }
+    };
+
+    CVType field_list_cvt = m_index->tpi().getType(tag.asTag().FieldList);
+    ProcessTpiStream process(*m_index, *ti, tag, m_parent_types);
+    FieldListRecord field_list;
+    if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>(
+            field_list_cvt, field_list))
+      llvm::consumeError(std::move(error));
+    if (llvm::Error error = visitMemberRecordStream(field_list.Data, process))
+      llvm::consumeError(std::move(error));
+  }
+
+  // Now that we know the forward -> full mapping of all type indices, we can
+  // re-write all the indices.  At the end of this process, we want a mapping
+  // consisting of fwd -> full and full -> full for all child -> parent indices.
+  // We can re-write the values in place, but for the keys, we must save them
+  // off so that we don't modify the map in place while also iterating it.
+  std::vector<TypeIndex> full_keys;
+  std::vector<TypeIndex> fwd_keys;
+  for (auto &entry : m_parent_types) {
+    TypeIndex key = entry.first;
+    TypeIndex value = entry.second;
+
+    auto iter = forward_to_full.find(value);
+    if (iter != forward_to_full.end())
+      entry.second = iter->second;
+
+    iter = forward_to_full.find(key);
+    if (iter != forward_to_full.end())
+      fwd_keys.push_back(key);
+    else
+      full_keys.push_back(key);
+  }
+  for (TypeIndex fwd : fwd_keys) {
+    TypeIndex full = forward_to_full[fwd];
+    m_parent_types[full] = m_parent_types[fwd];
+  }
+  for (TypeIndex full : full_keys) {
+    TypeIndex fwd = full_to_forward[full];
+    m_parent_types[fwd] = m_parent_types[full];
+  }
+}
+
+llvm::Optional<PdbCompilandSymId>
+SymbolFileNativePDB::FindSymbolScope(PdbCompilandSymId id) {
+  CVSymbol sym = m_index->ReadSymbolRecord(id);
+  if (symbolOpensScope(sym.kind())) {
+    // If this exact symbol opens a scope, we can just directly access its
+    // parent.
+    id.offset = getScopeParentOffset(sym);
+    // Global symbols have parent offset of 0.  Return llvm::None to indicate
+    // this.
+    if (id.offset == 0)
+      return llvm::None;
+    return id;
+  }
+
+  // Otherwise we need to start at the beginning and iterate forward until we
+  // reach (or pass) this particular symbol
+  CompilandIndexItem &cii = m_index->compilands().GetOrCreateCompiland(id.modi);
+  const CVSymbolArray &syms = cii.m_debug_stream.getSymbolArray();
+
+  auto begin = syms.begin();
+  auto end = syms.at(id.offset);
+  std::vector<PdbCompilandSymId> scope_stack;
+
+  while (begin != end) {
+    if (begin.offset() > id.offset) {
+      // We passed it.  We couldn't even find this symbol record.
+      lldbassert(false && "Invalid compiland symbol id!");
+      return llvm::None;
+    }
+
+    // We haven't found the symbol yet.  Check if we need to open or close the
+    // scope stack.
+    if (symbolOpensScope(begin->kind())) {
+      // We can use the end offset of the scope to determine whether or not
+      // we can just outright skip this entire scope.
+      uint32_t scope_end = getScopeEndOffset(*begin);
+      if (scope_end < id.offset) {
+        begin = syms.at(scope_end);
+      } else {
+        // The symbol we're looking for is somewhere in this scope.
+        scope_stack.emplace_back(id.modi, begin.offset());
+      }
+    } else if (symbolEndsScope(begin->kind())) {
+      scope_stack.pop_back();
+    }
+    ++begin;
+  }
+  if (scope_stack.empty())
+    return llvm::None;
+  // We have a match!  Return the top of the stack
+  return scope_stack.back();
+}
+
+llvm::Optional<llvm::codeview::TypeIndex>
+SymbolFileNativePDB::GetParentType(llvm::codeview::TypeIndex ti) {
+  auto parent_iter = m_parent_types.find(ti);
+  if (parent_iter == m_parent_types.end())
+    return llvm::None;
+  return parent_iter->second;
+}
Index: lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
===================================================================
--- lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
+++ lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
@@ -51,7 +51,7 @@
 class PdbAstBuilder {
 public:
   // Constructors and Destructors
-  PdbAstBuilder(ObjectFile &obj, PdbIndex &index, TypeSystemClang &clang);
+  PdbAstBuilder(TypeSystemClang &clang);
 
   lldb_private::CompilerDeclContext GetTranslationUnitDecl();
 
@@ -83,7 +83,7 @@
   clang::DeclContext *FromCompilerDeclContext(CompilerDeclContext context);
 
   TypeSystemClang &clang() { return m_clang; }
-  ClangASTImporter &importer() { return m_importer; }
+  ClangASTImporter &GetClangASTImporter() { return m_importer; }
 
   void Dump(Stream &stream);
 
@@ -126,19 +126,16 @@
   void ParseDeclsForSimpleContext(clang::DeclContext &context);
   void ParseBlockChildren(PdbCompilandSymId block_id);
 
-  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;
   TypeSystemClang &m_clang;
 
   ClangASTImporter m_importer;
 
-  llvm::DenseMap<TypeIndex, TypeIndex> m_parent_types;
   llvm::DenseMap<clang::Decl *, DeclStatus> m_decl_to_status;
   llvm::DenseMap<lldb::user_id_t, clang::Decl *> m_uid_to_decl;
   llvm::DenseMap<lldb::user_id_t, clang::QualType> m_uid_to_type;
Index: lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -24,6 +24,7 @@
 
 #include "PdbUtil.h"
 #include "UdtRecordCompleter.h"
+#include "SymbolFileNativePDB.h"
 
 using namespace lldb_private;
 using namespace lldb_private::npdb;
@@ -94,59 +95,6 @@
 };
 } // namespace
 
-static llvm::Optional<PdbCompilandSymId> FindSymbolScope(PdbIndex &index,
-                                                         PdbCompilandSymId id) {
-  CVSymbol sym = index.ReadSymbolRecord(id);
-  if (symbolOpensScope(sym.kind())) {
-    // If this exact symbol opens a scope, we can just directly access its
-    // parent.
-    id.offset = getScopeParentOffset(sym);
-    // Global symbols have parent offset of 0.  Return llvm::None to indicate
-    // this.
-    if (id.offset == 0)
-      return llvm::None;
-    return id;
-  }
-
-  // Otherwise we need to start at the beginning and iterate forward until we
-  // reach (or pass) this particular symbol
-  CompilandIndexItem &cii = index.compilands().GetOrCreateCompiland(id.modi);
-  const CVSymbolArray &syms = cii.m_debug_stream.getSymbolArray();
-
-  auto begin = syms.begin();
-  auto end = syms.at(id.offset);
-  std::vector<PdbCompilandSymId> scope_stack;
-
-  while (begin != end) {
-    if (begin.offset() > id.offset) {
-      // We passed it.  We couldn't even find this symbol record.
-      lldbassert(false && "Invalid compiland symbol id!");
-      return llvm::None;
-    }
-
-    // We haven't found the symbol yet.  Check if we need to open or close the
-    // scope stack.
-    if (symbolOpensScope(begin->kind())) {
-      // We can use the end offset of the scope to determine whether or not
-      // we can just outright skip this entire scope.
-      uint32_t scope_end = getScopeEndOffset(*begin);
-      if (scope_end < id.offset) {
-        begin = syms.at(scope_end);
-      } else {
-        // The symbol we're looking for is somewhere in this scope.
-        scope_stack.emplace_back(id.modi, begin.offset());
-      }
-    } else if (symbolEndsScope(begin->kind())) {
-      scope_stack.pop_back();
-    }
-    ++begin;
-  }
-  if (scope_stack.empty())
-    return llvm::None;
-  // We have a match!  Return the top of the stack
-  return scope_stack.back();
-}
-
 static clang::TagTypeKind TranslateUdtKind(const TagRecord &cr) {
   switch (cr.Kind) {
   case TypeRecordKind::Class:
@@ -207,65 +155,11 @@
   }
 }
 
-static llvm::Optional<CVTagRecord>
-GetNestedTagDefinition(const NestedTypeRecord &Record,
-                       const CVTagRecord &parent, TpiStream &tpi) {
-  // An LF_NESTTYPE is essentially a nested typedef / using declaration, but it
-  // is also used to indicate the primary definition of a nested class.  That is
-  // to say, if you have:
-  // struct A {
-  //   struct B {};
-  //   using C = B;
-  // };
-  // Then in the debug info, this will appear as:
-  // LF_STRUCTURE `A::B` [type index = N]
-  // LF_STRUCTURE `A`
-  //   LF_NESTTYPE [name = `B`, index = N]
-  //   LF_NESTTYPE [name = `C`, index = N]
-  // In order to accurately reconstruct the decl context hierarchy, we need to
-  // know which ones are actual definitions and which ones are just aliases.
-
-  // If it's a simple type, then this is something like `using foo = int`.
-  if (Record.Type.isSimple())
-    return llvm::None;
-
-  CVType cvt = tpi.getType(Record.Type);
-
-  if (!IsTagRecord(cvt))
-    return llvm::None;
-
-  // If it's an inner definition, then treat whatever name we have here as a
-  // single component of a mangled name.  So we can inject it into the parent's
-  // mangled name to see if it matches.
-  CVTagRecord child = CVTagRecord::create(cvt);
-  std::string qname = std::string(parent.asTag().getUniqueName());
-  if (qname.size() < 4 || child.asTag().getUniqueName().size() < 4)
-    return llvm::None;
-
-  // qname[3] is the tag type identifier (struct, class, union, etc).  Since the
-  // inner tag type is not necessarily the same as the outer tag type, re-write
-  // it to match the inner tag type.
-  qname[3] = child.asTag().getUniqueName()[3];
-  std::string piece;
-  if (qname[3] == 'W')
-    piece = "4";
-  piece += Record.Name;
-  piece.push_back('@');
-  qname.insert(4, std::move(piece));
-  if (qname != child.asTag().UniqueName)
-    return llvm::None;
-
-  return std::move(child);
-}
-
 static bool IsAnonymousNamespaceName(llvm::StringRef name) {
   return name == "`anonymous namespace'" || name == "`anonymous-namespace'";
 }
 
-PdbAstBuilder::PdbAstBuilder(ObjectFile &obj, PdbIndex &index, TypeSystemClang &clang)
-    : m_index(index), m_clang(clang) {
-  BuildParentMap();
-}
+PdbAstBuilder::PdbAstBuilder(TypeSystemClang &clang) : m_clang(clang) {}
 
 lldb_private::CompilerDeclContext PdbAstBuilder::GetTranslationUnitDecl() {
   return ToCompilerDeclContext(*m_clang.GetTranslationUnitDecl());
@@ -273,6 +167,8 @@
 
 std::pair<clang::DeclContext *, std::string>
 PdbAstBuilder::CreateDeclInfoForType(const TagRecord &record, TypeIndex ti) {
+  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
+      m_clang.GetSymbolFile()->GetBackingSymbolFile());
   // FIXME: Move this to GetDeclContextContainingUID.
   if (!record.hasUniqueName())
     return CreateDeclInfoForUndecoratedName(record.Name);
@@ -297,8 +193,8 @@
   // If this type doesn't have a parent type in the debug info, then the best we
   // can do is to say that it's either a series of namespaces (if the scope is
   // non-empty), or the translation unit (if the scope is empty).
-  auto parent_iter = m_parent_types.find(ti);
-  if (parent_iter == m_parent_types.end()) {
+  llvm::Optional<TypeIndex> parent_index = pdb->GetParentType(ti);
+  if (!parent_index) {
     if (scopes.empty())
       return {context, uname};
 
@@ -322,7 +218,7 @@
   // recurse into our lazy type creation / AST reconstruction logic to get an
   // LLDB TypeSP for the parent.  This will cause the AST to automatically get
   // the right DeclContext created for any parent.
-  clang::QualType parent_qt = GetOrCreateType(parent_iter->second);
+  clang::QualType parent_qt = GetOrCreateType(*parent_index);
   if (parent_qt.isNull())
     return {nullptr, ""};
 
@@ -330,120 +226,6 @@
   return {context, uname};
 }
 
-void PdbAstBuilder::BuildParentMap() {
-  LazyRandomTypeCollection &types = m_index.tpi().typeCollection();
-
-  llvm::DenseMap<TypeIndex, TypeIndex> forward_to_full;
-  llvm::DenseMap<TypeIndex, TypeIndex> full_to_forward;
-
-  struct RecordIndices {
-    TypeIndex forward;
-    TypeIndex full;
-  };
-
-  llvm::StringMap<RecordIndices> record_indices;
-
-  for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {
-    CVType type = types.getType(*ti);
-    if (!IsTagRecord(type))
-      continue;
-
-    CVTagRecord tag = CVTagRecord::create(type);
-
-    RecordIndices &indices = record_indices[tag.asTag().getUniqueName()];
-    if (tag.asTag().isForwardRef())
-      indices.forward = *ti;
-    else
-      indices.full = *ti;
-
-    if (indices.full != TypeIndex::None() &&
-        indices.forward != TypeIndex::None()) {
-      forward_to_full[indices.forward] = indices.full;
-      full_to_forward[indices.full] = indices.forward;
-    }
-
-    // We're looking for LF_NESTTYPE records in the field list, so ignore
-    // forward references (no field list), and anything without a nested class
-    // (since there won't be any LF_NESTTYPE records).
-    if (tag.asTag().isForwardRef() || !tag.asTag().containsNestedClass())
-      continue;
-
-    struct ProcessTpiStream : public TypeVisitorCallbacks {
-      ProcessTpiStream(PdbIndex &index, TypeIndex parent,
-                       const CVTagRecord &parent_cvt,
-                       llvm::DenseMap<TypeIndex, TypeIndex> &parents)
-          : index(index), parents(parents), parent(parent),
-            parent_cvt(parent_cvt) {}
-
-      PdbIndex &index;
-      llvm::DenseMap<TypeIndex, TypeIndex> &parents;
-
-      unsigned unnamed_type_index = 1;
-      TypeIndex parent;
-      const CVTagRecord &parent_cvt;
-
-      llvm::Error visitKnownMember(CVMemberRecord &CVR,
-                                   NestedTypeRecord &Record) override {
-        std::string unnamed_type_name;
-        if (Record.Name.empty()) {
-          unnamed_type_name =
-              llvm::formatv("<unnamed-type-$S{0}>", unnamed_type_index).str();
-          Record.Name = unnamed_type_name;
-          ++unnamed_type_index;
-        }
-        llvm::Optional<CVTagRecord> tag =
-            GetNestedTagDefinition(Record, parent_cvt, index.tpi());
-        if (!tag)
-          return llvm::ErrorSuccess();
-
-        parents[Record.Type] = parent;
-        return llvm::ErrorSuccess();
-      }
-    };
-
-    CVType field_list_cvt = m_index.tpi().getType(tag.asTag().FieldList);
-    ProcessTpiStream process(m_index, *ti, tag, m_parent_types);
-    FieldListRecord field_list;
-    if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>(
-            field_list_cvt, field_list))
-      llvm::consumeError(std::move(error));
-    if (llvm::Error error = visitMemberRecordStream(field_list.Data, process))
-      llvm::consumeError(std::move(error));
-  }
-
-  // Now that we know the forward -> full mapping of all type indices, we can
-  // re-write all the indices.  At the end of this process, we want a mapping
-  // consisting of fwd -> full and full -> full for all child -> parent indices.
-  // We can re-write the values in place, but for the keys, we must save them
-  // off so that we don't modify the map in place while also iterating it.
-  std::vector<TypeIndex> full_keys;
-  std::vector<TypeIndex> fwd_keys;
-  for (auto &entry : m_parent_types) {
-    TypeIndex key = entry.first;
-    TypeIndex value = entry.second;
-
-    auto iter = forward_to_full.find(value);
-    if (iter != forward_to_full.end())
-      entry.second = iter->second;
-
-    iter = forward_to_full.find(key);
-    if (iter != forward_to_full.end())
-      fwd_keys.push_back(key);
-    else
-      full_keys.push_back(key);
-  }
-  for (TypeIndex fwd : fwd_keys) {
-    TypeIndex full = forward_to_full[fwd];
-    m_parent_types[full] = m_parent_types[fwd];
-  }
-  for (TypeIndex full : full_keys) {
-    TypeIndex fwd = full_to_forward[full];
-    m_parent_types[fwd] = m_parent_types[full];
-  }
-
-  // Now that
-}
-
 static bool isLocalVariableType(SymbolKind K) {
   switch (K) {
   case S_REGISTER:
@@ -457,7 +239,10 @@
 }
 
 clang::Decl *PdbAstBuilder::GetOrCreateSymbolForId(PdbCompilandSymId id) {
-  CVSymbol cvs = m_index.ReadSymbolRecord(id);
+  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
+      m_clang.GetSymbolFile()->GetBackingSymbolFile());
+  PdbIndex &index = pdb->GetIndex();
+  CVSymbol cvs = index.ReadSymbolRecord(id);
 
   if (isLocalVariableType(cvs.kind())) {
     clang::DeclContext *scope = GetParentDeclContext(id);
@@ -534,6 +319,9 @@
 
 std::pair<clang::DeclContext *, std::string>
 PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) {
+  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
+      m_clang.GetSymbolFile()->GetBackingSymbolFile());
+  PdbIndex &index = pdb->GetIndex();
   MSVCUndecoratedNameParser parser(name);
   llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
 
@@ -547,7 +335,7 @@
   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);
+  std::vector<TypeIndex> types = index.tpi().findRecordsByName(scope_name);
   while (!types.empty()) {
     clang::QualType qt = GetOrCreateType(types.back());
     if (qt.isNull())
@@ -569,24 +357,27 @@
 clang::DeclContext *PdbAstBuilder::GetParentDeclContext(PdbSymUid uid) {
   // We must do this *without* calling GetOrCreate on the current uid, as
   // that would be an infinite recursion.
+  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
+      m_clang.GetSymbolFile()->GetBackingSymbolFile());
+  PdbIndex& index = pdb->GetIndex();
   switch (uid.kind()) {
   case PdbSymUidKind::CompilandSym: {
     llvm::Optional<PdbCompilandSymId> scope =
-        FindSymbolScope(m_index, uid.asCompilandSym());
+        pdb->FindSymbolScope(uid.asCompilandSym());
     if (scope)
       return GetOrCreateDeclContextForUid(*scope);
 
-    CVSymbol sym = m_index.ReadSymbolRecord(uid.asCompilandSym());
+    CVSymbol sym = index.ReadSymbolRecord(uid.asCompilandSym());
     return CreateDeclInfoForUndecoratedName(getSymbolName(sym)).first;
   }
   case PdbSymUidKind::Type: {
     // It could be a namespace, class, or global.  We don't support nested
     // functions yet.  Anyway, we just need to consult the parent type map.
     PdbTypeSymId type_id = uid.asTypeSym();
-    auto iter = m_parent_types.find(type_id.index);
-    if (iter == m_parent_types.end())
+    llvm::Optional<TypeIndex> parent_index = pdb->GetParentType(type_id.index);
+    if (!parent_index)
       return FromCompilerDeclContext(GetTranslationUnitDecl());
-    return GetOrCreateDeclContextForUid(PdbTypeSymId(iter->second));
+    return GetOrCreateDeclContextForUid(PdbTypeSymId(*parent_index));
   }
   case PdbSymUidKind::FieldListMember:
     // In this case the parent DeclContext is the one for the class that this
@@ -599,7 +390,7 @@
     // 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());
+    CVSymbol global = index.ReadSymbolRecord(uid.asGlobalSym());
     switch (global.kind()) {
     case SymbolKind::S_GDATA32:
     case SymbolKind::S_LDATA32:
@@ -651,19 +442,21 @@
     return true;
 
   PdbTypeSymId type_id = PdbSymUid(status.uid).asTypeSym();
-
-  lldbassert(IsTagRecord(type_id, m_index.tpi()));
+  PdbIndex &index = static_cast<SymbolFileNativePDB *>(
+                        m_clang.GetSymbolFile()->GetBackingSymbolFile())
+                        ->GetIndex();
+  lldbassert(IsTagRecord(type_id, index.tpi()));
 
   clang::QualType tag_qt = m_clang.getASTContext().getTypeDeclType(&tag);
   TypeSystemClang::SetHasExternalStorage(tag_qt.getAsOpaquePtr(), false);
 
   TypeIndex tag_ti = type_id.index;
-  CVType cvt = m_index.tpi().getType(tag_ti);
+  CVType cvt = index.tpi().getType(tag_ti);
   if (cvt.kind() == LF_MODIFIER)
     tag_ti = LookThroughModifierRecord(cvt);
 
-  PdbTypeSymId best_ti = GetBestPossibleDecl(tag_ti, m_index.tpi());
-  cvt = m_index.tpi().getType(best_ti.index);
+  PdbTypeSymId best_ti = GetBestPossibleDecl(tag_ti, index.tpi());
+  cvt = index.tpi().getType(best_ti.index);
   lldbassert(IsTagRecord(cvt));
 
   if (IsForwardRefUdt(cvt)) {
@@ -673,7 +466,7 @@
   }
 
   TypeIndex field_list_ti = GetFieldListIndex(cvt);
-  CVType field_list_cvt = m_index.tpi().getType(field_list_ti);
+  CVType field_list_cvt = index.tpi().getType(field_list_ti);
   if (field_list_cvt.kind() != LF_FIELDLIST)
     return false;
   FieldListRecord field_list;
@@ -684,7 +477,7 @@
   // Visit all members of this class, then perform any finalization necessary
   // to complete the class.
   CompilerType ct = ToCompilerType(tag_qt);
-  UdtRecordCompleter completer(best_ti, ct, tag, *this, m_index,
+  UdtRecordCompleter completer(best_ti, ct, tag, *this, index,
                                m_cxx_record_map);
   llvm::Error error =
       llvm::codeview::visitMemberRecordStream(field_list.Data, completer);
@@ -900,7 +693,10 @@
   if (!scope)
     return nullptr;
 
-  CVSymbol sym = m_index.ReadSymbolRecord(var_id);
+  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
+      m_clang.GetSymbolFile()->GetBackingSymbolFile());
+  PdbIndex &index = pdb->GetIndex();
+  CVSymbol sym = index.ReadSymbolRecord(var_id);
   return CreateVariableDecl(PdbSymUid(var_id), sym, *scope);
 }
 
@@ -908,7 +704,10 @@
   if (clang::Decl *decl = TryGetDecl(var_id))
     return llvm::dyn_cast<clang::VarDecl>(decl);
 
-  CVSymbol sym = m_index.ReadSymbolRecord(var_id);
+  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
+      m_clang.GetSymbolFile()->GetBackingSymbolFile());
+  PdbIndex &index = pdb->GetIndex();
+  CVSymbol sym = index.ReadSymbolRecord(var_id);
   auto context = FromCompilerDeclContext(GetTranslationUnitDecl());
   return CreateVariableDecl(PdbSymUid(var_id), sym, *context);
 }
@@ -918,7 +717,10 @@
   if (clang::Decl *decl = TryGetDecl(id))
     return llvm::dyn_cast<clang::TypedefNameDecl>(decl);
 
-  CVSymbol sym = m_index.ReadSymbolRecord(id);
+  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
+      m_clang.GetSymbolFile()->GetBackingSymbolFile());
+  PdbIndex &index = pdb->GetIndex();
+  CVSymbol sym = index.ReadSymbolRecord(id);
   lldbassert(sym.kind() == S_UDT);
   UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym));
 
@@ -950,7 +752,10 @@
   if (type.index.isSimple())
     return CreateSimpleType(type.index);
 
-  CVType cvt = m_index.tpi().getType(type.index);
+  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
+      m_clang.GetSymbolFile()->GetBackingSymbolFile());
+  PdbIndex &index = pdb->GetIndex();
+  CVType cvt = index.tpi().getType(type.index);
 
   if (cvt.kind() == LF_MODIFIER) {
     ModifierRecord modifier;
@@ -1006,7 +811,10 @@
   if (iter != m_uid_to_type.end())
     return iter->second;
 
-  PdbTypeSymId best_type = GetBestPossibleDecl(type, m_index.tpi());
+  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
+      m_clang.GetSymbolFile()->GetBackingSymbolFile());
+  PdbIndex &index = pdb->GetIndex();
+  PdbTypeSymId best_type = GetBestPossibleDecl(type, index.tpi());
 
   clang::QualType qt;
   if (best_type.index != type.index) {
@@ -1026,7 +834,7 @@
     return {};
 
   m_uid_to_type[toOpaqueUid(type)] = qt;
-  if (IsTagRecord(type, m_index.tpi())) {
+  if (IsTagRecord(type, index.tpi())) {
     clang::TagDecl *tag = qt->getAsTagDecl();
     lldbassert(m_decl_to_status.count(tag) == 0);
 
@@ -1045,6 +853,9 @@
                                   bool is_inline, clang::DeclContext *parent) {
   clang::FunctionDecl *function_decl = nullptr;
   if (parent->isRecord()) {
+    SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
+        m_clang.GetSymbolFile()->GetBackingSymbolFile());
+    PdbIndex &index = pdb->GetIndex();
     clang::QualType parent_qt = llvm::cast<clang::TypeDecl>(parent)
                                     ->getTypeForDecl()
                                     ->getCanonicalTypeInternal();
@@ -1058,29 +869,29 @@
       }
     }
 
-    CVType cvt = m_index.tpi().getType(func_ti);
+    CVType cvt = index.tpi().getType(func_ti);
     MemberFunctionRecord func_record(static_cast<TypeRecordKind>(cvt.kind()));
     llvm::cantFail(TypeDeserializer::deserializeAs<MemberFunctionRecord>(
         cvt, func_record));
     TypeIndex class_index = func_record.getClassType();
 
-    CVType parent_cvt = m_index.tpi().getType(class_index);
+    CVType parent_cvt = index.tpi().getType(class_index);
     TagRecord tag_record = CVTagRecord::create(parent_cvt).asTag();
     // If it's a forward reference, try to get the real TypeIndex.
     if (tag_record.isForwardRef()) {
       llvm::Expected<TypeIndex> eti =
-          m_index.tpi().findFullDeclForForwardRef(class_index);
+          index.tpi().findFullDeclForForwardRef(class_index);
       if (eti) {
-        tag_record = CVTagRecord::create(m_index.tpi().getType(*eti)).asTag();
+        tag_record = CVTagRecord::create(index.tpi().getType(*eti)).asTag();
       }
     }
     if (!tag_record.FieldList.isSimple()) {
-      CVType field_list_cvt = m_index.tpi().getType(tag_record.FieldList);
+      CVType field_list_cvt = index.tpi().getType(tag_record.FieldList);
       FieldListRecord field_list;
       if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>(
               field_list_cvt, field_list))
         llvm::consumeError(std::move(error));
-      CreateMethodDecl process(m_index, m_clang, func_ti, function_decl,
+      CreateMethodDecl process(index, m_clang, func_ti, function_decl,
                                parent_opaque_ty, func_name, func_ct);
       if (llvm::Error err = visitMemberRecordStream(field_list.Data, process))
         llvm::consumeError(std::move(err));
@@ -1107,8 +918,11 @@
 
 clang::FunctionDecl *
 PdbAstBuilder::GetOrCreateInlinedFunctionDecl(PdbCompilandSymId inlinesite_id) {
+  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
+      m_clang.GetSymbolFile()->GetBackingSymbolFile());
+  PdbIndex &index = pdb->GetIndex();
   CompilandIndexItem *cii =
-      m_index.compilands().GetCompiland(inlinesite_id.modi);
+      index.compilands().GetCompiland(inlinesite_id.modi);
   CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(inlinesite_id.offset);
   InlineSiteSym inline_site(static_cast<SymbolRecordKind>(sym.kind()));
   cantFail(SymbolDeserializer::deserializeAs<InlineSiteSym>(sym, inline_site));
@@ -1145,7 +959,10 @@
 PdbAstBuilder::CreateFunctionDeclFromId(PdbTypeSymId func_tid,
                                         PdbCompilandSymId func_sid) {
   lldbassert(func_tid.is_ipi);
-  CVType func_cvt = m_index.ipi().getType(func_tid.index);
+  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
+      m_clang.GetSymbolFile()->GetBackingSymbolFile());
+  PdbIndex &index = pdb->GetIndex();
+  CVType func_cvt = index.ipi().getType(func_tid.index);
   llvm::StringRef func_name;
   TypeIndex func_ti;
   clang::DeclContext *parent = nullptr;
@@ -1167,7 +984,7 @@
     func_ti = fir.getFunctionType();
     parent = FromCompilerDeclContext(GetTranslationUnitDecl());
     if (!fir.ParentScope.isNoneType()) {
-      CVType parent_cvt = m_index.ipi().getType(fir.ParentScope);
+      CVType parent_cvt = index.ipi().getType(fir.ParentScope);
       if (parent_cvt.kind() == LF_STRING_ID) {
         StringIdRecord sir;
         cantFail(
@@ -1205,7 +1022,10 @@
     context_name = tag->getQualifiedNameAsString();
   }
 
-  CVSymbol cvs = m_index.ReadSymbolRecord(func_id);
+  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
+      m_clang.GetSymbolFile()->GetBackingSymbolFile());
+  PdbIndex &index = pdb->GetIndex();
+  CVSymbol cvs = index.ReadSymbolRecord(func_id);
   ProcSym proc(static_cast<SymbolRecordKind>(cvs.kind()));
   llvm::cantFail(SymbolDeserializer::deserializeAs<ProcSym>(cvs, proc));
 
@@ -1245,7 +1065,10 @@
 void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id,
                                              clang::FunctionDecl &function_decl,
                                              uint32_t param_count) {
-  CompilandIndexItem *cii = m_index.compilands().GetCompiland(func_id.modi);
+  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
+      m_clang.GetSymbolFile()->GetBackingSymbolFile());
+  PdbIndex &index = pdb->GetIndex();
+  CompilandIndexItem *cii = index.compilands().GetCompiland(func_id.modi);
   CVSymbolArray scope =
       cii->m_debug_stream.getSymbolArrayForScope(func_id.offset);
 
@@ -1340,7 +1163,10 @@
 clang::QualType PdbAstBuilder::CreateArrayType(const ArrayRecord &ar) {
   clang::QualType element_type = GetOrCreateType(ar.ElementType);
 
-  uint64_t element_size = GetSizeOfType({ar.ElementType}, m_index.tpi());
+  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
+      m_clang.GetSymbolFile()->GetBackingSymbolFile());
+  PdbIndex &index = pdb->GetIndex();
+  uint64_t element_size = GetSizeOfType({ar.ElementType}, index.tpi());
   if (element_type.isNull() || element_size == 0)
     return {};
   uint64_t element_count = ar.Size / element_size;
@@ -1353,7 +1179,10 @@
 clang::QualType PdbAstBuilder::CreateFunctionType(
     TypeIndex args_type_idx, TypeIndex return_type_idx,
     llvm::codeview::CallingConvention calling_convention) {
-  TpiStream &stream = m_index.tpi();
+  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
+      m_clang.GetSymbolFile()->GetBackingSymbolFile());
+  PdbIndex &index = pdb->GetIndex();
+  TpiStream &stream = index.tpi();
   CVType args_cvt = stream.getType(args_type_idx);
   ArgListRecord args;
   llvm::cantFail(
@@ -1405,8 +1234,11 @@
 
 void PdbAstBuilder::ParseAllNamespacesPlusChildrenOf(
     llvm::Optional<llvm::StringRef> parent) {
-  TypeIndex ti{m_index.tpi().TypeIndexBegin()};
-  for (const CVType &cvt : m_index.tpi().typeArray()) {
+  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
+      m_clang.GetSymbolFile()->GetBackingSymbolFile());
+  PdbIndex &index = pdb->GetIndex();
+  TypeIndex ti{index.tpi().TypeIndexBegin()};
+  for (const CVType &cvt : index.tpi().typeArray()) {
     PdbTypeSymId tid{ti};
     ++ti;
 
@@ -1439,9 +1271,9 @@
     }
   }
 
-  uint32_t module_count = m_index.dbi().modules().getModuleCount();
+  uint32_t module_count = index.dbi().modules().getModuleCount();
   for (uint16_t modi = 0; modi < module_count; ++modi) {
-    CompilandIndexItem &cii = m_index.compilands().GetOrCreateCompiland(modi);
+    CompilandIndexItem &cii = index.compilands().GetOrCreateCompiland(modi);
     const CVSymbolArray &symbols = cii.m_debug_stream.getSymbolArray();
     auto iter = symbols.begin();
     while (iter != symbols.end()) {
@@ -1495,11 +1327,14 @@
 }
 
 void PdbAstBuilder::ParseBlockChildren(PdbCompilandSymId block_id) {
-  CVSymbol sym = m_index.ReadSymbolRecord(block_id);
+  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
+      m_clang.GetSymbolFile()->GetBackingSymbolFile());
+  PdbIndex &index = pdb->GetIndex();
+  CVSymbol sym = index.ReadSymbolRecord(block_id);
   lldbassert(sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32 ||
              sym.kind() == S_BLOCK32 || sym.kind() == S_INLINESITE);
   CompilandIndexItem &cii =
-      m_index.compilands().GetOrCreateCompiland(block_id.modi);
+      index.compilands().GetOrCreateCompiland(block_id.modi);
   CVSymbolArray symbols =
       cii.m_debug_stream.getSymbolArrayForScope(block_id.offset);
 
Index: lldb/include/lldb/Symbol/TypeSystem.h
===================================================================
--- lldb/include/lldb/Symbol/TypeSystem.h
+++ lldb/include/lldb/Symbol/TypeSystem.h
@@ -31,6 +31,9 @@
 class PDBASTParser;
 
 namespace lldb_private {
+namespace npdb {
+  class PdbAstBuilder;
+} // namespace npdb
 
 /// A SmallBitVector that represents a set of source languages (\p
 /// lldb::LanguageType).  Each lldb::LanguageType is represented by
@@ -88,6 +91,7 @@
 
   virtual DWARFASTParser *GetDWARFParser() { return nullptr; }
   virtual PDBASTParser *GetPDBParser() { return nullptr; }
+  virtual npdb::PdbAstBuilder *GetNativePDBParser() { return nullptr; }
 
   virtual SymbolFile *GetSymbolFile() const { return m_sym_file; }
 
@@ -366,7 +370,7 @@
   LLVM_DUMP_METHOD virtual void
   dump(lldb::opaque_compiler_type_t type) const = 0;
 #endif
-  
+
   virtual void DumpValue(lldb::opaque_compiler_type_t type,
                          ExecutionContext *exe_ctx, Stream *s,
                          lldb::Format format, const DataExtractor &data,
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to