diff options
Diffstat (limited to 'include/llvm/DebugInfo/CodeView')
25 files changed, 265 insertions, 287 deletions
diff --git a/include/llvm/DebugInfo/CodeView/CVRecord.h b/include/llvm/DebugInfo/CodeView/CVRecord.h index a327d450db55..487f3b6446fa 100644 --- a/include/llvm/DebugInfo/CodeView/CVRecord.h +++ b/include/llvm/DebugInfo/CodeView/CVRecord.h @@ -14,8 +14,8 @@ #include "llvm/ADT/Optional.h" #include "llvm/DebugInfo/CodeView/CodeViewError.h" #include "llvm/DebugInfo/CodeView/RecordSerialization.h" -#include "llvm/DebugInfo/MSF/StreamReader.h" -#include "llvm/DebugInfo/MSF/StreamRef.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include <cstdint> @@ -48,15 +48,13 @@ public: } // end namespace codeview -namespace msf { - template <typename Kind> struct VarStreamArrayExtractor<codeview::CVRecord<Kind>> { - Error operator()(ReadableStreamRef Stream, uint32_t &Len, + Error operator()(BinaryStreamRef Stream, uint32_t &Len, codeview::CVRecord<Kind> &Item) const { using namespace codeview; const RecordPrefix *Prefix = nullptr; - StreamReader Reader(Stream); + BinaryStreamReader Reader(Stream); uint32_t Offset = Reader.getOffset(); if (auto EC = Reader.readObject(Prefix)) @@ -76,8 +74,6 @@ struct VarStreamArrayExtractor<codeview::CVRecord<Kind>> { } }; -} // end namespace msf - } // end namespace llvm #endif // LLVM_DEBUGINFO_CODEVIEW_RECORDITERATOR_H diff --git a/include/llvm/DebugInfo/CodeView/CVTypeDumper.h b/include/llvm/DebugInfo/CodeView/CVTypeDumper.h index e1dd6a10b5a1..02f14ea2107b 100644 --- a/include/llvm/DebugInfo/CodeView/CVTypeDumper.h +++ b/include/llvm/DebugInfo/CodeView/CVTypeDumper.h @@ -22,10 +22,14 @@ namespace llvm { namespace codeview { +class TypeServerHandler; + /// Dumper for CodeView type streams found in COFF object files and PDB files. class CVTypeDumper { public: - explicit CVTypeDumper(TypeDatabase &TypeDB) : TypeDB(TypeDB) {} + explicit CVTypeDumper(TypeDatabase &TypeDB, + TypeServerHandler *Handler = nullptr) + : TypeDB(TypeDB), Handler(Handler) {} /// Dumps one type record. Returns false if there was a type parsing error, /// and true otherwise. This should be called in order, since the dumper @@ -48,6 +52,7 @@ public: private: TypeDatabase &TypeDB; + TypeServerHandler *Handler; }; } // end namespace codeview diff --git a/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h b/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h index d1b0363a4133..e9012db7602d 100644 --- a/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h +++ b/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h @@ -10,9 +10,10 @@ #ifndef LLVM_DEBUGINFO_CODEVIEW_CVTYPEVISITOR_H #define LLVM_DEBUGINFO_CODEVIEW_CVTYPEVISITOR_H -#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/TinyPtrVector.h" #include "llvm/DebugInfo/CodeView/CVRecord.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/CodeView/TypeServerHandler.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" #include "llvm/Support/Error.h" @@ -23,18 +24,23 @@ class CVTypeVisitor { public: explicit CVTypeVisitor(TypeVisitorCallbacks &Callbacks); + void addTypeServerHandler(TypeServerHandler &Handler); + Error visitTypeRecord(CVType &Record); Error visitMemberRecord(CVMemberRecord &Record); /// Visits the type records in Data. Sets the error flag on parse failures. Error visitTypeStream(const CVTypeArray &Types); + Error visitTypeStream(CVTypeRange Types); Error visitFieldListMemberStream(ArrayRef<uint8_t> FieldList); - Error visitFieldListMemberStream(msf::StreamReader Reader); + Error visitFieldListMemberStream(BinaryStreamReader Reader); private: /// The interface to the class that gets notified of each visitation. TypeVisitorCallbacks &Callbacks; + + TinyPtrVector<TypeServerHandler *> Handlers; }; } // end namespace codeview diff --git a/include/llvm/DebugInfo/CodeView/CodeView.h b/include/llvm/DebugInfo/CodeView/CodeView.h index e21cfa3d030a..2791c9dc3746 100644 --- a/include/llvm/DebugInfo/CodeView/CodeView.h +++ b/include/llvm/DebugInfo/CodeView/CodeView.h @@ -275,6 +275,12 @@ enum class MethodOptions : uint16_t { }; CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(MethodOptions) +/// Equivalent to CV_LABEL_TYPE_e. +enum class LabelType : uint16_t { + Near = 0x0, + Far = 0x4, +}; + /// Equivalent to CV_modifier_t. /// TODO: Add flag for _Atomic modifier enum class ModifierOptions : uint16_t { diff --git a/include/llvm/DebugInfo/CodeView/CodeViewError.h b/include/llvm/DebugInfo/CodeView/CodeViewError.h index 0556fd0e19f2..586a720ce6e4 100644 --- a/include/llvm/DebugInfo/CodeView/CodeViewError.h +++ b/include/llvm/DebugInfo/CodeView/CodeViewError.h @@ -21,6 +21,7 @@ enum class cv_error_code { insufficient_buffer, operation_unsupported, corrupt_record, + no_records, unknown_member_record, }; diff --git a/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h b/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h index 5a036b9d5b6c..b3976826a316 100644 --- a/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h +++ b/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h @@ -17,8 +17,8 @@ #include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/CodeView/CodeViewError.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" -#include "llvm/DebugInfo/MSF/StreamReader.h" -#include "llvm/DebugInfo/MSF/StreamWriter.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/BinaryStreamWriter.h" #include "llvm/Support/Error.h" #include <cassert> #include <cstdint> @@ -33,8 +33,8 @@ class CodeViewRecordIO { } public: - explicit CodeViewRecordIO(msf::StreamReader &Reader) : Reader(&Reader) {} - explicit CodeViewRecordIO(msf::StreamWriter &Writer) : Writer(&Writer) {} + explicit CodeViewRecordIO(BinaryStreamReader &Reader) : Reader(&Reader) {} + explicit CodeViewRecordIO(BinaryStreamWriter &Writer) : Writer(&Writer) {} Error beginRecord(Optional<uint32_t> MaxLength); Error endRecord(); @@ -160,8 +160,8 @@ private: SmallVector<RecordLimit, 2> Limits; - msf::StreamReader *Reader = nullptr; - msf::StreamWriter *Writer = nullptr; + BinaryStreamReader *Reader = nullptr; + BinaryStreamWriter *Writer = nullptr; }; } // end namespace codeview diff --git a/include/llvm/DebugInfo/CodeView/Formatters.h b/include/llvm/DebugInfo/CodeView/Formatters.h new file mode 100644 index 000000000000..37a91098a8b6 --- /dev/null +++ b/include/llvm/DebugInfo/CodeView/Formatters.h @@ -0,0 +1,40 @@ +//===- Formatters.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_FORMATTERS_H +#define LLVM_DEBUGINFO_CODEVIEW_FORMATTERS_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/FormatAdapters.h" + +namespace llvm { +namespace codeview { +namespace detail { +class GuidAdapter final : public llvm::FormatAdapter<ArrayRef<uint8_t>> { + ArrayRef<uint8_t> Guid; + +public: + explicit GuidAdapter(ArrayRef<uint8_t> Guid); + explicit GuidAdapter(StringRef Guid); + void format(llvm::raw_ostream &Stream, StringRef Style); +}; +} + +inline detail::GuidAdapter fmt_guid(StringRef Item) { + return detail::GuidAdapter(Item); +} + +inline detail::GuidAdapter fmt_guid(ArrayRef<uint8_t> Item) { + return detail::GuidAdapter(Item); +} +} +} + +#endif diff --git a/include/llvm/DebugInfo/CodeView/ModuleSubstream.h b/include/llvm/DebugInfo/CodeView/ModuleSubstream.h index 8860ae42fc09..a1c5c93cc3f8 100644 --- a/include/llvm/DebugInfo/CodeView/ModuleSubstream.h +++ b/include/llvm/DebugInfo/CodeView/ModuleSubstream.h @@ -11,8 +11,8 @@ #define LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAM_H #include "llvm/DebugInfo/CodeView/CodeView.h" -#include "llvm/DebugInfo/MSF/StreamArray.h" -#include "llvm/DebugInfo/MSF/StreamRef.h" +#include "llvm/Support/BinaryStreamArray.h" +#include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" @@ -59,23 +59,22 @@ struct ColumnNumberEntry { class ModuleSubstream { public: ModuleSubstream(); - ModuleSubstream(ModuleSubstreamKind Kind, msf::ReadableStreamRef Data); - static Error initialize(msf::ReadableStreamRef Stream, ModuleSubstream &Info); + ModuleSubstream(ModuleSubstreamKind Kind, BinaryStreamRef Data); + static Error initialize(BinaryStreamRef Stream, ModuleSubstream &Info); uint32_t getRecordLength() const; ModuleSubstreamKind getSubstreamKind() const; - msf::ReadableStreamRef getRecordData() const; + BinaryStreamRef getRecordData() const; private: ModuleSubstreamKind Kind; - msf::ReadableStreamRef Data; + BinaryStreamRef Data; }; -typedef msf::VarStreamArray<ModuleSubstream> ModuleSubstreamArray; +typedef VarStreamArray<ModuleSubstream> ModuleSubstreamArray; } // namespace codeview -namespace msf { template <> struct VarStreamArrayExtractor<codeview::ModuleSubstream> { - Error operator()(ReadableStreamRef Stream, uint32_t &Length, + Error operator()(BinaryStreamRef Stream, uint32_t &Length, codeview::ModuleSubstream &Info) const { if (auto EC = codeview::ModuleSubstream::initialize(Stream, Info)) return EC; @@ -83,7 +82,6 @@ template <> struct VarStreamArrayExtractor<codeview::ModuleSubstream> { return Error::success(); } }; -} // namespace msf } // namespace llvm #endif // LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAM_H diff --git a/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h b/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h index f9927d660933..1a40654a3f33 100644 --- a/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h +++ b/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h @@ -15,9 +15,9 @@ #include "llvm/DebugInfo/CodeView/CodeViewError.h" #include "llvm/DebugInfo/CodeView/Line.h" #include "llvm/DebugInfo/CodeView/ModuleSubstream.h" -#include "llvm/DebugInfo/MSF/StreamArray.h" -#include "llvm/DebugInfo/MSF/StreamReader.h" -#include "llvm/DebugInfo/MSF/StreamRef.h" +#include "llvm/Support/BinaryStreamArray.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include <cstdint> @@ -28,8 +28,8 @@ namespace codeview { struct LineColumnEntry { support::ulittle32_t NameIndex; - msf::FixedStreamArray<LineNumberEntry> LineNumbers; - msf::FixedStreamArray<ColumnNumberEntry> Columns; + FixedStreamArray<LineNumberEntry> LineNumbers; + FixedStreamArray<ColumnNumberEntry> Columns; }; struct FileChecksumEntry { @@ -38,49 +38,47 @@ struct FileChecksumEntry { ArrayRef<uint8_t> Checksum; // The bytes of the checksum. }; -typedef msf::VarStreamArray<LineColumnEntry> LineInfoArray; -typedef msf::VarStreamArray<FileChecksumEntry> FileChecksumArray; +typedef VarStreamArray<LineColumnEntry> LineInfoArray; +typedef VarStreamArray<FileChecksumEntry> FileChecksumArray; class IModuleSubstreamVisitor { public: virtual ~IModuleSubstreamVisitor() = default; virtual Error visitUnknown(ModuleSubstreamKind Kind, - msf::ReadableStreamRef Data) = 0; - virtual Error visitSymbols(msf::ReadableStreamRef Data); - virtual Error visitLines(msf::ReadableStreamRef Data, + BinaryStreamRef Data) = 0; + virtual Error visitSymbols(BinaryStreamRef Data); + virtual Error visitLines(BinaryStreamRef Data, const LineSubstreamHeader *Header, const LineInfoArray &Lines); - virtual Error visitStringTable(msf::ReadableStreamRef Data); - virtual Error visitFileChecksums(msf::ReadableStreamRef Data, + virtual Error visitStringTable(BinaryStreamRef Data); + virtual Error visitFileChecksums(BinaryStreamRef Data, const FileChecksumArray &Checksums); - virtual Error visitFrameData(msf::ReadableStreamRef Data); - virtual Error visitInlineeLines(msf::ReadableStreamRef Data); - virtual Error visitCrossScopeImports(msf::ReadableStreamRef Data); - virtual Error visitCrossScopeExports(msf::ReadableStreamRef Data); - virtual Error visitILLines(msf::ReadableStreamRef Data); - virtual Error visitFuncMDTokenMap(msf::ReadableStreamRef Data); - virtual Error visitTypeMDTokenMap(msf::ReadableStreamRef Data); - virtual Error visitMergedAssemblyInput(msf::ReadableStreamRef Data); - virtual Error visitCoffSymbolRVA(msf::ReadableStreamRef Data); + virtual Error visitFrameData(BinaryStreamRef Data); + virtual Error visitInlineeLines(BinaryStreamRef Data); + virtual Error visitCrossScopeImports(BinaryStreamRef Data); + virtual Error visitCrossScopeExports(BinaryStreamRef Data); + virtual Error visitILLines(BinaryStreamRef Data); + virtual Error visitFuncMDTokenMap(BinaryStreamRef Data); + virtual Error visitTypeMDTokenMap(BinaryStreamRef Data); + virtual Error visitMergedAssemblyInput(BinaryStreamRef Data); + virtual Error visitCoffSymbolRVA(BinaryStreamRef Data); }; Error visitModuleSubstream(const ModuleSubstream &R, IModuleSubstreamVisitor &V); } // end namespace codeview -namespace msf { - template <> class VarStreamArrayExtractor<codeview::LineColumnEntry> { public: VarStreamArrayExtractor(const codeview::LineSubstreamHeader *Header) : Header(Header) {} - Error operator()(ReadableStreamRef Stream, uint32_t &Len, + Error operator()(BinaryStreamRef Stream, uint32_t &Len, codeview::LineColumnEntry &Item) const { using namespace codeview; const LineFileBlockHeader *BlockHeader; - StreamReader Reader(Stream); + BinaryStreamReader Reader(Stream); if (auto EC = Reader.readObject(BlockHeader)) return EC; bool HasColumn = Header->Flags & LineFlags::HaveColumns; @@ -113,11 +111,11 @@ private: template <> class VarStreamArrayExtractor<codeview::FileChecksumEntry> { public: - Error operator()(ReadableStreamRef Stream, uint32_t &Len, + Error operator()(BinaryStreamRef Stream, uint32_t &Len, codeview::FileChecksumEntry &Item) const { using namespace codeview; const FileChecksum *Header; - StreamReader Reader(Stream); + BinaryStreamReader Reader(Stream); if (auto EC = Reader.readObject(Header)) return EC; Item.FileNameOffset = Header->FileNameOffset; @@ -129,8 +127,6 @@ public: } }; -} // end namespace msf - } // end namespace llvm #endif // LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAMVISITOR_H diff --git a/include/llvm/DebugInfo/CodeView/RecordSerialization.h b/include/llvm/DebugInfo/CodeView/RecordSerialization.h index 97b6f561bb97..58449c2c7565 100644 --- a/include/llvm/DebugInfo/CodeView/RecordSerialization.h +++ b/include/llvm/DebugInfo/CodeView/RecordSerialization.h @@ -15,7 +15,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/CodeViewError.h" -#include "llvm/DebugInfo/MSF/StreamReader.h" +#include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include <cinttypes> @@ -41,37 +41,37 @@ struct RecordPrefix { StringRef getBytesAsCharacters(ArrayRef<uint8_t> LeafData); StringRef getBytesAsCString(ArrayRef<uint8_t> LeafData); -inline Error consume(msf::StreamReader &Reader) { return Error::success(); } +inline Error consume(BinaryStreamReader &Reader) { return Error::success(); } /// Decodes a numeric "leaf" value. These are integer literals encountered in /// the type stream. If the value is positive and less than LF_NUMERIC (1 << /// 15), it is emitted directly in Data. Otherwise, it has a tag like LF_CHAR /// that indicates the bitwidth and sign of the numeric data. -Error consume(msf::StreamReader &Reader, APSInt &Num); +Error consume(BinaryStreamReader &Reader, APSInt &Num); /// Decodes a numeric leaf value that is known to be a particular type. -Error consume_numeric(msf::StreamReader &Reader, uint64_t &Value); +Error consume_numeric(BinaryStreamReader &Reader, uint64_t &Value); /// Decodes signed and unsigned fixed-length integers. -Error consume(msf::StreamReader &Reader, uint32_t &Item); -Error consume(msf::StreamReader &Reader, int32_t &Item); +Error consume(BinaryStreamReader &Reader, uint32_t &Item); +Error consume(BinaryStreamReader &Reader, int32_t &Item); /// Decodes a null terminated string. -Error consume(msf::StreamReader &Reader, StringRef &Item); +Error consume(BinaryStreamReader &Reader, StringRef &Item); Error consume(StringRef &Data, APSInt &Num); Error consume(StringRef &Data, uint32_t &Item); /// Decodes an arbitrary object whose layout matches that of the underlying /// byte sequence, and returns a pointer to the object. -template <typename T> Error consume(msf::StreamReader &Reader, T *&Item) { +template <typename T> Error consume(BinaryStreamReader &Reader, T *&Item) { return Reader.readObject(Item); } template <typename T, typename U> struct serialize_conditional_impl { serialize_conditional_impl(T &Item, U Func) : Item(Item), Func(Func) {} - Error deserialize(msf::StreamReader &Reader) const { + Error deserialize(BinaryStreamReader &Reader) const { if (!Func()) return Error::success(); return consume(Reader, Item); @@ -89,7 +89,7 @@ serialize_conditional_impl<T, U> serialize_conditional(T &Item, U Func) { template <typename T, typename U> struct serialize_array_impl { serialize_array_impl(ArrayRef<T> &Item, U Func) : Item(Item), Func(Func) {} - Error deserialize(msf::StreamReader &Reader) const { + Error deserialize(BinaryStreamReader &Reader) const { return Reader.readArray(Item, Func()); } @@ -100,7 +100,7 @@ template <typename T, typename U> struct serialize_array_impl { template <typename T> struct serialize_vector_tail_impl { serialize_vector_tail_impl(std::vector<T> &Item) : Item(Item) {} - Error deserialize(msf::StreamReader &Reader) const { + Error deserialize(BinaryStreamReader &Reader) const { T Field; // Stop when we run out of bytes or we hit record padding bytes. while (!Reader.empty() && Reader.peek() < LF_PAD0) { @@ -118,14 +118,14 @@ struct serialize_null_term_string_array_impl { serialize_null_term_string_array_impl(std::vector<StringRef> &Item) : Item(Item) {} - Error deserialize(msf::StreamReader &Reader) const { + Error deserialize(BinaryStreamReader &Reader) const { if (Reader.empty()) return make_error<CodeViewError>(cv_error_code::insufficient_buffer, "Null terminated string is empty!"); while (Reader.peek() != 0) { StringRef Field; - if (auto EC = Reader.readZeroString(Field)) + if (auto EC = Reader.readCString(Field)) return EC; Item.push_back(Field); } @@ -138,7 +138,7 @@ struct serialize_null_term_string_array_impl { template <typename T> struct serialize_arrayref_tail_impl { serialize_arrayref_tail_impl(ArrayRef<T> &Item) : Item(Item) {} - Error deserialize(msf::StreamReader &Reader) const { + Error deserialize(BinaryStreamReader &Reader) const { uint32_t Count = Reader.bytesRemaining() / sizeof(T); return Reader.readArray(Item, Count); } @@ -149,7 +149,7 @@ template <typename T> struct serialize_arrayref_tail_impl { template <typename T> struct serialize_numeric_impl { serialize_numeric_impl(T &Item) : Item(Item) {} - Error deserialize(msf::StreamReader &Reader) const { + Error deserialize(BinaryStreamReader &Reader) const { return consume_numeric(Reader, Item); } @@ -201,42 +201,42 @@ template <typename T> serialize_numeric_impl<T> serialize_numeric(T &Item) { #define CV_NUMERIC_FIELD(I) serialize_numeric(I) template <typename T, typename U> -Error consume(msf::StreamReader &Reader, +Error consume(BinaryStreamReader &Reader, const serialize_conditional_impl<T, U> &Item) { return Item.deserialize(Reader); } template <typename T, typename U> -Error consume(msf::StreamReader &Reader, +Error consume(BinaryStreamReader &Reader, const serialize_array_impl<T, U> &Item) { return Item.deserialize(Reader); } -inline Error consume(msf::StreamReader &Reader, +inline Error consume(BinaryStreamReader &Reader, const serialize_null_term_string_array_impl &Item) { return Item.deserialize(Reader); } template <typename T> -Error consume(msf::StreamReader &Reader, +Error consume(BinaryStreamReader &Reader, const serialize_vector_tail_impl<T> &Item) { return Item.deserialize(Reader); } template <typename T> -Error consume(msf::StreamReader &Reader, +Error consume(BinaryStreamReader &Reader, const serialize_arrayref_tail_impl<T> &Item) { return Item.deserialize(Reader); } template <typename T> -Error consume(msf::StreamReader &Reader, +Error consume(BinaryStreamReader &Reader, const serialize_numeric_impl<T> &Item) { return Item.deserialize(Reader); } template <typename T, typename U, typename... Args> -Error consume(msf::StreamReader &Reader, T &&X, U &&Y, Args &&... Rest) { +Error consume(BinaryStreamReader &Reader, T &&X, U &&Y, Args &&... Rest) { if (auto EC = consume(Reader, X)) return EC; return consume(Reader, Y, std::forward<Args>(Rest)...); diff --git a/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h b/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h index 13c2bb14ecf5..c1a5152930ff 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h +++ b/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h @@ -15,8 +15,8 @@ #include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h" #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h" #include "llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h" -#include "llvm/DebugInfo/MSF/ByteStream.h" -#include "llvm/DebugInfo/MSF/StreamReader.h" +#include "llvm/Support/BinaryByteStream.h" +#include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/Error.h" namespace llvm { @@ -25,10 +25,11 @@ class SymbolVisitorDelegate; class SymbolDeserializer : public SymbolVisitorCallbacks { struct MappingInfo { explicit MappingInfo(ArrayRef<uint8_t> RecordData) - : Stream(RecordData), Reader(Stream), Mapping(Reader) {} + : Stream(RecordData, llvm::support::little), Reader(Stream), + Mapping(Reader) {} - msf::ByteStream Stream; - msf::StreamReader Reader; + BinaryByteStream Stream; + BinaryStreamReader Reader; SymbolRecordMapping Mapping; }; diff --git a/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/include/llvm/DebugInfo/CodeView/SymbolRecord.h index 57772d39e972..c5a5549bf818 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolRecord.h +++ b/include/llvm/DebugInfo/CodeView/SymbolRecord.h @@ -13,13 +13,13 @@ #include "llvm/ADT/APSInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" -#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/DebugInfo/CodeView/CVRecord.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/RecordSerialization.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" -#include "llvm/DebugInfo/MSF/StreamArray.h" +#include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include <cstddef> @@ -176,7 +176,7 @@ struct BinaryAnnotationIterator { return Data == Other.Data; } - bool operator!=(BinaryAnnotationIterator Other) const { + bool operator!=(const BinaryAnnotationIterator &Other) const { return !(*this == Other); } @@ -938,7 +938,7 @@ public: }; typedef CVRecord<SymbolKind> CVSymbol; -typedef msf::VarStreamArray<CVSymbol> CVSymbolArray; +typedef VarStreamArray<CVSymbol> CVSymbolArray; } // end namespace codeview } // end namespace llvm diff --git a/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h b/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h index 1bd14ed1347a..0a1837a0d935 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h +++ b/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h @@ -14,16 +14,14 @@ #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h" namespace llvm { -namespace msf { -class StreamReader; -class StreamWriter; -} +class BinaryStreamReader; +class BinaryStreamWriter; namespace codeview { class SymbolRecordMapping : public SymbolVisitorCallbacks { public: - explicit SymbolRecordMapping(msf::StreamReader &Reader) : IO(Reader) {} - explicit SymbolRecordMapping(msf::StreamWriter &Writer) : IO(Writer) {} + explicit SymbolRecordMapping(BinaryStreamReader &Reader) : IO(Reader) {} + explicit SymbolRecordMapping(BinaryStreamWriter &Writer) : IO(Writer) {} Error visitSymbolBegin(CVSymbol &Record) override; Error visitSymbolEnd(CVSymbol &Record) override; diff --git a/include/llvm/DebugInfo/CodeView/SymbolSerializer.h b/include/llvm/DebugInfo/CodeView/SymbolSerializer.h index 4eb914e7ae6b..f2e99bd83326 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolSerializer.h +++ b/include/llvm/DebugInfo/CodeView/SymbolSerializer.h @@ -12,8 +12,6 @@ #include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h" #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h" -#include "llvm/DebugInfo/MSF/ByteStream.h" -#include "llvm/DebugInfo/MSF/StreamWriter.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" @@ -21,14 +19,19 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/BinaryByteStream.h" +#include "llvm/Support/BinaryStreamWriter.h" #include "llvm/Support/Error.h" namespace llvm { +class BinaryStreamWriter; namespace codeview { class SymbolSerializer : public SymbolVisitorCallbacks { - uint32_t RecordStart = 0; - msf::StreamWriter &Writer; + BumpPtrAllocator &Storage; + std::vector<uint8_t> RecordBuffer; + MutableBinaryByteStream Stream; + BinaryStreamWriter Writer; SymbolRecordMapping Mapping; Optional<SymbolKind> CurrentSymbol; @@ -42,40 +45,10 @@ class SymbolSerializer : public SymbolVisitorCallbacks { } public: - explicit SymbolSerializer(msf::StreamWriter &Writer) - : Writer(Writer), Mapping(Writer) {} + explicit SymbolSerializer(BumpPtrAllocator &Storage); - virtual Error visitSymbolBegin(CVSymbol &Record) override { - assert(!CurrentSymbol.hasValue() && "Already in a symbol mapping!"); - - RecordStart = Writer.getOffset(); - if (auto EC = writeRecordPrefix(Record.kind())) - return EC; - - CurrentSymbol = Record.kind(); - if (auto EC = Mapping.visitSymbolBegin(Record)) - return EC; - - return Error::success(); - } - - virtual Error visitSymbolEnd(CVSymbol &Record) override { - assert(CurrentSymbol.hasValue() && "Not in a symbol mapping!"); - - if (auto EC = Mapping.visitSymbolEnd(Record)) - return EC; - - uint32_t RecordEnd = Writer.getOffset(); - Writer.setOffset(RecordStart); - uint16_t Length = RecordEnd - Writer.getOffset() - 2; - if (auto EC = Writer.writeInteger(Length)) - return EC; - - Writer.setOffset(RecordEnd); - CurrentSymbol.reset(); - - return Error::success(); - } + virtual Error visitSymbolBegin(CVSymbol &Record) override; + virtual Error visitSymbolEnd(CVSymbol &Record) override; #define SYMBOL_RECORD(EnumName, EnumVal, Name) \ virtual Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \ diff --git a/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h b/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h index 2b468a289fd8..2bef3f61adfc 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h +++ b/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h @@ -15,9 +15,7 @@ namespace llvm { -namespace msf { -class StreamReader; -} // end namespace msf +class BinaryStreamReader; namespace codeview { @@ -25,7 +23,7 @@ class SymbolVisitorDelegate { public: virtual ~SymbolVisitorDelegate() = default; - virtual uint32_t getRecordOffset(msf::StreamReader Reader) = 0; + virtual uint32_t getRecordOffset(BinaryStreamReader Reader) = 0; virtual StringRef getFileNameForFileOffset(uint32_t FileOffset) = 0; virtual StringRef getStringTable() = 0; }; diff --git a/include/llvm/DebugInfo/CodeView/TypeDatabase.h b/include/llvm/DebugInfo/CodeView/TypeDatabase.h index cccc2868ffb5..54ad862cfa7e 100644 --- a/include/llvm/DebugInfo/CodeView/TypeDatabase.h +++ b/include/llvm/DebugInfo/CodeView/TypeDatabase.h @@ -27,13 +27,15 @@ public: TypeIndex getNextTypeIndex() const; /// Records the name of a type, and reserves its type index. - void recordType(StringRef Name, CVType Data); + void recordType(StringRef Name, const CVType &Data); /// Saves the name in a StringSet and creates a stable StringRef. StringRef saveTypeName(StringRef TypeName); StringRef getTypeName(TypeIndex Index) const; + const CVType &getTypeRecord(TypeIndex Index) const; + bool containsTypeIndex(TypeIndex Index) const; uint32_t size() const; diff --git a/include/llvm/DebugInfo/CodeView/TypeDeserializer.h b/include/llvm/DebugInfo/CodeView/TypeDeserializer.h index dc5eaf82845b..0e3443789170 100644 --- a/include/llvm/DebugInfo/CodeView/TypeDeserializer.h +++ b/include/llvm/DebugInfo/CodeView/TypeDeserializer.h @@ -16,8 +16,8 @@ #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/DebugInfo/CodeView/TypeRecordMapping.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" -#include "llvm/DebugInfo/MSF/ByteStream.h" -#include "llvm/DebugInfo/MSF/StreamReader.h" +#include "llvm/Support/BinaryByteStream.h" +#include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/Error.h" #include <cassert> #include <cstdint> @@ -29,10 +29,11 @@ namespace codeview { class TypeDeserializer : public TypeVisitorCallbacks { struct MappingInfo { explicit MappingInfo(ArrayRef<uint8_t> RecordData) - : Stream(RecordData), Reader(Stream), Mapping(Reader) {} + : Stream(RecordData, llvm::support::little), Reader(Stream), + Mapping(Reader) {} - msf::ByteStream Stream; - msf::StreamReader Reader; + BinaryByteStream Stream; + BinaryStreamReader Reader; TypeRecordMapping Mapping; }; @@ -72,16 +73,16 @@ private: class FieldListDeserializer : public TypeVisitorCallbacks { struct MappingInfo { - explicit MappingInfo(msf::StreamReader &R) + explicit MappingInfo(BinaryStreamReader &R) : Reader(R), Mapping(Reader), StartOffset(0) {} - msf::StreamReader &Reader; + BinaryStreamReader &Reader; TypeRecordMapping Mapping; uint32_t StartOffset; }; public: - explicit FieldListDeserializer(msf::StreamReader &Reader) : Mapping(Reader) { + explicit FieldListDeserializer(BinaryStreamReader &Reader) : Mapping(Reader) { CVType FieldList; FieldList.Type = TypeLeafKind::LF_FIELDLIST; consumeError(Mapping.Mapping.visitTypeBegin(FieldList)); diff --git a/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h b/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h index a466e4298158..00bb09137e48 100644 --- a/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h +++ b/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h @@ -28,8 +28,16 @@ public: TypeDumpVisitor(TypeDatabase &TypeDB, ScopedPrinter *W, bool PrintRecordBytes) : W(W), PrintRecordBytes(PrintRecordBytes), TypeDB(TypeDB) {} + /// When dumping types from an IPI stream in a PDB, a type index may refer to + /// a type or an item ID. The dumper will lookup the "name" of the index in + /// the item database if appropriate. If ItemDB is null, it will use TypeDB, + /// which is correct when dumping types from an object file (/Z7). + void setItemDB(TypeDatabase &DB) { ItemDB = &DB; } + void printTypeIndex(StringRef FieldName, TypeIndex TI) const; + void printItemIndex(StringRef FieldName, TypeIndex TI) const; + /// Action to take on unknown types. By default, they are ignored. Error visitUnknownType(CVType &Record) override; Error visitUnknownMember(CVMemberRecord &Record) override; @@ -54,11 +62,17 @@ private: void printMemberAttributes(MemberAccess Access, MethodKind Kind, MethodOptions Options); + /// Get the database of indices for the stream that we are dumping. If ItemDB + /// is set, then we must be dumping an item (IPI) stream. This will also + /// always get the appropriate DB for printing item names. + TypeDatabase &getSourceDB() const { return ItemDB ? *ItemDB : TypeDB; } + ScopedPrinter *W; bool PrintRecordBytes = false; TypeDatabase &TypeDB; + TypeDatabase *ItemDB = nullptr; }; } // end namespace codeview diff --git a/include/llvm/DebugInfo/CodeView/TypeRecord.h b/include/llvm/DebugInfo/CodeView/TypeRecord.h index 4f1c047815d2..1f10872c8768 100644 --- a/include/llvm/DebugInfo/CodeView/TypeRecord.h +++ b/include/llvm/DebugInfo/CodeView/TypeRecord.h @@ -18,7 +18,7 @@ #include "llvm/DebugInfo/CodeView/CVRecord.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" -#include "llvm/DebugInfo/MSF/StreamArray.h" +#include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/Endian.h" #include <algorithm> #include <cstdint> @@ -26,9 +26,7 @@ namespace llvm { -namespace msf { -class StreamReader; -} // end namespace msf +class BinaryStreamReader; namespace codeview { @@ -42,7 +40,8 @@ struct CVMemberRecord { TypeLeafKind Kind; ArrayRef<uint8_t> Data; }; -typedef msf::VarStreamArray<CVType> CVTypeArray; +typedef VarStreamArray<CVType> CVTypeArray; +typedef iterator_range<CVTypeArray::Iterator> CVTypeRange; /// Equvalent to CV_fldattr_t in cvinfo.h. struct MemberAttributes { @@ -106,10 +105,6 @@ public: PointerToMemberRepresentation Representation) : ContainingType(ContainingType), Representation(Representation) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getContainingType() const { return ContainingType; } PointerToMemberRepresentation getRepresentation() const { return Representation; @@ -139,10 +134,6 @@ public: : TypeRecord(TypeRecordKind::Modifier), ModifiedType(ModifiedType), Modifiers(Modifiers) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getModifiedType() const { return ModifiedType; } ModifierOptions getModifiers() const { return Modifiers; } @@ -161,10 +152,6 @@ public: CallConv(CallConv), Options(Options), ParameterCount(ParameterCount), ArgumentList(ArgumentList) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getReturnType() const { return ReturnType; } CallingConvention getCallConv() const { return CallConv; } FunctionOptions getOptions() const { return Options; } @@ -193,10 +180,6 @@ public: ArgumentList(ArgumentList), ThisPointerAdjustment(ThisPointerAdjustment) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getReturnType() const { return ReturnType; } TypeIndex getClassType() const { return ClassType; } TypeIndex getThisType() const { return ThisType; } @@ -216,6 +199,16 @@ public: int32_t ThisPointerAdjustment; }; +// LF_LABEL +class LabelRecord : public TypeRecord { +public: + explicit LabelRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} + + LabelRecord(LabelType Mode) : TypeRecord(TypeRecordKind::Label), Mode(Mode) {} + + LabelType Mode; +}; + // LF_MFUNC_ID class MemberFuncIdRecord : public TypeRecord { public: @@ -225,10 +218,6 @@ public: : TypeRecord(TypeRecordKind::MemberFuncId), ClassType(ClassType), FunctionType(FunctionType), Name(Name) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getClassType() const { return ClassType; } TypeIndex getFunctionType() const { return FunctionType; } StringRef getName() const { return Name; } @@ -237,17 +226,26 @@ public: StringRef Name; }; -// LF_ARGLIST, LF_SUBSTR_LIST +// LF_ARGLIST class ArgListRecord : public TypeRecord { public: explicit ArgListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} ArgListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices) - : TypeRecord(Kind), StringIndices(Indices) {} + : TypeRecord(Kind), ArgIndices(Indices) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); + ArrayRef<TypeIndex> getIndices() const { return ArgIndices; } + + std::vector<TypeIndex> ArgIndices; +}; + +// LF_SUBSTR_LIST +class StringListRecord : public TypeRecord { +public: + explicit StringListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} + + StringListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices) + : TypeRecord(Kind), StringIndices(Indices) {} ArrayRef<TypeIndex> getIndices() const { return StringIndices; } @@ -290,10 +288,6 @@ public: : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType), Attrs(Attrs), MemberInfo(Member) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getReferentType() const { return ReferentType; } PointerKind getPointerKind() const { @@ -356,10 +350,6 @@ public: NestedTypeRecord(TypeIndex Type, StringRef Name) : TypeRecord(TypeRecordKind::NestedType), Type(Type), Name(Name) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getNestedType() const { return Type; } StringRef getName() const { return Name; } @@ -374,10 +364,6 @@ public: explicit FieldListRecord(ArrayRef<uint8_t> Data) : TypeRecord(TypeRecordKind::FieldList), Data(Data) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap) { return false; } - ArrayRef<uint8_t> Data; }; @@ -390,10 +376,6 @@ public: : TypeRecord(TypeRecordKind::Array), ElementType(ElementType), IndexType(IndexType), Size(Size), Name(Name) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getElementType() const { return ElementType; } TypeIndex getIndexType() const { return IndexType; } uint64_t getSize() const { return Size; } @@ -414,10 +396,6 @@ protected: FieldList(FieldList), Name(Name), UniqueName(UniqueName) {} public: - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - static const int HfaKindShift = 11; static const int HfaKindMask = 0x1800; static const int WinRTKindShift = 14; @@ -451,10 +429,6 @@ public: : TagRecord(Kind, MemberCount, Options, FieldList, Name, UniqueName), DerivationList(DerivationList), VTableShape(VTableShape), Size(Size) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - HfaKind getHfa() const { uint16_t Value = static_cast<uint16_t>(Options); Value = (Value & HfaKindMask) >> HfaKindShift; @@ -506,9 +480,6 @@ public: UniqueName), UnderlyingType(UnderlyingType) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getUnderlyingType() const { return UnderlyingType; } TypeIndex UnderlyingType; }; @@ -521,10 +492,6 @@ public: : TypeRecord(TypeRecordKind::BitField), Type(Type), BitSize(BitSize), BitOffset(BitOffset) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getType() const { return Type; } uint8_t getBitOffset() const { return BitOffset; } uint8_t getBitSize() const { return BitSize; } @@ -542,10 +509,6 @@ public: explicit VFTableShapeRecord(std::vector<VFTableSlotKind> Slots) : TypeRecord(TypeRecordKind::VFTableShape), Slots(std::move(Slots)) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - ArrayRef<VFTableSlotKind> getSlots() const { if (!SlotsRef.empty()) return SlotsRef; @@ -565,10 +528,6 @@ public: : TypeRecord(TypeRecordKind::TypeServer2), Guid(Guid), Age(Age), Name(Name) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - StringRef getGuid() const { return Guid; } uint32_t getAge() const { return Age; } @@ -587,10 +546,6 @@ public: StringIdRecord(TypeIndex Id, StringRef String) : TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getId() const { return Id; } StringRef getString() const { return String; } @@ -606,10 +561,6 @@ public: : TypeRecord(TypeRecordKind::FuncId), ParentScope(ParentScope), FunctionType(FunctionType), Name(Name) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getParentScope() const { return ParentScope; } TypeIndex getFunctionType() const { return FunctionType; } @@ -629,10 +580,6 @@ public: : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT), SourceFile(SourceFile), LineNumber(LineNumber) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getUDT() const { return UDT; } TypeIndex getSourceFile() const { return SourceFile; } uint32_t getLineNumber() const { return LineNumber; } @@ -651,8 +598,6 @@ public: : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT), SourceFile(SourceFile), LineNumber(LineNumber), Module(Module) {} - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getUDT() const { return UDT; } TypeIndex getSourceFile() const { return SourceFile; } uint32_t getLineNumber() const { return LineNumber; } @@ -672,10 +617,6 @@ public: : TypeRecord(TypeRecordKind::BuildInfo), ArgIndices(ArgIndices.begin(), ArgIndices.end()) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - ArrayRef<TypeIndex> getArgs() const { return ArgIndices; } SmallVector<TypeIndex, 4> ArgIndices; }; @@ -693,10 +634,6 @@ public: MethodNames.insert(MethodNames.end(), Methods.begin(), Methods.end()); } - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getCompleteClass() const { return CompleteClass; } TypeIndex getOverriddenVTable() const { return OverriddenVFTable; } uint32_t getVFPtrOffset() const { return VFPtrOffset; } @@ -725,10 +662,6 @@ public: : TypeRecord(TypeRecordKind::OneMethod), Type(Type), Attrs(Access, MK, Options), VFTableOffset(VFTableOffset), Name(Name) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getType() const { return Type; } MethodKind getMethodKind() const { return Attrs.getMethodKind(); } MethodOptions getOptions() const { return Attrs.getFlags(); } @@ -754,10 +687,6 @@ public: MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods) : TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - ArrayRef<OneMethodRecord> getMethods() const { return Methods; } std::vector<OneMethodRecord> Methods; }; @@ -771,10 +700,6 @@ public: : TypeRecord(TypeRecordKind::OverloadedMethod), NumOverloads(NumOverloads), MethodList(MethodList), Name(Name) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - uint16_t getNumOverloads() const { return NumOverloads; } TypeIndex getMethodList() const { return MethodList; } StringRef getName() const { return Name; } @@ -796,10 +721,6 @@ public: : TypeRecord(TypeRecordKind::DataMember), Attrs(Access), Type(Type), FieldOffset(Offset), Name(Name) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - MemberAccess getAccess() const { return Attrs.getAccess(); } TypeIndex getType() const { return Type; } uint64_t getFieldOffset() const { return FieldOffset; } @@ -822,10 +743,6 @@ public: : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Access), Type(Type), Name(Name) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - MemberAccess getAccess() const { return Attrs.getAccess(); } TypeIndex getType() const { return Type; } StringRef getName() const { return Name; } @@ -846,10 +763,6 @@ public: : TypeRecord(TypeRecordKind::Enumerator), Attrs(Access), Value(std::move(Value)), Name(Name) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - MemberAccess getAccess() const { return Attrs.getAccess(); } APSInt getValue() const { return Value; } StringRef getName() const { return Name; } @@ -866,10 +779,6 @@ public: VFPtrRecord(TypeIndex Type) : TypeRecord(TypeRecordKind::VFPtr), Type(Type) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getType() const { return Type; } TypeIndex Type; @@ -886,10 +795,6 @@ public: : TypeRecord(TypeRecordKind::BaseClass), Attrs(Access), Type(Type), Offset(Offset) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - MemberAccess getAccess() const { return Attrs.getAccess(); } TypeIndex getBaseType() const { return Type; } uint64_t getBaseOffset() const { return Offset; } @@ -914,10 +819,6 @@ public: : TypeRecord(Kind), Attrs(Access), BaseType(BaseType), VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - MemberAccess getAccess() const { return Attrs.getAccess(); } TypeIndex getBaseType() const { return BaseType; } TypeIndex getVBPtrType() const { return VBPtrType; } @@ -942,8 +843,6 @@ public: TypeIndex getContinuationIndex() const { return ContinuationIndex; } - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex ContinuationIndex; }; diff --git a/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h b/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h index fe470a72abbb..924ca0470fad 100644 --- a/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h +++ b/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h @@ -16,15 +16,14 @@ #include "llvm/Support/Error.h" namespace llvm { -namespace msf { -class StreamReader; -class StreamWriter; -} +class BinaryStreamReader; +class BinaryStreamWriter; + namespace codeview { class TypeRecordMapping : public TypeVisitorCallbacks { public: - explicit TypeRecordMapping(msf::StreamReader &Reader) : IO(Reader) {} - explicit TypeRecordMapping(msf::StreamWriter &Writer) : IO(Writer) {} + explicit TypeRecordMapping(BinaryStreamReader &Reader) : IO(Reader) {} + explicit TypeRecordMapping(BinaryStreamWriter &Writer) : IO(Writer) {} Error visitTypeBegin(CVType &Record) override; Error visitTypeEnd(CVType &Record) override; diff --git a/include/llvm/DebugInfo/CodeView/TypeRecords.def b/include/llvm/DebugInfo/CodeView/TypeRecords.def index c98dbac21a7a..8c193bb13cb7 100644 --- a/include/llvm/DebugInfo/CodeView/TypeRecords.def +++ b/include/llvm/DebugInfo/CodeView/TypeRecords.def @@ -41,6 +41,7 @@ TYPE_RECORD(LF_POINTER, 0x1002, Pointer) TYPE_RECORD(LF_MODIFIER, 0x1001, Modifier) TYPE_RECORD(LF_PROCEDURE, 0x1008, Procedure) TYPE_RECORD(LF_MFUNCTION, 0x1009, MemberFunction) +TYPE_RECORD(LF_LABEL, 0x000e, Label) TYPE_RECORD(LF_ARGLIST, 0x1201, ArgList) TYPE_RECORD(LF_FIELDLIST, 0x1203, FieldList) @@ -79,9 +80,7 @@ MEMBER_RECORD(LF_INDEX, 0x1404, ListContinuation) TYPE_RECORD(LF_FUNC_ID, 0x1601, FuncId) TYPE_RECORD(LF_MFUNC_ID, 0x1602, MemberFuncId) TYPE_RECORD(LF_BUILDINFO, 0x1603, BuildInfo) -// FIXME: We reuse the structure of ArgListRecord for substring lists, but it -// makes for confusing dumper output. -TYPE_RECORD_ALIAS(LF_SUBSTR_LIST, 0x1604, StringList, ArgList) +TYPE_RECORD(LF_SUBSTR_LIST, 0x1604, StringList) TYPE_RECORD(LF_STRING_ID, 0x1605, StringId) TYPE_RECORD(LF_UDT_SRC_LINE, 0x1606, UdtSourceLine) TYPE_RECORD(LF_UDT_MOD_SRC_LINE, 0x1607, UdtModSourceLine) @@ -103,7 +102,6 @@ CV_TYPE(LF_MFUNCTION_16t, 0x0009) CV_TYPE(LF_COBOL0_16t, 0x000b) CV_TYPE(LF_COBOL1, 0x000c) CV_TYPE(LF_BARRAY_16t, 0x000d) -CV_TYPE(LF_LABEL, 0x000e) CV_TYPE(LF_NULLLEAF, 0x000f) // LF_NULL CV_TYPE(LF_NOTTRAN, 0x0010) CV_TYPE(LF_DIMARRAY_16t, 0x0011) diff --git a/include/llvm/DebugInfo/CodeView/TypeSerializer.h b/include/llvm/DebugInfo/CodeView/TypeSerializer.h index e05922194638..1f4873c4f969 100644 --- a/include/llvm/DebugInfo/CodeView/TypeSerializer.h +++ b/include/llvm/DebugInfo/CodeView/TypeSerializer.h @@ -12,8 +12,8 @@ #include "llvm/DebugInfo/CodeView/TypeRecordMapping.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" -#include "llvm/DebugInfo/MSF/ByteStream.h" -#include "llvm/DebugInfo/MSF/StreamWriter.h" +#include "llvm/Support/BinaryByteStream.h" +#include "llvm/Support/BinaryStreamWriter.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" @@ -56,8 +56,8 @@ class TypeSerializer : public TypeVisitorCallbacks { Optional<TypeLeafKind> TypeKind; Optional<TypeLeafKind> MemberKind; std::vector<uint8_t> RecordBuffer; - msf::MutableByteStream Stream; - msf::StreamWriter Writer; + MutableBinaryByteStream Stream; + BinaryStreamWriter Writer; TypeRecordMapping Mapping; RecordList SeenRecords; diff --git a/include/llvm/DebugInfo/CodeView/TypeServerHandler.h b/include/llvm/DebugInfo/CodeView/TypeServerHandler.h new file mode 100644 index 000000000000..35f06eaf6eb4 --- /dev/null +++ b/include/llvm/DebugInfo/CodeView/TypeServerHandler.h @@ -0,0 +1,36 @@ +//===- TypeServerHandler.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_TYPESERVERHANDLER_H +#define LLVM_DEBUGINFO_CODEVIEW_TYPESERVERHANDLER_H + +#include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/Support/Error.h" + +namespace llvm { +namespace codeview { +class TypeVisitorCallbacks; + +class TypeServerHandler { +public: + virtual ~TypeServerHandler() {} + + /// Handle a TypeServer record. If the implementation returns true + /// the record will not be processed by the top-level visitor. If + /// it returns false, it will be processed. If it returns an Error, + /// then the top-level visitor will fail. + virtual Expected<bool> handle(TypeServer2Record &TS, + TypeVisitorCallbacks &Callbacks) { + return false; + } +}; +} +} + +#endif diff --git a/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h b/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h index af396c79d074..2246f197e784 100644 --- a/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h +++ b/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h @@ -13,12 +13,17 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" +#include "llvm/Support/Error.h" namespace llvm { namespace codeview { +class TypeServerHandler; + /// Merges one type stream into another. Returns true on success. -bool mergeTypeStreams(TypeTableBuilder &DestStream, const CVTypeArray &Types); +Error mergeTypeStreams(TypeTableBuilder &DestIdStream, + TypeTableBuilder &DestTypeStream, + TypeServerHandler *Handler, const CVTypeArray &Types); } // end namespace codeview } // end namespace llvm diff --git a/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h b/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h index 4e6d81ece318..102bee4b0801 100644 --- a/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h +++ b/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h @@ -121,6 +121,12 @@ public: } return Index; } + + /// Stop building the record. + void reset() { + if (auto EC = TempSerializer.visitTypeEnd(Type)) + consumeError(std::move(EC)); + } }; } // end namespace codeview |