summaryrefslogtreecommitdiff
path: root/include/llvm/DebugInfo/CodeView
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/DebugInfo/CodeView')
-rw-r--r--include/llvm/DebugInfo/CodeView/CVRecord.h6
-rw-r--r--include/llvm/DebugInfo/CodeView/CodeView.h18
-rw-r--r--include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h4
-rw-r--r--include/llvm/DebugInfo/CodeView/DebugCrossExSubsection.h64
-rw-r--r--include/llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h88
-rw-r--r--include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h7
-rw-r--r--include/llvm/DebugInfo/CodeView/DebugLinesSubsection.h10
-rw-r--r--include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h3
-rw-r--r--include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h14
-rw-r--r--include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h128
-rw-r--r--include/llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h59
-rw-r--r--include/llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h3
-rw-r--r--include/llvm/DebugInfo/CodeView/EnumTables.h2
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeSerializer.h2
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeTableBuilder.h5
15 files changed, 369 insertions, 44 deletions
diff --git a/include/llvm/DebugInfo/CodeView/CVRecord.h b/include/llvm/DebugInfo/CodeView/CVRecord.h
index 68ad09982202..4c6bbedc6bbd 100644
--- a/include/llvm/DebugInfo/CodeView/CVRecord.h
+++ b/include/llvm/DebugInfo/CodeView/CVRecord.h
@@ -62,10 +62,8 @@ template <typename Kind> struct RemappedRecord {
template <typename Kind>
struct VarStreamArrayExtractor<codeview::CVRecord<Kind>> {
- typedef void ContextType;
-
- static Error extract(BinaryStreamRef Stream, uint32_t &Len,
- codeview::CVRecord<Kind> &Item) {
+ Error operator()(BinaryStreamRef Stream, uint32_t &Len,
+ codeview::CVRecord<Kind> &Item) {
using namespace codeview;
const RecordPrefix *Prefix = nullptr;
BinaryStreamReader Reader(Stream);
diff --git a/include/llvm/DebugInfo/CodeView/CodeView.h b/include/llvm/DebugInfo/CodeView/CodeView.h
index 9890263ae2d2..251c9d1ae62c 100644
--- a/include/llvm/DebugInfo/CodeView/CodeView.h
+++ b/include/llvm/DebugInfo/CodeView/CodeView.h
@@ -575,6 +575,24 @@ struct FrameData {
};
};
+// Corresponds to LocalIdAndGlobalIdPair structure.
+// This structure information allows cross-referencing between PDBs. For
+// example, when a PDB is being built during compilation it is not yet known
+// what other modules may end up in the PDB at link time. So certain types of
+// IDs may clash between the various compile time PDBs. For each affected
+// module, a subsection would be put into the PDB containing a mapping from its
+// local IDs to a single ID namespace for all items in the PDB file.
+struct CrossModuleExport {
+ support::ulittle32_t Local;
+ support::ulittle32_t Global;
+};
+
+struct CrossModuleImport {
+ support::ulittle32_t ModuleNameOffset;
+ support::ulittle32_t Count; // Number of elements
+ // support::ulittle32_t ids[Count]; // id from referenced module
+};
+
enum class CodeViewContainer { ObjectFile, Pdb };
inline uint32_t alignOf(CodeViewContainer Container) {
diff --git a/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h b/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h
index c958a95ee6de..9fc90f13d347 100644
--- a/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h
+++ b/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h
@@ -36,8 +36,8 @@ template <> struct VarStreamArrayExtractor<codeview::FileChecksumEntry> {
public:
typedef void ContextType;
- static Error extract(BinaryStreamRef Stream, uint32_t &Len,
- codeview::FileChecksumEntry &Item);
+ Error operator()(BinaryStreamRef Stream, uint32_t &Len,
+ codeview::FileChecksumEntry &Item);
};
}
diff --git a/include/llvm/DebugInfo/CodeView/DebugCrossExSubsection.h b/include/llvm/DebugInfo/CodeView/DebugCrossExSubsection.h
new file mode 100644
index 000000000000..f755b23422c7
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/DebugCrossExSubsection.h
@@ -0,0 +1,64 @@
+//===- DebugCrossExSubsection.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGCROSSEXSUBSECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGCROSSEXSUBSECTION_H
+
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Endian.h"
+
+#include <map>
+
+namespace llvm {
+namespace codeview {
+class DebugCrossModuleExportsSubsectionRef final : public DebugSubsectionRef {
+ typedef FixedStreamArray<CrossModuleExport> ReferenceArray;
+ typedef ReferenceArray::Iterator Iterator;
+
+public:
+ DebugCrossModuleExportsSubsectionRef()
+ : DebugSubsectionRef(DebugSubsectionKind::CrossScopeExports) {}
+
+ static bool classof(const DebugSubsectionRef *S) {
+ return S->kind() == DebugSubsectionKind::CrossScopeExports;
+ }
+
+ Error initialize(BinaryStreamReader Reader);
+ Error initialize(BinaryStreamRef Stream);
+
+ Iterator begin() const { return References.begin(); }
+ Iterator end() const { return References.end(); }
+
+private:
+ FixedStreamArray<CrossModuleExport> References;
+};
+
+class DebugCrossModuleExportsSubsection final : public DebugSubsection {
+public:
+ DebugCrossModuleExportsSubsection()
+ : DebugSubsection(DebugSubsectionKind::CrossScopeExports) {}
+
+ static bool classof(const DebugSubsection *S) {
+ return S->kind() == DebugSubsectionKind::CrossScopeExports;
+ }
+
+ void addMapping(uint32_t Local, uint32_t Global);
+
+ uint32_t calculateSerializedSize() const override;
+ Error commit(BinaryStreamWriter &Writer) const override;
+
+private:
+ std::map<uint32_t, uint32_t> Mappings;
+};
+}
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h b/include/llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h
new file mode 100644
index 000000000000..ea3a9a43d50b
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h
@@ -0,0 +1,88 @@
+//===- DebugCrossExSubsection.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGCROSSIMPSUBSECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGCROSSIMPSUBSECTION_H
+
+#include "llvm/ADT/StringMap.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Endian.h"
+
+namespace llvm {
+namespace codeview {
+
+struct CrossModuleImportItem {
+ const CrossModuleImport *Header = nullptr;
+ llvm::FixedStreamArray<support::ulittle32_t> Imports;
+};
+}
+}
+
+namespace llvm {
+template <> struct VarStreamArrayExtractor<codeview::CrossModuleImportItem> {
+public:
+ typedef void ContextType;
+
+ Error operator()(BinaryStreamRef Stream, uint32_t &Len,
+ codeview::CrossModuleImportItem &Item);
+};
+}
+
+namespace llvm {
+namespace codeview {
+class DebugStringTableSubsection;
+
+class DebugCrossModuleImportsSubsectionRef final : public DebugSubsectionRef {
+ typedef VarStreamArray<CrossModuleImportItem> ReferenceArray;
+ typedef ReferenceArray::Iterator Iterator;
+
+public:
+ DebugCrossModuleImportsSubsectionRef()
+ : DebugSubsectionRef(DebugSubsectionKind::CrossScopeImports) {}
+
+ static bool classof(const DebugSubsectionRef *S) {
+ return S->kind() == DebugSubsectionKind::CrossScopeImports;
+ }
+
+ Error initialize(BinaryStreamReader Reader);
+ Error initialize(BinaryStreamRef Stream);
+
+ Iterator begin() const { return References.begin(); }
+ Iterator end() const { return References.end(); }
+
+private:
+ ReferenceArray References;
+};
+
+class DebugCrossModuleImportsSubsection final : public DebugSubsection {
+public:
+ explicit DebugCrossModuleImportsSubsection(
+ DebugStringTableSubsection &Strings)
+ : DebugSubsection(DebugSubsectionKind::CrossScopeImports),
+ Strings(Strings) {}
+
+ static bool classof(const DebugSubsection *S) {
+ return S->kind() == DebugSubsectionKind::CrossScopeImports;
+ }
+
+ void addImport(StringRef Module, uint32_t ImportId);
+
+ uint32_t calculateSerializedSize() const override;
+ Error commit(BinaryStreamWriter &Writer) const override;
+
+private:
+ DebugStringTableSubsection &Strings;
+ StringMap<std::vector<support::ulittle32_t>> Mappings;
+};
+}
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h b/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h
index 60440700c265..c9b062717baa 100644
--- a/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h
+++ b/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h
@@ -43,10 +43,9 @@ struct InlineeSourceLine {
}
template <> struct VarStreamArrayExtractor<codeview::InlineeSourceLine> {
- typedef bool ContextType;
-
- static Error extract(BinaryStreamRef Stream, uint32_t &Len,
- codeview::InlineeSourceLine &Item, bool HasExtraFiles);
+ Error operator()(BinaryStreamRef Stream, uint32_t &Len,
+ codeview::InlineeSourceLine &Item);
+ bool HasExtraFiles = false;
};
namespace codeview {
diff --git a/include/llvm/DebugInfo/CodeView/DebugLinesSubsection.h b/include/llvm/DebugInfo/CodeView/DebugLinesSubsection.h
index 1b63af59c2ed..f1feb1336cc5 100644
--- a/include/llvm/DebugInfo/CodeView/DebugLinesSubsection.h
+++ b/include/llvm/DebugInfo/CodeView/DebugLinesSubsection.h
@@ -64,10 +64,10 @@ struct LineColumnEntry {
class LineColumnExtractor {
public:
- typedef const LineFragmentHeader *ContextType;
+ Error operator()(BinaryStreamRef Stream, uint32_t &Len,
+ LineColumnEntry &Item);
- static Error extract(BinaryStreamRef Stream, uint32_t &Len,
- LineColumnEntry &Item, const LineFragmentHeader *Ctx);
+ const LineFragmentHeader *Header = nullptr;
};
class DebugLinesSubsectionRef final : public DebugSubsectionRef {
@@ -122,7 +122,7 @@ public:
uint32_t calculateSerializedSize() const override;
Error commit(BinaryStreamWriter &Writer) const override;
- void setRelocationAddress(uint16_t Segment, uint16_t Offset);
+ void setRelocationAddress(uint16_t Segment, uint32_t Offset);
void setCodeSize(uint32_t Size);
void setFlags(LineFlags Flags);
@@ -131,7 +131,7 @@ public:
private:
DebugChecksumsSubsection &Checksums;
- uint16_t RelocOffset = 0;
+ uint32_t RelocOffset = 0;
uint16_t RelocSegment = 0;
uint32_t CodeSize = 0;
LineFlags Flags = LF_None;
diff --git a/include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h b/include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h
index fbe39cb16f09..be0a2344965b 100644
--- a/include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h
+++ b/include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h
@@ -39,11 +39,14 @@ public:
}
Error initialize(BinaryStreamRef Contents);
+ Error initialize(BinaryStreamReader &Reader);
Expected<StringRef> getString(uint32_t Offset) const;
bool valid() const { return Stream.valid(); }
+ BinaryStreamRef getBuffer() const { return Stream; }
+
private:
BinaryStreamRef Stream;
};
diff --git a/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h b/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h
index 847259c5ceac..49a269d92e35 100644
--- a/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h
+++ b/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h
@@ -52,7 +52,7 @@ public:
DebugSubsectionRecordBuilder(std::unique_ptr<DebugSubsection> Subsection,
CodeViewContainer Container);
uint32_t calculateSerializedLength();
- Error commit(BinaryStreamWriter &Writer);
+ Error commit(BinaryStreamWriter &Writer) const;
private:
std::unique_ptr<DebugSubsection> Subsection;
@@ -62,18 +62,12 @@ private:
} // namespace codeview
template <> struct VarStreamArrayExtractor<codeview::DebugSubsectionRecord> {
- typedef void ContextType;
-
- static Error extract(BinaryStreamRef Stream, uint32_t &Length,
- codeview::DebugSubsectionRecord &Info) {
- // FIXME: We need to pass the container type through to this function, but
- // VarStreamArray doesn't easily support stateful contexts. In practice
- // this isn't super important since the subsection header describes its
- // length and we can just skip it. It's more important when writing.
+ Error operator()(BinaryStreamRef Stream, uint32_t &Length,
+ codeview::DebugSubsectionRecord &Info) {
if (auto EC = codeview::DebugSubsectionRecord::initialize(
Stream, Info, codeview::CodeViewContainer::Pdb))
return EC;
- Length = Info.getRecordLength();
+ Length = alignTo(Info.getRecordLength(), 4);
return Error::success();
}
};
diff --git a/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h b/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h
index 55bef491c97e..d4a3d9195a36 100644
--- a/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h
+++ b/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h
@@ -10,6 +10,8 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTVISITOR_H
#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTVISITOR_H
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
#include "llvm/Support/Error.h"
#include <cstdint>
@@ -20,9 +22,65 @@ namespace codeview {
class DebugChecksumsSubsectionRef;
class DebugSubsectionRecord;
class DebugInlineeLinesSubsectionRef;
+class DebugCrossModuleExportsSubsectionRef;
+class DebugCrossModuleImportsSubsectionRef;
+class DebugFrameDataSubsectionRef;
class DebugLinesSubsectionRef;
+class DebugStringTableSubsectionRef;
+class DebugSymbolRVASubsectionRef;
+class DebugSymbolsSubsectionRef;
class DebugUnknownSubsectionRef;
+struct DebugSubsectionState {
+public:
+ // If no subsections are known about initially, we find as much as we can.
+ DebugSubsectionState();
+
+ // If only a string table subsection is given, we find a checksums subsection.
+ explicit DebugSubsectionState(const DebugStringTableSubsectionRef &Strings);
+
+ // If both subsections are given, we don't need to find anything.
+ DebugSubsectionState(const DebugStringTableSubsectionRef &Strings,
+ const DebugChecksumsSubsectionRef &Checksums);
+
+ template <typename T> void initialize(T &&FragmentRange) {
+ for (const DebugSubsectionRecord &R : FragmentRange) {
+ if (Strings && Checksums)
+ return;
+ if (R.kind() == DebugSubsectionKind::FileChecksums) {
+ initializeChecksums(R);
+ continue;
+ }
+ if (R.kind() == DebugSubsectionKind::StringTable && !Strings) {
+ // While in practice we should never encounter a string table even
+ // though the string table is already initialized, in theory it's
+ // possible. PDBs are supposed to have one global string table and
+ // then this subsection should not appear. Whereas object files are
+ // supposed to have this subsection appear exactly once. However,
+ // for testing purposes it's nice to be able to test this subsection
+ // independently of one format or the other, so for some tests we
+ // manually construct a PDB that contains this subsection in addition
+ // to a global string table.
+ initializeStrings(R);
+ continue;
+ }
+ }
+ }
+
+ const DebugStringTableSubsectionRef &strings() const { return *Strings; }
+ const DebugChecksumsSubsectionRef &checksums() const { return *Checksums; }
+
+private:
+ void initializeStrings(const DebugSubsectionRecord &SR);
+ void initializeChecksums(const DebugSubsectionRecord &FCR);
+
+ std::unique_ptr<DebugStringTableSubsectionRef> OwnedStrings;
+ std::unique_ptr<DebugChecksumsSubsectionRef> OwnedChecksums;
+
+ const DebugStringTableSubsectionRef *Strings = nullptr;
+ const DebugChecksumsSubsectionRef *Checksums = nullptr;
+};
+
class DebugSubsectionVisitor {
public:
virtual ~DebugSubsectionVisitor() = default;
@@ -30,34 +88,72 @@ public:
virtual Error visitUnknown(DebugUnknownSubsectionRef &Unknown) {
return Error::success();
}
- virtual Error visitLines(DebugLinesSubsectionRef &Lines) {
- return Error::success();
- }
+ virtual Error visitLines(DebugLinesSubsectionRef &Lines,
+ const DebugSubsectionState &State) = 0;
+ virtual Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums,
+ const DebugSubsectionState &State) = 0;
+ virtual Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees,
+ const DebugSubsectionState &State) = 0;
+ virtual Error
+ visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef &CSE,
+ const DebugSubsectionState &State) = 0;
+ virtual Error
+ visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &CSE,
+ const DebugSubsectionState &State) = 0;
- virtual Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums) {
- return Error::success();
- }
+ virtual Error visitStringTable(DebugStringTableSubsectionRef &ST,
+ const DebugSubsectionState &State) = 0;
- virtual Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees) {
- return Error::success();
- }
+ virtual Error visitSymbols(DebugSymbolsSubsectionRef &CSE,
+ const DebugSubsectionState &State) = 0;
- virtual Error finished() { return Error::success(); }
+ virtual Error visitFrameData(DebugFrameDataSubsectionRef &FD,
+ const DebugSubsectionState &State) = 0;
+ virtual Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &RVAs,
+ const DebugSubsectionState &State) = 0;
};
Error visitDebugSubsection(const DebugSubsectionRecord &R,
- DebugSubsectionVisitor &V);
+ DebugSubsectionVisitor &V,
+ const DebugSubsectionState &State);
+namespace detail {
template <typename T>
-Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V) {
- for (const auto &L : FragmentRange) {
- if (auto EC = visitDebugSubsection(L, V))
+Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V,
+ DebugSubsectionState &State) {
+ State.initialize(std::forward<T>(FragmentRange));
+
+ for (const DebugSubsectionRecord &L : FragmentRange) {
+ if (auto EC = visitDebugSubsection(L, V, State))
return EC;
}
- if (auto EC = V.finished())
- return EC;
return Error::success();
}
+} // namespace detail
+
+template <typename T>
+Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V) {
+ DebugSubsectionState State;
+ return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V,
+ State);
+}
+
+template <typename T>
+Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V,
+ const DebugStringTableSubsectionRef &Strings) {
+ DebugSubsectionState State(Strings);
+ return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V,
+ State);
+}
+
+template <typename T>
+Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V,
+ const DebugStringTableSubsectionRef &Strings,
+ const DebugChecksumsSubsectionRef &Checksums) {
+ DebugSubsectionState State(Strings, Checksums);
+ return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V,
+ State);
+}
} // end namespace codeview
diff --git a/include/llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h b/include/llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h
new file mode 100644
index 000000000000..ad58a293cb09
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h
@@ -0,0 +1,59 @@
+//===- DebugSymbolRVASubsection.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGSYMBOLRVASUBSECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGSYMBOLRVASUBSECTION_H
+
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace codeview {
+
+class DebugSymbolRVASubsectionRef final : public DebugSubsectionRef {
+public:
+ typedef FixedStreamArray<support::ulittle32_t> ArrayType;
+
+ DebugSymbolRVASubsectionRef();
+
+ static bool classof(const DebugSubsectionRef *S) {
+ return S->kind() == DebugSubsectionKind::CoffSymbolRVA;
+ }
+
+ ArrayType::Iterator begin() const { return RVAs.begin(); }
+ ArrayType::Iterator end() const { return RVAs.end(); }
+
+ Error initialize(BinaryStreamReader &Reader);
+
+private:
+ ArrayType RVAs;
+};
+
+class DebugSymbolRVASubsection final : public DebugSubsection {
+public:
+ DebugSymbolRVASubsection();
+
+ static bool classof(const DebugSubsection *S) {
+ return S->kind() == DebugSubsectionKind::CoffSymbolRVA;
+ }
+
+ Error commit(BinaryStreamWriter &Writer) const override;
+ uint32_t calculateSerializedSize() const override;
+
+ void addRVA(uint32_t RVA) { RVAs.push_back(support::ulittle32_t(RVA)); }
+
+private:
+ std::vector<support::ulittle32_t> RVAs;
+};
+} // namespace codeview
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h b/include/llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h
index 3d1eb27ba270..dfda7deb6cb4 100644
--- a/include/llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h
+++ b/include/llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h
@@ -27,6 +27,9 @@ public:
Error initialize(BinaryStreamReader Reader);
+ CVSymbolArray::Iterator begin() const { return Records.begin(); }
+ CVSymbolArray::Iterator end() const { return Records.end(); }
+
private:
CVSymbolArray Records;
};
diff --git a/include/llvm/DebugInfo/CodeView/EnumTables.h b/include/llvm/DebugInfo/CodeView/EnumTables.h
index 10d1c581a196..013e440613fc 100644
--- a/include/llvm/DebugInfo/CodeView/EnumTables.h
+++ b/include/llvm/DebugInfo/CodeView/EnumTables.h
@@ -11,8 +11,8 @@
#define LLVM_DEBUGINFO_CODEVIEW_ENUMTABLES_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/BinaryFormat/COFF.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/Support/COFF.h"
#include "llvm/Support/ScopedPrinter.h"
#include <stdint.h>
diff --git a/include/llvm/DebugInfo/CodeView/TypeSerializer.h b/include/llvm/DebugInfo/CodeView/TypeSerializer.h
index 1dee86a1da79..f785d4509547 100644
--- a/include/llvm/DebugInfo/CodeView/TypeSerializer.h
+++ b/include/llvm/DebugInfo/CodeView/TypeSerializer.h
@@ -86,6 +86,8 @@ public:
void reset();
+ BumpPtrAllocator &getAllocator() { return RecordStorage; }
+
ArrayRef<ArrayRef<uint8_t>> records() const;
TypeIndex insertRecordBytes(ArrayRef<uint8_t> &Record);
TypeIndex insertRecord(const RemappedType &Record);
diff --git a/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h b/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h
index 907ed1010e5b..1069dcd45334 100644
--- a/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h
+++ b/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h
@@ -37,8 +37,9 @@ private:
TypeSerializer Serializer;
public:
- explicit TypeTableBuilder(BumpPtrAllocator &Allocator)
- : Allocator(Allocator), Serializer(Allocator) {}
+ explicit TypeTableBuilder(BumpPtrAllocator &Allocator,
+ bool WriteUnique = true)
+ : Allocator(Allocator), Serializer(Allocator, WriteUnique) {}
TypeTableBuilder(const TypeTableBuilder &) = delete;
TypeTableBuilder &operator=(const TypeTableBuilder &) = delete;