]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
Merge llvm, clang, lld and lldb trunk r291476.
[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/DebugInfo/MSF/ByteStream.h"
20 #include "llvm/DebugInfo/MSF/StreamReader.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), Reader(Stream), Mapping(Reader) {}
33
34     msf::ByteStream Stream;
35     msf::StreamReader Reader;
36     TypeRecordMapping Mapping;
37   };
38
39 public:
40   TypeDeserializer() = default;
41
42   Error visitTypeBegin(CVType &Record) override {
43     assert(!Mapping && "Already in a type mapping!");
44     Mapping = llvm::make_unique<MappingInfo>(Record.content());
45     return Mapping->Mapping.visitTypeBegin(Record);
46   }
47
48   Error visitTypeEnd(CVType &Record) override {
49     assert(Mapping && "Not in a type mapping!");
50     auto EC = Mapping->Mapping.visitTypeEnd(Record);
51     Mapping.reset();
52     return EC;
53   }
54
55 #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
56   Error visitKnownRecord(CVType &CVR, Name##Record &Record) override {         \
57     return visitKnownRecordImpl<Name##Record>(CVR, Record);                    \
58   }
59 #define MEMBER_RECORD(EnumName, EnumVal, Name)
60 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
61 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
62 #include "TypeRecords.def"
63
64 private:
65   template <typename RecordType>
66   Error visitKnownRecordImpl(CVType &CVR, RecordType &Record) {
67     return Mapping->Mapping.visitKnownRecord(CVR, Record);
68   }
69
70   std::unique_ptr<MappingInfo> Mapping;
71 };
72
73 class FieldListDeserializer : public TypeVisitorCallbacks {
74   struct MappingInfo {
75     explicit MappingInfo(msf::StreamReader &R)
76         : Reader(R), Mapping(Reader), StartOffset(0) {}
77
78     msf::StreamReader &Reader;
79     TypeRecordMapping Mapping;
80     uint32_t StartOffset;
81   };
82
83 public:
84   explicit FieldListDeserializer(msf::StreamReader &Reader) : Mapping(Reader) {
85     CVType FieldList;
86     FieldList.Type = TypeLeafKind::LF_FIELDLIST;
87     consumeError(Mapping.Mapping.visitTypeBegin(FieldList));
88   }
89
90   ~FieldListDeserializer() override {
91     CVType FieldList;
92     FieldList.Type = TypeLeafKind::LF_FIELDLIST;
93     consumeError(Mapping.Mapping.visitTypeEnd(FieldList));
94   }
95
96   Error visitMemberBegin(CVMemberRecord &Record) override {
97     Mapping.StartOffset = Mapping.Reader.getOffset();
98     return Mapping.Mapping.visitMemberBegin(Record);
99   }
100
101   Error visitMemberEnd(CVMemberRecord &Record) override {
102     if (auto EC = Mapping.Mapping.visitMemberEnd(Record))
103       return EC;
104     return Error::success();
105   }
106
107 #define TYPE_RECORD(EnumName, EnumVal, Name)
108 #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
109   Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \
110     return visitKnownMemberImpl<Name##Record>(CVR, Record);                    \
111   }
112 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
113 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
114 #include "TypeRecords.def"
115
116 private:
117   template <typename RecordType>
118   Error visitKnownMemberImpl(CVMemberRecord &CVR, RecordType &Record) {
119     if (auto EC = Mapping.Mapping.visitKnownMember(CVR, Record))
120       return EC;
121
122     uint32_t EndOffset = Mapping.Reader.getOffset();
123     uint32_t RecordLength = EndOffset - Mapping.StartOffset;
124     Mapping.Reader.setOffset(Mapping.StartOffset);
125     if (auto EC = Mapping.Reader.readBytes(CVR.Data, RecordLength))
126       return EC;
127     assert(Mapping.Reader.getOffset() == EndOffset);
128     return Error::success();
129   }
130   MappingInfo Mapping;
131 };
132
133 } // end namespace codeview
134 } // end namespace llvm
135
136 #endif // LLVM_DEBUGINFO_CODEVIEW_TYPEDESERIALIZER_H