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