[SymbolFilePDB] Add support for function symbols
Summary:
This is combination of following changes,
- Resolve function symbols in PDB symbol file. `lldb-test symbols` will display information about function symbols.
- Implement SymbolFilePDB::FindFunctions methods. On lldb console, searching function symbol by name and by regular expression are both available.
- Create lldb type for PDBSymbolFunc.
- Add tests to check whether functions with the same name but from different sources can be resolved correctly.
Reviewers: zturner, lldb-commits
Reviewed By: zturner
Subscribers: amccarth, labath, llvm-commits
Differential Revision: https://reviews.llvm.org/D42443
llvm-svn: 324707
diff --git a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
index b07b81f..a765bb7 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -19,8 +19,11 @@
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeSystem.h"
+#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
+#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
@@ -166,6 +169,28 @@
}
return compiler_type.GetTypeName();
}
+
+bool GetDeclarationForSymbol(const PDBSymbol &symbol, Declaration &decl) {
+ auto &raw_sym = symbol.getRawSymbol();
+ auto lines_up = symbol.getSession().findLineNumbersByAddress(
+ raw_sym.getVirtualAddress(), raw_sym.getLength());
+ if (!lines_up)
+ return false;
+ auto first_line_up = lines_up->getNext();
+ if (!first_line_up)
+ return false;
+
+ uint32_t src_file_id = first_line_up->getSourceFileId();
+ auto src_file_up = symbol.getSession().getSourceFileById(src_file_id);
+ if (!src_file_up)
+ return false;
+
+ FileSpec spec(src_file_up->getFileName(), /*resolve_path*/false);
+ decl.SetFile(spec);
+ decl.SetColumn(first_line_up->getColumnNumber());
+ decl.SetLine(first_line_up->getLineNumber());
+ return true;
+}
}
PDBASTParser::PDBASTParser(lldb_private::ClangASTContext &ast) : m_ast(ast) {}
@@ -182,7 +207,10 @@
clang::DeclContext *tu_decl_ctx = m_ast.GetTranslationUnitDecl();
Declaration decl;
- if (auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&type)) {
+ switch (type.getSymTag()) {
+ case PDB_SymType::UDT: {
+ auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&type);
+ assert(udt);
AccessType access = lldb::eAccessPublic;
PDB_UdtType udt_kind = udt->getUdtKind();
auto tag_type_kind = TranslateUdtKind(udt_kind);
@@ -203,7 +231,10 @@
ConstString(udt->getName()), udt->getLength(), nullptr,
LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, clang_type,
lldb_private::Type::eResolveStateForward);
- } else if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(&type)) {
+ } break;
+ case PDB_SymType::Enum: {
+ auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(&type);
+ assert(enum_type);
auto underlying_type_up = enum_type->getUnderlyingType();
if (!underlying_type_up)
return nullptr;
@@ -244,7 +275,10 @@
type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), bytes,
nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
ast_enum, lldb_private::Type::eResolveStateFull);
- } else if (auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type)) {
+ } break;
+ case PDB_SymType::Typedef: {
+ auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type);
+ assert(type_def);
lldb_private::Type *target_type =
m_ast.GetSymbolFile()->ResolveTypeUID(type_def->getTypeId());
if (!target_type)
@@ -261,7 +295,24 @@
bytes, nullptr, target_type->GetID(),
lldb_private::Type::eEncodingIsTypedefUID, decl, ast_typedef,
lldb_private::Type::eResolveStateFull);
- } else if (auto func_sig = llvm::dyn_cast<PDBSymbolTypeFunctionSig>(&type)) {
+ } break;
+ case PDB_SymType::Function:
+ case PDB_SymType::FunctionSig: {
+ std::string name;
+ PDBSymbolTypeFunctionSig *func_sig = nullptr;
+ if (auto pdb_func = llvm::dyn_cast<PDBSymbolFunc>(&type)) {
+ auto sig = pdb_func->getSignature();
+ if (!sig)
+ return nullptr;
+ func_sig = sig.release();
+ // Function type is named.
+ name = pdb_func->getName();
+ } else if (auto pdb_func_sig =
+ llvm::dyn_cast<PDBSymbolTypeFunctionSig>(&type)) {
+ func_sig = const_cast<PDBSymbolTypeFunctionSig*>(pdb_func_sig);
+ } else
+ llvm_unreachable("Unexpected PDB symbol!");
+
auto arg_enum = func_sig->getArguments();
uint32_t num_args = arg_enum->getChildCount();
std::vector<CompilerType> arg_list;
@@ -302,11 +353,15 @@
return_ast_type, arg_list.data(), arg_list.size(), is_variadic,
type_quals);
+ GetDeclarationForSymbol(type, decl);
return std::make_shared<lldb_private::Type>(
- func_sig->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), 0,
+ type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), 0,
nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
func_sig_ast_type, lldb_private::Type::eResolveStateFull);
- } else if (auto array_type = llvm::dyn_cast<PDBSymbolTypeArray>(&type)) {
+ } break;
+ case PDB_SymType::ArrayType: {
+ auto array_type = llvm::dyn_cast<PDBSymbolTypeArray>(&type);
+ assert(array_type);
uint32_t num_elements = array_type->getCount();
uint32_t element_uid = array_type->getElementType()->getSymIndexId();
uint32_t bytes = array_type->getLength();
@@ -322,7 +377,10 @@
array_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(),
bytes, nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID,
decl, array_ast_type, lldb_private::Type::eResolveStateFull);
- } else if (auto *builtin_type = llvm::dyn_cast<PDBSymbolTypeBuiltin>(&type)) {
+ } break;
+ case PDB_SymType::BuiltinType: {
+ auto *builtin_type = llvm::dyn_cast<PDBSymbolTypeBuiltin>(&type);
+ assert(builtin_type);
PDB_BuiltinType builtin_kind = builtin_type->getBuiltinType();
if (builtin_kind == PDB_BuiltinType::None)
return nullptr;
@@ -347,7 +405,10 @@
builtin_type->getSymIndexId(), m_ast.GetSymbolFile(), type_name,
bytes, nullptr, LLDB_INVALID_UID, encoding_data_type,
decl, builtin_ast_type, lldb_private::Type::eResolveStateFull);
- } else if (auto *pointer_type = llvm::dyn_cast<PDBSymbolTypePointer>(&type)) {
+ } break;
+ case PDB_SymType::PointerType: {
+ auto *pointer_type = llvm::dyn_cast<PDBSymbolTypePointer>(&type);
+ assert(pointer_type);
Type *pointee_type = m_ast.GetSymbolFile()->ResolveTypeUID(
pointer_type->getPointeeType()->getSymIndexId());
if (!pointee_type)
@@ -367,6 +428,8 @@
pointer_type->getLength(), nullptr, LLDB_INVALID_UID,
encoding_data_type, decl, pointer_ast_type,
lldb_private::Type::eResolveStateFull);
+ } break;
+ default: break;
}
return nullptr;
}