diff options
author | Aleksandr Urakov <aleksandr.urakov@jetbrains.com> | 2018-09-10 08:08:43 +0000 |
---|---|---|
committer | Aleksandr Urakov <aleksandr.urakov@jetbrains.com> | 2018-09-10 08:08:43 +0000 |
commit | 709426b33a17d69b102f9ab80abda1749636c259 (patch) | |
tree | c9dee5eef4148aed830c50e3b6cd971e247acd72 /lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp | |
parent | 59491a1fa955da7a5baa9182722f655cb4496881 (diff) | |
download | bcm5719-llvm-709426b33a17d69b102f9ab80abda1749636c259.tar.gz bcm5719-llvm-709426b33a17d69b102f9ab80abda1749636c259.zip |
[PDB] Restore AST from PDB symbols
Summary:
This patch adds an implementation of retrieving of declarations and declaration
contexts based on PDB symbols.
PDB has different type symbols for const-qualified types, and this
implementation ensures that only one declaration was created for both const
and non-const types, but creates different compiler types for them.
The implementation also processes the case when there are two symbols
corresponding to a variable. It's possible e.g. for class static variables,
they has one global symbol and one symbol belonging to a class.
PDB has no info about namespaces, so this implementation parses the full symbol
name and tries to figure out if the symbol belongs to namespace or not,
and then creates nested namespaces if necessary.
Reviewers: asmith, zturner, labath
Reviewed By: asmith
Subscribers: aleksandr.urakov, teemperor, lldb-commits, stella.stamenova
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D51162
llvm-svn: 341782
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp')
-rw-r--r-- | lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp | 142 |
1 files changed, 120 insertions, 22 deletions
diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index f52aa982308..228de6f118c 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -551,8 +551,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; @@ -579,8 +578,7 @@ bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) { if (!clang_ast_ctx) return false; - PDBASTParser *pdb = - llvm::dyn_cast<PDBASTParser>(clang_ast_ctx->GetPDBParser()); + PDBASTParser *pdb = clang_ast_ctx->GetPDBParser(); if (!pdb) return false; @@ -588,24 +586,83 @@ bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &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, @@ -876,7 +933,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; } @@ -973,14 +1030,14 @@ uint32_t SymbolFilePDB::FindGlobalVariables( const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, uint32_t max_matches, lldb_private::VariableList &variables) { + if (!parent_decl_ctx) + parent_decl_ctx = m_tu_decl_ctx_up.get(); if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) return 0; 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; @@ -1000,6 +1057,15 @@ uint32_t SymbolFilePDB::FindGlobalVariables( if (sc.comp_unit == nullptr) continue; + if (!name.GetStringRef().equals( + PDBASTParser::PDBNameDropScope(pdb_data->getName()))) + continue; + + auto actual_parent_decl_ctx = + GetDeclContextContainingUID(result->getSymIndexId()); + if (actual_parent_decl_ctx != *parent_decl_ctx) + continue; + ParseVariables(sc, *pdb_data, &variables); matches = variables.GetSize() - old_size; } @@ -1275,7 +1341,7 @@ uint32_t SymbolFilePDB::FindTypes( std::string name_str = name.AsCString(); // There is an assumption 'name' is not a regex - FindTypesByName(name_str, max_matches, types); + FindTypesByName(name_str, parent_decl_ctx, max_matches, types); return types.GetSize(); } @@ -1335,14 +1401,16 @@ void SymbolFilePDB::FindTypesByRegex( } } -void SymbolFilePDB::FindTypesByName(const std::string &name, - uint32_t max_matches, - lldb_private::TypeMap &types) { +void SymbolFilePDB::FindTypesByName( + const std::string &name, + const lldb_private::CompilerDeclContext *parent_decl_ctx, + uint32_t max_matches, lldb_private::TypeMap &types) { + if (!parent_decl_ctx) + parent_decl_ctx = m_tu_decl_ctx_up.get(); 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; @@ -1351,6 +1419,11 @@ void SymbolFilePDB::FindTypesByName(const std::string &name, while (auto result = results->getNext()) { if (max_matches > 0 && matches >= max_matches) break; + + if (PDBASTParser::PDBNameDropScope(result->getRawSymbol().getName()) != + name) + continue; + switch (result->getSymTag()) { case PDB_SymType::Enum: case PDB_SymType::UDT: @@ -1367,6 +1440,11 @@ void SymbolFilePDB::FindTypesByName(const std::string &name, if (!ResolveTypeUID(result->getSymIndexId())) continue; + auto actual_parent_decl_ctx = + GetDeclContextContainingUID(result->getSymIndexId()); + if (actual_parent_decl_ctx != *parent_decl_ctx) + continue; + auto iter = m_types.find(result->getSymIndexId()); if (iter == m_types.end()) continue; @@ -1477,7 +1555,27 @@ 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() { |