summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/include/llvm/DebugInfo/CodeView
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/include/llvm/DebugInfo/CodeView')
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/ByteStream.h58
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CVDebugRecord.h55
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CVRecord.h65
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h78
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeDumper.h56
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h11
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CodeView.h7
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewError.h1
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewOStream.h39
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h170
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/EnumTables.h1
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/FieldListRecordBuilder.h65
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/ListRecordBuilder.h65
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h48
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/MethodListRecordBuilder.h35
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstream.h30
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h109
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h155
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/StreamArray.h275
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/StreamInterface.h55
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/StreamReader.h111
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/StreamRef.h104
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/StreamWriter.h86
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h74
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDumpDelegate.h10
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDumper.h12
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h1244
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h44
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolSerializer.h96
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h71
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h48
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h14
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabase.h55
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h53
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h136
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h67
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumper.h105
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumperBase.h0
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndex.h3
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h726
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordBuilder.h8
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h52
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecords.def3
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeSerializer.h140
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h141
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h114
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h45
47 files changed, 2196 insertions, 2744 deletions
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/ByteStream.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/ByteStream.h
deleted file mode 100644
index f398c93..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/ByteStream.h
+++ /dev/null
@@ -1,58 +0,0 @@
-//===- ByteStream.h - Reads stream data from a byte sequence ----*- 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_BYTESTREAM_H
-#define LLVM_DEBUGINFO_CODEVIEW_BYTESTREAM_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/DebugInfo/CodeView/StreamInterface.h"
-#include "llvm/Support/Error.h"
-#include <cstdint>
-#include <memory>
-#include <type_traits>
-
-namespace llvm {
-namespace codeview {
-class StreamReader;
-
-template <bool Writable = false> class ByteStream : public StreamInterface {
- typedef typename std::conditional<Writable, MutableArrayRef<uint8_t>,
- ArrayRef<uint8_t>>::type ArrayType;
-
-public:
- ByteStream() {}
- explicit ByteStream(ArrayType Data) : Data(Data) {}
- ~ByteStream() override {}
-
- Error readBytes(uint32_t Offset, uint32_t Size,
- ArrayRef<uint8_t> &Buffer) const override;
- Error readLongestContiguousChunk(uint32_t Offset,
- ArrayRef<uint8_t> &Buffer) const override;
-
- Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) const override;
-
- uint32_t getLength() const override;
-
- Error commit() const override;
-
- ArrayRef<uint8_t> data() const { return Data; }
- StringRef str() const;
-
-private:
- ArrayType Data;
-};
-
-extern template class ByteStream<true>;
-extern template class ByteStream<false>;
-
-} // end namespace pdb
-} // end namespace llvm
-
-#endif // LLVM_DEBUGINFO_CODEVIEW_BYTESTREAM_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVDebugRecord.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVDebugRecord.h
new file mode 100644
index 0000000..5a0bb42
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVDebugRecord.h
@@ -0,0 +1,55 @@
+//===- CVDebugRecord.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_CVDEBUGRECORD_H
+#define LLVM_DEBUGINFO_CODEVIEW_CVDEBUGRECORD_H
+
+#include "llvm/Support/Endian.h"
+
+namespace llvm {
+namespace OMF {
+struct Signature {
+ enum ID : uint32_t {
+ PDB70 = 0x53445352, // RSDS
+ PDB20 = 0x3031424e, // NB10
+ CV50 = 0x3131424e, // NB11
+ CV41 = 0x3930424e, // NB09
+ };
+
+ support::ulittle32_t CVSignature;
+ support::ulittle32_t Offset;
+};
+}
+
+namespace codeview {
+struct PDB70DebugInfo {
+ support::ulittle32_t CVSignature;
+ uint8_t Signature[16];
+ support::ulittle32_t Age;
+ // char PDBFileName[];
+};
+
+struct PDB20DebugInfo {
+ support::ulittle32_t CVSignature;
+ support::ulittle32_t Offset;
+ support::ulittle32_t Signature;
+ support::ulittle32_t Age;
+ // char PDBFileName[];
+};
+
+union DebugInfo {
+ struct OMF::Signature Signature;
+ struct PDB20DebugInfo PDB20;
+ struct PDB70DebugInfo PDB70;
+};
+}
+}
+
+#endif
+
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVRecord.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVRecord.h
index dba359f..a327d45 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVRecord.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVRecord.h
@@ -11,46 +11,73 @@
#define LLVM_DEBUGINFO_CODEVIEW_RECORDITERATOR_H
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
-#include "llvm/DebugInfo/CodeView/StreamInterface.h"
-#include "llvm/DebugInfo/CodeView/StreamReader.h"
+#include "llvm/DebugInfo/MSF/StreamReader.h"
+#include "llvm/DebugInfo/MSF/StreamRef.h"
#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
namespace llvm {
+
namespace codeview {
-template <typename Kind> struct CVRecord {
- uint32_t Length;
+template <typename Kind> class CVRecord {
+public:
+ CVRecord() = default;
+ CVRecord(Kind K, ArrayRef<uint8_t> Data) : Type(K), RecordData(Data) {}
+
+ uint32_t length() const { return RecordData.size(); }
+ Kind kind() const { return Type; }
+ ArrayRef<uint8_t> data() const { return RecordData; }
+
+ ArrayRef<uint8_t> content() const {
+ return RecordData.drop_front(sizeof(RecordPrefix));
+ }
+
+ Optional<uint32_t> hash() const { return Hash; }
+
+ void setHash(uint32_t Value) { Hash = Value; }
+
Kind Type;
- ArrayRef<uint8_t> Data;
- ArrayRef<uint8_t> RawData;
+ ArrayRef<uint8_t> RecordData;
+ Optional<uint32_t> Hash;
};
-template <typename Kind> struct VarStreamArrayExtractor<CVRecord<Kind>> {
- Error operator()(StreamRef Stream, uint32_t &Len,
- CVRecord<Kind> &Item) const {
+} // end namespace codeview
+
+namespace msf {
+
+template <typename Kind>
+struct VarStreamArrayExtractor<codeview::CVRecord<Kind>> {
+ Error operator()(ReadableStreamRef Stream, uint32_t &Len,
+ codeview::CVRecord<Kind> &Item) const {
+ using namespace codeview;
const RecordPrefix *Prefix = nullptr;
StreamReader Reader(Stream);
uint32_t Offset = Reader.getOffset();
if (auto EC = Reader.readObject(Prefix))
return EC;
- Item.Length = Prefix->RecordLen;
- if (Item.Length < 2)
+ if (Prefix->RecordLen < 2)
return make_error<CodeViewError>(cv_error_code::corrupt_record);
- Item.Type = static_cast<Kind>(uint16_t(Prefix->RecordKind));
+ Kind K = static_cast<Kind>(uint16_t(Prefix->RecordKind));
Reader.setOffset(Offset);
+ ArrayRef<uint8_t> RawData;
if (auto EC =
- Reader.readBytes(Item.RawData, Item.Length + sizeof(uint16_t)))
+ Reader.readBytes(RawData, Prefix->RecordLen + sizeof(uint16_t)))
return EC;
- Item.Data = Item.RawData.slice(sizeof(RecordPrefix));
- Len = Prefix->RecordLen + 2;
+ Item = codeview::CVRecord<Kind>(K, RawData);
+ Len = Item.length();
return Error::success();
}
};
-}
-}
-#endif
+} // end namespace msf
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_RECORDITERATOR_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h
index 7c88956..b2d3f5e 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h
@@ -18,83 +18,17 @@
namespace llvm {
namespace codeview {
+class SymbolVisitorCallbacks;
-template <typename Derived> class CVSymbolVisitor {
+class CVSymbolVisitor {
public:
- CVSymbolVisitor(SymbolVisitorDelegate *Delegate) : Delegate(Delegate) {}
+ CVSymbolVisitor(SymbolVisitorCallbacks &Callbacks);
- bool hadError() const { return HadError; }
-
- template <typename T>
- bool consumeObject(ArrayRef<uint8_t> &Data, const T *&Res) {
- if (Data.size() < sizeof(*Res)) {
- HadError = true;
- return false;
- }
- Res = reinterpret_cast<const T *>(Data.data());
- Data = Data.drop_front(sizeof(*Res));
- return true;
- }
-
-/// Actions to take on known symbols. By default, they do nothing. Visit methods
-/// for member records take the FieldData by non-const reference and are
-/// expected to consume the trailing bytes used by the field.
-/// FIXME: Make the visitor interpret the trailing bytes so that clients don't
-/// need to.
-#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
- void visit##Name(SymbolRecordKind Kind, Name &Record) {}
-#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "CVSymbolTypes.def"
-
- void visitSymbolRecord(const CVRecord<SymbolKind> &Record) {
- ArrayRef<uint8_t> Data = Record.Data;
- auto *DerivedThis = static_cast<Derived *>(this);
- DerivedThis->visitSymbolBegin(Record.Type, Data);
- uint32_t RecordOffset = Delegate ? Delegate->getRecordOffset(Data) : 0;
- switch (Record.Type) {
- default:
- DerivedThis->visitUnknownSymbol(Record.Type, Data);
- break;
-#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
- case EnumName: { \
- SymbolRecordKind RK = static_cast<SymbolRecordKind>(EnumName); \
- auto Result = Name::deserialize(RK, RecordOffset, Data); \
- if (Result.getError()) \
- return parseError(); \
- DerivedThis->visit##Name(Record.Type, *Result); \
- break; \
- }
-#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
- SYMBOL_RECORD(EnumVal, EnumVal, AliasName)
-#include "CVSymbolTypes.def"
- }
- DerivedThis->visitSymbolEnd(Record.Type, Record.Data);
- }
-
- /// Visits the symbol records in Data. Sets the error flag on parse failures.
- void visitSymbolStream(const CVSymbolArray &Symbols) {
- for (const auto &I : Symbols) {
- visitSymbolRecord(I);
- if (hadError())
- break;
- }
- }
-
- /// Action to take on unknown symbols. By default, they are ignored.
- void visitUnknownSymbol(SymbolKind Kind, ArrayRef<uint8_t> Data) {}
-
- /// Paired begin/end actions for all symbols. Receives all record data,
- /// including the fixed-length record prefix.
- void visitSymbolBegin(SymbolKind Leaf, ArrayRef<uint8_t> RecordData) {}
- void visitSymbolEnd(SymbolKind Leaf, ArrayRef<uint8_t> OriginalSymData) {}
-
- /// Helper for returning from a void function when the stream is corrupted.
- void parseError() { HadError = true; }
+ Error visitSymbolRecord(CVSymbol &Record);
+ Error visitSymbolStream(const CVSymbolArray &Symbols);
private:
- SymbolVisitorDelegate *Delegate;
- /// Whether a symbol stream parsing error was encountered.
- bool HadError = false;
+ SymbolVisitorCallbacks &Callbacks;
};
} // end namespace codeview
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeDumper.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeDumper.h
new file mode 100644
index 0000000..e1dd6a1
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeDumper.h
@@ -0,0 +1,56 @@
+//===-- CVTypeDumper.h - CodeView type info dumper --------------*- 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_CVTYPEDUMPER_H
+#define LLVM_DEBUGINFO_CODEVIEW_CVTYPEDUMPER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
+#include "llvm/Support/ScopedPrinter.h"
+
+namespace llvm {
+
+namespace codeview {
+
+/// Dumper for CodeView type streams found in COFF object files and PDB files.
+class CVTypeDumper {
+public:
+ explicit CVTypeDumper(TypeDatabase &TypeDB) : TypeDB(TypeDB) {}
+
+ /// 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
+ /// maintains state about previous records which are necessary for cross
+ /// type references.
+ Error dump(const CVType &Record, TypeVisitorCallbacks &Dumper);
+
+ /// Dumps the type records in Types. Returns false if there was a type stream
+ /// parse error, and true otherwise.
+ Error dump(const CVTypeArray &Types, TypeVisitorCallbacks &Dumper);
+
+ /// Dumps the type records in Data. Returns false if there was a type stream
+ /// parse error, and true otherwise. Use this method instead of the
+ /// CVTypeArray overload when type records are laid out contiguously in
+ /// memory.
+ Error dump(ArrayRef<uint8_t> Data, TypeVisitorCallbacks &Dumper);
+
+ static void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName,
+ TypeIndex TI, TypeDatabase &DB);
+
+private:
+ TypeDatabase &TypeDB;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_TYPEDUMPER_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
index 930ac69..d1b0363 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
@@ -10,6 +10,7 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_CVTYPEVISITOR_H
#define LLVM_DEBUGINFO_CODEVIEW_CVTYPEVISITOR_H
+#include "llvm/ADT/SmallVector.h"
#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
@@ -22,16 +23,14 @@ class CVTypeVisitor {
public:
explicit CVTypeVisitor(TypeVisitorCallbacks &Callbacks);
- Error visitTypeRecord(const CVRecord<TypeLeafKind> &Record);
+ 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 skipPadding(ArrayRef<uint8_t> &Data);
-
- /// Visits individual member records of a field list record. Member records do
- /// not describe their own length, and need special handling.
- Error visitFieldList(const CVRecord<TypeLeafKind> &Record);
+ Error visitFieldListMemberStream(ArrayRef<uint8_t> FieldList);
+ Error visitFieldListMemberStream(msf::StreamReader Reader);
private:
/// The interface to the class that gets notified of each visitation.
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeView.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeView.h
index 1ee203b..e21cfa3 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeView.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeView.h
@@ -21,8 +21,6 @@ namespace codeview {
enum class TypeRecordKind : uint16_t {
#define TYPE_RECORD(lf_ename, value, name) name = value,
#include "TypeRecords.def"
- // FIXME: Add serialization support
- FieldList = 0x1203,
};
/// Duplicate copy of the above enum, but using the official CV names. Useful
@@ -278,6 +276,7 @@ enum class MethodOptions : uint16_t {
CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(MethodOptions)
/// Equivalent to CV_modifier_t.
+/// TODO: Add flag for _Atomic modifier
enum class ModifierOptions : uint16_t {
None = 0x0000,
Const = 0x0001,
@@ -526,7 +525,7 @@ enum class RegisterId : uint16_t {
};
/// These values correspond to the THUNK_ORDINAL enumeration.
-enum class ThunkOrdinal {
+enum class ThunkOrdinal : uint8_t {
Standard,
ThisAdjustor,
Vcall,
@@ -536,7 +535,7 @@ enum class ThunkOrdinal {
BranchIsland
};
-enum class TrampolineType { TrampIncremental, BranchIsland };
+enum class TrampolineType : uint16_t { TrampIncremental, BranchIsland };
// These values correspond to the CV_SourceChksum_t enumeration.
enum class FileChecksumKind : uint8_t { None, MD5, SHA1, SHA256 };
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewError.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewError.h
index 69ff29a..0556fd0 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewError.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewError.h
@@ -21,6 +21,7 @@ enum class cv_error_code {
insufficient_buffer,
operation_unsupported,
corrupt_record,
+ unknown_member_record,
};
/// Base class for errors originating when parsing raw PDB files
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewOStream.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewOStream.h
deleted file mode 100644
index 14d057a..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewOStream.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//===- CodeViewOStream.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_CODEVIEWOSTREAM_H
-#define LLVM_DEBUGINFO_CODEVIEW_CODEVIEWOSTREAM_H
-
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-
-namespace llvm {
-namespace codeview {
-
-template <typename Writer> class CodeViewOStream {
-private:
- CodeViewOStream(const CodeViewOStream &) = delete;
- CodeViewOStream &operator=(const CodeViewOStream &) = delete;
-
-public:
- typedef typename Writer::LabelType LabelType;
-
-public:
- explicit CodeViewOStream(Writer &W);
-
-private:
- uint64_t size() const { return W.tell(); }
-
-private:
- Writer &W;
-};
-}
-}
-
-#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
new file mode 100644
index 0000000..5a036b9
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
@@ -0,0 +1,170 @@
+//===- CodeViewRecordIO.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_CODEVIEWRECORDIO_H
+#define LLVM_DEBUGINFO_CODEVIEW_CODEVIEWRECORDIO_H
+
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
+#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/Error.h"
+#include <cassert>
+#include <cstdint>
+#include <type_traits>
+
+namespace llvm {
+namespace codeview {
+
+class CodeViewRecordIO {
+ uint32_t getCurrentOffset() const {
+ return (isWriting()) ? Writer->getOffset() : Reader->getOffset();
+ }
+
+public:
+ explicit CodeViewRecordIO(msf::StreamReader &Reader) : Reader(&Reader) {}
+ explicit CodeViewRecordIO(msf::StreamWriter &Writer) : Writer(&Writer) {}
+
+ Error beginRecord(Optional<uint32_t> MaxLength);
+ Error endRecord();
+
+ Error mapInteger(TypeIndex &TypeInd);
+
+ bool isReading() const { return Reader != nullptr; }
+ bool isWriting() const { return !isReading(); }
+
+ uint32_t maxFieldLength() const;
+
+ template <typename T> Error mapObject(T &Value) {
+ if (isWriting())
+ return Writer->writeObject(Value);
+
+ const T *ValuePtr;
+ if (auto EC = Reader->readObject(ValuePtr))
+ return EC;
+ Value = *ValuePtr;
+ return Error::success();
+ }
+
+ template <typename T> Error mapInteger(T &Value) {
+ if (isWriting())
+ return Writer->writeInteger(Value);
+
+ return Reader->readInteger(Value);
+ }
+
+ template <typename T> Error mapEnum(T &Value) {
+ if (sizeof(Value) > maxFieldLength())
+ return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
+
+ using U = typename std::underlying_type<T>::type;
+ U X;
+ if (isWriting())
+ X = static_cast<U>(Value);
+
+ if (auto EC = mapInteger(X))
+ return EC;
+ if (isReading())
+ Value = static_cast<T>(X);
+ return Error::success();
+ }
+
+ Error mapEncodedInteger(int64_t &Value);
+ Error mapEncodedInteger(uint64_t &Value);
+ Error mapEncodedInteger(APSInt &Value);
+ Error mapStringZ(StringRef &Value);
+ Error mapGuid(StringRef &Guid);
+
+ Error mapStringZVectorZ(std::vector<StringRef> &Value);
+
+ template <typename SizeType, typename T, typename ElementMapper>
+ Error mapVectorN(T &Items, const ElementMapper &Mapper) {
+ SizeType Size;
+ if (isWriting()) {
+ Size = static_cast<SizeType>(Items.size());
+ if (auto EC = Writer->writeInteger(Size))
+ return EC;
+
+ for (auto &X : Items) {
+ if (auto EC = Mapper(*this, X))
+ return EC;
+ }
+ } else {
+ if (auto EC = Reader->readInteger(Size))
+ return EC;
+ for (SizeType I = 0; I < Size; ++I) {
+ typename T::value_type Item;
+ if (auto EC = Mapper(*this, Item))
+ return EC;
+ Items.push_back(Item);
+ }
+ }
+
+ return Error::success();
+ }
+
+ template <typename T, typename ElementMapper>
+ Error mapVectorTail(T &Items, const ElementMapper &Mapper) {
+ if (isWriting()) {
+ for (auto &Item : Items) {
+ if (auto EC = Mapper(*this, Item))
+ return EC;
+ }
+ } else {
+ typename T::value_type Field;
+ // Stop when we run out of bytes or we hit record padding bytes.
+ while (!Reader->empty() && Reader->peek() < 0xf0 /* LF_PAD0 */) {
+ if (auto EC = Mapper(*this, Field))
+ return EC;
+ Items.push_back(Field);
+ }
+ }
+ return Error::success();
+ }
+
+ Error mapByteVectorTail(ArrayRef<uint8_t> &Bytes);
+ Error mapByteVectorTail(std::vector<uint8_t> &Bytes);
+
+ Error skipPadding();
+
+private:
+ Error writeEncodedSignedInteger(const int64_t &Value);
+ Error writeEncodedUnsignedInteger(const uint64_t &Value);
+
+ struct RecordLimit {
+ uint32_t BeginOffset;
+ Optional<uint32_t> MaxLength;
+
+ Optional<uint32_t> bytesRemaining(uint32_t CurrentOffset) const {
+ if (!MaxLength.hasValue())
+ return None;
+ assert(CurrentOffset >= BeginOffset);
+
+ uint32_t BytesUsed = CurrentOffset - BeginOffset;
+ if (BytesUsed >= *MaxLength)
+ return 0;
+ return *MaxLength - BytesUsed;
+ }
+ };
+
+ SmallVector<RecordLimit, 2> Limits;
+
+ msf::StreamReader *Reader = nullptr;
+ msf::StreamWriter *Writer = nullptr;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_CODEVIEWRECORDIO_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/EnumTables.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/EnumTables.h
index 021288e..10d1c58 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/EnumTables.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/EnumTables.h
@@ -20,6 +20,7 @@
namespace llvm {
namespace codeview {
ArrayRef<EnumEntry<SymbolKind>> getSymbolTypeNames();
+ArrayRef<EnumEntry<TypeLeafKind>> getTypeLeafNames();
ArrayRef<EnumEntry<uint16_t>> getRegisterNames();
ArrayRef<EnumEntry<uint8_t>> getProcSymFlagNames();
ArrayRef<EnumEntry<uint16_t>> getLocalFlagNames();
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/FieldListRecordBuilder.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/FieldListRecordBuilder.h
deleted file mode 100644
index 75a0751..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/FieldListRecordBuilder.h
+++ /dev/null
@@ -1,65 +0,0 @@
-//===- FieldListRecordBuilder.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_FIELDLISTRECORDBUILDER_H
-#define LLVM_DEBUGINFO_CODEVIEW_FIELDLISTRECORDBUILDER_H
-
-#include "llvm/DebugInfo/CodeView/ListRecordBuilder.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-
-namespace llvm {
-namespace codeview {
-
-class MethodInfo {
-public:
- MethodInfo() : Access(), Kind(), Options(), Type(), VTableSlotOffset(-1) {}
-
- MethodInfo(MemberAccess Access, MethodKind Kind, MethodOptions Options,
- TypeIndex Type, int32_t VTableSlotOffset)
- : Access(Access), Kind(Kind), Options(Options), Type(Type),
- VTableSlotOffset(VTableSlotOffset) {}
-
- MemberAccess getAccess() const { return Access; }
- MethodKind getKind() const { return Kind; }
- MethodOptions getOptions() const { return Options; }
- TypeIndex getType() const { return Type; }
- int32_t getVTableSlotOffset() const { return VTableSlotOffset; }
-
-private:
- MemberAccess Access;
- MethodKind Kind;
- MethodOptions Options;
- TypeIndex Type;
- int32_t VTableSlotOffset;
-};
-
-class FieldListRecordBuilder : public ListRecordBuilder {
-private:
- FieldListRecordBuilder(const FieldListRecordBuilder &) = delete;
- void operator=(const FieldListRecordBuilder &) = delete;
-
-public:
- FieldListRecordBuilder();
-
- void reset() { ListRecordBuilder::reset(); }
-
- void writeBaseClass(const BaseClassRecord &Record);
- void writeEnumerator(const EnumeratorRecord &Record);
- void writeDataMember(const DataMemberRecord &Record);
- void writeOneMethod(const OneMethodRecord &Record);
- void writeOverloadedMethod(const OverloadedMethodRecord &Record);
- void writeNestedType(const NestedTypeRecord &Record);
- void writeStaticDataMember(const StaticDataMemberRecord &Record);
- void writeVirtualBaseClass(const VirtualBaseClassRecord &Record);
- void writeVFPtr(const VFPtrRecord &Type);
-};
-}
-}
-
-#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/ListRecordBuilder.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/ListRecordBuilder.h
deleted file mode 100644
index 00bf03d4..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/ListRecordBuilder.h
+++ /dev/null
@@ -1,65 +0,0 @@
-//===- ListRecordBuilder.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_LISTRECORDBUILDER_H
-#define LLVM_DEBUGINFO_CODEVIEW_LISTRECORDBUILDER_H
-
-#include "llvm/DebugInfo/CodeView/TypeRecordBuilder.h"
-
-namespace llvm {
-namespace codeview {
-class TypeTableBuilder;
-
-class ListRecordBuilder {
-private:
- ListRecordBuilder(const ListRecordBuilder &) = delete;
- ListRecordBuilder &operator=(const ListRecordBuilder &) = delete;
-
-protected:
- const int MethodKindShift = 2;
-
- explicit ListRecordBuilder(TypeRecordKind Kind);
-
-public:
- llvm::StringRef str() { return Builder.str(); }
-
- void reset() {
- Builder.reset(Kind);
- ContinuationOffsets.clear();
- SubrecordStart = 0;
- }
-
- void writeListContinuation(const ListContinuationRecord &R);
-
- /// Writes this list record as a possible sequence of records.
- TypeIndex writeListRecord(TypeTableBuilder &Table);
-
-protected:
- void finishSubRecord();
-
- TypeRecordBuilder &getBuilder() { return Builder; }
-
-private:
- size_t getLastContinuationStart() const {
- return ContinuationOffsets.empty() ? 0 : ContinuationOffsets.back();
- }
- size_t getLastContinuationEnd() const { return Builder.size(); }
- size_t getLastContinuationSize() const {
- return getLastContinuationEnd() - getLastContinuationStart();
- }
-
- TypeRecordKind Kind;
- TypeRecordBuilder Builder;
- SmallVector<size_t, 4> ContinuationOffsets;
- size_t SubrecordStart = 0;
-};
-}
-}
-
-#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h
deleted file mode 100644
index 002f885..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h
+++ /dev/null
@@ -1,48 +0,0 @@
-//===- MemoryTypeTableBuilder.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_MEMORYTYPETABLEBUILDER_H
-#define LLVM_DEBUGINFO_CODEVIEW_MEMORYTYPETABLEBUILDER_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
-#include <vector>
-
-namespace llvm {
-namespace codeview {
-
-class MemoryTypeTableBuilder : public TypeTableBuilder {
-public:
- MemoryTypeTableBuilder() {}
-
- bool empty() const { return Records.empty(); }
-
- template <typename TFunc> void ForEachRecord(TFunc Func) {
- uint32_t Index = TypeIndex::FirstNonSimpleIndex;
-
- for (StringRef R : Records) {
- Func(TypeIndex(Index), R);
- ++Index;
- }
- }
-
-protected:
- TypeIndex writeRecord(llvm::StringRef Data) override;
-
-private:
- std::vector<StringRef> Records;
- BumpPtrAllocator RecordStorage;
- DenseMap<StringRef, TypeIndex> HashedRecords;
-};
-
-} // end namespace codeview
-} // end namespace llvm
-
-#endif // LLVM_DEBUGINFO_CODEVIEW_MEMORYTYPETABLEBUILDER_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/MethodListRecordBuilder.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/MethodListRecordBuilder.h
deleted file mode 100644
index faa404d..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/MethodListRecordBuilder.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===- MethodListRecordBuilder.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_METHODLISTRECORDBUILDER_H
-#define LLVM_DEBUGINFO_CODEVIEW_METHODLISTRECORDBUILDER_H
-
-#include "llvm/DebugInfo/CodeView/ListRecordBuilder.h"
-
-namespace llvm {
-namespace codeview {
-
-class MethodInfo;
-
-class MethodListRecordBuilder : public ListRecordBuilder {
-private:
- MethodListRecordBuilder(const MethodListRecordBuilder &) = delete;
- MethodListRecordBuilder &operator=(const MethodListRecordBuilder &) = delete;
-
-public:
- MethodListRecordBuilder();
-
- void writeMethod(MemberAccess Access, MethodKind Kind, MethodOptions Options,
- TypeIndex Type, int32_t VTableSlotOffset);
- void writeMethod(const MethodInfo &Method);
-};
-}
-}
-
-#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstream.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstream.h
index 6affac8..8860ae4 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstream.h
+++ b/contrib/llvm/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/CodeView/StreamArray.h"
-#include "llvm/DebugInfo/CodeView/StreamRef.h"
+#include "llvm/DebugInfo/MSF/StreamArray.h"
+#include "llvm/DebugInfo/MSF/StreamRef.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
@@ -59,29 +59,31 @@ struct ColumnNumberEntry {
class ModuleSubstream {
public:
ModuleSubstream();
- ModuleSubstream(ModuleSubstreamKind Kind, StreamRef Data);
- static Error initialize(StreamRef Stream, ModuleSubstream &Info);
+ ModuleSubstream(ModuleSubstreamKind Kind, msf::ReadableStreamRef Data);
+ static Error initialize(msf::ReadableStreamRef Stream, ModuleSubstream &Info);
uint32_t getRecordLength() const;
ModuleSubstreamKind getSubstreamKind() const;
- StreamRef getRecordData() const;
+ msf::ReadableStreamRef getRecordData() const;
private:
ModuleSubstreamKind Kind;
- StreamRef Data;
+ msf::ReadableStreamRef Data;
};
-template <> struct VarStreamArrayExtractor<ModuleSubstream> {
- Error operator()(StreamRef Stream, uint32_t &Length,
- ModuleSubstream &Info) const {
- if (auto EC = ModuleSubstream::initialize(Stream, Info))
+typedef msf::VarStreamArray<ModuleSubstream> ModuleSubstreamArray;
+} // namespace codeview
+
+namespace msf {
+template <> struct VarStreamArrayExtractor<codeview::ModuleSubstream> {
+ Error operator()(ReadableStreamRef Stream, uint32_t &Length,
+ codeview::ModuleSubstream &Info) const {
+ if (auto EC = codeview::ModuleSubstream::initialize(Stream, Info))
return EC;
Length = Info.getRecordLength();
return Error::success();
}
};
-
-typedef VarStreamArray<ModuleSubstream> ModuleSubstreamArray;
-}
-}
+} // namespace msf
+} // namespace llvm
#endif // LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAM_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h
index 6df2309..f9927d6 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h
@@ -10,28 +10,75 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAMVISITOR_H
#define LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAMVISITOR_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/DebugInfo/CodeView/Line.h"
#include "llvm/DebugInfo/CodeView/ModuleSubstream.h"
-#include "llvm/DebugInfo/CodeView/StreamReader.h"
-#include "llvm/DebugInfo/CodeView/StreamRef.h"
+#include "llvm/DebugInfo/MSF/StreamArray.h"
+#include "llvm/DebugInfo/MSF/StreamReader.h"
+#include "llvm/DebugInfo/MSF/StreamRef.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
namespace llvm {
+
namespace codeview {
struct LineColumnEntry {
support::ulittle32_t NameIndex;
- FixedStreamArray<LineNumberEntry> LineNumbers;
- FixedStreamArray<ColumnNumberEntry> Columns;
+ msf::FixedStreamArray<LineNumberEntry> LineNumbers;
+ msf::FixedStreamArray<ColumnNumberEntry> Columns;
};
-template <> class VarStreamArrayExtractor<LineColumnEntry> {
+struct FileChecksumEntry {
+ uint32_t FileNameOffset; // Byte offset of filename in global stringtable.
+ FileChecksumKind Kind; // The type of checksum.
+ ArrayRef<uint8_t> Checksum; // The bytes of the checksum.
+};
+
+typedef msf::VarStreamArray<LineColumnEntry> LineInfoArray;
+typedef msf::VarStreamArray<FileChecksumEntry> FileChecksumArray;
+
+class IModuleSubstreamVisitor {
public:
- VarStreamArrayExtractor(const LineSubstreamHeader *Header) : Header(Header) {}
+ virtual ~IModuleSubstreamVisitor() = default;
- Error operator()(StreamRef Stream, uint32_t &Len,
- LineColumnEntry &Item) const {
+ virtual Error visitUnknown(ModuleSubstreamKind Kind,
+ msf::ReadableStreamRef Data) = 0;
+ virtual Error visitSymbols(msf::ReadableStreamRef Data);
+ virtual Error visitLines(msf::ReadableStreamRef Data,
+ const LineSubstreamHeader *Header,
+ const LineInfoArray &Lines);
+ virtual Error visitStringTable(msf::ReadableStreamRef Data);
+ virtual Error visitFileChecksums(msf::ReadableStreamRef 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);
+};
+
+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,
+ codeview::LineColumnEntry &Item) const {
+ using namespace codeview;
const LineFileBlockHeader *BlockHeader;
StreamReader Reader(Stream);
if (auto EC = Reader.readObject(BlockHeader))
@@ -61,19 +108,14 @@ public:
}
private:
- const LineSubstreamHeader *Header;
+ const codeview::LineSubstreamHeader *Header;
};
-struct FileChecksumEntry {
- uint32_t FileNameOffset; // Byte offset of filename in global stringtable.
- FileChecksumKind Kind; // The type of checksum.
- ArrayRef<uint8_t> Checksum; // The bytes of the checksum.
-};
-
-template <> class VarStreamArrayExtractor<FileChecksumEntry> {
+template <> class VarStreamArrayExtractor<codeview::FileChecksumEntry> {
public:
- Error operator()(StreamRef Stream, uint32_t &Len,
- FileChecksumEntry &Item) const {
+ Error operator()(ReadableStreamRef Stream, uint32_t &Len,
+ codeview::FileChecksumEntry &Item) const {
+ using namespace codeview;
const FileChecksum *Header;
StreamReader Reader(Stream);
if (auto EC = Reader.readObject(Header))
@@ -87,35 +129,8 @@ public:
}
};
-typedef VarStreamArray<LineColumnEntry> LineInfoArray;
-typedef VarStreamArray<FileChecksumEntry> FileChecksumArray;
-
-class IModuleSubstreamVisitor {
-public:
- virtual ~IModuleSubstreamVisitor() {}
-
- virtual Error visitUnknown(ModuleSubstreamKind Kind, StreamRef Data) = 0;
- virtual Error visitSymbols(StreamRef Data);
- virtual Error visitLines(StreamRef Data, const LineSubstreamHeader *Header,
- const LineInfoArray &Lines);
- virtual Error visitStringTable(StreamRef Data);
- virtual Error visitFileChecksums(StreamRef Data,
- const FileChecksumArray &Checksums);
- virtual Error visitFrameData(StreamRef Data);
- virtual Error visitInlineeLines(StreamRef Data);
- virtual Error visitCrossScopeImports(StreamRef Data);
- virtual Error visitCrossScopeExports(StreamRef Data);
- virtual Error visitILLines(StreamRef Data);
- virtual Error visitFuncMDTokenMap(StreamRef Data);
- virtual Error visitTypeMDTokenMap(StreamRef Data);
- virtual Error visitMergedAssemblyInput(StreamRef Data);
- virtual Error visitCoffSymbolRVA(StreamRef Data);
-};
-
-Error visitModuleSubstream(const ModuleSubstream &R,
- IModuleSubstreamVisitor &V);
+} // end namespace msf
-} // namespace codeview
-} // namespace llvm
+} // end namespace llvm
#endif // LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAMVISITOR_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h
index 84179f5..97b6f56 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h
@@ -13,8 +13,11 @@
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Endian.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/DebugInfo/MSF/StreamReader.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
#include <cinttypes>
#include <tuple>
@@ -24,8 +27,12 @@ using llvm::support::little32_t;
using llvm::support::ulittle16_t;
using llvm::support::ulittle32_t;
+/// Limit on the size of all codeview symbol and type records, including the
+/// RecordPrefix. MSVC does not emit any records larger than this.
+enum : unsigned { MaxRecordLength = 0xFF00 };
+
struct RecordPrefix {
- ulittle16_t RecordLen; // Record length, starting from &Leaf.
+ ulittle16_t RecordLen; // Record length, starting from &RecordKind.
ulittle16_t RecordKind; // Record kind enum (SymRecordKind or TypeRecordKind)
};
@@ -34,54 +41,40 @@ struct RecordPrefix {
StringRef getBytesAsCharacters(ArrayRef<uint8_t> LeafData);
StringRef getBytesAsCString(ArrayRef<uint8_t> LeafData);
-/// Consumes sizeof(T) bytes from the given byte sequence. Returns an error if
-/// there are not enough bytes remaining. Reinterprets the consumed bytes as a
-/// T object and points 'Res' at them.
-template <typename T, typename U>
-inline std::error_code consumeObject(U &Data, const T *&Res) {
- if (Data.size() < sizeof(*Res))
- return std::make_error_code(std::errc::illegal_byte_sequence);
- Res = reinterpret_cast<const T *>(Data.data());
- Data = Data.drop_front(sizeof(*Res));
- return std::error_code();
-}
-
-inline std::error_code consume(ArrayRef<uint8_t> &Data) {
- return std::error_code();
-}
+inline Error consume(msf::StreamReader &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.
-std::error_code consume(ArrayRef<uint8_t> &Data, APSInt &Num);
-std::error_code consume(StringRef &Data, APSInt &Num);
+Error consume(msf::StreamReader &Reader, APSInt &Num);
/// Decodes a numeric leaf value that is known to be a particular type.
-std::error_code consume_numeric(ArrayRef<uint8_t> &Data, uint64_t &Value);
+Error consume_numeric(msf::StreamReader &Reader, uint64_t &Value);
/// Decodes signed and unsigned fixed-length integers.
-std::error_code consume(ArrayRef<uint8_t> &Data, uint32_t &Item);
-std::error_code consume(StringRef &Data, uint32_t &Item);
-std::error_code consume(ArrayRef<uint8_t> &Data, int32_t &Item);
+Error consume(msf::StreamReader &Reader, uint32_t &Item);
+Error consume(msf::StreamReader &Reader, int32_t &Item);
/// Decodes a null terminated string.
-std::error_code consume(ArrayRef<uint8_t> &Data, StringRef &Item);
+Error consume(msf::StreamReader &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>
-std::error_code consume(ArrayRef<uint8_t> &Data, T *&Item) {
- return consumeObject(Data, Item);
+template <typename T> Error consume(msf::StreamReader &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) {}
- std::error_code deserialize(ArrayRef<uint8_t> &Data) const {
+ Error deserialize(msf::StreamReader &Reader) const {
if (!Func())
- return std::error_code();
- return consume(Data, Item);
+ return Error::success();
+ return consume(Reader, Item);
}
T &Item;
@@ -96,22 +89,8 @@ 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) {}
- std::error_code deserialize(ArrayRef<uint8_t> &Data) const {
- uint32_t N = Func();
- if (N == 0)
- return std::error_code();
-
- uint32_t Size = sizeof(T) * N;
-
- if (Size / sizeof(T) != N)
- return std::make_error_code(std::errc::illegal_byte_sequence);
-
- if (Data.size() < Size)
- return std::make_error_code(std::errc::illegal_byte_sequence);
-
- Item = ArrayRef<T>(reinterpret_cast<const T *>(Data.data()), N);
- Data = Data.drop_front(Size);
- return std::error_code();
+ Error deserialize(msf::StreamReader &Reader) const {
+ return Reader.readArray(Item, Func());
}
ArrayRef<T> &Item;
@@ -121,15 +100,15 @@ 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) {}
- std::error_code deserialize(ArrayRef<uint8_t> &Data) const {
+ Error deserialize(msf::StreamReader &Reader) const {
T Field;
// Stop when we run out of bytes or we hit record padding bytes.
- while (!Data.empty() && Data.front() < LF_PAD0) {
- if (auto EC = consume(Data, Field))
+ while (!Reader.empty() && Reader.peek() < LF_PAD0) {
+ if (auto EC = consume(Reader, Field))
return EC;
Item.push_back(Field);
}
- return std::error_code();
+ return Error::success();
}
std::vector<T> &Item;
@@ -139,21 +118,18 @@ struct serialize_null_term_string_array_impl {
serialize_null_term_string_array_impl(std::vector<StringRef> &Item)
: Item(Item) {}
- std::error_code deserialize(ArrayRef<uint8_t> &Data) const {
- if (Data.empty())
- return std::make_error_code(std::errc::illegal_byte_sequence);
+ Error deserialize(msf::StreamReader &Reader) const {
+ if (Reader.empty())
+ return make_error<CodeViewError>(cv_error_code::insufficient_buffer,
+ "Null terminated string is empty!");
- StringRef Field;
- // Stop when we run out of bytes or we hit record padding bytes.
- while (Data.front() != 0) {
- if (auto EC = consume(Data, Field))
+ while (Reader.peek() != 0) {
+ StringRef Field;
+ if (auto EC = Reader.readZeroString(Field))
return EC;
Item.push_back(Field);
- if (Data.empty())
- return std::make_error_code(std::errc::illegal_byte_sequence);
}
- Data = Data.drop_front(1);
- return std::error_code();
+ return Reader.skip(1);
}
std::vector<StringRef> &Item;
@@ -162,10 +138,9 @@ struct serialize_null_term_string_array_impl {
template <typename T> struct serialize_arrayref_tail_impl {
serialize_arrayref_tail_impl(ArrayRef<T> &Item) : Item(Item) {}
- std::error_code deserialize(ArrayRef<uint8_t> &Data) const {
- uint32_t Count = Data.size() / sizeof(T);
- Item = ArrayRef<T>(reinterpret_cast<const T *>(Data.begin()), Count);
- return std::error_code();
+ Error deserialize(msf::StreamReader &Reader) const {
+ uint32_t Count = Reader.bytesRemaining() / sizeof(T);
+ return Reader.readArray(Item, Count);
}
ArrayRef<T> &Item;
@@ -174,8 +149,8 @@ template <typename T> struct serialize_arrayref_tail_impl {
template <typename T> struct serialize_numeric_impl {
serialize_numeric_impl(T &Item) : Item(Item) {}
- std::error_code deserialize(ArrayRef<uint8_t> &Data) const {
- return consume_numeric(Data, Item);
+ Error deserialize(msf::StreamReader &Reader) const {
+ return consume_numeric(Reader, Item);
}
T &Item;
@@ -226,52 +201,50 @@ template <typename T> serialize_numeric_impl<T> serialize_numeric(T &Item) {
#define CV_NUMERIC_FIELD(I) serialize_numeric(I)
template <typename T, typename U>
-std::error_code consume(ArrayRef<uint8_t> &Data,
- const serialize_conditional_impl<T, U> &Item) {
- return Item.deserialize(Data);
+Error consume(msf::StreamReader &Reader,
+ const serialize_conditional_impl<T, U> &Item) {
+ return Item.deserialize(Reader);
}
template <typename T, typename U>
-std::error_code consume(ArrayRef<uint8_t> &Data,
- const serialize_array_impl<T, U> &Item) {
- return Item.deserialize(Data);
+Error consume(msf::StreamReader &Reader,
+ const serialize_array_impl<T, U> &Item) {
+ return Item.deserialize(Reader);
}
-inline std::error_code
-consume(ArrayRef<uint8_t> &Data,
- const serialize_null_term_string_array_impl &Item) {
- return Item.deserialize(Data);
+inline Error consume(msf::StreamReader &Reader,
+ const serialize_null_term_string_array_impl &Item) {
+ return Item.deserialize(Reader);
}
template <typename T>
-std::error_code consume(ArrayRef<uint8_t> &Data,
- const serialize_vector_tail_impl<T> &Item) {
- return Item.deserialize(Data);
+Error consume(msf::StreamReader &Reader,
+ const serialize_vector_tail_impl<T> &Item) {
+ return Item.deserialize(Reader);
}
template <typename T>
-std::error_code consume(ArrayRef<uint8_t> &Data,
- const serialize_arrayref_tail_impl<T> &Item) {
- return Item.deserialize(Data);
+Error consume(msf::StreamReader &Reader,
+ const serialize_arrayref_tail_impl<T> &Item) {
+ return Item.deserialize(Reader);
}
template <typename T>
-std::error_code consume(ArrayRef<uint8_t> &Data,
- const serialize_numeric_impl<T> &Item) {
- return Item.deserialize(Data);
+Error consume(msf::StreamReader &Reader,
+ const serialize_numeric_impl<T> &Item) {
+ return Item.deserialize(Reader);
}
template <typename T, typename U, typename... Args>
-std::error_code consume(ArrayRef<uint8_t> &Data, T &&X, U &&Y,
- Args &&... Rest) {
- if (auto EC = consume(Data, X))
+Error consume(msf::StreamReader &Reader, T &&X, U &&Y, Args &&... Rest) {
+ if (auto EC = consume(Reader, X))
return EC;
- return consume(Data, Y, std::forward<Args>(Rest)...);
+ return consume(Reader, Y, std::forward<Args>(Rest)...);
}
#define CV_DESERIALIZE(...) \
if (auto EC = consume(__VA_ARGS__)) \
- return EC;
+ return std::move(EC);
}
}
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/StreamArray.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/StreamArray.h
deleted file mode 100644
index 0b9349a..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/StreamArray.h
+++ /dev/null
@@ -1,275 +0,0 @@
-//===- StreamArray.h - Array backed by an arbitrary stream ----------------===//
-//
-// 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_STREAMARRAY_H
-#define LLVM_DEBUGINFO_CODEVIEW_STREAMARRAY_H
-
-#include "llvm/DebugInfo/CodeView/StreamRef.h"
-#include "llvm/Support/Error.h"
-
-#include <functional>
-#include <type_traits>
-
-namespace llvm {
-namespace codeview {
-
-/// VarStreamArrayExtractor is intended to be specialized to provide customized
-/// extraction logic. On input it receives a StreamRef pointing to the
-/// beginning of the next record, but where the length of the record is not yet
-/// known. Upon completion, it should return an appropriate Error instance if
-/// a record could not be extracted, or if one could be extracted it should
-/// return success and set Len to the number of bytes this record occupied in
-/// the underlying stream, and it should fill out the fields of the value type
-/// Item appropriately to represent the current record.
-///
-/// You can specialize this template for your own custom value types to avoid
-/// having to specify a second template argument to VarStreamArray (documented
-/// below).
-template <typename T> struct VarStreamArrayExtractor {
- // Method intentionally deleted. You must provide an explicit specialization
- // with the following method implemented.
- Error operator()(StreamRef Stream, uint32_t &Len, T &Item) const = delete;
-};
-
-/// VarStreamArray represents an array of variable length records backed by a
-/// stream. This could be a contiguous sequence of bytes in memory, it could
-/// be a file on disk, or it could be a PDB stream where bytes are stored as
-/// discontiguous blocks in a file. Usually it is desirable to treat arrays
-/// as contiguous blocks of memory, but doing so with large PDB files, for
-/// example, could mean allocating huge amounts of memory just to allow
-/// re-ordering of stream data to be contiguous before iterating over it. By
-/// abstracting this out, we need not duplicate this memory, and we can
-/// iterate over arrays in arbitrarily formatted streams. Elements are parsed
-/// lazily on iteration, so there is no upfront cost associated with building
-/// a VarStreamArray, no matter how large it may be.
-///
-/// You create a VarStreamArray by specifying a ValueType and an Extractor type.
-/// If you do not specify an Extractor type, it expects you to specialize
-/// VarStreamArrayExtractor<T> for your ValueType.
-///
-/// By default an Extractor is default constructed in the class, but in some
-/// cases you might find it useful for an Extractor to maintain state across
-/// extractions. In this case you can provide your own Extractor through a
-/// secondary constructor. The following examples show various ways of
-/// creating a VarStreamArray.
-///
-/// // Will use VarStreamArrayExtractor<MyType> as the extractor.
-/// VarStreamArray<MyType> MyTypeArray;
-///
-/// // Will use a default-constructed MyExtractor as the extractor.
-/// VarStreamArray<MyType, MyExtractor> MyTypeArray2;
-///
-/// // Will use the specific instance of MyExtractor provided.
-/// // MyExtractor need not be default-constructible in this case.
-/// MyExtractor E(SomeContext);
-/// VarStreamArray<MyType, MyExtractor> MyTypeArray3(E);
-///
-template <typename ValueType, typename Extractor> class VarStreamArrayIterator;
-
-template <typename ValueType,
- typename Extractor = VarStreamArrayExtractor<ValueType>>
-class VarStreamArray {
- friend class VarStreamArrayIterator<ValueType, Extractor>;
-
-public:
- typedef VarStreamArrayIterator<ValueType, Extractor> Iterator;
-
- VarStreamArray() {}
- explicit VarStreamArray(const Extractor &E) : E(E) {}
-
- explicit VarStreamArray(StreamRef Stream) : Stream(Stream) {}
- VarStreamArray(StreamRef Stream, const Extractor &E) : Stream(Stream), E(E) {}
-
- VarStreamArray(const VarStreamArray<ValueType, Extractor> &Other)
- : Stream(Other.Stream), E(Other.E) {}
-
- Iterator begin(bool *HadError = nullptr) const {
- return Iterator(*this, E, HadError);
- }
-
- Iterator end() const { return Iterator(E); }
-
- const Extractor &getExtractor() const { return E; }
-
- StreamRef getUnderlyingStream() const { return Stream; }
-
-private:
- StreamRef Stream;
- Extractor E;
-};
-
-template <typename ValueType, typename Extractor> class VarStreamArrayIterator {
- typedef VarStreamArrayIterator<ValueType, Extractor> IterType;
- typedef VarStreamArray<ValueType, Extractor> ArrayType;
-
-public:
- VarStreamArrayIterator(const ArrayType &Array, const Extractor &E,
- bool *HadError = nullptr)
- : IterRef(Array.Stream), Array(&Array), HadError(HadError), Extract(E) {
- if (IterRef.getLength() == 0)
- moveToEnd();
- else {
- auto EC = Extract(IterRef, ThisLen, ThisValue);
- if (EC) {
- consumeError(std::move(EC));
- markError();
- }
- }
- }
- VarStreamArrayIterator() {}
- explicit VarStreamArrayIterator(const Extractor &E) : Extract(E) {}
- ~VarStreamArrayIterator() {}
-
- bool operator==(const IterType &R) const {
- if (Array && R.Array) {
- // Both have a valid array, make sure they're same.
- assert(Array == R.Array);
- return IterRef == R.IterRef;
- }
-
- // Both iterators are at the end.
- if (!Array && !R.Array)
- return true;
-
- // One is not at the end and one is.
- return false;
- }
-
- bool operator!=(const IterType &R) { return !(*this == R); }
-
- const ValueType &operator*() const {
- assert(Array && !HasError);
- return ThisValue;
- }
-
- IterType &operator++() {
- // We are done with the current record, discard it so that we are
- // positioned at the next record.
- IterRef = IterRef.drop_front(ThisLen);
- if (IterRef.getLength() == 0) {
- // There is nothing after the current record, we must make this an end
- // iterator.
- moveToEnd();
- } else {
- // There is some data after the current record.
- auto EC = Extract(IterRef, ThisLen, ThisValue);
- if (EC) {
- consumeError(std::move(EC));
- markError();
- } else if (ThisLen == 0) {
- // An empty record? Make this an end iterator.
- moveToEnd();
- }
- }
- return *this;
- }
-
- IterType operator++(int) {
- IterType Original = *this;
- ++*this;
- return Original;
- }
-
-private:
- void moveToEnd() {
- Array = nullptr;
- ThisLen = 0;
- }
- void markError() {
- moveToEnd();
- HasError = true;
- if (HadError != nullptr)
- *HadError = true;
- }
-
- ValueType ThisValue;
- StreamRef IterRef;
- const ArrayType *Array{nullptr};
- uint32_t ThisLen{0};
- bool HasError{false};
- bool *HadError{nullptr};
- Extractor Extract;
-};
-
-template <typename T> class FixedStreamArrayIterator;
-
-template <typename T> class FixedStreamArray {
- friend class FixedStreamArrayIterator<T>;
-
-public:
- FixedStreamArray() : Stream() {}
- FixedStreamArray(StreamRef Stream) : Stream(Stream) {
- assert(Stream.getLength() % sizeof(T) == 0);
- }
-
- const T &operator[](uint32_t Index) const {
- assert(Index < size());
- uint32_t Off = Index * sizeof(T);
- ArrayRef<uint8_t> Data;
- if (auto EC = Stream.readBytes(Off, sizeof(T), Data)) {
- assert(false && "Unexpected failure reading from stream");
- // This should never happen since we asserted that the stream length was
- // an exact multiple of the element size.
- consumeError(std::move(EC));
- }
- return *reinterpret_cast<const T *>(Data.data());
- }
-
- uint32_t size() const { return Stream.getLength() / sizeof(T); }
-
- FixedStreamArrayIterator<T> begin() const {
- return FixedStreamArrayIterator<T>(*this, 0);
- }
- FixedStreamArrayIterator<T> end() const {
- return FixedStreamArrayIterator<T>(*this, size());
- }
-
- StreamRef getUnderlyingStream() const { return Stream; }
-
-private:
- StreamRef Stream;
-};
-
-template <typename T> class FixedStreamArrayIterator {
-public:
- FixedStreamArrayIterator(const FixedStreamArray<T> &Array, uint32_t Index)
- : Array(Array), Index(Index) {}
-
- bool operator==(const FixedStreamArrayIterator<T> &R) {
- assert(&Array == &R.Array);
- return Index == R.Index;
- }
-
- bool operator!=(const FixedStreamArrayIterator<T> &R) {
- return !(*this == R);
- }
-
- const T &operator*() const { return Array[Index]; }
-
- FixedStreamArrayIterator<T> &operator++() {
- assert(Index < Array.size());
- ++Index;
- return *this;
- }
-
- FixedStreamArrayIterator<T> operator++(int) {
- FixedStreamArrayIterator<T> Original = *this;
- ++*this;
- return Original;
- }
-
-private:
- const FixedStreamArray<T> &Array;
- uint32_t Index;
-};
-
-} // namespace codeview
-} // namespace llvm
-
-#endif // LLVM_DEBUGINFO_CODEVIEW_STREAMARRAY_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/StreamInterface.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/StreamInterface.h
deleted file mode 100644
index 241aec4..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/StreamInterface.h
+++ /dev/null
@@ -1,55 +0,0 @@
-//===- StreamInterface.h - Base interface for a stream of data --*- 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_STREAMINTERFACE_H
-#define LLVM_DEBUGINFO_CODEVIEW_STREAMINTERFACE_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/Support/Error.h"
-#include <cstdint>
-
-namespace llvm {
-namespace codeview {
-
-/// StreamInterface abstracts the notion of a data stream. This way, an
-/// implementation could implement trivial reading from a contiguous memory
-/// buffer or, as in the case of PDB files, reading from a set of possibly
-/// discontiguous blocks. The implementation is required to return references
-/// to stable memory, so if this is not possible (for example in the case of
-/// a PDB file with discontiguous blocks, it must keep its own pool of temp
-/// storage.
-class StreamInterface {
-public:
- virtual ~StreamInterface() {}
-
- // Given an offset into the stream and a number of bytes, attempt to read
- // the bytes and set the output ArrayRef to point to a reference into the
- // stream, without copying any data.
- virtual Error readBytes(uint32_t Offset, uint32_t Size,
- ArrayRef<uint8_t> &Buffer) const = 0;
-
- // Given an offset into the stream, read as much as possible without copying
- // any data.
- virtual Error readLongestContiguousChunk(uint32_t Offset,
- ArrayRef<uint8_t> &Buffer) const = 0;
-
- // Attempt to write the given bytes into the stream at the desired offset.
- // This will always necessitate a copy. Cannot shrink or grow the stream,
- // only writes into existing allocated space.
- virtual Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const = 0;
-
- virtual uint32_t getLength() const = 0;
-
- virtual Error commit() const = 0;
-};
-
-} // end namespace codeview
-} // end namespace llvm
-
-#endif // LLVM_DEBUGINFO_CODEVIEW_STREAMINTERFACE_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/StreamReader.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/StreamReader.h
deleted file mode 100644
index 2f497c2..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/StreamReader.h
+++ /dev/null
@@ -1,111 +0,0 @@
-//===- StreamReader.h - Reads bytes and objects from a stream ---*- 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_STREAMREADER_H
-#define LLVM_DEBUGINFO_CODEVIEW_STREAMREADER_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/DebugInfo/CodeView/CodeViewError.h"
-#include "llvm/DebugInfo/CodeView/StreamArray.h"
-#include "llvm/DebugInfo/CodeView/StreamInterface.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-
-#include <string>
-
-namespace llvm {
-namespace codeview {
-
-class StreamRef;
-
-class StreamReader {
-public:
- StreamReader(StreamRef Stream);
-
- Error readLongestContiguousChunk(ArrayRef<uint8_t> &Buffer);
- Error readBytes(ArrayRef<uint8_t> &Buffer, uint32_t Size);
- Error readInteger(uint16_t &Dest);
- Error readInteger(uint32_t &Dest);
- Error readZeroString(StringRef &Dest);
- Error readFixedString(StringRef &Dest, uint32_t Length);
- Error readStreamRef(StreamRef &Ref);
- Error readStreamRef(StreamRef &Ref, uint32_t Length);
-
- template <typename T> Error readEnum(T &Dest) {
- typename std::underlying_type<T>::type N;
- if (auto EC = readInteger(N))
- return EC;
- Dest = static_cast<T>(N);
- return Error::success();
- }
-
- template <typename T> Error readObject(const T *&Dest) {
- ArrayRef<uint8_t> Buffer;
- if (auto EC = readBytes(Buffer, sizeof(T)))
- return EC;
- Dest = reinterpret_cast<const T *>(Buffer.data());
- return Error::success();
- }
-
- template <typename T>
- Error readArray(ArrayRef<T> &Array, uint32_t NumElements) {
- ArrayRef<uint8_t> Bytes;
- if (NumElements == 0) {
- Array = ArrayRef<T>();
- return Error::success();
- }
-
- if (NumElements > UINT32_MAX/sizeof(T))
- return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
-
- if (auto EC = readBytes(Bytes, NumElements * sizeof(T)))
- return EC;
- Array = ArrayRef<T>(reinterpret_cast<const T *>(Bytes.data()), NumElements);
- return Error::success();
- }
-
- template <typename T, typename U>
- Error readArray(VarStreamArray<T, U> &Array, uint32_t Size) {
- StreamRef S;
- if (auto EC = readStreamRef(S, Size))
- return EC;
- Array = VarStreamArray<T, U>(S, Array.getExtractor());
- return Error::success();
- }
-
- template <typename T>
- Error readArray(FixedStreamArray<T> &Array, uint32_t NumItems) {
- if (NumItems == 0) {
- Array = FixedStreamArray<T>();
- return Error::success();
- }
- uint32_t Length = NumItems * sizeof(T);
- if (Length / sizeof(T) != NumItems)
- return make_error<CodeViewError>(cv_error_code::corrupt_record);
- if (Offset + Length > Stream.getLength())
- return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
- StreamRef View = Stream.slice(Offset, Length);
- Array = FixedStreamArray<T>(View);
- Offset += Length;
- return Error::success();
- }
-
- void setOffset(uint32_t Off) { Offset = Off; }
- uint32_t getOffset() const { return Offset; }
- uint32_t getLength() const { return Stream.getLength(); }
- uint32_t bytesRemaining() const { return getLength() - getOffset(); }
-
-private:
- StreamRef Stream;
- uint32_t Offset;
-};
-} // namespace codeview
-} // namespace llvm
-
-#endif // LLVM_DEBUGINFO_CODEVIEW_STREAMREADER_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/StreamRef.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/StreamRef.h
deleted file mode 100644
index a4f244a..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/StreamRef.h
+++ /dev/null
@@ -1,104 +0,0 @@
-//===- StreamRef.h - A copyable reference to a stream -----------*- 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_STREAMREF_H
-#define LLVM_DEBUGINFO_CODEVIEW_STREAMREF_H
-
-#include "llvm/DebugInfo/CodeView/CodeViewError.h"
-#include "llvm/DebugInfo/CodeView/StreamInterface.h"
-
-namespace llvm {
-namespace codeview {
-
-class StreamRef {
-public:
- StreamRef() : Stream(nullptr), ViewOffset(0), Length(0) {}
- StreamRef(const StreamInterface &Stream)
- : Stream(&Stream), ViewOffset(0), Length(Stream.getLength()) {}
- StreamRef(const StreamInterface &Stream, uint32_t Offset, uint32_t Length)
- : Stream(&Stream), ViewOffset(Offset), Length(Length) {}
-
- // Use StreamRef.slice() instead.
- StreamRef(const StreamRef &S, uint32_t Offset, uint32_t Length) = delete;
-
- Error readBytes(uint32_t Offset, uint32_t Size,
- ArrayRef<uint8_t> &Buffer) const {
- if (ViewOffset + Offset < Offset)
- return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
- if (Size + Offset > Length)
- return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
- return Stream->readBytes(ViewOffset + Offset, Size, Buffer);
- }
-
- // Given an offset into the stream, read as much as possible without copying
- // any data.
- Error readLongestContiguousChunk(uint32_t Offset,
- ArrayRef<uint8_t> &Buffer) const {
- if (Offset >= Length)
- return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
-
- if (auto EC = Stream->readLongestContiguousChunk(Offset, Buffer))
- return EC;
- // This StreamRef might refer to a smaller window over a larger stream. In
- // that case we will have read out more bytes than we should return, because
- // we should not read past the end of the current view.
- uint32_t MaxLength = Length - Offset;
- if (Buffer.size() > MaxLength)
- Buffer = Buffer.slice(0, MaxLength);
- return Error::success();
- }
-
- Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const {
- if (Data.size() + Offset > Length)
- return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
- return Stream->writeBytes(ViewOffset + Offset, Data);
- }
-
- uint32_t getLength() const { return Length; }
-
- Error commit() const { return Stream->commit(); }
-
- StreamRef drop_front(uint32_t N) const {
- if (!Stream)
- return StreamRef();
-
- N = std::min(N, Length);
- return StreamRef(*Stream, ViewOffset + N, Length - N);
- }
-
- StreamRef keep_front(uint32_t N) const {
- if (!Stream)
- return StreamRef();
- N = std::min(N, Length);
- return StreamRef(*Stream, ViewOffset, N);
- }
-
- StreamRef slice(uint32_t Offset, uint32_t Len) const {
- return drop_front(Offset).keep_front(Len);
- }
-
- bool operator==(const StreamRef &Other) const {
- if (Stream != Other.Stream)
- return false;
- if (ViewOffset != Other.ViewOffset)
- return false;
- if (Length != Other.Length)
- return false;
- return true;
- }
-
-private:
- const StreamInterface *Stream;
- uint32_t ViewOffset;
- uint32_t Length;
-};
-}
-}
-
-#endif // LLVM_DEBUGINFO_CODEVIEW_STREAMREF_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/StreamWriter.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/StreamWriter.h
deleted file mode 100644
index 4d393d2..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/StreamWriter.h
+++ /dev/null
@@ -1,86 +0,0 @@
-//===- StreamWriter.h - Writes bytes and objects to a stream ----*- 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_STREAMWRITER_H
-#define LLVM_DEBUGINFO_CODEVIEW_STREAMWRITER_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/DebugInfo/CodeView/CodeViewError.h"
-#include "llvm/DebugInfo/CodeView/StreamArray.h"
-#include "llvm/DebugInfo/CodeView/StreamInterface.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-
-#include <string>
-
-namespace llvm {
-namespace codeview {
-
-class StreamRef;
-
-class StreamWriter {
-public:
- StreamWriter(StreamRef Stream);
-
- Error writeBytes(ArrayRef<uint8_t> Buffer);
- Error writeInteger(uint16_t Dest);
- Error writeInteger(uint32_t Dest);
- Error writeZeroString(StringRef Str);
- Error writeFixedString(StringRef Str);
- Error writeStreamRef(StreamRef Ref);
- Error writeStreamRef(StreamRef Ref, uint32_t Size);
-
- template <typename T> Error writeEnum(T Num) {
- return writeInteger(
- static_cast<typename std::underlying_type<T>::type>(Num));
- }
-
- template <typename T> Error writeObject(const T &Obj) {
- static_assert(!std::is_pointer<T>::value,
- "writeObject should not be used with pointers, to write "
- "the pointed-to value dereference the pointer before calling "
- "writeObject");
- return writeBytes(
- ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&Obj), sizeof(T)));
- }
-
- template <typename T> Error writeArray(ArrayRef<T> Array) {
- if (Array.size() == 0)
- return Error::success();
-
- if (Array.size() > UINT32_MAX / sizeof(T))
- return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
-
- return writeBytes(
- ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Array.data()),
- Array.size() * sizeof(T)));
- }
-
- template <typename T, typename U>
- Error writeArray(VarStreamArray<T, U> Array) {
- return writeStreamRef(Array.getUnderlyingStream());
- }
-
- template <typename T> Error writeArray(FixedStreamArray<T> Array) {
- return writeStreamRef(Array.getUnderlyingStream());
- }
-
- void setOffset(uint32_t Off) { Offset = Off; }
- uint32_t getOffset() const { return Offset; }
- uint32_t getLength() const { return Stream.getLength(); }
- uint32_t bytesRemaining() const { return getLength() - getOffset(); }
-
-private:
- StreamRef Stream;
- uint32_t Offset;
-};
-} // namespace codeview
-} // namespace llvm
-
-#endif // LLVM_DEBUGINFO_CODEVIEW_STREAMREADER_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h
new file mode 100644
index 0000000..13c2bb1
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h
@@ -0,0 +1,74 @@
+//===- SymbolDeserializer.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_SYMBOLDESERIALIZER_H
+#define LLVM_DEBUGINFO_CODEVIEW_SYMBOLDESERIALIZER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#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/Error.h"
+
+namespace llvm {
+namespace codeview {
+class SymbolVisitorDelegate;
+class SymbolDeserializer : public SymbolVisitorCallbacks {
+ struct MappingInfo {
+ explicit MappingInfo(ArrayRef<uint8_t> RecordData)
+ : Stream(RecordData), Reader(Stream), Mapping(Reader) {}
+
+ msf::ByteStream Stream;
+ msf::StreamReader Reader;
+ SymbolRecordMapping Mapping;
+ };
+
+public:
+ explicit SymbolDeserializer(SymbolVisitorDelegate *Delegate)
+ : Delegate(Delegate) {}
+
+ Error visitSymbolBegin(CVSymbol &Record) override {
+ assert(!Mapping && "Already in a symbol mapping!");
+ Mapping = llvm::make_unique<MappingInfo>(Record.content());
+ return Mapping->Mapping.visitSymbolBegin(Record);
+ }
+ Error visitSymbolEnd(CVSymbol &Record) override {
+ assert(Mapping && "Not in a symbol mapping!");
+ auto EC = Mapping->Mapping.visitSymbolEnd(Record);
+ Mapping.reset();
+ return EC;
+ }
+
+#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
+ Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \
+ return visitKnownRecordImpl(CVR, Record); \
+ }
+#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "CVSymbolTypes.def"
+
+private:
+ template <typename T> Error visitKnownRecordImpl(CVSymbol &CVR, T &Record) {
+
+ Record.RecordOffset =
+ Delegate ? Delegate->getRecordOffset(Mapping->Reader) : 0;
+ if (auto EC = Mapping->Mapping.visitKnownRecord(CVR, Record))
+ return EC;
+ return Error::success();
+ }
+
+ SymbolVisitorDelegate *Delegate;
+ std::unique_ptr<MappingInfo> Mapping;
+};
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDumpDelegate.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDumpDelegate.h
index 30b0a40..823636c 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDumpDelegate.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDumpDelegate.h
@@ -10,20 +10,17 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLDUMPDELEGATE_H
#define LLVM_DEBUGINFO_CODEVIEW_SYMBOLDUMPDELEGATE_H
-#include "SymbolVisitorDelegate.h"
-
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
-
-#include <stdint.h>
+#include "llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h"
+#include <cstdint>
namespace llvm {
-
namespace codeview {
class SymbolDumpDelegate : public SymbolVisitorDelegate {
public:
- virtual ~SymbolDumpDelegate() {}
+ ~SymbolDumpDelegate() override = default;
virtual void printRelocatedField(StringRef Label, uint32_t RelocOffset,
uint32_t Offset,
@@ -31,6 +28,7 @@ public:
virtual void printBinaryBlockWithRelocs(StringRef Label,
ArrayRef<uint8_t> Block) = 0;
};
+
} // end namespace codeview
} // end namespace llvm
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDumper.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDumper.h
index 648e40f..a5419b3 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDumper.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDumper.h
@@ -20,30 +20,30 @@ namespace llvm {
class ScopedPrinter;
namespace codeview {
-class CVTypeDumper;
+class TypeDatabase;
/// Dumper for CodeView symbol streams found in COFF object files and PDB files.
class CVSymbolDumper {
public:
- CVSymbolDumper(ScopedPrinter &W, CVTypeDumper &CVTD,
+ CVSymbolDumper(ScopedPrinter &W, TypeDatabase &TypeDB,
std::unique_ptr<SymbolDumpDelegate> ObjDelegate,
bool PrintRecordBytes)
- : W(W), CVTD(CVTD), ObjDelegate(std::move(ObjDelegate)),
+ : W(W), TypeDB(TypeDB), ObjDelegate(std::move(ObjDelegate)),
PrintRecordBytes(PrintRecordBytes) {}
/// 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
/// maintains state about previous records which are necessary for cross
/// type references.
- bool dump(const CVRecord<SymbolKind> &Record);
+ Error dump(CVRecord<SymbolKind> &Record);
/// Dumps the type records in Data. Returns false if there was a type stream
/// parse error, and true otherwise.
- bool dump(const CVSymbolArray &Symbols);
+ Error dump(const CVSymbolArray &Symbols);
private:
ScopedPrinter &W;
- CVTypeDumper &CVTD;
+ TypeDatabase &TypeDB;
std::unique_ptr<SymbolDumpDelegate> ObjDelegate;
bool PrintRecordBytes;
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
index 77e894f..57772d3 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
@@ -11,23 +11,24 @@
#define LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H
#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/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
-#include "llvm/DebugInfo/CodeView/StreamArray.h"
-#include "llvm/DebugInfo/CodeView/StreamInterface.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/MSF/StreamArray.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
+#include <cstddef>
+#include <cstdint>
+#include <vector>
namespace llvm {
namespace codeview {
-using llvm::support::ulittle16_t;
-using llvm::support::ulittle32_t;
-using llvm::support::little32_t;
-
class SymbolRecord {
protected:
explicit SymbolRecord(SymbolRecordKind Kind) : Kind(Kind) {}
@@ -42,216 +43,119 @@ private:
// S_GPROC32, S_LPROC32, S_GPROC32_ID, S_LPROC32_ID, S_LPROC32_DPC or
// S_LPROC32_DPC_ID
class ProcSym : public SymbolRecord {
-public:
- struct Hdr {
- ulittle32_t PtrParent;
- ulittle32_t PtrEnd;
- ulittle32_t PtrNext;
- ulittle32_t CodeSize;
- ulittle32_t DbgStart;
- ulittle32_t DbgEnd;
- TypeIndex FunctionType;
- ulittle32_t CodeOffset;
- ulittle16_t Segment;
- uint8_t Flags; // ProcSymFlags enum
- // Name: The null-terminated name follows.
- };
-
- ProcSym(SymbolRecordKind Kind, uint32_t RecordOffset, const Hdr *H,
- StringRef Name)
- : SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*H), Name(Name) {
- }
+ static constexpr uint32_t RelocationOffset = 32;
- static ErrorOr<ProcSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- StringRef Name;
- CV_DESERIALIZE(Data, H, Name);
-
- return ProcSym(Kind, RecordOffset, H, Name);
- }
+public:
+ explicit ProcSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ ProcSym(SymbolRecordKind Kind, uint32_t RecordOffset)
+ : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
uint32_t getRelocationOffset() const {
- return RecordOffset + offsetof(Hdr, CodeOffset);
- }
-
- uint32_t RecordOffset;
- Hdr Header;
+ return RecordOffset + RelocationOffset;
+ }
+
+ uint32_t Parent = 0;
+ uint32_t End = 0;
+ uint32_t Next = 0;
+ uint32_t CodeSize = 0;
+ uint32_t DbgStart = 0;
+ uint32_t DbgEnd = 0;
+ TypeIndex FunctionType;
+ uint32_t CodeOffset = 0;
+ uint16_t Segment = 0;
+ ProcSymFlags Flags = ProcSymFlags::None;
StringRef Name;
+
+ uint32_t RecordOffset = 0;
};
// S_THUNK32
class Thunk32Sym : public SymbolRecord {
public:
- struct Hdr {
- ulittle32_t Parent;
- ulittle32_t End;
- ulittle32_t Next;
- ulittle32_t Off;
- ulittle16_t Seg;
- ulittle16_t Len;
- uint8_t Ord; // ThunkOrdinal enumeration
- // Name: The null-terminated name follows.
- // Variant portion of thunk
- };
-
- Thunk32Sym(SymbolRecordKind Kind, uint32_t RecordOffset, const Hdr *H,
- StringRef Name, ArrayRef<uint8_t> VariantData)
- : SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*H), Name(Name),
- VariantData(VariantData) {}
-
- static ErrorOr<Thunk32Sym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- StringRef Name;
- ArrayRef<uint8_t> VariantData;
-
- CV_DESERIALIZE(Data, H, Name, CV_ARRAY_FIELD_TAIL(VariantData));
-
- return Thunk32Sym(Kind, RecordOffset, H, Name, VariantData);
- }
+ explicit Thunk32Sym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ Thunk32Sym(SymbolRecordKind Kind, uint32_t RecordOffset)
+ : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
- uint32_t RecordOffset;
- Hdr Header;
+ uint32_t Parent;
+ uint32_t End;
+ uint32_t Next;
+ uint32_t Offset;
+ uint16_t Segment;
+ uint16_t Length;
+ ThunkOrdinal Thunk;
StringRef Name;
ArrayRef<uint8_t> VariantData;
+
+ uint32_t RecordOffset;
};
// S_TRAMPOLINE
class TrampolineSym : public SymbolRecord {
public:
- struct Hdr {
- ulittle16_t Type; // TrampolineType enum
- ulittle16_t Size;
- ulittle32_t ThunkOff;
- ulittle32_t TargetOff;
- ulittle16_t ThunkSection;
- ulittle16_t TargetSection;
- };
-
- TrampolineSym(SymbolRecordKind Kind, uint32_t RecordOffset, const Hdr *H)
- : SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*H) {}
-
- static ErrorOr<TrampolineSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
+ explicit TrampolineSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ TrampolineSym(SymbolRecordKind Kind, uint32_t RecordOffset)
+ : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
- CV_DESERIALIZE(Data, H);
-
- return TrampolineSym(Kind, RecordOffset, H);
- }
+ TrampolineType Type;
+ uint16_t Size;
+ uint32_t ThunkOffset;
+ uint32_t TargetOffset;
+ uint16_t ThunkSection;
+ uint16_t TargetSection;
uint32_t RecordOffset;
- Hdr Header;
};
// S_SECTION
class SectionSym : public SymbolRecord {
public:
- struct Hdr {
- ulittle16_t SectionNumber;
- uint8_t Alignment;
- uint8_t Reserved; // Must be 0
- ulittle32_t Rva;
- ulittle32_t Length;
- ulittle32_t Characteristics;
- // Name: The null-terminated name follows.
- };
-
- SectionSym(SymbolRecordKind Kind, uint32_t RecordOffset, const Hdr *H,
- StringRef Name)
- : SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*H), Name(Name) {
- }
-
- static ErrorOr<SectionSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- StringRef Name;
-
- CV_DESERIALIZE(Data, H, Name);
+ explicit SectionSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ SectionSym(SymbolRecordKind Kind, uint32_t RecordOffset)
+ : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
- return SectionSym(Kind, RecordOffset, H, Name);
- }
+ uint16_t SectionNumber;
+ uint8_t Alignment;
+ uint32_t Rva;
+ uint32_t Length;
+ uint32_t Characteristics;
+ StringRef Name;
uint32_t RecordOffset;
- Hdr Header;
- StringRef Name;
};
// S_COFFGROUP
class CoffGroupSym : public SymbolRecord {
public:
- struct Hdr {
- ulittle32_t Size;
- ulittle32_t Characteristics;
- ulittle32_t Offset;
- ulittle16_t Segment;
- // Name: The null-terminated name follows.
- };
-
- CoffGroupSym(SymbolRecordKind Kind, uint32_t RecordOffset, const Hdr *H,
- StringRef Name)
- : SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*H), Name(Name) {
- }
-
- static ErrorOr<CoffGroupSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- StringRef Name;
-
- CV_DESERIALIZE(Data, H, Name);
+ explicit CoffGroupSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ CoffGroupSym(SymbolRecordKind Kind, uint32_t RecordOffset)
+ : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
- return CoffGroupSym(Kind, RecordOffset, H, Name);
- }
+ uint32_t Size;
+ uint32_t Characteristics;
+ uint32_t Offset;
+ uint16_t Segment;
+ StringRef Name;
uint32_t RecordOffset;
- Hdr Header;
- StringRef Name;
};
class ScopeEndSym : public SymbolRecord {
public:
+ explicit ScopeEndSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
ScopeEndSym(SymbolRecordKind Kind, uint32_t RecordOffset)
: SymbolRecord(Kind), RecordOffset(RecordOffset) {}
- static ErrorOr<ScopeEndSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- return ScopeEndSym(Kind, RecordOffset);
- }
uint32_t RecordOffset;
};
class CallerSym : public SymbolRecord {
public:
- struct Hdr {
- ulittle32_t Count;
- };
-
- CallerSym(SymbolRecordKind Kind, uint32_t RecordOffset, const Hdr *Header,
- ArrayRef<TypeIndex> Indices)
- : SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*Header),
- Indices(Indices) {}
-
- static ErrorOr<CallerSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *Header;
- ArrayRef<TypeIndex> Indices;
-
- CV_DESERIALIZE(Data, Header, CV_ARRAY_FIELD_N(Indices, Header->Count));
-
- return CallerSym(Kind, RecordOffset, Header, Indices);
- }
+ explicit CallerSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ CallerSym(SymbolRecordKind Kind, uint32_t RecordOffset)
+ : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
+ std::vector<TypeIndex> Indices;
uint32_t RecordOffset;
- Hdr Header;
- ArrayRef<TypeIndex> Indices;
};
struct BinaryAnnotationIterator {
@@ -264,7 +168,7 @@ struct BinaryAnnotationIterator {
};
BinaryAnnotationIterator(ArrayRef<uint8_t> Annotations) : Data(Annotations) {}
- BinaryAnnotationIterator() {}
+ BinaryAnnotationIterator() = default;
BinaryAnnotationIterator(const BinaryAnnotationIterator &Other)
: Data(Other.Data) {}
@@ -435,1018 +339,608 @@ private:
// S_INLINESITE
class InlineSiteSym : public SymbolRecord {
public:
- struct Hdr {
- ulittle32_t PtrParent;
- ulittle32_t PtrEnd;
- TypeIndex Inlinee;
- // BinaryAnnotations
- };
-
- InlineSiteSym(uint32_t RecordOffset, const Hdr *H,
- ArrayRef<uint8_t> Annotations)
+ explicit InlineSiteSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ InlineSiteSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::InlineSiteSym),
- RecordOffset(RecordOffset), Header(*H), Annotations(Annotations) {}
-
- static ErrorOr<InlineSiteSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- ArrayRef<uint8_t> Annotations;
- CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Annotations));
-
- return InlineSiteSym(RecordOffset, H, Annotations);
- }
+ RecordOffset(RecordOffset) {}
llvm::iterator_range<BinaryAnnotationIterator> annotations() const {
- return llvm::make_range(BinaryAnnotationIterator(Annotations),
+ return llvm::make_range(BinaryAnnotationIterator(AnnotationData),
BinaryAnnotationIterator());
}
- uint32_t RecordOffset;
- Hdr Header;
+ uint32_t Parent;
+ uint32_t End;
+ TypeIndex Inlinee;
+ std::vector<uint8_t> AnnotationData;
-private:
- ArrayRef<uint8_t> Annotations;
+ uint32_t RecordOffset;
};
// S_PUB32
class PublicSym32 : public SymbolRecord {
public:
- struct Hdr {
- ulittle32_t Index; // Type index, or Metadata token if a managed symbol
- ulittle32_t Off;
- ulittle16_t Seg;
- // Name: The null-terminated name follows.
- };
-
- PublicSym32(uint32_t RecordOffset, const Hdr *H, StringRef Name)
- : SymbolRecord(SymbolRecordKind::PublicSym32), RecordOffset(RecordOffset),
- Header(*H), Name(Name) {}
-
- static ErrorOr<PublicSym32> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- StringRef Name;
- CV_DESERIALIZE(Data, H, Name);
+ explicit PublicSym32(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ explicit PublicSym32(uint32_t RecordOffset)
+ : SymbolRecord(SymbolRecordKind::PublicSym32),
+ RecordOffset(RecordOffset) {}
- return PublicSym32(RecordOffset, H, Name);
- }
+ uint32_t Index;
+ uint32_t Offset;
+ uint16_t Segment;
+ StringRef Name;
uint32_t RecordOffset;
- Hdr Header;
- StringRef Name;
};
// S_REGISTER
class RegisterSym : public SymbolRecord {
public:
- struct Hdr {
- ulittle32_t Index; // Type index or Metadata token
- ulittle16_t Register; // RegisterId enumeration
- // Name: The null-terminated name follows.
- };
-
- RegisterSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
- : SymbolRecord(SymbolRecordKind::RegisterSym), RecordOffset(RecordOffset),
- Header(*H), Name(Name) {}
+ explicit RegisterSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ RegisterSym(uint32_t RecordOffset)
+ : SymbolRecord(SymbolRecordKind::RegisterSym),
+ RecordOffset(RecordOffset) {}
- static ErrorOr<RegisterSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- StringRef Name;
- CV_DESERIALIZE(Data, H, Name);
-
- return RegisterSym(RecordOffset, H, Name);
- }
+ uint32_t Index;
+ RegisterId Register;
+ StringRef Name;
uint32_t RecordOffset;
- Hdr Header;
- StringRef Name;
};
// S_PROCREF, S_LPROCREF
class ProcRefSym : public SymbolRecord {
public:
- struct Hdr {
- ulittle32_t SumName; // SUC of the name (?)
- ulittle32_t SymOffset; // Offset of actual symbol in $$Symbols
- ulittle16_t Mod; // Module containing the actual symbol
- // Name: The null-terminated name follows.
- };
-
- ProcRefSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
- : SymbolRecord(SymbolRecordKind::ProcRefSym), RecordOffset(RecordOffset),
- Header(*H), Name(Name) {}
-
- static ErrorOr<ProcRefSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- StringRef Name;
- CV_DESERIALIZE(Data, H, Name);
-
- return ProcRefSym(RecordOffset, H, Name);
+ explicit ProcRefSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ explicit ProcRefSym(uint32_t RecordOffset)
+ : SymbolRecord(SymbolRecordKind::ProcRefSym), RecordOffset(RecordOffset) {
}
- uint32_t RecordOffset;
- Hdr Header;
+ uint32_t SumName;
+ uint32_t SymOffset;
+ uint16_t Module;
StringRef Name;
+
+ uint32_t RecordOffset;
};
// S_LOCAL
class LocalSym : public SymbolRecord {
public:
- struct Hdr {
- TypeIndex Type;
- ulittle16_t Flags; // LocalSymFlags enum
- // Name: The null-terminated name follows.
- };
-
- LocalSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
- : SymbolRecord(SymbolRecordKind::LocalSym), RecordOffset(RecordOffset),
- Header(*H), Name(Name) {}
+ explicit LocalSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ explicit LocalSym(uint32_t RecordOffset)
+ : SymbolRecord(SymbolRecordKind::LocalSym), RecordOffset(RecordOffset) {}
- static ErrorOr<LocalSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- StringRef Name;
- CV_DESERIALIZE(Data, H, Name);
-
- return LocalSym(RecordOffset, H, Name);
- }
+ TypeIndex Type;
+ LocalSymFlags Flags;
+ StringRef Name;
uint32_t RecordOffset;
- Hdr Header;
- StringRef Name;
};
struct LocalVariableAddrRange {
- ulittle32_t OffsetStart;
- ulittle16_t ISectStart;
- ulittle16_t Range;
+ uint32_t OffsetStart;
+ uint16_t ISectStart;
+ uint16_t Range;
};
struct LocalVariableAddrGap {
- ulittle16_t GapStartOffset;
- ulittle16_t Range;
+ uint16_t GapStartOffset;
+ uint16_t Range;
};
enum : uint16_t { MaxDefRange = 0xf000 };
// S_DEFRANGE
class DefRangeSym : public SymbolRecord {
-public:
- struct Hdr {
- ulittle32_t Program;
- LocalVariableAddrRange Range;
- // LocalVariableAddrGap Gaps[];
- };
+ static constexpr uint32_t RelocationOffset = 8;
- DefRangeSym(uint32_t RecordOffset, const Hdr *H,
- ArrayRef<LocalVariableAddrGap> Gaps)
- : SymbolRecord(SymbolRecordKind::DefRangeSym), RecordOffset(RecordOffset),
- Header(*H), Gaps(Gaps) {}
-
- static ErrorOr<DefRangeSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- ArrayRef<LocalVariableAddrGap> Gaps;
- CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps));
-
- return DefRangeSym(RecordOffset, H, Gaps);
- }
+public:
+ explicit DefRangeSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ explicit DefRangeSym(uint32_t RecordOffset)
+ : SymbolRecord(SymbolRecordKind::DefRangeSym),
+ RecordOffset(RecordOffset) {}
uint32_t getRelocationOffset() const {
- return RecordOffset + offsetof(Hdr, Range);
+ return RecordOffset + RelocationOffset;
}
+ uint32_t Program;
+ LocalVariableAddrRange Range;
+ std::vector<LocalVariableAddrGap> Gaps;
+
uint32_t RecordOffset;
- Hdr Header;
- ArrayRef<LocalVariableAddrGap> Gaps;
};
// S_DEFRANGE_SUBFIELD
class DefRangeSubfieldSym : public SymbolRecord {
+ static constexpr uint32_t RelocationOffset = 12;
+
public:
- struct Hdr {
- ulittle32_t Program;
- ulittle16_t OffsetInParent;
- LocalVariableAddrRange Range;
- // LocalVariableAddrGap Gaps[];
- };
- DefRangeSubfieldSym(uint32_t RecordOffset, const Hdr *H,
- ArrayRef<LocalVariableAddrGap> Gaps)
+ explicit DefRangeSubfieldSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ DefRangeSubfieldSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::DefRangeSubfieldSym),
- RecordOffset(RecordOffset), Header(*H), Gaps(Gaps) {}
-
- static ErrorOr<DefRangeSubfieldSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- ArrayRef<LocalVariableAddrGap> Gaps;
- CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps));
-
- return DefRangeSubfieldSym(RecordOffset, H, Gaps);
- }
+ RecordOffset(RecordOffset) {}
uint32_t getRelocationOffset() const {
- return RecordOffset + offsetof(Hdr, Range);
+ return RecordOffset + RelocationOffset;
}
+ uint32_t Program;
+ uint16_t OffsetInParent;
+ LocalVariableAddrRange Range;
+ std::vector<LocalVariableAddrGap> Gaps;
+
uint32_t RecordOffset;
- Hdr Header;
- ArrayRef<LocalVariableAddrGap> Gaps;
};
// S_DEFRANGE_REGISTER
class DefRangeRegisterSym : public SymbolRecord {
public:
- struct Hdr {
+ struct Header {
ulittle16_t Register;
ulittle16_t MayHaveNoName;
- LocalVariableAddrRange Range;
- // LocalVariableAddrGap Gaps[];
};
-
- DefRangeRegisterSym(uint32_t RecordOffset, const Hdr *H,
- ArrayRef<LocalVariableAddrGap> Gaps)
+ explicit DefRangeRegisterSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ DefRangeRegisterSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::DefRangeRegisterSym),
- RecordOffset(RecordOffset), Header(*H), Gaps(Gaps) {}
-
- DefRangeRegisterSym(uint16_t Register, uint16_t MayHaveNoName,
- uint32_t OffsetStart, uint16_t ISectStart, uint16_t Range,
- ArrayRef<LocalVariableAddrGap> Gaps)
- : SymbolRecord(SymbolRecordKind::DefRangeRegisterSym), RecordOffset(0),
- Gaps(Gaps) {
- Header.Register = Register;
- Header.MayHaveNoName = MayHaveNoName;
- Header.Range.OffsetStart = OffsetStart;
- Header.Range.ISectStart = ISectStart;
- Header.Range.Range = Range;
- }
+ RecordOffset(RecordOffset) {}
- static ErrorOr<DefRangeRegisterSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- ArrayRef<LocalVariableAddrGap> Gaps;
- CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps));
+ uint32_t getRelocationOffset() const { return RecordOffset + sizeof(Header); }
- return DefRangeRegisterSym(RecordOffset, H, Gaps);
- }
-
- uint32_t getRelocationOffset() const {
- return RecordOffset + offsetof(Hdr, Range);
- }
+ Header Hdr;
+ LocalVariableAddrRange Range;
+ std::vector<LocalVariableAddrGap> Gaps;
uint32_t RecordOffset;
- Hdr Header;
- ArrayRef<LocalVariableAddrGap> Gaps;
};
// S_DEFRANGE_SUBFIELD_REGISTER
class DefRangeSubfieldRegisterSym : public SymbolRecord {
public:
- struct Hdr {
- ulittle16_t Register; // Register to which the variable is relative
+ struct Header {
+ ulittle16_t Register;
ulittle16_t MayHaveNoName;
ulittle32_t OffsetInParent;
- LocalVariableAddrRange Range;
- // LocalVariableAddrGap Gaps[];
};
-
- DefRangeSubfieldRegisterSym(uint32_t RecordOffset, const Hdr *H,
- ArrayRef<LocalVariableAddrGap> Gaps)
+ explicit DefRangeSubfieldRegisterSym(SymbolRecordKind Kind)
+ : SymbolRecord(Kind) {}
+ DefRangeSubfieldRegisterSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::DefRangeSubfieldRegisterSym),
- RecordOffset(RecordOffset), Header(*H), Gaps(Gaps) {}
-
- DefRangeSubfieldRegisterSym(uint16_t Register, uint16_t MayHaveNoName,
- uint32_t OffsetInParent,
- ArrayRef<LocalVariableAddrGap> Gaps)
- : SymbolRecord(SymbolRecordKind::DefRangeSubfieldRegisterSym),
- RecordOffset(0), Gaps(Gaps) {
- Header.Register = Register;
- Header.MayHaveNoName = MayHaveNoName;
- Header.OffsetInParent = OffsetInParent;
- }
+ RecordOffset(RecordOffset) {}
- static ErrorOr<DefRangeSubfieldRegisterSym>
- deserialize(SymbolRecordKind Kind, uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- ArrayRef<LocalVariableAddrGap> Gaps;
- CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps));
+ uint32_t getRelocationOffset() const { return RecordOffset + sizeof(Header); }
- return DefRangeSubfieldRegisterSym(RecordOffset, H, Gaps);
- }
-
- uint32_t getRelocationOffset() const {
- return RecordOffset + offsetof(Hdr, Range);
- }
+ Header Hdr;
+ LocalVariableAddrRange Range;
+ std::vector<LocalVariableAddrGap> Gaps;
uint32_t RecordOffset;
- Hdr Header;
- ArrayRef<LocalVariableAddrGap> Gaps;
};
// S_DEFRANGE_FRAMEPOINTER_REL
class DefRangeFramePointerRelSym : public SymbolRecord {
-public:
- struct Hdr {
- little32_t Offset; // Offset from the frame pointer register
- LocalVariableAddrRange Range;
- // LocalVariableAddrGap Gaps[];
- };
+ static constexpr uint32_t RelocationOffset = 8;
- DefRangeFramePointerRelSym(uint32_t RecordOffset, const Hdr *H,
- ArrayRef<LocalVariableAddrGap> Gaps)
+public:
+ explicit DefRangeFramePointerRelSym(SymbolRecordKind Kind)
+ : SymbolRecord(Kind) {}
+ DefRangeFramePointerRelSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelSym),
- RecordOffset(RecordOffset), Header(*H), Gaps(Gaps) {}
-
- static ErrorOr<DefRangeFramePointerRelSym>
- deserialize(SymbolRecordKind Kind, uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- ArrayRef<LocalVariableAddrGap> Gaps;
- CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps));
-
- return DefRangeFramePointerRelSym(RecordOffset, H, Gaps);
- }
+ RecordOffset(RecordOffset) {}
uint32_t getRelocationOffset() const {
- return RecordOffset + offsetof(Hdr, Range);
+ return RecordOffset + RelocationOffset;
}
+ int32_t Offset;
+ LocalVariableAddrRange Range;
+ std::vector<LocalVariableAddrGap> Gaps;
+
uint32_t RecordOffset;
- Hdr Header;
- ArrayRef<LocalVariableAddrGap> Gaps;
};
// S_DEFRANGE_REGISTER_REL
class DefRangeRegisterRelSym : public SymbolRecord {
public:
- struct Hdr {
- ulittle16_t BaseRegister;
+ struct Header {
+ ulittle16_t Register;
ulittle16_t Flags;
little32_t BasePointerOffset;
- LocalVariableAddrRange Range;
- // LocalVariableAddrGap Gaps[];
};
-
- DefRangeRegisterRelSym(uint32_t RecordOffset, const Hdr *H,
- ArrayRef<LocalVariableAddrGap> Gaps)
+ explicit DefRangeRegisterRelSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ explicit DefRangeRegisterRelSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::DefRangeRegisterRelSym),
- RecordOffset(RecordOffset), Header(*H), Gaps(Gaps) {}
-
- DefRangeRegisterRelSym(uint16_t BaseRegister, uint16_t Flags,
- int32_t BasePointerOffset, uint32_t OffsetStart,
- uint16_t ISectStart, uint16_t Range,
- ArrayRef<LocalVariableAddrGap> Gaps)
- : SymbolRecord(SymbolRecordKind::DefRangeRegisterRelSym), RecordOffset(0),
- Gaps(Gaps) {
- Header.BaseRegister = BaseRegister;
- Header.Flags = Flags;
- Header.BasePointerOffset = BasePointerOffset;
- Header.Range.OffsetStart = OffsetStart;
- Header.Range.ISectStart = ISectStart;
- Header.Range.Range = Range;
- }
+ RecordOffset(RecordOffset) {}
- static ErrorOr<DefRangeRegisterRelSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- ArrayRef<LocalVariableAddrGap> Gaps;
- CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps));
+ // The flags implement this notional bitfield:
+ // uint16_t IsSubfield : 1;
+ // uint16_t Padding : 3;
+ // uint16_t OffsetInParent : 12;
+ enum : uint16_t {
+ IsSubfieldFlag = 1,
+ OffsetInParentShift = 4,
+ };
- return DefRangeRegisterRelSym(RecordOffset, H, Gaps);
- }
+ bool hasSpilledUDTMember() const { return Hdr.Flags & IsSubfieldFlag; }
+ uint16_t offsetInParent() const { return Hdr.Flags >> OffsetInParentShift; }
- bool hasSpilledUDTMember() const { return Header.Flags & 1; }
- uint16_t offsetInParent() const { return Header.Flags >> 4; }
+ uint32_t getRelocationOffset() const { return RecordOffset + sizeof(Header); }
- uint32_t getRelocationOffset() const {
- return RecordOffset + offsetof(Hdr, Range);
- }
+ Header Hdr;
+ LocalVariableAddrRange Range;
+ std::vector<LocalVariableAddrGap> Gaps;
uint32_t RecordOffset;
- Hdr Header;
- ArrayRef<LocalVariableAddrGap> Gaps;
};
// S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE
class DefRangeFramePointerRelFullScopeSym : public SymbolRecord {
public:
- struct Hdr {
- little32_t Offset; // Offset from the frame pointer register
- };
-
- DefRangeFramePointerRelFullScopeSym(uint32_t RecordOffset, const Hdr *H)
+ explicit DefRangeFramePointerRelFullScopeSym(SymbolRecordKind Kind)
+ : SymbolRecord(Kind) {}
+ explicit DefRangeFramePointerRelFullScopeSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelFullScopeSym),
- RecordOffset(RecordOffset), Header(*H) {}
-
- static ErrorOr<DefRangeFramePointerRelFullScopeSym>
- deserialize(SymbolRecordKind Kind, uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- CV_DESERIALIZE(Data, H);
+ RecordOffset(RecordOffset) {}
- return DefRangeFramePointerRelFullScopeSym(RecordOffset, H);
- }
+ int32_t Offset;
uint32_t RecordOffset;
- Hdr Header;
};
// S_BLOCK32
class BlockSym : public SymbolRecord {
-public:
- struct Hdr {
- ulittle32_t PtrParent;
- ulittle32_t PtrEnd;
- ulittle32_t CodeSize;
- ulittle32_t CodeOffset;
- ulittle16_t Segment;
- // Name: The null-terminated name follows.
- };
+ static constexpr uint32_t RelocationOffset = 16;
- BlockSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
- : SymbolRecord(SymbolRecordKind::BlockSym), RecordOffset(RecordOffset),
- Header(*H), Name(Name) {}
-
- static ErrorOr<BlockSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- StringRef Name;
- CV_DESERIALIZE(Data, H, Name);
-
- return BlockSym(RecordOffset, H, Name);
- }
+public:
+ explicit BlockSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ explicit BlockSym(uint32_t RecordOffset)
+ : SymbolRecord(SymbolRecordKind::BlockSym), RecordOffset(RecordOffset) {}
uint32_t getRelocationOffset() const {
- return RecordOffset + offsetof(Hdr, CodeOffset);
+ return RecordOffset + RelocationOffset;
}
- uint32_t RecordOffset;
- Hdr Header;
+ uint32_t Parent;
+ uint32_t End;
+ uint32_t CodeSize;
+ uint32_t CodeOffset;
+ uint16_t Segment;
StringRef Name;
+
+ uint32_t RecordOffset;
};
// S_LABEL32
class LabelSym : public SymbolRecord {
-public:
- struct Hdr {
- ulittle32_t CodeOffset;
- ulittle16_t Segment;
- uint8_t Flags; // CV_PROCFLAGS
- // Name: The null-terminated name follows.
- };
-
- LabelSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
- : SymbolRecord(SymbolRecordKind::LabelSym), RecordOffset(RecordOffset),
- Header(*H), Name(Name) {}
+ static constexpr uint32_t RelocationOffset = 4;
- static ErrorOr<LabelSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- StringRef Name;
- CV_DESERIALIZE(Data, H, Name);
-
- return LabelSym(RecordOffset, H, Name);
- }
+public:
+ explicit LabelSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ explicit LabelSym(uint32_t RecordOffset)
+ : SymbolRecord(SymbolRecordKind::LabelSym), RecordOffset(RecordOffset) {}
uint32_t getRelocationOffset() const {
- return RecordOffset + offsetof(Hdr, CodeOffset);
+ return RecordOffset + RelocationOffset;
}
- uint32_t RecordOffset;
- Hdr Header;
+ uint32_t CodeOffset;
+ uint16_t Segment;
+ ProcSymFlags Flags;
StringRef Name;
+
+ uint32_t RecordOffset;
};
// S_OBJNAME
class ObjNameSym : public SymbolRecord {
public:
- struct Hdr {
- ulittle32_t Signature;
- // Name: The null-terminated name follows.
- };
-
- ObjNameSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
- : SymbolRecord(SymbolRecordKind::ObjNameSym), RecordOffset(RecordOffset),
- Header(*H), Name(Name) {}
-
- static ErrorOr<ObjNameSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- StringRef Name;
- CV_DESERIALIZE(Data, H, Name);
-
- return ObjNameSym(RecordOffset, H, Name);
+ explicit ObjNameSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ ObjNameSym(uint32_t RecordOffset)
+ : SymbolRecord(SymbolRecordKind::ObjNameSym), RecordOffset(RecordOffset) {
}
- uint32_t RecordOffset;
- Hdr Header;
+ uint32_t Signature;
StringRef Name;
+
+ uint32_t RecordOffset;
};
// S_ENVBLOCK
class EnvBlockSym : public SymbolRecord {
public:
- struct Hdr {
- uint8_t Reserved;
- // Sequence of zero terminated strings.
- };
-
- EnvBlockSym(uint32_t RecordOffset, const Hdr *H,
- const std::vector<StringRef> &Fields)
- : SymbolRecord(SymbolRecordKind::EnvBlockSym), RecordOffset(RecordOffset),
- Header(*H), Fields(Fields) {}
-
- static ErrorOr<EnvBlockSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- std::vector<StringRef> Fields;
- CV_DESERIALIZE(Data, H, CV_STRING_ARRAY_NULL_TERM(Fields));
+ explicit EnvBlockSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ EnvBlockSym(uint32_t RecordOffset)
+ : SymbolRecord(SymbolRecordKind::EnvBlockSym),
+ RecordOffset(RecordOffset) {}
- return EnvBlockSym(RecordOffset, H, Fields);
- }
+ std::vector<StringRef> Fields;
uint32_t RecordOffset;
- Hdr Header;
- std::vector<StringRef> Fields;
};
// S_EXPORT
class ExportSym : public SymbolRecord {
public:
- struct Hdr {
- ulittle16_t Ordinal;
- ulittle16_t Flags; // ExportFlags
- // Name: The null-terminated name follows.
- };
+ explicit ExportSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ ExportSym(uint32_t RecordOffset)
+ : SymbolRecord(SymbolRecordKind::ExportSym), RecordOffset(RecordOffset) {}
- ExportSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
- : SymbolRecord(SymbolRecordKind::ExportSym), RecordOffset(RecordOffset),
- Header(*H), Name(Name) {}
-
- static ErrorOr<ExportSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- StringRef Name;
- CV_DESERIALIZE(Data, H, Name);
-
- return ExportSym(RecordOffset, H, Name);
- }
+ uint16_t Ordinal;
+ ExportFlags Flags;
+ StringRef Name;
uint32_t RecordOffset;
- Hdr Header;
- StringRef Name;
};
// S_FILESTATIC
class FileStaticSym : public SymbolRecord {
public:
- struct Hdr {
- ulittle32_t Index; // Type Index
- ulittle32_t ModFilenameOffset; // Index of mod filename in string table
- ulittle16_t Flags; // LocalSymFlags enum
- // Name: The null-terminated name follows.
- };
-
- FileStaticSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ explicit FileStaticSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ FileStaticSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::FileStaticSym),
- RecordOffset(RecordOffset), Header(*H), Name(Name) {}
-
- static ErrorOr<FileStaticSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- StringRef Name;
- CV_DESERIALIZE(Data, H, Name);
+ RecordOffset(RecordOffset) {}
- return FileStaticSym(RecordOffset, H, Name);
- }
+ uint32_t Index;
+ uint32_t ModFilenameOffset;
+ LocalSymFlags Flags;
+ StringRef Name;
uint32_t RecordOffset;
- Hdr Header;
- StringRef Name;
};
// S_COMPILE2
class Compile2Sym : public SymbolRecord {
public:
- struct Hdr {
- ulittle32_t flags; // CompileSym2Flags enum
- uint8_t getLanguage() const { return flags & 0xFF; }
- unsigned short Machine; // CPUType enum
- unsigned short VersionFrontendMajor;
- unsigned short VersionFrontendMinor;
- unsigned short VersionFrontendBuild;
- unsigned short VersionBackendMajor;
- unsigned short VersionBackendMinor;
- unsigned short VersionBackendBuild;
- // Version: The null-terminated version string follows.
- // Optional block of zero terminated strings terminated with a double zero.
- };
-
- Compile2Sym(uint32_t RecordOffset, const Hdr *H, StringRef Version)
- : SymbolRecord(SymbolRecordKind::Compile2Sym), RecordOffset(RecordOffset),
- Header(*H), Version(Version) {}
-
- static ErrorOr<Compile2Sym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- StringRef Version;
- CV_DESERIALIZE(Data, H, Version);
+ explicit Compile2Sym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ Compile2Sym(uint32_t RecordOffset)
+ : SymbolRecord(SymbolRecordKind::Compile2Sym),
+ RecordOffset(RecordOffset) {}
+
+ CompileSym2Flags Flags;
+ CPUType Machine;
+ uint16_t VersionFrontendMajor;
+ uint16_t VersionFrontendMinor;
+ uint16_t VersionFrontendBuild;
+ uint16_t VersionBackendMajor;
+ uint16_t VersionBackendMinor;
+ uint16_t VersionBackendBuild;
+ StringRef Version;
+ std::vector<StringRef> ExtraStrings;
- return Compile2Sym(RecordOffset, H, Version);
- }
+ uint8_t getLanguage() const { return static_cast<uint32_t>(Flags) & 0xFF; }
+ uint32_t getFlags() const { return static_cast<uint32_t>(Flags) & ~0xFF; }
uint32_t RecordOffset;
- Hdr Header;
- StringRef Version;
};
// S_COMPILE3
class Compile3Sym : public SymbolRecord {
public:
- struct Hdr {
- ulittle32_t flags; // CompileSym3Flags enum
- uint8_t getLanguage() const { return flags & 0xff; }
- ulittle16_t Machine; // CPUType enum
- ulittle16_t VersionFrontendMajor;
- ulittle16_t VersionFrontendMinor;
- ulittle16_t VersionFrontendBuild;
- ulittle16_t VersionFrontendQFE;
- ulittle16_t VersionBackendMajor;
- ulittle16_t VersionBackendMinor;
- ulittle16_t VersionBackendBuild;
- ulittle16_t VersionBackendQFE;
- // VersionString: The null-terminated version string follows.
- };
-
- Compile3Sym(uint32_t RecordOffset, const Hdr *H, StringRef Version)
- : SymbolRecord(SymbolRecordKind::Compile3Sym), RecordOffset(RecordOffset),
- Header(*H), Version(Version) {}
+ explicit Compile3Sym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ Compile3Sym(uint32_t RecordOffset)
+ : SymbolRecord(SymbolRecordKind::Compile3Sym),
+ RecordOffset(RecordOffset) {}
+
+ CompileSym3Flags Flags;
+ CPUType Machine;
+ uint16_t VersionFrontendMajor;
+ uint16_t VersionFrontendMinor;
+ uint16_t VersionFrontendBuild;
+ uint16_t VersionFrontendQFE;
+ uint16_t VersionBackendMajor;
+ uint16_t VersionBackendMinor;
+ uint16_t VersionBackendBuild;
+ uint16_t VersionBackendQFE;
+ StringRef Version;
- static ErrorOr<Compile3Sym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- StringRef Version;
- CV_DESERIALIZE(Data, H, Version);
-
- return Compile3Sym(RecordOffset, H, Version);
- }
+ uint8_t getLanguage() const { return static_cast<uint32_t>(Flags) & 0xFF; }
+ uint32_t getFlags() const { return static_cast<uint32_t>(Flags) & ~0xFF; }
uint32_t RecordOffset;
- Hdr Header;
- StringRef Version;
};
// S_FRAMEPROC
class FrameProcSym : public SymbolRecord {
public:
- struct Hdr {
- ulittle32_t TotalFrameBytes;
- ulittle32_t PaddingFrameBytes;
- ulittle32_t OffsetToPadding;
- ulittle32_t BytesOfCalleeSavedRegisters;
- ulittle32_t OffsetOfExceptionHandler;
- ulittle16_t SectionIdOfExceptionHandler;
- ulittle32_t Flags;
- };
-
- FrameProcSym(uint32_t RecordOffset, const Hdr *H)
+ explicit FrameProcSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ explicit FrameProcSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::FrameProcSym),
- RecordOffset(RecordOffset), Header(*H) {}
+ RecordOffset(RecordOffset) {}
- static ErrorOr<FrameProcSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- CV_DESERIALIZE(Data, H);
-
- return FrameProcSym(RecordOffset, H);
- }
+ uint32_t TotalFrameBytes;
+ uint32_t PaddingFrameBytes;
+ uint32_t OffsetToPadding;
+ uint32_t BytesOfCalleeSavedRegisters;
+ uint32_t OffsetOfExceptionHandler;
+ uint16_t SectionIdOfExceptionHandler;
+ FrameProcedureOptions Flags;
uint32_t RecordOffset;
- Hdr Header;
};
// S_CALLSITEINFO
class CallSiteInfoSym : public SymbolRecord {
-public:
- struct Hdr {
- ulittle32_t CodeOffset;
- ulittle16_t Segment;
- ulittle16_t Reserved;
- TypeIndex Type;
- };
+ static constexpr uint32_t RelocationOffset = 4;
- CallSiteInfoSym(uint32_t RecordOffset, const Hdr *H)
- : SymbolRecord(SymbolRecordKind::CallSiteInfoSym),
- RecordOffset(RecordOffset), Header(*H) {}
-
- static ErrorOr<CallSiteInfoSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- CV_DESERIALIZE(Data, H);
-
- return CallSiteInfoSym(RecordOffset, H);
- }
+public:
+ explicit CallSiteInfoSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ explicit CallSiteInfoSym(uint32_t RecordOffset)
+ : SymbolRecord(SymbolRecordKind::CallSiteInfoSym) {}
uint32_t getRelocationOffset() const {
- return RecordOffset + offsetof(Hdr, CodeOffset);
+ return RecordOffset + RelocationOffset;
}
+ uint32_t CodeOffset;
+ uint16_t Segment;
+ TypeIndex Type;
+
uint32_t RecordOffset;
- Hdr Header;
};
// S_HEAPALLOCSITE
class HeapAllocationSiteSym : public SymbolRecord {
-public:
- struct Hdr {
- ulittle32_t CodeOffset;
- ulittle16_t Segment;
- ulittle16_t CallInstructionSize;
- TypeIndex Type;
- };
+ static constexpr uint32_t RelocationOffset = 4;
- HeapAllocationSiteSym(uint32_t RecordOffset, const Hdr *H)
+public:
+ explicit HeapAllocationSiteSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ explicit HeapAllocationSiteSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::HeapAllocationSiteSym),
- RecordOffset(RecordOffset), Header(*H) {}
-
- static ErrorOr<HeapAllocationSiteSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- CV_DESERIALIZE(Data, H);
-
- return HeapAllocationSiteSym(RecordOffset, H);
- }
+ RecordOffset(RecordOffset) {}
uint32_t getRelocationOffset() const {
- return RecordOffset + offsetof(Hdr, CodeOffset);
+ return RecordOffset + RelocationOffset;
}
+ uint32_t CodeOffset;
+ uint16_t Segment;
+ uint16_t CallInstructionSize;
+ TypeIndex Type;
+
uint32_t RecordOffset;
- Hdr Header;
};
// S_FRAMECOOKIE
class FrameCookieSym : public SymbolRecord {
-public:
- struct Hdr {
- ulittle32_t CodeOffset;
- ulittle16_t Register;
- uint8_t CookieKind;
- uint8_t Flags;
- };
-
- FrameCookieSym(uint32_t RecordOffset, const Hdr *H)
- : SymbolRecord(SymbolRecordKind::FrameCookieSym),
- RecordOffset(RecordOffset), Header(*H) {}
+ static constexpr uint32_t RelocationOffset = 4;
- static ErrorOr<FrameCookieSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- CV_DESERIALIZE(Data, H);
-
- return FrameCookieSym(RecordOffset, H);
- }
+public:
+ explicit FrameCookieSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ explicit FrameCookieSym(uint32_t RecordOffset)
+ : SymbolRecord(SymbolRecordKind::FrameCookieSym) {}
uint32_t getRelocationOffset() const {
- return RecordOffset + offsetof(Hdr, CodeOffset);
+ return RecordOffset + RelocationOffset;
}
+ uint32_t CodeOffset;
+ uint16_t Register;
+ uint8_t CookieKind;
+ uint8_t Flags;
+
uint32_t RecordOffset;
- Hdr Header;
};
// S_UDT, S_COBOLUDT
class UDTSym : public SymbolRecord {
public:
- struct Hdr {
- TypeIndex Type; // Type of the UDT
- // Name: The null-terminated name follows.
- };
-
- UDTSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
- : SymbolRecord(SymbolRecordKind::UDTSym), RecordOffset(RecordOffset),
- Header(*H), Name(Name) {}
+ explicit UDTSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ explicit UDTSym(uint32_t RecordOffset)
+ : SymbolRecord(SymbolRecordKind::UDTSym) {}
- static ErrorOr<UDTSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- StringRef Name;
- CV_DESERIALIZE(Data, H, Name);
-
- return UDTSym(RecordOffset, H, Name);
- }
+ TypeIndex Type;
+ StringRef Name;
uint32_t RecordOffset;
- Hdr Header;
- StringRef Name;
};
// S_BUILDINFO
class BuildInfoSym : public SymbolRecord {
public:
- struct Hdr {
- ulittle32_t BuildId;
- };
-
- BuildInfoSym(uint32_t RecordOffset, const Hdr *H)
+ explicit BuildInfoSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ BuildInfoSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::BuildInfoSym),
- RecordOffset(RecordOffset), Header(*H) {}
+ RecordOffset(RecordOffset) {}
- static ErrorOr<BuildInfoSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- CV_DESERIALIZE(Data, H);
-
- return BuildInfoSym(RecordOffset, H);
- }
+ uint32_t BuildId;
uint32_t RecordOffset;
- Hdr Header;
};
// S_BPREL32
class BPRelativeSym : public SymbolRecord {
public:
- struct Hdr {
- little32_t Offset; // Offset from the base pointer register
- TypeIndex Type; // Type of the variable
- // Name: The null-terminated name follows.
- };
-
- BPRelativeSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ explicit BPRelativeSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ explicit BPRelativeSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::BPRelativeSym),
- RecordOffset(RecordOffset), Header(*H), Name(Name) {}
-
- static ErrorOr<BPRelativeSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- StringRef Name;
- CV_DESERIALIZE(Data, H, Name);
+ RecordOffset(RecordOffset) {}
- return BPRelativeSym(RecordOffset, H, Name);
- }
+ int32_t Offset;
+ TypeIndex Type;
+ StringRef Name;
uint32_t RecordOffset;
- Hdr Header;
- StringRef Name;
};
// S_REGREL32
class RegRelativeSym : public SymbolRecord {
public:
- struct Hdr {
- ulittle32_t Offset; // Offset from the register
- TypeIndex Type; // Type of the variable
- ulittle16_t Register; // Register to which the variable is relative
- // Name: The null-terminated name follows.
- };
-
- RegRelativeSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ explicit RegRelativeSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ explicit RegRelativeSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::RegRelativeSym),
- RecordOffset(RecordOffset), Header(*H), Name(Name) {}
-
- static ErrorOr<RegRelativeSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- StringRef Name;
- CV_DESERIALIZE(Data, H, Name);
+ RecordOffset(RecordOffset) {}
- return RegRelativeSym(RecordOffset, H, Name);
- }
+ uint32_t Offset;
+ TypeIndex Type;
+ uint16_t Register;
+ StringRef Name;
uint32_t RecordOffset;
- Hdr Header;
- StringRef Name;
};
// S_CONSTANT, S_MANCONSTANT
class ConstantSym : public SymbolRecord {
public:
- struct Hdr {
- TypeIndex Type;
- // Value: The value of the constant.
- // Name: The null-terminated name follows.
- };
-
- ConstantSym(uint32_t RecordOffset, const Hdr *H, const APSInt &Value,
- StringRef Name)
- : SymbolRecord(SymbolRecordKind::ConstantSym), RecordOffset(RecordOffset),
- Header(*H), Value(Value), Name(Name) {}
-
- static ErrorOr<ConstantSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- APSInt Value;
- StringRef Name;
- CV_DESERIALIZE(Data, H, Value, Name);
-
- return ConstantSym(RecordOffset, H, Value, Name);
- }
+ explicit ConstantSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ ConstantSym(uint32_t RecordOffset)
+ : SymbolRecord(SymbolRecordKind::ConstantSym),
+ RecordOffset(RecordOffset) {}
- uint32_t RecordOffset;
- Hdr Header;
+ TypeIndex Type;
APSInt Value;
StringRef Name;
+
+ uint32_t RecordOffset;
};
// S_LDATA32, S_GDATA32, S_LMANDATA, S_GMANDATA
class DataSym : public SymbolRecord {
-public:
- struct Hdr {
- TypeIndex Type;
- ulittle32_t DataOffset;
- ulittle16_t Segment;
- // Name: The null-terminated name follows.
- };
-
- DataSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
- : SymbolRecord(SymbolRecordKind::DataSym), RecordOffset(RecordOffset),
- Header(*H), Name(Name) {}
+ static constexpr uint32_t RelocationOffset = 8;
- static ErrorOr<DataSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- StringRef Name;
- CV_DESERIALIZE(Data, H, Name);
-
- return DataSym(RecordOffset, H, Name);
- }
+public:
+ explicit DataSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ DataSym(uint32_t RecordOffset)
+ : SymbolRecord(SymbolRecordKind::DataSym), RecordOffset(RecordOffset) {}
uint32_t getRelocationOffset() const {
- return RecordOffset + offsetof(Hdr, DataOffset);
+ return RecordOffset + RelocationOffset;
}
- uint32_t RecordOffset;
- Hdr Header;
+ TypeIndex Type;
+ uint32_t DataOffset;
+ uint16_t Segment;
StringRef Name;
+
+ uint32_t RecordOffset;
};
// S_LTHREAD32, S_GTHREAD32
class ThreadLocalDataSym : public SymbolRecord {
-public:
- struct Hdr {
- TypeIndex Type;
- ulittle32_t DataOffset;
- ulittle16_t Segment;
- // Name: The null-terminated name follows.
- };
+ static constexpr uint32_t RelocationOffset = 8;
- ThreadLocalDataSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+public:
+ explicit ThreadLocalDataSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ explicit ThreadLocalDataSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::ThreadLocalDataSym),
- RecordOffset(RecordOffset), Header(*H), Name(Name) {}
-
- static ErrorOr<ThreadLocalDataSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
- const Hdr *H = nullptr;
- StringRef Name;
- CV_DESERIALIZE(Data, H, Name);
-
- return ThreadLocalDataSym(RecordOffset, H, Name);
- }
+ RecordOffset(RecordOffset) {}
uint32_t getRelocationOffset() const {
- return RecordOffset + offsetof(Hdr, DataOffset);
+ return RecordOffset + RelocationOffset;
}
- uint32_t RecordOffset;
- Hdr Header;
+ TypeIndex Type;
+ uint32_t DataOffset;
+ uint16_t Segment;
StringRef Name;
+
+ uint32_t RecordOffset;
};
typedef CVRecord<SymbolKind> CVSymbol;
-typedef VarStreamArray<CVSymbol> CVSymbolArray;
+typedef msf::VarStreamArray<CVSymbol> CVSymbolArray;
-} // namespace codeview
-} // namespace llvm
+} // end namespace codeview
+} // end namespace llvm
-#endif
+#endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h
new file mode 100644
index 0000000..1bd14ed
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h
@@ -0,0 +1,44 @@
+//===- SymbolRecordMapping.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_SYMBOLRECORDMAPPING_H
+#define LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORDMAPPING_H
+
+#include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h"
+#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
+
+namespace llvm {
+namespace msf {
+class StreamReader;
+class StreamWriter;
+}
+
+namespace codeview {
+class SymbolRecordMapping : public SymbolVisitorCallbacks {
+public:
+ explicit SymbolRecordMapping(msf::StreamReader &Reader) : IO(Reader) {}
+ explicit SymbolRecordMapping(msf::StreamWriter &Writer) : IO(Writer) {}
+
+ Error visitSymbolBegin(CVSymbol &Record) override;
+ Error visitSymbolEnd(CVSymbol &Record) override;
+
+#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
+ Error visitKnownRecord(CVSymbol &CVR, Name &Record) override;
+#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "CVSymbolTypes.def"
+
+private:
+ Optional<SymbolKind> Kind;
+
+ CodeViewRecordIO IO;
+};
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolSerializer.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolSerializer.h
new file mode 100644
index 0000000..4eb914e
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolSerializer.h
@@ -0,0 +1,96 @@
+//===- symbolSerializer.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_SYMBOLSERIALIZER_H
+#define LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H
+
+#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"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace codeview {
+
+class SymbolSerializer : public SymbolVisitorCallbacks {
+ uint32_t RecordStart = 0;
+ msf::StreamWriter &Writer;
+ SymbolRecordMapping Mapping;
+ Optional<SymbolKind> CurrentSymbol;
+
+ Error writeRecordPrefix(SymbolKind Kind) {
+ RecordPrefix Prefix;
+ Prefix.RecordKind = Kind;
+ Prefix.RecordLen = 0;
+ if (auto EC = Writer.writeObject(Prefix))
+ return EC;
+ return Error::success();
+ }
+
+public:
+ explicit SymbolSerializer(msf::StreamWriter &Writer)
+ : Writer(Writer), Mapping(Writer) {}
+
+ 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();
+ }
+
+#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
+ virtual Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \
+ return visitKnownRecordImpl(CVR, Record); \
+ }
+#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "CVSymbolTypes.def"
+
+private:
+ template <typename RecordKind>
+ Error visitKnownRecordImpl(CVSymbol &CVR, RecordKind &Record) {
+ return Mapping.visitKnownRecord(CVR, Record);
+ }
+};
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h
new file mode 100644
index 0000000..96a93bf
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h
@@ -0,0 +1,71 @@
+//===- SymbolVisitorCallbackPipeline.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_SYMBOLVISITORCALLBACKPIPELINE_H
+#define LLVM_DEBUGINFO_CODEVIEW_SYMBOLVISITORCALLBACKPIPELINE_H
+
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
+#include "llvm/Support/Error.h"
+#include <vector>
+
+namespace llvm {
+namespace codeview {
+
+class SymbolVisitorCallbackPipeline : public SymbolVisitorCallbacks {
+public:
+ SymbolVisitorCallbackPipeline() = default;
+
+ Error visitUnknownSymbol(CVSymbol &Record) override {
+ for (auto Visitor : Pipeline) {
+ if (auto EC = Visitor->visitUnknownSymbol(Record))
+ return EC;
+ }
+ return Error::success();
+ }
+
+ Error visitSymbolBegin(CVSymbol &Record) override {
+ for (auto Visitor : Pipeline) {
+ if (auto EC = Visitor->visitSymbolBegin(Record))
+ return EC;
+ }
+ return Error::success();
+ }
+
+ Error visitSymbolEnd(CVSymbol &Record) override {
+ for (auto Visitor : Pipeline) {
+ if (auto EC = Visitor->visitSymbolEnd(Record))
+ return EC;
+ }
+ return Error::success();
+ }
+
+ void addCallbackToPipeline(SymbolVisitorCallbacks &Callbacks) {
+ Pipeline.push_back(&Callbacks);
+ }
+
+#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
+ Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \
+ for (auto Visitor : Pipeline) { \
+ if (auto EC = Visitor->visitKnownRecord(CVR, Record)) \
+ return EC; \
+ } \
+ return Error::success(); \
+ }
+#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def"
+
+private:
+ std::vector<SymbolVisitorCallbacks *> Pipeline;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLVISITORCALLBACKPIPELINE_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h
new file mode 100644
index 0000000..aaa9d2e
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h
@@ -0,0 +1,48 @@
+//===- SymbolVisitorCallbacks.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_SYMBOLVISITORCALLBACKS_H
+#define LLVM_DEBUGINFO_CODEVIEW_SYMBOLVISITORCALLBACKS_H
+
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace codeview {
+
+class SymbolVisitorCallbacks {
+ friend class CVSymbolVisitor;
+
+public:
+ virtual ~SymbolVisitorCallbacks() = default;
+
+ /// Action to take on unknown symbols. By default, they are ignored.
+ virtual Error visitUnknownSymbol(CVSymbol &Record) {
+ return Error::success();
+ }
+
+ /// Paired begin/end actions for all symbols. Receives all record data,
+ /// including the fixed-length record prefix. visitSymbolBegin() should
+ /// return
+ /// the type of the Symbol, or an error if it cannot be determined.
+ virtual Error visitSymbolBegin(CVSymbol &Record) { return Error::success(); }
+ virtual Error visitSymbolEnd(CVSymbol &Record) { return Error::success(); }
+
+#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
+ virtual Error visitKnownRecord(CVSymbol &CVR, Name &Record) { \
+ return Error::success(); \
+ }
+#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "CVSymbolTypes.def"
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLVISITORCALLBACKS_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h
index a496516..2b468a2 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h
@@ -10,24 +10,28 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLVISITORDELEGATE_H
#define LLVM_DEBUGINFO_CODEVIEW_SYMBOLVISITORDELEGATE_H
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
-
-#include <stdint.h>
+#include <cstdint>
namespace llvm {
+namespace msf {
+class StreamReader;
+} // end namespace msf
+
namespace codeview {
class SymbolVisitorDelegate {
public:
- virtual ~SymbolVisitorDelegate() {}
+ virtual ~SymbolVisitorDelegate() = default;
- virtual uint32_t getRecordOffset(ArrayRef<uint8_t> Record) = 0;
+ virtual uint32_t getRecordOffset(msf::StreamReader Reader) = 0;
virtual StringRef getFileNameForFileOffset(uint32_t FileOffset) = 0;
virtual StringRef getStringTable() = 0;
};
+
} // end namespace codeview
+
} // end namespace llvm
#endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLVISITORDELEGATE_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabase.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabase.h
new file mode 100644
index 0000000..cccc286
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabase.h
@@ -0,0 +1,55 @@
+//===- TypeDatabase.h - A collection of CodeView type records ---*- 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_TYPEDATABASE_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASE_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/StringSaver.h"
+
+namespace llvm {
+namespace codeview {
+class TypeDatabase {
+public:
+ TypeDatabase() : TypeNameStorage(Allocator) {}
+
+ /// Gets the type index for the next type record.
+ TypeIndex getNextTypeIndex() const;
+
+ /// Records the name of a type, and reserves its type index.
+ void recordType(StringRef Name, CVType Data);
+
+ /// Saves the name in a StringSet and creates a stable StringRef.
+ StringRef saveTypeName(StringRef TypeName);
+
+ StringRef getTypeName(TypeIndex Index) const;
+
+ bool containsTypeIndex(TypeIndex Index) const;
+
+ uint32_t size() const;
+
+private:
+ BumpPtrAllocator Allocator;
+
+ /// All user defined type records in .debug$T live in here. Type indices
+ /// greater than 0x1000 are user defined. Subtract 0x1000 from the index to
+ /// index into this vector.
+ SmallVector<StringRef, 10> CVUDTNames;
+ SmallVector<CVType, 10> TypeRecords;
+
+ StringSaver TypeNameStorage;
+};
+}
+}
+
+#endif \ No newline at end of file
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h
new file mode 100644
index 0000000..39d234c
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h
@@ -0,0 +1,53 @@
+//===-- TypeDatabaseVisitor.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_TYPEDATABASEVISITOR_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASEVISITOR_H
+
+#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
+
+namespace llvm {
+namespace codeview {
+
+/// Dumper for CodeView type streams found in COFF object files and PDB files.
+class TypeDatabaseVisitor : public TypeVisitorCallbacks {
+public:
+ explicit TypeDatabaseVisitor(TypeDatabase &TypeDB) : TypeDB(TypeDB) {}
+
+ /// Paired begin/end actions for all types. Receives all record data,
+ /// including the fixed-length record prefix.
+ Error visitTypeBegin(CVType &Record) override;
+ Error visitTypeEnd(CVType &Record) override;
+ Error visitMemberBegin(CVMemberRecord &Record) override;
+ Error visitMemberEnd(CVMemberRecord &Record) override;
+
+#define TYPE_RECORD(EnumName, EnumVal, Name) \
+ Error visitKnownRecord(CVType &CVR, Name##Record &Record) override;
+#define MEMBER_RECORD(EnumName, EnumVal, Name) \
+ Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override;
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "TypeRecords.def"
+
+private:
+ bool IsInFieldList = false;
+
+ /// Name of the current type. Only valid before visitTypeEnd.
+ StringRef Name;
+
+ TypeDatabase &TypeDB;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_TYPEDUMPER_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
new file mode 100644
index 0000000..dc5eaf8
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
@@ -0,0 +1,136 @@
+//===- TypeDeserializer.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_TYPEDESERIALIZER_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPEDESERIALIZER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#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/Error.h"
+#include <cassert>
+#include <cstdint>
+#include <memory>
+
+namespace llvm {
+namespace codeview {
+
+class TypeDeserializer : public TypeVisitorCallbacks {
+ struct MappingInfo {
+ explicit MappingInfo(ArrayRef<uint8_t> RecordData)
+ : Stream(RecordData), Reader(Stream), Mapping(Reader) {}
+
+ msf::ByteStream Stream;
+ msf::StreamReader Reader;
+ TypeRecordMapping Mapping;
+ };
+
+public:
+ TypeDeserializer() = default;
+
+ Error visitTypeBegin(CVType &Record) override {
+ assert(!Mapping && "Already in a type mapping!");
+ Mapping = llvm::make_unique<MappingInfo>(Record.content());
+ return Mapping->Mapping.visitTypeBegin(Record);
+ }
+
+ Error visitTypeEnd(CVType &Record) override {
+ assert(Mapping && "Not in a type mapping!");
+ auto EC = Mapping->Mapping.visitTypeEnd(Record);
+ Mapping.reset();
+ return EC;
+ }
+
+#define TYPE_RECORD(EnumName, EnumVal, Name) \
+ Error visitKnownRecord(CVType &CVR, Name##Record &Record) override { \
+ return visitKnownRecordImpl<Name##Record>(CVR, Record); \
+ }
+#define MEMBER_RECORD(EnumName, EnumVal, Name)
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "TypeRecords.def"
+
+private:
+ template <typename RecordType>
+ Error visitKnownRecordImpl(CVType &CVR, RecordType &Record) {
+ return Mapping->Mapping.visitKnownRecord(CVR, Record);
+ }
+
+ std::unique_ptr<MappingInfo> Mapping;
+};
+
+class FieldListDeserializer : public TypeVisitorCallbacks {
+ struct MappingInfo {
+ explicit MappingInfo(msf::StreamReader &R)
+ : Reader(R), Mapping(Reader), StartOffset(0) {}
+
+ msf::StreamReader &Reader;
+ TypeRecordMapping Mapping;
+ uint32_t StartOffset;
+ };
+
+public:
+ explicit FieldListDeserializer(msf::StreamReader &Reader) : Mapping(Reader) {
+ CVType FieldList;
+ FieldList.Type = TypeLeafKind::LF_FIELDLIST;
+ consumeError(Mapping.Mapping.visitTypeBegin(FieldList));
+ }
+
+ ~FieldListDeserializer() override {
+ CVType FieldList;
+ FieldList.Type = TypeLeafKind::LF_FIELDLIST;
+ consumeError(Mapping.Mapping.visitTypeEnd(FieldList));
+ }
+
+ Error visitMemberBegin(CVMemberRecord &Record) override {
+ Mapping.StartOffset = Mapping.Reader.getOffset();
+ return Mapping.Mapping.visitMemberBegin(Record);
+ }
+
+ Error visitMemberEnd(CVMemberRecord &Record) override {
+ if (auto EC = Mapping.Mapping.visitMemberEnd(Record))
+ return EC;
+ return Error::success();
+ }
+
+#define TYPE_RECORD(EnumName, EnumVal, Name)
+#define MEMBER_RECORD(EnumName, EnumVal, Name) \
+ Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \
+ return visitKnownMemberImpl<Name##Record>(CVR, Record); \
+ }
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "TypeRecords.def"
+
+private:
+ template <typename RecordType>
+ Error visitKnownMemberImpl(CVMemberRecord &CVR, RecordType &Record) {
+ if (auto EC = Mapping.Mapping.visitKnownMember(CVR, Record))
+ return EC;
+
+ uint32_t EndOffset = Mapping.Reader.getOffset();
+ uint32_t RecordLength = EndOffset - Mapping.StartOffset;
+ Mapping.Reader.setOffset(Mapping.StartOffset);
+ if (auto EC = Mapping.Reader.readBytes(CVR.Data, RecordLength))
+ return EC;
+ assert(Mapping.Reader.getOffset() == EndOffset);
+ return Error::success();
+ }
+ MappingInfo Mapping;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_TYPEDESERIALIZER_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h
new file mode 100644
index 0000000..a466e42
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h
@@ -0,0 +1,67 @@
+//===-- TypeDumpVisitor.h - CodeView type info dumper -----------*- 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_TYPEDUMPVISITOR_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPEDUMPVISITOR_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
+
+namespace llvm {
+class ScopedPrinter;
+
+namespace codeview {
+
+/// Dumper for CodeView type streams found in COFF object files and PDB files.
+class TypeDumpVisitor : public TypeVisitorCallbacks {
+public:
+ TypeDumpVisitor(TypeDatabase &TypeDB, ScopedPrinter *W, bool PrintRecordBytes)
+ : W(W), PrintRecordBytes(PrintRecordBytes), TypeDB(TypeDB) {}
+
+ void printTypeIndex(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;
+
+ /// Paired begin/end actions for all types. Receives all record data,
+ /// including the fixed-length record prefix.
+ Error visitTypeBegin(CVType &Record) override;
+ Error visitTypeEnd(CVType &Record) override;
+ Error visitMemberBegin(CVMemberRecord &Record) override;
+ Error visitMemberEnd(CVMemberRecord &Record) override;
+
+#define TYPE_RECORD(EnumName, EnumVal, Name) \
+ Error visitKnownRecord(CVType &CVR, Name##Record &Record) override;
+#define MEMBER_RECORD(EnumName, EnumVal, Name) \
+ Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override;
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "TypeRecords.def"
+
+private:
+ void printMemberAttributes(MemberAttributes Attrs);
+ void printMemberAttributes(MemberAccess Access, MethodKind Kind,
+ MethodOptions Options);
+
+ ScopedPrinter *W;
+
+ bool PrintRecordBytes = false;
+
+ TypeDatabase &TypeDB;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumper.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumper.h
deleted file mode 100644
index ca79ab0..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumper.h
+++ /dev/null
@@ -1,105 +0,0 @@
-//===-- TypeDumper.h - CodeView type info dumper ----------------*- 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_TYPEDUMPER_H
-#define LLVM_DEBUGINFO_CODEVIEW_TYPEDUMPER_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringSet.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
-
-namespace llvm {
-class ScopedPrinter;
-
-namespace codeview {
-
-/// Dumper for CodeView type streams found in COFF object files and PDB files.
-class CVTypeDumper : public TypeVisitorCallbacks {
-public:
- CVTypeDumper(ScopedPrinter *W, bool PrintRecordBytes)
- : W(W), PrintRecordBytes(PrintRecordBytes) {}
-
- StringRef getTypeName(TypeIndex TI);
- void printTypeIndex(StringRef FieldName, TypeIndex TI);
-
- /// 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
- /// maintains state about previous records which are necessary for cross
- /// type references.
- Error dump(const CVRecord<TypeLeafKind> &Record);
-
- /// Dumps the type records in Types. Returns false if there was a type stream
- /// parse error, and true otherwise.
- Error dump(const CVTypeArray &Types);
-
- /// Dumps the type records in Data. Returns false if there was a type stream
- /// parse error, and true otherwise. Use this method instead of the
- /// CVTypeArray overload when type records are laid out contiguously in
- /// memory.
- Error dump(ArrayRef<uint8_t> Data);
-
- /// Gets the type index for the next type record.
- unsigned getNextTypeIndex() const {
- return 0x1000 + CVUDTNames.size();
- }
-
- /// Records the name of a type, and reserves its type index.
- void recordType(StringRef Name) { CVUDTNames.push_back(Name); }
-
- /// Saves the name in a StringSet and creates a stable StringRef.
- StringRef saveName(StringRef TypeName) {
- return TypeNames.insert(TypeName).first->getKey();
- }
-
- void setPrinter(ScopedPrinter *P);
- ScopedPrinter *getPrinter() { return W; }
-
- /// Action to take on unknown types. By default, they are ignored.
- Error visitUnknownType(const CVRecord<TypeLeafKind> &Record) override;
- Error visitUnknownMember(const CVRecord<TypeLeafKind> &Record) override;
-
- /// Paired begin/end actions for all types. Receives all record data,
- /// including the fixed-length record prefix.
- Error visitTypeBegin(const CVRecord<TypeLeafKind> &Record) override;
- Error visitTypeEnd(const CVRecord<TypeLeafKind> &Record) override;
-
-#define TYPE_RECORD(EnumName, EnumVal, Name) \
- Error visit##Name(Name##Record &Record) override;
-#define MEMBER_RECORD(EnumName, EnumVal, Name) \
- TYPE_RECORD(EnumName, EnumVal, Name)
-#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "TypeRecords.def"
-
-private:
- void printMemberAttributes(MemberAttributes Attrs);
- void printMemberAttributes(MemberAccess Access, MethodKind Kind,
- MethodOptions Options);
-
- ScopedPrinter *W;
-
- bool PrintRecordBytes = false;
-
- /// Name of the current type. Only valid before visitTypeEnd.
- StringRef Name;
-
- /// All user defined type records in .debug$T live in here. Type indices
- /// greater than 0x1000 are user defined. Subtract 0x1000 from the index to
- /// index into this vector.
- SmallVector<StringRef, 10> CVUDTNames;
-
- StringSet<> TypeNames;
-};
-
-} // end namespace codeview
-} // end namespace llvm
-
-#endif // LLVM_DEBUGINFO_CODEVIEW_TYPEDUMPER_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumperBase.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumperBase.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumperBase.h
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndex.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndex.h
index c2ebf38..3c11d24 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndex.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndex.h
@@ -93,7 +93,7 @@ public:
static const uint32_t SimpleModeMask = 0x00000700;
public:
- TypeIndex() : Index(0) {}
+ TypeIndex() : Index(static_cast<uint32_t>(SimpleTypeKind::None)) {}
explicit TypeIndex(uint32_t Index) : Index(Index) {}
explicit TypeIndex(SimpleTypeKind Kind)
: Index(static_cast<uint32_t>(Kind)) {}
@@ -101,6 +101,7 @@ public:
: Index(static_cast<uint32_t>(Kind) | static_cast<uint32_t>(Mode)) {}
uint32_t getIndex() const { return Index; }
+ void setIndex(uint32_t I) { Index = I; }
bool isSimple() const { return Index < FirstNonSimpleIndex; }
bool isNoneType() const { return *this == None(); }
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
index 42751fb..4f1c047 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
@@ -12,27 +12,54 @@
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/Support/ErrorOr.h"
-#include <cinttypes>
-#include <utility>
+#include "llvm/DebugInfo/MSF/StreamArray.h"
+#include "llvm/Support/Endian.h"
+#include <algorithm>
+#include <cstdint>
+#include <vector>
namespace llvm {
+
+namespace msf {
+class StreamReader;
+} // end namespace msf
+
namespace codeview {
-using llvm::support::little32_t;
-using llvm::support::ulittle16_t;
-using llvm::support::ulittle32_t;
+using support::little32_t;
+using support::ulittle16_t;
+using support::ulittle32_t;
+
+typedef CVRecord<TypeLeafKind> CVType;
+
+struct CVMemberRecord {
+ TypeLeafKind Kind;
+ ArrayRef<uint8_t> Data;
+};
+typedef msf::VarStreamArray<CVType> CVTypeArray;
/// Equvalent to CV_fldattr_t in cvinfo.h.
struct MemberAttributes {
- ulittle16_t Attrs;
+ uint16_t Attrs = 0;
enum {
MethodKindShift = 2,
};
+ MemberAttributes() = default;
+
+ explicit MemberAttributes(MemberAccess Access)
+ : Attrs(static_cast<uint16_t>(Access)) {}
+
+ MemberAttributes(MemberAccess Access, MethodKind Kind, MethodOptions Flags) {
+ Attrs = static_cast<uint16_t>(Access);
+ Attrs |= (static_cast<uint16_t>(Kind) << MethodKindShift);
+ Attrs |= static_cast<uint16_t>(Flags);
+ }
/// Get the access specifier. Valid for any kind of member.
MemberAccess getAccess() const {
@@ -73,7 +100,7 @@ struct MemberAttributes {
// if it represents a member pointer.
class MemberPointerInfo {
public:
- MemberPointerInfo() {}
+ MemberPointerInfo() = default;
MemberPointerInfo(TypeIndex ContainingType,
PointerToMemberRepresentation Representation)
@@ -83,25 +110,18 @@ public:
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<MemberPointerInfo> deserialize(ArrayRef<uint8_t> &Data);
-
TypeIndex getContainingType() const { return ContainingType; }
PointerToMemberRepresentation getRepresentation() const {
return Representation;
}
-private:
- struct Layout {
- TypeIndex ClassType;
- ulittle16_t Representation; // PointerToMemberRepresentation
- };
-
TypeIndex ContainingType;
PointerToMemberRepresentation Representation;
};
class TypeRecord {
protected:
+ TypeRecord() = default;
explicit TypeRecord(TypeRecordKind Kind) : Kind(Kind) {}
public:
@@ -114,6 +134,7 @@ private:
// LF_MODIFIER
class ModifierRecord : public TypeRecord {
public:
+ explicit ModifierRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
ModifierRecord(TypeIndex ModifiedType, ModifierOptions Modifiers)
: TypeRecord(TypeRecordKind::Modifier), ModifiedType(ModifiedType),
Modifiers(Modifiers) {}
@@ -122,18 +143,9 @@ public:
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<ModifierRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
TypeIndex getModifiedType() const { return ModifiedType; }
ModifierOptions getModifiers() const { return Modifiers; }
-private:
- struct Layout {
- TypeIndex ModifiedType;
- ulittle16_t Modifiers; // ModifierOptions
- };
-
TypeIndex ModifiedType;
ModifierOptions Modifiers;
};
@@ -141,6 +153,7 @@ private:
// LF_PROCEDURE
class ProcedureRecord : public TypeRecord {
public:
+ explicit ProcedureRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
ProcedureRecord(TypeIndex ReturnType, CallingConvention CallConv,
FunctionOptions Options, uint16_t ParameterCount,
TypeIndex ArgumentList)
@@ -152,26 +165,12 @@ public:
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<ProcedureRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
- static uint32_t getLayoutSize() { return 2 + sizeof(Layout); }
-
TypeIndex getReturnType() const { return ReturnType; }
CallingConvention getCallConv() const { return CallConv; }
FunctionOptions getOptions() const { return Options; }
uint16_t getParameterCount() const { return ParameterCount; }
TypeIndex getArgumentList() const { return ArgumentList; }
-private:
- struct Layout {
- TypeIndex ReturnType;
- CallingConvention CallConv;
- FunctionOptions Options;
- ulittle16_t NumParameters;
- TypeIndex ArgListType;
- };
-
TypeIndex ReturnType;
CallingConvention CallConv;
FunctionOptions Options;
@@ -182,6 +181,8 @@ private:
// LF_MFUNCTION
class MemberFunctionRecord : public TypeRecord {
public:
+ explicit MemberFunctionRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
+
MemberFunctionRecord(TypeIndex ReturnType, TypeIndex ClassType,
TypeIndex ThisType, CallingConvention CallConv,
FunctionOptions Options, uint16_t ParameterCount,
@@ -196,9 +197,6 @@ public:
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<MemberFunctionRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
TypeIndex getReturnType() const { return ReturnType; }
TypeIndex getClassType() const { return ClassType; }
TypeIndex getThisType() const { return ThisType; }
@@ -208,18 +206,6 @@ public:
TypeIndex getArgumentList() const { return ArgumentList; }
int32_t getThisPointerAdjustment() const { return ThisPointerAdjustment; }
-private:
- struct Layout {
- TypeIndex ReturnType;
- TypeIndex ClassType;
- TypeIndex ThisType;
- CallingConvention CallConv;
- FunctionOptions Options;
- ulittle16_t NumParameters;
- TypeIndex ArgListType;
- little32_t ThisAdjustment;
- };
-
TypeIndex ReturnType;
TypeIndex ClassType;
TypeIndex ThisType;
@@ -233,6 +219,7 @@ private:
// LF_MFUNC_ID
class MemberFuncIdRecord : public TypeRecord {
public:
+ explicit MemberFuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
MemberFuncIdRecord(TypeIndex ClassType, TypeIndex FunctionType,
StringRef Name)
: TypeRecord(TypeRecordKind::MemberFuncId), ClassType(ClassType),
@@ -242,18 +229,9 @@ public:
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<MemberFuncIdRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
TypeIndex getClassType() const { return ClassType; }
TypeIndex getFunctionType() const { return FunctionType; }
StringRef getName() const { return Name; }
-
-private:
- struct Layout {
- TypeIndex ClassType;
- TypeIndex FunctionType;
- // Name: The null-terminated name follows.
- };
TypeIndex ClassType;
TypeIndex FunctionType;
StringRef Name;
@@ -262,6 +240,8 @@ private:
// LF_ARGLIST, LF_SUBSTR_LIST
class ArgListRecord : public TypeRecord {
public:
+ explicit ArgListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
+
ArgListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
: TypeRecord(Kind), StringIndices(Indices) {}
@@ -269,19 +249,8 @@ public:
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<ArgListRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
ArrayRef<TypeIndex> getIndices() const { return StringIndices; }
- static uint32_t getLayoutSize() { return 2 + sizeof(Layout); }
-
-private:
- struct Layout {
- ulittle32_t NumArgs; // Number of arguments
- // ArgTypes[]: Type indicies of arguments
- };
-
std::vector<TypeIndex> StringIndices;
};
@@ -294,94 +263,96 @@ public:
static const uint32_t PointerModeShift = 5;
static const uint32_t PointerModeMask = 0x07;
+ static const uint32_t PointerOptionMask = 0xFF;
+
static const uint32_t PointerSizeShift = 13;
static const uint32_t PointerSizeMask = 0xFF;
- PointerRecord(TypeIndex ReferentType, PointerKind Kind, PointerMode Mode,
- PointerOptions Options, uint8_t Size)
- : PointerRecord(ReferentType, Kind, Mode, Options, Size,
- MemberPointerInfo()) {}
+ explicit PointerRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
- PointerRecord(TypeIndex ReferentType, PointerKind Kind, PointerMode Mode,
- PointerOptions Options, uint8_t Size,
+ PointerRecord(TypeIndex ReferentType, uint32_t Attrs)
+ : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
+ Attrs(Attrs) {}
+
+ PointerRecord(TypeIndex ReferentType, PointerKind PK, PointerMode PM,
+ PointerOptions PO, uint8_t Size)
+ : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
+ Attrs(calcAttrs(PK, PM, PO, Size)) {}
+
+ PointerRecord(TypeIndex ReferentType, PointerKind PK, PointerMode PM,
+ PointerOptions PO, uint8_t Size,
+ const MemberPointerInfo &Member)
+ : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
+ Attrs(calcAttrs(PK, PM, PO, Size)), MemberInfo(Member) {}
+
+ PointerRecord(TypeIndex ReferentType, uint32_t Attrs,
const MemberPointerInfo &Member)
: TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
- PtrKind(Kind), Mode(Mode), Options(Options), Size(Size),
- MemberInfo(Member) {}
+ 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);
- static ErrorOr<PointerRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
TypeIndex getReferentType() const { return ReferentType; }
- PointerKind getPointerKind() const { return PtrKind; }
- PointerMode getMode() const { return Mode; }
- PointerOptions getOptions() const { return Options; }
- uint8_t getSize() const { return Size; }
- MemberPointerInfo getMemberInfo() const { return MemberInfo; }
- bool isPointerToMember() const {
- return Mode == PointerMode::PointerToDataMember ||
- Mode == PointerMode::PointerToMemberFunction;
+ PointerKind getPointerKind() const {
+ return static_cast<PointerKind>((Attrs >> PointerKindShift) &
+ PointerKindMask);
+ }
+
+ PointerMode getMode() const {
+ return static_cast<PointerMode>((Attrs >> PointerModeShift) &
+ PointerModeMask);
}
- bool isFlat() const {
- return !!(uint32_t(Options) & uint32_t(PointerOptions::Flat32));
+
+ PointerOptions getOptions() const {
+ return static_cast<PointerOptions>(Attrs);
}
- bool isConst() const {
- return !!(uint32_t(Options) & uint32_t(PointerOptions::Const));
+
+ uint8_t getSize() const {
+ return (Attrs >> PointerSizeShift) & PointerSizeMask;
}
+
+ MemberPointerInfo getMemberInfo() const { return *MemberInfo; }
+
+ bool isPointerToMember() const {
+ return getMode() == PointerMode::PointerToDataMember ||
+ getMode() == PointerMode::PointerToMemberFunction;
+ }
+
+ bool isFlat() const { return !!(Attrs & uint32_t(PointerOptions::Flat32)); }
+ bool isConst() const { return !!(Attrs & uint32_t(PointerOptions::Const)); }
+
bool isVolatile() const {
- return !!(uint32_t(Options) & uint32_t(PointerOptions::Volatile));
+ return !!(Attrs & uint32_t(PointerOptions::Volatile));
}
+
bool isUnaligned() const {
- return !!(uint32_t(Options) & uint32_t(PointerOptions::Unaligned));
+ return !!(Attrs & uint32_t(PointerOptions::Unaligned));
}
-private:
- struct Layout {
- TypeIndex PointeeType;
- ulittle32_t Attrs; // pointer attributes
- // if pointer to member:
- // PointerToMemberTail
- PointerKind getPtrKind() const {
- return PointerKind(Attrs & PointerKindMask);
- }
- PointerMode getPtrMode() const {
- return PointerMode((Attrs >> PointerModeShift) & PointerModeMask);
- }
- uint8_t getPtrSize() const {
- return (Attrs >> PointerSizeShift) & PointerSizeMask;
- }
- bool isFlat() const { return Attrs & (1 << 8); }
- bool isVolatile() const { return Attrs & (1 << 9); }
- bool isConst() const { return Attrs & (1 << 10); }
- bool isUnaligned() const { return Attrs & (1 << 11); }
-
- bool isPointerToDataMember() const {
- return getPtrMode() == PointerMode::PointerToDataMember;
- }
- bool isPointerToMemberFunction() const {
- return getPtrMode() == PointerMode::PointerToMemberFunction;
- }
- bool isPointerToMember() const {
- return isPointerToMemberFunction() || isPointerToDataMember();
- }
- };
-
TypeIndex ReferentType;
- PointerKind PtrKind;
- PointerMode Mode;
- PointerOptions Options;
- uint8_t Size;
- MemberPointerInfo MemberInfo;
+ uint32_t Attrs;
+
+ Optional<MemberPointerInfo> MemberInfo;
+
+private:
+ static uint32_t calcAttrs(PointerKind PK, PointerMode PM, PointerOptions PO,
+ uint8_t Size) {
+ uint32_t A = 0;
+ A |= static_cast<uint32_t>(PK);
+ A |= static_cast<uint32_t>(PO);
+ A |= (static_cast<uint32_t>(PM) << PointerModeShift);
+ A |= (static_cast<uint32_t>(Size) << PointerSizeShift);
+ return A;
+ }
};
// LF_NESTTYPE
class NestedTypeRecord : public TypeRecord {
public:
+ explicit NestedTypeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
NestedTypeRecord(TypeIndex Type, StringRef Name)
: TypeRecord(TypeRecordKind::NestedType), Type(Type), Name(Name) {}
@@ -389,26 +360,31 @@ public:
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<NestedTypeRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
TypeIndex getNestedType() const { return Type; }
StringRef getName() const { return Name; }
-private:
- struct Layout {
- ulittle16_t Pad0; // Should be zero
- TypeIndex Type; // Type index of nested type
- // Name: Null-terminated string
- };
-
TypeIndex Type;
StringRef Name;
};
+// LF_FIELDLIST
+class FieldListRecord : public TypeRecord {
+public:
+ explicit FieldListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
+ 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;
+};
+
// LF_ARRAY
class ArrayRecord : public TypeRecord {
public:
+ explicit ArrayRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
ArrayRecord(TypeIndex ElementType, TypeIndex IndexType, uint64_t Size,
StringRef Name)
: TypeRecord(TypeRecordKind::Array), ElementType(ElementType),
@@ -418,30 +394,20 @@ public:
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<ArrayRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
TypeIndex getElementType() const { return ElementType; }
TypeIndex getIndexType() const { return IndexType; }
uint64_t getSize() const { return Size; }
- llvm::StringRef getName() const { return Name; }
-
-private:
- struct Layout {
- TypeIndex ElementType;
- TypeIndex IndexType;
- // SizeOf: LF_NUMERIC encoded size in bytes. Not element count!
- // Name: The null-terminated name follows.
- };
+ StringRef getName() const { return Name; }
TypeIndex ElementType;
TypeIndex IndexType;
uint64_t Size;
- llvm::StringRef Name;
+ StringRef Name;
};
class TagRecord : public TypeRecord {
protected:
+ explicit TagRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
TagRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
TypeIndex FieldList, StringRef Name, StringRef UniqueName)
: TypeRecord(Kind), MemberCount(MemberCount), Options(Options),
@@ -457,13 +423,16 @@ public:
static const int WinRTKindShift = 14;
static const int WinRTKindMask = 0xC000;
+ bool hasUniqueName() const {
+ return (Options & ClassOptions::HasUniqueName) != ClassOptions::None;
+ }
+
uint16_t getMemberCount() const { return MemberCount; }
ClassOptions getOptions() const { return Options; }
TypeIndex getFieldList() const { return FieldList; }
StringRef getName() const { return Name; }
StringRef getUniqueName() const { return UniqueName; }
-private:
uint16_t MemberCount;
ClassOptions Options;
TypeIndex FieldList;
@@ -474,45 +443,34 @@ private:
// LF_CLASS, LF_STRUCTURE, LF_INTERFACE
class ClassRecord : public TagRecord {
public:
+ explicit ClassRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
ClassRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
- HfaKind Hfa, WindowsRTClassKind WinRTKind, TypeIndex FieldList,
- TypeIndex DerivationList, TypeIndex VTableShape, uint64_t Size,
- StringRef Name, StringRef UniqueName)
+ TypeIndex FieldList, TypeIndex DerivationList,
+ TypeIndex VTableShape, uint64_t Size, StringRef Name,
+ StringRef UniqueName)
: TagRecord(Kind, MemberCount, Options, FieldList, Name, UniqueName),
- Hfa(Hfa), WinRTKind(WinRTKind), DerivationList(DerivationList),
- VTableShape(VTableShape), Size(Size) {}
+ 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);
- static ErrorOr<ClassRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ HfaKind getHfa() const {
+ uint16_t Value = static_cast<uint16_t>(Options);
+ Value = (Value & HfaKindMask) >> HfaKindShift;
+ return static_cast<HfaKind>(Value);
+ }
+
+ WindowsRTClassKind getWinRTKind() const {
+ uint16_t Value = static_cast<uint16_t>(Options);
+ Value = (Value & WinRTKindMask) >> WinRTKindShift;
+ return static_cast<WindowsRTClassKind>(Value);
+ }
- HfaKind getHfa() const { return Hfa; }
- WindowsRTClassKind getWinRTKind() const { return WinRTKind; }
TypeIndex getDerivationList() const { return DerivationList; }
TypeIndex getVTableShape() const { return VTableShape; }
uint64_t getSize() const { return Size; }
-private:
- struct Layout {
- ulittle16_t MemberCount; // Number of members in FieldList.
- ulittle16_t Properties; // ClassOptions bitset
- TypeIndex FieldList; // LF_FIELDLIST: List of all kinds of members
- TypeIndex DerivedFrom; // LF_DERIVED: List of known derived classes
- TypeIndex VShape; // LF_VTSHAPE: Shape of the vftable
- // SizeOf: The 'sizeof' the UDT in bytes is encoded as an LF_NUMERIC
- // integer.
- // Name: The null-terminated name follows.
-
- bool hasUniqueName() const {
- return Properties & uint16_t(ClassOptions::HasUniqueName);
- }
- };
-
- HfaKind Hfa;
- WindowsRTClassKind WinRTKind;
TypeIndex DerivationList;
TypeIndex VTableShape;
uint64_t Size;
@@ -520,40 +478,28 @@ private:
// LF_UNION
struct UnionRecord : public TagRecord {
- UnionRecord(uint16_t MemberCount, ClassOptions Options, HfaKind Hfa,
- TypeIndex FieldList, uint64_t Size, StringRef Name,
- StringRef UniqueName)
+ explicit UnionRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
+ UnionRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
+ uint64_t Size, StringRef Name, StringRef UniqueName)
: TagRecord(TypeRecordKind::Union, MemberCount, Options, FieldList, Name,
UniqueName),
- Hfa(Hfa), Size(Size) {}
+ Size(Size) {}
- static ErrorOr<UnionRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ HfaKind getHfa() const {
+ uint16_t Value = static_cast<uint16_t>(Options);
+ Value = (Value & HfaKindMask) >> HfaKindShift;
+ return static_cast<HfaKind>(Value);
+ }
- HfaKind getHfa() const { return Hfa; }
uint64_t getSize() const { return Size; }
-private:
- struct Layout {
- ulittle16_t MemberCount; // Number of members in FieldList.
- ulittle16_t Properties; // ClassOptions bitset
- TypeIndex FieldList; // LF_FIELDLIST: List of all kinds of members
- // SizeOf: The 'sizeof' the UDT in bytes is encoded as an LF_NUMERIC
- // integer.
- // Name: The null-terminated name follows.
-
- bool hasUniqueName() const {
- return Properties & uint16_t(ClassOptions::HasUniqueName);
- }
- };
-
- HfaKind Hfa;
uint64_t Size;
};
// LF_ENUM
class EnumRecord : public TagRecord {
public:
+ explicit EnumRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
EnumRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
StringRef Name, StringRef UniqueName, TypeIndex UnderlyingType)
: TagRecord(TypeRecordKind::Enum, MemberCount, Options, FieldList, Name,
@@ -563,30 +509,14 @@ public:
/// Rewrite member type indices with IndexMap. Returns false if a type index is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<EnumRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
TypeIndex getUnderlyingType() const { return UnderlyingType; }
-
-private:
- struct Layout {
- ulittle16_t NumEnumerators; // Number of enumerators
- ulittle16_t Properties;
- TypeIndex UnderlyingType;
- TypeIndex FieldListType;
- // Name: The null-terminated name follows.
-
- bool hasUniqueName() const {
- return Properties & uint16_t(ClassOptions::HasUniqueName);
- }
- };
-
TypeIndex UnderlyingType;
};
// LF_BITFIELD
class BitFieldRecord : public TypeRecord {
public:
+ explicit BitFieldRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
BitFieldRecord(TypeIndex Type, uint8_t BitSize, uint8_t BitOffset)
: TypeRecord(TypeRecordKind::BitField), Type(Type), BitSize(BitSize),
BitOffset(BitOffset) {}
@@ -595,20 +525,9 @@ public:
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<BitFieldRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
TypeIndex getType() const { return Type; }
uint8_t getBitOffset() const { return BitOffset; }
uint8_t getBitSize() const { return BitSize; }
-
-private:
- struct Layout {
- TypeIndex Type;
- uint8_t BitSize;
- uint8_t BitOffset;
- };
-
TypeIndex Type;
uint8_t BitSize;
uint8_t BitOffset;
@@ -617,6 +536,7 @@ private:
// LF_VTSHAPE
class VFTableShapeRecord : public TypeRecord {
public:
+ explicit VFTableShapeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
explicit VFTableShapeRecord(ArrayRef<VFTableSlotKind> Slots)
: TypeRecord(TypeRecordKind::VFTableShape), SlotsRef(Slots) {}
explicit VFTableShapeRecord(std::vector<VFTableSlotKind> Slots)
@@ -626,26 +546,13 @@ public:
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<VFTableShapeRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
ArrayRef<VFTableSlotKind> getSlots() const {
if (!SlotsRef.empty())
return SlotsRef;
return Slots;
}
- uint32_t getEntryCount() const { return getSlots().size(); }
-
-private:
- struct Layout {
- // Number of vftable entries. Each method may have more than one entry due
- // to
- // things like covariant return types.
- ulittle16_t VFEntryCount;
- // Descriptors[]: 4-bit virtual method descriptors of type CV_VTS_desc_e.
- };
-private:
+ uint32_t getEntryCount() const { return getSlots().size(); }
ArrayRef<VFTableSlotKind> SlotsRef;
std::vector<VFTableSlotKind> Slots;
};
@@ -653,6 +560,7 @@ private:
// LF_TYPESERVER2
class TypeServer2Record : public TypeRecord {
public:
+ explicit TypeServer2Record(TypeRecordKind Kind) : TypeRecord(Kind) {}
TypeServer2Record(StringRef Guid, uint32_t Age, StringRef Name)
: TypeRecord(TypeRecordKind::TypeServer2), Guid(Guid), Age(Age),
Name(Name) {}
@@ -661,22 +569,12 @@ public:
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<TypeServer2Record> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
StringRef getGuid() const { return Guid; }
uint32_t getAge() const { return Age; }
StringRef getName() const { return Name; }
-private:
- struct Layout {
- char Guid[16]; // GUID
- ulittle32_t Age;
- // Name: Name of the PDB as a null-terminated string
- };
-
StringRef Guid;
uint32_t Age;
StringRef Name;
@@ -685,6 +583,7 @@ private:
// LF_STRING_ID
class StringIdRecord : public TypeRecord {
public:
+ explicit StringIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
StringIdRecord(TypeIndex Id, StringRef String)
: TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {}
@@ -692,19 +591,9 @@ public:
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<StringIdRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
TypeIndex getId() const { return Id; }
StringRef getString() const { return String; }
-
-private:
- struct Layout {
- TypeIndex id;
- // Name: Name of the PDB as a null-terminated string
- };
-
TypeIndex Id;
StringRef String;
};
@@ -712,6 +601,7 @@ private:
// LF_FUNC_ID
class FuncIdRecord : public TypeRecord {
public:
+ explicit FuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
FuncIdRecord(TypeIndex ParentScope, TypeIndex FunctionType, StringRef Name)
: TypeRecord(TypeRecordKind::FuncId), ParentScope(ParentScope),
FunctionType(FunctionType), Name(Name) {}
@@ -720,22 +610,12 @@ public:
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<FuncIdRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
TypeIndex getParentScope() const { return ParentScope; }
TypeIndex getFunctionType() const { return FunctionType; }
StringRef getName() const { return Name; }
-private:
- struct Layout {
- TypeIndex ParentScope;
- TypeIndex FunctionType;
- // Name: The null-terminated name follows.
- };
-
TypeIndex ParentScope;
TypeIndex FunctionType;
StringRef Name;
@@ -744,6 +624,7 @@ private:
// LF_UDT_SRC_LINE
class UdtSourceLineRecord : public TypeRecord {
public:
+ explicit UdtSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
UdtSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile, uint32_t LineNumber)
: TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
SourceFile(SourceFile), LineNumber(LineNumber) {}
@@ -752,20 +633,10 @@ public:
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<UdtSourceLineRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
TypeIndex getUDT() const { return UDT; }
TypeIndex getSourceFile() const { return SourceFile; }
uint32_t getLineNumber() const { return LineNumber; }
-private:
- struct Layout {
- TypeIndex UDT; // The user-defined type
- TypeIndex SourceFile; // StringID containing the source filename
- ulittle32_t LineNumber;
- };
-
TypeIndex UDT;
TypeIndex SourceFile;
uint32_t LineNumber;
@@ -774,6 +645,7 @@ private:
// LF_UDT_MOD_SRC_LINE
class UdtModSourceLineRecord : public TypeRecord {
public:
+ explicit UdtModSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
UdtModSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile,
uint32_t LineNumber, uint16_t Module)
: TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
@@ -781,28 +653,11 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<UdtModSourceLineRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data) {
- const Layout *L = nullptr;
- CV_DESERIALIZE(Data, L);
-
- return UdtModSourceLineRecord(L->UDT, L->SourceFile, L->LineNumber,
- L->Module);
- }
-
TypeIndex getUDT() const { return UDT; }
TypeIndex getSourceFile() const { return SourceFile; }
uint32_t getLineNumber() const { return LineNumber; }
uint16_t getModule() const { return Module; }
-private:
- struct Layout {
- TypeIndex UDT; // The user-defined type
- TypeIndex SourceFile; // StringID containing the source filename
- ulittle32_t LineNumber;
- ulittle16_t Module; // Module that contributes this UDT definition
- };
-
TypeIndex UDT;
TypeIndex SourceFile;
uint32_t LineNumber;
@@ -812,6 +667,7 @@ private:
// LF_BUILDINFO
class BuildInfoRecord : public TypeRecord {
public:
+ explicit BuildInfoRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
BuildInfoRecord(ArrayRef<TypeIndex> ArgIndices)
: TypeRecord(TypeRecordKind::BuildInfo),
ArgIndices(ArgIndices.begin(), ArgIndices.end()) {}
@@ -820,111 +676,73 @@ public:
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<BuildInfoRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
ArrayRef<TypeIndex> getArgs() const { return ArgIndices; }
-
-private:
- struct Layout {
- ulittle16_t NumArgs; // Number of arguments
- // ArgTypes[]: Type indicies of arguments
- };
SmallVector<TypeIndex, 4> ArgIndices;
};
// LF_VFTABLE
class VFTableRecord : public TypeRecord {
public:
+ explicit VFTableRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
VFTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable,
uint32_t VFPtrOffset, StringRef Name,
ArrayRef<StringRef> Methods)
- : TypeRecord(TypeRecordKind::VFTable),
- CompleteClass(CompleteClass), OverriddenVFTable(OverriddenVFTable),
- VFPtrOffset(VFPtrOffset), Name(Name), MethodNamesRef(Methods) {}
- VFTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable,
- uint32_t VFPtrOffset, StringRef Name,
- const std::vector<StringRef> &Methods)
- : TypeRecord(TypeRecordKind::VFTable),
- CompleteClass(CompleteClass), OverriddenVFTable(OverriddenVFTable),
- VFPtrOffset(VFPtrOffset), Name(Name), MethodNames(Methods) {}
+ : TypeRecord(TypeRecordKind::VFTable), CompleteClass(CompleteClass),
+ OverriddenVFTable(OverriddenVFTable), VFPtrOffset(VFPtrOffset) {
+ MethodNames.push_back(Name);
+ 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);
- static ErrorOr<VFTableRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
TypeIndex getCompleteClass() const { return CompleteClass; }
TypeIndex getOverriddenVTable() const { return OverriddenVFTable; }
uint32_t getVFPtrOffset() const { return VFPtrOffset; }
- StringRef getName() const { return Name; }
+ StringRef getName() const { return makeArrayRef(MethodNames).front(); }
ArrayRef<StringRef> getMethodNames() const {
- if (!MethodNamesRef.empty())
- return MethodNamesRef;
- return MethodNames;
+ return makeArrayRef(MethodNames).drop_front();
}
-private:
- struct Layout {
- TypeIndex CompleteClass; // Class that owns this vftable.
- TypeIndex OverriddenVFTable; // VFTable that this overrides.
- ulittle32_t VFPtrOffset; // VFPtr offset in CompleteClass
- ulittle32_t NamesLen; // Length of subsequent names array in bytes.
- // Names: A sequence of null-terminated strings. First string is vftable
- // names.
- };
-
TypeIndex CompleteClass;
TypeIndex OverriddenVFTable;
- ulittle32_t VFPtrOffset;
- StringRef Name;
- ArrayRef<StringRef> MethodNamesRef;
+ uint32_t VFPtrOffset;
std::vector<StringRef> MethodNames;
};
// LF_ONEMETHOD
class OneMethodRecord : public TypeRecord {
public:
- OneMethodRecord(TypeIndex Type, MethodKind Kind, MethodOptions Options,
- MemberAccess Access, int32_t VFTableOffset, StringRef Name)
- : TypeRecord(TypeRecordKind::OneMethod), Type(Type), Kind(Kind),
- Options(Options), Access(Access), VFTableOffset(VFTableOffset),
- Name(Name) {}
+ OneMethodRecord() : TypeRecord(TypeRecordKind::OneMethod) {}
+ explicit OneMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
+ OneMethodRecord(TypeIndex Type, MemberAttributes Attrs, int32_t VFTableOffset,
+ StringRef Name)
+ : TypeRecord(TypeRecordKind::OneMethod), Type(Type), Attrs(Attrs),
+ VFTableOffset(VFTableOffset), Name(Name) {}
+ OneMethodRecord(TypeIndex Type, MemberAccess Access, MethodKind MK,
+ MethodOptions Options, int32_t VFTableOffset, StringRef Name)
+ : 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);
- static ErrorOr<OneMethodRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
TypeIndex getType() const { return Type; }
- MethodKind getKind() const { return Kind; }
- MethodOptions getOptions() const { return Options; }
- MemberAccess getAccess() const { return Access; }
+ MethodKind getMethodKind() const { return Attrs.getMethodKind(); }
+ MethodOptions getOptions() const { return Attrs.getFlags(); }
+ MemberAccess getAccess() const { return Attrs.getAccess(); }
int32_t getVFTableOffset() const { return VFTableOffset; }
StringRef getName() const { return Name; }
bool isIntroducingVirtual() const {
- return Kind == MethodKind::IntroducingVirtual ||
- Kind == MethodKind::PureIntroducingVirtual;
+ return getMethodKind() == MethodKind::IntroducingVirtual ||
+ getMethodKind() == MethodKind::PureIntroducingVirtual;
}
-private:
- struct Layout {
- MemberAttributes Attrs;
- TypeIndex Type;
- // If is introduced virtual method:
- // VFTableOffset: int32_t offset in vftable
- // Name: Null-terminated string
- };
-
TypeIndex Type;
- MethodKind Kind;
- MethodOptions Options;
- MemberAccess Access;
+ MemberAttributes Attrs;
int32_t VFTableOffset;
StringRef Name;
};
@@ -932,6 +750,7 @@ private:
// LF_METHODLIST
class MethodOverloadListRecord : public TypeRecord {
public:
+ explicit MethodOverloadListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods)
: TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {}
@@ -939,27 +758,14 @@ public:
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<MethodOverloadListRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
ArrayRef<OneMethodRecord> getMethods() const { return Methods; }
-
-private:
- struct Layout {
- MemberAttributes Attrs;
- ulittle16_t Padding;
-
- TypeIndex Type;
- // If is introduced virtual method:
- // VFTableOffset: int32_t offset in vftable
- };
-
std::vector<OneMethodRecord> Methods;
};
/// For method overload sets. LF_METHOD
class OverloadedMethodRecord : public TypeRecord {
public:
+ explicit OverloadedMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
OverloadedMethodRecord(uint16_t NumOverloads, TypeIndex MethodList,
StringRef Name)
: TypeRecord(TypeRecordKind::OverloadedMethod),
@@ -969,20 +775,9 @@ public:
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<OverloadedMethodRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
uint16_t getNumOverloads() const { return NumOverloads; }
TypeIndex getMethodList() const { return MethodList; }
StringRef getName() const { return Name; }
-
-private:
- struct Layout {
- ulittle16_t MethodCount; // Size of overload set
- TypeIndex MethList; // Type index of methods in overload set
- // Name: Null-terminated string
- };
-
uint16_t NumOverloads;
TypeIndex MethodList;
StringRef Name;
@@ -991,32 +786,26 @@ private:
// LF_MEMBER
class DataMemberRecord : public TypeRecord {
public:
+ explicit DataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
+ DataMemberRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset,
+ StringRef Name)
+ : TypeRecord(TypeRecordKind::DataMember), Attrs(Attrs), Type(Type),
+ FieldOffset(Offset), Name(Name) {}
DataMemberRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset,
StringRef Name)
- : TypeRecord(TypeRecordKind::DataMember), Access(Access), Type(Type),
+ : 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);
- static ErrorOr<DataMemberRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
- MemberAccess getAccess() const { return Access; }
+ MemberAccess getAccess() const { return Attrs.getAccess(); }
TypeIndex getType() const { return Type; }
uint64_t getFieldOffset() const { return FieldOffset; }
StringRef getName() const { return Name; }
-private:
- struct Layout {
- MemberAttributes Attrs; // Access control attributes, etc
- TypeIndex Type;
- // FieldOffset: LF_NUMERIC encoded byte offset
- // Name: Null-terminated string
- };
-
- MemberAccess Access;
+ MemberAttributes Attrs;
TypeIndex Type;
uint64_t FieldOffset;
StringRef Name;
@@ -1025,29 +814,23 @@ private:
// LF_STMEMBER
class StaticDataMemberRecord : public TypeRecord {
public:
+ explicit StaticDataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
+ StaticDataMemberRecord(MemberAttributes Attrs, TypeIndex Type, StringRef Name)
+ : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Attrs), Type(Type),
+ Name(Name) {}
StaticDataMemberRecord(MemberAccess Access, TypeIndex Type, StringRef Name)
- : TypeRecord(TypeRecordKind::StaticDataMember), Access(Access),
- Type(Type), Name(Name) {}
+ : 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);
- static ErrorOr<StaticDataMemberRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
- MemberAccess getAccess() const { return Access; }
+ MemberAccess getAccess() const { return Attrs.getAccess(); }
TypeIndex getType() const { return Type; }
StringRef getName() const { return Name; }
-private:
- struct Layout {
- MemberAttributes Attrs; // Access control attributes, etc
- TypeIndex Type;
- // Name: Null-terminated string
- };
-
- MemberAccess Access;
+ MemberAttributes Attrs;
TypeIndex Type;
StringRef Name;
};
@@ -1055,29 +838,23 @@ private:
// LF_ENUMERATE
class EnumeratorRecord : public TypeRecord {
public:
+ explicit EnumeratorRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
+ EnumeratorRecord(MemberAttributes Attrs, APSInt Value, StringRef Name)
+ : TypeRecord(TypeRecordKind::Enumerator), Attrs(Attrs),
+ Value(std::move(Value)), Name(Name) {}
EnumeratorRecord(MemberAccess Access, APSInt Value, StringRef Name)
- : TypeRecord(TypeRecordKind::Enumerator), Access(Access),
+ : 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);
- static ErrorOr<EnumeratorRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
- MemberAccess getAccess() const { return Access; }
+ MemberAccess getAccess() const { return Attrs.getAccess(); }
APSInt getValue() const { return Value; }
StringRef getName() const { return Name; }
-private:
- struct Layout {
- MemberAttributes Attrs; // Access control attributes, etc
- // EnumValue: LF_NUMERIC encoded enumerator value
- // Name: Null-terminated string
- };
-
- MemberAccess Access;
+ MemberAttributes Attrs;
APSInt Value;
StringRef Name;
};
@@ -1085,6 +862,7 @@ private:
// LF_VFUNCTAB
class VFPtrRecord : public TypeRecord {
public:
+ explicit VFPtrRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
VFPtrRecord(TypeIndex Type)
: TypeRecord(TypeRecordKind::VFPtr), Type(Type) {}
@@ -1092,44 +870,31 @@ public:
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<VFPtrRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
TypeIndex getType() const { return Type; }
-private:
- struct Layout {
- ulittle16_t Pad0;
- TypeIndex Type; // Type of vfptr
- };
TypeIndex Type;
};
// LF_BCLASS, LF_BINTERFACE
class BaseClassRecord : public TypeRecord {
public:
+ explicit BaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
+ BaseClassRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset)
+ : TypeRecord(TypeRecordKind::BaseClass), Attrs(Attrs), Type(Type),
+ Offset(Offset) {}
BaseClassRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset)
- : TypeRecord(TypeRecordKind::BaseClass), Access(Access), Type(Type),
+ : 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);
- static ErrorOr<BaseClassRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
- MemberAccess getAccess() const { return Access; }
+ MemberAccess getAccess() const { return Attrs.getAccess(); }
TypeIndex getBaseType() const { return Type; }
uint64_t getBaseOffset() const { return Offset; }
-private:
- struct Layout {
- MemberAttributes Attrs; // Access control attributes, etc
- TypeIndex BaseType; // Base class type
- // BaseOffset: LF_NUMERIC encoded byte offset of base from derived.
- };
- MemberAccess Access;
+ MemberAttributes Attrs;
TypeIndex Type;
uint64_t Offset;
};
@@ -1137,34 +902,29 @@ private:
// LF_VBCLASS, LF_IVBCLASS
class VirtualBaseClassRecord : public TypeRecord {
public:
- VirtualBaseClassRecord(MemberAccess Access, TypeIndex BaseType,
- TypeIndex VBPtrType, uint64_t Offset, uint64_t Index)
- : TypeRecord(TypeRecordKind::VirtualBaseClass), Access(Access),
- BaseType(BaseType), VBPtrType(VBPtrType), VBPtrOffset(Offset),
- VTableIndex(Index) {}
+ explicit VirtualBaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
+ VirtualBaseClassRecord(TypeRecordKind Kind, MemberAttributes Attrs,
+ TypeIndex BaseType, TypeIndex VBPtrType,
+ uint64_t Offset, uint64_t Index)
+ : TypeRecord(Kind), Attrs(Attrs), BaseType(BaseType),
+ VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {}
+ VirtualBaseClassRecord(TypeRecordKind Kind, MemberAccess Access,
+ TypeIndex BaseType, TypeIndex VBPtrType,
+ uint64_t Offset, uint64_t Index)
+ : 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);
- static ErrorOr<VirtualBaseClassRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
- MemberAccess getAccess() const { return Access; }
+ MemberAccess getAccess() const { return Attrs.getAccess(); }
TypeIndex getBaseType() const { return BaseType; }
TypeIndex getVBPtrType() const { return VBPtrType; }
uint64_t getVBPtrOffset() const { return VBPtrOffset; }
uint64_t getVTableIndex() const { return VTableIndex; }
-private:
- struct Layout {
- MemberAttributes Attrs; // Access control attributes, etc.
- TypeIndex BaseType; // Base class type
- TypeIndex VBPtrType; // Virtual base pointer type
- // VBPtrOffset: Offset of vbptr from vfptr encoded as LF_NUMERIC.
- // VBTableIndex: Index of vbase within vbtable encoded as LF_NUMERIC.
- };
- MemberAccess Access;
+ MemberAttributes Attrs;
TypeIndex BaseType;
TypeIndex VBPtrType;
uint64_t VBPtrOffset;
@@ -1175,6 +935,7 @@ private:
/// together. The first will end in an LF_INDEX record that points to the next.
class ListContinuationRecord : public TypeRecord {
public:
+ explicit ListContinuationRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
ListContinuationRecord(TypeIndex ContinuationIndex)
: TypeRecord(TypeRecordKind::ListContinuation),
ContinuationIndex(ContinuationIndex) {}
@@ -1183,20 +944,11 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<ListContinuationRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
-
-private:
- struct Layout {
- ulittle16_t Pad0;
- TypeIndex ContinuationIndex;
- };
TypeIndex ContinuationIndex;
};
-typedef CVRecord<TypeLeafKind> CVType;
-typedef VarStreamArray<CVType> CVTypeArray;
-}
-}
+} // end namespace codeview
+
+} // end namespace llvm
-#endif
+#endif // LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordBuilder.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordBuilder.h
index eb7993b..5a6507e 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordBuilder.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordBuilder.h
@@ -47,6 +47,12 @@ public:
llvm::StringRef str();
uint64_t size() const { return Stream.tell(); }
+ TypeRecordKind kind() const { return Kind; }
+
+ /// Returns the number of bytes remaining before this record is larger than
+ /// the maximum record length. Accounts for the extra two byte size field in
+ /// the header.
+ size_t maxBytesRemaining() const { return MaxRecordLength - size() - 2; }
void truncate(uint64_t Size) {
// This works because raw_svector_ostream is not buffered.
@@ -56,10 +62,12 @@ public:
void reset(TypeRecordKind K) {
Buffer.clear();
+ Kind = K;
writeTypeRecordKind(K);
}
private:
+ TypeRecordKind Kind;
llvm::SmallVector<char, 256> Buffer;
llvm::raw_svector_ostream Stream;
llvm::support::endian::Writer<llvm::support::endianness::little> Writer;
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h
new file mode 100644
index 0000000..fe470a7
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h
@@ -0,0 +1,52 @@
+//===- TypeRecordMapping.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_TYPERECORDMAPPING_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPERECORDMAPPING_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace msf {
+class StreamReader;
+class StreamWriter;
+}
+namespace codeview {
+class TypeRecordMapping : public TypeVisitorCallbacks {
+public:
+ explicit TypeRecordMapping(msf::StreamReader &Reader) : IO(Reader) {}
+ explicit TypeRecordMapping(msf::StreamWriter &Writer) : IO(Writer) {}
+
+ Error visitTypeBegin(CVType &Record) override;
+ Error visitTypeEnd(CVType &Record) override;
+
+ Error visitMemberBegin(CVMemberRecord &Record) override;
+ Error visitMemberEnd(CVMemberRecord &Record) override;
+
+#define TYPE_RECORD(EnumName, EnumVal, Name) \
+ Error visitKnownRecord(CVType &CVR, Name##Record &Record) override;
+#define MEMBER_RECORD(EnumName, EnumVal, Name) \
+ Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override;
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "TypeRecords.def"
+
+private:
+ Optional<TypeLeafKind> TypeKind;
+ Optional<TypeLeafKind> MemberKind;
+
+ CodeViewRecordIO IO;
+};
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecords.def b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecords.def
index 0959f4b..c98dbac 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecords.def
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecords.def
@@ -43,6 +43,8 @@ TYPE_RECORD(LF_PROCEDURE, 0x1008, Procedure)
TYPE_RECORD(LF_MFUNCTION, 0x1009, MemberFunction)
TYPE_RECORD(LF_ARGLIST, 0x1201, ArgList)
+TYPE_RECORD(LF_FIELDLIST, 0x1203, FieldList)
+
TYPE_RECORD(LF_ARRAY, 0x1503, Array)
TYPE_RECORD(LF_CLASS, 0x1504, Class)
TYPE_RECORD_ALIAS(LF_STRUCTURE, 0x1505, Struct, Class)
@@ -159,7 +161,6 @@ CV_TYPE(LF_OEM2, 0x1011)
CV_TYPE(LF_SKIP, 0x1200)
CV_TYPE(LF_DEFARG_ST, 0x1202)
-CV_TYPE(LF_FIELDLIST, 0x1203)
CV_TYPE(LF_DERIVED, 0x1204)
CV_TYPE(LF_DIMCONU, 0x1207)
CV_TYPE(LF_DIMCONLU, 0x1208)
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeSerializer.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeSerializer.h
new file mode 100644
index 0000000..e059221
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeSerializer.h
@@ -0,0 +1,140 @@
+//===- TypeSerializer.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_TYPESERIALIZER_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPESERIALIZER_H
+
+#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/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+
+namespace codeview {
+
+class TypeSerializer : public TypeVisitorCallbacks {
+ struct SubRecord {
+ SubRecord(TypeLeafKind K, uint32_t S) : Kind(K), Size(S) {}
+
+ TypeLeafKind Kind;
+ uint32_t Size = 0;
+ };
+ struct RecordSegment {
+ SmallVector<SubRecord, 16> SubRecords;
+
+ uint32_t length() const {
+ uint32_t L = sizeof(RecordPrefix);
+ for (const auto &R : SubRecords) {
+ L += R.Size;
+ }
+ return L;
+ }
+ };
+
+ typedef SmallVector<MutableArrayRef<uint8_t>, 2> RecordList;
+
+ static constexpr uint8_t ContinuationLength = 8;
+ BumpPtrAllocator &RecordStorage;
+ RecordSegment CurrentSegment;
+ RecordList FieldListSegments;
+
+ TypeIndex LastTypeIndex;
+ Optional<TypeLeafKind> TypeKind;
+ Optional<TypeLeafKind> MemberKind;
+ std::vector<uint8_t> RecordBuffer;
+ msf::MutableByteStream Stream;
+ msf::StreamWriter Writer;
+ TypeRecordMapping Mapping;
+
+ RecordList SeenRecords;
+ StringMap<TypeIndex> HashedRecords;
+
+ bool isInFieldList() const;
+ TypeIndex calcNextTypeIndex() const;
+ TypeIndex incrementTypeIndex();
+ MutableArrayRef<uint8_t> getCurrentSubRecordData();
+ MutableArrayRef<uint8_t> getCurrentRecordData();
+ Error writeRecordPrefix(TypeLeafKind Kind);
+ TypeIndex insertRecordBytesPrivate(MutableArrayRef<uint8_t> Record);
+
+ Expected<MutableArrayRef<uint8_t>>
+ addPadding(MutableArrayRef<uint8_t> Record);
+
+public:
+ explicit TypeSerializer(BumpPtrAllocator &Storage);
+
+ ArrayRef<MutableArrayRef<uint8_t>> records() const;
+ TypeIndex getLastTypeIndex() const;
+ TypeIndex insertRecordBytes(MutableArrayRef<uint8_t> Record);
+ Expected<TypeIndex> visitTypeEndGetIndex(CVType &Record);
+
+ Error visitTypeBegin(CVType &Record) override;
+ Error visitTypeEnd(CVType &Record) override;
+ Error visitMemberBegin(CVMemberRecord &Record) override;
+ Error visitMemberEnd(CVMemberRecord &Record) override;
+
+#define TYPE_RECORD(EnumName, EnumVal, Name) \
+ virtual Error visitKnownRecord(CVType &CVR, Name##Record &Record) override { \
+ return visitKnownRecordImpl(CVR, Record); \
+ }
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#define MEMBER_RECORD(EnumName, EnumVal, Name) \
+ Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \
+ return visitKnownMemberImpl<Name##Record>(CVR, Record); \
+ }
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "llvm/DebugInfo/CodeView/TypeRecords.def"
+
+private:
+ template <typename RecordKind>
+ Error visitKnownRecordImpl(CVType &CVR, RecordKind &Record) {
+ return Mapping.visitKnownRecord(CVR, Record);
+ }
+
+ template <typename RecordType>
+ Error visitKnownMemberImpl(CVMemberRecord &CVR, RecordType &Record) {
+ assert(CVR.Kind == static_cast<TypeLeafKind>(Record.getKind()));
+
+ if (auto EC = Writer.writeEnum(CVR.Kind))
+ return EC;
+
+ if (auto EC = Mapping.visitKnownMember(CVR, Record))
+ return EC;
+
+ // Get all the data that was just written and is yet to be committed to
+ // the current segment. Then pad it to 4 bytes.
+ MutableArrayRef<uint8_t> ThisRecord = getCurrentSubRecordData();
+ auto ExpectedRecord = addPadding(ThisRecord);
+ if (!ExpectedRecord)
+ return ExpectedRecord.takeError();
+ ThisRecord = *ExpectedRecord;
+
+ CurrentSegment.SubRecords.emplace_back(CVR.Kind, ThisRecord.size());
+ CVR.Data = ThisRecord;
+
+ // Both the last subrecord and the total length of this segment should be
+ // multiples of 4.
+ assert(ThisRecord.size() % 4 == 0);
+ assert(CurrentSegment.length() % 4 == 0);
+
+ return Error::success();
+ }
+};
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h
index 5b2aa61..4e6d81e 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h
@@ -10,61 +10,120 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPETABLEBUILDER_H
#define LLVM_DEBUGINFO_CODEVIEW_TYPETABLEBUILDER_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeSerializer.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <type_traits>
namespace llvm {
-
-class StringRef;
-
namespace codeview {
-class FieldListRecordBuilder;
-class MethodListRecordBuilder;
-class TypeRecordBuilder;
-
class TypeTableBuilder {
private:
+ TypeIndex handleError(Error EC) const {
+ assert(false && "Couldn't write Type!");
+ consumeError(std::move(EC));
+ return TypeIndex();
+ }
+
+ BumpPtrAllocator &Allocator;
+ TypeSerializer Serializer;
+
+public:
+ explicit TypeTableBuilder(BumpPtrAllocator &Allocator)
+ : Allocator(Allocator), Serializer(Allocator) {}
TypeTableBuilder(const TypeTableBuilder &) = delete;
TypeTableBuilder &operator=(const TypeTableBuilder &) = delete;
-protected:
- TypeTableBuilder();
+ bool empty() const { return Serializer.records().empty(); }
-public:
- virtual ~TypeTableBuilder();
+ BumpPtrAllocator &getAllocator() const { return Allocator; }
+
+ template <typename T> TypeIndex writeKnownType(T &Record) {
+ static_assert(!std::is_same<T, FieldListRecord>::value,
+ "Can't serialize FieldList!");
+
+ CVType Type;
+ Type.Type = static_cast<TypeLeafKind>(Record.getKind());
+ if (auto EC = Serializer.visitTypeBegin(Type))
+ return handleError(std::move(EC));
+ if (auto EC = Serializer.visitKnownRecord(Type, Record))
+ return handleError(std::move(EC));
+
+ auto ExpectedIndex = Serializer.visitTypeEndGetIndex(Type);
+ if (!ExpectedIndex)
+ return handleError(ExpectedIndex.takeError());
+
+ return *ExpectedIndex;
+ }
+
+ TypeIndex writeSerializedRecord(MutableArrayRef<uint8_t> Record) {
+ return Serializer.insertRecordBytes(Record);
+ }
+
+ template <typename TFunc> void ForEachRecord(TFunc Func) {
+ uint32_t Index = TypeIndex::FirstNonSimpleIndex;
+
+ for (auto Record : Serializer.records()) {
+ Func(TypeIndex(Index), Record);
+ ++Index;
+ }
+ }
+
+ ArrayRef<MutableArrayRef<uint8_t>> records() const {
+ return Serializer.records();
+ }
+};
+
+class FieldListRecordBuilder {
+ TypeTableBuilder &TypeTable;
+ TypeSerializer TempSerializer;
+ CVType Type;
public:
- TypeIndex writeModifier(const ModifierRecord &Record);
- TypeIndex writeProcedure(const ProcedureRecord &Record);
- TypeIndex writeMemberFunction(const MemberFunctionRecord &Record);
- TypeIndex writeArgList(const ArgListRecord &Record);
- TypeIndex writePointer(const PointerRecord &Record);
- TypeIndex writeArray(const ArrayRecord &Record);
- TypeIndex writeClass(const ClassRecord &Record);
- TypeIndex writeUnion(const UnionRecord &Record);
- TypeIndex writeEnum(const EnumRecord &Record);
- TypeIndex writeBitField(const BitFieldRecord &Record);
- TypeIndex writeVFTableShape(const VFTableShapeRecord &Record);
- TypeIndex writeStringId(const StringIdRecord &Record);
- TypeIndex writeVFTable(const VFTableRecord &Record);
- TypeIndex writeUdtSourceLine(const UdtSourceLineRecord &Record);
- TypeIndex writeUdtModSourceLine(const UdtModSourceLineRecord &Record);
- TypeIndex writeFuncId(const FuncIdRecord &Record);
- TypeIndex writeMemberFuncId(const MemberFuncIdRecord &Record);
- TypeIndex writeBuildInfo(const BuildInfoRecord &Record);
- TypeIndex writeMethodOverloadList(const MethodOverloadListRecord &Record);
- TypeIndex writeTypeServer2(const TypeServer2Record &Record);
-
- TypeIndex writeFieldList(FieldListRecordBuilder &FieldList);
-
- TypeIndex writeRecord(TypeRecordBuilder &builder);
-
- virtual TypeIndex writeRecord(llvm::StringRef record) = 0;
+ explicit FieldListRecordBuilder(TypeTableBuilder &TypeTable)
+ : TypeTable(TypeTable), TempSerializer(TypeTable.getAllocator()) {
+ Type.Type = TypeLeafKind::LF_FIELDLIST;
+ }
+
+ void begin() {
+ if (auto EC = TempSerializer.visitTypeBegin(Type))
+ consumeError(std::move(EC));
+ }
+
+ template <typename T> void writeMemberType(T &Record) {
+ CVMemberRecord CVMR;
+ CVMR.Kind = static_cast<TypeLeafKind>(Record.getKind());
+ if (auto EC = TempSerializer.visitMemberBegin(CVMR))
+ consumeError(std::move(EC));
+ if (auto EC = TempSerializer.visitKnownMember(CVMR, Record))
+ consumeError(std::move(EC));
+ if (auto EC = TempSerializer.visitMemberEnd(CVMR))
+ consumeError(std::move(EC));
+ }
+
+ TypeIndex end() {
+ if (auto EC = TempSerializer.visitTypeEnd(Type)) {
+ consumeError(std::move(EC));
+ return TypeIndex();
+ }
+
+ TypeIndex Index;
+ for (auto Record : TempSerializer.records()) {
+ Index = TypeTable.writeSerializedRecord(Record);
+ }
+ return Index;
+ }
};
-}
-}
-#endif
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_TYPETABLEBUILDER_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h
new file mode 100644
index 0000000..f251296
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h
@@ -0,0 +1,114 @@
+//===- TypeVisitorCallbackPipeline.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_TYPEVISITORCALLBACKPIPELINE_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPEVISITORCALLBACKPIPELINE_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
+#include "llvm/Support/Error.h"
+#include <vector>
+
+namespace llvm {
+namespace codeview {
+
+class TypeVisitorCallbackPipeline : public TypeVisitorCallbacks {
+public:
+ TypeVisitorCallbackPipeline() = default;
+
+ Error visitUnknownType(CVRecord<TypeLeafKind> &Record) override {
+ for (auto Visitor : Pipeline) {
+ if (auto EC = Visitor->visitUnknownType(Record))
+ return EC;
+ }
+ return Error::success();
+ }
+
+ Error visitUnknownMember(CVMemberRecord &Record) override {
+ for (auto Visitor : Pipeline) {
+ if (auto EC = Visitor->visitUnknownMember(Record))
+ return EC;
+ }
+ return Error::success();
+ }
+
+ Error visitTypeBegin(CVType &Record) override {
+ for (auto Visitor : Pipeline) {
+ if (auto EC = Visitor->visitTypeBegin(Record))
+ return EC;
+ }
+ return Error::success();
+ }
+
+ Error visitTypeEnd(CVType &Record) override {
+ for (auto Visitor : Pipeline) {
+ if (auto EC = Visitor->visitTypeEnd(Record))
+ return EC;
+ }
+ return Error::success();
+ }
+
+ Error visitMemberBegin(CVMemberRecord &Record) override {
+ for (auto Visitor : Pipeline) {
+ if (auto EC = Visitor->visitMemberBegin(Record))
+ return EC;
+ }
+ return Error::success();
+ }
+
+ Error visitMemberEnd(CVMemberRecord &Record) override {
+ for (auto Visitor : Pipeline) {
+ if (auto EC = Visitor->visitMemberEnd(Record))
+ return EC;
+ }
+ return Error::success();
+ }
+
+ void addCallbackToPipeline(TypeVisitorCallbacks &Callbacks) {
+ Pipeline.push_back(&Callbacks);
+ }
+
+#define TYPE_RECORD(EnumName, EnumVal, Name) \
+ Error visitKnownRecord(CVType &CVR, Name##Record &Record) override { \
+ return visitKnownRecordImpl(CVR, Record); \
+ }
+#define MEMBER_RECORD(EnumName, EnumVal, Name) \
+ Error visitKnownMember(CVMemberRecord &CVMR, Name##Record &Record) \
+ override { \
+ return visitKnownMemberImpl(CVMR, Record); \
+ }
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "llvm/DebugInfo/CodeView/TypeRecords.def"
+
+private:
+ template <typename T> Error visitKnownRecordImpl(CVType &CVR, T &Record) {
+ for (auto Visitor : Pipeline) {
+ if (auto EC = Visitor->visitKnownRecord(CVR, Record))
+ return EC;
+ }
+ return Error::success();
+ }
+
+ template <typename T>
+ Error visitKnownMemberImpl(CVMemberRecord &CVMR, T &Record) {
+ for (auto Visitor : Pipeline) {
+ if (auto EC = Visitor->visitKnownMember(CVMR, Record))
+ return EC;
+ }
+ return Error::success();
+ }
+ std::vector<TypeVisitorCallbacks *> Pipeline;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_TYPEVISITORCALLBACKPIPELINE_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h
index 310847e..5e27df3 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h
@@ -10,54 +10,53 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEVISITORCALLBACKS_H
#define LLVM_DEBUGINFO_CODEVIEW_TYPEVISITORCALLBACKS_H
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/Support/Error.h"
namespace llvm {
namespace codeview {
+
class TypeVisitorCallbacks {
friend class CVTypeVisitor;
public:
- virtual ~TypeVisitorCallbacks() {}
+ virtual ~TypeVisitorCallbacks() = default;
/// Action to take on unknown types. By default, they are ignored.
- virtual Error visitUnknownType(const CVRecord<TypeLeafKind> &Record) {
- return Error::success();
- }
- virtual Error visitUnknownMember(const CVRecord<TypeLeafKind> &Record) {
- return Error::success();
- }
-
+ virtual Error visitUnknownType(CVType &Record) { return Error::success(); }
/// Paired begin/end actions for all types. Receives all record data,
- /// including the fixed-length record prefix.
- virtual Error visitTypeBegin(const CVRecord<TypeLeafKind> &Record) {
- return Error::success();
- }
- virtual Error visitTypeEnd(const CVRecord<TypeLeafKind> &Record) {
+ /// including the fixed-length record prefix. visitTypeBegin() should return
+ /// the type of the Record, or an error if it cannot be determined.
+ virtual Error visitTypeBegin(CVType &Record) { return Error::success(); }
+ virtual Error visitTypeEnd(CVType &Record) { return Error::success(); }
+
+ virtual Error visitUnknownMember(CVMemberRecord &Record) {
return Error::success();
}
- virtual Error visitFieldListBegin(const CVRecord<TypeLeafKind> &Record) {
+ virtual Error visitMemberBegin(CVMemberRecord &Record) {
return Error::success();
}
- virtual Error visitFieldListEnd(const CVRecord<TypeLeafKind> &Record) {
+ virtual Error visitMemberEnd(CVMemberRecord &Record) {
return Error::success();
}
#define TYPE_RECORD(EnumName, EnumVal, Name) \
- virtual Error visit##Name(Name##Record &Record) { return Error::success(); }
+ virtual Error visitKnownRecord(CVType &CVR, Name##Record &Record) { \
+ return Error::success(); \
+ }
#define MEMBER_RECORD(EnumName, EnumVal, Name) \
- TYPE_RECORD(EnumName, EnumVal, Name)
+ virtual Error visitKnownMember(CVMemberRecord &CVM, Name##Record &Record) { \
+ return Error::success(); \
+ }
+
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#include "TypeRecords.def"
};
-}
-}
-#endif
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_TYPEVISITORCALLBACKS_H
OpenPOWER on IntegriCloud