1 //===-- 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 
12 #include "clang/Lex/Lexer.h"
13 
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/PluginManager.h"
16 #include "lldb/Symbol/ClangASTContext.h"
17 #include "lldb/Symbol/CompileUnit.h"
18 #include "lldb/Symbol/LineTable.h"
19 #include "lldb/Symbol/ObjectFile.h"
20 #include "lldb/Symbol/SymbolContext.h"
21 #include "lldb/Symbol/TypeMap.h"
22 
23 #include "llvm/DebugInfo/PDB/GenericError.h"
24 #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
25 #include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
26 #include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
27 #include "llvm/DebugInfo/PDB/PDBSymbol.h"
28 #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
29 #include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
30 #include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
31 #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
32 #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
33 #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
34 #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
35 #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
36 #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
37 
38 #include "Plugins/SymbolFile/PDB/PDBASTParser.h"
39 
40 #include <regex>
41 
42 using namespace lldb_private;
43 using namespace llvm::pdb;
44 
45 namespace {
46 lldb::LanguageType TranslateLanguage(PDB_Lang lang) {
47   switch (lang) {
48   case PDB_Lang::Cpp:
49     return lldb::LanguageType::eLanguageTypeC_plus_plus;
50   case PDB_Lang::C:
51     return lldb::LanguageType::eLanguageTypeC;
52   default:
53     return lldb::LanguageType::eLanguageTypeUnknown;
54   }
55 }
56 
57 bool ShouldAddLine(uint32_t requested_line, uint32_t actual_line,
58                    uint32_t addr_length) {
59   return ((requested_line == 0 || actual_line == requested_line) &&
60           addr_length > 0);
61 }
62 }
63 
64 void SymbolFilePDB::Initialize() {
65   PluginManager::RegisterPlugin(GetPluginNameStatic(),
66                                 GetPluginDescriptionStatic(), CreateInstance,
67                                 DebuggerInitialize);
68 }
69 
70 void SymbolFilePDB::Terminate() {
71   PluginManager::UnregisterPlugin(CreateInstance);
72 }
73 
74 void SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger) {}
75 
76 lldb_private::ConstString SymbolFilePDB::GetPluginNameStatic() {
77   static ConstString g_name("pdb");
78   return g_name;
79 }
80 
81 const char *SymbolFilePDB::GetPluginDescriptionStatic() {
82   return "Microsoft PDB debug symbol file reader.";
83 }
84 
85 lldb_private::SymbolFile *
86 SymbolFilePDB::CreateInstance(lldb_private::ObjectFile *obj_file) {
87   return new SymbolFilePDB(obj_file);
88 }
89 
90 SymbolFilePDB::SymbolFilePDB(lldb_private::ObjectFile *object_file)
91     : SymbolFile(object_file), m_cached_compile_unit_count(0) {}
92 
93 SymbolFilePDB::~SymbolFilePDB() {}
94 
95 uint32_t SymbolFilePDB::CalculateAbilities() {
96   if (!m_session_up) {
97     // Lazily load and match the PDB file, but only do this once.
98     std::string exePath = m_obj_file->GetFileSpec().GetPath();
99     auto error = loadDataForEXE(PDB_ReaderType::DIA, llvm::StringRef(exePath),
100                                 m_session_up);
101     if (error) {
102       llvm::consumeError(std::move(error));
103       return 0;
104     }
105   }
106   return CompileUnits | LineTables;
107 }
108 
109 void SymbolFilePDB::InitializeObject() {
110   lldb::addr_t obj_load_address = m_obj_file->GetFileOffset();
111   m_session_up->setLoadAddress(obj_load_address);
112 
113   TypeSystem *type_system =
114       GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
115   ClangASTContext *clang_type_system =
116       llvm::dyn_cast_or_null<ClangASTContext>(type_system);
117   m_tu_decl_ctx_up = llvm::make_unique<CompilerDeclContext>(
118       type_system, clang_type_system->GetTranslationUnitDecl());
119 }
120 
121 uint32_t SymbolFilePDB::GetNumCompileUnits() {
122   if (m_cached_compile_unit_count == 0) {
123     auto global = m_session_up->getGlobalScope();
124     auto compilands = global->findAllChildren<PDBSymbolCompiland>();
125     m_cached_compile_unit_count = compilands->getChildCount();
126 
127     // The linker can inject an additional "dummy" compilation unit into the
128     // PDB. Ignore this special compile unit for our purposes, if it is there.
129     // It is always the last one.
130     auto last_cu = compilands->getChildAtIndex(m_cached_compile_unit_count - 1);
131     std::string name = last_cu->getName();
132     if (name == "* Linker *")
133       --m_cached_compile_unit_count;
134   }
135   return m_cached_compile_unit_count;
136 }
137 
138 lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index) {
139   auto global = m_session_up->getGlobalScope();
140   auto compilands = global->findAllChildren<PDBSymbolCompiland>();
141   auto cu = compilands->getChildAtIndex(index);
142 
143   uint32_t id = cu->getSymIndexId();
144 
145   return ParseCompileUnitForSymIndex(id);
146 }
147 
148 lldb::LanguageType
149 SymbolFilePDB::ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) {
150   // What fields should I expect to be filled out on the SymbolContext?  Is it
151   // safe to assume that `sc.comp_unit` is valid?
152   if (!sc.comp_unit)
153     return lldb::eLanguageTypeUnknown;
154 
155   auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(
156       sc.comp_unit->GetID());
157   if (!cu)
158     return lldb::eLanguageTypeUnknown;
159   auto details = cu->findOneChild<PDBSymbolCompilandDetails>();
160   if (!details)
161     return lldb::eLanguageTypeUnknown;
162   return TranslateLanguage(details->getLanguage());
163 }
164 
165 size_t SymbolFilePDB::ParseCompileUnitFunctions(
166     const lldb_private::SymbolContext &sc) {
167   // TODO: Implement this
168   return size_t();
169 }
170 
171 bool SymbolFilePDB::ParseCompileUnitLineTable(
172     const lldb_private::SymbolContext &sc) {
173   return ParseCompileUnitLineTable(sc, 0);
174 }
175 
176 bool SymbolFilePDB::ParseCompileUnitDebugMacros(
177     const lldb_private::SymbolContext &sc) {
178   // PDB doesn't contain information about macros
179   return false;
180 }
181 
182 bool SymbolFilePDB::ParseCompileUnitSupportFiles(
183     const lldb_private::SymbolContext &sc,
184     lldb_private::FileSpecList &support_files) {
185   if (!sc.comp_unit)
186     return false;
187 
188   // In theory this is unnecessary work for us, because all of this information
189   // is easily (and quickly) accessible from DebugInfoPDB, so caching it a
190   // second time seems like a waste.  Unfortunately, there's no good way around
191   // this short of a moderate refactor since SymbolVendor depends on being able
192   // to cache this list.
193   auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(
194       sc.comp_unit->GetID());
195   if (!cu)
196     return false;
197   auto files = m_session_up->getSourceFilesForCompiland(*cu);
198   if (!files || files->getChildCount() == 0)
199     return false;
200 
201   while (auto file = files->getNext()) {
202     FileSpec spec(file->getFileName(), false);
203     support_files.Append(spec);
204   }
205   return true;
206 }
207 
208 bool SymbolFilePDB::ParseImportedModules(
209     const lldb_private::SymbolContext &sc,
210     std::vector<lldb_private::ConstString> &imported_modules) {
211   // PDB does not yet support module debug info
212   return false;
213 }
214 
215 size_t
216 SymbolFilePDB::ParseFunctionBlocks(const lldb_private::SymbolContext &sc) {
217   // TODO: Implement this
218   return size_t();
219 }
220 
221 size_t SymbolFilePDB::ParseTypes(const lldb_private::SymbolContext &sc) {
222   // TODO: Implement this
223   return size_t();
224 }
225 
226 size_t
227 SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) {
228   // TODO: Implement this
229   return size_t();
230 }
231 
232 lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
233   auto find_result = m_types.find(type_uid);
234   if (find_result != m_types.end())
235     return find_result->second.get();
236 
237   TypeSystem *type_system =
238       GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
239   ClangASTContext *clang_type_system =
240       llvm::dyn_cast_or_null<ClangASTContext>(type_system);
241   if (!clang_type_system)
242     return nullptr;
243   PDBASTParser *pdb =
244       llvm::dyn_cast<PDBASTParser>(clang_type_system->GetPDBParser());
245   if (!pdb)
246     return nullptr;
247 
248   auto pdb_type = m_session_up->getSymbolById(type_uid);
249   if (pdb_type == nullptr)
250     return nullptr;
251 
252   lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type);
253   m_types.insert(std::make_pair(type_uid, result));
254   return result.get();
255 }
256 
257 bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) {
258   // TODO: Implement this
259   return false;
260 }
261 
262 lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) {
263   return lldb_private::CompilerDecl();
264 }
265 
266 lldb_private::CompilerDeclContext
267 SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) {
268   // PDB always uses the translation unit decl context for everything.  We can
269   // improve this later but it's not easy because PDB doesn't provide a high
270   // enough level of type fidelity in this area.
271   return *m_tu_decl_ctx_up;
272 }
273 
274 lldb_private::CompilerDeclContext
275 SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
276   return *m_tu_decl_ctx_up;
277 }
278 
279 void SymbolFilePDB::ParseDeclsForContext(
280     lldb_private::CompilerDeclContext decl_ctx) {}
281 
282 uint32_t
283 SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,
284                                     uint32_t resolve_scope,
285                                     lldb_private::SymbolContext &sc) {
286   return uint32_t();
287 }
288 
289 uint32_t SymbolFilePDB::ResolveSymbolContext(
290     const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines,
291     uint32_t resolve_scope, lldb_private::SymbolContextList &sc_list) {
292   if (resolve_scope & lldb::eSymbolContextCompUnit) {
293     // Locate all compilation units with line numbers referencing the specified
294     // file.  For example, if `file_spec` is <vector>, then this should return
295     // all source files and header files that reference <vector>, either
296     // directly or indirectly.
297     auto compilands = m_session_up->findCompilandsForSourceFile(
298         file_spec.GetPath(), PDB_NameSearchFlags::NS_CaseInsensitive);
299 
300     // For each one, either find its previously parsed data or parse it afresh
301     // and add it to the symbol context list.
302     while (auto compiland = compilands->getNext()) {
303       // If we're not checking inlines, then don't add line information for this
304       // file unless the FileSpec matches.
305       if (!check_inlines) {
306         // `getSourceFileName` returns the basename of the original source file
307         // used to generate this compiland.  It does not return the full path.
308         // Currently the only way to get that is to do a basename lookup to get
309         // the IPDBSourceFile, but this is ambiguous in the case of two source
310         // files with the same name contributing to the same compiland.  This is
311         // a moderately extreme edge case, so we consider this OK for now,
312         // although we need to find a long-term solution.
313         std::string source_file = compiland->getSourceFileName();
314         auto pdb_file = m_session_up->findOneSourceFile(
315             compiland.get(), source_file,
316             PDB_NameSearchFlags::NS_CaseInsensitive);
317         source_file = pdb_file->getFileName();
318         FileSpec this_spec(source_file, false, FileSpec::ePathSyntaxWindows);
319         if (!file_spec.FileEquals(this_spec))
320           continue;
321       }
322 
323       SymbolContext sc;
324       auto cu = ParseCompileUnitForSymIndex(compiland->getSymIndexId());
325       sc.comp_unit = cu.get();
326       sc.module_sp = cu->GetModule();
327       sc_list.Append(sc);
328 
329       // If we were asked to resolve line entries, add all entries to the line
330       // table that match the requested line (or all lines if `line` == 0).
331       if (resolve_scope & lldb::eSymbolContextLineEntry)
332         ParseCompileUnitLineTable(sc, line);
333     }
334   }
335   return sc_list.GetSize();
336 }
337 
338 uint32_t SymbolFilePDB::FindGlobalVariables(
339     const lldb_private::ConstString &name,
340     const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append,
341     uint32_t max_matches, lldb_private::VariableList &variables) {
342   return uint32_t();
343 }
344 
345 uint32_t
346 SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression &regex,
347                                    bool append, uint32_t max_matches,
348                                    lldb_private::VariableList &variables) {
349   return uint32_t();
350 }
351 
352 uint32_t SymbolFilePDB::FindFunctions(
353     const lldb_private::ConstString &name,
354     const lldb_private::CompilerDeclContext *parent_decl_ctx,
355     uint32_t name_type_mask, bool include_inlines, bool append,
356     lldb_private::SymbolContextList &sc_list) {
357   return uint32_t();
358 }
359 
360 uint32_t
361 SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression &regex,
362                              bool include_inlines, bool append,
363                              lldb_private::SymbolContextList &sc_list) {
364   return uint32_t();
365 }
366 
367 void SymbolFilePDB::GetMangledNamesForFunction(
368     const std::string &scope_qualified_name,
369     std::vector<lldb_private::ConstString> &mangled_names) {}
370 
371 uint32_t SymbolFilePDB::FindTypes(
372     const lldb_private::SymbolContext &sc,
373     const lldb_private::ConstString &name,
374     const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append,
375     uint32_t max_matches,
376     llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
377     lldb_private::TypeMap &types) {
378   if (!append)
379     types.Clear();
380   if (!name)
381     return 0;
382 
383   searched_symbol_files.clear();
384   searched_symbol_files.insert(this);
385 
386   std::string name_str = name.AsCString();
387 
388   // If this might be a regex, we have to return EVERY symbol and process them
389   // one by one, which is going to destroy performance on large PDB files.  So
390   // try really hard not to use a regex match.
391   if (name_str.find_first_of("[]?*.-+\\") != std::string::npos)
392     FindTypesByRegex(name_str, max_matches, types);
393   else
394     FindTypesByName(name_str, max_matches, types);
395   return types.GetSize();
396 }
397 
398 void SymbolFilePDB::FindTypesByRegex(const std::string &regex,
399                                      uint32_t max_matches,
400                                      lldb_private::TypeMap &types) {
401   // When searching by regex, we need to go out of our way to limit the search
402   // space as much as possible since this searches EVERYTHING in the PDB,
403   // manually doing regex comparisons.  PDB library isn't optimized for regex
404   // searches or searches across multiple symbol types at the same time, so the
405   // best we can do is to search enums, then typedefs, then classes one by one,
406   // and do a regex comparison against each of them.
407   PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef,
408                                   PDB_SymType::UDT};
409   auto global = m_session_up->getGlobalScope();
410   std::unique_ptr<IPDBEnumSymbols> results;
411 
412   std::regex re(regex);
413 
414   uint32_t matches = 0;
415 
416   for (auto tag : tags_to_search) {
417     results = global->findAllChildren(tag);
418     while (auto result = results->getNext()) {
419       if (max_matches > 0 && matches >= max_matches)
420         break;
421 
422       std::string type_name;
423       if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(result.get()))
424         type_name = enum_type->getName();
425       else if (auto typedef_type =
426                    llvm::dyn_cast<PDBSymbolTypeTypedef>(result.get()))
427         type_name = typedef_type->getName();
428       else if (auto class_type = llvm::dyn_cast<PDBSymbolTypeUDT>(result.get()))
429         type_name = class_type->getName();
430       else {
431         // We're looking only for types that have names.  Skip symbols, as well
432         // as unnamed types such as arrays, pointers, etc.
433         continue;
434       }
435 
436       if (!std::regex_match(type_name, re))
437         continue;
438 
439       // This should cause the type to get cached and stored in the `m_types`
440       // lookup.
441       if (!ResolveTypeUID(result->getSymIndexId()))
442         continue;
443 
444       auto iter = m_types.find(result->getSymIndexId());
445       if (iter == m_types.end())
446         continue;
447       types.Insert(iter->second);
448       ++matches;
449     }
450   }
451 }
452 
453 void SymbolFilePDB::FindTypesByName(const std::string &name,
454                                     uint32_t max_matches,
455                                     lldb_private::TypeMap &types) {
456   auto global = m_session_up->getGlobalScope();
457   std::unique_ptr<IPDBEnumSymbols> results;
458   results = global->findChildren(PDB_SymType::None, name,
459                                  PDB_NameSearchFlags::NS_Default);
460 
461   uint32_t matches = 0;
462 
463   while (auto result = results->getNext()) {
464     if (max_matches > 0 && matches >= max_matches)
465       break;
466     switch (result->getSymTag()) {
467     case PDB_SymType::Enum:
468     case PDB_SymType::UDT:
469     case PDB_SymType::Typedef:
470       break;
471     default:
472       // We're looking only for types that have names.  Skip symbols, as well as
473       // unnamed types such as arrays, pointers, etc.
474       continue;
475     }
476 
477     // This should cause the type to get cached and stored in the `m_types`
478     // lookup.
479     if (!ResolveTypeUID(result->getSymIndexId()))
480       continue;
481 
482     auto iter = m_types.find(result->getSymIndexId());
483     if (iter == m_types.end())
484       continue;
485     types.Insert(iter->second);
486     ++matches;
487   }
488 }
489 
490 size_t SymbolFilePDB::FindTypes(
491     const std::vector<lldb_private::CompilerContext> &contexts, bool append,
492     lldb_private::TypeMap &types) {
493   return 0;
494 }
495 
496 lldb_private::TypeList *SymbolFilePDB::GetTypeList() { return nullptr; }
497 
498 size_t SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
499                                uint32_t type_mask,
500                                lldb_private::TypeList &type_list) {
501   return size_t();
502 }
503 
504 lldb_private::TypeSystem *
505 SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {
506   auto type_system =
507       m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
508   if (type_system)
509     type_system->SetSymbolFile(this);
510   return type_system;
511 }
512 
513 lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace(
514     const lldb_private::SymbolContext &sc,
515     const lldb_private::ConstString &name,
516     const lldb_private::CompilerDeclContext *parent_decl_ctx) {
517   return lldb_private::CompilerDeclContext();
518 }
519 
520 lldb_private::ConstString SymbolFilePDB::GetPluginName() {
521   static ConstString g_name("pdb");
522   return g_name;
523 }
524 
525 uint32_t SymbolFilePDB::GetPluginVersion() { return 1; }
526 
527 IPDBSession &SymbolFilePDB::GetPDBSession() { return *m_session_up; }
528 
529 const IPDBSession &SymbolFilePDB::GetPDBSession() const {
530   return *m_session_up;
531 }
532 
533 lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitForSymIndex(uint32_t id) {
534   auto found_cu = m_comp_units.find(id);
535   if (found_cu != m_comp_units.end())
536     return found_cu->second;
537 
538   auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(id);
539 
540   // `getSourceFileName` returns the basename of the original source file used
541   // to generate this compiland.  It does not return the full path.  Currently
542   // the only way to get that is to do a basename lookup to get the
543   // IPDBSourceFile, but this is ambiguous in the case of two source files with
544   // the same name contributing to the same compiland. This is a moderately
545   // extreme edge case, so we consider this OK for now, although we need to find
546   // a long-term solution.
547   auto file =
548       m_session_up->findOneSourceFile(cu.get(), cu->getSourceFileName(),
549                                       PDB_NameSearchFlags::NS_CaseInsensitive);
550   std::string path = file->getFileName();
551 
552   lldb::LanguageType lang;
553   auto details = cu->findOneChild<PDBSymbolCompilandDetails>();
554   if (!details)
555     lang = lldb::eLanguageTypeC_plus_plus;
556   else
557     lang = TranslateLanguage(details->getLanguage());
558 
559   // Don't support optimized code for now, DebugInfoPDB does not return this
560   // information.
561   LazyBool optimized = eLazyBoolNo;
562   auto result = std::make_shared<CompileUnit>(
563       m_obj_file->GetModule(), nullptr, path.c_str(), id, lang, optimized);
564   m_comp_units.insert(std::make_pair(id, result));
565   return result;
566 }
567 
568 bool SymbolFilePDB::ParseCompileUnitLineTable(
569     const lldb_private::SymbolContext &sc, uint32_t match_line) {
570   auto global = m_session_up->getGlobalScope();
571   auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(
572       sc.comp_unit->GetID());
573 
574   // LineEntry needs the *index* of the file into the list of support files
575   // returned by ParseCompileUnitSupportFiles.  But the underlying SDK gives us
576   // a globally unique idenfitifier in the namespace of the PDB.  So, we have to
577   // do a mapping so that we can hand out indices.
578   llvm::DenseMap<uint32_t, uint32_t> index_map;
579   BuildSupportFileIdToSupportFileIndexMap(*cu, index_map);
580   auto line_table = llvm::make_unique<LineTable>(sc.comp_unit);
581 
582   // Find contributions to `cu` from all source and header files.
583   std::string path = sc.comp_unit->GetPath();
584   auto files = m_session_up->getSourceFilesForCompiland(*cu);
585 
586   // For each source and header file, create a LineSequence for contributions to
587   // the cu from that file, and add the sequence.
588   while (auto file = files->getNext()) {
589     std::unique_ptr<LineSequence> sequence(
590         line_table->CreateLineSequenceContainer());
591     auto lines = m_session_up->findLineNumbers(*cu, *file);
592     int entry_count = lines->getChildCount();
593 
594     uint64_t prev_addr;
595     uint32_t prev_length;
596     uint32_t prev_line;
597     uint32_t prev_source_idx;
598 
599     for (int i = 0; i < entry_count; ++i) {
600       auto line = lines->getChildAtIndex(i);
601 
602       uint64_t lno = line->getLineNumber();
603       uint64_t addr = line->getVirtualAddress();
604       uint32_t length = line->getLength();
605       uint32_t source_id = line->getSourceFileId();
606       uint32_t col = line->getColumnNumber();
607       uint32_t source_idx = index_map[source_id];
608 
609       // There was a gap between the current entry and the previous entry if the
610       // addresses don't perfectly line up.
611       bool is_gap = (i > 0) && (prev_addr + prev_length < addr);
612 
613       // Before inserting the current entry, insert a terminal entry at the end
614       // of the previous entry's address range if the current entry resulted in
615       // a gap from the previous entry.
616       if (is_gap && ShouldAddLine(match_line, prev_line, prev_length)) {
617         line_table->AppendLineEntryToSequence(
618             sequence.get(), prev_addr + prev_length, prev_line, 0,
619             prev_source_idx, false, false, false, false, true);
620       }
621 
622       if (ShouldAddLine(match_line, lno, length)) {
623         bool is_statement = line->isStatement();
624         bool is_prologue = false;
625         bool is_epilogue = false;
626         auto func =
627             m_session_up->findSymbolByAddress(addr, PDB_SymType::Function);
628         if (func) {
629           auto prologue = func->findOneChild<PDBSymbolFuncDebugStart>();
630           is_prologue = (addr == prologue->getVirtualAddress());
631 
632           auto epilogue = func->findOneChild<PDBSymbolFuncDebugEnd>();
633           is_epilogue = (addr == epilogue->getVirtualAddress());
634         }
635 
636         line_table->AppendLineEntryToSequence(sequence.get(), addr, lno, col,
637                                               source_idx, is_statement, false,
638                                               is_prologue, is_epilogue, false);
639       }
640 
641       prev_addr = addr;
642       prev_length = length;
643       prev_line = lno;
644       prev_source_idx = source_idx;
645     }
646 
647     if (entry_count > 0 && ShouldAddLine(match_line, prev_line, prev_length)) {
648       // The end is always a terminal entry, so insert it regardless.
649       line_table->AppendLineEntryToSequence(
650           sequence.get(), prev_addr + prev_length, prev_line, 0,
651           prev_source_idx, false, false, false, false, true);
652     }
653 
654     line_table->InsertSequence(sequence.release());
655   }
656 
657   sc.comp_unit->SetLineTable(line_table.release());
658   return true;
659 }
660 
661 void SymbolFilePDB::BuildSupportFileIdToSupportFileIndexMap(
662     const PDBSymbolCompiland &cu,
663     llvm::DenseMap<uint32_t, uint32_t> &index_map) const {
664   // This is a hack, but we need to convert the source id into an index into the
665   // support files array.  We don't want to do path comparisons to avoid
666   // basename / full path issues that may or may not even be a problem, so we
667   // use the globally unique source file identifiers.  Ideally we could use the
668   // global identifiers everywhere, but LineEntry currently assumes indices.
669   auto source_files = m_session_up->getSourceFilesForCompiland(cu);
670   int index = 0;
671 
672   while (auto file = source_files->getNext()) {
673     uint32_t source_id = file->getUniqueId();
674     index_map[source_id] = index++;
675   }
676 }
677