summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
diff options
context:
space:
mode:
authorAleksandr Urakov <aleksandr.urakov@jetbrains.com>2018-09-10 08:08:43 +0000
committerAleksandr Urakov <aleksandr.urakov@jetbrains.com>2018-09-10 08:08:43 +0000
commit709426b33a17d69b102f9ab80abda1749636c259 (patch)
treec9dee5eef4148aed830c50e3b6cd971e247acd72 /lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
parent59491a1fa955da7a5baa9182722f655cb4496881 (diff)
downloadbcm5719-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.cpp142
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() {
OpenPOWER on IntegriCloud