14#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
15#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
16#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
17#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
18#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
19#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
20#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
21#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
22#include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h"
23#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
24#include "llvm/Support/Path.h"
34static bool IsMainFile(llvm::StringRef main, llvm::StringRef other) {
41 if (llvm::sys::fs::equivalent(main, other))
44 llvm::SmallString<64> normalized(other);
45 llvm::sys::path::native(normalized);
46 return main.equals_insensitive(normalized);
52 SymbolDeserializer::deserializeAs<Compile3Sym>(sym, *cci.
m_compile_opts));
58 SymbolDeserializer::deserializeAs<ObjNameSym>(sym, *cci.
m_obj_name));
63 BuildInfoSym bis(SymbolRecordKind::BuildInfoSym);
64 llvm::cantFail(SymbolDeserializer::deserializeAs<BuildInfoSym>(sym, bis));
68 LazyRandomTypeCollection &types = index.
ipi().typeCollection();
69 std::optional<CVType> cvt = types.tryGetType(bis.BuildId);
71 if (!cvt || cvt->kind() != LF_BUILDINFO)
75 llvm::cantFail(TypeDeserializer::deserializeAs<BuildInfoRecord>(*cvt, bir));
76 cci.
m_build_info.assign(bir.ArgIndices.begin(), bir.ArgIndices.end());
90 for (
const CVSymbol &sym : syms) {
110 for (
const auto &ss : item.
m_debug_stream.getSubsectionsArray()) {
111 if (ss.kind() != DebugSubsectionKind::InlineeLines)
114 DebugInlineeLinesSubsectionRef inlinee_lines;
115 llvm::BinaryStreamReader reader(ss.getRecordData());
116 if (llvm::Error
error = inlinee_lines.initialize(reader)) {
117 consumeError(std::move(
error));
121 for (
const InlineeSourceLine &Line : inlinee_lines) {
129 llvm::pdb::DbiModuleDescriptor descriptor)
130 : m_id(
id), m_debug_stream(std::move(debug_stream)),
131 m_module_descriptor(std::move(descriptor)) {}
136 return *result.first->second;
140 const DbiModuleList &modules =
m_index.
dbi().modules();
141 llvm::pdb::DbiModuleDescriptor descriptor = modules.getModuleDescriptor(modi);
142 uint16_t stream = descriptor.getModuleStreamIndex();
143 std::unique_ptr<llvm::msf::MappedBlockStream> stream_data =
147 std::unique_ptr<CompilandIndexItem>& cci = result.first->second;
150 llvm::pdb::ModuleDebugStreamRef debug_stream(descriptor,
nullptr);
151 cci = std::make_unique<CompilandIndexItem>(
PdbCompilandId{ modi }, debug_stream, std::move(descriptor));
155 llvm::pdb::ModuleDebugStreamRef debug_stream(descriptor,
156 std::move(stream_data));
158 cantFail(debug_stream.reload());
160 cci = std::make_unique<CompilandIndexItem>(
161 PdbCompilandId{modi}, std::move(debug_stream), std::move(descriptor));
165 auto strings =
m_index.
pdb().getStringTable();
167 cci->m_strings.initialize(cci->m_debug_stream.getSubsectionsArray());
168 cci->m_strings.setStrings(strings->getStringTable());
170 consumeError(strings.takeError());
180 std::string s = std::string(main_file.str());
181 llvm::sys::path::native(main_file);
183 uint32_t file_count = modules.getSourceFileCount(modi);
184 cci->m_file_list.reserve(file_count);
185 bool found_main_file =
false;
186 for (llvm::StringRef file : modules.source_files(modi)) {
187 if (!found_main_file &&
IsMainFile(main_file, file)) {
188 cci->m_file_list.insert(cci->m_file_list.begin(), file);
189 found_main_file =
true;
192 cci->m_file_list.push_back(file);
202 return iter->second.get();
209 return iter->second.get();
228 LazyRandomTypeCollection &types =
m_index.
ipi().typeCollection();
230 StringIdRecord working_dir;
231 StringIdRecord file_name;
235 TypeDeserializer::deserializeAs<StringIdRecord>(dir_cvt, working_dir));
237 TypeDeserializer::deserializeAs<StringIdRecord>(file_cvt, file_name));
239 llvm::sys::path::Style style = working_dir.String.starts_with(
"/")
240 ? llvm::sys::path::Style::posix
241 : llvm::sys::path::Style::windows;
242 if (llvm::sys::path::is_absolute(file_name.String, style))
243 return file_name.String;
245 llvm::SmallString<64> absolute_path = working_dir.String;
246 llvm::sys::path::append(absolute_path, file_name.String);
247 return absolute_path;
static llvm::raw_ostream & error(Stream &strm)
static void ParseBuildInfo(PdbIndex &index, const CVSymbol &sym, CompilandIndexItem &cci)
static void ParseObjname(const CVSymbol &sym, CompilandIndexItem &cci)
static bool IsMainFile(llvm::StringRef main, llvm::StringRef other)
static void ParseExtendedInfo(PdbIndex &index, CompilandIndexItem &item)
static void ParseInlineeLineTableForCompileUnit(CompilandIndexItem &item)
static void ParseCompile3(const CVSymbol &sym, CompilandIndexItem &cci)
llvm::DenseMap< uint16_t, std::unique_ptr< CompilandIndexItem > > m_comp_units
CompilandIndexItem & GetOrCreateCompiland(uint16_t modi)
llvm::SmallString< 64 > GetMainSourceFile(const CompilandIndexItem &item) const
const CompilandIndexItem * GetCompiland(uint16_t modi) const
PdbIndex - Lazy access to the important parts of a PDB file.
llvm::pdb::TpiStream & ipi()
llvm::pdb::DbiStream & dbi()
llvm::pdb::PDBFile & pdb()
A class that represents a running process on the host machine.
Represents a single compile unit.
std::map< llvm::codeview::TypeIndex, llvm::codeview::InlineeSourceLine > m_inline_map
llvm::SmallVector< llvm::codeview::TypeIndex, 5 > m_build_info
CompilandIndexItem(PdbCompilandId m_id, llvm::pdb::ModuleDebugStreamRef debug_stream, llvm::pdb::DbiModuleDescriptor descriptor)
std::optional< llvm::codeview::ObjNameSym > m_obj_name
std::optional< llvm::codeview::Compile3Sym > m_compile_opts
llvm::pdb::ModuleDebugStreamRef m_debug_stream