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/CVRecord.h31
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeDumper.h56
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h42
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CodeView.h88
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewError.h1
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h15
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def (renamed from contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def)0
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def (renamed from contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecords.def)6
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h104
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugCrossExSubsection.h68
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h95
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h60
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h121
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugLinesSubsection.h150
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h89
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsection.h52
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h103
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h114
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h67
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h56
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugUnknownSubsection.h32
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/EnumTables.h14
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/Formatters.h73
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/GUID.h55
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h113
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/Line.h21
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstream.h89
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h136
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h44
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/StringsAndChecksums.h102
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h40
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDumper.h11
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h41
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h17
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolSerializer.h81
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h10
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h8
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h10
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeCollection.h38
-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.h37
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h29
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumperBase.h0
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndex.h98
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h41
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeName.h22
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h239
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h14
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeSerializer.h71
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h69
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h32
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableCollection.h43
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h10
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h17
56 files changed, 2283 insertions, 802 deletions
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVRecord.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVRecord.h
index a327d45..44040e0 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVRecord.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVRecord.h
@@ -14,8 +14,9 @@
#include "llvm/ADT/Optional.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
-#include "llvm/DebugInfo/MSF/StreamRef.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include <cstdint>
@@ -26,12 +27,19 @@ namespace codeview {
template <typename Kind> class CVRecord {
public:
- CVRecord() = default;
+ CVRecord() : Type(static_cast<Kind>(0)) {}
+
CVRecord(Kind K, ArrayRef<uint8_t> Data) : Type(K), RecordData(Data) {}
+ bool valid() const { return Type != static_cast<Kind>(0); }
+
uint32_t length() const { return RecordData.size(); }
Kind kind() const { return Type; }
ArrayRef<uint8_t> data() const { return RecordData; }
+ StringRef str_data() const {
+ return StringRef(reinterpret_cast<const char *>(RecordData.data()),
+ RecordData.size());
+ }
ArrayRef<uint8_t> content() const {
return RecordData.drop_front(sizeof(RecordPrefix));
@@ -46,17 +54,22 @@ public:
Optional<uint32_t> Hash;
};
-} // end namespace codeview
+template <typename Kind> struct RemappedRecord {
+ explicit RemappedRecord(const CVRecord<Kind> &R) : OriginalRecord(R) {}
-namespace msf {
+ CVRecord<Kind> OriginalRecord;
+ SmallVector<std::pair<uint32_t, TypeIndex>, 8> Mappings;
+};
+
+} // end namespace codeview
template <typename Kind>
struct VarStreamArrayExtractor<codeview::CVRecord<Kind>> {
- Error operator()(ReadableStreamRef Stream, uint32_t &Len,
- codeview::CVRecord<Kind> &Item) const {
+ Error operator()(BinaryStreamRef Stream, uint32_t &Len,
+ codeview::CVRecord<Kind> &Item) {
using namespace codeview;
const RecordPrefix *Prefix = nullptr;
- StreamReader Reader(Stream);
+ BinaryStreamReader Reader(Stream);
uint32_t Offset = Reader.getOffset();
if (auto EC = Reader.readObject(Prefix))
@@ -76,8 +89,6 @@ struct VarStreamArrayExtractor<codeview::CVRecord<Kind>> {
}
};
-} // 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 b2d3f5e..7c8cd12 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h
@@ -25,7 +25,9 @@ public:
CVSymbolVisitor(SymbolVisitorCallbacks &Callbacks);
Error visitSymbolRecord(CVSymbol &Record);
+ Error visitSymbolRecord(CVSymbol &Record, uint32_t Offset);
Error visitSymbolStream(const CVSymbolArray &Symbols);
+ Error visitSymbolStream(const CVSymbolArray &Symbols, uint32_t InitialOffset);
private:
SymbolVisitorCallbacks &Callbacks;
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeDumper.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeDumper.h
deleted file mode 100644
index e1dd6a1..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeDumper.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//===-- 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 d1b0363..df55e18 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
@@ -10,32 +10,42 @@
#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"
#include "llvm/Support/Error.h"
namespace llvm {
namespace codeview {
+class TypeCollection;
+class TypeVisitorCallbacks;
+
+enum VisitorDataSource {
+ VDS_BytesPresent, // The record bytes are passed into the the visitation
+ // function. The algorithm should first deserialize them
+ // before passing them on through the pipeline.
+ VDS_BytesExternal // The record bytes are not present, and it is the
+ // responsibility of the visitor callback interface to
+ // supply the bytes.
+};
-class CVTypeVisitor {
-public:
- explicit CVTypeVisitor(TypeVisitorCallbacks &Callbacks);
-
- Error visitTypeRecord(CVType &Record);
- Error visitMemberRecord(CVMemberRecord &Record);
+Error visitTypeRecord(CVType &Record, TypeIndex Index,
+ TypeVisitorCallbacks &Callbacks,
+ VisitorDataSource Source = VDS_BytesPresent);
+Error visitTypeRecord(CVType &Record, TypeVisitorCallbacks &Callbacks,
+ VisitorDataSource Source = VDS_BytesPresent);
- /// Visits the type records in Data. Sets the error flag on parse failures.
- Error visitTypeStream(const CVTypeArray &Types);
+Error visitMemberRecord(CVMemberRecord Record, TypeVisitorCallbacks &Callbacks,
+ VisitorDataSource Source = VDS_BytesPresent);
+Error visitMemberRecord(TypeLeafKind Kind, ArrayRef<uint8_t> Record,
+ TypeVisitorCallbacks &Callbacks);
- Error visitFieldListMemberStream(ArrayRef<uint8_t> FieldList);
- Error visitFieldListMemberStream(msf::StreamReader Reader);
+Error visitMemberRecordStream(ArrayRef<uint8_t> FieldList,
+ TypeVisitorCallbacks &Callbacks);
-private:
- /// The interface to the class that gets notified of each visitation.
- TypeVisitorCallbacks &Callbacks;
-};
+Error visitTypeStream(const CVTypeArray &Types, TypeVisitorCallbacks &Callbacks,
+ VisitorDataSource Source = VDS_BytesPresent);
+Error visitTypeStream(CVTypeRange Types, TypeVisitorCallbacks &Callbacks);
+Error visitTypeStream(TypeCollection &Types, TypeVisitorCallbacks &Callbacks);
} // end namespace codeview
} // end namespace llvm
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeView.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeView.h
index e21cfa3..b7a7e33 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeView.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeView.h
@@ -6,6 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// Defines constants and basic types describing CodeView debug information.
+//
+//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_CODEVIEW_CODEVIEW_H
#define LLVM_DEBUGINFO_CODEVIEW_CODEVIEW_H
@@ -13,6 +17,8 @@
#include <cinttypes>
#include <type_traits>
+#include "llvm/Support/Endian.h"
+
namespace llvm {
namespace codeview {
@@ -20,28 +26,28 @@ namespace codeview {
/// documentation and headers talk about this as the "leaf" type.
enum class TypeRecordKind : uint16_t {
#define TYPE_RECORD(lf_ename, value, name) name = value,
-#include "TypeRecords.def"
+#include "CodeViewTypes.def"
};
/// Duplicate copy of the above enum, but using the official CV names. Useful
/// for reference purposes and when dealing with unknown record types.
enum TypeLeafKind : uint16_t {
#define CV_TYPE(name, val) name = val,
-#include "TypeRecords.def"
+#include "CodeViewTypes.def"
};
/// Distinguishes individual records in the Symbols subsection of a .debug$S
/// section. Equivalent to SYM_ENUM_e in cvinfo.h.
enum class SymbolRecordKind : uint16_t {
#define SYMBOL_RECORD(lf_ename, value, name) name = value,
-#include "CVSymbolTypes.def"
+#include "CodeViewSymbols.def"
};
/// Duplicate copy of the above enum, but using the official CV names. Useful
/// for reference purposes and when dealing with unknown record types.
enum SymbolKind : uint16_t {
#define CV_SYMBOL(name, val) name = val,
-#include "CVSymbolTypes.def"
+#include "CodeViewSymbols.def"
};
#define CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(Class) \
@@ -275,6 +281,12 @@ enum class MethodOptions : uint16_t {
};
CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(MethodOptions)
+/// Equivalent to CV_LABEL_TYPE_e.
+enum class LabelType : uint16_t {
+ Near = 0x0,
+ Far = 0x4,
+};
+
/// Equivalent to CV_modifier_t.
/// TODO: Add flag for _Atomic modifier
enum class ModifierOptions : uint16_t {
@@ -285,7 +297,7 @@ enum class ModifierOptions : uint16_t {
};
CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ModifierOptions)
-enum class ModuleSubstreamKind : uint32_t {
+enum class DebugSubsectionKind : uint32_t {
None = 0,
Symbols = 0xf1,
Lines = 0xf2,
@@ -390,6 +402,16 @@ enum class LocalSymFlags : uint16_t {
};
CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(LocalSymFlags)
+/// Corresponds to the CV_PUBSYMFLAGS bitfield.
+enum class PublicSymFlags : uint32_t {
+ None = 0,
+ Code = 1 << 0,
+ Function = 1 << 1,
+ Managed = 1 << 2,
+ MSIL = 1 << 3,
+};
+CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(PublicSymFlags)
+
/// Corresponds to the CV_PROCFLAGS bitfield.
enum class ProcSymFlags : uint8_t {
None = 0,
@@ -406,6 +428,8 @@ CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ProcSymFlags)
/// Corresponds to COMPILESYM2::Flags bitfield.
enum class CompileSym2Flags : uint32_t {
+ None = 0,
+ SourceLanguageMask = 0xFF,
EC = 1 << 8,
NoDbgInfo = 1 << 9,
LTCG = 1 << 10,
@@ -420,6 +444,8 @@ CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(CompileSym2Flags)
/// Corresponds to COMPILESYM3::Flags bitfield.
enum class CompileSym3Flags : uint32_t {
+ None = 0,
+ SourceLanguageMask = 0xFF,
EC = 1 << 8,
NoDbgInfo = 1 << 9,
LTCG = 1 << 10,
@@ -436,6 +462,7 @@ enum class CompileSym3Flags : uint32_t {
CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(CompileSym3Flags)
enum class ExportFlags : uint16_t {
+ None = 0,
IsConstant = 1 << 0,
IsData = 1 << 1,
IsPrivate = 1 << 2,
@@ -540,9 +567,54 @@ 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 };
-enum LineFlags : uint32_t {
- HaveColumns = 1, // CV_LINES_HAVE_COLUMNS
-};
+enum LineFlags : uint16_t {
+ LF_None = 0,
+ LF_HaveColumns = 1, // CV_LINES_HAVE_COLUMNS
+};
+
+/// Data in the the SUBSEC_FRAMEDATA subection.
+struct FrameData {
+ support::ulittle32_t RvaStart;
+ support::ulittle32_t CodeSize;
+ support::ulittle32_t LocalSize;
+ support::ulittle32_t ParamsSize;
+ support::ulittle32_t MaxStackSize;
+ support::ulittle32_t FrameFunc;
+ support::ulittle16_t PrologSize;
+ support::ulittle16_t SavedRegsSize;
+ support::ulittle32_t Flags;
+ enum : uint32_t {
+ HasSEH = 1 << 0,
+ HasEH = 1 << 1,
+ IsFunctionStart = 1 << 2,
+ };
+};
+
+// Corresponds to LocalIdAndGlobalIdPair structure.
+// This structure information allows cross-referencing between PDBs. For
+// example, when a PDB is being built during compilation it is not yet known
+// what other modules may end up in the PDB at link time. So certain types of
+// IDs may clash between the various compile time PDBs. For each affected
+// module, a subsection would be put into the PDB containing a mapping from its
+// local IDs to a single ID namespace for all items in the PDB file.
+struct CrossModuleExport {
+ support::ulittle32_t Local;
+ support::ulittle32_t Global;
+};
+
+struct CrossModuleImport {
+ support::ulittle32_t ModuleNameOffset;
+ support::ulittle32_t Count; // Number of elements
+ // support::ulittle32_t ids[Count]; // id from referenced module
+};
+
+enum class CodeViewContainer { ObjectFile, Pdb };
+
+inline uint32_t alignOf(CodeViewContainer Container) {
+ if (Container == CodeViewContainer::ObjectFile)
+ return 1;
+ return 4;
+}
}
}
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewError.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewError.h
index 0556fd0..586a720 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,
+ no_records,
unknown_member_record,
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
index 5a036b9..94f104f 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
@@ -17,8 +17,8 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
-#include "llvm/DebugInfo/MSF/StreamWriter.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Error.h"
#include <cassert>
#include <cstdint>
@@ -33,8 +33,8 @@ class CodeViewRecordIO {
}
public:
- explicit CodeViewRecordIO(msf::StreamReader &Reader) : Reader(&Reader) {}
- explicit CodeViewRecordIO(msf::StreamWriter &Writer) : Writer(&Writer) {}
+ explicit CodeViewRecordIO(BinaryStreamReader &Reader) : Reader(&Reader) {}
+ explicit CodeViewRecordIO(BinaryStreamWriter &Writer) : Writer(&Writer) {}
Error beginRecord(Optional<uint32_t> MaxLength);
Error endRecord();
@@ -84,7 +84,7 @@ public:
Error mapEncodedInteger(uint64_t &Value);
Error mapEncodedInteger(APSInt &Value);
Error mapStringZ(StringRef &Value);
- Error mapGuid(StringRef &Guid);
+ Error mapGuid(GUID &Guid);
Error mapStringZVectorZ(std::vector<StringRef> &Value);
@@ -136,6 +136,7 @@ public:
Error mapByteVectorTail(ArrayRef<uint8_t> &Bytes);
Error mapByteVectorTail(std::vector<uint8_t> &Bytes);
+ Error padToAlignment(uint32_t Align);
Error skipPadding();
private:
@@ -160,8 +161,8 @@ private:
SmallVector<RecordLimit, 2> Limits;
- msf::StreamReader *Reader = nullptr;
- msf::StreamWriter *Writer = nullptr;
+ BinaryStreamReader *Reader = nullptr;
+ BinaryStreamWriter *Writer = nullptr;
};
} // end namespace codeview
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def
index 32813d8..32813d8 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecords.def b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def
index c98dbac..8c193bb 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecords.def
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def
@@ -41,6 +41,7 @@ TYPE_RECORD(LF_POINTER, 0x1002, Pointer)
TYPE_RECORD(LF_MODIFIER, 0x1001, Modifier)
TYPE_RECORD(LF_PROCEDURE, 0x1008, Procedure)
TYPE_RECORD(LF_MFUNCTION, 0x1009, MemberFunction)
+TYPE_RECORD(LF_LABEL, 0x000e, Label)
TYPE_RECORD(LF_ARGLIST, 0x1201, ArgList)
TYPE_RECORD(LF_FIELDLIST, 0x1203, FieldList)
@@ -79,9 +80,7 @@ MEMBER_RECORD(LF_INDEX, 0x1404, ListContinuation)
TYPE_RECORD(LF_FUNC_ID, 0x1601, FuncId)
TYPE_RECORD(LF_MFUNC_ID, 0x1602, MemberFuncId)
TYPE_RECORD(LF_BUILDINFO, 0x1603, BuildInfo)
-// FIXME: We reuse the structure of ArgListRecord for substring lists, but it
-// makes for confusing dumper output.
-TYPE_RECORD_ALIAS(LF_SUBSTR_LIST, 0x1604, StringList, ArgList)
+TYPE_RECORD(LF_SUBSTR_LIST, 0x1604, StringList)
TYPE_RECORD(LF_STRING_ID, 0x1605, StringId)
TYPE_RECORD(LF_UDT_SRC_LINE, 0x1606, UdtSourceLine)
TYPE_RECORD(LF_UDT_MOD_SRC_LINE, 0x1607, UdtModSourceLine)
@@ -103,7 +102,6 @@ CV_TYPE(LF_MFUNCTION_16t, 0x0009)
CV_TYPE(LF_COBOL0_16t, 0x000b)
CV_TYPE(LF_COBOL1, 0x000c)
CV_TYPE(LF_BARRAY_16t, 0x000d)
-CV_TYPE(LF_LABEL, 0x000e)
CV_TYPE(LF_NULLLEAF, 0x000f) // LF_NULL
CV_TYPE(LF_NOTTRAN, 0x0010)
CV_TYPE(LF_DIMARRAY_16t, 0x0011)
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h
new file mode 100644
index 0000000..78b2845
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h
@@ -0,0 +1,104 @@
+//===- DebugChecksumsSubsection.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_DEBUGCHECKSUMSSUBSECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGCHECKSUMSSUBSECTION_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+
+namespace codeview {
+
+class DebugStringTableSubsection;
+
+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.
+};
+
+} // end namespace codeview
+
+template <> struct VarStreamArrayExtractor<codeview::FileChecksumEntry> {
+public:
+ using ContextType = void;
+
+ Error operator()(BinaryStreamRef Stream, uint32_t &Len,
+ codeview::FileChecksumEntry &Item);
+};
+
+namespace codeview {
+
+class DebugChecksumsSubsectionRef final : public DebugSubsectionRef {
+ using FileChecksumArray = VarStreamArray<codeview::FileChecksumEntry>;
+ using Iterator = FileChecksumArray::Iterator;
+
+public:
+ DebugChecksumsSubsectionRef()
+ : DebugSubsectionRef(DebugSubsectionKind::FileChecksums) {}
+
+ static bool classof(const DebugSubsectionRef *S) {
+ return S->kind() == DebugSubsectionKind::FileChecksums;
+ }
+
+ bool valid() const { return Checksums.valid(); }
+
+ Error initialize(BinaryStreamReader Reader);
+ Error initialize(BinaryStreamRef Stream);
+
+ Iterator begin() const { return Checksums.begin(); }
+ Iterator end() const { return Checksums.end(); }
+
+ const FileChecksumArray &getArray() const { return Checksums; }
+
+private:
+ FileChecksumArray Checksums;
+};
+
+class DebugChecksumsSubsection final : public DebugSubsection {
+public:
+ explicit DebugChecksumsSubsection(DebugStringTableSubsection &Strings);
+
+ static bool classof(const DebugSubsection *S) {
+ return S->kind() == DebugSubsectionKind::FileChecksums;
+ }
+
+ void addChecksum(StringRef FileName, FileChecksumKind Kind,
+ ArrayRef<uint8_t> Bytes);
+
+ uint32_t calculateSerializedSize() const override;
+ Error commit(BinaryStreamWriter &Writer) const override;
+ uint32_t mapChecksumOffset(StringRef FileName) const;
+
+private:
+ DebugStringTableSubsection &Strings;
+
+ DenseMap<uint32_t, uint32_t> OffsetMap;
+ uint32_t SerializedSize = 0;
+ BumpPtrAllocator Storage;
+ std::vector<FileChecksumEntry> Checksums;
+};
+
+} // end namespace codeview
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGCHECKSUMSSUBSECTION_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugCrossExSubsection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugCrossExSubsection.h
new file mode 100644
index 0000000..2f9e981
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugCrossExSubsection.h
@@ -0,0 +1,68 @@
+//===- DebugCrossExSubsection.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGCROSSEXSUBSECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGCROSSEXSUBSECTION_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <map>
+
+namespace llvm {
+namespace codeview {
+
+class DebugCrossModuleExportsSubsectionRef final : public DebugSubsectionRef {
+ using ReferenceArray = FixedStreamArray<CrossModuleExport>;
+ using Iterator = ReferenceArray::Iterator;
+
+public:
+ DebugCrossModuleExportsSubsectionRef()
+ : DebugSubsectionRef(DebugSubsectionKind::CrossScopeExports) {}
+
+ static bool classof(const DebugSubsectionRef *S) {
+ return S->kind() == DebugSubsectionKind::CrossScopeExports;
+ }
+
+ Error initialize(BinaryStreamReader Reader);
+ Error initialize(BinaryStreamRef Stream);
+
+ Iterator begin() const { return References.begin(); }
+ Iterator end() const { return References.end(); }
+
+private:
+ FixedStreamArray<CrossModuleExport> References;
+};
+
+class DebugCrossModuleExportsSubsection final : public DebugSubsection {
+public:
+ DebugCrossModuleExportsSubsection()
+ : DebugSubsection(DebugSubsectionKind::CrossScopeExports) {}
+
+ static bool classof(const DebugSubsection *S) {
+ return S->kind() == DebugSubsectionKind::CrossScopeExports;
+ }
+
+ void addMapping(uint32_t Local, uint32_t Global);
+
+ uint32_t calculateSerializedSize() const override;
+ Error commit(BinaryStreamWriter &Writer) const override;
+
+private:
+ std::map<uint32_t, uint32_t> Mappings;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGCROSSEXSUBSECTION_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h
new file mode 100644
index 0000000..8be7ef2
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h
@@ -0,0 +1,95 @@
+//===- DebugCrossExSubsection.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGCROSSIMPSUBSECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGCROSSIMPSUBSECTION_H
+
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+
+namespace codeview {
+
+struct CrossModuleImportItem {
+ const CrossModuleImport *Header = nullptr;
+ FixedStreamArray<support::ulittle32_t> Imports;
+};
+
+} // end namespace codeview
+
+template <> struct VarStreamArrayExtractor<codeview::CrossModuleImportItem> {
+public:
+ using ContextType = void;
+
+ Error operator()(BinaryStreamRef Stream, uint32_t &Len,
+ codeview::CrossModuleImportItem &Item);
+};
+
+namespace codeview {
+
+class DebugStringTableSubsection;
+
+class DebugCrossModuleImportsSubsectionRef final : public DebugSubsectionRef {
+ using ReferenceArray = VarStreamArray<CrossModuleImportItem>;
+ using Iterator = ReferenceArray::Iterator;
+
+public:
+ DebugCrossModuleImportsSubsectionRef()
+ : DebugSubsectionRef(DebugSubsectionKind::CrossScopeImports) {}
+
+ static bool classof(const DebugSubsectionRef *S) {
+ return S->kind() == DebugSubsectionKind::CrossScopeImports;
+ }
+
+ Error initialize(BinaryStreamReader Reader);
+ Error initialize(BinaryStreamRef Stream);
+
+ Iterator begin() const { return References.begin(); }
+ Iterator end() const { return References.end(); }
+
+private:
+ ReferenceArray References;
+};
+
+class DebugCrossModuleImportsSubsection final : public DebugSubsection {
+public:
+ explicit DebugCrossModuleImportsSubsection(
+ DebugStringTableSubsection &Strings)
+ : DebugSubsection(DebugSubsectionKind::CrossScopeImports),
+ Strings(Strings) {}
+
+ static bool classof(const DebugSubsection *S) {
+ return S->kind() == DebugSubsectionKind::CrossScopeImports;
+ }
+
+ void addImport(StringRef Module, uint32_t ImportId);
+
+ uint32_t calculateSerializedSize() const override;
+ Error commit(BinaryStreamWriter &Writer) const override;
+
+private:
+ DebugStringTableSubsection &Strings;
+ StringMap<std::vector<support::ulittle32_t>> Mappings;
+};
+
+} // end namespace codeview
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGCROSSIMPSUBSECTION_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h
new file mode 100644
index 0000000..1e329c7
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h
@@ -0,0 +1,60 @@
+//===- DebugFrameDataSubsection.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_DEBUGFRAMEDATASUBSECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGFRAMEDATASUBSECTION_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace codeview {
+class DebugFrameDataSubsectionRef final : public DebugSubsectionRef {
+public:
+ DebugFrameDataSubsectionRef()
+ : DebugSubsectionRef(DebugSubsectionKind::FrameData) {}
+ static bool classof(const DebugSubsection *S) {
+ return S->kind() == DebugSubsectionKind::FrameData;
+ }
+
+ Error initialize(BinaryStreamReader Reader);
+
+ FixedStreamArray<FrameData>::Iterator begin() const { return Frames.begin(); }
+ FixedStreamArray<FrameData>::Iterator end() const { return Frames.end(); }
+
+ const void *getRelocPtr() const { return RelocPtr; }
+
+private:
+ const uint32_t *RelocPtr = nullptr;
+ FixedStreamArray<FrameData> Frames;
+};
+
+class DebugFrameDataSubsection final : public DebugSubsection {
+public:
+ DebugFrameDataSubsection()
+ : DebugSubsection(DebugSubsectionKind::FrameData) {}
+ static bool classof(const DebugSubsection *S) {
+ return S->kind() == DebugSubsectionKind::FrameData;
+ }
+
+ uint32_t calculateSerializedSize() const override;
+ Error commit(BinaryStreamWriter &Writer) const override;
+
+ void addFrameData(const FrameData &Frame);
+ void setFrames(ArrayRef<FrameData> Frames);
+
+private:
+ std::vector<FrameData> Frames;
+};
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h
new file mode 100644
index 0000000..b88c0ea
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h
@@ -0,0 +1,121 @@
+//===- DebugInlineeLinesSubsection.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_DEBUGINLINEELINESSUBSECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGINLINEELINESSUBSECTION_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/DebugInfo/CodeView/Line.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+
+namespace codeview {
+
+class DebugChecksumsSubsection;
+
+enum class InlineeLinesSignature : uint32_t {
+ Normal, // CV_INLINEE_SOURCE_LINE_SIGNATURE
+ ExtraFiles // CV_INLINEE_SOURCE_LINE_SIGNATURE_EX
+};
+
+struct InlineeSourceLineHeader {
+ TypeIndex Inlinee; // ID of the function that was inlined.
+ support::ulittle32_t FileID; // Offset into FileChecksums subsection.
+ support::ulittle32_t SourceLineNum; // First line of inlined code.
+ // If extra files present:
+ // ulittle32_t ExtraFileCount;
+ // ulittle32_t Files[];
+};
+
+struct InlineeSourceLine {
+ const InlineeSourceLineHeader *Header;
+ FixedStreamArray<support::ulittle32_t> ExtraFiles;
+};
+
+} // end namespace codeview
+
+template <> struct VarStreamArrayExtractor<codeview::InlineeSourceLine> {
+ Error operator()(BinaryStreamRef Stream, uint32_t &Len,
+ codeview::InlineeSourceLine &Item);
+
+ bool HasExtraFiles = false;
+};
+
+namespace codeview {
+
+class DebugInlineeLinesSubsectionRef final : public DebugSubsectionRef {
+ using LinesArray = VarStreamArray<InlineeSourceLine>;
+ using Iterator = LinesArray::Iterator;
+
+public:
+ DebugInlineeLinesSubsectionRef();
+
+ static bool classof(const DebugSubsectionRef *S) {
+ return S->kind() == DebugSubsectionKind::InlineeLines;
+ }
+
+ Error initialize(BinaryStreamReader Reader);
+ bool hasExtraFiles() const;
+
+ Iterator begin() const { return Lines.begin(); }
+ Iterator end() const { return Lines.end(); }
+
+private:
+ InlineeLinesSignature Signature;
+ VarStreamArray<InlineeSourceLine> Lines;
+};
+
+class DebugInlineeLinesSubsection final : public DebugSubsection {
+public:
+ struct Entry {
+ std::vector<support::ulittle32_t> ExtraFiles;
+ InlineeSourceLineHeader Header;
+ };
+
+ DebugInlineeLinesSubsection(DebugChecksumsSubsection &Checksums,
+ bool HasExtraFiles = false);
+
+ static bool classof(const DebugSubsection *S) {
+ return S->kind() == DebugSubsectionKind::InlineeLines;
+ }
+
+ Error commit(BinaryStreamWriter &Writer) const override;
+ uint32_t calculateSerializedSize() const override;
+
+ void addInlineSite(TypeIndex FuncId, StringRef FileName, uint32_t SourceLine);
+ void addExtraFile(StringRef FileName);
+
+ bool hasExtraFiles() const { return HasExtraFiles; }
+ void setHasExtraFiles(bool Has) { HasExtraFiles = Has; }
+
+ std::vector<Entry>::const_iterator begin() const { return Entries.begin(); }
+ std::vector<Entry>::const_iterator end() const { return Entries.end(); }
+
+private:
+ DebugChecksumsSubsection &Checksums;
+ bool HasExtraFiles = false;
+ uint32_t ExtraFileCount = 0;
+ std::vector<Entry> Entries;
+};
+
+} // end namespace codeview
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGINLINEELINESSUBSECTION_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugLinesSubsection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugLinesSubsection.h
new file mode 100644
index 0000000..53044b6
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugLinesSubsection.h
@@ -0,0 +1,150 @@
+//===- DebugLinesSubsection.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_DEBUGLINESSUBSECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGLINESSUBSECTION_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/DebugInfo/CodeView/Line.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+namespace codeview {
+
+class DebugChecksumsSubsection;
+class DebugStringTableSubsection;
+
+// Corresponds to the `CV_DebugSLinesHeader_t` structure.
+struct LineFragmentHeader {
+ support::ulittle32_t RelocOffset; // Code offset of line contribution.
+ support::ulittle16_t RelocSegment; // Code segment of line contribution.
+ support::ulittle16_t Flags; // See LineFlags enumeration.
+ support::ulittle32_t CodeSize; // Code size of this line contribution.
+};
+
+// Corresponds to the `CV_DebugSLinesFileBlockHeader_t` structure.
+struct LineBlockFragmentHeader {
+ support::ulittle32_t NameIndex; // Offset of FileChecksum entry in File
+ // checksums buffer. The checksum entry then
+ // contains another offset into the string
+ // table of the actual name.
+ support::ulittle32_t NumLines; // Number of lines
+ support::ulittle32_t BlockSize; // Code size of block, in bytes.
+ // The following two variable length arrays appear immediately after the
+ // header. The structure definitions follow.
+ // LineNumberEntry Lines[NumLines];
+ // ColumnNumberEntry Columns[NumLines];
+};
+
+// Corresponds to `CV_Line_t` structure
+struct LineNumberEntry {
+ support::ulittle32_t Offset; // Offset to start of code bytes for line number
+ support::ulittle32_t Flags; // Start:24, End:7, IsStatement:1
+};
+
+// Corresponds to `CV_Column_t` structure
+struct ColumnNumberEntry {
+ support::ulittle16_t StartColumn;
+ support::ulittle16_t EndColumn;
+};
+
+struct LineColumnEntry {
+ support::ulittle32_t NameIndex;
+ FixedStreamArray<LineNumberEntry> LineNumbers;
+ FixedStreamArray<ColumnNumberEntry> Columns;
+};
+
+class LineColumnExtractor {
+public:
+ Error operator()(BinaryStreamRef Stream, uint32_t &Len,
+ LineColumnEntry &Item);
+
+ const LineFragmentHeader *Header = nullptr;
+};
+
+class DebugLinesSubsectionRef final : public DebugSubsectionRef {
+ friend class LineColumnExtractor;
+
+ using LineInfoArray = VarStreamArray<LineColumnEntry, LineColumnExtractor>;
+ using Iterator = LineInfoArray::Iterator;
+
+public:
+ DebugLinesSubsectionRef();
+
+ static bool classof(const DebugSubsectionRef *S) {
+ return S->kind() == DebugSubsectionKind::Lines;
+ }
+
+ Error initialize(BinaryStreamReader Reader);
+
+ Iterator begin() const { return LinesAndColumns.begin(); }
+ Iterator end() const { return LinesAndColumns.end(); }
+
+ const LineFragmentHeader *header() const { return Header; }
+
+ bool hasColumnInfo() const;
+
+private:
+ const LineFragmentHeader *Header = nullptr;
+ LineInfoArray LinesAndColumns;
+};
+
+class DebugLinesSubsection final : public DebugSubsection {
+ struct Block {
+ Block(uint32_t ChecksumBufferOffset)
+ : ChecksumBufferOffset(ChecksumBufferOffset) {}
+
+ uint32_t ChecksumBufferOffset;
+ std::vector<LineNumberEntry> Lines;
+ std::vector<ColumnNumberEntry> Columns;
+ };
+
+public:
+ DebugLinesSubsection(DebugChecksumsSubsection &Checksums,
+ DebugStringTableSubsection &Strings);
+
+ static bool classof(const DebugSubsection *S) {
+ return S->kind() == DebugSubsectionKind::Lines;
+ }
+
+ void createBlock(StringRef FileName);
+ void addLineInfo(uint32_t Offset, const LineInfo &Line);
+ void addLineAndColumnInfo(uint32_t Offset, const LineInfo &Line,
+ uint32_t ColStart, uint32_t ColEnd);
+
+ uint32_t calculateSerializedSize() const override;
+ Error commit(BinaryStreamWriter &Writer) const override;
+
+ void setRelocationAddress(uint16_t Segment, uint32_t Offset);
+ void setCodeSize(uint32_t Size);
+ void setFlags(LineFlags Flags);
+
+ bool hasColumnInfo() const;
+
+private:
+ DebugChecksumsSubsection &Checksums;
+ uint32_t RelocOffset = 0;
+ uint16_t RelocSegment = 0;
+ uint32_t CodeSize = 0;
+ LineFlags Flags = LF_None;
+ std::vector<Block> Blocks;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGLINESSUBSECTION_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h
new file mode 100644
index 0000000..7f0f10e
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h
@@ -0,0 +1,89 @@
+//===- DebugStringTableSubsection.h - CodeView String Table -----*- 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_DEBUGSTRINGTABLESUBSECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGSTRINGTABLESUBSECTION_H
+
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+
+namespace llvm {
+
+class BinaryStreamReader;
+
+namespace codeview {
+
+/// Represents a read-only view of a CodeView string table. This is a very
+/// simple flat buffer consisting of null-terminated strings, where strings
+/// are retrieved by their offset in the buffer. DebugStringTableSubsectionRef
+/// does not own the underlying storage for the buffer.
+class DebugStringTableSubsectionRef : public DebugSubsectionRef {
+public:
+ DebugStringTableSubsectionRef();
+
+ static bool classof(const DebugSubsectionRef *S) {
+ return S->kind() == DebugSubsectionKind::StringTable;
+ }
+
+ Error initialize(BinaryStreamRef Contents);
+ Error initialize(BinaryStreamReader &Reader);
+
+ Expected<StringRef> getString(uint32_t Offset) const;
+
+ bool valid() const { return Stream.valid(); }
+
+ BinaryStreamRef getBuffer() const { return Stream; }
+
+private:
+ BinaryStreamRef Stream;
+};
+
+/// Represents a read-write view of a CodeView string table.
+/// DebugStringTableSubsection owns the underlying storage for the table, and is
+/// capable of serializing the string table into a format understood by
+/// DebugStringTableSubsectionRef.
+class DebugStringTableSubsection : public DebugSubsection {
+public:
+ DebugStringTableSubsection();
+
+ static bool classof(const DebugSubsection *S) {
+ return S->kind() == DebugSubsectionKind::StringTable;
+ }
+
+ // If string S does not exist in the string table, insert it.
+ // Returns the ID for S.
+ uint32_t insert(StringRef S);
+
+ // Return the ID for string S. Assumes S exists in the table.
+ uint32_t getStringId(StringRef S) const;
+
+ uint32_t calculateSerializedSize() const override;
+ Error commit(BinaryStreamWriter &Writer) const override;
+
+ uint32_t size() const;
+
+ StringMap<uint32_t>::const_iterator begin() const { return Strings.begin(); }
+
+ StringMap<uint32_t>::const_iterator end() const { return Strings.end(); }
+
+private:
+ StringMap<uint32_t> Strings;
+ uint32_t StringSize = 1;
+};
+
+} // end namespace codeview
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGSTRINGTABLESUBSECTION_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsection.h
new file mode 100644
index 0000000..e427e00
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsection.h
@@ -0,0 +1,52 @@
+//===- DebugSubsection.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_MODULEDEBUGFRAGMENT_H
+#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENT_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Casting.h"
+
+namespace llvm {
+namespace codeview {
+
+class DebugSubsectionRef {
+public:
+ explicit DebugSubsectionRef(DebugSubsectionKind Kind) : Kind(Kind) {}
+ virtual ~DebugSubsectionRef();
+
+ static bool classof(const DebugSubsectionRef *S) { return true; }
+
+ DebugSubsectionKind kind() const { return Kind; }
+
+protected:
+ DebugSubsectionKind Kind;
+};
+
+class DebugSubsection {
+public:
+ explicit DebugSubsection(DebugSubsectionKind Kind) : Kind(Kind) {}
+ virtual ~DebugSubsection();
+
+ static bool classof(const DebugSubsection *S) { return true; }
+
+ DebugSubsectionKind kind() const { return Kind; }
+
+ virtual Error commit(BinaryStreamWriter &Writer) const = 0;
+ virtual uint32_t calculateSerializedSize() const = 0;
+
+protected:
+ DebugSubsectionKind Kind;
+};
+
+} // namespace codeview
+} // namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENT_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h
new file mode 100644
index 0000000..fc0cf0d
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h
@@ -0,0 +1,103 @@
+//===- DebugSubsectionRecord.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_DEBUGSUBSECTIONRECORD_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGSUBSECTIONRECORD_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MathExtras.h"
+#include <cstdint>
+#include <memory>
+
+namespace llvm {
+
+class BinaryStreamWriter;
+
+namespace codeview {
+
+class DebugSubsection;
+
+// Corresponds to the `CV_DebugSSubsectionHeader_t` structure.
+struct DebugSubsectionHeader {
+ support::ulittle32_t Kind; // codeview::DebugSubsectionKind enum
+ support::ulittle32_t Length; // number of bytes occupied by this record.
+};
+
+class DebugSubsectionRecord {
+public:
+ DebugSubsectionRecord();
+ DebugSubsectionRecord(DebugSubsectionKind Kind, BinaryStreamRef Data,
+ CodeViewContainer Container);
+
+ static Error initialize(BinaryStreamRef Stream, DebugSubsectionRecord &Info,
+ CodeViewContainer Container);
+
+ uint32_t getRecordLength() const;
+ DebugSubsectionKind kind() const;
+ BinaryStreamRef getRecordData() const;
+
+private:
+ CodeViewContainer Container = CodeViewContainer::ObjectFile;
+ DebugSubsectionKind Kind = DebugSubsectionKind::None;
+ BinaryStreamRef Data;
+};
+
+class DebugSubsectionRecordBuilder {
+public:
+ DebugSubsectionRecordBuilder(std::shared_ptr<DebugSubsection> Subsection,
+ CodeViewContainer Container);
+
+ /// Use this to copy existing subsections directly from source to destination.
+ /// For example, line table subsections in an object file only need to be
+ /// relocated before being copied into the PDB.
+ DebugSubsectionRecordBuilder(const DebugSubsectionRecord &Contents,
+ CodeViewContainer Container);
+
+ uint32_t calculateSerializedLength();
+ Error commit(BinaryStreamWriter &Writer) const;
+
+private:
+ /// The subsection to build. Will be null if Contents is non-empty.
+ std::shared_ptr<DebugSubsection> Subsection;
+
+ /// The bytes of the subsection. Only non-empty if Subsection is null.
+ DebugSubsectionRecord Contents;
+
+ CodeViewContainer Container;
+};
+
+} // end namespace codeview
+
+template <> struct VarStreamArrayExtractor<codeview::DebugSubsectionRecord> {
+ Error operator()(BinaryStreamRef Stream, uint32_t &Length,
+ codeview::DebugSubsectionRecord &Info) {
+ // FIXME: We need to pass the container type through to this function. In
+ // practice this isn't super important since the subsection header describes
+ // its length and we can just skip it. It's more important when writing.
+ if (auto EC = codeview::DebugSubsectionRecord::initialize(
+ Stream, Info, codeview::CodeViewContainer::Pdb))
+ return EC;
+ Length = alignTo(Info.getRecordLength(), 4);
+ return Error::success();
+ }
+};
+
+namespace codeview {
+
+using DebugSubsectionArray = VarStreamArray<DebugSubsectionRecord>;
+
+} // end namespace codeview
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGSUBSECTIONRECORD_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h
new file mode 100644
index 0000000..75f749d
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h
@@ -0,0 +1,114 @@
+//===- DebugSubsectionVisitor.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_MODULEDEBUGFRAGMENTVISITOR_H
+#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTVISITOR_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
+#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+
+namespace llvm {
+
+namespace codeview {
+
+class DebugChecksumsSubsectionRef;
+class DebugSubsectionRecord;
+class DebugInlineeLinesSubsectionRef;
+class DebugCrossModuleExportsSubsectionRef;
+class DebugCrossModuleImportsSubsectionRef;
+class DebugFrameDataSubsectionRef;
+class DebugLinesSubsectionRef;
+class DebugStringTableSubsectionRef;
+class DebugSymbolRVASubsectionRef;
+class DebugSymbolsSubsectionRef;
+class DebugUnknownSubsectionRef;
+class StringsAndChecksumsRef;
+
+class DebugSubsectionVisitor {
+public:
+ virtual ~DebugSubsectionVisitor() = default;
+
+ virtual Error visitUnknown(DebugUnknownSubsectionRef &Unknown) {
+ return Error::success();
+ }
+ virtual Error visitLines(DebugLinesSubsectionRef &Lines,
+ const StringsAndChecksumsRef &State) = 0;
+ virtual Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums,
+ const StringsAndChecksumsRef &State) = 0;
+ virtual Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees,
+ const StringsAndChecksumsRef &State) = 0;
+ virtual Error
+ visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef &CSE,
+ const StringsAndChecksumsRef &State) = 0;
+ virtual Error
+ visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &CSE,
+ const StringsAndChecksumsRef &State) = 0;
+
+ virtual Error visitStringTable(DebugStringTableSubsectionRef &ST,
+ const StringsAndChecksumsRef &State) = 0;
+
+ virtual Error visitSymbols(DebugSymbolsSubsectionRef &CSE,
+ const StringsAndChecksumsRef &State) = 0;
+
+ virtual Error visitFrameData(DebugFrameDataSubsectionRef &FD,
+ const StringsAndChecksumsRef &State) = 0;
+ virtual Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &RVAs,
+ const StringsAndChecksumsRef &State) = 0;
+};
+
+Error visitDebugSubsection(const DebugSubsectionRecord &R,
+ DebugSubsectionVisitor &V,
+ const StringsAndChecksumsRef &State);
+
+namespace detail {
+template <typename T>
+Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V,
+ StringsAndChecksumsRef &State) {
+ State.initialize(std::forward<T>(FragmentRange));
+
+ for (const DebugSubsectionRecord &L : FragmentRange) {
+ if (auto EC = visitDebugSubsection(L, V, State))
+ return EC;
+ }
+ return Error::success();
+}
+} // namespace detail
+
+template <typename T>
+Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V) {
+ StringsAndChecksumsRef State;
+ return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V,
+ State);
+}
+
+template <typename T>
+Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V,
+ const DebugStringTableSubsectionRef &Strings) {
+ StringsAndChecksumsRef State(Strings);
+ return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V,
+ State);
+}
+
+template <typename T>
+Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V,
+ const DebugStringTableSubsectionRef &Strings,
+ const DebugChecksumsSubsectionRef &Checksums) {
+ StringsAndChecksumsRef State(Strings, Checksums);
+ return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V,
+ State);
+}
+
+} // end namespace codeview
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTVISITOR_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h
new file mode 100644
index 0000000..a4c04b5
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h
@@ -0,0 +1,67 @@
+//===- DebugSymbolRVASubsection.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGSYMBOLRVASUBSECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGSYMBOLRVASUBSECTION_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+
+class BinaryStreamReader;
+
+namespace codeview {
+
+class DebugSymbolRVASubsectionRef final : public DebugSubsectionRef {
+public:
+ using ArrayType = FixedStreamArray<support::ulittle32_t>;
+
+ DebugSymbolRVASubsectionRef();
+
+ static bool classof(const DebugSubsectionRef *S) {
+ return S->kind() == DebugSubsectionKind::CoffSymbolRVA;
+ }
+
+ ArrayType::Iterator begin() const { return RVAs.begin(); }
+ ArrayType::Iterator end() const { return RVAs.end(); }
+
+ Error initialize(BinaryStreamReader &Reader);
+
+private:
+ ArrayType RVAs;
+};
+
+class DebugSymbolRVASubsection final : public DebugSubsection {
+public:
+ DebugSymbolRVASubsection();
+
+ static bool classof(const DebugSubsection *S) {
+ return S->kind() == DebugSubsectionKind::CoffSymbolRVA;
+ }
+
+ Error commit(BinaryStreamWriter &Writer) const override;
+ uint32_t calculateSerializedSize() const override;
+
+ void addRVA(uint32_t RVA) { RVAs.push_back(support::ulittle32_t(RVA)); }
+
+private:
+ std::vector<support::ulittle32_t> RVAs;
+};
+
+} // end namespace codeview
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGSYMBOLRVASUBSECTION_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h
new file mode 100644
index 0000000..dfda7de
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h
@@ -0,0 +1,56 @@
+//===- DebugSymbolsSubsection.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_DEBUGSYMBOLSSUBSECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGSYMBOLSSUBSECTION_H
+
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace codeview {
+class DebugSymbolsSubsectionRef final : public DebugSubsectionRef {
+public:
+ DebugSymbolsSubsectionRef()
+ : DebugSubsectionRef(DebugSubsectionKind::Symbols) {}
+
+ static bool classof(const DebugSubsectionRef *S) {
+ return S->kind() == DebugSubsectionKind::Symbols;
+ }
+
+ Error initialize(BinaryStreamReader Reader);
+
+ CVSymbolArray::Iterator begin() const { return Records.begin(); }
+ CVSymbolArray::Iterator end() const { return Records.end(); }
+
+private:
+ CVSymbolArray Records;
+};
+
+class DebugSymbolsSubsection final : public DebugSubsection {
+public:
+ DebugSymbolsSubsection() : DebugSubsection(DebugSubsectionKind::Symbols) {}
+ static bool classof(const DebugSubsection *S) {
+ return S->kind() == DebugSubsectionKind::Symbols;
+ }
+
+ uint32_t calculateSerializedSize() const override;
+ Error commit(BinaryStreamWriter &Writer) const override;
+
+ void addSymbol(CVSymbol Symbol);
+
+private:
+ uint32_t Length = 0;
+ std::vector<CVSymbol> Records;
+};
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugUnknownSubsection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugUnknownSubsection.h
new file mode 100644
index 0000000..ea9a96c
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugUnknownSubsection.h
@@ -0,0 +1,32 @@
+//===- DebugUnknownSubsection.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_MODULEDEBUGUNKNOWNFRAGMENT_H
+#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGUNKNOWNFRAGMENT_H
+
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/Support/BinaryStreamRef.h"
+
+namespace llvm {
+namespace codeview {
+
+class DebugUnknownSubsectionRef final : public DebugSubsectionRef {
+public:
+ DebugUnknownSubsectionRef(DebugSubsectionKind Kind, BinaryStreamRef Data)
+ : DebugSubsectionRef(Kind), Data(Data) {}
+
+ BinaryStreamRef getData() const { return Data; }
+
+private:
+ BinaryStreamRef Data;
+};
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/EnumTables.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/EnumTables.h
index 10d1c58..ee0f0f7 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/EnumTables.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/EnumTables.h
@@ -1,4 +1,4 @@
-//===- EnumTables.h Enum to string conversion tables ------------*- C++ -*-===//
+//===- EnumTables.h - Enum to string conversion tables ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,17 +11,18 @@
#define LLVM_DEBUGINFO_CODEVIEW_ENUMTABLES_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/BinaryFormat/COFF.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/Support/COFF.h"
#include "llvm/Support/ScopedPrinter.h"
-
-#include <stdint.h>
+#include <cstdint>
namespace llvm {
namespace codeview {
+
ArrayRef<EnumEntry<SymbolKind>> getSymbolTypeNames();
ArrayRef<EnumEntry<TypeLeafKind>> getTypeLeafNames();
ArrayRef<EnumEntry<uint16_t>> getRegisterNames();
+ArrayRef<EnumEntry<uint32_t>> getPublicSymFlagNames();
ArrayRef<EnumEntry<uint8_t>> getProcSymFlagNames();
ArrayRef<EnumEntry<uint16_t>> getLocalFlagNames();
ArrayRef<EnumEntry<uint8_t>> getFrameCookieKindNames();
@@ -37,7 +38,8 @@ ArrayRef<EnumEntry<uint8_t>> getThunkOrdinalNames();
ArrayRef<EnumEntry<uint16_t>> getTrampolineNames();
ArrayRef<EnumEntry<COFF::SectionCharacteristics>>
getImageSectionCharacteristicNames();
-} // namespace codeview
-} // namespace llvm
+
+} // end namespace codeview
+} // end namespace llvm
#endif // LLVM_DEBUGINFO_CODEVIEW_ENUMTABLES_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/Formatters.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/Formatters.h
new file mode 100644
index 0000000..278ad02
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/Formatters.h
@@ -0,0 +1,73 @@
+//===- Formatters.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_FORMATTERS_H
+#define LLVM_DEBUGINFO_CODEVIEW_FORMATTERS_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/GUID.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/Support/FormatAdapters.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
+
+namespace llvm {
+
+namespace codeview {
+
+namespace detail {
+
+class GuidAdapter final : public FormatAdapter<ArrayRef<uint8_t>> {
+ ArrayRef<uint8_t> Guid;
+
+public:
+ explicit GuidAdapter(ArrayRef<uint8_t> Guid);
+ explicit GuidAdapter(StringRef Guid);
+
+ void format(raw_ostream &Stream, StringRef Style) override;
+};
+
+} // end namespace detail
+
+inline detail::GuidAdapter fmt_guid(StringRef Item) {
+ return detail::GuidAdapter(Item);
+}
+
+inline detail::GuidAdapter fmt_guid(ArrayRef<uint8_t> Item) {
+ return detail::GuidAdapter(Item);
+}
+
+} // end namespace codeview
+
+template <> struct format_provider<codeview::TypeIndex> {
+public:
+ static void format(const codeview::TypeIndex &V, raw_ostream &Stream,
+ StringRef Style) {
+ if (V.isNoneType())
+ Stream << "<no type>";
+ else {
+ Stream << formatv("{0:X+4}", V.getIndex());
+ if (V.isSimple())
+ Stream << " (" << codeview::TypeIndex::simpleTypeName(V) << ")";
+ }
+ }
+};
+
+template <> struct format_provider<codeview::GUID> {
+ static void format(const codeview::GUID &V, llvm::raw_ostream &Stream,
+ StringRef Style) {
+ Stream << V;
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_FORMATTERS_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/GUID.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/GUID.h
new file mode 100644
index 0000000..a055ce9
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/GUID.h
@@ -0,0 +1,55 @@
+//===- GUID.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_GUID_H
+#define LLVM_DEBUGINFO_CODEVIEW_GUID_H
+
+#include <cstdint>
+#include <cstring>
+
+namespace llvm {
+class raw_ostream;
+
+namespace codeview {
+
+/// This represents the 'GUID' type from windows.h.
+struct GUID {
+ uint8_t Guid[16];
+};
+
+inline bool operator==(const GUID &LHS, const GUID &RHS) {
+ return 0 == ::memcmp(LHS.Guid, RHS.Guid, sizeof(LHS.Guid));
+}
+
+inline bool operator<(const GUID &LHS, const GUID &RHS) {
+ return ::memcmp(LHS.Guid, RHS.Guid, sizeof(LHS.Guid)) < 0;
+}
+
+inline bool operator<=(const GUID &LHS, const GUID &RHS) {
+ return ::memcmp(LHS.Guid, RHS.Guid, sizeof(LHS.Guid)) <= 0;
+}
+
+inline bool operator>(const GUID &LHS, const GUID &RHS) {
+ return !(LHS <= RHS);
+}
+
+inline bool operator>=(const GUID &LHS, const GUID &RHS) {
+ return !(LHS < RHS);
+}
+
+inline bool operator!=(const GUID &LHS, const GUID &RHS) {
+ return !(LHS == RHS);
+}
+
+raw_ostream &operator<<(raw_ostream &OS, const GUID &Guid);
+
+} // namespace codeview
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h
new file mode 100644
index 0000000..cc0c243
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h
@@ -0,0 +1,113 @@
+//===- LazyRandomTypeCollection.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_LAZYRANDOMTYPECOLLECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_LAZYRANDOMTYPECOLLECTION_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/TypeCollection.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/StringSaver.h"
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+namespace codeview {
+
+/// \brief Provides amortized O(1) random access to a CodeView type stream.
+/// Normally to access a type from a type stream, you must know its byte
+/// offset into the type stream, because type records are variable-lengthed.
+/// However, this is not the way we prefer to access them. For example, given
+/// a symbol record one of the fields may be the TypeIndex of the symbol's
+/// type record. Or given a type record such as an array type, there might
+/// be a TypeIndex for the element type. Sequential access is perfect when
+/// we're just dumping every entry, but it's very poor for real world usage.
+///
+/// Type streams in PDBs contain an additional field which is a list of pairs
+/// containing indices and their corresponding offsets, roughly every ~8KB of
+/// record data. This general idea need not be confined to PDBs though. By
+/// supplying such an array, the producer of a type stream can allow the
+/// consumer much better access time, because the consumer can find the nearest
+/// index in this array, and do a linear scan forward only from there.
+///
+/// LazyRandomTypeCollection implements this algorithm, but additionally goes
+/// one step further by caching offsets of every record that has been visited at
+/// least once. This way, even repeated visits of the same record will never
+/// require more than one linear scan. For a type stream of N elements divided
+/// into M chunks of roughly equal size, this yields a worst case lookup time
+/// of O(N/M) and an amortized time of O(1).
+class LazyRandomTypeCollection : public TypeCollection {
+ using PartialOffsetArray = FixedStreamArray<TypeIndexOffset>;
+
+ struct CacheEntry {
+ CVType Type;
+ uint32_t Offset;
+ StringRef Name;
+ };
+
+public:
+ explicit LazyRandomTypeCollection(uint32_t RecordCountHint);
+ LazyRandomTypeCollection(StringRef Data, uint32_t RecordCountHint);
+ LazyRandomTypeCollection(ArrayRef<uint8_t> Data, uint32_t RecordCountHint);
+ LazyRandomTypeCollection(const CVTypeArray &Types, uint32_t RecordCountHint,
+ PartialOffsetArray PartialOffsets);
+ LazyRandomTypeCollection(const CVTypeArray &Types, uint32_t RecordCountHint);
+
+ void reset(ArrayRef<uint8_t> Data, uint32_t RecordCountHint);
+ void reset(StringRef Data, uint32_t RecordCountHint);
+
+ uint32_t getOffsetOfType(TypeIndex Index);
+
+ CVType getType(TypeIndex Index) override;
+ StringRef getTypeName(TypeIndex Index) override;
+ bool contains(TypeIndex Index) override;
+ uint32_t size() override;
+ uint32_t capacity() override;
+ Optional<TypeIndex> getFirst() override;
+ Optional<TypeIndex> getNext(TypeIndex Prev) override;
+
+private:
+ Error ensureTypeExists(TypeIndex Index);
+ void ensureCapacityFor(TypeIndex Index);
+
+ Error visitRangeForType(TypeIndex TI);
+ Error fullScanForType(TypeIndex TI);
+ void visitRange(TypeIndex Begin, uint32_t BeginOffset, TypeIndex End);
+
+ /// Number of actual records.
+ uint32_t Count = 0;
+
+ /// The largest type index which we've visited.
+ TypeIndex LargestTypeIndex = TypeIndex::None();
+
+ BumpPtrAllocator Allocator;
+ StringSaver NameStorage;
+
+ /// The type array to allow random access visitation of.
+ CVTypeArray Types;
+
+ std::vector<CacheEntry> Records;
+
+ /// An array of index offsets for the given type stream, allowing log(N)
+ /// lookups of a type record by index. Similar to KnownOffsets but only
+ /// contains offsets for some type indices, some of which may not have
+ /// ever been visited.
+ PartialOffsetArray PartialOffsets;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_LAZYRANDOMTYPECOLLECTION_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/Line.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/Line.h
index 975b503..ac229c3 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/Line.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/Line.h
@@ -127,27 +127,6 @@ public:
bool isNeverStepInto() const { return LineInf.isNeverStepInto(); }
};
-enum class InlineeLinesSignature : uint32_t {
- Normal, // CV_INLINEE_SOURCE_LINE_SIGNATURE
- ExtraFiles // CV_INLINEE_SOURCE_LINE_SIGNATURE_EX
-};
-
-struct InlineeSourceLine {
- TypeIndex Inlinee; // ID of the function that was inlined.
- ulittle32_t FileID; // Offset into FileChecksums subsection.
- ulittle32_t SourceLineNum; // First line of inlined code.
- // If extra files present:
- // ulittle32_t ExtraFileCount;
- // ulittle32_t Files[];
-};
-
-struct FileChecksum {
- ulittle32_t FileNameOffset; // Byte offset of filename in global string table.
- uint8_t ChecksumSize; // Number of bytes of checksum.
- uint8_t ChecksumKind; // FileChecksumKind
- // Checksum bytes follow.
-};
-
} // namespace codeview
} // namespace llvm
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstream.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstream.h
deleted file mode 100644
index 8860ae4..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstream.h
+++ /dev/null
@@ -1,89 +0,0 @@
-//===- ModuleSubstream.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_MODULESUBSTREAM_H
-#define LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAM_H
-
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/MSF/StreamArray.h"
-#include "llvm/DebugInfo/MSF/StreamRef.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-
-namespace llvm {
-namespace codeview {
-
-// Corresponds to the `CV_DebugSSubsectionHeader_t` structure.
-struct ModuleSubsectionHeader {
- support::ulittle32_t Kind; // codeview::ModuleSubstreamKind enum
- support::ulittle32_t Length; // number of bytes occupied by this record.
-};
-
-// Corresponds to the `CV_DebugSLinesHeader_t` structure.
-struct LineSubstreamHeader {
- support::ulittle32_t RelocOffset; // Code offset of line contribution.
- support::ulittle16_t RelocSegment; // Code segment of line contribution.
- support::ulittle16_t Flags; // See LineFlags enumeration.
- support::ulittle32_t CodeSize; // Code size of this line contribution.
-};
-
-// Corresponds to the `CV_DebugSLinesFileBlockHeader_t` structure.
-struct LineFileBlockHeader {
- support::ulittle32_t NameIndex; // Index in DBI name buffer of filename.
- support::ulittle32_t NumLines; // Number of lines
- support::ulittle32_t BlockSize; // Code size of block, in bytes.
- // The following two variable length arrays appear immediately after the
- // header. The structure definitions follow.
- // LineNumberEntry Lines[NumLines];
- // ColumnNumberEntry Columns[NumLines];
-};
-
-// Corresponds to `CV_Line_t` structure
-struct LineNumberEntry {
- support::ulittle32_t Offset; // Offset to start of code bytes for line number
- support::ulittle32_t Flags; // Start:24, End:7, IsStatement:1
-};
-
-// Corresponds to `CV_Column_t` structure
-struct ColumnNumberEntry {
- support::ulittle16_t StartColumn;
- support::ulittle16_t EndColumn;
-};
-
-class ModuleSubstream {
-public:
- ModuleSubstream();
- ModuleSubstream(ModuleSubstreamKind Kind, msf::ReadableStreamRef Data);
- static Error initialize(msf::ReadableStreamRef Stream, ModuleSubstream &Info);
- uint32_t getRecordLength() const;
- ModuleSubstreamKind getSubstreamKind() const;
- msf::ReadableStreamRef getRecordData() const;
-
-private:
- ModuleSubstreamKind Kind;
- msf::ReadableStreamRef Data;
-};
-
-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();
- }
-};
-} // 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
deleted file mode 100644
index f9927d6..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h
+++ /dev/null
@@ -1,136 +0,0 @@
-//===- ModuleSubstreamVisitor.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_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/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;
- msf::FixedStreamArray<LineNumberEntry> LineNumbers;
- msf::FixedStreamArray<ColumnNumberEntry> Columns;
-};
-
-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:
- virtual ~IModuleSubstreamVisitor() = default;
-
- 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))
- return EC;
- bool HasColumn = Header->Flags & LineFlags::HaveColumns;
- uint32_t LineInfoSize =
- BlockHeader->NumLines *
- (sizeof(LineNumberEntry) + (HasColumn ? sizeof(ColumnNumberEntry) : 0));
- if (BlockHeader->BlockSize < sizeof(LineFileBlockHeader))
- return make_error<CodeViewError>(cv_error_code::corrupt_record,
- "Invalid line block record size");
- uint32_t Size = BlockHeader->BlockSize - sizeof(LineFileBlockHeader);
- if (LineInfoSize > Size)
- return make_error<CodeViewError>(cv_error_code::corrupt_record,
- "Invalid line block record size");
- // The value recorded in BlockHeader->BlockSize includes the size of
- // LineFileBlockHeader.
- Len = BlockHeader->BlockSize;
- Item.NameIndex = BlockHeader->NameIndex;
- if (auto EC = Reader.readArray(Item.LineNumbers, BlockHeader->NumLines))
- return EC;
- if (HasColumn) {
- if (auto EC = Reader.readArray(Item.Columns, BlockHeader->NumLines))
- return EC;
- }
- return Error::success();
- }
-
-private:
- const codeview::LineSubstreamHeader *Header;
-};
-
-template <> class VarStreamArrayExtractor<codeview::FileChecksumEntry> {
-public:
- 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))
- return EC;
- Item.FileNameOffset = Header->FileNameOffset;
- Item.Kind = static_cast<FileChecksumKind>(Header->ChecksumKind);
- if (auto EC = Reader.readBytes(Item.Checksum, Header->ChecksumSize))
- return EC;
- Len = sizeof(FileChecksum) + Header->ChecksumSize;
- return Error::success();
- }
-};
-
-} // end namespace msf
-
-} // 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 97b6f56..58449c2 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h
@@ -15,7 +15,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
+#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include <cinttypes>
@@ -41,37 +41,37 @@ struct RecordPrefix {
StringRef getBytesAsCharacters(ArrayRef<uint8_t> LeafData);
StringRef getBytesAsCString(ArrayRef<uint8_t> LeafData);
-inline Error consume(msf::StreamReader &Reader) { return Error::success(); }
+inline Error consume(BinaryStreamReader &Reader) { return Error::success(); }
/// Decodes a numeric "leaf" value. These are integer literals encountered in
/// the type stream. If the value is positive and less than LF_NUMERIC (1 <<
/// 15), it is emitted directly in Data. Otherwise, it has a tag like LF_CHAR
/// that indicates the bitwidth and sign of the numeric data.
-Error consume(msf::StreamReader &Reader, APSInt &Num);
+Error consume(BinaryStreamReader &Reader, APSInt &Num);
/// Decodes a numeric leaf value that is known to be a particular type.
-Error consume_numeric(msf::StreamReader &Reader, uint64_t &Value);
+Error consume_numeric(BinaryStreamReader &Reader, uint64_t &Value);
/// Decodes signed and unsigned fixed-length integers.
-Error consume(msf::StreamReader &Reader, uint32_t &Item);
-Error consume(msf::StreamReader &Reader, int32_t &Item);
+Error consume(BinaryStreamReader &Reader, uint32_t &Item);
+Error consume(BinaryStreamReader &Reader, int32_t &Item);
/// Decodes a null terminated string.
-Error consume(msf::StreamReader &Reader, StringRef &Item);
+Error consume(BinaryStreamReader &Reader, StringRef &Item);
Error consume(StringRef &Data, APSInt &Num);
Error consume(StringRef &Data, uint32_t &Item);
/// Decodes an arbitrary object whose layout matches that of the underlying
/// byte sequence, and returns a pointer to the object.
-template <typename T> Error consume(msf::StreamReader &Reader, T *&Item) {
+template <typename T> Error consume(BinaryStreamReader &Reader, T *&Item) {
return Reader.readObject(Item);
}
template <typename T, typename U> struct serialize_conditional_impl {
serialize_conditional_impl(T &Item, U Func) : Item(Item), Func(Func) {}
- Error deserialize(msf::StreamReader &Reader) const {
+ Error deserialize(BinaryStreamReader &Reader) const {
if (!Func())
return Error::success();
return consume(Reader, Item);
@@ -89,7 +89,7 @@ serialize_conditional_impl<T, U> serialize_conditional(T &Item, U Func) {
template <typename T, typename U> struct serialize_array_impl {
serialize_array_impl(ArrayRef<T> &Item, U Func) : Item(Item), Func(Func) {}
- Error deserialize(msf::StreamReader &Reader) const {
+ Error deserialize(BinaryStreamReader &Reader) const {
return Reader.readArray(Item, Func());
}
@@ -100,7 +100,7 @@ template <typename T, typename U> struct serialize_array_impl {
template <typename T> struct serialize_vector_tail_impl {
serialize_vector_tail_impl(std::vector<T> &Item) : Item(Item) {}
- Error deserialize(msf::StreamReader &Reader) const {
+ Error deserialize(BinaryStreamReader &Reader) const {
T Field;
// Stop when we run out of bytes or we hit record padding bytes.
while (!Reader.empty() && Reader.peek() < LF_PAD0) {
@@ -118,14 +118,14 @@ struct serialize_null_term_string_array_impl {
serialize_null_term_string_array_impl(std::vector<StringRef> &Item)
: Item(Item) {}
- Error deserialize(msf::StreamReader &Reader) const {
+ Error deserialize(BinaryStreamReader &Reader) const {
if (Reader.empty())
return make_error<CodeViewError>(cv_error_code::insufficient_buffer,
"Null terminated string is empty!");
while (Reader.peek() != 0) {
StringRef Field;
- if (auto EC = Reader.readZeroString(Field))
+ if (auto EC = Reader.readCString(Field))
return EC;
Item.push_back(Field);
}
@@ -138,7 +138,7 @@ struct serialize_null_term_string_array_impl {
template <typename T> struct serialize_arrayref_tail_impl {
serialize_arrayref_tail_impl(ArrayRef<T> &Item) : Item(Item) {}
- Error deserialize(msf::StreamReader &Reader) const {
+ Error deserialize(BinaryStreamReader &Reader) const {
uint32_t Count = Reader.bytesRemaining() / sizeof(T);
return Reader.readArray(Item, Count);
}
@@ -149,7 +149,7 @@ template <typename T> struct serialize_arrayref_tail_impl {
template <typename T> struct serialize_numeric_impl {
serialize_numeric_impl(T &Item) : Item(Item) {}
- Error deserialize(msf::StreamReader &Reader) const {
+ Error deserialize(BinaryStreamReader &Reader) const {
return consume_numeric(Reader, Item);
}
@@ -201,42 +201,42 @@ template <typename T> serialize_numeric_impl<T> serialize_numeric(T &Item) {
#define CV_NUMERIC_FIELD(I) serialize_numeric(I)
template <typename T, typename U>
-Error consume(msf::StreamReader &Reader,
+Error consume(BinaryStreamReader &Reader,
const serialize_conditional_impl<T, U> &Item) {
return Item.deserialize(Reader);
}
template <typename T, typename U>
-Error consume(msf::StreamReader &Reader,
+Error consume(BinaryStreamReader &Reader,
const serialize_array_impl<T, U> &Item) {
return Item.deserialize(Reader);
}
-inline Error consume(msf::StreamReader &Reader,
+inline Error consume(BinaryStreamReader &Reader,
const serialize_null_term_string_array_impl &Item) {
return Item.deserialize(Reader);
}
template <typename T>
-Error consume(msf::StreamReader &Reader,
+Error consume(BinaryStreamReader &Reader,
const serialize_vector_tail_impl<T> &Item) {
return Item.deserialize(Reader);
}
template <typename T>
-Error consume(msf::StreamReader &Reader,
+Error consume(BinaryStreamReader &Reader,
const serialize_arrayref_tail_impl<T> &Item) {
return Item.deserialize(Reader);
}
template <typename T>
-Error consume(msf::StreamReader &Reader,
+Error consume(BinaryStreamReader &Reader,
const serialize_numeric_impl<T> &Item) {
return Item.deserialize(Reader);
}
template <typename T, typename U, typename... Args>
-Error consume(msf::StreamReader &Reader, T &&X, U &&Y, Args &&... Rest) {
+Error consume(BinaryStreamReader &Reader, T &&X, U &&Y, Args &&... Rest) {
if (auto EC = consume(Reader, X))
return EC;
return consume(Reader, Y, std::forward<Args>(Rest)...);
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/StringsAndChecksums.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/StringsAndChecksums.h
new file mode 100644
index 0000000..1a83882
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/StringsAndChecksums.h
@@ -0,0 +1,102 @@
+//===- StringsAndChecksums.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_STRINGSANDCHECKSUMS_H
+#define LLVM_DEBUGINFO_CODEVIEW_STRINGSANDCHECKSUMS_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
+#include <memory>
+
+namespace llvm {
+namespace codeview {
+
+class StringsAndChecksumsRef {
+public:
+ // If no subsections are known about initially, we find as much as we can.
+ StringsAndChecksumsRef();
+
+ // If only a string table subsection is given, we find a checksums subsection.
+ explicit StringsAndChecksumsRef(const DebugStringTableSubsectionRef &Strings);
+
+ // If both subsections are given, we don't need to find anything.
+ StringsAndChecksumsRef(const DebugStringTableSubsectionRef &Strings,
+ const DebugChecksumsSubsectionRef &Checksums);
+
+ void setChecksums(const DebugChecksumsSubsectionRef &CS);
+
+ template <typename T> void initialize(T &&FragmentRange) {
+ for (const DebugSubsectionRecord &R : FragmentRange) {
+ if (Strings && Checksums)
+ return;
+ if (R.kind() == DebugSubsectionKind::FileChecksums) {
+ initializeChecksums(R);
+ continue;
+ }
+ if (R.kind() == DebugSubsectionKind::StringTable && !Strings) {
+ // While in practice we should never encounter a string table even
+ // though the string table is already initialized, in theory it's
+ // possible. PDBs are supposed to have one global string table and
+ // then this subsection should not appear. Whereas object files are
+ // supposed to have this subsection appear exactly once. However,
+ // for testing purposes it's nice to be able to test this subsection
+ // independently of one format or the other, so for some tests we
+ // manually construct a PDB that contains this subsection in addition
+ // to a global string table.
+ initializeStrings(R);
+ continue;
+ }
+ }
+ }
+
+ const DebugStringTableSubsectionRef &strings() const { return *Strings; }
+ const DebugChecksumsSubsectionRef &checksums() const { return *Checksums; }
+
+ bool hasStrings() const { return Strings != nullptr; }
+ bool hasChecksums() const { return Checksums != nullptr; }
+
+private:
+ void initializeStrings(const DebugSubsectionRecord &SR);
+ void initializeChecksums(const DebugSubsectionRecord &FCR);
+
+ std::unique_ptr<DebugStringTableSubsectionRef> OwnedStrings;
+ std::unique_ptr<DebugChecksumsSubsectionRef> OwnedChecksums;
+
+ const DebugStringTableSubsectionRef *Strings = nullptr;
+ const DebugChecksumsSubsectionRef *Checksums = nullptr;
+};
+
+class StringsAndChecksums {
+public:
+ using StringsPtr = std::shared_ptr<DebugStringTableSubsection>;
+ using ChecksumsPtr = std::shared_ptr<DebugChecksumsSubsection>;
+
+ // If no subsections are known about initially, we find as much as we can.
+ StringsAndChecksums() = default;
+
+ void setStrings(const StringsPtr &SP) { Strings = SP; }
+ void setChecksums(const ChecksumsPtr &CP) { Checksums = CP; }
+
+ const StringsPtr &strings() const { return Strings; }
+ const ChecksumsPtr &checksums() const { return Checksums; }
+
+ bool hasStrings() const { return Strings != nullptr; }
+ bool hasChecksums() const { return Checksums != nullptr; }
+
+private:
+ StringsPtr Strings;
+ ChecksumsPtr Checksums;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_STRINGSANDCHECKSUMS_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h
index 13c2bb1..5b6599d 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h
@@ -15,8 +15,8 @@
#include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
#include "llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h"
-#include "llvm/DebugInfo/MSF/ByteStream.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Error.h"
namespace llvm {
@@ -24,21 +24,40 @@ namespace codeview {
class SymbolVisitorDelegate;
class SymbolDeserializer : public SymbolVisitorCallbacks {
struct MappingInfo {
- explicit MappingInfo(ArrayRef<uint8_t> RecordData)
- : Stream(RecordData), Reader(Stream), Mapping(Reader) {}
+ MappingInfo(ArrayRef<uint8_t> RecordData, CodeViewContainer Container)
+ : Stream(RecordData, llvm::support::little), Reader(Stream),
+ Mapping(Reader, Container) {}
- msf::ByteStream Stream;
- msf::StreamReader Reader;
+ BinaryByteStream Stream;
+ BinaryStreamReader Reader;
SymbolRecordMapping Mapping;
};
public:
- explicit SymbolDeserializer(SymbolVisitorDelegate *Delegate)
- : Delegate(Delegate) {}
+ template <typename T> static Error deserializeAs(CVSymbol Symbol, T &Record) {
+ // If we're just deserializing one record, then don't worry about alignment
+ // as there's nothing that comes after.
+ SymbolDeserializer S(nullptr, CodeViewContainer::ObjectFile);
+ if (auto EC = S.visitSymbolBegin(Symbol))
+ return EC;
+ if (auto EC = S.visitKnownRecord(Symbol, Record))
+ return EC;
+ if (auto EC = S.visitSymbolEnd(Symbol))
+ return EC;
+ return Error::success();
+ }
+
+ explicit SymbolDeserializer(SymbolVisitorDelegate *Delegate,
+ CodeViewContainer Container)
+ : Delegate(Delegate), Container(Container) {}
+
+ Error visitSymbolBegin(CVSymbol &Record, uint32_t Offset) override {
+ return visitSymbolBegin(Record);
+ }
Error visitSymbolBegin(CVSymbol &Record) override {
assert(!Mapping && "Already in a symbol mapping!");
- Mapping = llvm::make_unique<MappingInfo>(Record.content());
+ Mapping = llvm::make_unique<MappingInfo>(Record.content(), Container);
return Mapping->Mapping.visitSymbolBegin(Record);
}
Error visitSymbolEnd(CVSymbol &Record) override {
@@ -53,7 +72,7 @@ public:
return visitKnownRecordImpl(CVR, Record); \
}
#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "CVSymbolTypes.def"
+#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
private:
template <typename T> Error visitKnownRecordImpl(CVSymbol &CVR, T &Record) {
@@ -66,6 +85,7 @@ private:
}
SymbolVisitorDelegate *Delegate;
+ CodeViewContainer Container;
std::unique_ptr<MappingInfo> Mapping;
};
}
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDumper.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDumper.h
index a5419b3..293daa8 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDumper.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDumper.h
@@ -20,15 +20,17 @@ namespace llvm {
class ScopedPrinter;
namespace codeview {
-class TypeDatabase;
+class TypeCollection;
/// Dumper for CodeView symbol streams found in COFF object files and PDB files.
class CVSymbolDumper {
public:
- CVSymbolDumper(ScopedPrinter &W, TypeDatabase &TypeDB,
+ CVSymbolDumper(ScopedPrinter &W, TypeCollection &Types,
+ CodeViewContainer Container,
std::unique_ptr<SymbolDumpDelegate> ObjDelegate,
bool PrintRecordBytes)
- : W(W), TypeDB(TypeDB), ObjDelegate(std::move(ObjDelegate)),
+ : W(W), Types(Types), Container(Container),
+ ObjDelegate(std::move(ObjDelegate)),
PrintRecordBytes(PrintRecordBytes) {}
/// Dumps one type record. Returns false if there was a type parsing error,
@@ -43,7 +45,8 @@ public:
private:
ScopedPrinter &W;
- TypeDatabase &TypeDB;
+ TypeCollection &Types;
+ CodeViewContainer Container;
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 57772d3..f3086cf 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
@@ -13,16 +13,14 @@
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/DebugInfo/MSF/StreamArray.h"
+#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <cstddef>
#include <cstdint>
#include <vector>
@@ -36,7 +34,6 @@ protected:
public:
SymbolRecordKind getKind() const { return Kind; }
-private:
SymbolRecordKind Kind;
};
@@ -155,6 +152,7 @@ public:
: SymbolRecord(Kind), RecordOffset(RecordOffset) {}
std::vector<TypeIndex> Indices;
+
uint32_t RecordOffset;
};
@@ -167,8 +165,8 @@ struct BinaryAnnotationIterator {
int32_t S1;
};
- BinaryAnnotationIterator(ArrayRef<uint8_t> Annotations) : Data(Annotations) {}
BinaryAnnotationIterator() = default;
+ BinaryAnnotationIterator(ArrayRef<uint8_t> Annotations) : Data(Annotations) {}
BinaryAnnotationIterator(const BinaryAnnotationIterator &Other)
: Data(Other.Data) {}
@@ -176,7 +174,7 @@ struct BinaryAnnotationIterator {
return Data == Other.Data;
}
- bool operator!=(BinaryAnnotationIterator Other) const {
+ bool operator!=(const BinaryAnnotationIterator &Other) const {
return !(*this == Other);
}
@@ -344,9 +342,9 @@ public:
: SymbolRecord(SymbolRecordKind::InlineSiteSym),
RecordOffset(RecordOffset) {}
- llvm::iterator_range<BinaryAnnotationIterator> annotations() const {
- return llvm::make_range(BinaryAnnotationIterator(AnnotationData),
- BinaryAnnotationIterator());
+ iterator_range<BinaryAnnotationIterator> annotations() const {
+ return make_range(BinaryAnnotationIterator(AnnotationData),
+ BinaryAnnotationIterator());
}
uint32_t Parent;
@@ -365,7 +363,7 @@ public:
: SymbolRecord(SymbolRecordKind::PublicSym32),
RecordOffset(RecordOffset) {}
- uint32_t Index;
+ PublicSymFlags Flags;
uint32_t Offset;
uint16_t Segment;
StringRef Name;
@@ -381,7 +379,7 @@ public:
: SymbolRecord(SymbolRecordKind::RegisterSym),
RecordOffset(RecordOffset) {}
- uint32_t Index;
+ TypeIndex Index;
RegisterId Register;
StringRef Name;
@@ -481,6 +479,7 @@ public:
ulittle16_t Register;
ulittle16_t MayHaveNoName;
};
+
explicit DefRangeRegisterSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
DefRangeRegisterSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::DefRangeRegisterSym),
@@ -503,6 +502,7 @@ public:
ulittle16_t MayHaveNoName;
ulittle32_t OffsetInParent;
};
+
explicit DefRangeSubfieldRegisterSym(SymbolRecordKind Kind)
: SymbolRecord(Kind) {}
DefRangeSubfieldRegisterSym(uint32_t RecordOffset)
@@ -548,6 +548,7 @@ public:
ulittle16_t Flags;
little32_t BasePointerOffset;
};
+
explicit DefRangeRegisterRelSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
explicit DefRangeRegisterRelSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::DefRangeRegisterRelSym),
@@ -681,7 +682,7 @@ public:
: SymbolRecord(SymbolRecordKind::FileStaticSym),
RecordOffset(RecordOffset) {}
- uint32_t Index;
+ TypeIndex Index;
uint32_t ModFilenameOffset;
LocalSymFlags Flags;
StringRef Name;
@@ -734,6 +735,10 @@ public:
uint16_t VersionBackendQFE;
StringRef Version;
+ void setLanguage(SourceLanguage Lang) {
+ Flags = CompileSym3Flags((uint32_t(Flags) & 0xFFFFFF00) | uint32_t(Lang));
+ }
+
uint8_t getLanguage() const { return static_cast<uint32_t>(Flags) & 0xFF; }
uint32_t getFlags() const { return static_cast<uint32_t>(Flags) & ~0xFF; }
@@ -816,7 +821,7 @@ public:
uint32_t CodeOffset;
uint16_t Register;
- uint8_t CookieKind;
+ FrameCookieKind CookieKind;
uint8_t Flags;
uint32_t RecordOffset;
@@ -843,7 +848,7 @@ public:
: SymbolRecord(SymbolRecordKind::BuildInfoSym),
RecordOffset(RecordOffset) {}
- uint32_t BuildId;
+ TypeIndex BuildId;
uint32_t RecordOffset;
};
@@ -873,7 +878,7 @@ public:
uint32_t Offset;
TypeIndex Type;
- uint16_t Register;
+ RegisterId Register;
StringRef Name;
uint32_t RecordOffset;
@@ -937,8 +942,8 @@ public:
uint32_t RecordOffset;
};
-typedef CVRecord<SymbolKind> CVSymbol;
-typedef msf::VarStreamArray<CVSymbol> CVSymbolArray;
+using CVSymbol = CVRecord<SymbolKind>;
+using CVSymbolArray = VarStreamArray<CVSymbol>;
} // end namespace codeview
} // end namespace llvm
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h
index 1bd14ed..391e8f1 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h
@@ -14,16 +14,18 @@
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
namespace llvm {
-namespace msf {
-class StreamReader;
-class StreamWriter;
-}
+class BinaryStreamReader;
+class BinaryStreamWriter;
namespace codeview {
class SymbolRecordMapping : public SymbolVisitorCallbacks {
public:
- explicit SymbolRecordMapping(msf::StreamReader &Reader) : IO(Reader) {}
- explicit SymbolRecordMapping(msf::StreamWriter &Writer) : IO(Writer) {}
+ explicit SymbolRecordMapping(BinaryStreamReader &Reader,
+ CodeViewContainer Container)
+ : IO(Reader), Container(Container) {}
+ explicit SymbolRecordMapping(BinaryStreamWriter &Writer,
+ CodeViewContainer Container)
+ : IO(Writer), Container(Container) {}
Error visitSymbolBegin(CVSymbol &Record) override;
Error visitSymbolEnd(CVSymbol &Record) override;
@@ -31,12 +33,13 @@ public:
#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
Error visitKnownRecord(CVSymbol &CVR, Name &Record) override;
#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "CVSymbolTypes.def"
+#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
private:
Optional<SymbolKind> Kind;
CodeViewRecordIO IO;
+ CodeViewContainer Container;
};
}
}
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolSerializer.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolSerializer.h
index 4eb914e..b63ced5 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolSerializer.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolSerializer.h
@@ -1,4 +1,4 @@
-//===- symbolSerializer.h ---------------------------------------*- C++ -*-===//
+//===- SymbolSerializer.h ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,25 +10,27 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H
#define LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H
+#include "llvm/ADT/Optional.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.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/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <vector>
namespace llvm {
namespace codeview {
class SymbolSerializer : public SymbolVisitorCallbacks {
- uint32_t RecordStart = 0;
- msf::StreamWriter &Writer;
+ BumpPtrAllocator &Storage;
+ std::vector<uint8_t> RecordBuffer;
+ MutableBinaryByteStream Stream;
+ BinaryStreamWriter Writer;
SymbolRecordMapping Mapping;
Optional<SymbolKind> CurrentSymbol;
@@ -42,47 +44,29 @@ class SymbolSerializer : public SymbolVisitorCallbacks {
}
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();
+ SymbolSerializer(BumpPtrAllocator &Storage, CodeViewContainer Container);
+
+ template <typename SymType>
+ static CVSymbol writeOneSymbol(SymType &Sym, BumpPtrAllocator &Storage,
+ CodeViewContainer Container) {
+ CVSymbol Result;
+ Result.Type = static_cast<SymbolKind>(Sym.Kind);
+ SymbolSerializer Serializer(Storage, Container);
+ consumeError(Serializer.visitSymbolBegin(Result));
+ consumeError(Serializer.visitKnownRecord(Result, Sym));
+ consumeError(Serializer.visitSymbolEnd(Result));
+ return Result;
}
- 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();
- }
+ Error visitSymbolBegin(CVSymbol &Record) override;
+ Error visitSymbolEnd(CVSymbol &Record) override;
#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
- virtual Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \
+ Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \
return visitKnownRecordImpl(CVR, Record); \
}
#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "CVSymbolTypes.def"
+#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
private:
template <typename RecordKind>
@@ -90,7 +74,8 @@ private:
return Mapping.visitKnownRecord(CVR, Record);
}
};
-}
-}
-#endif
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h
index 96a93bf..e29511a 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h
@@ -30,6 +30,14 @@ public:
return Error::success();
}
+ Error visitSymbolBegin(CVSymbol &Record, uint32_t Offset) override {
+ for (auto Visitor : Pipeline) {
+ if (auto EC = Visitor->visitSymbolBegin(Record, Offset))
+ return EC;
+ }
+ return Error::success();
+ }
+
Error visitSymbolBegin(CVSymbol &Record) override {
for (auto Visitor : Pipeline) {
if (auto EC = Visitor->visitSymbolBegin(Record))
@@ -59,7 +67,7 @@ public:
return Error::success(); \
}
#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def"
+#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
private:
std::vector<SymbolVisitorCallbacks *> Pipeline;
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h
index aaa9d2e..0816f7c 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h
@@ -29,8 +29,10 @@ public:
/// 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.
+ /// return the type of the Symbol, or an error if it cannot be determined.
+ virtual Error visitSymbolBegin(CVSymbol &Record, uint32_t Offset) {
+ return Error::success();
+ }
virtual Error visitSymbolBegin(CVSymbol &Record) { return Error::success(); }
virtual Error visitSymbolEnd(CVSymbol &Record) { return Error::success(); }
@@ -39,7 +41,7 @@ public:
return Error::success(); \
}
#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "CVSymbolTypes.def"
+#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
};
} // end namespace codeview
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h
index 2b468a2..a2a3c6f 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h
@@ -15,19 +15,19 @@
namespace llvm {
-namespace msf {
-class StreamReader;
-} // end namespace msf
+class BinaryStreamReader;
namespace codeview {
+class DebugStringTableSubsectionRef;
+
class SymbolVisitorDelegate {
public:
virtual ~SymbolVisitorDelegate() = default;
- virtual uint32_t getRecordOffset(msf::StreamReader Reader) = 0;
+ virtual uint32_t getRecordOffset(BinaryStreamReader Reader) = 0;
virtual StringRef getFileNameForFileOffset(uint32_t FileOffset) = 0;
- virtual StringRef getStringTable() = 0;
+ virtual DebugStringTableSubsectionRef getStringTable() = 0;
};
} // end namespace codeview
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeCollection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeCollection.h
new file mode 100644
index 0000000..0f856f5
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeCollection.h
@@ -0,0 +1,38 @@
+//===- TypeCollection.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_TYPECOLLECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPECOLLECTION_H
+
+#include "llvm/ADT/StringRef.h"
+
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+
+namespace llvm {
+namespace codeview {
+class TypeCollection {
+public:
+ virtual ~TypeCollection() = default;
+
+ bool empty() { return size() == 0; }
+
+ virtual Optional<TypeIndex> getFirst() = 0;
+ virtual Optional<TypeIndex> getNext(TypeIndex Prev) = 0;
+
+ virtual CVType getType(TypeIndex Index) = 0;
+ virtual StringRef getTypeName(TypeIndex Index) = 0;
+ virtual bool contains(TypeIndex Index) = 0;
+ virtual uint32_t size() = 0;
+ virtual uint32_t capacity() = 0;
+};
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabase.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabase.h
deleted file mode 100644
index cccc286..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabase.h
+++ /dev/null
@@ -1,55 +0,0 @@
-//===- 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
deleted file mode 100644
index 39d234c..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h
+++ /dev/null
@@ -1,53 +0,0 @@
-//===-- 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
index dc5eaf8..965cdfd 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
@@ -16,8 +16,8 @@
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
-#include "llvm/DebugInfo/MSF/ByteStream.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Error.h"
#include <cassert>
#include <cstdint>
@@ -29,22 +29,39 @@ namespace codeview {
class TypeDeserializer : public TypeVisitorCallbacks {
struct MappingInfo {
explicit MappingInfo(ArrayRef<uint8_t> RecordData)
- : Stream(RecordData), Reader(Stream), Mapping(Reader) {}
+ : Stream(RecordData, llvm::support::little), Reader(Stream),
+ Mapping(Reader) {}
- msf::ByteStream Stream;
- msf::StreamReader Reader;
+ BinaryByteStream Stream;
+ BinaryStreamReader Reader;
TypeRecordMapping Mapping;
};
public:
TypeDeserializer() = default;
+ template <typename T> static Error deserializeAs(CVType &CVT, T &Record) {
+ Record.Kind = static_cast<TypeRecordKind>(CVT.kind());
+ MappingInfo I(CVT.content());
+ if (auto EC = I.Mapping.visitTypeBegin(CVT))
+ return EC;
+ if (auto EC = I.Mapping.visitKnownRecord(CVT, Record))
+ return EC;
+ if (auto EC = I.Mapping.visitTypeEnd(CVT))
+ return EC;
+ return Error::success();
+ }
+
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 visitTypeBegin(CVType &Record, TypeIndex Index) override {
+ return visitTypeBegin(Record);
+ }
+
Error visitTypeEnd(CVType &Record) override {
assert(Mapping && "Not in a type mapping!");
auto EC = Mapping->Mapping.visitTypeEnd(Record);
@@ -59,7 +76,7 @@ public:
#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"
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
private:
template <typename RecordType>
@@ -72,16 +89,16 @@ private:
class FieldListDeserializer : public TypeVisitorCallbacks {
struct MappingInfo {
- explicit MappingInfo(msf::StreamReader &R)
+ explicit MappingInfo(BinaryStreamReader &R)
: Reader(R), Mapping(Reader), StartOffset(0) {}
- msf::StreamReader &Reader;
+ BinaryStreamReader &Reader;
TypeRecordMapping Mapping;
uint32_t StartOffset;
};
public:
- explicit FieldListDeserializer(msf::StreamReader &Reader) : Mapping(Reader) {
+ explicit FieldListDeserializer(BinaryStreamReader &Reader) : Mapping(Reader) {
CVType FieldList;
FieldList.Type = TypeLeafKind::LF_FIELDLIST;
consumeError(Mapping.Mapping.visitTypeBegin(FieldList));
@@ -111,7 +128,7 @@ public:
}
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "TypeRecords.def"
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
private:
template <typename RecordType>
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h
index a466e42..afb8b36 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h
@@ -12,7 +12,6 @@
#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"
@@ -22,14 +21,25 @@ class ScopedPrinter;
namespace codeview {
+class TypeCollection;
+
/// 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) {}
+ TypeDumpVisitor(TypeCollection &TpiTypes, ScopedPrinter *W,
+ bool PrintRecordBytes)
+ : W(W), PrintRecordBytes(PrintRecordBytes), TpiTypes(TpiTypes) {}
+
+ /// When dumping types from an IPI stream in a PDB, a type index may refer to
+ /// a type or an item ID. The dumper will lookup the "name" of the index in
+ /// the item database if appropriate. If ItemDB is null, it will use TypeDB,
+ /// which is correct when dumping types from an object file (/Z7).
+ void setIpiTypes(TypeCollection &Types) { IpiTypes = &Types; }
void printTypeIndex(StringRef FieldName, TypeIndex TI) const;
+ void printItemIndex(StringRef FieldName, TypeIndex TI) const;
+
/// Action to take on unknown types. By default, they are ignored.
Error visitUnknownType(CVType &Record) override;
Error visitUnknownMember(CVMemberRecord &Record) override;
@@ -37,6 +47,7 @@ public:
/// Paired begin/end actions for all types. Receives all record data,
/// including the fixed-length record prefix.
Error visitTypeBegin(CVType &Record) override;
+ Error visitTypeBegin(CVType &Record, TypeIndex Index) override;
Error visitTypeEnd(CVType &Record) override;
Error visitMemberBegin(CVMemberRecord &Record) override;
Error visitMemberEnd(CVMemberRecord &Record) override;
@@ -47,18 +58,26 @@ public:
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"
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
private:
void printMemberAttributes(MemberAttributes Attrs);
void printMemberAttributes(MemberAccess Access, MethodKind Kind,
MethodOptions Options);
+ /// Get the database of indices for the stream that we are dumping. If ItemDB
+ /// is set, then we must be dumping an item (IPI) stream. This will also
+ /// always get the appropriate DB for printing item names.
+ TypeCollection &getSourceTypes() const {
+ return IpiTypes ? *IpiTypes : TpiTypes;
+ }
+
ScopedPrinter *W;
bool PrintRecordBytes = false;
- TypeDatabase &TypeDB;
+ TypeCollection &TpiTypes;
+ TypeCollection *IpiTypes = nullptr;
};
} // end namespace codeview
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumperBase.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumperBase.h
deleted file mode 100644
index e69de29..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumperBase.h
+++ /dev/null
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndex.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndex.h
index 3c11d24..e0c2226 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndex.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndex.h
@@ -10,13 +10,20 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEINDEX_H
#define LLVM_DEBUGINFO_CODEVIEW_TYPEINDEX_H
+#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/Support/Endian.h"
#include <cassert>
#include <cinttypes>
+#include <functional>
namespace llvm {
+
+class ScopedPrinter;
+
namespace codeview {
+class TypeCollection;
+
enum class SimpleTypeKind : uint32_t {
None = 0x0000, // uncharacterized type (no type)
Void = 0x0003, // void
@@ -106,6 +113,15 @@ public:
bool isNoneType() const { return *this == None(); }
+ uint32_t toArrayIndex() const {
+ assert(!isSimple());
+ return getIndex() - FirstNonSimpleIndex;
+ }
+
+ static TypeIndex fromArrayIndex(uint32_t Index) {
+ return TypeIndex(Index + FirstNonSimpleIndex);
+ }
+
SimpleTypeKind getSimpleKind() const {
assert(isSimple());
return static_cast<SimpleTypeKind>(Index & SimpleKindMask);
@@ -159,6 +175,39 @@ public:
static TypeIndex Float32() { return TypeIndex(SimpleTypeKind::Float32); }
static TypeIndex Float64() { return TypeIndex(SimpleTypeKind::Float64); }
+ TypeIndex &operator+=(unsigned N) {
+ Index += N;
+ return *this;
+ }
+
+ TypeIndex &operator++() {
+ Index += 1;
+ return *this;
+ }
+
+ TypeIndex operator++(int) {
+ TypeIndex Copy = *this;
+ operator++();
+ return Copy;
+ }
+
+ TypeIndex &operator-=(unsigned N) {
+ assert(Index >= N);
+ Index -= N;
+ return *this;
+ }
+
+ TypeIndex &operator--() {
+ Index -= 1;
+ return *this;
+ }
+
+ TypeIndex operator--(int) {
+ TypeIndex Copy = *this;
+ operator--();
+ return Copy;
+ }
+
friend inline bool operator==(const TypeIndex &A, const TypeIndex &B) {
return A.getIndex() == B.getIndex();
}
@@ -183,11 +232,58 @@ public:
return A.getIndex() >= B.getIndex();
}
+ friend inline TypeIndex operator+(const TypeIndex &A, uint32_t N) {
+ TypeIndex Result(A);
+ Result += N;
+ return Result;
+ }
+
+ friend inline TypeIndex operator-(const TypeIndex &A, uint32_t N) {
+ assert(A.getIndex() >= N);
+ TypeIndex Result(A);
+ Result -= N;
+ return Result;
+ }
+
+ friend inline uint32_t operator-(const TypeIndex &A, const TypeIndex &B) {
+ assert(A >= B);
+ return A.toArrayIndex() - B.toArrayIndex();
+ }
+
+ static StringRef simpleTypeName(TypeIndex TI);
+
private:
support::ulittle32_t Index;
};
+// Used for pseudo-indexing an array of type records. An array of such records
+// sorted by TypeIndex can allow log(N) lookups even though such a type record
+// stream does not provide random access.
+struct TypeIndexOffset {
+ TypeIndex Type;
+ support::ulittle32_t Offset;
+};
+
+void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, TypeIndex TI,
+ TypeCollection &Types);
}
-}
+
+template <> struct DenseMapInfo<codeview::TypeIndex> {
+ static inline codeview::TypeIndex getEmptyKey() {
+ return codeview::TypeIndex{DenseMapInfo<uint32_t>::getEmptyKey()};
+ }
+ static inline codeview::TypeIndex getTombstoneKey() {
+ return codeview::TypeIndex{DenseMapInfo<uint32_t>::getTombstoneKey()};
+ }
+ static unsigned getHashValue(const codeview::TypeIndex &TI) {
+ return DenseMapInfo<uint32_t>::getHashValue(TI.getIndex());
+ }
+ static bool isEqual(const codeview::TypeIndex &LHS,
+ const codeview::TypeIndex &RHS) {
+ return LHS == RHS;
+ }
+};
+
+} // namespace llvm
#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h
new file mode 100644
index 0000000..afe8942
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h
@@ -0,0 +1,41 @@
+//===- TypeIndexDiscovery.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_TYPEINDEXDISCOVERY_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPEINDEXDISCOVERY_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace codeview {
+enum class TiRefKind { TypeRef, IndexRef };
+struct TiReference {
+ TiRefKind Kind;
+ uint32_t Offset;
+ uint32_t Count;
+};
+
+void discoverTypeIndices(ArrayRef<uint8_t> RecordData,
+ SmallVectorImpl<TiReference> &Refs);
+void discoverTypeIndices(const CVType &Type,
+ SmallVectorImpl<TiReference> &Refs);
+void discoverTypeIndices(const CVType &Type,
+ SmallVectorImpl<TypeIndex> &Indices);
+
+/// Discover type indices in symbol records. Returns false if this is an unknown
+/// record.
+bool discoverTypeIndices(const CVSymbol &Symbol,
+ SmallVectorImpl<TiReference> &Refs);
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeName.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeName.h
new file mode 100644
index 0000000..a987b4a
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeName.h
@@ -0,0 +1,22 @@
+//===- TypeName.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_TYPENAME_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPENAME_H
+
+#include "llvm/DebugInfo/CodeView/TypeCollection.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+
+namespace llvm {
+namespace codeview {
+std::string computeTypeName(TypeCollection &Types, TypeIndex Index);
+}
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
index 4f1c047..7942c0c 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
@@ -15,41 +15,42 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/GUID.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/DebugInfo/MSF/StreamArray.h"
+#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/Endian.h"
#include <algorithm>
#include <cstdint>
#include <vector>
namespace llvm {
-
-namespace msf {
-class StreamReader;
-} // end namespace msf
-
namespace codeview {
using support::little32_t;
using support::ulittle16_t;
using support::ulittle32_t;
-typedef CVRecord<TypeLeafKind> CVType;
+using CVType = CVRecord<TypeLeafKind>;
+using RemappedType = RemappedRecord<TypeLeafKind>;
struct CVMemberRecord {
TypeLeafKind Kind;
ArrayRef<uint8_t> Data;
};
-typedef msf::VarStreamArray<CVType> CVTypeArray;
+using CVTypeArray = VarStreamArray<CVType>;
+using CVTypeRange = iterator_range<CVTypeArray::Iterator>;
/// Equvalent to CV_fldattr_t in cvinfo.h.
struct MemberAttributes {
uint16_t Attrs = 0;
+
enum {
MethodKindShift = 2,
};
+
MemberAttributes() = default;
explicit MemberAttributes(MemberAccess Access)
@@ -106,10 +107,6 @@ public:
PointerToMemberRepresentation Representation)
: ContainingType(ContainingType), Representation(Representation) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getContainingType() const { return ContainingType; }
PointerToMemberRepresentation getRepresentation() const {
return Representation;
@@ -127,22 +124,18 @@ protected:
public:
TypeRecordKind getKind() const { return Kind; }
-private:
TypeRecordKind Kind;
};
// LF_MODIFIER
class ModifierRecord : public TypeRecord {
public:
+ ModifierRecord() = default;
explicit ModifierRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
ModifierRecord(TypeIndex ModifiedType, ModifierOptions Modifiers)
: TypeRecord(TypeRecordKind::Modifier), ModifiedType(ModifiedType),
Modifiers(Modifiers) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getModifiedType() const { return ModifiedType; }
ModifierOptions getModifiers() const { return Modifiers; }
@@ -153,6 +146,7 @@ public:
// LF_PROCEDURE
class ProcedureRecord : public TypeRecord {
public:
+ ProcedureRecord() = default;
explicit ProcedureRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
ProcedureRecord(TypeIndex ReturnType, CallingConvention CallConv,
FunctionOptions Options, uint16_t ParameterCount,
@@ -161,10 +155,6 @@ public:
CallConv(CallConv), Options(Options), ParameterCount(ParameterCount),
ArgumentList(ArgumentList) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getReturnType() const { return ReturnType; }
CallingConvention getCallConv() const { return CallConv; }
FunctionOptions getOptions() const { return Options; }
@@ -181,6 +171,7 @@ public:
// LF_MFUNCTION
class MemberFunctionRecord : public TypeRecord {
public:
+ MemberFunctionRecord() = default;
explicit MemberFunctionRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
MemberFunctionRecord(TypeIndex ReturnType, TypeIndex ClassType,
@@ -193,10 +184,6 @@ public:
ArgumentList(ArgumentList),
ThisPointerAdjustment(ThisPointerAdjustment) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getReturnType() const { return ReturnType; }
TypeIndex getClassType() const { return ClassType; }
TypeIndex getThisType() const { return ThisType; }
@@ -216,38 +203,58 @@ public:
int32_t ThisPointerAdjustment;
};
+// LF_LABEL
+class LabelRecord : public TypeRecord {
+public:
+ LabelRecord() = default;
+ explicit LabelRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
+
+ LabelRecord(LabelType Mode) : TypeRecord(TypeRecordKind::Label), Mode(Mode) {}
+
+ LabelType Mode;
+};
+
// LF_MFUNC_ID
class MemberFuncIdRecord : public TypeRecord {
public:
+ MemberFuncIdRecord() = default;
explicit MemberFuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
MemberFuncIdRecord(TypeIndex ClassType, TypeIndex FunctionType,
StringRef Name)
: TypeRecord(TypeRecordKind::MemberFuncId), ClassType(ClassType),
FunctionType(FunctionType), Name(Name) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getClassType() const { return ClassType; }
TypeIndex getFunctionType() const { return FunctionType; }
StringRef getName() const { return Name; }
+
TypeIndex ClassType;
TypeIndex FunctionType;
StringRef Name;
};
-// LF_ARGLIST, LF_SUBSTR_LIST
+// LF_ARGLIST
class ArgListRecord : public TypeRecord {
public:
+ ArgListRecord() = default;
explicit ArgListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
ArgListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
- : TypeRecord(Kind), StringIndices(Indices) {}
+ : TypeRecord(Kind), ArgIndices(Indices) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+ ArrayRef<TypeIndex> getIndices() const { return ArgIndices; }
+
+ std::vector<TypeIndex> ArgIndices;
+};
+
+// LF_SUBSTR_LIST
+class StringListRecord : public TypeRecord {
+public:
+ StringListRecord() = default;
+ explicit StringListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
+
+ StringListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
+ : TypeRecord(Kind), StringIndices(Indices) {}
ArrayRef<TypeIndex> getIndices() const { return StringIndices; }
@@ -268,6 +275,7 @@ public:
static const uint32_t PointerSizeShift = 13;
static const uint32_t PointerSizeMask = 0xFF;
+ PointerRecord() = default;
explicit PointerRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
PointerRecord(TypeIndex ReferentType, uint32_t Attrs)
@@ -280,19 +288,9 @@ public:
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)
+ PointerOptions PO, uint8_t Size, const MemberPointerInfo &MPI)
: TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
- Attrs(Attrs), MemberInfo(Member) {}
-
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+ Attrs(calcAttrs(PK, PM, PO, Size)), MemberInfo(MPI) {}
TypeIndex getReferentType() const { return ReferentType; }
@@ -334,7 +332,6 @@ public:
TypeIndex ReferentType;
uint32_t Attrs;
-
Optional<MemberPointerInfo> MemberInfo;
private:
@@ -352,14 +349,11 @@ private:
// LF_NESTTYPE
class NestedTypeRecord : public TypeRecord {
public:
+ NestedTypeRecord() = default;
explicit NestedTypeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
NestedTypeRecord(TypeIndex Type, StringRef Name)
: TypeRecord(TypeRecordKind::NestedType), Type(Type), Name(Name) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getNestedType() const { return Type; }
StringRef getName() const { return Name; }
@@ -370,30 +364,24 @@ public:
// LF_FIELDLIST
class FieldListRecord : public TypeRecord {
public:
+ FieldListRecord() = default;
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:
+ ArrayRecord() = default;
explicit ArrayRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
ArrayRecord(TypeIndex ElementType, TypeIndex IndexType, uint64_t Size,
StringRef Name)
: TypeRecord(TypeRecordKind::Array), ElementType(ElementType),
IndexType(IndexType), Size(Size), Name(Name) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getElementType() const { return ElementType; }
TypeIndex getIndexType() const { return IndexType; }
uint64_t getSize() const { return Size; }
@@ -407,6 +395,7 @@ public:
class TagRecord : public TypeRecord {
protected:
+ TagRecord() = default;
explicit TagRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
TagRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
TypeIndex FieldList, StringRef Name, StringRef UniqueName)
@@ -414,10 +403,6 @@ protected:
FieldList(FieldList), Name(Name), UniqueName(UniqueName) {}
public:
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
static const int HfaKindShift = 11;
static const int HfaKindMask = 0x1800;
static const int WinRTKindShift = 14;
@@ -443,6 +428,7 @@ public:
// LF_CLASS, LF_STRUCTURE, LF_INTERFACE
class ClassRecord : public TagRecord {
public:
+ ClassRecord() = default;
explicit ClassRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
ClassRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
TypeIndex FieldList, TypeIndex DerivationList,
@@ -451,10 +437,6 @@ public:
: TagRecord(Kind, MemberCount, Options, FieldList, Name, UniqueName),
DerivationList(DerivationList), VTableShape(VTableShape), Size(Size) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
HfaKind getHfa() const {
uint16_t Value = static_cast<uint16_t>(Options);
Value = (Value & HfaKindMask) >> HfaKindShift;
@@ -478,6 +460,7 @@ public:
// LF_UNION
struct UnionRecord : public TagRecord {
+ UnionRecord() = default;
explicit UnionRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
UnionRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
uint64_t Size, StringRef Name, StringRef UniqueName)
@@ -499,6 +482,7 @@ struct UnionRecord : public TagRecord {
// LF_ENUM
class EnumRecord : public TagRecord {
public:
+ EnumRecord() = default;
explicit EnumRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
EnumRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
StringRef Name, StringRef UniqueName, TypeIndex UnderlyingType)
@@ -506,28 +490,24 @@ public:
UniqueName),
UnderlyingType(UnderlyingType) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getUnderlyingType() const { return UnderlyingType; }
+
TypeIndex UnderlyingType;
};
// LF_BITFIELD
class BitFieldRecord : public TypeRecord {
public:
+ BitFieldRecord() = default;
explicit BitFieldRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
BitFieldRecord(TypeIndex Type, uint8_t BitSize, uint8_t BitOffset)
: TypeRecord(TypeRecordKind::BitField), Type(Type), BitSize(BitSize),
BitOffset(BitOffset) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getType() const { return Type; }
uint8_t getBitOffset() const { return BitOffset; }
uint8_t getBitSize() const { return BitSize; }
+
TypeIndex Type;
uint8_t BitSize;
uint8_t BitOffset;
@@ -536,16 +516,13 @@ public:
// LF_VTSHAPE
class VFTableShapeRecord : public TypeRecord {
public:
+ VFTableShapeRecord() = default;
explicit VFTableShapeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
explicit VFTableShapeRecord(ArrayRef<VFTableSlotKind> Slots)
: TypeRecord(TypeRecordKind::VFTableShape), SlotsRef(Slots) {}
explicit VFTableShapeRecord(std::vector<VFTableSlotKind> Slots)
: TypeRecord(TypeRecordKind::VFTableShape), Slots(std::move(Slots)) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
ArrayRef<VFTableSlotKind> getSlots() const {
if (!SlotsRef.empty())
return SlotsRef;
@@ -553,6 +530,7 @@ public:
}
uint32_t getEntryCount() const { return getSlots().size(); }
+
ArrayRef<VFTableSlotKind> SlotsRef;
std::vector<VFTableSlotKind> Slots;
};
@@ -560,22 +538,19 @@ public:
// LF_TYPESERVER2
class TypeServer2Record : public TypeRecord {
public:
+ TypeServer2Record() = default;
explicit TypeServer2Record(TypeRecordKind Kind) : TypeRecord(Kind) {}
- TypeServer2Record(StringRef Guid, uint32_t Age, StringRef Name)
- : TypeRecord(TypeRecordKind::TypeServer2), Guid(Guid), Age(Age),
- Name(Name) {}
-
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
- StringRef getGuid() const { return Guid; }
+ TypeServer2Record(StringRef GuidStr, uint32_t Age, StringRef Name)
+ : TypeRecord(TypeRecordKind::TypeServer2), Age(Age), Name(Name) {
+ assert(GuidStr.size() == 16 && "guid isn't 16 bytes");
+ ::memcpy(Guid.Guid, GuidStr.data(), 16);
+ }
+ const GUID &getGuid() const { return Guid; }
uint32_t getAge() const { return Age; }
-
StringRef getName() const { return Name; }
- StringRef Guid;
+ GUID Guid;
uint32_t Age;
StringRef Name;
};
@@ -583,17 +558,14 @@ public:
// LF_STRING_ID
class StringIdRecord : public TypeRecord {
public:
+ StringIdRecord() = default;
explicit StringIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
StringIdRecord(TypeIndex Id, StringRef String)
: TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getId() const { return Id; }
-
StringRef getString() const { return String; }
+
TypeIndex Id;
StringRef String;
};
@@ -601,19 +573,14 @@ public:
// LF_FUNC_ID
class FuncIdRecord : public TypeRecord {
public:
+ FuncIdRecord() = default;
explicit FuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
FuncIdRecord(TypeIndex ParentScope, TypeIndex FunctionType, StringRef Name)
: TypeRecord(TypeRecordKind::FuncId), ParentScope(ParentScope),
FunctionType(FunctionType), Name(Name) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getParentScope() const { return ParentScope; }
-
TypeIndex getFunctionType() const { return FunctionType; }
-
StringRef getName() const { return Name; }
TypeIndex ParentScope;
@@ -624,15 +591,12 @@ public:
// LF_UDT_SRC_LINE
class UdtSourceLineRecord : public TypeRecord {
public:
+ UdtSourceLineRecord() = default;
explicit UdtSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
UdtSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile, uint32_t LineNumber)
: TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
SourceFile(SourceFile), LineNumber(LineNumber) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getUDT() const { return UDT; }
TypeIndex getSourceFile() const { return SourceFile; }
uint32_t getLineNumber() const { return LineNumber; }
@@ -645,14 +609,13 @@ public:
// LF_UDT_MOD_SRC_LINE
class UdtModSourceLineRecord : public TypeRecord {
public:
+ UdtModSourceLineRecord() = default;
explicit UdtModSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
UdtModSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile,
uint32_t LineNumber, uint16_t Module)
: TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
SourceFile(SourceFile), LineNumber(LineNumber), Module(Module) {}
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getUDT() const { return UDT; }
TypeIndex getSourceFile() const { return SourceFile; }
uint32_t getLineNumber() const { return LineNumber; }
@@ -667,22 +630,21 @@ public:
// LF_BUILDINFO
class BuildInfoRecord : public TypeRecord {
public:
+ BuildInfoRecord() = default;
explicit BuildInfoRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
BuildInfoRecord(ArrayRef<TypeIndex> ArgIndices)
: TypeRecord(TypeRecordKind::BuildInfo),
ArgIndices(ArgIndices.begin(), ArgIndices.end()) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
ArrayRef<TypeIndex> getArgs() const { return ArgIndices; }
+
SmallVector<TypeIndex, 4> ArgIndices;
};
// LF_VFTABLE
class VFTableRecord : public TypeRecord {
public:
+ VFTableRecord() = default;
explicit VFTableRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
VFTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable,
uint32_t VFPtrOffset, StringRef Name,
@@ -693,14 +655,11 @@ public:
MethodNames.insert(MethodNames.end(), Methods.begin(), Methods.end());
}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getCompleteClass() const { return CompleteClass; }
TypeIndex getOverriddenVTable() const { return OverriddenVFTable; }
uint32_t getVFPtrOffset() const { return VFPtrOffset; }
StringRef getName() const { return makeArrayRef(MethodNames).front(); }
+
ArrayRef<StringRef> getMethodNames() const {
return makeArrayRef(MethodNames).drop_front();
}
@@ -714,7 +673,7 @@ public:
// LF_ONEMETHOD
class OneMethodRecord : public TypeRecord {
public:
- OneMethodRecord() : TypeRecord(TypeRecordKind::OneMethod) {}
+ OneMethodRecord() = default;
explicit OneMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
OneMethodRecord(TypeIndex Type, MemberAttributes Attrs, int32_t VFTableOffset,
StringRef Name)
@@ -725,10 +684,6 @@ public:
: TypeRecord(TypeRecordKind::OneMethod), Type(Type),
Attrs(Access, MK, Options), VFTableOffset(VFTableOffset), Name(Name) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getType() const { return Type; }
MethodKind getMethodKind() const { return Attrs.getMethodKind(); }
MethodOptions getOptions() const { return Attrs.getFlags(); }
@@ -750,34 +705,30 @@ public:
// LF_METHODLIST
class MethodOverloadListRecord : public TypeRecord {
public:
+ MethodOverloadListRecord() = default;
explicit MethodOverloadListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods)
: TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
ArrayRef<OneMethodRecord> getMethods() const { return Methods; }
+
std::vector<OneMethodRecord> Methods;
};
/// For method overload sets. LF_METHOD
class OverloadedMethodRecord : public TypeRecord {
public:
+ OverloadedMethodRecord() = default;
explicit OverloadedMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
OverloadedMethodRecord(uint16_t NumOverloads, TypeIndex MethodList,
StringRef Name)
: TypeRecord(TypeRecordKind::OverloadedMethod),
NumOverloads(NumOverloads), MethodList(MethodList), Name(Name) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
uint16_t getNumOverloads() const { return NumOverloads; }
TypeIndex getMethodList() const { return MethodList; }
StringRef getName() const { return Name; }
+
uint16_t NumOverloads;
TypeIndex MethodList;
StringRef Name;
@@ -786,6 +737,7 @@ public:
// LF_MEMBER
class DataMemberRecord : public TypeRecord {
public:
+ DataMemberRecord() = default;
explicit DataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
DataMemberRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset,
StringRef Name)
@@ -796,10 +748,6 @@ public:
: TypeRecord(TypeRecordKind::DataMember), Attrs(Access), Type(Type),
FieldOffset(Offset), Name(Name) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
MemberAccess getAccess() const { return Attrs.getAccess(); }
TypeIndex getType() const { return Type; }
uint64_t getFieldOffset() const { return FieldOffset; }
@@ -814,6 +762,7 @@ public:
// LF_STMEMBER
class StaticDataMemberRecord : public TypeRecord {
public:
+ StaticDataMemberRecord() = default;
explicit StaticDataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
StaticDataMemberRecord(MemberAttributes Attrs, TypeIndex Type, StringRef Name)
: TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Attrs), Type(Type),
@@ -822,10 +771,6 @@ public:
: TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Access), Type(Type),
Name(Name) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
MemberAccess getAccess() const { return Attrs.getAccess(); }
TypeIndex getType() const { return Type; }
StringRef getName() const { return Name; }
@@ -838,6 +783,7 @@ public:
// LF_ENUMERATE
class EnumeratorRecord : public TypeRecord {
public:
+ EnumeratorRecord() = default;
explicit EnumeratorRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
EnumeratorRecord(MemberAttributes Attrs, APSInt Value, StringRef Name)
: TypeRecord(TypeRecordKind::Enumerator), Attrs(Attrs),
@@ -846,10 +792,6 @@ public:
: TypeRecord(TypeRecordKind::Enumerator), Attrs(Access),
Value(std::move(Value)), Name(Name) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
MemberAccess getAccess() const { return Attrs.getAccess(); }
APSInt getValue() const { return Value; }
StringRef getName() const { return Name; }
@@ -862,14 +804,11 @@ public:
// LF_VFUNCTAB
class VFPtrRecord : public TypeRecord {
public:
+ VFPtrRecord() = default;
explicit VFPtrRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
VFPtrRecord(TypeIndex Type)
: TypeRecord(TypeRecordKind::VFPtr), Type(Type) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getType() const { return Type; }
TypeIndex Type;
@@ -878,6 +817,7 @@ public:
// LF_BCLASS, LF_BINTERFACE
class BaseClassRecord : public TypeRecord {
public:
+ BaseClassRecord() = default;
explicit BaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
BaseClassRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset)
: TypeRecord(TypeRecordKind::BaseClass), Attrs(Attrs), Type(Type),
@@ -886,10 +826,6 @@ public:
: TypeRecord(TypeRecordKind::BaseClass), Attrs(Access), Type(Type),
Offset(Offset) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
MemberAccess getAccess() const { return Attrs.getAccess(); }
TypeIndex getBaseType() const { return Type; }
uint64_t getBaseOffset() const { return Offset; }
@@ -902,6 +838,7 @@ public:
// LF_VBCLASS, LF_IVBCLASS
class VirtualBaseClassRecord : public TypeRecord {
public:
+ VirtualBaseClassRecord() = default;
explicit VirtualBaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
VirtualBaseClassRecord(TypeRecordKind Kind, MemberAttributes Attrs,
TypeIndex BaseType, TypeIndex VBPtrType,
@@ -914,10 +851,6 @@ public:
: TypeRecord(Kind), Attrs(Access), BaseType(BaseType),
VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
MemberAccess getAccess() const { return Attrs.getAccess(); }
TypeIndex getBaseType() const { return BaseType; }
TypeIndex getVBPtrType() const { return VBPtrType; }
@@ -935,6 +868,7 @@ public:
/// together. The first will end in an LF_INDEX record that points to the next.
class ListContinuationRecord : public TypeRecord {
public:
+ ListContinuationRecord() = default;
explicit ListContinuationRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
ListContinuationRecord(TypeIndex ContinuationIndex)
: TypeRecord(TypeRecordKind::ListContinuation),
@@ -942,13 +876,10 @@ public:
TypeIndex getContinuationIndex() const { return ContinuationIndex; }
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex ContinuationIndex;
};
} // end namespace codeview
-
} // end namespace llvm
#endif // LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h
index fe470a7..cbe8d60 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h
@@ -16,16 +16,16 @@
#include "llvm/Support/Error.h"
namespace llvm {
-namespace msf {
-class StreamReader;
-class StreamWriter;
-}
+class BinaryStreamReader;
+class BinaryStreamWriter;
+
namespace codeview {
class TypeRecordMapping : public TypeVisitorCallbacks {
public:
- explicit TypeRecordMapping(msf::StreamReader &Reader) : IO(Reader) {}
- explicit TypeRecordMapping(msf::StreamWriter &Writer) : IO(Writer) {}
+ explicit TypeRecordMapping(BinaryStreamReader &Reader) : IO(Reader) {}
+ explicit TypeRecordMapping(BinaryStreamWriter &Writer) : IO(Writer) {}
+ using TypeVisitorCallbacks::visitTypeBegin;
Error visitTypeBegin(CVType &Record) override;
Error visitTypeEnd(CVType &Record) override;
@@ -38,7 +38,7 @@ public:
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"
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
private:
Optional<TypeLeafKind> TypeKind;
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeSerializer.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeSerializer.h
index e059221..0e734a8 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeSerializer.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeSerializer.h
@@ -10,22 +10,29 @@
#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/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Error.h"
+#include <cassert>
+#include <cstdint>
+#include <memory>
+#include <vector>
namespace llvm {
-
namespace codeview {
+class TypeHasher;
+
class TypeSerializer : public TypeVisitorCallbacks {
struct SubRecord {
SubRecord(TypeLeafKind K, uint32_t S) : Kind(K), Size(S) {}
@@ -45,43 +52,54 @@ class TypeSerializer : public TypeVisitorCallbacks {
}
};
- typedef SmallVector<MutableArrayRef<uint8_t>, 2> RecordList;
+ using MutableRecordList = SmallVector<MutableArrayRef<uint8_t>, 2>;
static constexpr uint8_t ContinuationLength = 8;
BumpPtrAllocator &RecordStorage;
RecordSegment CurrentSegment;
- RecordList FieldListSegments;
+ MutableRecordList FieldListSegments;
- TypeIndex LastTypeIndex;
Optional<TypeLeafKind> TypeKind;
Optional<TypeLeafKind> MemberKind;
std::vector<uint8_t> RecordBuffer;
- msf::MutableByteStream Stream;
- msf::StreamWriter Writer;
+ MutableBinaryByteStream Stream;
+ BinaryStreamWriter Writer;
TypeRecordMapping Mapping;
- RecordList SeenRecords;
- StringMap<TypeIndex> HashedRecords;
+ /// Private type record hashing implementation details are handled here.
+ std::unique_ptr<TypeHasher> Hasher;
+
+ /// Contains a list of all records indexed by TypeIndex.toArrayIndex().
+ SmallVector<ArrayRef<uint8_t>, 2> SeenRecords;
+
+ /// Temporary storage that we use to copy a record's data while re-writing
+ /// its type indices.
+ SmallVector<uint8_t, 256> RemapStorage;
+
+ TypeIndex nextTypeIndex() const;
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);
+ explicit TypeSerializer(BumpPtrAllocator &Storage, bool Hash = true);
+ ~TypeSerializer() override;
- ArrayRef<MutableArrayRef<uint8_t>> records() const;
- TypeIndex getLastTypeIndex() const;
- TypeIndex insertRecordBytes(MutableArrayRef<uint8_t> Record);
+ void reset();
+
+ BumpPtrAllocator &getAllocator() { return RecordStorage; }
+
+ ArrayRef<ArrayRef<uint8_t>> records() const;
+ TypeIndex insertRecordBytes(ArrayRef<uint8_t> &Record);
+ TypeIndex insertRecord(const RemappedType &Record);
Expected<TypeIndex> visitTypeEndGetIndex(CVType &Record);
+ using TypeVisitorCallbacks::visitTypeBegin;
Error visitTypeBegin(CVType &Record) override;
Error visitTypeEnd(CVType &Record) override;
Error visitMemberBegin(CVMemberRecord &Record) override;
@@ -97,7 +115,7 @@ public:
return visitKnownMemberImpl<Name##Record>(CVR, Record); \
}
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "llvm/DebugInfo/CodeView/TypeRecords.def"
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
private:
template <typename RecordKind>
@@ -134,7 +152,8 @@ private:
return Error::success();
}
};
-}
-}
-#endif
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_TYPESERIALIZER_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h
index af396c7..d78fab4 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h
@@ -12,13 +12,76 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/Support/Error.h"
namespace llvm {
namespace codeview {
-/// Merges one type stream into another. Returns true on success.
-bool mergeTypeStreams(TypeTableBuilder &DestStream, const CVTypeArray &Types);
+class TypeIndex;
+class TypeTableBuilder;
+
+/// \brief Merge one set of type records into another. This method assumes
+/// that all records are type records, and there are no Id records present.
+///
+/// \param Dest The table to store the re-written type records into.
+///
+/// \param SourceToDest A vector, indexed by the TypeIndex in the source
+/// type stream, that contains the index of the corresponding type record
+/// in the destination stream.
+///
+/// \param Types The collection of types to merge in.
+///
+/// \returns Error::success() if the operation succeeded, otherwise an
+/// appropriate error code.
+Error mergeTypeRecords(TypeTableBuilder &Dest,
+ SmallVectorImpl<TypeIndex> &SourceToDest,
+ const CVTypeArray &Types);
+
+/// \brief Merge one set of id records into another. This method assumes
+/// that all records are id records, and there are no Type records present.
+/// However, since Id records can refer back to Type records, this method
+/// assumes that the referenced type records have also been merged into
+/// another type stream (for example using the above method), and accepts
+/// the mapping from source to dest for that stream so that it can re-write
+/// the type record mappings accordingly.
+///
+/// \param Dest The table to store the re-written id records into.
+///
+/// \param Types The mapping to use for the type records that these id
+/// records refer to.
+///
+/// \param SourceToDest A vector, indexed by the TypeIndex in the source
+/// id stream, that contains the index of the corresponding id record
+/// in the destination stream.
+///
+/// \param Ids The collection of id records to merge in.
+///
+/// \returns Error::success() if the operation succeeded, otherwise an
+/// appropriate error code.
+Error mergeIdRecords(TypeTableBuilder &Dest, ArrayRef<TypeIndex> Types,
+ SmallVectorImpl<TypeIndex> &SourceToDest,
+ const CVTypeArray &Ids);
+
+/// \brief Merge a unified set of type and id records, splitting them into
+/// separate output streams.
+///
+/// \param DestIds The table to store the re-written id records into.
+///
+/// \param DestTypes the table to store the re-written type records into.
+///
+/// \param SourceToDest A vector, indexed by the TypeIndex in the source
+/// id stream, that contains the index of the corresponding id record
+/// in the destination stream.
+///
+/// \param IdsAndTypes The collection of id records to merge in.
+///
+/// \returns Error::success() if the operation succeeded, otherwise an
+/// appropriate error code.
+Error mergeTypeAndIdRecords(TypeTableBuilder &DestIds,
+ TypeTableBuilder &DestTypes,
+ SmallVectorImpl<TypeIndex> &SourceToDest,
+ const CVTypeArray &IdsAndTypes);
} // end namespace codeview
} // end namespace llvm
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h
index 4e6d81e..1069dcd 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h
@@ -13,8 +13,8 @@
#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/DebugInfo/CodeView/TypeSerializer.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Error.h"
#include <algorithm>
@@ -37,8 +37,9 @@ private:
TypeSerializer Serializer;
public:
- explicit TypeTableBuilder(BumpPtrAllocator &Allocator)
- : Allocator(Allocator), Serializer(Allocator) {}
+ explicit TypeTableBuilder(BumpPtrAllocator &Allocator,
+ bool WriteUnique = true)
+ : Allocator(Allocator), Serializer(Allocator, WriteUnique) {}
TypeTableBuilder(const TypeTableBuilder &) = delete;
TypeTableBuilder &operator=(const TypeTableBuilder &) = delete;
@@ -64,10 +65,14 @@ public:
return *ExpectedIndex;
}
- TypeIndex writeSerializedRecord(MutableArrayRef<uint8_t> Record) {
+ TypeIndex writeSerializedRecord(ArrayRef<uint8_t> Record) {
return Serializer.insertRecordBytes(Record);
}
+ TypeIndex writeSerializedRecord(const RemappedType &Record) {
+ return Serializer.insertRecord(Record);
+ }
+
template <typename TFunc> void ForEachRecord(TFunc Func) {
uint32_t Index = TypeIndex::FirstNonSimpleIndex;
@@ -77,23 +82,24 @@ public:
}
}
- ArrayRef<MutableArrayRef<uint8_t>> records() const {
- return Serializer.records();
- }
+ ArrayRef<ArrayRef<uint8_t>> records() const { return Serializer.records(); }
};
class FieldListRecordBuilder {
TypeTableBuilder &TypeTable;
+ BumpPtrAllocator Allocator;
TypeSerializer TempSerializer;
CVType Type;
public:
explicit FieldListRecordBuilder(TypeTableBuilder &TypeTable)
- : TypeTable(TypeTable), TempSerializer(TypeTable.getAllocator()) {
+ : TypeTable(TypeTable), TempSerializer(Allocator, false) {
Type.Type = TypeLeafKind::LF_FIELDLIST;
}
void begin() {
+ TempSerializer.reset();
+
if (auto EC = TempSerializer.visitTypeBegin(Type))
consumeError(std::move(EC));
}
@@ -109,16 +115,18 @@ public:
consumeError(std::move(EC));
}
- TypeIndex end() {
+ TypeIndex end(bool Write) {
+ TypeIndex Index;
if (auto EC = TempSerializer.visitTypeEnd(Type)) {
consumeError(std::move(EC));
return TypeIndex();
}
- TypeIndex Index;
- for (auto Record : TempSerializer.records()) {
- Index = TypeTable.writeSerializedRecord(Record);
+ if (Write) {
+ for (auto Record : TempSerializer.records())
+ Index = TypeTable.writeSerializedRecord(Record);
}
+
return Index;
}
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableCollection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableCollection.h
new file mode 100644
index 0000000..80326a0
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableCollection.h
@@ -0,0 +1,43 @@
+//===- TypeTableCollection.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_TYPETABLECOLLECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPETABLECOLLECTION_H
+
+#include "llvm/DebugInfo/CodeView/TypeCollection.h"
+#include "llvm/Support/StringSaver.h"
+
+#include <vector>
+
+namespace llvm {
+namespace codeview {
+
+class TypeTableCollection : public TypeCollection {
+public:
+ explicit TypeTableCollection(ArrayRef<ArrayRef<uint8_t>> Records);
+
+ Optional<TypeIndex> getFirst() override;
+ Optional<TypeIndex> getNext(TypeIndex Prev) override;
+
+ CVType getType(TypeIndex Index) override;
+ StringRef getTypeName(TypeIndex Index) override;
+ bool contains(TypeIndex Index) override;
+ uint32_t size() override;
+ uint32_t capacity() override;
+
+private:
+ BumpPtrAllocator Allocator;
+ StringSaver NameStorage;
+ std::vector<StringRef> Names;
+ ArrayRef<ArrayRef<uint8_t>> Records;
+};
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h
index f251296..126fb8a 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h
@@ -47,6 +47,14 @@ public:
return Error::success();
}
+ Error visitTypeBegin(CVType &Record, TypeIndex Index) override {
+ for (auto Visitor : Pipeline) {
+ if (auto EC = Visitor->visitTypeBegin(Record, Index))
+ return EC;
+ }
+ return Error::success();
+ }
+
Error visitTypeEnd(CVType &Record) override {
for (auto Visitor : Pipeline) {
if (auto EC = Visitor->visitTypeEnd(Record))
@@ -86,7 +94,7 @@ public:
}
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "llvm/DebugInfo/CodeView/TypeRecords.def"
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
private:
template <typename T> Error visitKnownRecordImpl(CVType &CVR, T &Record) {
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h
index 5e27df3..d7a4733 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h
@@ -17,8 +17,6 @@ namespace llvm {
namespace codeview {
class TypeVisitorCallbacks {
- friend class CVTypeVisitor;
-
public:
virtual ~TypeVisitorCallbacks() = default;
@@ -26,8 +24,15 @@ public:
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. visitTypeBegin() should return
- /// the type of the Record, or an error if it cannot be determined.
+ /// the type of the Record, or an error if it cannot be determined. Exactly
+ /// one of the two visitTypeBegin methods will be called, depending on whether
+ /// records are being visited sequentially or randomly. An implementation
+ /// should be prepared to handle both (or assert if it can't handle random
+ /// access visitation).
virtual Error visitTypeBegin(CVType &Record) { return Error::success(); }
+ virtual Error visitTypeBegin(CVType &Record, TypeIndex Index) {
+ return Error::success();
+ }
virtual Error visitTypeEnd(CVType &Record) { return Error::success(); }
virtual Error visitUnknownMember(CVMemberRecord &Record) {
@@ -53,7 +58,11 @@ public:
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "TypeRecords.def"
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+#undef TYPE_RECORD
+#undef TYPE_RECORD_ALIAS
+#undef MEMBER_RECORD
+#undef MEMBER_RECORD_ALIAS
};
} // end namespace codeview
OpenPOWER on IntegriCloud