blob: 314708ebb2e3917e9e70afef850e5e9667694bf7 [file] [log] [blame]
Zachary Turner74e08ca2016-03-02 22:05:52 +00001//===-- SymbolFilePDB.cpp ---------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "SymbolFilePDB.h"
11
Zachary Turner42dff792016-04-15 00:21:26 +000012#include "clang/Lex/Lexer.h"
13
Zachary Turner74e08ca2016-03-02 22:05:52 +000014#include "lldb/Core/Module.h"
15#include "lldb/Core/PluginManager.h"
Zachary Turner42dff792016-04-15 00:21:26 +000016#include "lldb/Symbol/ClangASTContext.h"
Zachary Turner74e08ca2016-03-02 22:05:52 +000017#include "lldb/Symbol/CompileUnit.h"
18#include "lldb/Symbol/LineTable.h"
19#include "lldb/Symbol/ObjectFile.h"
20#include "lldb/Symbol/SymbolContext.h"
Aaron Smith10a02572018-01-13 06:58:18 +000021#include "lldb/Symbol/SymbolVendor.h"
Zachary Turner42dff792016-04-15 00:21:26 +000022#include "lldb/Symbol/TypeMap.h"
Aaron Smithec40f812018-01-23 20:35:19 +000023#include "lldb/Symbol/TypeList.h"
Aaron Smith86e94342017-12-22 05:26:50 +000024#include "lldb/Utility/RegularExpression.h"
Zachary Turner74e08ca2016-03-02 22:05:52 +000025
Pavel Labathb8d8c622016-05-09 11:07:43 +000026#include "llvm/DebugInfo/PDB/GenericError.h"
Aaron Smith1f8552a2017-12-22 00:04:36 +000027#include "llvm/DebugInfo/PDB/IPDBDataStream.h"
Zachary Turner74e08ca2016-03-02 22:05:52 +000028#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
29#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
30#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
Aaron Smith1f8552a2017-12-22 00:04:36 +000031#include "llvm/DebugInfo/PDB/IPDBTable.h"
Zachary Turner74e08ca2016-03-02 22:05:52 +000032#include "llvm/DebugInfo/PDB/PDBSymbol.h"
Aaron Smith7ac1c782018-02-09 05:31:28 +000033#include "llvm/DebugInfo/PDB/PDBSymbolBlock.h"
Zachary Turner74e08ca2016-03-02 22:05:52 +000034#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
35#include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
Aaron Smith1f8552a2017-12-22 00:04:36 +000036#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
Zachary Turner74e08ca2016-03-02 22:05:52 +000037#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
38#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
39#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
40#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
Aaron Smith7ac1c782018-02-09 05:31:28 +000041#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
Zachary Turner42dff792016-04-15 00:21:26 +000042#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
43#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
44#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
45
Aaron Smith7ac1c782018-02-09 05:31:28 +000046#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
Zachary Turner42dff792016-04-15 00:21:26 +000047#include "Plugins/SymbolFile/PDB/PDBASTParser.h"
48
49#include <regex>
Zachary Turner74e08ca2016-03-02 22:05:52 +000050
Aaron Smith10a02572018-01-13 06:58:18 +000051using namespace lldb;
Zachary Turner74e08ca2016-03-02 22:05:52 +000052using namespace lldb_private;
Zachary Turner54fd7ff2016-05-04 20:33:53 +000053using namespace llvm::pdb;
Zachary Turner74e08ca2016-03-02 22:05:52 +000054
Kate Stoneb9c1b512016-09-06 20:57:50 +000055namespace {
56lldb::LanguageType TranslateLanguage(PDB_Lang lang) {
57 switch (lang) {
58 case PDB_Lang::Cpp:
59 return lldb::LanguageType::eLanguageTypeC_plus_plus;
60 case PDB_Lang::C:
61 return lldb::LanguageType::eLanguageTypeC;
62 default:
63 return lldb::LanguageType::eLanguageTypeUnknown;
64 }
Zachary Turner74e08ca2016-03-02 22:05:52 +000065}
66
Kate Stoneb9c1b512016-09-06 20:57:50 +000067bool ShouldAddLine(uint32_t requested_line, uint32_t actual_line,
68 uint32_t addr_length) {
69 return ((requested_line == 0 || actual_line == requested_line) &&
70 addr_length > 0);
71}
Zachary Turner74e08ca2016-03-02 22:05:52 +000072}
73
Kate Stoneb9c1b512016-09-06 20:57:50 +000074void SymbolFilePDB::Initialize() {
75 PluginManager::RegisterPlugin(GetPluginNameStatic(),
76 GetPluginDescriptionStatic(), CreateInstance,
77 DebuggerInitialize);
Zachary Turner74e08ca2016-03-02 22:05:52 +000078}
79
Kate Stoneb9c1b512016-09-06 20:57:50 +000080void SymbolFilePDB::Terminate() {
81 PluginManager::UnregisterPlugin(CreateInstance);
Zachary Turner74e08ca2016-03-02 22:05:52 +000082}
83
Kate Stoneb9c1b512016-09-06 20:57:50 +000084void SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger) {}
85
86lldb_private::ConstString SymbolFilePDB::GetPluginNameStatic() {
87 static ConstString g_name("pdb");
88 return g_name;
Zachary Turner74e08ca2016-03-02 22:05:52 +000089}
90
Kate Stoneb9c1b512016-09-06 20:57:50 +000091const char *SymbolFilePDB::GetPluginDescriptionStatic() {
92 return "Microsoft PDB debug symbol file reader.";
Zachary Turner74e08ca2016-03-02 22:05:52 +000093}
94
95lldb_private::SymbolFile *
Kate Stoneb9c1b512016-09-06 20:57:50 +000096SymbolFilePDB::CreateInstance(lldb_private::ObjectFile *obj_file) {
97 return new SymbolFilePDB(obj_file);
Zachary Turner74e08ca2016-03-02 22:05:52 +000098}
99
100SymbolFilePDB::SymbolFilePDB(lldb_private::ObjectFile *object_file)
Aaron Smith10a02572018-01-13 06:58:18 +0000101 : SymbolFile(object_file), m_session_up(), m_global_scope_up(),
102 m_cached_compile_unit_count(0), m_tu_decl_ctx_up() {}
Zachary Turner74e08ca2016-03-02 22:05:52 +0000103
Kate Stoneb9c1b512016-09-06 20:57:50 +0000104SymbolFilePDB::~SymbolFilePDB() {}
Zachary Turner74e08ca2016-03-02 22:05:52 +0000105
Kate Stoneb9c1b512016-09-06 20:57:50 +0000106uint32_t SymbolFilePDB::CalculateAbilities() {
Aaron Smith1f8552a2017-12-22 00:04:36 +0000107 uint32_t abilities = 0;
108 if (!m_obj_file)
109 return 0;
110
Kate Stoneb9c1b512016-09-06 20:57:50 +0000111 if (!m_session_up) {
112 // Lazily load and match the PDB file, but only do this once.
113 std::string exePath = m_obj_file->GetFileSpec().GetPath();
114 auto error = loadDataForEXE(PDB_ReaderType::DIA, llvm::StringRef(exePath),
115 m_session_up);
116 if (error) {
117 llvm::consumeError(std::move(error));
Aaron Smith1f8552a2017-12-22 00:04:36 +0000118 auto module_sp = m_obj_file->GetModule();
119 if (!module_sp)
120 return 0;
121 // See if any symbol file is specified through `--symfile` option.
122 FileSpec symfile = module_sp->GetSymbolFileFileSpec();
123 if (!symfile)
124 return 0;
125 error = loadDataForPDB(PDB_ReaderType::DIA,
126 llvm::StringRef(symfile.GetPath()),
127 m_session_up);
128 if (error) {
129 llvm::consumeError(std::move(error));
130 return 0;
131 }
Zachary Turner74e08ca2016-03-02 22:05:52 +0000132 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000133 }
Aaron Smith1f8552a2017-12-22 00:04:36 +0000134 if (!m_session_up.get())
135 return 0;
136
137 auto enum_tables_up = m_session_up->getEnumTables();
138 if (!enum_tables_up)
139 return 0;
140 while (auto table_up = enum_tables_up->getNext()) {
141 if (table_up->getItemCount() == 0)
142 continue;
143 auto type = table_up->getTableType();
144 switch (type) {
145 case PDB_TableType::Symbols:
146 // This table represents a store of symbols with types listed in
147 // PDBSym_Type
148 abilities |= (CompileUnits | Functions | Blocks |
149 GlobalVariables | LocalVariables | VariableTypes);
150 break;
151 case PDB_TableType::LineNumbers:
152 abilities |= LineTables;
153 break;
154 default: break;
155 }
156 }
157 return abilities;
Zachary Turner74e08ca2016-03-02 22:05:52 +0000158}
159
Kate Stoneb9c1b512016-09-06 20:57:50 +0000160void SymbolFilePDB::InitializeObject() {
161 lldb::addr_t obj_load_address = m_obj_file->GetFileOffset();
Aaron Smith10a02572018-01-13 06:58:18 +0000162 lldbassert(obj_load_address &&
163 obj_load_address != LLDB_INVALID_ADDRESS);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000164 m_session_up->setLoadAddress(obj_load_address);
Aaron Smith10a02572018-01-13 06:58:18 +0000165 if (!m_global_scope_up)
166 m_global_scope_up = m_session_up->getGlobalScope();
167 lldbassert(m_global_scope_up.get());
Zachary Turner42dff792016-04-15 00:21:26 +0000168
Kate Stoneb9c1b512016-09-06 20:57:50 +0000169 TypeSystem *type_system =
170 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
171 ClangASTContext *clang_type_system =
172 llvm::dyn_cast_or_null<ClangASTContext>(type_system);
Aaron Smith10a02572018-01-13 06:58:18 +0000173 lldbassert(clang_type_system);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000174 m_tu_decl_ctx_up = llvm::make_unique<CompilerDeclContext>(
175 type_system, clang_type_system->GetTranslationUnitDecl());
Zachary Turner74e08ca2016-03-02 22:05:52 +0000176}
177
Kate Stoneb9c1b512016-09-06 20:57:50 +0000178uint32_t SymbolFilePDB::GetNumCompileUnits() {
179 if (m_cached_compile_unit_count == 0) {
Aaron Smith10a02572018-01-13 06:58:18 +0000180 auto compilands = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();
181 if (!compilands)
182 return 0;
183
184 // The linker could link *.dll (compiland language = LINK), or import
185 // *.dll. For example, a compiland with name `Import:KERNEL32.dll`
186 // could be found as a child of the global scope (PDB executable).
187 // Usually, such compilands contain `thunk` symbols in which we are not
188 // interested for now. However we still count them in the compiland list.
189 // If we perform any compiland related activity, like finding symbols
190 // through llvm::pdb::IPDBSession methods, such compilands will all be
191 // searched automatically no matter whether we include them or not.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000192 m_cached_compile_unit_count = compilands->getChildCount();
Zachary Turner74e08ca2016-03-02 22:05:52 +0000193
Kate Stoneb9c1b512016-09-06 20:57:50 +0000194 // The linker can inject an additional "dummy" compilation unit into the
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +0000195 // PDB. Ignore this special compile unit for our purposes, if it is there.
196 // It is always the last one.
Aaron Smith10a02572018-01-13 06:58:18 +0000197 auto last_compiland_up =
198 compilands->getChildAtIndex(m_cached_compile_unit_count - 1);
199 lldbassert(last_compiland_up.get());
200 std::string name = last_compiland_up->getName();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000201 if (name == "* Linker *")
202 --m_cached_compile_unit_count;
203 }
204 return m_cached_compile_unit_count;
205}
Zachary Turner74e08ca2016-03-02 22:05:52 +0000206
Aaron Smith10a02572018-01-13 06:58:18 +0000207void SymbolFilePDB::GetCompileUnitIndex(
Aaron Smithe664b5d2018-03-19 21:14:19 +0000208 const llvm::pdb::PDBSymbolCompiland &pdb_compiland,
Aaron Smith10a02572018-01-13 06:58:18 +0000209 uint32_t &index) {
Aaron Smith10a02572018-01-13 06:58:18 +0000210 auto results_up = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();
211 if (!results_up)
212 return;
Aaron Smithe664b5d2018-03-19 21:14:19 +0000213 auto uid = pdb_compiland.getSymIndexId();
Raphael Isemannfbdf0b92018-01-22 06:56:09 +0000214 for (uint32_t cu_idx = 0; cu_idx < GetNumCompileUnits(); ++cu_idx) {
Aaron Smith10a02572018-01-13 06:58:18 +0000215 auto compiland_up = results_up->getChildAtIndex(cu_idx);
216 if (!compiland_up)
217 continue;
218 if (compiland_up->getSymIndexId() == uid) {
219 index = cu_idx;
220 return;
221 }
222 }
223 index = UINT32_MAX;
224 return;
225}
226
227std::unique_ptr<llvm::pdb::PDBSymbolCompiland>
228SymbolFilePDB::GetPDBCompilandByUID(uint32_t uid) {
229 return m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(uid);
230}
231
Kate Stoneb9c1b512016-09-06 20:57:50 +0000232lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index) {
Aaron Smith10a02572018-01-13 06:58:18 +0000233 if (index >= GetNumCompileUnits())
234 return CompUnitSP();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000235
Aaron Smith10a02572018-01-13 06:58:18 +0000236 // Assuming we always retrieve same compilands listed in same order through
237 // `PDBSymbolExe::findAllChildren` method, otherwise using `index` to get a
238 // compile unit makes no sense.
239 auto results = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();
240 if (!results)
241 return CompUnitSP();
242 auto compiland_up = results->getChildAtIndex(index);
243 if (!compiland_up)
244 return CompUnitSP();
245 return ParseCompileUnitForUID(compiland_up->getSymIndexId(), index);
Zachary Turner74e08ca2016-03-02 22:05:52 +0000246}
247
248lldb::LanguageType
Kate Stoneb9c1b512016-09-06 20:57:50 +0000249SymbolFilePDB::ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) {
250 // What fields should I expect to be filled out on the SymbolContext? Is it
251 // safe to assume that `sc.comp_unit` is valid?
252 if (!sc.comp_unit)
253 return lldb::eLanguageTypeUnknown;
Zachary Turner74e08ca2016-03-02 22:05:52 +0000254
Aaron Smith10a02572018-01-13 06:58:18 +0000255 auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID());
256 if (!compiland_up)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000257 return lldb::eLanguageTypeUnknown;
Aaron Smith10a02572018-01-13 06:58:18 +0000258 auto details = compiland_up->findOneChild<PDBSymbolCompilandDetails>();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000259 if (!details)
260 return lldb::eLanguageTypeUnknown;
261 return TranslateLanguage(details->getLanguage());
Zachary Turner74e08ca2016-03-02 22:05:52 +0000262}
263
Aaron Smith7ac1c782018-02-09 05:31:28 +0000264lldb_private::Function *
265SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(
Aaron Smithe664b5d2018-03-19 21:14:19 +0000266 const PDBSymbolFunc &pdb_func,
Aaron Smith7ac1c782018-02-09 05:31:28 +0000267 const lldb_private::SymbolContext &sc) {
Aaron Smith7ac1c782018-02-09 05:31:28 +0000268 lldbassert(sc.comp_unit && sc.module_sp.get());
269
Aaron Smithe664b5d2018-03-19 21:14:19 +0000270 auto file_vm_addr = pdb_func.getVirtualAddress();
Aaron Smith7ac1c782018-02-09 05:31:28 +0000271 if (file_vm_addr == LLDB_INVALID_ADDRESS)
272 return nullptr;
273
Aaron Smithe664b5d2018-03-19 21:14:19 +0000274 auto func_length = pdb_func.getLength();
Aaron Smith7ac1c782018-02-09 05:31:28 +0000275 AddressRange func_range = AddressRange(file_vm_addr,
276 func_length,
277 sc.module_sp->GetSectionList());
278 if (!func_range.GetBaseAddress().IsValid())
279 return nullptr;
280
Aaron Smithe664b5d2018-03-19 21:14:19 +0000281 lldb_private::Type* func_type = ResolveTypeUID(pdb_func.getSymIndexId());
Aaron Smith7ac1c782018-02-09 05:31:28 +0000282 if (!func_type)
283 return nullptr;
284
Aaron Smithe664b5d2018-03-19 21:14:19 +0000285 user_id_t func_type_uid = pdb_func.getSignatureId();
Aaron Smithf76fe682018-03-07 03:16:50 +0000286
Aaron Smith7ac1c782018-02-09 05:31:28 +0000287 Mangled mangled = GetMangledForPDBFunc(pdb_func);
288
289 FunctionSP func_sp = std::make_shared<Function>(sc.comp_unit,
Aaron Smithe664b5d2018-03-19 21:14:19 +0000290 pdb_func.getSymIndexId(),
Aaron Smith7ac1c782018-02-09 05:31:28 +0000291 func_type_uid,
292 mangled,
293 func_type,
294 func_range);
295
296 sc.comp_unit->AddFunction(func_sp);
297 return func_sp.get();
298}
299
Kate Stoneb9c1b512016-09-06 20:57:50 +0000300size_t SymbolFilePDB::ParseCompileUnitFunctions(
301 const lldb_private::SymbolContext &sc) {
Aaron Smith7ac1c782018-02-09 05:31:28 +0000302 lldbassert(sc.comp_unit);
303 size_t func_added = 0;
304 auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID());
305 if (!compiland_up)
306 return 0;
307 auto results_up = compiland_up->findAllChildren<PDBSymbolFunc>();
308 if (!results_up)
309 return 0;
310 while (auto pdb_func_up = results_up->getNext()) {
311 auto func_sp =
312 sc.comp_unit->FindFunctionByUID(pdb_func_up->getSymIndexId());
313 if (!func_sp) {
Aaron Smithe664b5d2018-03-19 21:14:19 +0000314 if (ParseCompileUnitFunctionForPDBFunc(*pdb_func_up, sc))
Aaron Smith7ac1c782018-02-09 05:31:28 +0000315 ++func_added;
316 }
317 }
318 return func_added;
Zachary Turner74e08ca2016-03-02 22:05:52 +0000319}
320
Kate Stoneb9c1b512016-09-06 20:57:50 +0000321bool SymbolFilePDB::ParseCompileUnitLineTable(
322 const lldb_private::SymbolContext &sc) {
Aaron Smith10a02572018-01-13 06:58:18 +0000323 lldbassert(sc.comp_unit);
324 if (sc.comp_unit->GetLineTable())
325 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000326 return ParseCompileUnitLineTable(sc, 0);
Zachary Turner74e08ca2016-03-02 22:05:52 +0000327}
328
Kate Stoneb9c1b512016-09-06 20:57:50 +0000329bool SymbolFilePDB::ParseCompileUnitDebugMacros(
330 const lldb_private::SymbolContext &sc) {
331 // PDB doesn't contain information about macros
332 return false;
333}
334
335bool SymbolFilePDB::ParseCompileUnitSupportFiles(
336 const lldb_private::SymbolContext &sc,
337 lldb_private::FileSpecList &support_files) {
Aaron Smith10a02572018-01-13 06:58:18 +0000338 lldbassert(sc.comp_unit);
Zachary Turner74e08ca2016-03-02 22:05:52 +0000339
Kate Stoneb9c1b512016-09-06 20:57:50 +0000340 // In theory this is unnecessary work for us, because all of this information
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +0000341 // is easily (and quickly) accessible from DebugInfoPDB, so caching it a
342 // second time seems like a waste. Unfortunately, there's no good way around
343 // this short of a moderate refactor since SymbolVendor depends on being able
344 // to cache this list.
Aaron Smith10a02572018-01-13 06:58:18 +0000345 auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID());
346 if (!compiland_up)
Zachary Turner74e08ca2016-03-02 22:05:52 +0000347 return false;
Aaron Smith10a02572018-01-13 06:58:18 +0000348 auto files = m_session_up->getSourceFilesForCompiland(*compiland_up);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000349 if (!files || files->getChildCount() == 0)
Zachary Turner74e08ca2016-03-02 22:05:52 +0000350 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000351
352 while (auto file = files->getNext()) {
Aaron Smith10a02572018-01-13 06:58:18 +0000353 FileSpec spec(file->getFileName(), false, FileSpec::ePathSyntaxWindows);
354 support_files.AppendIfUnique(spec);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000355 }
356 return true;
Zachary Turner74e08ca2016-03-02 22:05:52 +0000357}
358
Kate Stoneb9c1b512016-09-06 20:57:50 +0000359bool SymbolFilePDB::ParseImportedModules(
360 const lldb_private::SymbolContext &sc,
361 std::vector<lldb_private::ConstString> &imported_modules) {
362 // PDB does not yet support module debug info
363 return false;
Zachary Turner74e08ca2016-03-02 22:05:52 +0000364}
365
Aaron Smith7ac1c782018-02-09 05:31:28 +0000366static size_t
367ParseFunctionBlocksForPDBSymbol(const lldb_private::SymbolContext &sc,
368 uint64_t func_file_vm_addr,
369 const llvm::pdb::PDBSymbol *pdb_symbol,
370 lldb_private::Block *parent_block,
371 bool is_top_parent) {
372 assert(pdb_symbol && parent_block);
373
374 size_t num_added = 0;
375 switch (pdb_symbol->getSymTag()) {
376 case PDB_SymType::Block:
377 case PDB_SymType::Function: {
378 Block *block = nullptr;
379 auto &raw_sym = pdb_symbol->getRawSymbol();
380 if (auto *pdb_func = llvm::dyn_cast<PDBSymbolFunc>(pdb_symbol)) {
381 if (pdb_func->hasNoInlineAttribute())
382 break;
383 if (is_top_parent)
384 block = parent_block;
385 else
386 break;
387 } else if (llvm::dyn_cast<PDBSymbolBlock>(pdb_symbol)) {
388 auto uid = pdb_symbol->getSymIndexId();
389 if (parent_block->FindBlockByID(uid))
390 break;
391 if (raw_sym.getVirtualAddress() < func_file_vm_addr)
392 break;
393
394 auto block_sp = std::make_shared<Block>(pdb_symbol->getSymIndexId());
395 parent_block->AddChild(block_sp);
396 block = block_sp.get();
397 } else
398 llvm_unreachable("Unexpected PDB symbol!");
399
400 block->AddRange(
401 Block::Range(raw_sym.getVirtualAddress() - func_file_vm_addr,
402 raw_sym.getLength()));
403 block->FinalizeRanges();
404 ++num_added;
405
406 auto results_up = pdb_symbol->findAllChildren();
407 if (!results_up)
408 break;
409 while (auto symbol_up = results_up->getNext()) {
410 num_added += ParseFunctionBlocksForPDBSymbol(sc, func_file_vm_addr,
411 symbol_up.get(),
412 block, false);
413 }
414 } break;
415 default: break;
416 }
417 return num_added;
418}
419
Zachary Turner74e08ca2016-03-02 22:05:52 +0000420size_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000421SymbolFilePDB::ParseFunctionBlocks(const lldb_private::SymbolContext &sc) {
Aaron Smith7ac1c782018-02-09 05:31:28 +0000422 lldbassert(sc.comp_unit && sc.function);
423 size_t num_added = 0;
424 auto uid = sc.function->GetID();
425 auto pdb_func_up = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(uid);
426 if (!pdb_func_up)
427 return 0;
428 Block &parent_block = sc.function->GetBlock(false);
429 num_added =
430 ParseFunctionBlocksForPDBSymbol(sc, pdb_func_up->getVirtualAddress(),
431 pdb_func_up.get(), &parent_block, true);
432 return num_added;
Zachary Turner74e08ca2016-03-02 22:05:52 +0000433}
434
Kate Stoneb9c1b512016-09-06 20:57:50 +0000435size_t SymbolFilePDB::ParseTypes(const lldb_private::SymbolContext &sc) {
Aaron Smithec40f812018-01-23 20:35:19 +0000436 lldbassert(sc.module_sp.get());
Aaron Smith66b84072018-03-14 04:05:27 +0000437 if (!sc.comp_unit)
Aaron Smithec40f812018-01-23 20:35:19 +0000438 return 0;
Aaron Smith66b84072018-03-14 04:05:27 +0000439
440 size_t num_added = 0;
441 auto compiland = GetPDBCompilandByUID(sc.comp_unit->GetID());
442 if (!compiland)
443 return 0;
444
445 auto ParseTypesByTagFn = [&num_added, this](const PDBSymbol &raw_sym) {
446 std::unique_ptr<IPDBEnumSymbols> results;
447 PDB_SymType tags_to_search[] = { PDB_SymType::Enum, PDB_SymType::Typedef,
448 PDB_SymType::UDT };
449 for (auto tag : tags_to_search) {
450 results = raw_sym.findAllChildren(tag);
451 if (!results || results->getChildCount() == 0)
452 continue;
453 while (auto symbol = results->getNext()) {
454 switch (symbol->getSymTag()) {
455 case PDB_SymType::Enum:
456 case PDB_SymType::UDT:
457 case PDB_SymType::Typedef:
458 break;
459 default:
460 continue;
461 }
462
463 // This should cause the type to get cached and stored in the `m_types`
464 // lookup.
465 if (!ResolveTypeUID(symbol->getSymIndexId()))
466 continue;
467
468 ++num_added;
469 }
Aaron Smithec40f812018-01-23 20:35:19 +0000470 }
Aaron Smith66b84072018-03-14 04:05:27 +0000471 };
Aaron Smithec40f812018-01-23 20:35:19 +0000472
Aaron Smith66b84072018-03-14 04:05:27 +0000473 if (sc.function) {
474 auto pdb_func =
475 m_session_up->getConcreteSymbolById<PDBSymbolFunc>(sc.function->GetID());
476 if (!pdb_func)
477 return 0;
478 ParseTypesByTagFn(*pdb_func);
479 } else {
480 ParseTypesByTagFn(*compiland);
Aaron Smithec40f812018-01-23 20:35:19 +0000481
Aaron Smith66b84072018-03-14 04:05:27 +0000482 // Also parse global types particularly coming from this compiland.
483 // Unfortunately, PDB has no compiland information for each global type.
484 // We have to parse them all. But ensure we only do this once.
485 static bool parse_all_global_types = false;
486 if (!parse_all_global_types) {
487 ParseTypesByTagFn(*m_global_scope_up);
488 parse_all_global_types = true;
489 }
Aaron Smithec40f812018-01-23 20:35:19 +0000490 }
491 return num_added;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000492}
493
494size_t
495SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) {
496 // TODO: Implement this
497 return size_t();
498}
499
500lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
501 auto find_result = m_types.find(type_uid);
502 if (find_result != m_types.end())
503 return find_result->second.get();
504
505 TypeSystem *type_system =
506 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
507 ClangASTContext *clang_type_system =
508 llvm::dyn_cast_or_null<ClangASTContext>(type_system);
509 if (!clang_type_system)
Zachary Turner74e08ca2016-03-02 22:05:52 +0000510 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000511 PDBASTParser *pdb =
512 llvm::dyn_cast<PDBASTParser>(clang_type_system->GetPDBParser());
513 if (!pdb)
514 return nullptr;
515
516 auto pdb_type = m_session_up->getSymbolById(type_uid);
517 if (pdb_type == nullptr)
518 return nullptr;
519
520 lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type);
Aaron Smithec40f812018-01-23 20:35:19 +0000521 if (result.get()) {
Aaron Smith86e94342017-12-22 05:26:50 +0000522 m_types.insert(std::make_pair(type_uid, result));
Aaron Smithec40f812018-01-23 20:35:19 +0000523 auto type_list = GetTypeList();
Aaron Smithf76fe682018-03-07 03:16:50 +0000524 if (type_list)
525 type_list->Insert(result);
Aaron Smithec40f812018-01-23 20:35:19 +0000526 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000527 return result.get();
Zachary Turner74e08ca2016-03-02 22:05:52 +0000528}
529
Kate Stoneb9c1b512016-09-06 20:57:50 +0000530bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) {
531 // TODO: Implement this
532 return false;
533}
534
535lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) {
536 return lldb_private::CompilerDecl();
537}
538
539lldb_private::CompilerDeclContext
540SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) {
541 // PDB always uses the translation unit decl context for everything. We can
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +0000542 // improve this later but it's not easy because PDB doesn't provide a high
543 // enough level of type fidelity in this area.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000544 return *m_tu_decl_ctx_up;
545}
546
547lldb_private::CompilerDeclContext
548SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
549 return *m_tu_decl_ctx_up;
550}
551
552void SymbolFilePDB::ParseDeclsForContext(
553 lldb_private::CompilerDeclContext decl_ctx) {}
554
555uint32_t
556SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,
557 uint32_t resolve_scope,
558 lldb_private::SymbolContext &sc) {
Aaron Smith7ac1c782018-02-09 05:31:28 +0000559 uint32_t resolved_flags = 0;
Pavel Labath4d4d63e2018-02-09 11:37:01 +0000560 if (resolve_scope & eSymbolContextCompUnit ||
561 resolve_scope & eSymbolContextVariable ||
562 resolve_scope & eSymbolContextFunction ||
563 resolve_scope & eSymbolContextBlock ||
Aaron Smith7ac1c782018-02-09 05:31:28 +0000564 resolve_scope & eSymbolContextLineEntry) {
565 addr_t file_vm_addr = so_addr.GetFileAddress();
566 auto symbol_up =
567 m_session_up->findSymbolByAddress(file_vm_addr, PDB_SymType::None);
568 if (!symbol_up)
569 return 0;
570
571 auto cu_sp = GetCompileUnitContainsAddress(so_addr);
572 if (!cu_sp) {
573 if (resolved_flags | eSymbolContextVariable) {
574 // TODO: Resolve variables
575 }
576 return 0;
577 }
578 sc.comp_unit = cu_sp.get();
579 resolved_flags |= eSymbolContextCompUnit;
580 lldbassert(sc.module_sp == cu_sp->GetModule());
581
582 switch (symbol_up->getSymTag()) {
583 case PDB_SymType::Function:
584 if (resolve_scope & eSymbolContextFunction) {
585 auto *pdb_func = llvm::dyn_cast<PDBSymbolFunc>(symbol_up.get());
586 assert(pdb_func);
587 auto func_uid = pdb_func->getSymIndexId();
588 sc.function = sc.comp_unit->FindFunctionByUID(func_uid).get();
589 if (sc.function == nullptr)
Aaron Smithe664b5d2018-03-19 21:14:19 +0000590 sc.function = ParseCompileUnitFunctionForPDBFunc(*pdb_func, sc);
Aaron Smith7ac1c782018-02-09 05:31:28 +0000591 if (sc.function) {
592 resolved_flags |= eSymbolContextFunction;
593 if (resolve_scope & eSymbolContextBlock) {
594 Block &block = sc.function->GetBlock(true);
595 sc.block = block.FindBlockByID(sc.function->GetID());
596 if (sc.block)
597 resolved_flags |= eSymbolContextBlock;
598 }
599 }
600 }
601 break;
602 default:
603 break;
604 }
605
606 if (resolve_scope & eSymbolContextLineEntry) {
607 if (auto *line_table = sc.comp_unit->GetLineTable()) {
608 Address addr(so_addr);
609 if (line_table->FindLineEntryByAddress(addr, sc.line_entry))
610 resolved_flags |= eSymbolContextLineEntry;
611 }
612 }
613 }
614 return resolved_flags;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000615}
616
Aaron Smith10a02572018-01-13 06:58:18 +0000617std::string SymbolFilePDB::GetSourceFileNameForPDBCompiland(
618 const PDBSymbolCompiland *pdb_compiland) {
619 if (!pdb_compiland)
620 return std::string();
621
622 std::string source_file_name;
623 // `getSourceFileName` returns the basename of the original source file
624 // used to generate this compiland. It does not return the full path.
625 // Currently the only way to get that is to do a basename lookup to get the
626 // IPDBSourceFile, but this is ambiguous in the case of two source files
627 // with the same name contributing to the same compiland. This is an edge
628 // case that we ignore for now, although we need to a long-term solution.
629 std::string file_name = pdb_compiland->getSourceFileName();
630 if (!file_name.empty()) {
631 auto one_src_file_up =
Aaron Smithf76fe682018-03-07 03:16:50 +0000632 m_session_up->findOneSourceFile(pdb_compiland, file_name,
633 PDB_NameSearchFlags::NS_CaseInsensitive);
Aaron Smith10a02572018-01-13 06:58:18 +0000634 if (one_src_file_up)
635 source_file_name = one_src_file_up->getFileName();
636 }
637 // For some reason, source file name could be empty, so we will walk through
638 // all source files of this compiland, and determine the right source file
639 // if any that is used to generate this compiland based on language
640 // indicated in compilanddetails language field.
641 if (!source_file_name.empty())
642 return source_file_name;
643
644 auto details_up = pdb_compiland->findOneChild<PDBSymbolCompilandDetails>();
645 PDB_Lang pdb_lang = details_up ? details_up->getLanguage() : PDB_Lang::Cpp;
646 auto src_files_up =
Aaron Smithf76fe682018-03-07 03:16:50 +0000647 m_session_up->getSourceFilesForCompiland(*pdb_compiland);
Aaron Smith10a02572018-01-13 06:58:18 +0000648 if (src_files_up) {
649 while (auto file_up = src_files_up->getNext()) {
650 FileSpec file_spec(file_up->getFileName(), false,
651 FileSpec::ePathSyntaxWindows);
652 auto file_extension = file_spec.GetFileNameExtension();
653 if (pdb_lang == PDB_Lang::Cpp || pdb_lang == PDB_Lang::C) {
654 static const char* exts[] = { "cpp", "c", "cc", "cxx" };
Aaron Smithdee18b82018-03-09 18:50:19 +0000655 if (llvm::is_contained(exts, file_extension.GetStringRef().lower())) {
Aaron Smith10a02572018-01-13 06:58:18 +0000656 source_file_name = file_up->getFileName();
Aaron Smithdee18b82018-03-09 18:50:19 +0000657 break;
658 }
Aaron Smith10a02572018-01-13 06:58:18 +0000659 } else if (pdb_lang == PDB_Lang::Masm &&
660 ConstString::Compare(file_extension, ConstString("ASM"),
661 false) == 0) {
662 source_file_name = file_up->getFileName();
663 break;
664 }
665 }
666 }
667 return source_file_name;
668}
669
Kate Stoneb9c1b512016-09-06 20:57:50 +0000670uint32_t SymbolFilePDB::ResolveSymbolContext(
671 const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines,
672 uint32_t resolve_scope, lldb_private::SymbolContextList &sc_list) {
Aaron Smith10a02572018-01-13 06:58:18 +0000673 const size_t old_size = sc_list.GetSize();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000674 if (resolve_scope & lldb::eSymbolContextCompUnit) {
675 // Locate all compilation units with line numbers referencing the specified
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +0000676 // file. For example, if `file_spec` is <vector>, then this should return
677 // all source files and header files that reference <vector>, either
678 // directly or indirectly.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000679 auto compilands = m_session_up->findCompilandsForSourceFile(
680 file_spec.GetPath(), PDB_NameSearchFlags::NS_CaseInsensitive);
681
Aaron Smith10a02572018-01-13 06:58:18 +0000682 if (!compilands)
683 return 0;
684
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +0000685 // For each one, either find its previously parsed data or parse it afresh
686 // and add it to the symbol context list.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000687 while (auto compiland = compilands->getNext()) {
688 // If we're not checking inlines, then don't add line information for this
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +0000689 // file unless the FileSpec matches.
Aaron Smith7ac1c782018-02-09 05:31:28 +0000690 // For inline functions, we don't have to match the FileSpec since they
691 // could be defined in headers other than file specified in FileSpec.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000692 if (!check_inlines) {
693 // `getSourceFileName` returns the basename of the original source file
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +0000694 // used to generate this compiland. It does not return the full path.
695 // Currently the only way to get that is to do a basename lookup to get
696 // the IPDBSourceFile, but this is ambiguous in the case of two source
697 // files with the same name contributing to the same compiland. This is
698 // a moderately extreme edge case, so we consider this OK for now,
699 // although we need to find a long-term solution.
Aaron Smith10a02572018-01-13 06:58:18 +0000700 std::string source_file =
701 GetSourceFileNameForPDBCompiland(compiland.get());
702 if (source_file.empty())
703 continue;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000704 FileSpec this_spec(source_file, false, FileSpec::ePathSyntaxWindows);
Aaron Smith10a02572018-01-13 06:58:18 +0000705 bool need_full_match = !file_spec.GetDirectory().IsEmpty();
706 if (FileSpec::Compare(file_spec, this_spec, need_full_match) != 0)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000707 continue;
708 }
709
710 SymbolContext sc;
Aaron Smith10a02572018-01-13 06:58:18 +0000711 auto cu = ParseCompileUnitForUID(compiland->getSymIndexId());
712 if (!cu.get())
713 continue;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000714 sc.comp_unit = cu.get();
715 sc.module_sp = cu->GetModule();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000716
717 // If we were asked to resolve line entries, add all entries to the line
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +0000718 // table that match the requested line (or all lines if `line` == 0).
Aaron Smith7ac1c782018-02-09 05:31:28 +0000719 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock |
720 eSymbolContextLineEntry)) {
721 bool has_line_table = ParseCompileUnitLineTable(sc, line);
722
723 if ((resolve_scope & eSymbolContextLineEntry) && !has_line_table) {
724 // The query asks for line entries, but we can't get them for the
725 // compile unit. This is not normal for `line` = 0. So just assert it.
Aaron Smithf76fe682018-03-07 03:16:50 +0000726 assert(line && "Couldn't get all line entries!\n");
Aaron Smith7ac1c782018-02-09 05:31:28 +0000727
728 // Current compiland does not have the requested line. Search next.
729 continue;
730 }
731
732 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) {
733 if (!has_line_table)
734 continue;
735
736 auto *line_table = sc.comp_unit->GetLineTable();
737 lldbassert(line_table);
738
739 uint32_t num_line_entries = line_table->GetSize();
740 // Skip the terminal line entry.
741 --num_line_entries;
742
743 // If `line `!= 0, see if we can resolve function for each line
744 // entry in the line table.
745 for (uint32_t line_idx = 0; line && line_idx < num_line_entries;
746 ++line_idx) {
747 if (!line_table->GetLineEntryAtIndex(line_idx, sc.line_entry))
748 continue;
749
750 auto file_vm_addr =
751 sc.line_entry.range.GetBaseAddress().GetFileAddress();
752 if (file_vm_addr == LLDB_INVALID_ADDRESS)
753 continue;
754
755 auto symbol_up =
756 m_session_up->findSymbolByAddress(file_vm_addr,
757 PDB_SymType::Function);
758 if (symbol_up) {
759 auto func_uid = symbol_up->getSymIndexId();
760 sc.function = sc.comp_unit->FindFunctionByUID(func_uid).get();
761 if (sc.function == nullptr) {
762 auto pdb_func = llvm::dyn_cast<PDBSymbolFunc>(symbol_up.get());
763 assert(pdb_func);
Aaron Smithe664b5d2018-03-19 21:14:19 +0000764 sc.function = ParseCompileUnitFunctionForPDBFunc(*pdb_func, sc);
Aaron Smith7ac1c782018-02-09 05:31:28 +0000765 }
766 if (sc.function && (resolve_scope & eSymbolContextBlock)) {
767 Block &block = sc.function->GetBlock(true);
768 sc.block = block.FindBlockByID(sc.function->GetID());
769 }
770 }
771 sc_list.Append(sc);
772 }
773 } else if (has_line_table) {
774 // We can parse line table for the compile unit. But no query to
775 // resolve function or block. We append `sc` to the list anyway.
776 sc_list.Append(sc);
777 }
778 } else {
779 // No query for line entry, function or block. But we have a valid
780 // compile unit, append `sc` to the list.
781 sc_list.Append(sc);
782 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000783 }
784 }
Aaron Smith10a02572018-01-13 06:58:18 +0000785 return sc_list.GetSize() - old_size;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000786}
787
788uint32_t SymbolFilePDB::FindGlobalVariables(
789 const lldb_private::ConstString &name,
790 const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append,
791 uint32_t max_matches, lldb_private::VariableList &variables) {
792 return uint32_t();
793}
794
795uint32_t
796SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression &regex,
797 bool append, uint32_t max_matches,
798 lldb_private::VariableList &variables) {
799 return uint32_t();
800}
801
Aaron Smithe664b5d2018-03-19 21:14:19 +0000802bool SymbolFilePDB::ResolveFunction(const llvm::pdb::PDBSymbolFunc &pdb_func,
Aaron Smith7ac1c782018-02-09 05:31:28 +0000803 bool include_inlines,
804 lldb_private::SymbolContextList &sc_list) {
Aaron Smith7ac1c782018-02-09 05:31:28 +0000805 lldb_private::SymbolContext sc;
Aaron Smithe664b5d2018-03-19 21:14:19 +0000806 auto file_vm_addr = pdb_func.getVirtualAddress();
Aaron Smith7ac1c782018-02-09 05:31:28 +0000807 if (file_vm_addr == LLDB_INVALID_ADDRESS)
808 return false;
809
810 Address so_addr(file_vm_addr);
811 sc.comp_unit = GetCompileUnitContainsAddress(so_addr).get();
812 if (!sc.comp_unit)
813 return false;
814 sc.module_sp = sc.comp_unit->GetModule();
815 auto symbol_up =
816 m_session_up->findSymbolByAddress(file_vm_addr, PDB_SymType::Function);
817 if (!symbol_up)
818 return false;
819
820 auto *func = llvm::dyn_cast<PDBSymbolFunc>(symbol_up.get());
821 assert(func);
Aaron Smithe664b5d2018-03-19 21:14:19 +0000822 sc.function = ParseCompileUnitFunctionForPDBFunc(*func, sc);
Aaron Smith7ac1c782018-02-09 05:31:28 +0000823 if (!sc.function)
824 return false;
825
826 sc_list.Append(sc);
827 return true;
828}
829
830bool SymbolFilePDB::ResolveFunction(uint32_t uid, bool include_inlines,
831 lldb_private::SymbolContextList &sc_list) {
832 auto pdb_func_up =
833 m_session_up->getConcreteSymbolById<PDBSymbolFunc>(uid);
834 if (!pdb_func_up && !(include_inlines && pdb_func_up->hasInlineAttribute()))
835 return false;
Aaron Smithe664b5d2018-03-19 21:14:19 +0000836 return ResolveFunction(*pdb_func_up, include_inlines, sc_list);
Aaron Smith7ac1c782018-02-09 05:31:28 +0000837}
838
839void SymbolFilePDB::CacheFunctionNames() {
840 if (!m_func_full_names.IsEmpty())
841 return;
842
843 std::map<uint64_t, uint32_t> addr_ids;
844
845 if (auto results_up = m_global_scope_up->findAllChildren<PDBSymbolFunc>()) {
846 while (auto pdb_func_up = results_up->getNext()) {
Aaron Smithf76fe682018-03-07 03:16:50 +0000847 if (pdb_func_up->isCompilerGenerated())
848 continue;
849
Aaron Smith7ac1c782018-02-09 05:31:28 +0000850 auto name = pdb_func_up->getName();
851 auto demangled_name = pdb_func_up->getUndecoratedName();
852 if (name.empty() && demangled_name.empty())
853 continue;
Aaron Smith7ac1c782018-02-09 05:31:28 +0000854
Aaron Smithf76fe682018-03-07 03:16:50 +0000855 auto uid = pdb_func_up->getSymIndexId();
Aaron Smith7ac1c782018-02-09 05:31:28 +0000856 if (!demangled_name.empty() && pdb_func_up->getVirtualAddress())
857 addr_ids.insert(std::make_pair(pdb_func_up->getVirtualAddress(), uid));
858
859 if (auto parent = pdb_func_up->getClassParent()) {
860
861 // PDB have symbols for class/struct methods or static methods in Enum
862 // Class. We won't bother to check if the parent is UDT or Enum here.
863 m_func_method_names.Append(ConstString(name), uid);
864
865 ConstString cstr_name(name);
866
867 // To search a method name, like NS::Class:MemberFunc, LLDB searches its
868 // base name, i.e. MemberFunc by default. Since PDBSymbolFunc does not
869 // have inforamtion of this, we extract base names and cache them by our
870 // own effort.
871 llvm::StringRef basename;
872 CPlusPlusLanguage::MethodName cpp_method(cstr_name);
873 if (cpp_method.IsValid()) {
874 llvm::StringRef context;
875 basename = cpp_method.GetBasename();
876 if (basename.empty())
877 CPlusPlusLanguage::ExtractContextAndIdentifier(name.c_str(),
878 context, basename);
879 }
880
881 if (!basename.empty())
882 m_func_base_names.Append(ConstString(basename), uid);
883 else {
884 m_func_base_names.Append(ConstString(name), uid);
885 }
886
887 if (!demangled_name.empty())
888 m_func_full_names.Append(ConstString(demangled_name), uid);
889
890 } else {
891 // Handle not-method symbols.
892
893 // The function name might contain namespace, or its lexical scope. It
894 // is not safe to get its base name by applying same scheme as we deal
895 // with the method names.
896 // FIXME: Remove namespace if function is static in a scope.
897 m_func_base_names.Append(ConstString(name), uid);
898
899 if (name == "main") {
900 m_func_full_names.Append(ConstString(name), uid);
901
902 if (!demangled_name.empty() && name != demangled_name) {
903 m_func_full_names.Append(ConstString(demangled_name), uid);
904 m_func_base_names.Append(ConstString(demangled_name), uid);
905 }
906 } else if (!demangled_name.empty()) {
907 m_func_full_names.Append(ConstString(demangled_name), uid);
908 } else {
909 m_func_full_names.Append(ConstString(name), uid);
910 }
911 }
912 }
913 }
914
915 if (auto results_up =
916 m_global_scope_up->findAllChildren<PDBSymbolPublicSymbol>()) {
917 while (auto pub_sym_up = results_up->getNext()) {
918 if (!pub_sym_up->isFunction())
919 continue;
920 auto name = pub_sym_up->getName();
921 if (name.empty())
922 continue;
923
924 if (CPlusPlusLanguage::IsCPPMangledName(name.c_str())) {
Aaron Smith7ac1c782018-02-09 05:31:28 +0000925 auto vm_addr = pub_sym_up->getVirtualAddress();
926
927 // PDB public symbol has mangled name for its associated function.
928 if (vm_addr && addr_ids.find(vm_addr) != addr_ids.end()) {
929 // Cache mangled name.
930 m_func_full_names.Append(ConstString(name), addr_ids[vm_addr]);
931 }
932 }
933 }
934 }
935 // Sort them before value searching is working properly
936 m_func_full_names.Sort();
937 m_func_full_names.SizeToFit();
938 m_func_method_names.Sort();
939 m_func_method_names.SizeToFit();
940 m_func_base_names.Sort();
941 m_func_base_names.SizeToFit();
942}
943
Kate Stoneb9c1b512016-09-06 20:57:50 +0000944uint32_t SymbolFilePDB::FindFunctions(
945 const lldb_private::ConstString &name,
946 const lldb_private::CompilerDeclContext *parent_decl_ctx,
947 uint32_t name_type_mask, bool include_inlines, bool append,
948 lldb_private::SymbolContextList &sc_list) {
Aaron Smith7ac1c782018-02-09 05:31:28 +0000949 if (!append)
950 sc_list.Clear();
951 lldbassert((name_type_mask & eFunctionNameTypeAuto) == 0);
952
953 if (name_type_mask == eFunctionNameTypeNone)
954 return 0;
955 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
956 return 0;
957 if (name.IsEmpty())
958 return 0;
959
960 auto old_size = sc_list.GetSize();
Pavel Labath4d4d63e2018-02-09 11:37:01 +0000961 if (name_type_mask & eFunctionNameTypeFull ||
962 name_type_mask & eFunctionNameTypeBase ||
Aaron Smith7ac1c782018-02-09 05:31:28 +0000963 name_type_mask & eFunctionNameTypeMethod) {
964 CacheFunctionNames();
965
966 std::set<uint32_t> resolved_ids;
967 auto ResolveFn = [include_inlines, &name, &sc_list, &resolved_ids, this] (
968 UniqueCStringMap<uint32_t> &Names)
969 {
970 std::vector<uint32_t> ids;
971 if (Names.GetValues(name, ids)) {
972 for (auto id : ids) {
973 if (resolved_ids.find(id) == resolved_ids.end()) {
974 if (ResolveFunction(id, include_inlines, sc_list))
975 resolved_ids.insert(id);
976 }
977 }
978 }
979 };
980 if (name_type_mask & eFunctionNameTypeFull) {
981 ResolveFn(m_func_full_names);
982 }
983 if (name_type_mask & eFunctionNameTypeBase) {
984 ResolveFn(m_func_base_names);
985 }
986 if (name_type_mask & eFunctionNameTypeMethod) {
987 ResolveFn(m_func_method_names);
988 }
989 }
990 return sc_list.GetSize() - old_size;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000991}
992
993uint32_t
994SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression &regex,
995 bool include_inlines, bool append,
996 lldb_private::SymbolContextList &sc_list) {
Aaron Smith7ac1c782018-02-09 05:31:28 +0000997 if (!append)
998 sc_list.Clear();
999 if (!regex.IsValid())
1000 return 0;
1001
1002 auto old_size = sc_list.GetSize();
1003 CacheFunctionNames();
1004
1005 std::set<uint32_t> resolved_ids;
1006 auto ResolveFn = [&regex, include_inlines, &sc_list, &resolved_ids, this] (
1007 UniqueCStringMap<uint32_t> &Names)
1008 {
1009 std::vector<uint32_t> ids;
1010 if (Names.GetValues(regex, ids)) {
1011 for (auto id : ids) {
1012 if (resolved_ids.find(id) == resolved_ids.end())
1013 if (ResolveFunction(id, include_inlines, sc_list))
1014 resolved_ids.insert(id);
1015 }
1016 }
1017 };
1018 ResolveFn(m_func_full_names);
1019 ResolveFn(m_func_base_names);
1020
1021 return sc_list.GetSize() - old_size;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001022}
1023
1024void SymbolFilePDB::GetMangledNamesForFunction(
1025 const std::string &scope_qualified_name,
1026 std::vector<lldb_private::ConstString> &mangled_names) {}
1027
1028uint32_t SymbolFilePDB::FindTypes(
1029 const lldb_private::SymbolContext &sc,
1030 const lldb_private::ConstString &name,
1031 const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append,
1032 uint32_t max_matches,
1033 llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
1034 lldb_private::TypeMap &types) {
1035 if (!append)
1036 types.Clear();
1037 if (!name)
1038 return 0;
Aaron Smith7ac1c782018-02-09 05:31:28 +00001039 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
1040 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001041
1042 searched_symbol_files.clear();
1043 searched_symbol_files.insert(this);
1044
1045 std::string name_str = name.AsCString();
1046
Aaron Smith86e94342017-12-22 05:26:50 +00001047 // There is an assumption 'name' is not a regex
1048 FindTypesByName(name_str, max_matches, types);
1049
Kate Stoneb9c1b512016-09-06 20:57:50 +00001050 return types.GetSize();
1051}
1052
Aaron Smith86e94342017-12-22 05:26:50 +00001053void
1054SymbolFilePDB::FindTypesByRegex(const lldb_private::RegularExpression &regex,
1055 uint32_t max_matches,
1056 lldb_private::TypeMap &types) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001057 // When searching by regex, we need to go out of our way to limit the search
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +00001058 // space as much as possible since this searches EVERYTHING in the PDB,
1059 // manually doing regex comparisons. PDB library isn't optimized for regex
1060 // searches or searches across multiple symbol types at the same time, so the
Kate Stoneb9c1b512016-09-06 20:57:50 +00001061 // best we can do is to search enums, then typedefs, then classes one by one,
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +00001062 // and do a regex comparison against each of them.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001063 PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef,
1064 PDB_SymType::UDT};
Kate Stoneb9c1b512016-09-06 20:57:50 +00001065 std::unique_ptr<IPDBEnumSymbols> results;
1066
Kate Stoneb9c1b512016-09-06 20:57:50 +00001067 uint32_t matches = 0;
1068
1069 for (auto tag : tags_to_search) {
Aaron Smith10a02572018-01-13 06:58:18 +00001070 results = m_global_scope_up->findAllChildren(tag);
1071 if (!results)
1072 continue;
1073
Kate Stoneb9c1b512016-09-06 20:57:50 +00001074 while (auto result = results->getNext()) {
1075 if (max_matches > 0 && matches >= max_matches)
1076 break;
1077
1078 std::string type_name;
1079 if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(result.get()))
1080 type_name = enum_type->getName();
1081 else if (auto typedef_type =
Aaron Smith7ac1c782018-02-09 05:31:28 +00001082 llvm::dyn_cast<PDBSymbolTypeTypedef>(result.get()))
Kate Stoneb9c1b512016-09-06 20:57:50 +00001083 type_name = typedef_type->getName();
1084 else if (auto class_type = llvm::dyn_cast<PDBSymbolTypeUDT>(result.get()))
1085 type_name = class_type->getName();
1086 else {
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +00001087 // We're looking only for types that have names. Skip symbols, as well
1088 // as unnamed types such as arrays, pointers, etc.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001089 continue;
1090 }
1091
Aaron Smith86e94342017-12-22 05:26:50 +00001092 if (!regex.Execute(type_name))
Kate Stoneb9c1b512016-09-06 20:57:50 +00001093 continue;
1094
1095 // This should cause the type to get cached and stored in the `m_types`
1096 // lookup.
1097 if (!ResolveTypeUID(result->getSymIndexId()))
1098 continue;
1099
1100 auto iter = m_types.find(result->getSymIndexId());
1101 if (iter == m_types.end())
1102 continue;
1103 types.Insert(iter->second);
1104 ++matches;
1105 }
1106 }
1107}
1108
1109void SymbolFilePDB::FindTypesByName(const std::string &name,
1110 uint32_t max_matches,
1111 lldb_private::TypeMap &types) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001112 std::unique_ptr<IPDBEnumSymbols> results;
Aaron Smithf76fe682018-03-07 03:16:50 +00001113 if (name.empty())
1114 return;
Aaron Smith10a02572018-01-13 06:58:18 +00001115 results = m_global_scope_up->findChildren(PDB_SymType::None, name,
1116 PDB_NameSearchFlags::NS_Default);
1117 if (!results)
1118 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001119
1120 uint32_t matches = 0;
1121
1122 while (auto result = results->getNext()) {
1123 if (max_matches > 0 && matches >= max_matches)
1124 break;
1125 switch (result->getSymTag()) {
1126 case PDB_SymType::Enum:
1127 case PDB_SymType::UDT:
1128 case PDB_SymType::Typedef:
1129 break;
1130 default:
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +00001131 // We're looking only for types that have names. Skip symbols, as well as
Kate Stoneb9c1b512016-09-06 20:57:50 +00001132 // unnamed types such as arrays, pointers, etc.
1133 continue;
1134 }
1135
1136 // This should cause the type to get cached and stored in the `m_types`
1137 // lookup.
1138 if (!ResolveTypeUID(result->getSymIndexId()))
1139 continue;
1140
1141 auto iter = m_types.find(result->getSymIndexId());
1142 if (iter == m_types.end())
1143 continue;
1144 types.Insert(iter->second);
1145 ++matches;
1146 }
1147}
1148
1149size_t SymbolFilePDB::FindTypes(
1150 const std::vector<lldb_private::CompilerContext> &contexts, bool append,
1151 lldb_private::TypeMap &types) {
1152 return 0;
1153}
1154
Aaron Smithec40f812018-01-23 20:35:19 +00001155lldb_private::TypeList *SymbolFilePDB::GetTypeList() {
1156 return m_obj_file->GetModule()->GetTypeList();
1157}
Kate Stoneb9c1b512016-09-06 20:57:50 +00001158
Aaron Smith7ac1c782018-02-09 05:31:28 +00001159void
Aaron Smithe664b5d2018-03-19 21:14:19 +00001160SymbolFilePDB::GetTypesForPDBSymbol(const llvm::pdb::PDBSymbol &pdb_symbol,
Aaron Smith7ac1c782018-02-09 05:31:28 +00001161 uint32_t type_mask,
1162 TypeCollection &type_collection) {
Aaron Smith7ac1c782018-02-09 05:31:28 +00001163 bool can_parse = false;
Aaron Smithe664b5d2018-03-19 21:14:19 +00001164 switch (pdb_symbol.getSymTag()) {
Aaron Smith7ac1c782018-02-09 05:31:28 +00001165 case PDB_SymType::ArrayType:
1166 can_parse = ((type_mask & eTypeClassArray) != 0);
1167 break;
1168 case PDB_SymType::BuiltinType:
1169 can_parse = ((type_mask & eTypeClassBuiltin) != 0);
1170 break;
1171 case PDB_SymType::Enum:
1172 can_parse = ((type_mask & eTypeClassEnumeration) != 0);
1173 break;
1174 case PDB_SymType::Function:
1175 case PDB_SymType::FunctionSig:
1176 can_parse = ((type_mask & eTypeClassFunction) != 0);
1177 break;
1178 case PDB_SymType::PointerType:
1179 can_parse = ((type_mask & (eTypeClassPointer | eTypeClassBlockPointer |
1180 eTypeClassMemberPointer)) != 0);
1181 break;
1182 case PDB_SymType::Typedef:
1183 can_parse = ((type_mask & eTypeClassTypedef) != 0);
1184 break;
1185 case PDB_SymType::UDT: {
Aaron Smithe664b5d2018-03-19 21:14:19 +00001186 auto *udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&pdb_symbol);
Aaron Smith7ac1c782018-02-09 05:31:28 +00001187 assert(udt);
1188 can_parse = (udt->getUdtKind() != PDB_UdtType::Interface &&
1189 ((type_mask & (eTypeClassClass | eTypeClassStruct |
1190 eTypeClassUnion)) != 0));
1191 } break;
1192 default:break;
1193 }
1194
1195 if (can_parse) {
Aaron Smithe664b5d2018-03-19 21:14:19 +00001196 if (auto *type = ResolveTypeUID(pdb_symbol.getSymIndexId())) {
Aaron Smith7ac1c782018-02-09 05:31:28 +00001197 auto result =
1198 std::find(type_collection.begin(), type_collection.end(), type);
1199 if (result == type_collection.end())
1200 type_collection.push_back(type);
1201 }
1202 }
1203
Aaron Smithe664b5d2018-03-19 21:14:19 +00001204 auto results_up = pdb_symbol.findAllChildren();
Aaron Smith7ac1c782018-02-09 05:31:28 +00001205 while (auto symbol_up = results_up->getNext())
Aaron Smithe664b5d2018-03-19 21:14:19 +00001206 GetTypesForPDBSymbol(*symbol_up, type_mask, type_collection);
Aaron Smith7ac1c782018-02-09 05:31:28 +00001207}
1208
Kate Stoneb9c1b512016-09-06 20:57:50 +00001209size_t SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
1210 uint32_t type_mask,
1211 lldb_private::TypeList &type_list) {
Aaron Smith7ac1c782018-02-09 05:31:28 +00001212 TypeCollection type_collection;
1213 uint32_t old_size = type_list.GetSize();
1214 CompileUnit *cu = sc_scope ?
1215 sc_scope->CalculateSymbolContextCompileUnit() : nullptr;
1216 if (cu) {
1217 auto compiland_up = GetPDBCompilandByUID(cu->GetID());
Aaron Smithe664b5d2018-03-19 21:14:19 +00001218 if (!compiland_up)
1219 return 0;
1220 GetTypesForPDBSymbol(*compiland_up, type_mask, type_collection);
Aaron Smith7ac1c782018-02-09 05:31:28 +00001221 } else {
1222 for (uint32_t cu_idx = 0; cu_idx < GetNumCompileUnits(); ++cu_idx) {
1223 auto cu_sp = ParseCompileUnitAtIndex(cu_idx);
1224 if (cu_sp.get()) {
Aaron Smithe664b5d2018-03-19 21:14:19 +00001225 if (auto compiland_up = GetPDBCompilandByUID(cu_sp->GetID()))
1226 GetTypesForPDBSymbol(*compiland_up, type_mask, type_collection);
Aaron Smith7ac1c782018-02-09 05:31:28 +00001227 }
1228 }
1229 }
1230
1231 for (auto type : type_collection) {
1232 type->GetForwardCompilerType();
1233 type_list.Insert(type->shared_from_this());
1234 }
1235 return type_list.GetSize() - old_size;
Zachary Turner74e08ca2016-03-02 22:05:52 +00001236}
1237
1238lldb_private::TypeSystem *
Kate Stoneb9c1b512016-09-06 20:57:50 +00001239SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {
1240 auto type_system =
1241 m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
1242 if (type_system)
1243 type_system->SetSymbolFile(this);
1244 return type_system;
Zachary Turner74e08ca2016-03-02 22:05:52 +00001245}
1246
Kate Stoneb9c1b512016-09-06 20:57:50 +00001247lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace(
1248 const lldb_private::SymbolContext &sc,
1249 const lldb_private::ConstString &name,
1250 const lldb_private::CompilerDeclContext *parent_decl_ctx) {
1251 return lldb_private::CompilerDeclContext();
Zachary Turner74e08ca2016-03-02 22:05:52 +00001252}
1253
Kate Stoneb9c1b512016-09-06 20:57:50 +00001254lldb_private::ConstString SymbolFilePDB::GetPluginName() {
1255 static ConstString g_name("pdb");
1256 return g_name;
Zachary Turner74e08ca2016-03-02 22:05:52 +00001257}
1258
Kate Stoneb9c1b512016-09-06 20:57:50 +00001259uint32_t SymbolFilePDB::GetPluginVersion() { return 1; }
1260
1261IPDBSession &SymbolFilePDB::GetPDBSession() { return *m_session_up; }
1262
1263const IPDBSession &SymbolFilePDB::GetPDBSession() const {
1264 return *m_session_up;
Zachary Turner74e08ca2016-03-02 22:05:52 +00001265}
1266
Aaron Smith10a02572018-01-13 06:58:18 +00001267lldb::CompUnitSP
1268SymbolFilePDB::ParseCompileUnitForUID(uint32_t id, uint32_t index) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001269 auto found_cu = m_comp_units.find(id);
1270 if (found_cu != m_comp_units.end())
1271 return found_cu->second;
1272
Aaron Smith10a02572018-01-13 06:58:18 +00001273 auto compiland_up = GetPDBCompilandByUID(id);
1274 if (!compiland_up)
1275 return CompUnitSP();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001276
1277 lldb::LanguageType lang;
Aaron Smith10a02572018-01-13 06:58:18 +00001278 auto details = compiland_up->findOneChild<PDBSymbolCompilandDetails>();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001279 if (!details)
1280 lang = lldb::eLanguageTypeC_plus_plus;
1281 else
1282 lang = TranslateLanguage(details->getLanguage());
1283
Aaron Smithf76fe682018-03-07 03:16:50 +00001284 if (lang == lldb::LanguageType::eLanguageTypeUnknown)
1285 return CompUnitSP();
1286
1287 std::string path = GetSourceFileNameForPDBCompiland(compiland_up.get());
1288 if (path.empty())
1289 return CompUnitSP();
1290
Kate Stoneb9c1b512016-09-06 20:57:50 +00001291 // Don't support optimized code for now, DebugInfoPDB does not return this
1292 // information.
1293 LazyBool optimized = eLazyBoolNo;
Aaron Smith10a02572018-01-13 06:58:18 +00001294 auto cu_sp = std::make_shared<CompileUnit>(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001295 m_obj_file->GetModule(), nullptr, path.c_str(), id, lang, optimized);
Aaron Smith10a02572018-01-13 06:58:18 +00001296
1297 if (!cu_sp)
1298 return CompUnitSP();
1299
1300 m_comp_units.insert(std::make_pair(id, cu_sp));
1301 if (index == UINT32_MAX)
Aaron Smithe664b5d2018-03-19 21:14:19 +00001302 GetCompileUnitIndex(*compiland_up, index);
Aaron Smith10a02572018-01-13 06:58:18 +00001303 lldbassert(index != UINT32_MAX);
1304 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
1305 index, cu_sp);
1306 return cu_sp;
Zachary Turner42dff792016-04-15 00:21:26 +00001307}
1308
Kate Stoneb9c1b512016-09-06 20:57:50 +00001309bool SymbolFilePDB::ParseCompileUnitLineTable(
1310 const lldb_private::SymbolContext &sc, uint32_t match_line) {
Aaron Smith10a02572018-01-13 06:58:18 +00001311 lldbassert(sc.comp_unit);
1312
1313 auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID());
1314 if (!compiland_up)
1315 return false;
Zachary Turner42dff792016-04-15 00:21:26 +00001316
Kate Stoneb9c1b512016-09-06 20:57:50 +00001317 // LineEntry needs the *index* of the file into the list of support files
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +00001318 // returned by ParseCompileUnitSupportFiles. But the underlying SDK gives us
1319 // a globally unique idenfitifier in the namespace of the PDB. So, we have to
1320 // do a mapping so that we can hand out indices.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001321 llvm::DenseMap<uint32_t, uint32_t> index_map;
Aaron Smith10a02572018-01-13 06:58:18 +00001322 BuildSupportFileIdToSupportFileIndexMap(*compiland_up, index_map);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001323 auto line_table = llvm::make_unique<LineTable>(sc.comp_unit);
Zachary Turner74e08ca2016-03-02 22:05:52 +00001324
Aaron Smith10a02572018-01-13 06:58:18 +00001325 // Find contributions to `compiland` from all source and header files.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001326 std::string path = sc.comp_unit->GetPath();
Aaron Smith10a02572018-01-13 06:58:18 +00001327 auto files = m_session_up->getSourceFilesForCompiland(*compiland_up);
1328 if (!files)
1329 return false;
Zachary Turner74e08ca2016-03-02 22:05:52 +00001330
Kate Stoneb9c1b512016-09-06 20:57:50 +00001331 // For each source and header file, create a LineSequence for contributions to
Aaron Smith10a02572018-01-13 06:58:18 +00001332 // the compiland from that file, and add the sequence.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001333 while (auto file = files->getNext()) {
1334 std::unique_ptr<LineSequence> sequence(
1335 line_table->CreateLineSequenceContainer());
Aaron Smith10a02572018-01-13 06:58:18 +00001336 auto lines = m_session_up->findLineNumbers(*compiland_up, *file);
1337 if (!lines)
1338 continue;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001339 int entry_count = lines->getChildCount();
Zachary Turner74e08ca2016-03-02 22:05:52 +00001340
Kate Stoneb9c1b512016-09-06 20:57:50 +00001341 uint64_t prev_addr;
1342 uint32_t prev_length;
1343 uint32_t prev_line;
1344 uint32_t prev_source_idx;
Zachary Turner74e08ca2016-03-02 22:05:52 +00001345
Kate Stoneb9c1b512016-09-06 20:57:50 +00001346 for (int i = 0; i < entry_count; ++i) {
1347 auto line = lines->getChildAtIndex(i);
Zachary Turner74e08ca2016-03-02 22:05:52 +00001348
Kate Stoneb9c1b512016-09-06 20:57:50 +00001349 uint64_t lno = line->getLineNumber();
1350 uint64_t addr = line->getVirtualAddress();
1351 uint32_t length = line->getLength();
1352 uint32_t source_id = line->getSourceFileId();
1353 uint32_t col = line->getColumnNumber();
1354 uint32_t source_idx = index_map[source_id];
Zachary Turner74e08ca2016-03-02 22:05:52 +00001355
Kate Stoneb9c1b512016-09-06 20:57:50 +00001356 // There was a gap between the current entry and the previous entry if the
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +00001357 // addresses don't perfectly line up.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001358 bool is_gap = (i > 0) && (prev_addr + prev_length < addr);
Zachary Turner74e08ca2016-03-02 22:05:52 +00001359
Kate Stoneb9c1b512016-09-06 20:57:50 +00001360 // Before inserting the current entry, insert a terminal entry at the end
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +00001361 // of the previous entry's address range if the current entry resulted in
1362 // a gap from the previous entry.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001363 if (is_gap && ShouldAddLine(match_line, prev_line, prev_length)) {
1364 line_table->AppendLineEntryToSequence(
1365 sequence.get(), prev_addr + prev_length, prev_line, 0,
1366 prev_source_idx, false, false, false, false, true);
1367 }
Zachary Turner74e08ca2016-03-02 22:05:52 +00001368
Kate Stoneb9c1b512016-09-06 20:57:50 +00001369 if (ShouldAddLine(match_line, lno, length)) {
1370 bool is_statement = line->isStatement();
1371 bool is_prologue = false;
1372 bool is_epilogue = false;
1373 auto func =
1374 m_session_up->findSymbolByAddress(addr, PDB_SymType::Function);
1375 if (func) {
1376 auto prologue = func->findOneChild<PDBSymbolFuncDebugStart>();
Aaron Smith10a02572018-01-13 06:58:18 +00001377 if (prologue)
1378 is_prologue = (addr == prologue->getVirtualAddress());
Zachary Turner74e08ca2016-03-02 22:05:52 +00001379
Kate Stoneb9c1b512016-09-06 20:57:50 +00001380 auto epilogue = func->findOneChild<PDBSymbolFuncDebugEnd>();
Aaron Smith10a02572018-01-13 06:58:18 +00001381 if (epilogue)
1382 is_epilogue = (addr == epilogue->getVirtualAddress());
Zachary Turner74e08ca2016-03-02 22:05:52 +00001383 }
Zachary Turner7e8c7be2016-03-10 00:06:26 +00001384
Kate Stoneb9c1b512016-09-06 20:57:50 +00001385 line_table->AppendLineEntryToSequence(sequence.get(), addr, lno, col,
1386 source_idx, is_statement, false,
1387 is_prologue, is_epilogue, false);
1388 }
Zachary Turner7e8c7be2016-03-10 00:06:26 +00001389
Kate Stoneb9c1b512016-09-06 20:57:50 +00001390 prev_addr = addr;
1391 prev_length = length;
1392 prev_line = lno;
1393 prev_source_idx = source_idx;
Zachary Turner74e08ca2016-03-02 22:05:52 +00001394 }
1395
Kate Stoneb9c1b512016-09-06 20:57:50 +00001396 if (entry_count > 0 && ShouldAddLine(match_line, prev_line, prev_length)) {
1397 // The end is always a terminal entry, so insert it regardless.
1398 line_table->AppendLineEntryToSequence(
1399 sequence.get(), prev_addr + prev_length, prev_line, 0,
1400 prev_source_idx, false, false, false, false, true);
1401 }
1402
1403 line_table->InsertSequence(sequence.release());
1404 }
1405
Aaron Smith10a02572018-01-13 06:58:18 +00001406 if (line_table->GetSize()) {
1407 sc.comp_unit->SetLineTable(line_table.release());
1408 return true;
1409 }
1410 return false;
Zachary Turner74e08ca2016-03-02 22:05:52 +00001411}
1412
Kate Stoneb9c1b512016-09-06 20:57:50 +00001413void SymbolFilePDB::BuildSupportFileIdToSupportFileIndexMap(
Aaron Smith10a02572018-01-13 06:58:18 +00001414 const PDBSymbolCompiland &compiland,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001415 llvm::DenseMap<uint32_t, uint32_t> &index_map) const {
1416 // This is a hack, but we need to convert the source id into an index into the
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +00001417 // support files array. We don't want to do path comparisons to avoid
1418 // basename / full path issues that may or may not even be a problem, so we
1419 // use the globally unique source file identifiers. Ideally we could use the
1420 // global identifiers everywhere, but LineEntry currently assumes indices.
Aaron Smith10a02572018-01-13 06:58:18 +00001421 auto source_files = m_session_up->getSourceFilesForCompiland(compiland);
1422 if (!source_files)
1423 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001424 int index = 0;
Zachary Turner74e08ca2016-03-02 22:05:52 +00001425
Kate Stoneb9c1b512016-09-06 20:57:50 +00001426 while (auto file = source_files->getNext()) {
1427 uint32_t source_id = file->getUniqueId();
1428 index_map[source_id] = index++;
1429 }
Zachary Turner74e08ca2016-03-02 22:05:52 +00001430}
Aaron Smith7ac1c782018-02-09 05:31:28 +00001431
1432lldb::CompUnitSP SymbolFilePDB::GetCompileUnitContainsAddress(
1433 const lldb_private::Address &so_addr) {
1434 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1435 if (file_vm_addr == LLDB_INVALID_ADDRESS)
1436 return nullptr;
1437
1438 auto lines_up =
1439 m_session_up->findLineNumbersByAddress(file_vm_addr, /*Length=*/200);
1440 if (!lines_up)
1441 return nullptr;
1442
1443 auto first_line_up = lines_up->getNext();
1444 if (!first_line_up)
1445 return nullptr;
1446 auto compiland_up = GetPDBCompilandByUID(first_line_up->getCompilandId());
1447 if (compiland_up) {
1448 return ParseCompileUnitForUID(compiland_up->getSymIndexId());
1449 }
1450
1451 return nullptr;
1452}
1453
1454Mangled
Aaron Smithe664b5d2018-03-19 21:14:19 +00001455SymbolFilePDB::GetMangledForPDBFunc(const llvm::pdb::PDBSymbolFunc &pdb_func) {
Aaron Smith7ac1c782018-02-09 05:31:28 +00001456 Mangled mangled;
Aaron Smithe664b5d2018-03-19 21:14:19 +00001457 auto func_name = pdb_func.getName();
1458 auto func_undecorated_name = pdb_func.getUndecoratedName();
Aaron Smith7ac1c782018-02-09 05:31:28 +00001459 std::string func_decorated_name;
1460
1461 // Seek from public symbols for non-static function's decorated name if any.
1462 // For static functions, they don't have undecorated names and aren't exposed
1463 // in Public Symbols either.
1464 if (!func_undecorated_name.empty()) {
1465 auto result_up =
1466 m_global_scope_up->findChildren(PDB_SymType::PublicSymbol,
1467 func_undecorated_name,
1468 PDB_NameSearchFlags::NS_UndecoratedName);
1469 if (result_up) {
1470 while (auto symbol_up = result_up->getNext()) {
1471 // For a public symbol, it is unique.
1472 lldbassert(result_up->getChildCount() == 1);
1473 if (auto *pdb_public_sym =
Aaron Smithf76fe682018-03-07 03:16:50 +00001474 llvm::dyn_cast_or_null<PDBSymbolPublicSymbol>(symbol_up.get())) {
Aaron Smith7ac1c782018-02-09 05:31:28 +00001475 if (pdb_public_sym->isFunction()) {
1476 func_decorated_name = pdb_public_sym->getName();
Aaron Smithf76fe682018-03-07 03:16:50 +00001477 break;
Aaron Smith7ac1c782018-02-09 05:31:28 +00001478 }
1479 }
1480 }
1481 }
1482 }
1483 if (!func_decorated_name.empty()) {
1484 mangled.SetMangledName(ConstString(func_decorated_name));
1485
1486 // For MSVC, format of C funciton's decorated name depends on calling
1487 // conventon. Unfortunately none of the format is recognized by current
1488 // LLDB. For example, `_purecall` is a __cdecl C function. From PDB,
1489 // `__purecall` is retrieved as both its decorated and
1490 // undecorated name (using PDBSymbolFunc::getUndecoratedName method).
1491 // However `__purecall` string is not treated as mangled in LLDB
1492 // (neither `?` nor `_Z` prefix). Mangled::GetDemangledName method
1493 // will fail internally and caches an empty string as its undecorated
1494 // name. So we will face a contradition here for the same symbol:
1495 // non-empty undecorated name from PDB
1496 // empty undecorated name from LLDB
1497 if (!func_undecorated_name.empty() &&
1498 mangled.GetDemangledName(mangled.GuessLanguage()).IsEmpty())
1499 mangled.SetDemangledName(ConstString(func_undecorated_name));
1500
1501 // LLDB uses several flags to control how a C++ decorated name is
1502 // undecorated for MSVC. See `safeUndecorateName` in Class Mangled.
1503 // So the yielded name could be different from what we retrieve from
1504 // PDB source unless we also apply same flags in getting undecorated
1505 // name through PDBSymbolFunc::getUndecoratedNameEx method.
1506 if (!func_undecorated_name.empty() &&
1507 mangled.GetDemangledName(mangled.GuessLanguage()) !=
1508 ConstString(func_undecorated_name))
1509 mangled.SetDemangledName(ConstString(func_undecorated_name));
1510 } else if (!func_undecorated_name.empty()) {
1511 mangled.SetDemangledName(ConstString(func_undecorated_name));
1512 } else if (!func_name.empty())
1513 mangled.SetValue(ConstString(func_name), false);
1514
1515 return mangled;
1516}
1517
1518bool SymbolFilePDB::DeclContextMatchesThisSymbolFile(
1519 const lldb_private::CompilerDeclContext *decl_ctx) {
1520 if (decl_ctx == nullptr || !decl_ctx->IsValid())
1521 return true;
1522
1523 TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem();
1524 if (!decl_ctx_type_system)
1525 return false;
1526 TypeSystem *type_system = GetTypeSystemForLanguage(
1527 decl_ctx_type_system->GetMinimumLanguage(nullptr));
1528 if (decl_ctx_type_system == type_system)
1529 return true; // The type systems match, return true
1530
1531 return false;
1532}