blob: 2779aee341de4c4d0834ce36de983d37a386856b [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
Aleksandr Urakovc1e530e2018-11-06 08:02:55 +000012#include "PDBASTParser.h"
13#include "PDBLocationToDWARFExpression.h"
14
Zachary Turner42dff792016-04-15 00:21:26 +000015#include "clang/Lex/Lexer.h"
16
Zachary Turner74e08ca2016-03-02 22:05:52 +000017#include "lldb/Core/Module.h"
18#include "lldb/Core/PluginManager.h"
Zachary Turner42dff792016-04-15 00:21:26 +000019#include "lldb/Symbol/ClangASTContext.h"
Zachary Turner74e08ca2016-03-02 22:05:52 +000020#include "lldb/Symbol/CompileUnit.h"
21#include "lldb/Symbol/LineTable.h"
22#include "lldb/Symbol/ObjectFile.h"
23#include "lldb/Symbol/SymbolContext.h"
Aaron Smith10a02572018-01-13 06:58:18 +000024#include "lldb/Symbol/SymbolVendor.h"
Aaron Smithec40f812018-01-23 20:35:19 +000025#include "lldb/Symbol/TypeList.h"
Aaron Smith308e39c2018-03-22 19:26:33 +000026#include "lldb/Symbol/TypeMap.h"
Aaron Smithcab0d232018-05-23 01:52:42 +000027#include "lldb/Symbol/Variable.h"
Aaron Smith86e94342017-12-22 05:26:50 +000028#include "lldb/Utility/RegularExpression.h"
Zachary Turner74e08ca2016-03-02 22:05:52 +000029
Pavel Labathb8d8c622016-05-09 11:07:43 +000030#include "llvm/DebugInfo/PDB/GenericError.h"
Aaron Smith1f8552a2017-12-22 00:04:36 +000031#include "llvm/DebugInfo/PDB/IPDBDataStream.h"
Zachary Turner74e08ca2016-03-02 22:05:52 +000032#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
33#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
Aaron Smith308e39c2018-03-22 19:26:33 +000034#include "llvm/DebugInfo/PDB/IPDBSectionContrib.h"
Zachary Turner74e08ca2016-03-02 22:05:52 +000035#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
Aaron Smith1f8552a2017-12-22 00:04:36 +000036#include "llvm/DebugInfo/PDB/IPDBTable.h"
Zachary Turner74e08ca2016-03-02 22:05:52 +000037#include "llvm/DebugInfo/PDB/PDBSymbol.h"
Aaron Smith7ac1c782018-02-09 05:31:28 +000038#include "llvm/DebugInfo/PDB/PDBSymbolBlock.h"
Zachary Turner74e08ca2016-03-02 22:05:52 +000039#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
40#include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
Aaron Smith1f8552a2017-12-22 00:04:36 +000041#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
Zachary Turner74e08ca2016-03-02 22:05:52 +000042#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
43#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
44#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
45#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
Aaron Smith7ac1c782018-02-09 05:31:28 +000046#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
Zachary Turner42dff792016-04-15 00:21:26 +000047#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
48#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
49#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
50
Aleksandr Urakov7d2a74f2018-08-14 07:57:44 +000051#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" // For IsCPPMangledName
Aleksandr Urakovc1e530e2018-11-06 08:02:55 +000052#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
Zachary Turner307f5ae2018-10-12 19:47:13 +000053#include "Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h"
Zachary Turner42dff792016-04-15 00:21:26 +000054
55#include <regex>
Zachary Turner74e08ca2016-03-02 22:05:52 +000056
Aaron Smith10a02572018-01-13 06:58:18 +000057using namespace lldb;
Zachary Turner74e08ca2016-03-02 22:05:52 +000058using namespace lldb_private;
Zachary Turner54fd7ff2016-05-04 20:33:53 +000059using namespace llvm::pdb;
Zachary Turner74e08ca2016-03-02 22:05:52 +000060
Kate Stoneb9c1b512016-09-06 20:57:50 +000061namespace {
62lldb::LanguageType TranslateLanguage(PDB_Lang lang) {
63 switch (lang) {
64 case PDB_Lang::Cpp:
65 return lldb::LanguageType::eLanguageTypeC_plus_plus;
66 case PDB_Lang::C:
67 return lldb::LanguageType::eLanguageTypeC;
68 default:
69 return lldb::LanguageType::eLanguageTypeUnknown;
70 }
Zachary Turner74e08ca2016-03-02 22:05:52 +000071}
72
Kate Stoneb9c1b512016-09-06 20:57:50 +000073bool ShouldAddLine(uint32_t requested_line, uint32_t actual_line,
74 uint32_t addr_length) {
75 return ((requested_line == 0 || actual_line == requested_line) &&
76 addr_length > 0);
77}
Aaron Smithc8316ed2018-03-22 03:44:51 +000078} // namespace
Zachary Turner74e08ca2016-03-02 22:05:52 +000079
Zachary Turner307f5ae2018-10-12 19:47:13 +000080static bool ShouldUseNativeReader() {
81#if !defined(_WIN32)
82 return true;
83#endif
84 llvm::StringRef use_native = ::getenv("LLDB_USE_NATIVE_PDB_READER");
85 return use_native.equals_lower("on") || use_native.equals_lower("yes") ||
86 use_native.equals_lower("1") || use_native.equals_lower("true");
87}
88
Kate Stoneb9c1b512016-09-06 20:57:50 +000089void SymbolFilePDB::Initialize() {
Zachary Turner307f5ae2018-10-12 19:47:13 +000090 if (ShouldUseNativeReader()) {
91 npdb::SymbolFileNativePDB::Initialize();
92 } else {
93 PluginManager::RegisterPlugin(GetPluginNameStatic(),
94 GetPluginDescriptionStatic(), CreateInstance,
95 DebuggerInitialize);
96 }
Zachary Turner74e08ca2016-03-02 22:05:52 +000097}
98
Kate Stoneb9c1b512016-09-06 20:57:50 +000099void SymbolFilePDB::Terminate() {
Zachary Turner307f5ae2018-10-12 19:47:13 +0000100 if (ShouldUseNativeReader()) {
101 npdb::SymbolFileNativePDB::Terminate();
102 } else {
103 PluginManager::UnregisterPlugin(CreateInstance);
104 }
Zachary Turner74e08ca2016-03-02 22:05:52 +0000105}
106
Kate Stoneb9c1b512016-09-06 20:57:50 +0000107void SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger) {}
108
109lldb_private::ConstString SymbolFilePDB::GetPluginNameStatic() {
110 static ConstString g_name("pdb");
111 return g_name;
Zachary Turner74e08ca2016-03-02 22:05:52 +0000112}
113
Kate Stoneb9c1b512016-09-06 20:57:50 +0000114const char *SymbolFilePDB::GetPluginDescriptionStatic() {
115 return "Microsoft PDB debug symbol file reader.";
Zachary Turner74e08ca2016-03-02 22:05:52 +0000116}
117
118lldb_private::SymbolFile *
Kate Stoneb9c1b512016-09-06 20:57:50 +0000119SymbolFilePDB::CreateInstance(lldb_private::ObjectFile *obj_file) {
120 return new SymbolFilePDB(obj_file);
Zachary Turner74e08ca2016-03-02 22:05:52 +0000121}
122
123SymbolFilePDB::SymbolFilePDB(lldb_private::ObjectFile *object_file)
Aaron Smith10a02572018-01-13 06:58:18 +0000124 : SymbolFile(object_file), m_session_up(), m_global_scope_up(),
125 m_cached_compile_unit_count(0), m_tu_decl_ctx_up() {}
Zachary Turner74e08ca2016-03-02 22:05:52 +0000126
Kate Stoneb9c1b512016-09-06 20:57:50 +0000127SymbolFilePDB::~SymbolFilePDB() {}
Zachary Turner74e08ca2016-03-02 22:05:52 +0000128
Kate Stoneb9c1b512016-09-06 20:57:50 +0000129uint32_t SymbolFilePDB::CalculateAbilities() {
Aaron Smith1f8552a2017-12-22 00:04:36 +0000130 uint32_t abilities = 0;
131 if (!m_obj_file)
132 return 0;
133
Kate Stoneb9c1b512016-09-06 20:57:50 +0000134 if (!m_session_up) {
135 // Lazily load and match the PDB file, but only do this once.
136 std::string exePath = m_obj_file->GetFileSpec().GetPath();
137 auto error = loadDataForEXE(PDB_ReaderType::DIA, llvm::StringRef(exePath),
138 m_session_up);
139 if (error) {
140 llvm::consumeError(std::move(error));
Aaron Smith1f8552a2017-12-22 00:04:36 +0000141 auto module_sp = m_obj_file->GetModule();
142 if (!module_sp)
143 return 0;
144 // See if any symbol file is specified through `--symfile` option.
145 FileSpec symfile = module_sp->GetSymbolFileFileSpec();
146 if (!symfile)
147 return 0;
148 error = loadDataForPDB(PDB_ReaderType::DIA,
Aaron Smithc8316ed2018-03-22 03:44:51 +0000149 llvm::StringRef(symfile.GetPath()), m_session_up);
Aaron Smith1f8552a2017-12-22 00:04:36 +0000150 if (error) {
151 llvm::consumeError(std::move(error));
152 return 0;
153 }
Zachary Turner74e08ca2016-03-02 22:05:52 +0000154 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000155 }
Aaron Smithd5a925f2018-03-22 19:21:34 +0000156 if (!m_session_up)
Aaron Smith1f8552a2017-12-22 00:04:36 +0000157 return 0;
158
159 auto enum_tables_up = m_session_up->getEnumTables();
160 if (!enum_tables_up)
161 return 0;
162 while (auto table_up = enum_tables_up->getNext()) {
163 if (table_up->getItemCount() == 0)
164 continue;
165 auto type = table_up->getTableType();
166 switch (type) {
167 case PDB_TableType::Symbols:
168 // This table represents a store of symbols with types listed in
169 // PDBSym_Type
Aaron Smithc8316ed2018-03-22 03:44:51 +0000170 abilities |= (CompileUnits | Functions | Blocks | GlobalVariables |
171 LocalVariables | VariableTypes);
Aaron Smith1f8552a2017-12-22 00:04:36 +0000172 break;
173 case PDB_TableType::LineNumbers:
174 abilities |= LineTables;
175 break;
Aaron Smithc8316ed2018-03-22 03:44:51 +0000176 default:
177 break;
Aaron Smith1f8552a2017-12-22 00:04:36 +0000178 }
179 }
180 return abilities;
Zachary Turner74e08ca2016-03-02 22:05:52 +0000181}
182
Kate Stoneb9c1b512016-09-06 20:57:50 +0000183void SymbolFilePDB::InitializeObject() {
184 lldb::addr_t obj_load_address = m_obj_file->GetFileOffset();
Aaron Smithc8316ed2018-03-22 03:44:51 +0000185 lldbassert(obj_load_address && obj_load_address != LLDB_INVALID_ADDRESS);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000186 m_session_up->setLoadAddress(obj_load_address);
Aaron Smith10a02572018-01-13 06:58:18 +0000187 if (!m_global_scope_up)
188 m_global_scope_up = m_session_up->getGlobalScope();
189 lldbassert(m_global_scope_up.get());
Zachary Turner42dff792016-04-15 00:21:26 +0000190
Kate Stoneb9c1b512016-09-06 20:57:50 +0000191 TypeSystem *type_system =
192 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
193 ClangASTContext *clang_type_system =
194 llvm::dyn_cast_or_null<ClangASTContext>(type_system);
Aaron Smith10a02572018-01-13 06:58:18 +0000195 lldbassert(clang_type_system);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000196 m_tu_decl_ctx_up = llvm::make_unique<CompilerDeclContext>(
197 type_system, clang_type_system->GetTranslationUnitDecl());
Zachary Turner74e08ca2016-03-02 22:05:52 +0000198}
199
Kate Stoneb9c1b512016-09-06 20:57:50 +0000200uint32_t SymbolFilePDB::GetNumCompileUnits() {
201 if (m_cached_compile_unit_count == 0) {
Aaron Smith10a02572018-01-13 06:58:18 +0000202 auto compilands = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();
203 if (!compilands)
204 return 0;
205
206 // The linker could link *.dll (compiland language = LINK), or import
Adrian Prantl05097242018-04-30 16:49:04 +0000207 // *.dll. For example, a compiland with name `Import:KERNEL32.dll` could be
208 // found as a child of the global scope (PDB executable). Usually, such
209 // compilands contain `thunk` symbols in which we are not interested for
210 // now. However we still count them in the compiland list. If we perform
211 // any compiland related activity, like finding symbols through
212 // llvm::pdb::IPDBSession methods, such compilands will all be searched
213 // automatically no matter whether we include them or not.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000214 m_cached_compile_unit_count = compilands->getChildCount();
Zachary Turner74e08ca2016-03-02 22:05:52 +0000215
Kate Stoneb9c1b512016-09-06 20:57:50 +0000216 // The linker can inject an additional "dummy" compilation unit into the
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +0000217 // PDB. Ignore this special compile unit for our purposes, if it is there.
218 // It is always the last one.
Aaron Smith10a02572018-01-13 06:58:18 +0000219 auto last_compiland_up =
220 compilands->getChildAtIndex(m_cached_compile_unit_count - 1);
221 lldbassert(last_compiland_up.get());
222 std::string name = last_compiland_up->getName();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000223 if (name == "* Linker *")
224 --m_cached_compile_unit_count;
225 }
226 return m_cached_compile_unit_count;
227}
Zachary Turner74e08ca2016-03-02 22:05:52 +0000228
Aaron Smith10a02572018-01-13 06:58:18 +0000229void SymbolFilePDB::GetCompileUnitIndex(
Aaron Smithc8316ed2018-03-22 03:44:51 +0000230 const llvm::pdb::PDBSymbolCompiland &pdb_compiland, uint32_t &index) {
Aaron Smith10a02572018-01-13 06:58:18 +0000231 auto results_up = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();
232 if (!results_up)
233 return;
Aaron Smithe664b5d2018-03-19 21:14:19 +0000234 auto uid = pdb_compiland.getSymIndexId();
Raphael Isemannfbdf0b92018-01-22 06:56:09 +0000235 for (uint32_t cu_idx = 0; cu_idx < GetNumCompileUnits(); ++cu_idx) {
Aaron Smith10a02572018-01-13 06:58:18 +0000236 auto compiland_up = results_up->getChildAtIndex(cu_idx);
237 if (!compiland_up)
238 continue;
239 if (compiland_up->getSymIndexId() == uid) {
240 index = cu_idx;
241 return;
242 }
243 }
244 index = UINT32_MAX;
245 return;
246}
247
248std::unique_ptr<llvm::pdb::PDBSymbolCompiland>
249SymbolFilePDB::GetPDBCompilandByUID(uint32_t uid) {
250 return m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(uid);
251}
252
Kate Stoneb9c1b512016-09-06 20:57:50 +0000253lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index) {
Aaron Smith10a02572018-01-13 06:58:18 +0000254 if (index >= GetNumCompileUnits())
255 return CompUnitSP();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000256
Aaron Smith10a02572018-01-13 06:58:18 +0000257 // Assuming we always retrieve same compilands listed in same order through
258 // `PDBSymbolExe::findAllChildren` method, otherwise using `index` to get a
259 // compile unit makes no sense.
260 auto results = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();
261 if (!results)
262 return CompUnitSP();
263 auto compiland_up = results->getChildAtIndex(index);
264 if (!compiland_up)
265 return CompUnitSP();
266 return ParseCompileUnitForUID(compiland_up->getSymIndexId(), index);
Zachary Turner74e08ca2016-03-02 22:05:52 +0000267}
268
269lldb::LanguageType
Kate Stoneb9c1b512016-09-06 20:57:50 +0000270SymbolFilePDB::ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) {
271 // What fields should I expect to be filled out on the SymbolContext? Is it
272 // safe to assume that `sc.comp_unit` is valid?
273 if (!sc.comp_unit)
274 return lldb::eLanguageTypeUnknown;
Zachary Turner74e08ca2016-03-02 22:05:52 +0000275
Aaron Smith10a02572018-01-13 06:58:18 +0000276 auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID());
277 if (!compiland_up)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000278 return lldb::eLanguageTypeUnknown;
Aaron Smith10a02572018-01-13 06:58:18 +0000279 auto details = compiland_up->findOneChild<PDBSymbolCompilandDetails>();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000280 if (!details)
281 return lldb::eLanguageTypeUnknown;
282 return TranslateLanguage(details->getLanguage());
Zachary Turner74e08ca2016-03-02 22:05:52 +0000283}
284
Aaron Smithc8316ed2018-03-22 03:44:51 +0000285lldb_private::Function *SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(
286 const PDBSymbolFunc &pdb_func, const lldb_private::SymbolContext &sc) {
Aaron Smith7ac1c782018-02-09 05:31:28 +0000287 lldbassert(sc.comp_unit && sc.module_sp.get());
288
Aaron Smithe664b5d2018-03-19 21:14:19 +0000289 auto file_vm_addr = pdb_func.getVirtualAddress();
Aaron Smith308e39c2018-03-22 19:26:33 +0000290 if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)
Aaron Smith7ac1c782018-02-09 05:31:28 +0000291 return nullptr;
292
Aaron Smithe664b5d2018-03-19 21:14:19 +0000293 auto func_length = pdb_func.getLength();
Aaron Smithc8316ed2018-03-22 03:44:51 +0000294 AddressRange func_range =
295 AddressRange(file_vm_addr, func_length, sc.module_sp->GetSectionList());
Aaron Smith7ac1c782018-02-09 05:31:28 +0000296 if (!func_range.GetBaseAddress().IsValid())
297 return nullptr;
298
Aaron Smithc8316ed2018-03-22 03:44:51 +0000299 lldb_private::Type *func_type = ResolveTypeUID(pdb_func.getSymIndexId());
Aaron Smith7ac1c782018-02-09 05:31:28 +0000300 if (!func_type)
301 return nullptr;
302
Aaron Smithe664b5d2018-03-19 21:14:19 +0000303 user_id_t func_type_uid = pdb_func.getSignatureId();
Aaron Smithf76fe682018-03-07 03:16:50 +0000304
Aaron Smith7ac1c782018-02-09 05:31:28 +0000305 Mangled mangled = GetMangledForPDBFunc(pdb_func);
306
Aaron Smithc8316ed2018-03-22 03:44:51 +0000307 FunctionSP func_sp =
308 std::make_shared<Function>(sc.comp_unit, pdb_func.getSymIndexId(),
309 func_type_uid, mangled, func_type, func_range);
Aaron Smith7ac1c782018-02-09 05:31:28 +0000310
311 sc.comp_unit->AddFunction(func_sp);
312 return func_sp.get();
313}
314
Kate Stoneb9c1b512016-09-06 20:57:50 +0000315size_t SymbolFilePDB::ParseCompileUnitFunctions(
316 const lldb_private::SymbolContext &sc) {
Aaron Smith7ac1c782018-02-09 05:31:28 +0000317 lldbassert(sc.comp_unit);
318 size_t func_added = 0;
319 auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID());
320 if (!compiland_up)
321 return 0;
322 auto results_up = compiland_up->findAllChildren<PDBSymbolFunc>();
323 if (!results_up)
324 return 0;
325 while (auto pdb_func_up = results_up->getNext()) {
326 auto func_sp =
327 sc.comp_unit->FindFunctionByUID(pdb_func_up->getSymIndexId());
328 if (!func_sp) {
Aaron Smithe664b5d2018-03-19 21:14:19 +0000329 if (ParseCompileUnitFunctionForPDBFunc(*pdb_func_up, sc))
Aaron Smith7ac1c782018-02-09 05:31:28 +0000330 ++func_added;
331 }
332 }
333 return func_added;
Zachary Turner74e08ca2016-03-02 22:05:52 +0000334}
335
Kate Stoneb9c1b512016-09-06 20:57:50 +0000336bool SymbolFilePDB::ParseCompileUnitLineTable(
337 const lldb_private::SymbolContext &sc) {
Aaron Smith10a02572018-01-13 06:58:18 +0000338 lldbassert(sc.comp_unit);
339 if (sc.comp_unit->GetLineTable())
340 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000341 return ParseCompileUnitLineTable(sc, 0);
Zachary Turner74e08ca2016-03-02 22:05:52 +0000342}
343
Kate Stoneb9c1b512016-09-06 20:57:50 +0000344bool SymbolFilePDB::ParseCompileUnitDebugMacros(
345 const lldb_private::SymbolContext &sc) {
346 // PDB doesn't contain information about macros
347 return false;
348}
349
350bool SymbolFilePDB::ParseCompileUnitSupportFiles(
351 const lldb_private::SymbolContext &sc,
352 lldb_private::FileSpecList &support_files) {
Aaron Smith10a02572018-01-13 06:58:18 +0000353 lldbassert(sc.comp_unit);
Zachary Turner74e08ca2016-03-02 22:05:52 +0000354
Kate Stoneb9c1b512016-09-06 20:57:50 +0000355 // In theory this is unnecessary work for us, because all of this information
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +0000356 // is easily (and quickly) accessible from DebugInfoPDB, so caching it a
357 // second time seems like a waste. Unfortunately, there's no good way around
358 // this short of a moderate refactor since SymbolVendor depends on being able
359 // to cache this list.
Aaron Smith10a02572018-01-13 06:58:18 +0000360 auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID());
361 if (!compiland_up)
Zachary Turner74e08ca2016-03-02 22:05:52 +0000362 return false;
Aaron Smith10a02572018-01-13 06:58:18 +0000363 auto files = m_session_up->getSourceFilesForCompiland(*compiland_up);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000364 if (!files || files->getChildCount() == 0)
Zachary Turner74e08ca2016-03-02 22:05:52 +0000365 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000366
367 while (auto file = files->getNext()) {
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +0000368 FileSpec spec(file->getFileName(), FileSpec::Style::windows);
Aaron Smith10a02572018-01-13 06:58:18 +0000369 support_files.AppendIfUnique(spec);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000370 }
Pavel Labath9ea80d22018-06-28 10:03:42 +0000371
372 // LLDB uses the DWARF-like file numeration (one based),
373 // the zeroth file is the compile unit itself
374 support_files.Insert(0, *sc.comp_unit);
375
Kate Stoneb9c1b512016-09-06 20:57:50 +0000376 return true;
Zachary Turner74e08ca2016-03-02 22:05:52 +0000377}
378
Kate Stoneb9c1b512016-09-06 20:57:50 +0000379bool SymbolFilePDB::ParseImportedModules(
380 const lldb_private::SymbolContext &sc,
381 std::vector<lldb_private::ConstString> &imported_modules) {
382 // PDB does not yet support module debug info
383 return false;
Zachary Turner74e08ca2016-03-02 22:05:52 +0000384}
385
Aaron Smithc8316ed2018-03-22 03:44:51 +0000386static size_t ParseFunctionBlocksForPDBSymbol(
387 const lldb_private::SymbolContext &sc, uint64_t func_file_vm_addr,
388 const llvm::pdb::PDBSymbol *pdb_symbol, lldb_private::Block *parent_block,
389 bool is_top_parent) {
Aaron Smith7ac1c782018-02-09 05:31:28 +0000390 assert(pdb_symbol && parent_block);
391
392 size_t num_added = 0;
393 switch (pdb_symbol->getSymTag()) {
394 case PDB_SymType::Block:
395 case PDB_SymType::Function: {
396 Block *block = nullptr;
397 auto &raw_sym = pdb_symbol->getRawSymbol();
398 if (auto *pdb_func = llvm::dyn_cast<PDBSymbolFunc>(pdb_symbol)) {
399 if (pdb_func->hasNoInlineAttribute())
400 break;
401 if (is_top_parent)
402 block = parent_block;
403 else
404 break;
405 } else if (llvm::dyn_cast<PDBSymbolBlock>(pdb_symbol)) {
406 auto uid = pdb_symbol->getSymIndexId();
407 if (parent_block->FindBlockByID(uid))
408 break;
409 if (raw_sym.getVirtualAddress() < func_file_vm_addr)
410 break;
411
412 auto block_sp = std::make_shared<Block>(pdb_symbol->getSymIndexId());
413 parent_block->AddChild(block_sp);
414 block = block_sp.get();
415 } else
416 llvm_unreachable("Unexpected PDB symbol!");
417
Aaron Smithc8316ed2018-03-22 03:44:51 +0000418 block->AddRange(Block::Range(
419 raw_sym.getVirtualAddress() - func_file_vm_addr, raw_sym.getLength()));
Aaron Smith7ac1c782018-02-09 05:31:28 +0000420 block->FinalizeRanges();
421 ++num_added;
422
423 auto results_up = pdb_symbol->findAllChildren();
424 if (!results_up)
425 break;
426 while (auto symbol_up = results_up->getNext()) {
Aaron Smithc8316ed2018-03-22 03:44:51 +0000427 num_added += ParseFunctionBlocksForPDBSymbol(
428 sc, func_file_vm_addr, symbol_up.get(), block, false);
Aaron Smith7ac1c782018-02-09 05:31:28 +0000429 }
430 } break;
Aaron Smithc8316ed2018-03-22 03:44:51 +0000431 default:
432 break;
Aaron Smith7ac1c782018-02-09 05:31:28 +0000433 }
434 return num_added;
435}
436
Zachary Turner74e08ca2016-03-02 22:05:52 +0000437size_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000438SymbolFilePDB::ParseFunctionBlocks(const lldb_private::SymbolContext &sc) {
Aaron Smith7ac1c782018-02-09 05:31:28 +0000439 lldbassert(sc.comp_unit && sc.function);
440 size_t num_added = 0;
441 auto uid = sc.function->GetID();
442 auto pdb_func_up = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(uid);
443 if (!pdb_func_up)
444 return 0;
445 Block &parent_block = sc.function->GetBlock(false);
446 num_added =
447 ParseFunctionBlocksForPDBSymbol(sc, pdb_func_up->getVirtualAddress(),
448 pdb_func_up.get(), &parent_block, true);
449 return num_added;
Zachary Turner74e08ca2016-03-02 22:05:52 +0000450}
451
Kate Stoneb9c1b512016-09-06 20:57:50 +0000452size_t SymbolFilePDB::ParseTypes(const lldb_private::SymbolContext &sc) {
Aaron Smithec40f812018-01-23 20:35:19 +0000453 lldbassert(sc.module_sp.get());
Aaron Smith66b84072018-03-14 04:05:27 +0000454 if (!sc.comp_unit)
Aaron Smithec40f812018-01-23 20:35:19 +0000455 return 0;
Aaron Smith66b84072018-03-14 04:05:27 +0000456
457 size_t num_added = 0;
458 auto compiland = GetPDBCompilandByUID(sc.comp_unit->GetID());
459 if (!compiland)
460 return 0;
461
462 auto ParseTypesByTagFn = [&num_added, this](const PDBSymbol &raw_sym) {
463 std::unique_ptr<IPDBEnumSymbols> results;
Aaron Smithc8316ed2018-03-22 03:44:51 +0000464 PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef,
465 PDB_SymType::UDT};
Aaron Smith66b84072018-03-14 04:05:27 +0000466 for (auto tag : tags_to_search) {
467 results = raw_sym.findAllChildren(tag);
468 if (!results || results->getChildCount() == 0)
469 continue;
470 while (auto symbol = results->getNext()) {
471 switch (symbol->getSymTag()) {
472 case PDB_SymType::Enum:
473 case PDB_SymType::UDT:
474 case PDB_SymType::Typedef:
475 break;
476 default:
477 continue;
478 }
479
480 // This should cause the type to get cached and stored in the `m_types`
481 // lookup.
Aleksandr Urakov7d2a74f2018-08-14 07:57:44 +0000482 if (auto type = ResolveTypeUID(symbol->getSymIndexId())) {
483 // Resolve the type completely to avoid a completion
484 // (and so a list change, which causes an iterators invalidation)
485 // during a TypeList dumping
486 type->GetFullCompilerType();
487 ++num_added;
488 }
Aaron Smith66b84072018-03-14 04:05:27 +0000489 }
Aaron Smithec40f812018-01-23 20:35:19 +0000490 }
Aaron Smith66b84072018-03-14 04:05:27 +0000491 };
Aaron Smithec40f812018-01-23 20:35:19 +0000492
Aaron Smith66b84072018-03-14 04:05:27 +0000493 if (sc.function) {
Aaron Smithc8316ed2018-03-22 03:44:51 +0000494 auto pdb_func = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(
495 sc.function->GetID());
Aaron Smith66b84072018-03-14 04:05:27 +0000496 if (!pdb_func)
497 return 0;
498 ParseTypesByTagFn(*pdb_func);
499 } else {
500 ParseTypesByTagFn(*compiland);
Aaron Smithec40f812018-01-23 20:35:19 +0000501
Aaron Smith66b84072018-03-14 04:05:27 +0000502 // Also parse global types particularly coming from this compiland.
Adrian Prantl05097242018-04-30 16:49:04 +0000503 // Unfortunately, PDB has no compiland information for each global type. We
504 // have to parse them all. But ensure we only do this once.
Aaron Smith66b84072018-03-14 04:05:27 +0000505 static bool parse_all_global_types = false;
506 if (!parse_all_global_types) {
507 ParseTypesByTagFn(*m_global_scope_up);
508 parse_all_global_types = true;
509 }
Aaron Smithec40f812018-01-23 20:35:19 +0000510 }
511 return num_added;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000512}
513
514size_t
515SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) {
Aaron Smithcab0d232018-05-23 01:52:42 +0000516 if (!sc.comp_unit)
517 return 0;
518
519 size_t num_added = 0;
520 if (sc.function) {
521 auto pdb_func = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(
522 sc.function->GetID());
523 if (!pdb_func)
524 return 0;
525
526 num_added += ParseVariables(sc, *pdb_func);
527 sc.function->GetBlock(false).SetDidParseVariables(true, true);
528 } else if (sc.comp_unit) {
529 auto compiland = GetPDBCompilandByUID(sc.comp_unit->GetID());
530 if (!compiland)
531 return 0;
532
533 if (sc.comp_unit->GetVariableList(false))
534 return 0;
535
536 auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();
537 if (results && results->getChildCount()) {
538 while (auto result = results->getNext()) {
Aleksandr Urakov356aa4a2018-10-23 08:29:17 +0000539 auto cu_id = GetCompilandId(*result);
Aaron Smithcab0d232018-05-23 01:52:42 +0000540 // FIXME: We are not able to determine variable's compile unit.
541 if (cu_id == 0)
542 continue;
543
544 if (cu_id == sc.comp_unit->GetID())
545 num_added += ParseVariables(sc, *result);
546 }
547 }
548
549 // FIXME: A `file static` or `global constant` variable appears both in
550 // compiland's children and global scope's children with unexpectedly
551 // different symbol's Id making it ambiguous.
552
553 // FIXME: 'local constant', for example, const char var[] = "abc", declared
554 // in a function scope, can't be found in PDB.
555
556 // Parse variables in this compiland.
557 num_added += ParseVariables(sc, *compiland);
558 }
559
560 return num_added;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000561}
562
563lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
564 auto find_result = m_types.find(type_uid);
565 if (find_result != m_types.end())
566 return find_result->second.get();
567
568 TypeSystem *type_system =
569 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
570 ClangASTContext *clang_type_system =
571 llvm::dyn_cast_or_null<ClangASTContext>(type_system);
572 if (!clang_type_system)
Zachary Turner74e08ca2016-03-02 22:05:52 +0000573 return nullptr;
Aleksandr Urakov709426b2018-09-10 08:08:43 +0000574 PDBASTParser *pdb = clang_type_system->GetPDBParser();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000575 if (!pdb)
576 return nullptr;
577
578 auto pdb_type = m_session_up->getSymbolById(type_uid);
579 if (pdb_type == nullptr)
580 return nullptr;
581
582 lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type);
Aaron Smithd5a925f2018-03-22 19:21:34 +0000583 if (result) {
Aaron Smith86e94342017-12-22 05:26:50 +0000584 m_types.insert(std::make_pair(type_uid, result));
Aaron Smithec40f812018-01-23 20:35:19 +0000585 auto type_list = GetTypeList();
Aaron Smithf76fe682018-03-07 03:16:50 +0000586 if (type_list)
587 type_list->Insert(result);
Aaron Smithec40f812018-01-23 20:35:19 +0000588 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000589 return result.get();
Zachary Turner74e08ca2016-03-02 22:05:52 +0000590}
591
Adrian Prantleca07c52018-11-05 20:49:07 +0000592llvm::Optional<SymbolFile::ArrayInfo> SymbolFilePDB::GetDynamicArrayInfoForUID(
593 lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
594 return llvm::None;
595}
596
Kate Stoneb9c1b512016-09-06 20:57:50 +0000597bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) {
Aleksandr Urakov7d2a74f2018-08-14 07:57:44 +0000598 std::lock_guard<std::recursive_mutex> guard(
599 GetObjectFile()->GetModule()->GetMutex());
600
601 ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
602 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
603 if (!clang_ast_ctx)
604 return false;
605
Aleksandr Urakov709426b2018-09-10 08:08:43 +0000606 PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();
Aleksandr Urakov7d2a74f2018-08-14 07:57:44 +0000607 if (!pdb)
608 return false;
609
610 return pdb->CompleteTypeFromPDB(compiler_type);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000611}
612
613lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) {
Aleksandr Urakov709426b2018-09-10 08:08:43 +0000614 ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
615 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
616 if (!clang_ast_ctx)
617 return CompilerDecl();
618
619 PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();
620 if (!pdb)
621 return CompilerDecl();
622
623 auto symbol = m_session_up->getSymbolById(uid);
624 if (!symbol)
625 return CompilerDecl();
626
627 auto decl = pdb->GetDeclForSymbol(*symbol);
628 if (!decl)
629 return CompilerDecl();
630
631 return CompilerDecl(clang_ast_ctx, decl);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000632}
633
634lldb_private::CompilerDeclContext
635SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) {
Aleksandr Urakov709426b2018-09-10 08:08:43 +0000636 ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
637 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
638 if (!clang_ast_ctx)
639 return CompilerDeclContext();
640
641 PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();
642 if (!pdb)
643 return CompilerDeclContext();
644
645 auto symbol = m_session_up->getSymbolById(uid);
646 if (!symbol)
647 return CompilerDeclContext();
648
649 auto decl_context = pdb->GetDeclContextForSymbol(*symbol);
650 if (!decl_context)
651 return GetDeclContextContainingUID(uid);
652
653 return CompilerDeclContext(clang_ast_ctx, decl_context);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000654}
655
656lldb_private::CompilerDeclContext
657SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
Aleksandr Urakov709426b2018-09-10 08:08:43 +0000658 ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
659 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
660 if (!clang_ast_ctx)
661 return CompilerDeclContext();
662
663 PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();
664 if (!pdb)
665 return CompilerDeclContext();
666
667 auto symbol = m_session_up->getSymbolById(uid);
668 if (!symbol)
669 return CompilerDeclContext();
670
671 auto decl_context = pdb->GetDeclContextContainingSymbol(*symbol);
672 assert(decl_context);
673
674 return CompilerDeclContext(clang_ast_ctx, decl_context);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000675}
676
677void SymbolFilePDB::ParseDeclsForContext(
Aleksandr Urakov709426b2018-09-10 08:08:43 +0000678 lldb_private::CompilerDeclContext decl_ctx) {
679 ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
680 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
681 if (!clang_ast_ctx)
682 return;
683
684 PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();
685 if (!pdb)
686 return;
687
688 pdb->ParseDeclsForDeclContext(
689 static_cast<clang::DeclContext *>(decl_ctx.GetOpaqueDeclContext()));
690}
Kate Stoneb9c1b512016-09-06 20:57:50 +0000691
692uint32_t
693SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,
Zachary Turner991e4452018-10-25 20:45:19 +0000694 SymbolContextItem resolve_scope,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000695 lldb_private::SymbolContext &sc) {
Aaron Smith7ac1c782018-02-09 05:31:28 +0000696 uint32_t resolved_flags = 0;
Pavel Labath4d4d63e2018-02-09 11:37:01 +0000697 if (resolve_scope & eSymbolContextCompUnit ||
698 resolve_scope & eSymbolContextVariable ||
699 resolve_scope & eSymbolContextFunction ||
700 resolve_scope & eSymbolContextBlock ||
Aaron Smith7ac1c782018-02-09 05:31:28 +0000701 resolve_scope & eSymbolContextLineEntry) {
Aaron Smith7ac1c782018-02-09 05:31:28 +0000702 auto cu_sp = GetCompileUnitContainsAddress(so_addr);
703 if (!cu_sp) {
704 if (resolved_flags | eSymbolContextVariable) {
705 // TODO: Resolve variables
706 }
707 return 0;
708 }
709 sc.comp_unit = cu_sp.get();
710 resolved_flags |= eSymbolContextCompUnit;
711 lldbassert(sc.module_sp == cu_sp->GetModule());
Pavel Labath9ea80d22018-06-28 10:03:42 +0000712 }
Aaron Smith7ac1c782018-02-09 05:31:28 +0000713
Aleksandr Urakov398f81b2018-08-29 07:26:11 +0000714 if (resolve_scope & eSymbolContextFunction ||
715 resolve_scope & eSymbolContextBlock) {
Pavel Labath9ea80d22018-06-28 10:03:42 +0000716 addr_t file_vm_addr = so_addr.GetFileAddress();
717 auto symbol_up =
718 m_session_up->findSymbolByAddress(file_vm_addr, PDB_SymType::Function);
719 if (symbol_up) {
720 auto *pdb_func = llvm::dyn_cast<PDBSymbolFunc>(symbol_up.get());
721 assert(pdb_func);
722 auto func_uid = pdb_func->getSymIndexId();
723 sc.function = sc.comp_unit->FindFunctionByUID(func_uid).get();
724 if (sc.function == nullptr)
725 sc.function = ParseCompileUnitFunctionForPDBFunc(*pdb_func, sc);
726 if (sc.function) {
727 resolved_flags |= eSymbolContextFunction;
728 if (resolve_scope & eSymbolContextBlock) {
Aleksandr Urakov398f81b2018-08-29 07:26:11 +0000729 auto block_symbol = m_session_up->findSymbolByAddress(
730 file_vm_addr, PDB_SymType::Block);
731 auto block_id = block_symbol ? block_symbol->getSymIndexId()
732 : sc.function->GetID();
733 sc.block = sc.function->GetBlock(true).FindBlockByID(block_id);
Pavel Labath9ea80d22018-06-28 10:03:42 +0000734 if (sc.block)
735 resolved_flags |= eSymbolContextBlock;
Aaron Smith7ac1c782018-02-09 05:31:28 +0000736 }
737 }
Aaron Smith7ac1c782018-02-09 05:31:28 +0000738 }
739 }
Pavel Labath9ea80d22018-06-28 10:03:42 +0000740
741 if (resolve_scope & eSymbolContextLineEntry) {
742 if (auto *line_table = sc.comp_unit->GetLineTable()) {
743 Address addr(so_addr);
744 if (line_table->FindLineEntryByAddress(addr, sc.line_entry))
745 resolved_flags |= eSymbolContextLineEntry;
746 }
747 }
748
Aaron Smith7ac1c782018-02-09 05:31:28 +0000749 return resolved_flags;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000750}
751
752uint32_t SymbolFilePDB::ResolveSymbolContext(
753 const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines,
Zachary Turner991e4452018-10-25 20:45:19 +0000754 SymbolContextItem resolve_scope, lldb_private::SymbolContextList &sc_list) {
Aaron Smith10a02572018-01-13 06:58:18 +0000755 const size_t old_size = sc_list.GetSize();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000756 if (resolve_scope & lldb::eSymbolContextCompUnit) {
757 // Locate all compilation units with line numbers referencing the specified
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +0000758 // file. For example, if `file_spec` is <vector>, then this should return
759 // all source files and header files that reference <vector>, either
760 // directly or indirectly.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000761 auto compilands = m_session_up->findCompilandsForSourceFile(
762 file_spec.GetPath(), PDB_NameSearchFlags::NS_CaseInsensitive);
763
Aaron Smith10a02572018-01-13 06:58:18 +0000764 if (!compilands)
765 return 0;
766
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +0000767 // For each one, either find its previously parsed data or parse it afresh
768 // and add it to the symbol context list.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000769 while (auto compiland = compilands->getNext()) {
Adrian Prantl05097242018-04-30 16:49:04 +0000770 // If we're not checking inlines, then don't add line information for
771 // this file unless the FileSpec matches. For inline functions, we don't
772 // have to match the FileSpec since they could be defined in headers
773 // other than file specified in FileSpec.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000774 if (!check_inlines) {
Aaron Smith487b0c62018-03-20 00:18:22 +0000775 std::string source_file = compiland->getSourceFileFullPath();
Aaron Smith10a02572018-01-13 06:58:18 +0000776 if (source_file.empty())
777 continue;
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +0000778 FileSpec this_spec(source_file, FileSpec::Style::windows);
Aaron Smith10a02572018-01-13 06:58:18 +0000779 bool need_full_match = !file_spec.GetDirectory().IsEmpty();
780 if (FileSpec::Compare(file_spec, this_spec, need_full_match) != 0)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000781 continue;
782 }
783
784 SymbolContext sc;
Aaron Smith10a02572018-01-13 06:58:18 +0000785 auto cu = ParseCompileUnitForUID(compiland->getSymIndexId());
Aaron Smithd5a925f2018-03-22 19:21:34 +0000786 if (!cu)
Aaron Smith10a02572018-01-13 06:58:18 +0000787 continue;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000788 sc.comp_unit = cu.get();
789 sc.module_sp = cu->GetModule();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000790
791 // If we were asked to resolve line entries, add all entries to the line
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +0000792 // table that match the requested line (or all lines if `line` == 0).
Aaron Smith7ac1c782018-02-09 05:31:28 +0000793 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock |
794 eSymbolContextLineEntry)) {
795 bool has_line_table = ParseCompileUnitLineTable(sc, line);
796
797 if ((resolve_scope & eSymbolContextLineEntry) && !has_line_table) {
798 // The query asks for line entries, but we can't get them for the
Adrian Prantl05097242018-04-30 16:49:04 +0000799 // compile unit. This is not normal for `line` = 0. So just assert
800 // it.
Aaron Smithf76fe682018-03-07 03:16:50 +0000801 assert(line && "Couldn't get all line entries!\n");
Aaron Smith7ac1c782018-02-09 05:31:28 +0000802
803 // Current compiland does not have the requested line. Search next.
804 continue;
805 }
806
807 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) {
808 if (!has_line_table)
809 continue;
810
811 auto *line_table = sc.comp_unit->GetLineTable();
812 lldbassert(line_table);
813
814 uint32_t num_line_entries = line_table->GetSize();
815 // Skip the terminal line entry.
816 --num_line_entries;
817
Adrian Prantl05097242018-04-30 16:49:04 +0000818 // If `line `!= 0, see if we can resolve function for each line entry
819 // in the line table.
Aaron Smith7ac1c782018-02-09 05:31:28 +0000820 for (uint32_t line_idx = 0; line && line_idx < num_line_entries;
821 ++line_idx) {
822 if (!line_table->GetLineEntryAtIndex(line_idx, sc.line_entry))
823 continue;
824
825 auto file_vm_addr =
826 sc.line_entry.range.GetBaseAddress().GetFileAddress();
Aaron Smith308e39c2018-03-22 19:26:33 +0000827 if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)
Aaron Smith7ac1c782018-02-09 05:31:28 +0000828 continue;
829
Aaron Smithc8316ed2018-03-22 03:44:51 +0000830 auto symbol_up = m_session_up->findSymbolByAddress(
831 file_vm_addr, PDB_SymType::Function);
Aaron Smith7ac1c782018-02-09 05:31:28 +0000832 if (symbol_up) {
833 auto func_uid = symbol_up->getSymIndexId();
834 sc.function = sc.comp_unit->FindFunctionByUID(func_uid).get();
835 if (sc.function == nullptr) {
836 auto pdb_func = llvm::dyn_cast<PDBSymbolFunc>(symbol_up.get());
837 assert(pdb_func);
Aaron Smithe664b5d2018-03-19 21:14:19 +0000838 sc.function = ParseCompileUnitFunctionForPDBFunc(*pdb_func, sc);
Aaron Smith7ac1c782018-02-09 05:31:28 +0000839 }
840 if (sc.function && (resolve_scope & eSymbolContextBlock)) {
841 Block &block = sc.function->GetBlock(true);
842 sc.block = block.FindBlockByID(sc.function->GetID());
843 }
844 }
845 sc_list.Append(sc);
846 }
847 } else if (has_line_table) {
848 // We can parse line table for the compile unit. But no query to
849 // resolve function or block. We append `sc` to the list anyway.
850 sc_list.Append(sc);
851 }
852 } else {
853 // No query for line entry, function or block. But we have a valid
854 // compile unit, append `sc` to the list.
855 sc_list.Append(sc);
856 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000857 }
858 }
Aaron Smith10a02572018-01-13 06:58:18 +0000859 return sc_list.GetSize() - old_size;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000860}
861
Aaron Smithcab0d232018-05-23 01:52:42 +0000862std::string SymbolFilePDB::GetMangledForPDBData(const PDBSymbolData &pdb_data) {
Aleksandr Urakov356aa4a2018-10-23 08:29:17 +0000863 // Cache public names at first
864 if (m_public_names.empty())
865 if (auto result_up =
866 m_global_scope_up->findAllChildren(PDB_SymType::PublicSymbol))
867 while (auto symbol_up = result_up->getNext())
868 if (auto addr = symbol_up->getRawSymbol().getVirtualAddress())
869 m_public_names[addr] = symbol_up->getRawSymbol().getName();
Aaron Smithcab0d232018-05-23 01:52:42 +0000870
Aleksandr Urakov356aa4a2018-10-23 08:29:17 +0000871 // Look up the name in the cache
872 return m_public_names.lookup(pdb_data.getVirtualAddress());
Aaron Smithcab0d232018-05-23 01:52:42 +0000873}
874
875VariableSP SymbolFilePDB::ParseVariableForPDBData(
876 const lldb_private::SymbolContext &sc,
877 const llvm::pdb::PDBSymbolData &pdb_data) {
878 VariableSP var_sp;
879 uint32_t var_uid = pdb_data.getSymIndexId();
880 auto result = m_variables.find(var_uid);
881 if (result != m_variables.end())
882 return result->second;
883
884 ValueType scope = eValueTypeInvalid;
885 bool is_static_member = false;
886 bool is_external = false;
887 bool is_artificial = false;
888
889 switch (pdb_data.getDataKind()) {
890 case PDB_DataKind::Global:
891 scope = eValueTypeVariableGlobal;
892 is_external = true;
893 break;
894 case PDB_DataKind::Local:
895 scope = eValueTypeVariableLocal;
896 break;
897 case PDB_DataKind::FileStatic:
898 scope = eValueTypeVariableStatic;
899 break;
900 case PDB_DataKind::StaticMember:
901 is_static_member = true;
902 scope = eValueTypeVariableStatic;
903 break;
904 case PDB_DataKind::Member:
905 scope = eValueTypeVariableStatic;
906 break;
907 case PDB_DataKind::Param:
908 scope = eValueTypeVariableArgument;
909 break;
910 case PDB_DataKind::Constant:
911 scope = eValueTypeConstResult;
912 break;
913 default:
914 break;
915 }
916
917 switch (pdb_data.getLocationType()) {
918 case PDB_LocType::TLS:
919 scope = eValueTypeVariableThreadLocal;
920 break;
921 case PDB_LocType::RegRel: {
922 // It is a `this` pointer.
923 if (pdb_data.getDataKind() == PDB_DataKind::ObjectPtr) {
924 scope = eValueTypeVariableArgument;
925 is_artificial = true;
926 }
927 } break;
928 default:
929 break;
930 }
931
932 Declaration decl;
933 if (!is_artificial && !pdb_data.isCompilerGenerated()) {
934 if (auto lines = pdb_data.getLineNumbers()) {
935 if (auto first_line = lines->getNext()) {
936 uint32_t src_file_id = first_line->getSourceFileId();
937 auto src_file = m_session_up->getSourceFileById(src_file_id);
938 if (src_file) {
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +0000939 FileSpec spec(src_file->getFileName());
Aaron Smithcab0d232018-05-23 01:52:42 +0000940 decl.SetFile(spec);
941 decl.SetColumn(first_line->getColumnNumber());
942 decl.SetLine(first_line->getLineNumber());
943 }
944 }
945 }
946 }
947
948 Variable::RangeList ranges;
949 SymbolContextScope *context_scope = sc.comp_unit;
950 if (scope == eValueTypeVariableLocal) {
951 if (sc.function) {
952 context_scope = sc.function->GetBlock(true).FindBlockByID(
Aleksandr Urakov709426b2018-09-10 08:08:43 +0000953 pdb_data.getLexicalParentId());
Aaron Smithcab0d232018-05-23 01:52:42 +0000954 if (context_scope == nullptr)
955 context_scope = sc.function;
956 }
957 }
958
959 SymbolFileTypeSP type_sp =
960 std::make_shared<SymbolFileType>(*this, pdb_data.getTypeId());
961
962 auto var_name = pdb_data.getName();
963 auto mangled = GetMangledForPDBData(pdb_data);
964 auto mangled_cstr = mangled.empty() ? nullptr : mangled.c_str();
965
Jonas Devlieghere924d5602018-07-13 10:29:27 +0000966 bool is_constant;
967 DWARFExpression location = ConvertPDBLocationToDWARFExpression(
968 GetObjectFile()->GetModule(), pdb_data, is_constant);
Aaron Smithcab0d232018-05-23 01:52:42 +0000969
970 var_sp = std::make_shared<Variable>(
971 var_uid, var_name.c_str(), mangled_cstr, type_sp, scope, context_scope,
972 ranges, &decl, location, is_external, is_artificial, is_static_member);
Jonas Devlieghere924d5602018-07-13 10:29:27 +0000973 var_sp->SetLocationIsConstantValueData(is_constant);
Aaron Smithcab0d232018-05-23 01:52:42 +0000974
975 m_variables.insert(std::make_pair(var_uid, var_sp));
976 return var_sp;
977}
978
979size_t
980SymbolFilePDB::ParseVariables(const lldb_private::SymbolContext &sc,
981 const llvm::pdb::PDBSymbol &pdb_symbol,
982 lldb_private::VariableList *variable_list) {
983 size_t num_added = 0;
984
985 if (auto pdb_data = llvm::dyn_cast<PDBSymbolData>(&pdb_symbol)) {
986 VariableListSP local_variable_list_sp;
987
988 auto result = m_variables.find(pdb_data->getSymIndexId());
989 if (result != m_variables.end()) {
990 if (variable_list)
991 variable_list->AddVariableIfUnique(result->second);
992 } else {
993 // Prepare right VariableList for this variable.
994 if (auto lexical_parent = pdb_data->getLexicalParent()) {
995 switch (lexical_parent->getSymTag()) {
996 case PDB_SymType::Exe:
997 assert(sc.comp_unit);
998 LLVM_FALLTHROUGH;
999 case PDB_SymType::Compiland: {
1000 if (sc.comp_unit) {
1001 local_variable_list_sp = sc.comp_unit->GetVariableList(false);
1002 if (!local_variable_list_sp) {
1003 local_variable_list_sp = std::make_shared<VariableList>();
1004 sc.comp_unit->SetVariableList(local_variable_list_sp);
1005 }
1006 }
1007 } break;
1008 case PDB_SymType::Block:
1009 case PDB_SymType::Function: {
1010 if (sc.function) {
1011 Block *block = sc.function->GetBlock(true).FindBlockByID(
1012 lexical_parent->getSymIndexId());
1013 if (block) {
1014 local_variable_list_sp = block->GetBlockVariableList(false);
1015 if (!local_variable_list_sp) {
1016 local_variable_list_sp = std::make_shared<VariableList>();
1017 block->SetVariableList(local_variable_list_sp);
1018 }
1019 }
1020 }
1021 } break;
1022 default:
1023 break;
1024 }
1025 }
1026
1027 if (local_variable_list_sp) {
1028 if (auto var_sp = ParseVariableForPDBData(sc, *pdb_data)) {
1029 local_variable_list_sp->AddVariableIfUnique(var_sp);
1030 if (variable_list)
1031 variable_list->AddVariableIfUnique(var_sp);
1032 ++num_added;
1033 }
1034 }
1035 }
1036 }
1037
1038 if (auto results = pdb_symbol.findAllChildren()) {
1039 while (auto result = results->getNext())
1040 num_added += ParseVariables(sc, *result, variable_list);
1041 }
1042
1043 return num_added;
1044}
1045
Kate Stoneb9c1b512016-09-06 20:57:50 +00001046uint32_t SymbolFilePDB::FindGlobalVariables(
1047 const lldb_private::ConstString &name,
Pavel Labath34cda142018-05-31 09:46:26 +00001048 const lldb_private::CompilerDeclContext *parent_decl_ctx,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001049 uint32_t max_matches, lldb_private::VariableList &variables) {
Aleksandr Urakov709426b2018-09-10 08:08:43 +00001050 if (!parent_decl_ctx)
1051 parent_decl_ctx = m_tu_decl_ctx_up.get();
Aaron Smithcab0d232018-05-23 01:52:42 +00001052 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
1053 return 0;
1054 if (name.IsEmpty())
1055 return 0;
1056
Aleksandr Urakov709426b2018-09-10 08:08:43 +00001057 auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();
Aaron Smithcab0d232018-05-23 01:52:42 +00001058 if (!results)
1059 return 0;
1060
1061 uint32_t matches = 0;
1062 size_t old_size = variables.GetSize();
1063 while (auto result = results->getNext()) {
1064 auto pdb_data = llvm::dyn_cast<PDBSymbolData>(result.get());
1065 if (max_matches > 0 && matches >= max_matches)
1066 break;
1067
1068 SymbolContext sc;
1069 sc.module_sp = m_obj_file->GetModule();
1070 lldbassert(sc.module_sp.get());
1071
Aleksandr Urakov709426b2018-09-10 08:08:43 +00001072 if (!name.GetStringRef().equals(
Aleksandr Urakovc1e530e2018-11-06 08:02:55 +00001073 MSVCUndecoratedNameParser::DropScope(pdb_data->getName())))
Aleksandr Urakov709426b2018-09-10 08:08:43 +00001074 continue;
1075
Aleksandr Urakov356aa4a2018-10-23 08:29:17 +00001076 sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get();
1077 // FIXME: We are not able to determine the compile unit.
1078 if (sc.comp_unit == nullptr)
1079 continue;
1080
Aleksandr Urakov709426b2018-09-10 08:08:43 +00001081 auto actual_parent_decl_ctx =
1082 GetDeclContextContainingUID(result->getSymIndexId());
1083 if (actual_parent_decl_ctx != *parent_decl_ctx)
1084 continue;
1085
Aaron Smithcab0d232018-05-23 01:52:42 +00001086 ParseVariables(sc, *pdb_data, &variables);
1087 matches = variables.GetSize() - old_size;
1088 }
1089
1090 return matches;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001091}
1092
1093uint32_t
1094SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression &regex,
Pavel Labath34cda142018-05-31 09:46:26 +00001095 uint32_t max_matches,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001096 lldb_private::VariableList &variables) {
Aaron Smithcab0d232018-05-23 01:52:42 +00001097 if (!regex.IsValid())
1098 return 0;
1099 auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();
1100 if (!results)
1101 return 0;
1102
1103 uint32_t matches = 0;
1104 size_t old_size = variables.GetSize();
1105 while (auto pdb_data = results->getNext()) {
1106 if (max_matches > 0 && matches >= max_matches)
1107 break;
1108
1109 auto var_name = pdb_data->getName();
1110 if (var_name.empty())
1111 continue;
1112 if (!regex.Execute(var_name))
1113 continue;
1114 SymbolContext sc;
1115 sc.module_sp = m_obj_file->GetModule();
1116 lldbassert(sc.module_sp.get());
1117
Aleksandr Urakov356aa4a2018-10-23 08:29:17 +00001118 sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get();
Aaron Smithcab0d232018-05-23 01:52:42 +00001119 // FIXME: We are not able to determine the compile unit.
1120 if (sc.comp_unit == nullptr)
1121 continue;
1122
1123 ParseVariables(sc, *pdb_data, &variables);
1124 matches = variables.GetSize() - old_size;
1125 }
1126
1127 return matches;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001128}
1129
Aaron Smithe664b5d2018-03-19 21:14:19 +00001130bool SymbolFilePDB::ResolveFunction(const llvm::pdb::PDBSymbolFunc &pdb_func,
Aaron Smith7ac1c782018-02-09 05:31:28 +00001131 bool include_inlines,
1132 lldb_private::SymbolContextList &sc_list) {
Aaron Smith7ac1c782018-02-09 05:31:28 +00001133 lldb_private::SymbolContext sc;
Aaron Smitha3a8cc82018-03-20 00:34:18 +00001134 sc.comp_unit = ParseCompileUnitForUID(pdb_func.getCompilandId()).get();
Aaron Smith7ac1c782018-02-09 05:31:28 +00001135 if (!sc.comp_unit)
1136 return false;
1137 sc.module_sp = sc.comp_unit->GetModule();
Aaron Smitha3a8cc82018-03-20 00:34:18 +00001138 sc.function = ParseCompileUnitFunctionForPDBFunc(pdb_func, sc);
Aaron Smith7ac1c782018-02-09 05:31:28 +00001139 if (!sc.function)
1140 return false;
1141
1142 sc_list.Append(sc);
1143 return true;
1144}
1145
1146bool SymbolFilePDB::ResolveFunction(uint32_t uid, bool include_inlines,
1147 lldb_private::SymbolContextList &sc_list) {
Aaron Smithc8316ed2018-03-22 03:44:51 +00001148 auto pdb_func_up = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(uid);
Aaron Smith7ac1c782018-02-09 05:31:28 +00001149 if (!pdb_func_up && !(include_inlines && pdb_func_up->hasInlineAttribute()))
1150 return false;
Aaron Smithe664b5d2018-03-19 21:14:19 +00001151 return ResolveFunction(*pdb_func_up, include_inlines, sc_list);
Aaron Smith7ac1c782018-02-09 05:31:28 +00001152}
1153
1154void SymbolFilePDB::CacheFunctionNames() {
1155 if (!m_func_full_names.IsEmpty())
1156 return;
1157
1158 std::map<uint64_t, uint32_t> addr_ids;
1159
1160 if (auto results_up = m_global_scope_up->findAllChildren<PDBSymbolFunc>()) {
1161 while (auto pdb_func_up = results_up->getNext()) {
Aaron Smithf76fe682018-03-07 03:16:50 +00001162 if (pdb_func_up->isCompilerGenerated())
1163 continue;
1164
Aaron Smith7ac1c782018-02-09 05:31:28 +00001165 auto name = pdb_func_up->getName();
1166 auto demangled_name = pdb_func_up->getUndecoratedName();
1167 if (name.empty() && demangled_name.empty())
1168 continue;
Aaron Smith7ac1c782018-02-09 05:31:28 +00001169
Aaron Smithf76fe682018-03-07 03:16:50 +00001170 auto uid = pdb_func_up->getSymIndexId();
Aaron Smith7ac1c782018-02-09 05:31:28 +00001171 if (!demangled_name.empty() && pdb_func_up->getVirtualAddress())
1172 addr_ids.insert(std::make_pair(pdb_func_up->getVirtualAddress(), uid));
1173
1174 if (auto parent = pdb_func_up->getClassParent()) {
1175
1176 // PDB have symbols for class/struct methods or static methods in Enum
1177 // Class. We won't bother to check if the parent is UDT or Enum here.
1178 m_func_method_names.Append(ConstString(name), uid);
1179
Adrian Prantl05097242018-04-30 16:49:04 +00001180 // To search a method name, like NS::Class:MemberFunc, LLDB searches
1181 // its base name, i.e. MemberFunc by default. Since PDBSymbolFunc does
1182 // not have inforamtion of this, we extract base names and cache them
1183 // by our own effort.
Aleksandr Urakovc1e530e2018-11-06 08:02:55 +00001184 llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name);
Aaron Smith7ac1c782018-02-09 05:31:28 +00001185 if (!basename.empty())
1186 m_func_base_names.Append(ConstString(basename), uid);
1187 else {
1188 m_func_base_names.Append(ConstString(name), uid);
1189 }
1190
1191 if (!demangled_name.empty())
1192 m_func_full_names.Append(ConstString(demangled_name), uid);
1193
1194 } else {
1195 // Handle not-method symbols.
1196
Aleksandr Urakovc1e530e2018-11-06 08:02:55 +00001197 // The function name might contain namespace, or its lexical scope.
1198 llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name);
1199 if (!basename.empty())
1200 m_func_base_names.Append(ConstString(basename), uid);
1201 else
1202 m_func_base_names.Append(ConstString(name), uid);
Aaron Smith7ac1c782018-02-09 05:31:28 +00001203
1204 if (name == "main") {
1205 m_func_full_names.Append(ConstString(name), uid);
1206
1207 if (!demangled_name.empty() && name != demangled_name) {
1208 m_func_full_names.Append(ConstString(demangled_name), uid);
1209 m_func_base_names.Append(ConstString(demangled_name), uid);
1210 }
1211 } else if (!demangled_name.empty()) {
1212 m_func_full_names.Append(ConstString(demangled_name), uid);
1213 } else {
1214 m_func_full_names.Append(ConstString(name), uid);
1215 }
1216 }
1217 }
1218 }
1219
1220 if (auto results_up =
Aaron Smithc8316ed2018-03-22 03:44:51 +00001221 m_global_scope_up->findAllChildren<PDBSymbolPublicSymbol>()) {
Aaron Smith7ac1c782018-02-09 05:31:28 +00001222 while (auto pub_sym_up = results_up->getNext()) {
1223 if (!pub_sym_up->isFunction())
1224 continue;
1225 auto name = pub_sym_up->getName();
1226 if (name.empty())
1227 continue;
1228
1229 if (CPlusPlusLanguage::IsCPPMangledName(name.c_str())) {
Aaron Smith7ac1c782018-02-09 05:31:28 +00001230 auto vm_addr = pub_sym_up->getVirtualAddress();
1231
1232 // PDB public symbol has mangled name for its associated function.
1233 if (vm_addr && addr_ids.find(vm_addr) != addr_ids.end()) {
1234 // Cache mangled name.
1235 m_func_full_names.Append(ConstString(name), addr_ids[vm_addr]);
1236 }
1237 }
1238 }
1239 }
1240 // Sort them before value searching is working properly
1241 m_func_full_names.Sort();
1242 m_func_full_names.SizeToFit();
1243 m_func_method_names.Sort();
1244 m_func_method_names.SizeToFit();
1245 m_func_base_names.Sort();
1246 m_func_base_names.SizeToFit();
1247}
1248
Kate Stoneb9c1b512016-09-06 20:57:50 +00001249uint32_t SymbolFilePDB::FindFunctions(
1250 const lldb_private::ConstString &name,
1251 const lldb_private::CompilerDeclContext *parent_decl_ctx,
Zachary Turner117b1fa2018-10-25 20:45:40 +00001252 FunctionNameType name_type_mask, bool include_inlines, bool append,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001253 lldb_private::SymbolContextList &sc_list) {
Aaron Smith7ac1c782018-02-09 05:31:28 +00001254 if (!append)
1255 sc_list.Clear();
1256 lldbassert((name_type_mask & eFunctionNameTypeAuto) == 0);
1257
1258 if (name_type_mask == eFunctionNameTypeNone)
1259 return 0;
1260 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
1261 return 0;
1262 if (name.IsEmpty())
1263 return 0;
1264
1265 auto old_size = sc_list.GetSize();
Pavel Labath4d4d63e2018-02-09 11:37:01 +00001266 if (name_type_mask & eFunctionNameTypeFull ||
1267 name_type_mask & eFunctionNameTypeBase ||
Aaron Smith7ac1c782018-02-09 05:31:28 +00001268 name_type_mask & eFunctionNameTypeMethod) {
1269 CacheFunctionNames();
1270
1271 std::set<uint32_t> resolved_ids;
Aaron Smithc8316ed2018-03-22 03:44:51 +00001272 auto ResolveFn = [include_inlines, &name, &sc_list, &resolved_ids,
1273 this](UniqueCStringMap<uint32_t> &Names) {
Aaron Smith7ac1c782018-02-09 05:31:28 +00001274 std::vector<uint32_t> ids;
1275 if (Names.GetValues(name, ids)) {
1276 for (auto id : ids) {
1277 if (resolved_ids.find(id) == resolved_ids.end()) {
1278 if (ResolveFunction(id, include_inlines, sc_list))
1279 resolved_ids.insert(id);
1280 }
1281 }
1282 }
1283 };
1284 if (name_type_mask & eFunctionNameTypeFull) {
1285 ResolveFn(m_func_full_names);
1286 }
1287 if (name_type_mask & eFunctionNameTypeBase) {
1288 ResolveFn(m_func_base_names);
1289 }
1290 if (name_type_mask & eFunctionNameTypeMethod) {
1291 ResolveFn(m_func_method_names);
1292 }
1293 }
1294 return sc_list.GetSize() - old_size;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001295}
1296
1297uint32_t
1298SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression &regex,
1299 bool include_inlines, bool append,
1300 lldb_private::SymbolContextList &sc_list) {
Aaron Smith7ac1c782018-02-09 05:31:28 +00001301 if (!append)
1302 sc_list.Clear();
1303 if (!regex.IsValid())
1304 return 0;
1305
1306 auto old_size = sc_list.GetSize();
1307 CacheFunctionNames();
1308
1309 std::set<uint32_t> resolved_ids;
Aaron Smithc8316ed2018-03-22 03:44:51 +00001310 auto ResolveFn = [&regex, include_inlines, &sc_list, &resolved_ids,
1311 this](UniqueCStringMap<uint32_t> &Names) {
Aaron Smith7ac1c782018-02-09 05:31:28 +00001312 std::vector<uint32_t> ids;
1313 if (Names.GetValues(regex, ids)) {
1314 for (auto id : ids) {
1315 if (resolved_ids.find(id) == resolved_ids.end())
1316 if (ResolveFunction(id, include_inlines, sc_list))
1317 resolved_ids.insert(id);
1318 }
1319 }
1320 };
1321 ResolveFn(m_func_full_names);
1322 ResolveFn(m_func_base_names);
1323
1324 return sc_list.GetSize() - old_size;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001325}
1326
1327void SymbolFilePDB::GetMangledNamesForFunction(
1328 const std::string &scope_qualified_name,
1329 std::vector<lldb_private::ConstString> &mangled_names) {}
1330
1331uint32_t SymbolFilePDB::FindTypes(
1332 const lldb_private::SymbolContext &sc,
1333 const lldb_private::ConstString &name,
1334 const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append,
1335 uint32_t max_matches,
1336 llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
1337 lldb_private::TypeMap &types) {
1338 if (!append)
1339 types.Clear();
1340 if (!name)
1341 return 0;
Aaron Smith7ac1c782018-02-09 05:31:28 +00001342 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
1343 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001344
1345 searched_symbol_files.clear();
1346 searched_symbol_files.insert(this);
1347
Aaron Smith86e94342017-12-22 05:26:50 +00001348 // There is an assumption 'name' is not a regex
Aleksandr Urakovc1e530e2018-11-06 08:02:55 +00001349 FindTypesByName(name.GetStringRef(), parent_decl_ctx, max_matches, types);
Aaron Smithc8316ed2018-03-22 03:44:51 +00001350
Kate Stoneb9c1b512016-09-06 20:57:50 +00001351 return types.GetSize();
1352}
1353
Zachary Turner49110232018-11-05 17:40:28 +00001354void SymbolFilePDB::DumpClangAST(Stream &s) {
1355 auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
1356 auto clang = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
1357 if (!clang)
1358 return;
1359 clang->Dump(s);
1360}
1361
Aaron Smithc8316ed2018-03-22 03:44:51 +00001362void SymbolFilePDB::FindTypesByRegex(
1363 const lldb_private::RegularExpression &regex, uint32_t max_matches,
1364 lldb_private::TypeMap &types) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001365 // When searching by regex, we need to go out of our way to limit the search
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +00001366 // space as much as possible since this searches EVERYTHING in the PDB,
1367 // manually doing regex comparisons. PDB library isn't optimized for regex
1368 // searches or searches across multiple symbol types at the same time, so the
Kate Stoneb9c1b512016-09-06 20:57:50 +00001369 // best we can do is to search enums, then typedefs, then classes one by one,
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +00001370 // and do a regex comparison against each of them.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001371 PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef,
1372 PDB_SymType::UDT};
Kate Stoneb9c1b512016-09-06 20:57:50 +00001373 std::unique_ptr<IPDBEnumSymbols> results;
1374
Kate Stoneb9c1b512016-09-06 20:57:50 +00001375 uint32_t matches = 0;
1376
1377 for (auto tag : tags_to_search) {
Aaron Smith10a02572018-01-13 06:58:18 +00001378 results = m_global_scope_up->findAllChildren(tag);
1379 if (!results)
1380 continue;
1381
Kate Stoneb9c1b512016-09-06 20:57:50 +00001382 while (auto result = results->getNext()) {
1383 if (max_matches > 0 && matches >= max_matches)
1384 break;
1385
1386 std::string type_name;
1387 if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(result.get()))
1388 type_name = enum_type->getName();
1389 else if (auto typedef_type =
Aaron Smithc8316ed2018-03-22 03:44:51 +00001390 llvm::dyn_cast<PDBSymbolTypeTypedef>(result.get()))
Kate Stoneb9c1b512016-09-06 20:57:50 +00001391 type_name = typedef_type->getName();
1392 else if (auto class_type = llvm::dyn_cast<PDBSymbolTypeUDT>(result.get()))
1393 type_name = class_type->getName();
1394 else {
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +00001395 // We're looking only for types that have names. Skip symbols, as well
1396 // as unnamed types such as arrays, pointers, etc.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001397 continue;
1398 }
1399
Aaron Smith86e94342017-12-22 05:26:50 +00001400 if (!regex.Execute(type_name))
Kate Stoneb9c1b512016-09-06 20:57:50 +00001401 continue;
1402
1403 // This should cause the type to get cached and stored in the `m_types`
1404 // lookup.
1405 if (!ResolveTypeUID(result->getSymIndexId()))
1406 continue;
1407
1408 auto iter = m_types.find(result->getSymIndexId());
1409 if (iter == m_types.end())
1410 continue;
1411 types.Insert(iter->second);
1412 ++matches;
1413 }
1414 }
1415}
1416
Aleksandr Urakov709426b2018-09-10 08:08:43 +00001417void SymbolFilePDB::FindTypesByName(
Aleksandr Urakovc1e530e2018-11-06 08:02:55 +00001418 llvm::StringRef name,
Aleksandr Urakov709426b2018-09-10 08:08:43 +00001419 const lldb_private::CompilerDeclContext *parent_decl_ctx,
1420 uint32_t max_matches, lldb_private::TypeMap &types) {
1421 if (!parent_decl_ctx)
1422 parent_decl_ctx = m_tu_decl_ctx_up.get();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001423 std::unique_ptr<IPDBEnumSymbols> results;
Aaron Smithf76fe682018-03-07 03:16:50 +00001424 if (name.empty())
1425 return;
Aleksandr Urakov709426b2018-09-10 08:08:43 +00001426 results = m_global_scope_up->findAllChildren(PDB_SymType::None);
Aaron Smith10a02572018-01-13 06:58:18 +00001427 if (!results)
1428 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001429
1430 uint32_t matches = 0;
1431
1432 while (auto result = results->getNext()) {
1433 if (max_matches > 0 && matches >= max_matches)
1434 break;
Aleksandr Urakov709426b2018-09-10 08:08:43 +00001435
Aleksandr Urakovc1e530e2018-11-06 08:02:55 +00001436 if (MSVCUndecoratedNameParser::DropScope(
1437 result->getRawSymbol().getName()) != name)
Aleksandr Urakov709426b2018-09-10 08:08:43 +00001438 continue;
1439
Kate Stoneb9c1b512016-09-06 20:57:50 +00001440 switch (result->getSymTag()) {
1441 case PDB_SymType::Enum:
1442 case PDB_SymType::UDT:
1443 case PDB_SymType::Typedef:
1444 break;
1445 default:
Adrian Prantl05097242018-04-30 16:49:04 +00001446 // We're looking only for types that have names. Skip symbols, as well
1447 // as unnamed types such as arrays, pointers, etc.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001448 continue;
1449 }
1450
1451 // This should cause the type to get cached and stored in the `m_types`
1452 // lookup.
1453 if (!ResolveTypeUID(result->getSymIndexId()))
1454 continue;
1455
Aleksandr Urakov709426b2018-09-10 08:08:43 +00001456 auto actual_parent_decl_ctx =
1457 GetDeclContextContainingUID(result->getSymIndexId());
1458 if (actual_parent_decl_ctx != *parent_decl_ctx)
1459 continue;
1460
Kate Stoneb9c1b512016-09-06 20:57:50 +00001461 auto iter = m_types.find(result->getSymIndexId());
1462 if (iter == m_types.end())
1463 continue;
1464 types.Insert(iter->second);
1465 ++matches;
1466 }
1467}
1468
1469size_t SymbolFilePDB::FindTypes(
1470 const std::vector<lldb_private::CompilerContext> &contexts, bool append,
1471 lldb_private::TypeMap &types) {
1472 return 0;
1473}
1474
Aaron Smithec40f812018-01-23 20:35:19 +00001475lldb_private::TypeList *SymbolFilePDB::GetTypeList() {
1476 return m_obj_file->GetModule()->GetTypeList();
1477}
Kate Stoneb9c1b512016-09-06 20:57:50 +00001478
Aaron Smithc8316ed2018-03-22 03:44:51 +00001479void SymbolFilePDB::GetTypesForPDBSymbol(const llvm::pdb::PDBSymbol &pdb_symbol,
1480 uint32_t type_mask,
1481 TypeCollection &type_collection) {
Aaron Smith7ac1c782018-02-09 05:31:28 +00001482 bool can_parse = false;
Aaron Smithe664b5d2018-03-19 21:14:19 +00001483 switch (pdb_symbol.getSymTag()) {
Aaron Smith7ac1c782018-02-09 05:31:28 +00001484 case PDB_SymType::ArrayType:
1485 can_parse = ((type_mask & eTypeClassArray) != 0);
1486 break;
1487 case PDB_SymType::BuiltinType:
1488 can_parse = ((type_mask & eTypeClassBuiltin) != 0);
1489 break;
1490 case PDB_SymType::Enum:
1491 can_parse = ((type_mask & eTypeClassEnumeration) != 0);
1492 break;
1493 case PDB_SymType::Function:
1494 case PDB_SymType::FunctionSig:
1495 can_parse = ((type_mask & eTypeClassFunction) != 0);
1496 break;
1497 case PDB_SymType::PointerType:
1498 can_parse = ((type_mask & (eTypeClassPointer | eTypeClassBlockPointer |
1499 eTypeClassMemberPointer)) != 0);
1500 break;
1501 case PDB_SymType::Typedef:
1502 can_parse = ((type_mask & eTypeClassTypedef) != 0);
1503 break;
1504 case PDB_SymType::UDT: {
Aaron Smithe664b5d2018-03-19 21:14:19 +00001505 auto *udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&pdb_symbol);
Aaron Smith7ac1c782018-02-09 05:31:28 +00001506 assert(udt);
1507 can_parse = (udt->getUdtKind() != PDB_UdtType::Interface &&
Aaron Smithc8316ed2018-03-22 03:44:51 +00001508 ((type_mask & (eTypeClassClass | eTypeClassStruct |
1509 eTypeClassUnion)) != 0));
Aaron Smith7ac1c782018-02-09 05:31:28 +00001510 } break;
Aaron Smithc8316ed2018-03-22 03:44:51 +00001511 default:
1512 break;
Aaron Smith7ac1c782018-02-09 05:31:28 +00001513 }
1514
1515 if (can_parse) {
Aaron Smithe664b5d2018-03-19 21:14:19 +00001516 if (auto *type = ResolveTypeUID(pdb_symbol.getSymIndexId())) {
Aaron Smith7ac1c782018-02-09 05:31:28 +00001517 auto result =
1518 std::find(type_collection.begin(), type_collection.end(), type);
1519 if (result == type_collection.end())
1520 type_collection.push_back(type);
1521 }
1522 }
1523
Aaron Smithe664b5d2018-03-19 21:14:19 +00001524 auto results_up = pdb_symbol.findAllChildren();
Aaron Smith7ac1c782018-02-09 05:31:28 +00001525 while (auto symbol_up = results_up->getNext())
Aaron Smithe664b5d2018-03-19 21:14:19 +00001526 GetTypesForPDBSymbol(*symbol_up, type_mask, type_collection);
Aaron Smith7ac1c782018-02-09 05:31:28 +00001527}
1528
Kate Stoneb9c1b512016-09-06 20:57:50 +00001529size_t SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
Zachary Turner117b1fa2018-10-25 20:45:40 +00001530 TypeClass type_mask,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001531 lldb_private::TypeList &type_list) {
Aaron Smith7ac1c782018-02-09 05:31:28 +00001532 TypeCollection type_collection;
1533 uint32_t old_size = type_list.GetSize();
Aaron Smithc8316ed2018-03-22 03:44:51 +00001534 CompileUnit *cu =
1535 sc_scope ? sc_scope->CalculateSymbolContextCompileUnit() : nullptr;
Aaron Smith7ac1c782018-02-09 05:31:28 +00001536 if (cu) {
1537 auto compiland_up = GetPDBCompilandByUID(cu->GetID());
Aaron Smithe664b5d2018-03-19 21:14:19 +00001538 if (!compiland_up)
1539 return 0;
1540 GetTypesForPDBSymbol(*compiland_up, type_mask, type_collection);
Aaron Smith7ac1c782018-02-09 05:31:28 +00001541 } else {
1542 for (uint32_t cu_idx = 0; cu_idx < GetNumCompileUnits(); ++cu_idx) {
1543 auto cu_sp = ParseCompileUnitAtIndex(cu_idx);
Aaron Smithd5a925f2018-03-22 19:21:34 +00001544 if (cu_sp) {
Aaron Smithe664b5d2018-03-19 21:14:19 +00001545 if (auto compiland_up = GetPDBCompilandByUID(cu_sp->GetID()))
1546 GetTypesForPDBSymbol(*compiland_up, type_mask, type_collection);
Aaron Smith7ac1c782018-02-09 05:31:28 +00001547 }
1548 }
1549 }
1550
1551 for (auto type : type_collection) {
1552 type->GetForwardCompilerType();
1553 type_list.Insert(type->shared_from_this());
1554 }
1555 return type_list.GetSize() - old_size;
Zachary Turner74e08ca2016-03-02 22:05:52 +00001556}
1557
1558lldb_private::TypeSystem *
Kate Stoneb9c1b512016-09-06 20:57:50 +00001559SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {
1560 auto type_system =
1561 m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
1562 if (type_system)
1563 type_system->SetSymbolFile(this);
1564 return type_system;
Zachary Turner74e08ca2016-03-02 22:05:52 +00001565}
1566
Kate Stoneb9c1b512016-09-06 20:57:50 +00001567lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace(
1568 const lldb_private::SymbolContext &sc,
1569 const lldb_private::ConstString &name,
1570 const lldb_private::CompilerDeclContext *parent_decl_ctx) {
Aleksandr Urakov709426b2018-09-10 08:08:43 +00001571 auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
1572 auto clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
1573 if (!clang_type_system)
1574 return CompilerDeclContext();
1575
1576 PDBASTParser *pdb = clang_type_system->GetPDBParser();
1577 if (!pdb)
1578 return CompilerDeclContext();
1579
1580 clang::DeclContext *decl_context = nullptr;
1581 if (parent_decl_ctx)
1582 decl_context = static_cast<clang::DeclContext *>(
1583 parent_decl_ctx->GetOpaqueDeclContext());
1584
1585 auto namespace_decl =
1586 pdb->FindNamespaceDecl(decl_context, name.GetStringRef());
1587 if (!namespace_decl)
1588 return CompilerDeclContext();
1589
1590 return CompilerDeclContext(type_system,
1591 static_cast<clang::DeclContext *>(namespace_decl));
Zachary Turner74e08ca2016-03-02 22:05:52 +00001592}
1593
Kate Stoneb9c1b512016-09-06 20:57:50 +00001594lldb_private::ConstString SymbolFilePDB::GetPluginName() {
1595 static ConstString g_name("pdb");
1596 return g_name;
Zachary Turner74e08ca2016-03-02 22:05:52 +00001597}
1598
Kate Stoneb9c1b512016-09-06 20:57:50 +00001599uint32_t SymbolFilePDB::GetPluginVersion() { return 1; }
1600
1601IPDBSession &SymbolFilePDB::GetPDBSession() { return *m_session_up; }
1602
1603const IPDBSession &SymbolFilePDB::GetPDBSession() const {
1604 return *m_session_up;
Zachary Turner74e08ca2016-03-02 22:05:52 +00001605}
1606
Aaron Smithc8316ed2018-03-22 03:44:51 +00001607lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitForUID(uint32_t id,
1608 uint32_t index) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001609 auto found_cu = m_comp_units.find(id);
1610 if (found_cu != m_comp_units.end())
1611 return found_cu->second;
1612
Aaron Smith10a02572018-01-13 06:58:18 +00001613 auto compiland_up = GetPDBCompilandByUID(id);
1614 if (!compiland_up)
1615 return CompUnitSP();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001616
1617 lldb::LanguageType lang;
Aaron Smith10a02572018-01-13 06:58:18 +00001618 auto details = compiland_up->findOneChild<PDBSymbolCompilandDetails>();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001619 if (!details)
1620 lang = lldb::eLanguageTypeC_plus_plus;
1621 else
1622 lang = TranslateLanguage(details->getLanguage());
1623
Aaron Smithf76fe682018-03-07 03:16:50 +00001624 if (lang == lldb::LanguageType::eLanguageTypeUnknown)
1625 return CompUnitSP();
1626
Aaron Smith487b0c62018-03-20 00:18:22 +00001627 std::string path = compiland_up->getSourceFileFullPath();
Aaron Smithf76fe682018-03-07 03:16:50 +00001628 if (path.empty())
1629 return CompUnitSP();
1630
Kate Stoneb9c1b512016-09-06 20:57:50 +00001631 // Don't support optimized code for now, DebugInfoPDB does not return this
1632 // information.
1633 LazyBool optimized = eLazyBoolNo;
Aaron Smithc8316ed2018-03-22 03:44:51 +00001634 auto cu_sp = std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr,
1635 path.c_str(), id, lang, optimized);
Aaron Smith10a02572018-01-13 06:58:18 +00001636
1637 if (!cu_sp)
1638 return CompUnitSP();
1639
1640 m_comp_units.insert(std::make_pair(id, cu_sp));
1641 if (index == UINT32_MAX)
Aaron Smithe664b5d2018-03-19 21:14:19 +00001642 GetCompileUnitIndex(*compiland_up, index);
Aaron Smith10a02572018-01-13 06:58:18 +00001643 lldbassert(index != UINT32_MAX);
Aaron Smithc8316ed2018-03-22 03:44:51 +00001644 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(index,
1645 cu_sp);
Aaron Smith10a02572018-01-13 06:58:18 +00001646 return cu_sp;
Zachary Turner42dff792016-04-15 00:21:26 +00001647}
1648
Kate Stoneb9c1b512016-09-06 20:57:50 +00001649bool SymbolFilePDB::ParseCompileUnitLineTable(
1650 const lldb_private::SymbolContext &sc, uint32_t match_line) {
Aaron Smith10a02572018-01-13 06:58:18 +00001651 lldbassert(sc.comp_unit);
1652
1653 auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID());
1654 if (!compiland_up)
1655 return false;
Zachary Turner42dff792016-04-15 00:21:26 +00001656
Kate Stoneb9c1b512016-09-06 20:57:50 +00001657 // LineEntry needs the *index* of the file into the list of support files
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +00001658 // returned by ParseCompileUnitSupportFiles. But the underlying SDK gives us
Adrian Prantl05097242018-04-30 16:49:04 +00001659 // a globally unique idenfitifier in the namespace of the PDB. So, we have
1660 // to do a mapping so that we can hand out indices.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001661 llvm::DenseMap<uint32_t, uint32_t> index_map;
Aaron Smith10a02572018-01-13 06:58:18 +00001662 BuildSupportFileIdToSupportFileIndexMap(*compiland_up, index_map);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001663 auto line_table = llvm::make_unique<LineTable>(sc.comp_unit);
Zachary Turner74e08ca2016-03-02 22:05:52 +00001664
Aaron Smith10a02572018-01-13 06:58:18 +00001665 // Find contributions to `compiland` from all source and header files.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001666 std::string path = sc.comp_unit->GetPath();
Aaron Smith10a02572018-01-13 06:58:18 +00001667 auto files = m_session_up->getSourceFilesForCompiland(*compiland_up);
1668 if (!files)
1669 return false;
Zachary Turner74e08ca2016-03-02 22:05:52 +00001670
Adrian Prantl05097242018-04-30 16:49:04 +00001671 // For each source and header file, create a LineSequence for contributions
1672 // to the compiland from that file, and add the sequence.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001673 while (auto file = files->getNext()) {
1674 std::unique_ptr<LineSequence> sequence(
1675 line_table->CreateLineSequenceContainer());
Aaron Smith10a02572018-01-13 06:58:18 +00001676 auto lines = m_session_up->findLineNumbers(*compiland_up, *file);
1677 if (!lines)
1678 continue;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001679 int entry_count = lines->getChildCount();
Zachary Turner74e08ca2016-03-02 22:05:52 +00001680
Kate Stoneb9c1b512016-09-06 20:57:50 +00001681 uint64_t prev_addr;
1682 uint32_t prev_length;
1683 uint32_t prev_line;
1684 uint32_t prev_source_idx;
Zachary Turner74e08ca2016-03-02 22:05:52 +00001685
Kate Stoneb9c1b512016-09-06 20:57:50 +00001686 for (int i = 0; i < entry_count; ++i) {
1687 auto line = lines->getChildAtIndex(i);
Zachary Turner74e08ca2016-03-02 22:05:52 +00001688
Kate Stoneb9c1b512016-09-06 20:57:50 +00001689 uint64_t lno = line->getLineNumber();
1690 uint64_t addr = line->getVirtualAddress();
1691 uint32_t length = line->getLength();
1692 uint32_t source_id = line->getSourceFileId();
1693 uint32_t col = line->getColumnNumber();
1694 uint32_t source_idx = index_map[source_id];
Zachary Turner74e08ca2016-03-02 22:05:52 +00001695
Adrian Prantl05097242018-04-30 16:49:04 +00001696 // There was a gap between the current entry and the previous entry if
1697 // the addresses don't perfectly line up.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001698 bool is_gap = (i > 0) && (prev_addr + prev_length < addr);
Zachary Turner74e08ca2016-03-02 22:05:52 +00001699
Kate Stoneb9c1b512016-09-06 20:57:50 +00001700 // Before inserting the current entry, insert a terminal entry at the end
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +00001701 // of the previous entry's address range if the current entry resulted in
1702 // a gap from the previous entry.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001703 if (is_gap && ShouldAddLine(match_line, prev_line, prev_length)) {
1704 line_table->AppendLineEntryToSequence(
1705 sequence.get(), prev_addr + prev_length, prev_line, 0,
1706 prev_source_idx, false, false, false, false, true);
Aaron Smith010edd32018-06-08 02:45:25 +00001707
1708 line_table->InsertSequence(sequence.release());
1709 sequence.reset(line_table->CreateLineSequenceContainer());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001710 }
Zachary Turner74e08ca2016-03-02 22:05:52 +00001711
Kate Stoneb9c1b512016-09-06 20:57:50 +00001712 if (ShouldAddLine(match_line, lno, length)) {
1713 bool is_statement = line->isStatement();
1714 bool is_prologue = false;
1715 bool is_epilogue = false;
1716 auto func =
1717 m_session_up->findSymbolByAddress(addr, PDB_SymType::Function);
1718 if (func) {
1719 auto prologue = func->findOneChild<PDBSymbolFuncDebugStart>();
Aaron Smith10a02572018-01-13 06:58:18 +00001720 if (prologue)
1721 is_prologue = (addr == prologue->getVirtualAddress());
Zachary Turner74e08ca2016-03-02 22:05:52 +00001722
Kate Stoneb9c1b512016-09-06 20:57:50 +00001723 auto epilogue = func->findOneChild<PDBSymbolFuncDebugEnd>();
Aaron Smith10a02572018-01-13 06:58:18 +00001724 if (epilogue)
1725 is_epilogue = (addr == epilogue->getVirtualAddress());
Zachary Turner74e08ca2016-03-02 22:05:52 +00001726 }
Zachary Turner7e8c7be2016-03-10 00:06:26 +00001727
Kate Stoneb9c1b512016-09-06 20:57:50 +00001728 line_table->AppendLineEntryToSequence(sequence.get(), addr, lno, col,
1729 source_idx, is_statement, false,
1730 is_prologue, is_epilogue, false);
1731 }
Zachary Turner7e8c7be2016-03-10 00:06:26 +00001732
Kate Stoneb9c1b512016-09-06 20:57:50 +00001733 prev_addr = addr;
1734 prev_length = length;
1735 prev_line = lno;
1736 prev_source_idx = source_idx;
Zachary Turner74e08ca2016-03-02 22:05:52 +00001737 }
1738
Kate Stoneb9c1b512016-09-06 20:57:50 +00001739 if (entry_count > 0 && ShouldAddLine(match_line, prev_line, prev_length)) {
1740 // The end is always a terminal entry, so insert it regardless.
1741 line_table->AppendLineEntryToSequence(
1742 sequence.get(), prev_addr + prev_length, prev_line, 0,
1743 prev_source_idx, false, false, false, false, true);
1744 }
1745
1746 line_table->InsertSequence(sequence.release());
1747 }
1748
Aaron Smith10a02572018-01-13 06:58:18 +00001749 if (line_table->GetSize()) {
1750 sc.comp_unit->SetLineTable(line_table.release());
1751 return true;
1752 }
1753 return false;
Zachary Turner74e08ca2016-03-02 22:05:52 +00001754}
1755
Kate Stoneb9c1b512016-09-06 20:57:50 +00001756void SymbolFilePDB::BuildSupportFileIdToSupportFileIndexMap(
Aaron Smith10a02572018-01-13 06:58:18 +00001757 const PDBSymbolCompiland &compiland,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001758 llvm::DenseMap<uint32_t, uint32_t> &index_map) const {
Adrian Prantl05097242018-04-30 16:49:04 +00001759 // This is a hack, but we need to convert the source id into an index into
1760 // the support files array. We don't want to do path comparisons to avoid
Adrian McCarthy9d0eb9962017-01-27 21:42:28 +00001761 // basename / full path issues that may or may not even be a problem, so we
1762 // use the globally unique source file identifiers. Ideally we could use the
1763 // global identifiers everywhere, but LineEntry currently assumes indices.
Aaron Smith10a02572018-01-13 06:58:18 +00001764 auto source_files = m_session_up->getSourceFilesForCompiland(compiland);
1765 if (!source_files)
1766 return;
Pavel Labath9ea80d22018-06-28 10:03:42 +00001767
1768 // LLDB uses the DWARF-like file numeration (one based)
1769 int index = 1;
Zachary Turner74e08ca2016-03-02 22:05:52 +00001770
Kate Stoneb9c1b512016-09-06 20:57:50 +00001771 while (auto file = source_files->getNext()) {
1772 uint32_t source_id = file->getUniqueId();
1773 index_map[source_id] = index++;
1774 }
Zachary Turner74e08ca2016-03-02 22:05:52 +00001775}
Aaron Smith7ac1c782018-02-09 05:31:28 +00001776
1777lldb::CompUnitSP SymbolFilePDB::GetCompileUnitContainsAddress(
Aaron Smith308e39c2018-03-22 19:26:33 +00001778 const lldb_private::Address &so_addr) {
Aaron Smith7ac1c782018-02-09 05:31:28 +00001779 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
Aaron Smith308e39c2018-03-22 19:26:33 +00001780 if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)
Aaron Smith7ac1c782018-02-09 05:31:28 +00001781 return nullptr;
1782
Aaron Smith308e39c2018-03-22 19:26:33 +00001783 // If it is a PDB function's vm addr, this is the first sure bet.
1784 if (auto lines =
1785 m_session_up->findLineNumbersByAddress(file_vm_addr, /*Length=*/1)) {
1786 if (auto first_line = lines->getNext())
1787 return ParseCompileUnitForUID(first_line->getCompilandId());
Aaron Smith7ac1c782018-02-09 05:31:28 +00001788 }
1789
Aaron Smith308e39c2018-03-22 19:26:33 +00001790 // Otherwise we resort to section contributions.
1791 if (auto sec_contribs = m_session_up->getSectionContribs()) {
1792 while (auto section = sec_contribs->getNext()) {
1793 auto va = section->getVirtualAddress();
1794 if (file_vm_addr >= va && file_vm_addr < va + section->getLength())
1795 return ParseCompileUnitForUID(section->getCompilandId());
1796 }
1797 }
Aaron Smith7ac1c782018-02-09 05:31:28 +00001798 return nullptr;
1799}
1800
1801Mangled
Aaron Smithe664b5d2018-03-19 21:14:19 +00001802SymbolFilePDB::GetMangledForPDBFunc(const llvm::pdb::PDBSymbolFunc &pdb_func) {
Aaron Smith7ac1c782018-02-09 05:31:28 +00001803 Mangled mangled;
Aaron Smithe664b5d2018-03-19 21:14:19 +00001804 auto func_name = pdb_func.getName();
1805 auto func_undecorated_name = pdb_func.getUndecoratedName();
Aaron Smith7ac1c782018-02-09 05:31:28 +00001806 std::string func_decorated_name;
1807
1808 // Seek from public symbols for non-static function's decorated name if any.
1809 // For static functions, they don't have undecorated names and aren't exposed
1810 // in Public Symbols either.
1811 if (!func_undecorated_name.empty()) {
Aaron Smithc8316ed2018-03-22 03:44:51 +00001812 auto result_up = m_global_scope_up->findChildren(
1813 PDB_SymType::PublicSymbol, func_undecorated_name,
1814 PDB_NameSearchFlags::NS_UndecoratedName);
Aaron Smith7ac1c782018-02-09 05:31:28 +00001815 if (result_up) {
1816 while (auto symbol_up = result_up->getNext()) {
1817 // For a public symbol, it is unique.
1818 lldbassert(result_up->getChildCount() == 1);
1819 if (auto *pdb_public_sym =
Aaron Smithc8316ed2018-03-22 03:44:51 +00001820 llvm::dyn_cast_or_null<PDBSymbolPublicSymbol>(
1821 symbol_up.get())) {
Aaron Smith7ac1c782018-02-09 05:31:28 +00001822 if (pdb_public_sym->isFunction()) {
1823 func_decorated_name = pdb_public_sym->getName();
Aaron Smithf76fe682018-03-07 03:16:50 +00001824 break;
Aaron Smith7ac1c782018-02-09 05:31:28 +00001825 }
1826 }
1827 }
1828 }
1829 }
1830 if (!func_decorated_name.empty()) {
1831 mangled.SetMangledName(ConstString(func_decorated_name));
1832
1833 // For MSVC, format of C funciton's decorated name depends on calling
1834 // conventon. Unfortunately none of the format is recognized by current
1835 // LLDB. For example, `_purecall` is a __cdecl C function. From PDB,
Adrian Prantl05097242018-04-30 16:49:04 +00001836 // `__purecall` is retrieved as both its decorated and undecorated name
1837 // (using PDBSymbolFunc::getUndecoratedName method). However `__purecall`
1838 // string is not treated as mangled in LLDB (neither `?` nor `_Z` prefix).
1839 // Mangled::GetDemangledName method will fail internally and caches an
1840 // empty string as its undecorated name. So we will face a contradition
1841 // here for the same symbol:
Aaron Smith7ac1c782018-02-09 05:31:28 +00001842 // non-empty undecorated name from PDB
1843 // empty undecorated name from LLDB
1844 if (!func_undecorated_name.empty() &&
1845 mangled.GetDemangledName(mangled.GuessLanguage()).IsEmpty())
1846 mangled.SetDemangledName(ConstString(func_undecorated_name));
1847
1848 // LLDB uses several flags to control how a C++ decorated name is
Adrian Prantl05097242018-04-30 16:49:04 +00001849 // undecorated for MSVC. See `safeUndecorateName` in Class Mangled. So the
1850 // yielded name could be different from what we retrieve from
Aaron Smith7ac1c782018-02-09 05:31:28 +00001851 // PDB source unless we also apply same flags in getting undecorated
1852 // name through PDBSymbolFunc::getUndecoratedNameEx method.
1853 if (!func_undecorated_name.empty() &&
1854 mangled.GetDemangledName(mangled.GuessLanguage()) !=
1855 ConstString(func_undecorated_name))
1856 mangled.SetDemangledName(ConstString(func_undecorated_name));
1857 } else if (!func_undecorated_name.empty()) {
1858 mangled.SetDemangledName(ConstString(func_undecorated_name));
1859 } else if (!func_name.empty())
1860 mangled.SetValue(ConstString(func_name), false);
1861
1862 return mangled;
1863}
1864
1865bool SymbolFilePDB::DeclContextMatchesThisSymbolFile(
1866 const lldb_private::CompilerDeclContext *decl_ctx) {
1867 if (decl_ctx == nullptr || !decl_ctx->IsValid())
1868 return true;
1869
1870 TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem();
1871 if (!decl_ctx_type_system)
1872 return false;
1873 TypeSystem *type_system = GetTypeSystemForLanguage(
1874 decl_ctx_type_system->GetMinimumLanguage(nullptr));
1875 if (decl_ctx_type_system == type_system)
1876 return true; // The type systems match, return true
1877
1878 return false;
1879}
Aleksandr Urakov356aa4a2018-10-23 08:29:17 +00001880
1881uint32_t SymbolFilePDB::GetCompilandId(const llvm::pdb::PDBSymbolData &data) {
1882 static const auto pred_upper = [](uint32_t lhs, SecContribInfo rhs) {
1883 return lhs < rhs.Offset;
1884 };
1885
1886 // Cache section contributions
1887 if (m_sec_contribs.empty()) {
1888 if (auto SecContribs = m_session_up->getSectionContribs()) {
1889 while (auto SectionContrib = SecContribs->getNext()) {
1890 auto comp_id = SectionContrib->getCompilandId();
1891 if (!comp_id)
1892 continue;
1893
1894 auto sec = SectionContrib->getAddressSection();
1895 auto &sec_cs = m_sec_contribs[sec];
1896
1897 auto offset = SectionContrib->getAddressOffset();
1898 auto it =
1899 std::upper_bound(sec_cs.begin(), sec_cs.end(), offset, pred_upper);
1900
1901 auto size = SectionContrib->getLength();
1902 sec_cs.insert(it, {offset, size, comp_id});
1903 }
1904 }
1905 }
1906
1907 // Check by line number
1908 if (auto Lines = data.getLineNumbers()) {
1909 if (auto FirstLine = Lines->getNext())
1910 return FirstLine->getCompilandId();
1911 }
1912
1913 // Retrieve section + offset
1914 uint32_t DataSection = data.getAddressSection();
1915 uint32_t DataOffset = data.getAddressOffset();
1916 if (DataSection == 0) {
1917 if (auto RVA = data.getRelativeVirtualAddress())
1918 m_session_up->addressForRVA(RVA, DataSection, DataOffset);
1919 }
1920
1921 if (DataSection) {
1922 // Search by section contributions
1923 auto &sec_cs = m_sec_contribs[DataSection];
1924 auto it =
1925 std::upper_bound(sec_cs.begin(), sec_cs.end(), DataOffset, pred_upper);
1926 if (it != sec_cs.begin()) {
1927 --it;
1928 if (DataOffset < it->Offset + it->Size)
1929 return it->CompilandId;
1930 }
1931 } else {
1932 // Search in lexical tree
1933 auto LexParentId = data.getLexicalParentId();
1934 while (auto LexParent = m_session_up->getSymbolById(LexParentId)) {
1935 if (LexParent->getSymTag() == PDB_SymType::Exe)
1936 break;
1937 if (LexParent->getSymTag() == PDB_SymType::Compiland)
1938 return LexParentId;
1939 LexParentId = LexParent->getRawSymbol().getLexicalParentId();
1940 }
1941 }
1942
1943 return 0;
1944}