--- /dev/null
+//===- CodeView.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_CODEVIEW_H
+#define LLVM_DEBUGINFO_CODEVIEW_CODEVIEW_H
+
+#include <cinttypes>
+
+namespace llvm {
+namespace codeview {
+
+enum class CallingConvention : uint8_t {
+ NearC = 0x00, // near right to left push, caller pops stack
+ FarC = 0x01, // far right to left push, caller pops stack
+ NearPascal = 0x02, // near left to right push, callee pops stack
+ FarPascal = 0x03, // far left to right push, callee pops stack
+ NearFast = 0x04, // near left to right push with regs, callee pops stack
+ FarFast = 0x05, // far left to right push with regs, callee pops stack
+ NearStdCall = 0x07, // near standard call
+ FarStdCall = 0x08, // far standard call
+ NearSysCall = 0x09, // near sys call
+ FarSysCall = 0x0a, // far sys call
+ ThisCall = 0x0b, // this call (this passed in register)
+ MipsCall = 0x0c, // Mips call
+ Generic = 0x0d, // Generic call sequence
+ AlphaCall = 0x0e, // Alpha call
+ PpcCall = 0x0f, // PPC call
+ SHCall = 0x10, // Hitachi SuperH call
+ ArmCall = 0x11, // ARM call
+ AM33Call = 0x12, // AM33 call
+ TriCall = 0x13, // TriCore Call
+ SH5Call = 0x14, // Hitachi SuperH-5 call
+ M32RCall = 0x15, // M32R Call
+ ClrCall = 0x16, // clr call
+ Inline =
+ 0x17, // Marker for routines always inlined and thus lacking a convention
+ NearVector = 0x18 // near left to right push with regs, callee pops stack
+};
+
+enum class ClassOptions : uint16_t {
+ None = 0x0000,
+ Packed = 0x0001,
+ HasConstructorOrDestructor = 0x0002,
+ HasOverloadedOperator = 0x0004,
+ Nested = 0x0008,
+ ContainsNestedClass = 0x0010,
+ HasOverloadedAssignmentOperator = 0x0020,
+ HasConversionOperator = 0x0040,
+ ForwardReference = 0x0080,
+ Scoped = 0x0100,
+ HasUniqueName = 0x0200,
+ Sealed = 0x0400,
+ Intrinsic = 0x2000
+};
+
+inline ClassOptions operator|(ClassOptions a, ClassOptions b) {
+ return static_cast<ClassOptions>(static_cast<uint16_t>(a) |
+ static_cast<uint16_t>(b));
+}
+
+inline ClassOptions operator&(ClassOptions a, ClassOptions b) {
+ return static_cast<ClassOptions>(static_cast<uint16_t>(a) &
+ static_cast<uint16_t>(b));
+}
+
+inline ClassOptions operator~(ClassOptions a) {
+ return static_cast<ClassOptions>(~static_cast<uint16_t>(a));
+}
+
+enum class FrameProcedureOptions : uint32_t {
+ None = 0x00000000,
+ HasAlloca = 0x00000001,
+ HasSetJmp = 0x00000002,
+ HasLongJmp = 0x00000004,
+ HasInlineAssembly = 0x00000008,
+ HasExceptionHandling = 0x00000010,
+ MarkedInline = 0x00000020,
+ HasStructuredExceptionHandling = 0x00000040,
+ Naked = 0x00000080,
+ SecurityChecks = 0x00000100,
+ AsynchronousExceptionHandling = 0x00000200,
+ NoStackOrderingForSecurityChecks = 0x00000400,
+ Inlined = 0x00000800,
+ StrictSecurityChecks = 0x00001000,
+ SafeBuffers = 0x00002000,
+ ProfileGuidedOptimization = 0x00040000,
+ ValidProfileCounts = 0x00080000,
+ OptimizedForSpeed = 0x00100000,
+ GuardCfg = 0x00200000,
+ GuardCfw = 0x00400000
+};
+
+inline FrameProcedureOptions operator|(FrameProcedureOptions a,
+ FrameProcedureOptions b) {
+ return static_cast<FrameProcedureOptions>(static_cast<uint32_t>(a) |
+ static_cast<uint32_t>(b));
+}
+
+inline FrameProcedureOptions operator&(FrameProcedureOptions a,
+ FrameProcedureOptions b) {
+ return static_cast<FrameProcedureOptions>(static_cast<uint32_t>(a) &
+ static_cast<uint32_t>(b));
+}
+
+inline FrameProcedureOptions operator~(FrameProcedureOptions a) {
+ return static_cast<FrameProcedureOptions>(~static_cast<uint32_t>(a));
+}
+
+enum class FunctionOptions : uint8_t {
+ None = 0x00,
+ CxxReturnUdt = 0x01,
+ Constructor = 0x02,
+ ConstructorWithVirtualBases = 0x04
+};
+
+inline FunctionOptions operator|(FunctionOptions a, FunctionOptions b) {
+ return static_cast<FunctionOptions>(static_cast<uint8_t>(a) |
+ static_cast<uint8_t>(b));
+}
+
+inline FunctionOptions operator&(FunctionOptions a, FunctionOptions b) {
+ return static_cast<FunctionOptions>(static_cast<uint8_t>(a) &
+ static_cast<uint8_t>(b));
+}
+
+inline FunctionOptions operator~(FunctionOptions a) {
+ return static_cast<FunctionOptions>(~static_cast<uint8_t>(a));
+}
+
+enum class HfaKind : uint8_t {
+ None = 0x00,
+ Float = 0x01,
+ Double = 0x02,
+ Other = 0x03
+};
+
+enum class MemberAccess : uint8_t {
+ None = 0,
+ Private = 1,
+ Protected = 2,
+ Public = 3
+};
+
+enum class MethodKind : uint8_t {
+ Vanilla = 0x00,
+ Virtual = 0x01,
+ Static = 0x02,
+ Friend = 0x03,
+ IntroducingVirtual = 0x04,
+ PureVirtual = 0x05,
+ PureIntroducingVirtual = 0x06
+};
+
+enum class MethodOptions : uint16_t {
+ None = 0x0000,
+ Pseudo = 0x0020,
+ CompilerGenerated = 0x0100,
+ Sealed = 0x0200
+};
+
+inline MethodOptions operator|(MethodOptions a, MethodOptions b) {
+ return static_cast<MethodOptions>(static_cast<uint16_t>(a) |
+ static_cast<uint16_t>(b));
+}
+
+inline MethodOptions operator&(MethodOptions a, MethodOptions b) {
+ return static_cast<MethodOptions>(static_cast<uint16_t>(a) &
+ static_cast<uint16_t>(b));
+}
+
+inline MethodOptions operator~(MethodOptions a) {
+ return static_cast<MethodOptions>(~static_cast<uint16_t>(a));
+}
+
+enum class ModifierOptions : uint16_t {
+ None = 0x0000,
+ Const = 0x0001,
+ Volatile = 0x0002,
+ Unaligned = 0x0004
+};
+
+inline ModifierOptions operator|(ModifierOptions a, ModifierOptions b) {
+ return static_cast<ModifierOptions>(static_cast<uint16_t>(a) |
+ static_cast<uint16_t>(b));
+}
+
+inline ModifierOptions operator&(ModifierOptions a, ModifierOptions b) {
+ return static_cast<ModifierOptions>(static_cast<uint16_t>(a) &
+ static_cast<uint16_t>(b));
+}
+
+inline ModifierOptions operator~(ModifierOptions a) {
+ return static_cast<ModifierOptions>(~static_cast<uint16_t>(a));
+}
+
+enum class ModuleSubstreamKind : uint32_t {
+ Symbols = 0xf1,
+ Lines = 0xf2,
+ StringTable = 0xf3,
+ FileChecksums = 0xf4,
+ FrameData = 0xf5,
+ InlineeLines = 0xf6,
+ CrossScopeImports = 0xf7,
+ CrossScopeExports = 0xf8
+};
+
+enum class PointerKind : uint8_t {
+ Near16 = 0x00, // 16 bit pointer
+ Far16 = 0x01, // 16:16 far pointer
+ Huge16 = 0x02, // 16:16 huge pointer
+ BasedOnSegment = 0x03, // based on segment
+ BasedOnValue = 0x04, // based on value of base
+ BasedOnSegmentValue = 0x05, // based on segment value of base
+ BasedOnAddress = 0x06, // based on address of base
+ BasedOnSegmentAddress = 0x07, // based on segment address of base
+ BasedOnType = 0x08, // based on type
+ BasedOnSelf = 0x09, // based on self
+ Near32 = 0x0a, // 32 bit pointer
+ Far32 = 0x0b, // 16:32 pointer
+ Near64 = 0x0c // 64 bit pointer
+};
+
+enum class PointerMode : uint8_t {
+ Pointer = 0x00, // "normal" pointer
+ LValueReference = 0x01, // "old" reference
+ PointerToDataMember = 0x02, // pointer to data member
+ PointerToMemberFunction = 0x03, // pointer to member function
+ RValueReference = 0x04 // r-value reference
+};
+
+enum class PointerOptions : uint32_t {
+ None = 0x00000000,
+ Flat32 = 0x00000100,
+ Volatile = 0x00000200,
+ Const = 0x00000400,
+ Unaligned = 0x00000800,
+ Restrict = 0x00001000,
+ WinRTSmartPointer = 0x00080000
+};
+
+inline PointerOptions operator|(PointerOptions a, PointerOptions b) {
+ return static_cast<PointerOptions>(static_cast<uint16_t>(a) |
+ static_cast<uint16_t>(b));
+}
+
+inline PointerOptions operator&(PointerOptions a, PointerOptions b) {
+ return static_cast<PointerOptions>(static_cast<uint16_t>(a) &
+ static_cast<uint16_t>(b));
+}
+
+inline PointerOptions operator~(PointerOptions a) {
+ return static_cast<PointerOptions>(~static_cast<uint16_t>(a));
+}
+
+enum class PointerToMemberRepresentation : uint16_t {
+ Unknown = 0x00, // not specified (pre VC8)
+ SingleInheritanceData = 0x01, // member data, single inheritance
+ MultipleInheritanceData = 0x02, // member data, multiple inheritance
+ VirtualInheritanceData = 0x03, // member data, virtual inheritance
+ GeneralData = 0x04, // member data, most general
+ SingleInheritanceFunction = 0x05, // member function, single inheritance
+ MultipleInheritanceFunction = 0x06, // member function, multiple inheritance
+ VirtualInheritanceFunction = 0x07, // member function, virtual inheritance
+ GeneralFunction = 0x08 // member function, most general
+};
+
+enum class TypeRecordKind : uint16_t {
+ None = 0,
+
+ VirtualTableShape = 0x000a,
+ Label = 0x000e,
+ EndPrecompiledHeader = 0x0014,
+
+ Modifier = 0x1001,
+ Pointer = 0x1002,
+ Procedure = 0x1008,
+ MemberFunction = 0x1009,
+
+ Oem = 0x100f,
+ Oem2 = 0x1011,
+
+ ArgumentList = 0x1201,
+ FieldList = 0x1203,
+ BitField = 0x1205,
+ MethodList = 0x1206,
+
+ BaseClass = 0x1400,
+ VirtualBaseClass = 0x1401,
+ IndirectVirtualBaseClass = 0x1402,
+ Index = 0x1404,
+ VirtualFunctionTablePointer = 0x1409,
+
+ Enumerate = 0x1502,
+ Array = 0x1503,
+ Class = 0x1504,
+ Structure = 0x1505,
+ Union = 0x1506,
+ Enum = 0x1507,
+ Alias = 0x150a,
+ Member = 0x150d,
+ StaticMember = 0x150e,
+ Method = 0x150f,
+ NestedType = 0x1510,
+ OneMethod = 0x1511,
+ VirtualFunctionTable = 0x151d,
+
+ FunctionId = 0x1601,
+ MemberFunctionId = 0x1602,
+ BuildInfo = 0x1603,
+ SubstringList = 0x1604,
+ StringId = 0x1605,
+ UdtSourceLine = 0x1606,
+
+ SByte = 0x8000,
+ Int16 = 0x8001,
+ UInt16 = 0x8002,
+ Int32 = 0x8003,
+ UInt32 = 0x8004,
+ Single = 0x8005,
+ Double = 0x8006,
+ Float80 = 0x8007,
+ Float128 = 0x8008,
+ Int64 = 0x8009,
+ UInt64 = 0x800a,
+ Float48 = 0x800b,
+ Complex32 = 0x800c,
+ Complex64 = 0x800d,
+ Complex80 = 0x800e,
+ Complex128 = 0x800f,
+ VarString = 0x8010,
+
+ Int128 = 0x8017,
+ UInt128 = 0x8018,
+
+ Decimal = 0x8019,
+ Date = 0x801a,
+ Utf8String = 0x801b,
+
+ Float16 = 0x801c
+};
+
+enum class VirtualTableSlotKind : uint8_t {
+ Near16 = 0x00,
+ Far16 = 0x01,
+ This = 0x02,
+ Outer = 0x03,
+ Meta = 0x04,
+ Near = 0x05,
+ Far = 0x06
+};
+
+enum class WindowsRTClassKind : uint8_t {
+ None = 0x00,
+ RefClass = 0x01,
+ ValueClass = 0x02,
+ Interface = 0x03
+};
+}
+}
+
+#endif
--- /dev/null
+//===- CodeViewOStream.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_CODEVIEWOSTREAM_H
+#define LLVM_DEBUGINFO_CODEVIEW_CODEVIEWOSTREAM_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+
+namespace llvm {
+namespace codeview {
+
+template <typename Writer> class CodeViewOStream {
+private:
+ CodeViewOStream(const CodeViewOStream &) = delete;
+ CodeViewOStream &operator=(const CodeViewOStream &) = delete;
+
+public:
+ typedef typename Writer::LabelType LabelType;
+
+public:
+ explicit CodeViewOStream(Writer &W);
+
+private:
+ uint64_t size() const { return W.tell(); }
+
+private:
+ Writer &W;
+};
+}
+}
+
+#endif
--- /dev/null
+//===- FieldListRecordBuilder.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_FIELDLISTRECORDBUILDER_H
+#define LLVM_DEBUGINFO_CODEVIEW_FIELDLISTRECORDBUILDER_H
+
+#include "llvm/DebugInfo/CodeView/ListRecordBuilder.h"
+
+namespace llvm {
+namespace codeview {
+
+class MethodInfo {
+public:
+ MethodInfo() : Access(), Kind(), Options(), Type(), VTableSlotOffset(-1) {}
+
+ MethodInfo(MemberAccess Access, MethodKind Kind, MethodOptions Options,
+ TypeIndex Type, int32_t VTableSlotOffset)
+ : Access(Access), Kind(Kind), Options(Options), Type(Type),
+ VTableSlotOffset(VTableSlotOffset) {}
+
+ MemberAccess getAccess() const { return Access; }
+ MethodKind getKind() const { return Kind; }
+ MethodOptions getOptions() const { return Options; }
+ TypeIndex getType() const { return Type; }
+ int32_t getVTableSlotOffset() const { return VTableSlotOffset; }
+
+private:
+ MemberAccess Access;
+ MethodKind Kind;
+ MethodOptions Options;
+ TypeIndex Type;
+ int32_t VTableSlotOffset;
+};
+
+class FieldListRecordBuilder : public ListRecordBuilder {
+private:
+ FieldListRecordBuilder(const FieldListRecordBuilder &) = delete;
+ void operator=(const FieldListRecordBuilder &) = delete;
+
+public:
+ FieldListRecordBuilder();
+
+ void writeBaseClass(MemberAccess Access, TypeIndex Type, uint64_t Offset);
+ void writeEnumerate(MemberAccess Access, uint64_t Value, StringRef Name);
+ void writeIndirectVirtualBaseClass(MemberAccess Access, TypeIndex Type,
+ TypeIndex VirtualBasePointerType,
+ int64_t VirtualBasePointerOffset,
+ uint64_t SlotIndex);
+ void writeMember(MemberAccess Access, TypeIndex Type, uint64_t Offset,
+ StringRef Name);
+ void writeOneMethod(MemberAccess Access, MethodKind Kind,
+ MethodOptions Options, TypeIndex Type,
+ int32_t VTableSlotOffset, StringRef Name);
+ void writeOneMethod(const MethodInfo &Method, StringRef Name);
+ void writeMethod(uint16_t OverloadCount, TypeIndex MethodList,
+ StringRef Name);
+ void writeNestedType(TypeIndex Type, StringRef Name);
+ void writeStaticMember(MemberAccess Access, TypeIndex Type, StringRef Name);
+ void writeVirtualBaseClass(MemberAccess Access, TypeIndex Type,
+ TypeIndex VirtualBasePointerType,
+ int64_t VirtualBasePointerOffset,
+ uint64_t SlotIndex);
+ void writeVirtualBaseClass(TypeRecordKind Kind, MemberAccess Access,
+ TypeIndex Type, TypeIndex VirtualBasePointerType,
+ int64_t VirtualBasePointerOffset,
+ uint64_t SlotIndex);
+ void writeVirtualFunctionTablePointer(TypeIndex Type);
+};
+}
+}
+
+#endif
--- /dev/null
+//===- FunctionId.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_FUNCTIONID_H
+#define LLVM_DEBUGINFO_CODEVIEW_FUNCTIONID_H
+
+#include <cinttypes>
+
+namespace llvm {
+namespace codeview {
+
+class FunctionId {
+public:
+ FunctionId() : Index(0) {}
+
+ explicit FunctionId(uint32_t Index) : Index(Index) {}
+
+ uint32_t getIndex() const { return Index; }
+
+private:
+ uint32_t Index;
+};
+
+inline bool operator==(const FunctionId &A, const FunctionId &B) {
+ return A.getIndex() == B.getIndex();
+}
+
+inline bool operator!=(const FunctionId &A, const FunctionId &B) {
+ return A.getIndex() != B.getIndex();
+}
+
+inline bool operator<(const FunctionId &A, const FunctionId &B) {
+ return A.getIndex() < B.getIndex();
+}
+
+inline bool operator<=(const FunctionId &A, const FunctionId &B) {
+ return A.getIndex() <= B.getIndex();
+}
+
+inline bool operator>(const FunctionId &A, const FunctionId &B) {
+ return A.getIndex() > B.getIndex();
+}
+
+inline bool operator>=(const FunctionId &A, const FunctionId &B) {
+ return A.getIndex() >= B.getIndex();
+}
+}
+}
+
+#endif
--- /dev/null
+//===- Line.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_LINE_H
+#define LLVM_DEBUGINFO_CODEVIEW_LINE_H
+
+#include <cinttypes>
+
+namespace llvm {
+namespace codeview {
+
+class LineInfo {
+public:
+ static const int32_t AlwaysStepIntoLineNumber = 0xfeefee;
+ static const int32_t NeverStepIntoLineNumber = 0xf00f00;
+
+private:
+ static const uint32_t StartLineMask = 0x00ffffff;
+ static const uint32_t EndLineDeltaMask = 0x7f000000;
+ static const int EndLineDeltaShift = 24;
+ static const uint32_t StatementFlag = 0x80000000u;
+
+public:
+ LineInfo(uint32_t StartLine, uint32_t EndLine, bool IsStatement);
+
+ uint32_t getStartLine() const { return LineData & StartLineMask; }
+
+ uint32_t getLineDelta() const {
+ return (LineData & EndLineDeltaMask) >> EndLineDeltaShift;
+ }
+
+ uint32_t getEndLine() const { return getStartLine() + getLineDelta(); }
+
+ bool isStatement() const { return (LineData & StatementFlag) != 0; }
+
+ uint32_t getRawData() const { return LineData; }
+
+ bool isAlwaysStepInto() const {
+ return getStartLine() == AlwaysStepIntoLineNumber;
+ }
+
+ bool isNeverStepInto() const {
+ return getStartLine() == NeverStepIntoLineNumber;
+ }
+
+private:
+ uint32_t LineData;
+};
+
+class ColumnInfo {
+private:
+ static const uint32_t StartColumnMask = 0x0000ffffu;
+ static const uint32_t EndColumnMask = 0xffff0000u;
+ static const int EndColumnShift = 16;
+
+public:
+ ColumnInfo(uint16_t StartColumn, uint16_t EndColumn) {
+ ColumnData =
+ (static_cast<uint32_t>(StartColumn) & StartColumnMask) |
+ ((static_cast<uint32_t>(EndColumn) << EndColumnShift) & EndColumnMask);
+ }
+
+ uint16_t getStartColumn() const {
+ return static_cast<uint16_t>(ColumnData & StartColumnMask);
+ }
+
+ uint16_t getEndColumn() const {
+ return static_cast<uint16_t>((ColumnData & EndColumnMask) >>
+ EndColumnShift);
+ }
+
+ uint32_t getRawData() const { return ColumnData; }
+
+private:
+ uint32_t ColumnData;
+};
+
+class Line {
+private:
+ int32_t CodeOffset;
+ LineInfo LineInf;
+ ColumnInfo ColumnInf;
+
+public:
+ Line(int32_t CodeOffset, uint32_t StartLine, uint32_t EndLine,
+ uint16_t StartColumn, uint16_t EndColumn, bool IsStatement)
+ : CodeOffset(CodeOffset), LineInf(StartLine, EndLine, IsStatement),
+ ColumnInf(StartColumn, EndColumn) {}
+
+ Line(int32_t CodeOffset, LineInfo LineInf, ColumnInfo ColumnInf)
+ : CodeOffset(CodeOffset), LineInf(LineInf), ColumnInf(ColumnInf) {}
+
+ LineInfo getLineInfo() const { return LineInf; }
+
+ ColumnInfo getColumnInfo() const { return ColumnInf; }
+
+ int32_t getCodeOffset() const { return CodeOffset; }
+
+ uint32_t getStartLine() const { return LineInf.getStartLine(); }
+
+ uint32_t getLineDelta() const { return LineInf.getLineDelta(); }
+
+ uint32_t getEndLine() const { return LineInf.getEndLine(); }
+
+ uint16_t getStartColumn() const { return ColumnInf.getStartColumn(); }
+
+ uint16_t getEndColumn() const { return ColumnInf.getEndColumn(); }
+
+ bool isStatement() const { return LineInf.isStatement(); }
+
+ bool isAlwaysStepInto() const { return LineInf.isAlwaysStepInto(); }
+
+ bool isNeverStepInto() const { return LineInf.isNeverStepInto(); }
+};
+}
+}
+
+#endif
--- /dev/null
+//===- ListRecordBuilder.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_LISTRECORDBUILDER_H
+#define LLVM_DEBUGINFO_CODEVIEW_LISTRECORDBUILDER_H
+
+#include "llvm/DebugInfo/CodeView/TypeRecordBuilder.h"
+
+namespace llvm {
+namespace codeview {
+
+class ListRecordBuilder {
+private:
+ ListRecordBuilder(const ListRecordBuilder &) = delete;
+ ListRecordBuilder &operator=(const ListRecordBuilder &) = delete;
+
+protected:
+ const int MethodKindShift = 2;
+
+ explicit ListRecordBuilder(TypeRecordKind Kind);
+
+public:
+ llvm::StringRef str() { return Builder.str(); }
+
+protected:
+ void finishSubRecord();
+
+ TypeRecordBuilder &getBuilder() { return Builder; }
+
+private:
+ TypeRecordBuilder Builder;
+ SmallVector<size_t, 4> ContinuationOffsets;
+};
+}
+}
+
+#endif
--- /dev/null
+//===- MemoryTypeTableBuilder.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_MEMORYTYPETABLEBUILDER_H
+#define LLVM_DEBUGINFO_CODEVIEW_MEMORYTYPETABLEBUILDER_H
+
+#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
+#include <functional>
+#include <memory>
+#include <unordered_map>
+#include <vector>
+
+namespace llvm {
+namespace codeview {
+
+class MemoryTypeTableBuilder : public TypeTableBuilder {
+public:
+ class Record {
+ public:
+ explicit Record(llvm::StringRef RData);
+
+ const char *data() const { return Data.get(); }
+ uint16_t size() const { return Size; }
+
+ private:
+ uint16_t Size;
+ std::unique_ptr<char[]> Data;
+ };
+
+private:
+ class RecordHash : std::unary_function<llvm::StringRef, size_t> {
+ public:
+ size_t operator()(llvm::StringRef Val) const {
+ return static_cast<size_t>(llvm::hash_value(Val));
+ }
+ };
+
+public:
+ MemoryTypeTableBuilder() {}
+
+ template <typename TFunc> void ForEachRecord(TFunc Func) {
+ uint32_t Index = TypeIndex::FirstNonSimpleIndex;
+
+ for (const std::unique_ptr<Record> &R : Records) {
+ Func(TypeIndex(Index), R.get());
+ ++Index;
+ }
+ }
+
+private:
+ virtual TypeIndex writeRecord(llvm::StringRef Data) override;
+
+private:
+ std::vector<std::unique_ptr<Record>> Records;
+ std::unordered_map<llvm::StringRef, TypeIndex, RecordHash> HashedRecords;
+};
+}
+}
+
+#endif
--- /dev/null
+//===- MethodListRecordBuilder.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_METHODLISTRECORDBUILDER_H
+#define LLVM_DEBUGINFO_CODEVIEW_METHODLISTRECORDBUILDER_H
+
+#include "llvm/DebugInfo/CodeView/ListRecordBuilder.h"
+
+namespace llvm {
+namespace codeview {
+
+class MethodInfo;
+
+class MethodListRecordBuilder : public ListRecordBuilder {
+private:
+ MethodListRecordBuilder(const MethodListRecordBuilder &) = delete;
+ MethodListRecordBuilder &operator=(const MethodListRecordBuilder &) = delete;
+
+public:
+ MethodListRecordBuilder();
+
+ void writeMethod(MemberAccess Access, MethodKind Kind, MethodOptions Options,
+ TypeIndex Type, int32_t VTableSlotOffset);
+ void writeMethod(const MethodInfo &Method);
+};
+}
+}
+
+#endif
--- /dev/null
+//===- TypeIndex.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_TYPEINDEX_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPEINDEX_H
+
+#include <cassert>
+#include <cinttypes>
+
+namespace llvm {
+namespace codeview {
+
+enum class SimpleTypeKind : uint32_t {
+ None = 0x0000, // uncharacterized type (no type)
+ Void = 0x0003, // void
+ NotTranslated = 0x0007, // type not translated by cvpack
+ HResult = 0x0008, // OLE/COM HRESULT
+
+ SignedCharacter = 0x0010, // 8 bit signed
+ UnsignedCharacter = 0x0020, // 8 bit unsigned
+ NarrowCharacter = 0x0070, // really a char
+ WideCharacter = 0x0071, // wide char
+
+ SByte = 0x0068, // 8 bit signed int
+ Byte = 0x0069, // 8 bit unsigned int
+ Int16Short = 0x0011, // 16 bit signed
+ UInt16Short = 0x0021, // 16 bit unsigned
+ Int16 = 0x0072, // 16 bit signed int
+ UInt16 = 0x0073, // 16 bit unsigned int
+ Int32Long = 0x0012, // 32 bit signed
+ UInt32Long = 0x0022, // 32 bit unsigned
+ Int32 = 0x0074, // 32 bit signed int
+ UInt32 = 0x0075, // 32 bit unsigned int
+ Int64Quad = 0x0013, // 64 bit signed
+ UInt64Quad = 0x0023, // 64 bit unsigned
+ Int64 = 0x0076, // 64 bit signed int
+ UInt64 = 0x0077, // 64 bit unsigned int
+ Int128 = 0x0078, // 128 bit signed int
+ UInt128 = 0x0079, // 128 bit unsigned int
+
+ Float16 = 0x0046, // 16 bit real
+ Float32 = 0x0040, // 32 bit real
+ Float32PartialPrecision = 0x0045, // 32 bit PP real
+ Float48 = 0x0044, // 48 bit real
+ Float64 = 0x0041, // 64 bit real
+ Float80 = 0x0042, // 80 bit real
+ Float128 = 0x0043, // 128 bit real
+
+ Complex32 = 0x0050, // 32 bit complex
+ Complex64 = 0x0051, // 64 bit complex
+ Complex80 = 0x0052, // 80 bit complex
+ Complex128 = 0x0053, // 128 bit complex
+
+ Boolean8 = 0x0030, // 8 bit boolean
+ Boolean16 = 0x0031, // 16 bit boolean
+ Boolean32 = 0x0032, // 32 bit boolean
+ Boolean64 = 0x0033 // 64 bit boolean
+};
+
+enum class SimpleTypeMode : uint32_t {
+ Direct = 0x00000000, // Not a pointer
+ NearPointer = 0x00000100, // Near pointer
+ FarPointer = 0x00000200, // Far pointer
+ HugePointer = 0x00000300, // Huge pointer
+ NearPointer32 = 0x00000400, // 32 bit near pointer
+ FarPointer32 = 0x00000500, // 32 bit far pointer
+ NearPointer64 = 0x00000600, // 64 bit near pointer
+ NearPointer128 = 0x00000700 // 128 bit near pointer
+};
+
+class TypeIndex {
+public:
+ static const uint32_t FirstNonSimpleIndex = 0x1000;
+ static const uint32_t SimpleKindMask = 0x000000ff;
+ static const uint32_t SimpleModeMask = 0x00000700;
+
+public:
+ TypeIndex() : Index(0) {}
+ explicit TypeIndex(uint32_t Index) : Index(Index) {}
+ explicit TypeIndex(SimpleTypeKind Kind)
+ : Index(static_cast<uint32_t>(Kind)) {}
+ TypeIndex(SimpleTypeKind Kind, SimpleTypeMode Mode)
+ : Index(static_cast<uint32_t>(Kind) | static_cast<uint32_t>(Mode)) {}
+
+ uint32_t getIndex() const { return Index; }
+ bool isSimple() const { return Index < FirstNonSimpleIndex; }
+
+ SimpleTypeKind getSimpleKind() const {
+ assert(isSimple());
+ return static_cast<SimpleTypeKind>(Index & SimpleKindMask);
+ }
+
+ SimpleTypeMode getSimpleMode() const {
+ assert(isSimple());
+ return static_cast<SimpleTypeMode>(Index & SimpleModeMask);
+ }
+
+ static TypeIndex Void() { return TypeIndex(SimpleTypeKind::Void); }
+ static TypeIndex VoidPointer32() {
+ return TypeIndex(SimpleTypeKind::Void, SimpleTypeMode::NearPointer32);
+ }
+ static TypeIndex VoidPointer64() {
+ return TypeIndex(SimpleTypeKind::Void, SimpleTypeMode::NearPointer64);
+ }
+
+ static TypeIndex SignedCharacter() {
+ return TypeIndex(SimpleTypeKind::SignedCharacter);
+ }
+ static TypeIndex UnsignedCharacter() {
+ return TypeIndex(SimpleTypeKind::UnsignedCharacter);
+ }
+ static TypeIndex NarrowCharacter() {
+ return TypeIndex(SimpleTypeKind::NarrowCharacter);
+ }
+ static TypeIndex WideCharacter() {
+ return TypeIndex(SimpleTypeKind::WideCharacter);
+ }
+ static TypeIndex Int16Short() {
+ return TypeIndex(SimpleTypeKind::Int16Short);
+ }
+ static TypeIndex UInt16Short() {
+ return TypeIndex(SimpleTypeKind::UInt16Short);
+ }
+ static TypeIndex Int32() { return TypeIndex(SimpleTypeKind::Int32); }
+ static TypeIndex UInt32() { return TypeIndex(SimpleTypeKind::UInt32); }
+ static TypeIndex Int32Long() { return TypeIndex(SimpleTypeKind::Int32Long); }
+ static TypeIndex UInt32Long() {
+ return TypeIndex(SimpleTypeKind::UInt32Long);
+ }
+ static TypeIndex Int64() { return TypeIndex(SimpleTypeKind::Int64); }
+ static TypeIndex UInt64() { return TypeIndex(SimpleTypeKind::UInt64); }
+ static TypeIndex Int64Quad() { return TypeIndex(SimpleTypeKind::Int64Quad); }
+ static TypeIndex UInt64Quad() {
+ return TypeIndex(SimpleTypeKind::UInt64Quad);
+ }
+
+ static TypeIndex Float32() { return TypeIndex(SimpleTypeKind::Float32); }
+ static TypeIndex Float64() { return TypeIndex(SimpleTypeKind::Float64); }
+
+private:
+ uint32_t Index;
+};
+
+inline bool operator==(const TypeIndex &A, const TypeIndex &B) {
+ return A.getIndex() == B.getIndex();
+}
+
+inline bool operator!=(const TypeIndex &A, const TypeIndex &B) {
+ return A.getIndex() != B.getIndex();
+}
+
+inline bool operator<(const TypeIndex &A, const TypeIndex &B) {
+ return A.getIndex() < B.getIndex();
+}
+
+inline bool operator<=(const TypeIndex &A, const TypeIndex &B) {
+ return A.getIndex() <= B.getIndex();
+}
+
+inline bool operator>(const TypeIndex &A, const TypeIndex &B) {
+ return A.getIndex() > B.getIndex();
+}
+
+inline bool operator>=(const TypeIndex &A, const TypeIndex &B) {
+ return A.getIndex() >= B.getIndex();
+}
+}
+}
+
+#endif
--- /dev/null
+//===- TypeRecord.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_TYPERECORD_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include <cinttypes>
+
+namespace llvm {
+namespace codeview {
+
+class TypeRecord {
+protected:
+ explicit TypeRecord(TypeRecordKind Kind) : Kind(Kind) {}
+
+public:
+ TypeRecordKind getKind() const { return Kind; }
+
+private:
+ TypeRecordKind Kind;
+};
+
+class ModifierRecord : public TypeRecord {
+public:
+ ModifierRecord(TypeIndex ModifiedType, ModifierOptions Options)
+ : TypeRecord(TypeRecordKind::Modifier), ModifiedType(ModifiedType),
+ Options(Options) {}
+
+ TypeIndex getModifiedType() const { return ModifiedType; }
+ ModifierOptions getOptions() const { return Options; }
+
+private:
+ TypeIndex ModifiedType;
+ ModifierOptions Options;
+};
+
+class ProcedureRecord : public TypeRecord {
+public:
+ ProcedureRecord(TypeIndex ReturnType, CallingConvention CallConv,
+ FunctionOptions Options, uint16_t ParameterCount,
+ TypeIndex ArgumentList)
+ : TypeRecord(TypeRecordKind::Procedure), ReturnType(ReturnType),
+ CallConv(CallConv), Options(Options), ParameterCount(ParameterCount),
+ ArgumentList(ArgumentList) {}
+
+ TypeIndex getReturnType() const { return ReturnType; }
+ CallingConvention getCallConv() const { return CallConv; }
+ FunctionOptions getOptions() const { return Options; }
+ uint16_t getParameterCount() const { return ParameterCount; }
+ TypeIndex getArgumentList() const { return ArgumentList; }
+
+private:
+ TypeIndex ReturnType;
+ CallingConvention CallConv;
+ FunctionOptions Options;
+ uint16_t ParameterCount;
+ TypeIndex ArgumentList;
+};
+
+class MemberFunctionRecord : public TypeRecord {
+public:
+ MemberFunctionRecord(TypeIndex ReturnType, TypeIndex ClassType,
+ TypeIndex ThisType, CallingConvention CallConv,
+ FunctionOptions Options, uint16_t ParameterCount,
+ TypeIndex ArgumentList, int32_t ThisPointerAdjustment)
+ : TypeRecord(TypeRecordKind::MemberFunction), ReturnType(ReturnType),
+ ClassType(ClassType), ThisType(ThisType), CallConv(CallConv),
+ Options(Options), ParameterCount(ParameterCount),
+ ArgumentList(ArgumentList),
+ ThisPointerAdjustment(ThisPointerAdjustment) {}
+
+ TypeIndex getReturnType() const { return ReturnType; }
+ TypeIndex getClassType() const { return ClassType; }
+ TypeIndex getThisType() const { return ThisType; }
+ CallingConvention getCallConv() const { return CallConv; }
+ FunctionOptions getOptions() const { return Options; }
+ uint16_t getParameterCount() const { return ParameterCount; }
+ TypeIndex getArgumentList() const { return ArgumentList; }
+ int32_t getThisPointerAdjustment() const { return ThisPointerAdjustment; }
+
+private:
+ TypeIndex ReturnType;
+ TypeIndex ClassType;
+ TypeIndex ThisType;
+ CallingConvention CallConv;
+ FunctionOptions Options;
+ uint16_t ParameterCount;
+ TypeIndex ArgumentList;
+ int32_t ThisPointerAdjustment;
+};
+
+class ArgumentListRecord : public TypeRecord {
+public:
+ explicit ArgumentListRecord(llvm::ArrayRef<TypeIndex> ArgumentTypes)
+ : TypeRecord(TypeRecordKind::ArgumentList), ArgumentTypes(ArgumentTypes) {
+ }
+
+ llvm::ArrayRef<TypeIndex> getArgumentTypes() const { return ArgumentTypes; }
+
+private:
+ llvm::ArrayRef<TypeIndex> ArgumentTypes;
+};
+
+class PointerRecordBase : public TypeRecord {
+public:
+ PointerRecordBase(TypeIndex ReferentType, PointerKind Kind, PointerMode Mode,
+ PointerOptions Options, uint8_t Size)
+ : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
+ PtrKind(Kind), Mode(Mode), Options(Options), Size(Size) {}
+
+ TypeIndex getReferentType() const { return ReferentType; }
+ PointerKind getPointerKind() const { return PtrKind; }
+ PointerMode getMode() const { return Mode; }
+ PointerOptions getOptions() const { return Options; }
+ uint8_t getSize() const { return Size; }
+
+private:
+ TypeIndex ReferentType;
+ PointerKind PtrKind;
+ PointerMode Mode;
+ PointerOptions Options;
+ uint8_t Size;
+};
+
+class PointerRecord : public PointerRecordBase {
+public:
+ PointerRecord(TypeIndex ReferentType, PointerKind Kind, PointerMode Mode,
+ PointerOptions Options, uint8_t Size)
+ : PointerRecordBase(ReferentType, Kind, Mode, Options, Size) {}
+};
+
+class PointerToMemberRecord : public PointerRecordBase {
+public:
+ PointerToMemberRecord(TypeIndex ReferentType, PointerKind Kind,
+ PointerMode Mode, PointerOptions Options, uint8_t Size,
+ TypeIndex ContainingType,
+ PointerToMemberRepresentation Representation)
+ : PointerRecordBase(ReferentType, Kind, Mode, Options, Size),
+ ContainingType(ContainingType), Representation(Representation) {}
+
+ TypeIndex getContainingType() const { return ContainingType; }
+ PointerToMemberRepresentation getRepresentation() const {
+ return Representation;
+ }
+
+private:
+ TypeIndex ContainingType;
+ PointerToMemberRepresentation Representation;
+};
+
+class ArrayRecord : public TypeRecord {
+public:
+ ArrayRecord(TypeIndex ElementType, TypeIndex IndexType, uint64_t Size,
+ llvm::StringRef Name)
+ : TypeRecord(TypeRecordKind::Array), ElementType(ElementType),
+ IndexType(IndexType), Size(Size), Name(Name) {}
+
+ TypeIndex getElementType() const { return ElementType; }
+ TypeIndex getIndexType() const { return IndexType; }
+ uint64_t getSize() const { return Size; }
+ llvm::StringRef getName() const { return Name; }
+
+private:
+ TypeIndex ElementType;
+ TypeIndex IndexType;
+ uint64_t Size;
+ llvm::StringRef Name;
+};
+
+class TagRecord : public TypeRecord {
+protected:
+ TagRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
+ TypeIndex FieldList, StringRef Name, StringRef UniqueName)
+ : TypeRecord(Kind), MemberCount(MemberCount), Options(Options),
+ FieldList(FieldList), Name(Name), UniqueName(UniqueName) {}
+
+public:
+ uint16_t getMemberCount() const { return MemberCount; }
+ ClassOptions getOptions() const { return Options; }
+ TypeIndex getFieldList() const { return FieldList; }
+ StringRef getName() const { return Name; }
+ StringRef getUniqueName() const { return UniqueName; }
+
+private:
+ uint16_t MemberCount;
+ ClassOptions Options;
+ TypeIndex FieldList;
+ StringRef Name;
+ StringRef UniqueName;
+};
+
+class AggregateRecord : public TagRecord {
+public:
+ AggregateRecord(TypeRecordKind Kind, uint16_t MemberCount,
+ ClassOptions Options, HfaKind Hfa,
+ WindowsRTClassKind WinRTKind, TypeIndex FieldList,
+ TypeIndex DerivationList, TypeIndex VTableShape,
+ uint64_t Size, StringRef Name, StringRef UniqueName)
+ : TagRecord(Kind, MemberCount, Options, FieldList, Name, UniqueName),
+ Hfa(Hfa), WinRTKind(WinRTKind), DerivationList(DerivationList),
+ VTableShape(VTableShape), Size(Size) {}
+
+ HfaKind getHfa() const { return Hfa; }
+ WindowsRTClassKind getWinRTKind() const { return WinRTKind; }
+ TypeIndex getDerivationList() const { return DerivationList; }
+ TypeIndex getVTableShape() const { return VTableShape; }
+ uint64_t getSize() const { return Size; }
+
+private:
+ HfaKind Hfa;
+ WindowsRTClassKind WinRTKind;
+ TypeIndex DerivationList;
+ TypeIndex VTableShape;
+ uint64_t Size;
+};
+
+class EnumRecord : public TagRecord {
+public:
+ EnumRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
+ StringRef Name, StringRef UniqueName, TypeIndex UnderlyingType)
+ : TagRecord(TypeRecordKind::Enum, MemberCount, Options, FieldList, Name,
+ UniqueName),
+ UnderlyingType(UnderlyingType) {}
+
+ TypeIndex getUnderlyingType() const { return UnderlyingType; }
+
+private:
+ TypeIndex UnderlyingType;
+};
+
+class BitFieldRecord : TypeRecord {
+public:
+ BitFieldRecord(TypeIndex Type, uint8_t BitSize, uint8_t BitOffset)
+ : TypeRecord(TypeRecordKind::BitField), Type(Type), BitOffset(BitOffset),
+ BitSize(BitSize) {}
+
+ TypeIndex getType() const { return Type; }
+ uint8_t getBitOffset() const { return BitOffset; }
+ uint8_t getBitSize() const { return BitSize; }
+
+private:
+ TypeIndex Type;
+ uint8_t BitSize;
+ uint8_t BitOffset;
+};
+
+class VirtualTableShapeRecord : TypeRecord {
+public:
+ explicit VirtualTableShapeRecord(ArrayRef<VirtualTableSlotKind> Slots)
+ : TypeRecord(TypeRecordKind::VirtualTableShape), Slots(Slots) {}
+
+ ArrayRef<VirtualTableSlotKind> getSlots() const { return Slots; }
+
+private:
+ ArrayRef<VirtualTableSlotKind> Slots;
+};
+}
+}
+
+#endif
--- /dev/null
+//===- TypeRecordBuilder.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_TYPERECORDBUILDER_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPERECORDBUILDER_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/EndianStream.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+namespace codeview {
+
+class TypeRecordBuilder {
+private:
+ TypeRecordBuilder(const TypeRecordBuilder &) = delete;
+ TypeRecordBuilder &operator=(const TypeRecordBuilder &) = delete;
+
+public:
+ explicit TypeRecordBuilder(TypeRecordKind Kind);
+
+ void writeUInt8(uint8_t Value);
+ void writeInt16(int16_t Value);
+ void writeUInt16(uint16_t Value);
+ void writeInt32(int32_t Value);
+ void writeUInt32(uint32_t Value);
+ void writeInt64(int64_t Value);
+ void writeUInt64(uint64_t Value);
+ void writeTypeIndex(TypeIndex TypeInd);
+ void writeTypeRecordKind(TypeRecordKind Kind);
+ void writeEncodedInteger(int64_t Value);
+ void writeEncodedSignedInteger(int64_t Value);
+ void writeEncodedUnsignedInteger(uint64_t Value);
+ void writeNullTerminatedString(const char *Value);
+ void writeNullTerminatedString(StringRef Value);
+
+ llvm::StringRef str();
+
+ uint64_t size() const { return Stream.tell(); }
+
+private:
+ llvm::SmallVector<char, 256> Buffer;
+ llvm::raw_svector_ostream Stream;
+ llvm::support::endian::Writer<llvm::support::endianness::little> Writer;
+};
+}
+}
+
+#endif
--- /dev/null
+//===- TypeSymbolEmitter.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_TYPESYMBOLEMITTER_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPESYMBOLEMITTER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+
+namespace llvm {
+namespace codeview {
+
+class TypeSymbolEmitter {
+private:
+ TypeSymbolEmitter(const TypeSymbolEmitter &) = delete;
+ TypeSymbolEmitter &operator=(const TypeSymbolEmitter &) = delete;
+
+protected:
+ TypeSymbolEmitter() {}
+
+public:
+ virtual ~TypeSymbolEmitter() {}
+
+public:
+ virtual void writeUserDefinedType(TypeIndex TI, StringRef Name) = 0;
+};
+}
+}
+
+#endif
--- /dev/null
+//===- TypeTableBuilder.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_TYPETABLEBUILDER_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPETABLEBUILDER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+namespace codeview {
+
+class FieldListRecordBuilder;
+class MethodListRecordBuilder;
+class TypeRecordBuilder;
+
+class TypeTableBuilder {
+private:
+ TypeTableBuilder(const TypeTableBuilder &) = delete;
+ TypeTableBuilder &operator=(const TypeTableBuilder &) = delete;
+
+protected:
+ TypeTableBuilder();
+
+public:
+ virtual ~TypeTableBuilder();
+
+public:
+ TypeIndex writeModifier(const ModifierRecord &Record);
+ TypeIndex writeProcedure(const ProcedureRecord &Record);
+ TypeIndex writeMemberFunction(const MemberFunctionRecord &Record);
+ TypeIndex writeArgumentList(const ArgumentListRecord &Record);
+ TypeIndex writeRecord(TypeRecordBuilder &builder);
+ TypeIndex writePointer(const PointerRecord &Record);
+ TypeIndex writePointerToMember(const PointerToMemberRecord &Record);
+ TypeIndex writeArray(const ArrayRecord &Record);
+ TypeIndex writeAggregate(const AggregateRecord &Record);
+ TypeIndex writeEnum(const EnumRecord &Record);
+ TypeIndex writeBitField(const BitFieldRecord &Record);
+ TypeIndex writeVirtualTableShape(const VirtualTableShapeRecord &Record);
+
+ TypeIndex writeFieldList(FieldListRecordBuilder &FieldList);
+ TypeIndex writeMethodList(MethodListRecordBuilder &MethodList);
+
+private:
+ virtual TypeIndex writeRecord(llvm::StringRef record) = 0;
+};
+}
+}
+
+#endif
+add_subdirectory(CodeView)
add_subdirectory(DWARF)
add_subdirectory(PDB)
add_subdirectory(Symbolize)
--- /dev/null
+add_llvm_library(LLVMCodeView
+ FieldListRecordBuilder.cpp
+ Line.cpp
+ ListRecordBuilder.cpp
+ MemoryTypeTableBuilder.cpp
+ MethodListRecordBuilder.cpp
+ TypeRecordBuilder.cpp
+ TypeTableBuilder.cpp
+ )
--- /dev/null
+//===-- FieldListRecordBuilder.cpp ----------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/FieldListRecordBuilder.h"
+
+using namespace llvm;
+using namespace codeview;
+
+FieldListRecordBuilder::FieldListRecordBuilder()
+ : ListRecordBuilder(TypeRecordKind::FieldList) {}
+
+void FieldListRecordBuilder::writeBaseClass(MemberAccess Access, TypeIndex Type,
+ uint64_t Offset) {
+ TypeRecordBuilder &Builder = getBuilder();
+
+ Builder.writeTypeRecordKind(TypeRecordKind::BaseClass);
+ Builder.writeUInt16(static_cast<uint16_t>(Access));
+ Builder.writeTypeIndex(Type);
+ Builder.writeEncodedUnsignedInteger(Offset);
+
+ finishSubRecord();
+}
+
+void FieldListRecordBuilder::writeEnumerate(MemberAccess Access, uint64_t Value,
+ StringRef Name) {
+ TypeRecordBuilder &Builder = getBuilder();
+
+ Builder.writeTypeRecordKind(TypeRecordKind::Enumerate);
+ Builder.writeUInt16(static_cast<uint16_t>(Access));
+ Builder.writeEncodedUnsignedInteger(Value);
+ Builder.writeNullTerminatedString(Name);
+
+ finishSubRecord();
+}
+
+void FieldListRecordBuilder::writeMember(MemberAccess Access, TypeIndex Type,
+ uint64_t Offset, StringRef Name) {
+ TypeRecordBuilder &Builder = getBuilder();
+
+ Builder.writeTypeRecordKind(TypeRecordKind::Member);
+ Builder.writeUInt16(static_cast<uint16_t>(Access));
+ Builder.writeTypeIndex(Type);
+ Builder.writeEncodedUnsignedInteger(Offset);
+ Builder.writeNullTerminatedString(Name);
+
+ finishSubRecord();
+}
+
+void FieldListRecordBuilder::writeMethod(uint16_t OverloadCount,
+ TypeIndex MethodList, StringRef Name) {
+ TypeRecordBuilder &Builder = getBuilder();
+
+ Builder.writeTypeRecordKind(TypeRecordKind::Method);
+ Builder.writeUInt16(OverloadCount);
+ Builder.writeTypeIndex(MethodList);
+ Builder.writeNullTerminatedString(Name);
+
+ finishSubRecord();
+}
+
+void FieldListRecordBuilder::writeOneMethod(
+ MemberAccess Access, MethodKind Kind, MethodOptions Options, TypeIndex Type,
+ int32_t VTableSlotOffset, StringRef Name) {
+ TypeRecordBuilder &Builder = getBuilder();
+
+ uint16_t Flags = static_cast<uint16_t>(Access);
+ Flags |= static_cast<uint16_t>(Kind) << MethodKindShift;
+ Flags |= static_cast<uint16_t>(Options);
+
+ Builder.writeTypeRecordKind(TypeRecordKind::OneMethod);
+ Builder.writeUInt16(Flags);
+ Builder.writeTypeIndex(Type);
+ switch (Kind) {
+ case MethodKind::IntroducingVirtual:
+ case MethodKind::PureIntroducingVirtual:
+ assert(VTableSlotOffset >= 0);
+ Builder.writeInt32(VTableSlotOffset);
+ break;
+
+ default:
+ assert(VTableSlotOffset == -1);
+ break;
+ }
+
+ Builder.writeNullTerminatedString(Name);
+
+ finishSubRecord();
+}
+
+void FieldListRecordBuilder::writeOneMethod(const MethodInfo &Method,
+ StringRef Name) {
+ writeOneMethod(Method.getAccess(), Method.getKind(), Method.getOptions(),
+ Method.getType(), Method.getVTableSlotOffset(), Name);
+}
+
+void FieldListRecordBuilder::writeNestedType(TypeIndex Type, StringRef Name) {
+ TypeRecordBuilder &Builder = getBuilder();
+
+ Builder.writeTypeRecordKind(TypeRecordKind::NestedType);
+ Builder.writeUInt16(0);
+ Builder.writeTypeIndex(Type);
+ Builder.writeNullTerminatedString(Name);
+
+ finishSubRecord();
+}
+
+void FieldListRecordBuilder::writeStaticMember(MemberAccess Access,
+ TypeIndex Type, StringRef Name) {
+ TypeRecordBuilder &Builder = getBuilder();
+
+ Builder.writeTypeRecordKind(TypeRecordKind::StaticMember);
+ Builder.writeUInt16(static_cast<uint16_t>(Access));
+ Builder.writeTypeIndex(Type);
+ Builder.writeNullTerminatedString(Name);
+
+ finishSubRecord();
+}
+
+void FieldListRecordBuilder::writeIndirectVirtualBaseClass(
+ MemberAccess Access, TypeIndex Type, TypeIndex VirtualBasePointerType,
+ int64_t VirtualBasePointerOffset, uint64_t SlotIndex) {
+ writeVirtualBaseClass(TypeRecordKind::IndirectVirtualBaseClass, Access, Type,
+ VirtualBasePointerType, VirtualBasePointerOffset,
+ SlotIndex);
+}
+
+void FieldListRecordBuilder::writeVirtualBaseClass(
+ MemberAccess Access, TypeIndex Type, TypeIndex VirtualBasePointerType,
+ int64_t VirtualBasePointerOffset, uint64_t SlotIndex) {
+ writeVirtualBaseClass(TypeRecordKind::VirtualBaseClass, Access, Type,
+ VirtualBasePointerType, VirtualBasePointerOffset,
+ SlotIndex);
+}
+
+void FieldListRecordBuilder::writeVirtualBaseClass(
+ TypeRecordKind Kind, MemberAccess Access, TypeIndex Type,
+ TypeIndex VirtualBasePointerType, int64_t VirtualBasePointerOffset,
+ uint64_t SlotIndex) {
+ TypeRecordBuilder &Builder = getBuilder();
+
+ Builder.writeTypeRecordKind(Kind);
+ Builder.writeUInt16(static_cast<uint16_t>(Access));
+ Builder.writeTypeIndex(Type);
+ Builder.writeTypeIndex(VirtualBasePointerType);
+ Builder.writeEncodedInteger(VirtualBasePointerOffset);
+ Builder.writeEncodedUnsignedInteger(SlotIndex);
+
+ finishSubRecord();
+}
+
+void FieldListRecordBuilder::writeVirtualFunctionTablePointer(TypeIndex Type) {
+ TypeRecordBuilder &Builder = getBuilder();
+
+ Builder.writeTypeRecordKind(TypeRecordKind::VirtualFunctionTablePointer);
+ Builder.writeUInt16(0);
+ Builder.writeTypeIndex(Type);
+
+ finishSubRecord();
+}
\ No newline at end of file
--- /dev/null
+;===- ./lib/CodeView/LLVMBuild.txt -------------------------------*- Conf -*--===;
+;
+; The LLVM Compiler Infrastructure
+;
+; This file is distributed under the University of Illinois Open Source
+; License. See LICENSE.TXT for details.
+;
+;===------------------------------------------------------------------------===;
+;
+; This is an LLVMBuild description file for the components in this subdirectory.
+;
+; For more information on the LLVMBuild system, please see:
+;
+; http://llvm.org/docs/LLVMBuild.html
+;
+;===------------------------------------------------------------------------===;
+
+[component_0]
+type = Library
+name = CodeView
+parent = Libraries
+required_libraries = Support
--- /dev/null
+//===-- Line.cpp ----------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/Line.h"
+
+using namespace llvm;
+using namespace codeview;
+
+LineInfo::LineInfo(uint32_t StartLine, uint32_t EndLine, bool IsStatement) {
+ LineData = StartLine & StartLineMask;
+ uint32_t LineDelta = EndLine - StartLine;
+ LineData |= (LineDelta << EndLineDeltaShift) & EndLineDeltaMask;
+ if (IsStatement) {
+ LineData |= StatementFlag;
+ }
+}
--- /dev/null
+//===-- ListRecordBuilder.cpp ---------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/ListRecordBuilder.h"
+
+using namespace llvm;
+using namespace codeview;
+
+ListRecordBuilder::ListRecordBuilder(TypeRecordKind Kind) : Builder(Kind) {}
+
+void ListRecordBuilder::finishSubRecord() {
+ // The builder starts at offset 2 in the actual CodeView buffer, so add an
+ // additional offset of 2 before computing the alignment.
+ uint32_t Remainder = (Builder.size() + 2) % 4;
+ if (Remainder != 0) {
+ for (int32_t PaddingBytesLeft = 4 - Remainder; PaddingBytesLeft > 0;
+ --PaddingBytesLeft) {
+ Builder.writeUInt8(0xf0 + PaddingBytesLeft);
+ }
+ }
+
+ // TODO: Split the list into multiple records if it's longer than 64KB, using
+ // a subrecord of TypeRecordKind::Index to chain the records together.
+ assert(Builder.size() < 65536);
+}
--- /dev/null
+//===-- MemoryTypeTableBuilder.cpp ----------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+
+using namespace llvm;
+using namespace codeview;
+
+MemoryTypeTableBuilder::Record::Record(StringRef RData)
+ : Size(RData.size()), Data(new char[RData.size()]) {
+ memcpy(Data.get(), RData.data(), RData.size());
+}
+
+TypeIndex MemoryTypeTableBuilder::writeRecord(StringRef Data) {
+ auto I = HashedRecords.find(Data);
+ if (I != HashedRecords.end()) {
+ return I->second;
+ }
+
+ std::unique_ptr<Record> R(new Record(Data));
+
+ TypeIndex TI(static_cast<uint32_t>(Records.size()) +
+ TypeIndex::FirstNonSimpleIndex);
+ HashedRecords.insert(std::make_pair(StringRef(R->data(), R->size()), TI));
+ Records.push_back(std::move(R));
+
+ return TI;
+}
--- /dev/null
+//===-- MethodListRecordBuilder.cpp ---------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/MethodListRecordBuilder.h"
+#include "llvm/DebugInfo/CodeView/FieldListRecordBuilder.h"
+
+using namespace llvm;
+using namespace codeview;
+
+MethodListRecordBuilder::MethodListRecordBuilder()
+ : ListRecordBuilder(TypeRecordKind::MethodList) {}
+
+void MethodListRecordBuilder::writeMethod(MemberAccess Access, MethodKind Kind,
+ MethodOptions Options, TypeIndex Type,
+ int32_t VTableSlotOffset) {
+ TypeRecordBuilder &Builder = getBuilder();
+
+ uint16_t Flags = static_cast<uint16_t>(Access);
+ Flags |= static_cast<uint16_t>(Kind) << MethodKindShift;
+ Flags |= static_cast<uint16_t>(Options);
+
+ Builder.writeUInt16(Flags);
+ Builder.writeUInt16(0);
+ Builder.writeTypeIndex(Type);
+ switch (Kind) {
+ case MethodKind::IntroducingVirtual:
+ case MethodKind::PureIntroducingVirtual:
+ assert(VTableSlotOffset >= 0);
+ Builder.writeInt32(VTableSlotOffset);
+ break;
+
+ default:
+ assert(VTableSlotOffset == -1);
+ break;
+ }
+
+ // TODO: Fail if too big?
+}
+
+void MethodListRecordBuilder::writeMethod(const MethodInfo &Method) {
+ writeMethod(Method.getAccess(), Method.getKind(), Method.getOptions(),
+ Method.getType(), Method.getVTableSlotOffset());
+}
--- /dev/null
+//===-- TypeRecordBuilder.cpp ---------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/TypeRecordBuilder.h"
+
+using namespace llvm;
+using namespace codeview;
+
+TypeRecordBuilder::TypeRecordBuilder(TypeRecordKind Kind) : Stream(Buffer),
+ Writer(Stream) {
+ writeTypeRecordKind(Kind);
+}
+
+StringRef TypeRecordBuilder::str() {
+ return StringRef(Buffer.data(), Buffer.size());
+}
+
+void TypeRecordBuilder::writeUInt8(uint8_t Value) {
+ Writer.write(Value);
+}
+
+void TypeRecordBuilder::writeInt16(int16_t Value) {
+ Writer.write(Value);
+}
+
+void TypeRecordBuilder::writeUInt16(uint16_t Value) {
+ Writer.write(Value);
+}
+
+void TypeRecordBuilder::writeInt32(int32_t Value) {
+ Writer.write(Value);
+}
+
+void TypeRecordBuilder::writeUInt32(uint32_t Value) {
+ Writer.write(Value);
+}
+
+void TypeRecordBuilder::writeInt64(int64_t Value) {
+ Writer.write(Value);
+}
+
+void TypeRecordBuilder::writeUInt64(uint64_t Value) {
+ Writer.write(Value);
+}
+
+void TypeRecordBuilder::writeEncodedInteger(int64_t Value) {
+ if (Value >= 0) {
+ writeEncodedUnsignedInteger(static_cast<uint64_t>(Value));
+ } else {
+ writeEncodedSignedInteger(Value);
+ }
+}
+
+void TypeRecordBuilder::writeEncodedSignedInteger(int64_t Value) {
+ if (Value >= std::numeric_limits<int8_t>::min() &&
+ Value <= std::numeric_limits<int8_t>::max()) {
+ writeUInt16(static_cast<uint16_t>(TypeRecordKind::SByte));
+ writeInt16(static_cast<int8_t>(Value));
+ } else if (Value >= std::numeric_limits<int16_t>::min() &&
+ Value <= std::numeric_limits<int16_t>::max()) {
+ writeUInt16(static_cast<uint16_t>(TypeRecordKind::Int16));
+ writeInt16(static_cast<int16_t>(Value));
+ } else if (Value >= std::numeric_limits<int32_t>::min() &&
+ Value <= std::numeric_limits<int32_t>::max()) {
+ writeUInt16(static_cast<uint32_t>(TypeRecordKind::Int32));
+ writeInt32(static_cast<int32_t>(Value));
+ } else {
+ writeUInt16(static_cast<uint16_t>(TypeRecordKind::Int64));
+ writeInt64(Value);
+ }
+}
+
+void TypeRecordBuilder::writeEncodedUnsignedInteger(uint64_t Value) {
+ if (Value < static_cast<uint16_t>(TypeRecordKind::SByte)) {
+ writeUInt16(static_cast<uint16_t>(Value));
+ } else if (Value <= std::numeric_limits<uint16_t>::max()) {
+ writeUInt16(static_cast<uint16_t>(TypeRecordKind::UInt16));
+ writeUInt16(static_cast<uint16_t>(Value));
+ } else if (Value <= std::numeric_limits<uint32_t>::max()) {
+ writeUInt16(static_cast<uint16_t>(TypeRecordKind::UInt32));
+ writeUInt32(static_cast<uint32_t>(Value));
+ } else {
+ writeUInt16(static_cast<uint16_t>(TypeRecordKind::UInt64));
+ writeUInt64(Value);
+ }
+}
+
+void TypeRecordBuilder::writeNullTerminatedString(const char *Value) {
+ assert(Value != nullptr);
+
+ size_t Length = strlen(Value);
+ Stream.write(Value, Length);
+ writeUInt8(0);
+}
+
+void TypeRecordBuilder::writeNullTerminatedString(StringRef Value) {
+ Stream.write(Value.data(), Value.size());
+ writeUInt8(0);
+}
+
+void TypeRecordBuilder::writeTypeIndex(TypeIndex TypeInd) {
+ writeUInt32(TypeInd.getIndex());
+}
+
+void TypeRecordBuilder::writeTypeRecordKind(TypeRecordKind Kind) {
+ writeUInt16(static_cast<uint16_t>(Kind));
+}
--- /dev/null
+//===-- TypeTableBuilder.cpp ----------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/DebugInfo/CodeView/FieldListRecordBuilder.h"
+#include "llvm/DebugInfo/CodeView/MethodListRecordBuilder.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecordBuilder.h"
+#include "llvm/support/raw_ostream.h"
+
+using namespace llvm;
+using namespace codeview;
+
+namespace {
+
+const uint32_t PointerKindMask = 0x0000001f;
+const int PointerKindShift = 0;
+const uint32_t PointerModeMask = 0x000000e0;
+const int PointerModeShift = 5;
+const uint32_t PointerSizeMask = 0x0007e000;
+const int PointerSizeShift = 13;
+const uint32_t PointerOptionsMask = 0x00081f00;
+
+const int ClassHfaKindShift = 11;
+const int ClassWindowsRTClassKindShift = 14;
+
+void writePointerBase(TypeRecordBuilder &Builder,
+ const PointerRecordBase &Record) {
+ Builder.writeTypeIndex(Record.getReferentType());
+ uint32_t flags =
+ static_cast<uint32_t>(Record.getOptions()) |
+ (Record.getSize() << PointerSizeShift) |
+ (static_cast<uint32_t>(Record.getMode()) << PointerModeShift) |
+ (static_cast<uint32_t>(Record.getPointerKind()) << PointerKindShift);
+ Builder.writeUInt32(flags);
+}
+}
+
+TypeTableBuilder::TypeTableBuilder() {}
+
+TypeTableBuilder::~TypeTableBuilder() {}
+
+TypeIndex TypeTableBuilder::writeModifier(const ModifierRecord &Record) {
+ TypeRecordBuilder Builder(TypeRecordKind::Modifier);
+
+ Builder.writeTypeIndex(Record.getModifiedType());
+ Builder.writeUInt16(static_cast<uint16_t>(Record.getOptions()));
+
+ return writeRecord(Builder);
+}
+
+TypeIndex TypeTableBuilder::writeProcedure(const ProcedureRecord &Record) {
+ TypeRecordBuilder Builder(TypeRecordKind::Procedure);
+
+ Builder.writeTypeIndex(Record.getReturnType());
+ Builder.writeUInt8(static_cast<uint8_t>(Record.getCallConv()));
+ Builder.writeUInt8(static_cast<uint8_t>(Record.getOptions()));
+ Builder.writeUInt16(Record.getParameterCount());
+ Builder.writeTypeIndex(Record.getArgumentList());
+
+ return writeRecord(Builder);
+}
+
+TypeIndex
+TypeTableBuilder::writeMemberFunction(const MemberFunctionRecord &Record) {
+ TypeRecordBuilder Builder(TypeRecordKind::MemberFunction);
+
+ Builder.writeTypeIndex(Record.getReturnType());
+ Builder.writeTypeIndex(Record.getClassType());
+ Builder.writeTypeIndex(Record.getThisType());
+ Builder.writeUInt8(static_cast<uint8_t>(Record.getCallConv()));
+ Builder.writeUInt8(static_cast<uint8_t>(Record.getOptions()));
+ Builder.writeUInt16(Record.getParameterCount());
+ Builder.writeTypeIndex(Record.getArgumentList());
+ Builder.writeInt32(Record.getThisPointerAdjustment());
+
+ return writeRecord(Builder);
+}
+
+TypeIndex
+TypeTableBuilder::writeArgumentList(const ArgumentListRecord &Record) {
+ TypeRecordBuilder Builder(TypeRecordKind::ArgumentList);
+
+ Builder.writeUInt32(Record.getArgumentTypes().size());
+ for (TypeIndex TI : Record.getArgumentTypes()) {
+ Builder.writeTypeIndex(TI);
+ }
+
+ return writeRecord(Builder);
+}
+
+TypeIndex TypeTableBuilder::writePointer(const PointerRecord &Record) {
+ TypeRecordBuilder Builder(TypeRecordKind::Pointer);
+
+ writePointerBase(Builder, Record);
+
+ return writeRecord(Builder);
+}
+
+TypeIndex
+TypeTableBuilder::writePointerToMember(const PointerToMemberRecord &Record) {
+ TypeRecordBuilder Builder(TypeRecordKind::Pointer);
+
+ writePointerBase(Builder, Record);
+
+ Builder.writeTypeIndex(Record.getContainingType());
+ Builder.writeUInt16(static_cast<uint16_t>(Record.getRepresentation()));
+
+ return writeRecord(Builder);
+}
+
+TypeIndex TypeTableBuilder::writeArray(const ArrayRecord &Record) {
+ TypeRecordBuilder Builder(TypeRecordKind::Array);
+
+ Builder.writeTypeIndex(Record.getElementType());
+ Builder.writeTypeIndex(Record.getIndexType());
+ Builder.writeEncodedUnsignedInteger(Record.getSize());
+ Builder.writeNullTerminatedString(Record.getName());
+
+ return writeRecord(Builder);
+}
+
+TypeIndex TypeTableBuilder::writeAggregate(const AggregateRecord &Record) {
+ assert((Record.getKind() == TypeRecordKind::Structure) ||
+ (Record.getKind() == TypeRecordKind::Class) ||
+ (Record.getKind() == TypeRecordKind::Union));
+
+ TypeRecordBuilder Builder(Record.getKind());
+
+ Builder.writeUInt16(Record.getMemberCount());
+ uint16_t Flags =
+ static_cast<uint16_t>(Record.getOptions()) |
+ (static_cast<uint16_t>(Record.getHfa()) << ClassHfaKindShift) |
+ (static_cast<uint16_t>(Record.getWinRTKind())
+ << ClassWindowsRTClassKindShift);
+ Builder.writeUInt16(Flags);
+ Builder.writeTypeIndex(Record.getFieldList());
+ if (Record.getKind() != TypeRecordKind::Union) {
+ Builder.writeTypeIndex(Record.getDerivationList());
+ Builder.writeTypeIndex(Record.getVTableShape());
+ } else {
+ assert(Record.getDerivationList() == TypeIndex());
+ assert(Record.getVTableShape() == TypeIndex());
+ }
+ Builder.writeEncodedUnsignedInteger(Record.getSize());
+ Builder.writeNullTerminatedString(Record.getName());
+ if ((Record.getOptions() & ClassOptions::HasUniqueName) !=
+ ClassOptions::None) {
+ Builder.writeNullTerminatedString(Record.getUniqueName());
+ }
+
+ return writeRecord(Builder);
+}
+
+TypeIndex TypeTableBuilder::writeEnum(const EnumRecord &Record) {
+ TypeRecordBuilder Builder(TypeRecordKind::Enum);
+
+ Builder.writeUInt16(Record.getMemberCount());
+ Builder.writeUInt16(static_cast<uint16_t>(Record.getOptions()));
+ Builder.writeTypeIndex(Record.getUnderlyingType());
+ Builder.writeTypeIndex(Record.getFieldList());
+ Builder.writeNullTerminatedString(Record.getName());
+ if ((Record.getOptions() & ClassOptions::HasUniqueName) !=
+ ClassOptions::None) {
+ Builder.writeNullTerminatedString(Record.getUniqueName());
+ }
+
+ return writeRecord(Builder);
+}
+
+TypeIndex TypeTableBuilder::writeBitField(const BitFieldRecord &Record) {
+ TypeRecordBuilder Builder(TypeRecordKind::BitField);
+
+ Builder.writeTypeIndex(Record.getType());
+ Builder.writeUInt8(Record.getBitSize());
+ Builder.writeUInt8(Record.getBitOffset());
+
+ return writeRecord(Builder);
+}
+
+TypeIndex TypeTableBuilder::writeVirtualTableShape(
+ const VirtualTableShapeRecord &Record) {
+ TypeRecordBuilder Builder(TypeRecordKind::VirtualTableShape);
+
+ ArrayRef<VirtualTableSlotKind> Slots = Record.getSlots();
+
+ Builder.writeUInt16(Slots.size());
+ for (size_t SlotIndex = 0; SlotIndex < Slots.size(); SlotIndex += 2) {
+ uint8_t Byte = static_cast<uint8_t>(Slots[SlotIndex]) << 4;
+ if ((SlotIndex + 1) < Slots.size()) {
+ Byte |= static_cast<uint8_t>(Slots[SlotIndex + 1]);
+ }
+ Builder.writeUInt8(Byte);
+ }
+
+ return writeRecord(Builder);
+}
+
+TypeIndex TypeTableBuilder::writeRecord(TypeRecordBuilder &Builder) {
+ return writeRecord(Builder.str());
+}
+
+TypeIndex TypeTableBuilder::writeFieldList(FieldListRecordBuilder &FieldList) {
+ // TODO: Split the list into multiple records if it's longer than 64KB, using
+ // a subrecord of TypeRecordKind::Index to chain the records together.
+ return writeRecord(FieldList.str());
+}
+
+TypeIndex
+TypeTableBuilder::writeMethodList(MethodListRecordBuilder &MethodList) {
+ // TODO: Split the list into multiple records if it's longer than 64KB, using
+ // a subrecord of TypeRecordKind::Index to chain the records together.
+ return writeRecord(MethodList.str());
+}
;===------------------------------------------------------------------------===;
[common]
-subdirectories = DWARF PDB Symbolize
+subdirectories = CodeView DWARF PDB Symbolize
[component_0]
type = Group
include $(LEVEL)/Makefile.config
-PARALLEL_DIRS := DWARF PDB Symbolize
+PARALLEL_DIRS := CodeView DWARF PDB Symbolize
include $(LEVEL)/Makefile.common