diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:06:29 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:06:29 +0000 | 
| commit | 94994d372d014ce4c8758b9605d63fae651bd8aa (patch) | |
| tree | 51c0b708bd59f205d6b35cb2a8c24d62f0c33d77 /source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp | |
| parent | 39be7ce23363d12ae3e49aeb1fdb2bfeb892e836 (diff) | |
Notes
Diffstat (limited to 'source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp')
| -rw-r--r-- | source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp | 591 | 
1 files changed, 418 insertions, 173 deletions
diff --git a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index 05f3017819fa..ad25842f4d05 100644 --- a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -9,6 +9,9 @@  #include "SymbolFilePDB.h" +#include "PDBASTParser.h" +#include "PDBLocationToDWARFExpression.h" +  #include "clang/Lex/Lexer.h"  #include "lldb/Core/Module.h" @@ -46,8 +49,8 @@  #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"  #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" -#include "Plugins/SymbolFile/PDB/PDBASTParser.h" -#include "Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h" +#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" +#include "Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h"  #include <regex> @@ -74,14 +77,32 @@ bool ShouldAddLine(uint32_t requested_line, uint32_t actual_line,  }  } // namespace +static bool ShouldUseNativeReader() { +#if defined(_WIN32) +  llvm::StringRef use_native = ::getenv("LLDB_USE_NATIVE_PDB_READER"); +  return use_native.equals_lower("on") || use_native.equals_lower("yes") || +         use_native.equals_lower("1") || use_native.equals_lower("true"); +#else +  return true; +#endif +} +  void SymbolFilePDB::Initialize() { -  PluginManager::RegisterPlugin(GetPluginNameStatic(), -                                GetPluginDescriptionStatic(), CreateInstance, -                                DebuggerInitialize); +  if (ShouldUseNativeReader()) { +    npdb::SymbolFileNativePDB::Initialize(); +  } else { +    PluginManager::RegisterPlugin(GetPluginNameStatic(), +                                  GetPluginDescriptionStatic(), CreateInstance, +                                  DebuggerInitialize); +  }  }  void SymbolFilePDB::Terminate() { -  PluginManager::UnregisterPlugin(CreateInstance); +  if (ShouldUseNativeReader()) { +    npdb::SymbolFileNativePDB::Terminate(); +  } else { +    PluginManager::UnregisterPlugin(CreateInstance); +  }  }  void SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger) {} @@ -246,14 +267,8 @@ lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index) {    return ParseCompileUnitForUID(compiland_up->getSymIndexId(), index);  } -lldb::LanguageType -SymbolFilePDB::ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) { -  // What fields should I expect to be filled out on the SymbolContext?  Is it -  // safe to assume that `sc.comp_unit` is valid? -  if (!sc.comp_unit) -    return lldb::eLanguageTypeUnknown; - -  auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID()); +lldb::LanguageType SymbolFilePDB::ParseLanguage(CompileUnit &comp_unit) { +  auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());    if (!compiland_up)      return lldb::eLanguageTypeUnknown;    auto details = compiland_up->findOneChild<PDBSymbolCompilandDetails>(); @@ -262,9 +277,11 @@ SymbolFilePDB::ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) {    return TranslateLanguage(details->getLanguage());  } -lldb_private::Function *SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc( -    const PDBSymbolFunc &pdb_func, const lldb_private::SymbolContext &sc) { -  lldbassert(sc.comp_unit && sc.module_sp.get()); +lldb_private::Function * +SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func, +                                                  CompileUnit &comp_unit) { +  if (FunctionSP result = comp_unit.FindFunctionByUID(pdb_func.getSymIndexId())) +    return result.get();    auto file_vm_addr = pdb_func.getVirtualAddress();    if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0) @@ -272,7 +289,8 @@ lldb_private::Function *SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(    auto func_length = pdb_func.getLength();    AddressRange func_range = -      AddressRange(file_vm_addr, func_length, sc.module_sp->GetSectionList()); +      AddressRange(file_vm_addr, func_length, +                   GetObjectFile()->GetModule()->GetSectionList());    if (!func_range.GetBaseAddress().IsValid())      return nullptr; @@ -285,59 +303,61 @@ lldb_private::Function *SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(    Mangled mangled = GetMangledForPDBFunc(pdb_func);    FunctionSP func_sp = -      std::make_shared<Function>(sc.comp_unit, pdb_func.getSymIndexId(), +      std::make_shared<Function>(&comp_unit, pdb_func.getSymIndexId(),                                   func_type_uid, mangled, func_type, func_range); -  sc.comp_unit->AddFunction(func_sp); +  comp_unit.AddFunction(func_sp); + +  TypeSystem *type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); +  if (!type_system) +    return nullptr; +  ClangASTContext *clang_type_system = +    llvm::dyn_cast_or_null<ClangASTContext>(type_system); +  if (!clang_type_system) +    return nullptr; +  clang_type_system->GetPDBParser()->GetDeclForSymbol(pdb_func); +    return func_sp.get();  } -size_t SymbolFilePDB::ParseCompileUnitFunctions( -    const lldb_private::SymbolContext &sc) { -  lldbassert(sc.comp_unit); +size_t SymbolFilePDB::ParseFunctions(CompileUnit &comp_unit) {    size_t func_added = 0; -  auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID()); +  auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());    if (!compiland_up)      return 0;    auto results_up = compiland_up->findAllChildren<PDBSymbolFunc>();    if (!results_up)      return 0;    while (auto pdb_func_up = results_up->getNext()) { -    auto func_sp = -        sc.comp_unit->FindFunctionByUID(pdb_func_up->getSymIndexId()); +    auto func_sp = comp_unit.FindFunctionByUID(pdb_func_up->getSymIndexId());      if (!func_sp) { -      if (ParseCompileUnitFunctionForPDBFunc(*pdb_func_up, sc)) +      if (ParseCompileUnitFunctionForPDBFunc(*pdb_func_up, comp_unit))          ++func_added;      }    }    return func_added;  } -bool SymbolFilePDB::ParseCompileUnitLineTable( -    const lldb_private::SymbolContext &sc) { -  lldbassert(sc.comp_unit); -  if (sc.comp_unit->GetLineTable()) +bool SymbolFilePDB::ParseLineTable(CompileUnit &comp_unit) { +  if (comp_unit.GetLineTable())      return true; -  return ParseCompileUnitLineTable(sc, 0); +  return ParseCompileUnitLineTable(comp_unit, 0);  } -bool SymbolFilePDB::ParseCompileUnitDebugMacros( -    const lldb_private::SymbolContext &sc) { +bool SymbolFilePDB::ParseDebugMacros(CompileUnit &comp_unit) {    // PDB doesn't contain information about macros    return false;  } -bool SymbolFilePDB::ParseCompileUnitSupportFiles( -    const lldb_private::SymbolContext &sc, -    lldb_private::FileSpecList &support_files) { -  lldbassert(sc.comp_unit); +bool SymbolFilePDB::ParseSupportFiles( +    CompileUnit &comp_unit, lldb_private::FileSpecList &support_files) {    // In theory this is unnecessary work for us, because all of this information    // is easily (and quickly) accessible from DebugInfoPDB, so caching it a    // second time seems like a waste.  Unfortunately, there's no good way around    // this short of a moderate refactor since SymbolVendor depends on being able    // to cache this list. -  auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID()); +  auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());    if (!compiland_up)      return false;    auto files = m_session_up->getSourceFilesForCompiland(*compiland_up); @@ -345,13 +365,13 @@ bool SymbolFilePDB::ParseCompileUnitSupportFiles(      return false;    while (auto file = files->getNext()) { -    FileSpec spec(file->getFileName(), false, FileSpec::Style::windows); +    FileSpec spec(file->getFileName(), FileSpec::Style::windows);      support_files.AppendIfUnique(spec);    }    // LLDB uses the DWARF-like file numeration (one based),    // the zeroth file is the compile unit itself -  support_files.Insert(0, *sc.comp_unit); +  support_files.Insert(0, comp_unit);    return true;  } @@ -364,9 +384,8 @@ bool SymbolFilePDB::ParseImportedModules(  }  static size_t ParseFunctionBlocksForPDBSymbol( -    const lldb_private::SymbolContext &sc, uint64_t func_file_vm_addr, -    const llvm::pdb::PDBSymbol *pdb_symbol, lldb_private::Block *parent_block, -    bool is_top_parent) { +    uint64_t func_file_vm_addr, const llvm::pdb::PDBSymbol *pdb_symbol, +    lldb_private::Block *parent_block, bool is_top_parent) {    assert(pdb_symbol && parent_block);    size_t num_added = 0; @@ -405,7 +424,7 @@ static size_t ParseFunctionBlocksForPDBSymbol(        break;      while (auto symbol_up = results_up->getNext()) {        num_added += ParseFunctionBlocksForPDBSymbol( -          sc, func_file_vm_addr, symbol_up.get(), block, false); +          func_file_vm_addr, symbol_up.get(), block, false);      }    } break;    default: @@ -414,28 +433,22 @@ static size_t ParseFunctionBlocksForPDBSymbol(    return num_added;  } -size_t -SymbolFilePDB::ParseFunctionBlocks(const lldb_private::SymbolContext &sc) { -  lldbassert(sc.comp_unit && sc.function); +size_t SymbolFilePDB::ParseBlocksRecursive(Function &func) {    size_t num_added = 0; -  auto uid = sc.function->GetID(); +  auto uid = func.GetID();    auto pdb_func_up = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(uid);    if (!pdb_func_up)      return 0; -  Block &parent_block = sc.function->GetBlock(false); -  num_added = -      ParseFunctionBlocksForPDBSymbol(sc, pdb_func_up->getVirtualAddress(), -                                      pdb_func_up.get(), &parent_block, true); +  Block &parent_block = func.GetBlock(false); +  num_added = ParseFunctionBlocksForPDBSymbol( +      pdb_func_up->getVirtualAddress(), pdb_func_up.get(), &parent_block, true);    return num_added;  } -size_t SymbolFilePDB::ParseTypes(const lldb_private::SymbolContext &sc) { -  lldbassert(sc.module_sp.get()); -  if (!sc.comp_unit) -    return 0; +size_t SymbolFilePDB::ParseTypes(CompileUnit &comp_unit) {    size_t num_added = 0; -  auto compiland = GetPDBCompilandByUID(sc.comp_unit->GetID()); +  auto compiland = GetPDBCompilandByUID(comp_unit.GetID());    if (!compiland)      return 0; @@ -459,31 +472,26 @@ size_t SymbolFilePDB::ParseTypes(const lldb_private::SymbolContext &sc) {          // This should cause the type to get cached and stored in the `m_types`          // lookup. -        if (!ResolveTypeUID(symbol->getSymIndexId())) -          continue; - -        ++num_added; +        if (auto type = ResolveTypeUID(symbol->getSymIndexId())) { +          // Resolve the type completely to avoid a completion +          // (and so a list change, which causes an iterators invalidation) +          // during a TypeList dumping +          type->GetFullCompilerType(); +          ++num_added; +        }        }      }    }; -  if (sc.function) { -    auto pdb_func = m_session_up->getConcreteSymbolById<PDBSymbolFunc>( -        sc.function->GetID()); -    if (!pdb_func) -      return 0; -    ParseTypesByTagFn(*pdb_func); -  } else { -    ParseTypesByTagFn(*compiland); - -    // Also parse global types particularly coming from this compiland. -    // Unfortunately, PDB has no compiland information for each global type. We -    // have to parse them all. But ensure we only do this once. -    static bool parse_all_global_types = false; -    if (!parse_all_global_types) { -      ParseTypesByTagFn(*m_global_scope_up); -      parse_all_global_types = true; -    } +  ParseTypesByTagFn(*compiland); + +  // Also parse global types particularly coming from this compiland. +  // Unfortunately, PDB has no compiland information for each global type. We +  // have to parse them all. But ensure we only do this once. +  static bool parse_all_global_types = false; +  if (!parse_all_global_types) { +    ParseTypesByTagFn(*m_global_scope_up); +    parse_all_global_types = true;    }    return num_added;  } @@ -513,7 +521,7 @@ SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) {      auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();      if (results && results->getChildCount()) {        while (auto result = results->getNext()) { -        auto cu_id = result->getCompilandId(); +        auto cu_id = GetCompilandId(*result);          // FIXME: We are not able to determine variable's compile unit.          if (cu_id == 0)            continue; @@ -548,8 +556,7 @@ lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {        llvm::dyn_cast_or_null<ClangASTContext>(type_system);    if (!clang_type_system)      return nullptr; -  PDBASTParser *pdb = -      llvm::dyn_cast<PDBASTParser>(clang_type_system->GetPDBParser()); +  PDBASTParser *pdb = clang_type_system->GetPDBParser();    if (!pdb)      return nullptr; @@ -567,34 +574,109 @@ lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {    return result.get();  } +llvm::Optional<SymbolFile::ArrayInfo> SymbolFilePDB::GetDynamicArrayInfoForUID( +    lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { +  return llvm::None; +} +  bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) { -  // TODO: Implement this -  return false; +  std::lock_guard<std::recursive_mutex> guard( +      GetObjectFile()->GetModule()->GetMutex()); + +  ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>( +      GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus)); +  if (!clang_ast_ctx) +    return false; + +  PDBASTParser *pdb = clang_ast_ctx->GetPDBParser(); +  if (!pdb) +    return false; + +  return pdb->CompleteTypeFromPDB(compiler_type);  }  lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) { -  return lldb_private::CompilerDecl(); +  ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>( +      GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus)); +  if (!clang_ast_ctx) +    return CompilerDecl(); + +  PDBASTParser *pdb = clang_ast_ctx->GetPDBParser(); +  if (!pdb) +    return CompilerDecl(); + +  auto symbol = m_session_up->getSymbolById(uid); +  if (!symbol) +    return CompilerDecl(); + +  auto decl = pdb->GetDeclForSymbol(*symbol); +  if (!decl) +    return CompilerDecl(); + +  return CompilerDecl(clang_ast_ctx, decl);  }  lldb_private::CompilerDeclContext  SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) { -  // PDB always uses the translation unit decl context for everything.  We can -  // improve this later but it's not easy because PDB doesn't provide a high -  // enough level of type fidelity in this area. -  return *m_tu_decl_ctx_up; +  ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>( +      GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus)); +  if (!clang_ast_ctx) +    return CompilerDeclContext(); + +  PDBASTParser *pdb = clang_ast_ctx->GetPDBParser(); +  if (!pdb) +    return CompilerDeclContext(); + +  auto symbol = m_session_up->getSymbolById(uid); +  if (!symbol) +    return CompilerDeclContext(); + +  auto decl_context = pdb->GetDeclContextForSymbol(*symbol); +  if (!decl_context) +    return GetDeclContextContainingUID(uid); + +  return CompilerDeclContext(clang_ast_ctx, decl_context);  }  lldb_private::CompilerDeclContext  SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) { -  return *m_tu_decl_ctx_up; +  ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>( +      GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus)); +  if (!clang_ast_ctx) +    return CompilerDeclContext(); + +  PDBASTParser *pdb = clang_ast_ctx->GetPDBParser(); +  if (!pdb) +    return CompilerDeclContext(); + +  auto symbol = m_session_up->getSymbolById(uid); +  if (!symbol) +    return CompilerDeclContext(); + +  auto decl_context = pdb->GetDeclContextContainingSymbol(*symbol); +  assert(decl_context); + +  return CompilerDeclContext(clang_ast_ctx, decl_context);  }  void SymbolFilePDB::ParseDeclsForContext( -    lldb_private::CompilerDeclContext decl_ctx) {} +    lldb_private::CompilerDeclContext decl_ctx) { +  ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>( +      GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus)); +  if (!clang_ast_ctx) +    return; + +  PDBASTParser *pdb = clang_ast_ctx->GetPDBParser(); +  if (!pdb) +    return; + +  pdb->ParseDeclsForDeclContext( +      static_cast<clang::DeclContext *>(decl_ctx.GetOpaqueDeclContext())); +}  uint32_t  SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr, -                                    uint32_t resolve_scope, +                                    SymbolContextItem resolve_scope,                                      lldb_private::SymbolContext &sc) {    uint32_t resolved_flags = 0;    if (resolve_scope & eSymbolContextCompUnit || @@ -614,7 +696,8 @@ SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,      lldbassert(sc.module_sp == cu_sp->GetModule());    } -  if (resolve_scope & eSymbolContextFunction) { +  if (resolve_scope & eSymbolContextFunction || +      resolve_scope & eSymbolContextBlock) {      addr_t file_vm_addr = so_addr.GetFileAddress();      auto symbol_up =          m_session_up->findSymbolByAddress(file_vm_addr, PDB_SymType::Function); @@ -624,12 +707,16 @@ SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,        auto func_uid = pdb_func->getSymIndexId();        sc.function = sc.comp_unit->FindFunctionByUID(func_uid).get();        if (sc.function == nullptr) -        sc.function = ParseCompileUnitFunctionForPDBFunc(*pdb_func, sc); +        sc.function = +            ParseCompileUnitFunctionForPDBFunc(*pdb_func, *sc.comp_unit);        if (sc.function) {          resolved_flags |= eSymbolContextFunction;          if (resolve_scope & eSymbolContextBlock) { -          Block &block = sc.function->GetBlock(true); -          sc.block = block.FindBlockByID(sc.function->GetID()); +          auto block_symbol = m_session_up->findSymbolByAddress( +              file_vm_addr, PDB_SymType::Block); +          auto block_id = block_symbol ? block_symbol->getSymIndexId() +                                       : sc.function->GetID(); +          sc.block = sc.function->GetBlock(true).FindBlockByID(block_id);            if (sc.block)              resolved_flags |= eSymbolContextBlock;          } @@ -650,7 +737,7 @@ SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,  uint32_t SymbolFilePDB::ResolveSymbolContext(      const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines, -    uint32_t resolve_scope, lldb_private::SymbolContextList &sc_list) { +    SymbolContextItem resolve_scope, lldb_private::SymbolContextList &sc_list) {    const size_t old_size = sc_list.GetSize();    if (resolve_scope & lldb::eSymbolContextCompUnit) {      // Locate all compilation units with line numbers referencing the specified @@ -674,7 +761,7 @@ uint32_t SymbolFilePDB::ResolveSymbolContext(          std::string source_file = compiland->getSourceFileFullPath();          if (source_file.empty())            continue; -        FileSpec this_spec(source_file, false, FileSpec::Style::windows); +        FileSpec this_spec(source_file, FileSpec::Style::windows);          bool need_full_match = !file_spec.GetDirectory().IsEmpty();          if (FileSpec::Compare(file_spec, this_spec, need_full_match) != 0)            continue; @@ -691,7 +778,7 @@ uint32_t SymbolFilePDB::ResolveSymbolContext(        // table that match the requested line (or all lines if `line` == 0).        if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock |                             eSymbolContextLineEntry)) { -        bool has_line_table = ParseCompileUnitLineTable(sc, line); +        bool has_line_table = ParseCompileUnitLineTable(*sc.comp_unit, line);          if ((resolve_scope & eSymbolContextLineEntry) && !has_line_table) {            // The query asks for line entries, but we can't get them for the @@ -734,7 +821,8 @@ uint32_t SymbolFilePDB::ResolveSymbolContext(                if (sc.function == nullptr) {                  auto pdb_func = llvm::dyn_cast<PDBSymbolFunc>(symbol_up.get());                  assert(pdb_func); -                sc.function = ParseCompileUnitFunctionForPDBFunc(*pdb_func, sc); +                sc.function = ParseCompileUnitFunctionForPDBFunc(*pdb_func, +                                                                 *sc.comp_unit);                }                if (sc.function && (resolve_scope & eSymbolContextBlock)) {                  Block &block = sc.function->GetBlock(true); @@ -759,24 +847,16 @@ uint32_t SymbolFilePDB::ResolveSymbolContext(  }  std::string SymbolFilePDB::GetMangledForPDBData(const PDBSymbolData &pdb_data) { -  std::string decorated_name; -  auto vm_addr = pdb_data.getVirtualAddress(); -  if (vm_addr != LLDB_INVALID_ADDRESS && vm_addr) { -    auto result_up = -        m_global_scope_up->findAllChildren(PDB_SymType::PublicSymbol); -    if (result_up) { -      while (auto symbol_up = result_up->getNext()) { -        if (symbol_up->getRawSymbol().getVirtualAddress() == vm_addr) { -          decorated_name = symbol_up->getRawSymbol().getName(); -          break; -        } -      } -    } -  } -  if (!decorated_name.empty()) -    return decorated_name; - -  return std::string(); +  // Cache public names at first +  if (m_public_names.empty()) +    if (auto result_up = +            m_global_scope_up->findAllChildren(PDB_SymType::PublicSymbol)) +      while (auto symbol_up = result_up->getNext()) +        if (auto addr = symbol_up->getRawSymbol().getVirtualAddress()) +          m_public_names[addr] = symbol_up->getRawSymbol().getName(); + +  // Look up the name in the cache +  return m_public_names.lookup(pdb_data.getVirtualAddress());  }  VariableSP SymbolFilePDB::ParseVariableForPDBData( @@ -843,7 +923,7 @@ VariableSP SymbolFilePDB::ParseVariableForPDBData(          uint32_t src_file_id = first_line->getSourceFileId();          auto src_file = m_session_up->getSourceFileById(src_file_id);          if (src_file) { -          FileSpec spec(src_file->getFileName(), /*resolve_path*/ false); +          FileSpec spec(src_file->getFileName());            decl.SetFile(spec);            decl.SetColumn(first_line->getColumnNumber());            decl.SetLine(first_line->getLineNumber()); @@ -857,7 +937,7 @@ VariableSP SymbolFilePDB::ParseVariableForPDBData(    if (scope == eValueTypeVariableLocal) {      if (sc.function) {        context_scope = sc.function->GetBlock(true).FindBlockByID( -          pdb_data.getClassParentId()); +          pdb_data.getLexicalParentId());        if (context_scope == nullptr)          context_scope = sc.function;      } @@ -937,6 +1017,9 @@ SymbolFilePDB::ParseVariables(const lldb_private::SymbolContext &sc,            if (variable_list)              variable_list->AddVariableIfUnique(var_sp);            ++num_added; +          PDBASTParser *ast = GetPDBAstParser(); +          if (ast) +            ast->GetDeclForSymbol(*pdb_data);          }        }      } @@ -959,9 +1042,7 @@ uint32_t SymbolFilePDB::FindGlobalVariables(    if (name.IsEmpty())      return 0; -  auto results = -      m_global_scope_up->findChildren(PDB_SymType::Data, name.GetStringRef(), -                                      PDB_NameSearchFlags::NS_CaseSensitive); +  auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();    if (!results)      return 0; @@ -976,11 +1057,19 @@ uint32_t SymbolFilePDB::FindGlobalVariables(      sc.module_sp = m_obj_file->GetModule();      lldbassert(sc.module_sp.get()); -    sc.comp_unit = ParseCompileUnitForUID(pdb_data->getCompilandId()).get(); +    if (!name.GetStringRef().equals( +            MSVCUndecoratedNameParser::DropScope(pdb_data->getName()))) +      continue; + +    sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get();      // FIXME: We are not able to determine the compile unit.      if (sc.comp_unit == nullptr)        continue; +    if (parent_decl_ctx && GetDeclContextContainingUID( +                               result->getSymIndexId()) != *parent_decl_ctx) +      continue; +      ParseVariables(sc, *pdb_data, &variables);      matches = variables.GetSize() - old_size;    } @@ -1013,7 +1102,7 @@ SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression ®ex,      sc.module_sp = m_obj_file->GetModule();      lldbassert(sc.module_sp.get()); -    sc.comp_unit = ParseCompileUnitForUID(pdb_data->getCompilandId()).get(); +    sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get();      // FIXME: We are not able to determine the compile unit.      if (sc.comp_unit == nullptr)        continue; @@ -1033,7 +1122,7 @@ bool SymbolFilePDB::ResolveFunction(const llvm::pdb::PDBSymbolFunc &pdb_func,    if (!sc.comp_unit)      return false;    sc.module_sp = sc.comp_unit->GetModule(); -  sc.function = ParseCompileUnitFunctionForPDBFunc(pdb_func, sc); +  sc.function = ParseCompileUnitFunctionForPDBFunc(pdb_func, *sc.comp_unit);    if (!sc.function)      return false; @@ -1075,22 +1164,11 @@ void SymbolFilePDB::CacheFunctionNames() {          // Class. We won't bother to check if the parent is UDT or Enum here.          m_func_method_names.Append(ConstString(name), uid); -        ConstString cstr_name(name); -          // To search a method name, like NS::Class:MemberFunc, LLDB searches          // its base name, i.e. MemberFunc by default. Since PDBSymbolFunc does          // not have inforamtion of this, we extract base names and cache them          // by our own effort. -        llvm::StringRef basename; -        CPlusPlusLanguage::MethodName cpp_method(cstr_name); -        if (cpp_method.IsValid()) { -          llvm::StringRef context; -          basename = cpp_method.GetBasename(); -          if (basename.empty()) -            CPlusPlusLanguage::ExtractContextAndIdentifier(name.c_str(), -                                                           context, basename); -        } - +        llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name);          if (!basename.empty())            m_func_base_names.Append(ConstString(basename), uid);          else { @@ -1103,11 +1181,12 @@ void SymbolFilePDB::CacheFunctionNames() {        } else {          // Handle not-method symbols. -        // The function name might contain namespace, or its lexical scope. It -        // is not safe to get its base name by applying same scheme as we deal -        // with the method names. -        // FIXME: Remove namespace if function is static in a scope. -        m_func_base_names.Append(ConstString(name), uid); +        // The function name might contain namespace, or its lexical scope. +        llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name); +        if (!basename.empty()) +          m_func_base_names.Append(ConstString(basename), uid); +        else +          m_func_base_names.Append(ConstString(name), uid);          if (name == "main") {            m_func_full_names.Append(ConstString(name), uid); @@ -1157,7 +1236,7 @@ void SymbolFilePDB::CacheFunctionNames() {  uint32_t SymbolFilePDB::FindFunctions(      const lldb_private::ConstString &name,      const lldb_private::CompilerDeclContext *parent_decl_ctx, -    uint32_t name_type_mask, bool include_inlines, bool append, +    FunctionNameType name_type_mask, bool include_inlines, bool append,      lldb_private::SymbolContextList &sc_list) {    if (!append)      sc_list.Clear(); @@ -1177,20 +1256,28 @@ uint32_t SymbolFilePDB::FindFunctions(      CacheFunctionNames();      std::set<uint32_t> resolved_ids; -    auto ResolveFn = [include_inlines, &name, &sc_list, &resolved_ids, -                      this](UniqueCStringMap<uint32_t> &Names) { +    auto ResolveFn = [this, &name, parent_decl_ctx, include_inlines, &sc_list, +                      &resolved_ids](UniqueCStringMap<uint32_t> &Names) {        std::vector<uint32_t> ids; -      if (Names.GetValues(name, ids)) { -        for (auto id : ids) { -          if (resolved_ids.find(id) == resolved_ids.end()) { -            if (ResolveFunction(id, include_inlines, sc_list)) -              resolved_ids.insert(id); -          } -        } +      if (!Names.GetValues(name, ids)) +        return; + +      for (uint32_t id : ids) { +        if (resolved_ids.find(id) != resolved_ids.end()) +          continue; + +        if (parent_decl_ctx && +            GetDeclContextContainingUID(id) != *parent_decl_ctx) +          continue; + +        if (ResolveFunction(id, include_inlines, sc_list)) +          resolved_ids.insert(id);        }      };      if (name_type_mask & eFunctionNameTypeFull) {        ResolveFn(m_func_full_names); +      ResolveFn(m_func_base_names); +      ResolveFn(m_func_method_names);      }      if (name_type_mask & eFunctionNameTypeBase) {        ResolveFn(m_func_base_names); @@ -1236,8 +1323,59 @@ void SymbolFilePDB::GetMangledNamesForFunction(      const std::string &scope_qualified_name,      std::vector<lldb_private::ConstString> &mangled_names) {} +void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) { +  std::set<lldb::addr_t> sym_addresses; +  for (size_t i = 0; i < symtab.GetNumSymbols(); i++) +    sym_addresses.insert(symtab.SymbolAtIndex(i)->GetFileAddress()); + +  auto results = m_global_scope_up->findAllChildren<PDBSymbolPublicSymbol>(); +  if (!results) +    return; + +  auto section_list = m_obj_file->GetSectionList(); +  if (!section_list) +    return; + +  while (auto pub_symbol = results->getNext()) { +    auto section_idx = pub_symbol->getAddressSection() - 1; +    if (section_idx >= section_list->GetSize()) +      continue; + +    auto section = section_list->GetSectionAtIndex(section_idx); +    if (!section) +      continue; + +    auto offset = pub_symbol->getAddressOffset(); + +    auto file_addr = section->GetFileAddress() + offset; +    if (sym_addresses.find(file_addr) != sym_addresses.end()) +      continue; +    sym_addresses.insert(file_addr); + +    auto size = pub_symbol->getLength(); +    symtab.AddSymbol( +        Symbol(pub_symbol->getSymIndexId(),   // symID +               pub_symbol->getName().c_str(), // name +               true,                          // name_is_mangled +               pub_symbol->isCode() ? eSymbolTypeCode : eSymbolTypeData, // type +               true,      // external +               false,     // is_debug +               false,     // is_trampoline +               false,     // is_artificial +               section,   // section_sp +               offset,    // value +               size,      // size +               size != 0, // size_is_valid +               false,     // contains_linker_annotations +               0          // flags +               )); +  } + +  symtab.CalculateSymbolSizes(); +  symtab.Finalize(); +} +  uint32_t SymbolFilePDB::FindTypes( -    const lldb_private::SymbolContext &sc,      const lldb_private::ConstString &name,      const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append,      uint32_t max_matches, @@ -1253,14 +1391,20 @@ uint32_t SymbolFilePDB::FindTypes(    searched_symbol_files.clear();    searched_symbol_files.insert(this); -  std::string name_str = name.AsCString(); -    // There is an assumption 'name' is not a regex -  FindTypesByName(name_str, max_matches, types); +  FindTypesByName(name.GetStringRef(), parent_decl_ctx, max_matches, types);    return types.GetSize();  } +void SymbolFilePDB::DumpClangAST(Stream &s) { +  auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); +  auto clang = llvm::dyn_cast_or_null<ClangASTContext>(type_system); +  if (!clang) +    return; +  clang->Dump(s); +} +  void SymbolFilePDB::FindTypesByRegex(      const lldb_private::RegularExpression ®ex, uint32_t max_matches,      lldb_private::TypeMap &types) { @@ -1316,14 +1460,14 @@ void SymbolFilePDB::FindTypesByRegex(    }  } -void SymbolFilePDB::FindTypesByName(const std::string &name, -                                    uint32_t max_matches, -                                    lldb_private::TypeMap &types) { +void SymbolFilePDB::FindTypesByName( +    llvm::StringRef name, +    const lldb_private::CompilerDeclContext *parent_decl_ctx, +    uint32_t max_matches, lldb_private::TypeMap &types) {    std::unique_ptr<IPDBEnumSymbols> results;    if (name.empty())      return; -  results = m_global_scope_up->findChildren(PDB_SymType::None, name, -                                            PDB_NameSearchFlags::NS_Default); +  results = m_global_scope_up->findAllChildren(PDB_SymType::None);    if (!results)      return; @@ -1332,6 +1476,11 @@ void SymbolFilePDB::FindTypesByName(const std::string &name,    while (auto result = results->getNext()) {      if (max_matches > 0 && matches >= max_matches)        break; + +    if (MSVCUndecoratedNameParser::DropScope( +            result->getRawSymbol().getName()) != name) +      continue; +      switch (result->getSymTag()) {      case PDB_SymType::Enum:      case PDB_SymType::UDT: @@ -1348,6 +1497,10 @@ void SymbolFilePDB::FindTypesByName(const std::string &name,      if (!ResolveTypeUID(result->getSymIndexId()))        continue; +    if (parent_decl_ctx && GetDeclContextContainingUID( +                               result->getSymIndexId()) != *parent_decl_ctx) +      continue; +      auto iter = m_types.find(result->getSymIndexId());      if (iter == m_types.end())        continue; @@ -1417,7 +1570,7 @@ void SymbolFilePDB::GetTypesForPDBSymbol(const llvm::pdb::PDBSymbol &pdb_symbol,  }  size_t SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope, -                               uint32_t type_mask, +                               TypeClass type_mask,                                 lldb_private::TypeList &type_list) {    TypeCollection type_collection;    uint32_t old_size = type_list.GetSize(); @@ -1454,11 +1607,40 @@ SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {    return type_system;  } +PDBASTParser *SymbolFilePDB::GetPDBAstParser() { +  auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); +  auto clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system); +  if (!clang_type_system) +    return nullptr; + +  return clang_type_system->GetPDBParser(); +} + +  lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace( -    const lldb_private::SymbolContext &sc,      const lldb_private::ConstString &name,      const lldb_private::CompilerDeclContext *parent_decl_ctx) { -  return lldb_private::CompilerDeclContext(); +  auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); +  auto clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system); +  if (!clang_type_system) +    return CompilerDeclContext(); + +  PDBASTParser *pdb = clang_type_system->GetPDBParser(); +  if (!pdb) +    return CompilerDeclContext(); + +  clang::DeclContext *decl_context = nullptr; +  if (parent_decl_ctx) +    decl_context = static_cast<clang::DeclContext *>( +        parent_decl_ctx->GetOpaqueDeclContext()); + +  auto namespace_decl = +      pdb->FindNamespaceDecl(decl_context, name.GetStringRef()); +  if (!namespace_decl) +    return CompilerDeclContext(); + +  return CompilerDeclContext(type_system, +                             static_cast<clang::DeclContext *>(namespace_decl));  }  lldb_private::ConstString SymbolFilePDB::GetPluginName() { @@ -1516,11 +1698,9 @@ lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitForUID(uint32_t id,    return cu_sp;  } -bool SymbolFilePDB::ParseCompileUnitLineTable( -    const lldb_private::SymbolContext &sc, uint32_t match_line) { -  lldbassert(sc.comp_unit); - -  auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID()); +bool SymbolFilePDB::ParseCompileUnitLineTable(CompileUnit &comp_unit, +                                              uint32_t match_line) { +  auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());    if (!compiland_up)      return false; @@ -1530,10 +1710,10 @@ bool SymbolFilePDB::ParseCompileUnitLineTable(    // to do a mapping so that we can hand out indices.    llvm::DenseMap<uint32_t, uint32_t> index_map;    BuildSupportFileIdToSupportFileIndexMap(*compiland_up, index_map); -  auto line_table = llvm::make_unique<LineTable>(sc.comp_unit); +  auto line_table = llvm::make_unique<LineTable>(&comp_unit);    // Find contributions to `compiland` from all source and header files. -  std::string path = sc.comp_unit->GetPath(); +  std::string path = comp_unit.GetPath();    auto files = m_session_up->getSourceFilesForCompiland(*compiland_up);    if (!files)      return false; @@ -1617,7 +1797,7 @@ bool SymbolFilePDB::ParseCompileUnitLineTable(    }    if (line_table->GetSize()) { -    sc.comp_unit->SetLineTable(line_table.release()); +    comp_unit.SetLineTable(line_table.release());      return true;    }    return false; @@ -1747,3 +1927,68 @@ bool SymbolFilePDB::DeclContextMatchesThisSymbolFile(    return false;  } + +uint32_t SymbolFilePDB::GetCompilandId(const llvm::pdb::PDBSymbolData &data) { +  static const auto pred_upper = [](uint32_t lhs, SecContribInfo rhs) { +    return lhs < rhs.Offset; +  }; + +  // Cache section contributions +  if (m_sec_contribs.empty()) { +    if (auto SecContribs = m_session_up->getSectionContribs()) { +      while (auto SectionContrib = SecContribs->getNext()) { +        auto comp_id = SectionContrib->getCompilandId(); +        if (!comp_id) +          continue; + +        auto sec = SectionContrib->getAddressSection(); +        auto &sec_cs = m_sec_contribs[sec]; + +        auto offset = SectionContrib->getAddressOffset(); +        auto it = +            std::upper_bound(sec_cs.begin(), sec_cs.end(), offset, pred_upper); + +        auto size = SectionContrib->getLength(); +        sec_cs.insert(it, {offset, size, comp_id}); +      } +    } +  } + +  // Check by line number +  if (auto Lines = data.getLineNumbers()) { +    if (auto FirstLine = Lines->getNext()) +      return FirstLine->getCompilandId(); +  } + +  // Retrieve section + offset +  uint32_t DataSection = data.getAddressSection(); +  uint32_t DataOffset = data.getAddressOffset(); +  if (DataSection == 0) { +    if (auto RVA = data.getRelativeVirtualAddress()) +      m_session_up->addressForRVA(RVA, DataSection, DataOffset); +  } + +  if (DataSection) { +    // Search by section contributions +    auto &sec_cs = m_sec_contribs[DataSection]; +    auto it = +        std::upper_bound(sec_cs.begin(), sec_cs.end(), DataOffset, pred_upper); +    if (it != sec_cs.begin()) { +      --it; +      if (DataOffset < it->Offset + it->Size) +        return it->CompilandId; +    } +  } else { +    // Search in lexical tree +    auto LexParentId = data.getLexicalParentId(); +    while (auto LexParent = m_session_up->getSymbolById(LexParentId)) { +      if (LexParent->getSymTag() == PDB_SymType::Exe) +        break; +      if (LexParent->getSymTag() == PDB_SymType::Compiland) +        return LexParentId; +      LexParentId = LexParent->getRawSymbol().getLexicalParentId(); +    } +  } + +  return 0; +}  | 
