diff options
Diffstat (limited to 'include/llvm/DebugInfo/CodeView')
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; |