aboutsummaryrefslogtreecommitdiff
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.h12
-rw-r--r--include/llvm/DebugInfo/CodeView/CVTypeDumper.h7
-rw-r--r--include/llvm/DebugInfo/CodeView/CVTypeVisitor.h10
-rw-r--r--include/llvm/DebugInfo/CodeView/CodeView.h6
-rw-r--r--include/llvm/DebugInfo/CodeView/CodeViewError.h1
-rw-r--r--include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h12
-rw-r--r--include/llvm/DebugInfo/CodeView/Formatters.h40
-rw-r--r--include/llvm/DebugInfo/CodeView/ModuleSubstream.h18
-rw-r--r--include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h54
-rw-r--r--include/llvm/DebugInfo/CodeView/RecordSerialization.h44
-rw-r--r--include/llvm/DebugInfo/CodeView/SymbolDeserializer.h11
-rw-r--r--include/llvm/DebugInfo/CodeView/SymbolRecord.h8
-rw-r--r--include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h10
-rw-r--r--include/llvm/DebugInfo/CodeView/SymbolSerializer.h47
-rw-r--r--include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h6
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeDatabase.h4
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeDeserializer.h17
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h14
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeRecord.h157
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeRecordMapping.h11
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeRecords.def6
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeSerializer.h8
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeServerHandler.h36
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeStreamMerger.h7
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeTableBuilder.h6
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