]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
Merge ^/head r317808 through r317970.
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / DebugInfo / CodeView / TypeDeserializer.h
1 //===- TypeDeserializer.h ---------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEDESERIALIZER_H
11 #define LLVM_DEBUGINFO_CODEVIEW_TYPEDESERIALIZER_H
12
13 #include "llvm/ADT/ArrayRef.h"
14 #include "llvm/ADT/STLExtras.h"
15 #include "llvm/DebugInfo/CodeView/CodeView.h"
16 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
17 #include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
18 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
19 #include "llvm/Support/BinaryByteStream.h"
20 #include "llvm/Support/BinaryStreamReader.h"
21 #include "llvm/Support/Error.h"
22 #include <cassert>
23 #include <cstdint>
24 #include <memory>
25
26 namespace llvm {
27 namespace codeview {
28
29 class TypeDeserializer : public TypeVisitorCallbacks {
30   struct MappingInfo {
31     explicit MappingInfo(ArrayRef<uint8_t> RecordData)
32         : Stream(RecordData, llvm::support::little), Reader(Stream),
33           Mapping(Reader) {}
34
35     BinaryByteStream Stream;
36     BinaryStreamReader Reader;
37     TypeRecordMapping Mapping;
38   };
39
40 public:
41   TypeDeserializer() = default;
42
43   Error visitTypeBegin(CVType &Record) override {
44     assert(!Mapping && "Already in a type mapping!");
45     Mapping = llvm::make_unique<MappingInfo>(Record.content());
46     return Mapping->Mapping.visitTypeBegin(Record);
47   }
48
49   Error visitTypeEnd(CVType &Record) override {
50     assert(Mapping && "Not in a type mapping!");
51     auto EC = Mapping->Mapping.visitTypeEnd(Record);
52     Mapping.reset();
53     return EC;
54   }
55
56 #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
57   Error visitKnownRecord(CVType &CVR, Name##Record &Record) override {         \
58     return visitKnownRecordImpl<Name##Record>(CVR, Record);                    \
59   }
60 #define MEMBER_RECORD(EnumName, EnumVal, Name)
61 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
62 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
63 #include "TypeRecords.def"
64
65 private:
66   template <typename RecordType>
67   Error visitKnownRecordImpl(CVType &CVR, RecordType &Record) {
68     return Mapping->Mapping.visitKnownRecord(CVR, Record);
69   }
70
71   std::unique_ptr<MappingInfo> Mapping;
72 };
73
74 class FieldListDeserializer : public TypeVisitorCallbacks {
75   struct MappingInfo {
76     explicit MappingInfo(BinaryStreamReader &R)
77         : Reader(R), Mapping(Reader), StartOffset(0) {}
78
79     BinaryStreamReader &Reader;
80     TypeRecordMapping Mapping;
81     uint32_t StartOffset;
82   };
83
84 public:
85   explicit FieldListDeserializer(BinaryStreamReader &Reader) : Mapping(Reader) {
86     CVType FieldList;
87     FieldList.Type = TypeLeafKind::LF_FIELDLIST;
88     consumeError(Mapping.Mapping.visitTypeBegin(FieldList));
89   }
90
91   ~FieldListDeserializer() override {
92     CVType FieldList;
93     FieldList.Type = TypeLeafKind::LF_FIELDLIST;
94     consumeError(Mapping.Mapping.visitTypeEnd(FieldList));
95   }
96
97   Error visitMemberBegin(CVMemberRecord &Record) override {
98     Mapping.StartOffset = Mapping.Reader.getOffset();
99     return Mapping.Mapping.visitMemberBegin(Record);
100   }
101
102   Error visitMemberEnd(CVMemberRecord &Record) override {
103     if (auto EC = Mapping.Mapping.visitMemberEnd(Record))
104       return EC;
105     return Error::success();
106   }
107
108 #define TYPE_RECORD(EnumName, EnumVal, Name)
109 #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
110   Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \
111     return visitKnownMemberImpl<Name##Record>(CVR, Record);                    \
112   }
113 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
114 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
115 #include "TypeRecords.def"
116
117 private:
118   template <typename RecordType>
119   Error visitKnownMemberImpl(CVMemberRecord &CVR, RecordType &Record) {
120     if (auto EC = Mapping.Mapping.visitKnownMember(CVR, Record))
121       return EC;
122
123     uint32_t EndOffset = Mapping.Reader.getOffset();
124     uint32_t RecordLength = EndOffset - Mapping.StartOffset;
125     Mapping.Reader.setOffset(Mapping.StartOffset);
126     if (auto EC = Mapping.Reader.readBytes(CVR.Data, RecordLength))
127       return EC;
128     assert(Mapping.Reader.getOffset() == EndOffset);
129     return Error::success();
130   }
131   MappingInfo Mapping;
132 };
133
134 } // end namespace codeview
135 } // end namespace llvm
136
137 #endif // LLVM_DEBUGINFO_CODEVIEW_TYPEDESERIALIZER_H