Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit 27775cd

Browse files
committed
[codeview] Remove Type member from CVRecord
Summary: Now CVType and CVSymbol are effectively type-safe wrappers around ArrayRef<uint8_t>. Make the kind() accessor load it from the RecordPrefix, which is the same for types and symbols. Reviewers: zturner, aganea Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D60018 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357658 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent c89c280 commit 27775cd

21 files changed

+73
-96
lines changed

include/llvm/DebugInfo/CodeView/CVRecord.h

+20-9
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,31 @@ namespace llvm {
2424

2525
namespace codeview {
2626

27+
/// CVRecord is a fat pointer (base + size pair) to a symbol or type record.
28+
/// Carrying the size separately instead of trusting the size stored in the
29+
/// record prefix provides some extra safety and flexibility.
2730
template <typename Kind> class CVRecord {
2831
public:
29-
CVRecord() : Type(static_cast<Kind>(0)) {}
32+
CVRecord() = default;
3033

31-
CVRecord(Kind K, ArrayRef<uint8_t> Data) : Type(K), RecordData(Data) {}
34+
CVRecord(ArrayRef<uint8_t> Data) : RecordData(Data) {}
3235

33-
bool valid() const { return Type != static_cast<Kind>(0); }
36+
CVRecord(const RecordPrefix *P, size_t Size)
37+
: RecordData(reinterpret_cast<const uint8_t *>(P), Size) {}
38+
39+
bool valid() const { return kind() != Kind(0); }
3440

3541
uint32_t length() const { return RecordData.size(); }
36-
Kind kind() const { return Type; }
42+
43+
Kind kind() const {
44+
if (RecordData.size() < sizeof(RecordPrefix))
45+
return Kind(0);
46+
return static_cast<Kind>(static_cast<uint16_t>(
47+
reinterpret_cast<const RecordPrefix *>(RecordData.data())->RecordKind));
48+
}
49+
3750
ArrayRef<uint8_t> data() const { return RecordData; }
51+
3852
StringRef str_data() const {
3953
return StringRef(reinterpret_cast<const char *>(RecordData.data()),
4054
RecordData.size());
@@ -44,7 +58,6 @@ template <typename Kind> class CVRecord {
4458
return RecordData.drop_front(sizeof(RecordPrefix));
4559
}
4660

47-
Kind Type;
4861
ArrayRef<uint8_t> RecordData;
4962
};
5063

@@ -71,8 +84,7 @@ Error forEachCodeViewRecord(ArrayRef<uint8_t> StreamBuffer, Func F) {
7184
ArrayRef<uint8_t> Data = StreamBuffer.take_front(RealLen);
7285
StreamBuffer = StreamBuffer.drop_front(RealLen);
7386

74-
Record R(static_cast<decltype(Record::Type)>((uint16_t)Prefix->RecordKind),
75-
Data);
87+
Record R(Data);
7688
if (auto EC = F(R))
7789
return EC;
7890
}
@@ -91,13 +103,12 @@ inline Expected<CVRecord<Kind>> readCVRecordFromStream(BinaryStreamRef Stream,
91103
return std::move(EC);
92104
if (Prefix->RecordLen < 2)
93105
return make_error<CodeViewError>(cv_error_code::corrupt_record);
94-
Kind K = static_cast<Kind>(uint16_t(Prefix->RecordKind));
95106

96107
Reader.setOffset(Offset);
97108
ArrayRef<uint8_t> RawData;
98109
if (auto EC = Reader.readBytes(RawData, Prefix->RecordLen + sizeof(uint16_t)))
99110
return std::move(EC);
100-
return codeview::CVRecord<Kind>(K, RawData);
111+
return codeview::CVRecord<Kind>(RawData);
101112
}
102113

103114
} // end namespace codeview

include/llvm/DebugInfo/CodeView/RecordSerialization.h

+3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ using llvm::support::ulittle32_t;
3131
enum : unsigned { MaxRecordLength = 0xFF00 };
3232

3333
struct RecordPrefix {
34+
RecordPrefix() = default;
35+
explicit RecordPrefix(uint16_t Kind) : RecordLen(2), RecordKind(Kind) {}
36+
3437
ulittle16_t RecordLen; // Record length, starting from &RecordKind.
3538
ulittle16_t RecordKind; // Record kind enum (SymRecordKind or TypeRecordKind)
3639
};

include/llvm/DebugInfo/CodeView/SymbolSerializer.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ class SymbolSerializer : public SymbolVisitorCallbacks {
5151
template <typename SymType>
5252
static CVSymbol writeOneSymbol(SymType &Sym, BumpPtrAllocator &Storage,
5353
CodeViewContainer Container) {
54-
CVSymbol Result;
55-
Result.Type = static_cast<SymbolKind>(Sym.Kind);
54+
RecordPrefix Prefix{uint16_t(Sym.Kind)};
55+
CVSymbol Result(&Prefix, sizeof(Prefix));
5656
SymbolSerializer Serializer(Storage, Container);
5757
consumeError(Serializer.visitSymbolBegin(Result));
5858
consumeError(Serializer.visitKnownRecord(Result, Sym));

include/llvm/DebugInfo/CodeView/TypeDeserializer.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class TypeDeserializer : public TypeVisitorCallbacks {
5858
TypeRecordKind K =
5959
static_cast<TypeRecordKind>(uint16_t(Prefix->RecordKind));
6060
T Record(K);
61-
CVType CVT(static_cast<TypeLeafKind>(K), Data);
61+
CVType CVT(Data);
6262
if (auto EC = deserializeAs<T>(CVT, Record))
6363
return std::move(EC);
6464
return Record;
@@ -111,14 +111,14 @@ class FieldListDeserializer : public TypeVisitorCallbacks {
111111

112112
public:
113113
explicit FieldListDeserializer(BinaryStreamReader &Reader) : Mapping(Reader) {
114-
CVType FieldList;
115-
FieldList.Type = TypeLeafKind::LF_FIELDLIST;
114+
RecordPrefix Pre(static_cast<uint16_t>(TypeLeafKind::LF_FIELDLIST));
115+
CVType FieldList(&Pre, sizeof(Pre));
116116
consumeError(Mapping.Mapping.visitTypeBegin(FieldList));
117117
}
118118

119119
~FieldListDeserializer() override {
120-
CVType FieldList;
121-
FieldList.Type = TypeLeafKind::LF_FIELDLIST;
120+
RecordPrefix Pre(static_cast<uint16_t>(TypeLeafKind::LF_FIELDLIST));
121+
CVType FieldList(&Pre, sizeof(Pre));
122122
consumeError(Mapping.Mapping.visitTypeEnd(FieldList));
123123
}
124124

lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp

+2-7
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,8 @@ Optional<TypeIndex> AppendingTypeTableBuilder::getNext(TypeIndex Prev) {
4949
return Prev;
5050
}
5151

52-
CVType AppendingTypeTableBuilder::getType(TypeIndex Index) {
53-
CVType Type;
54-
Type.RecordData = SeenRecords[Index.toArrayIndex()];
55-
const RecordPrefix *P =
56-
reinterpret_cast<const RecordPrefix *>(Type.RecordData.data());
57-
Type.Type = static_cast<TypeLeafKind>(uint16_t(P->RecordKind));
58-
return Type;
52+
CVType AppendingTypeTableBuilder::getType(TypeIndex Index){
53+
return CVType(SeenRecords[Index.toArrayIndex()]);
5954
}
6055

6156
StringRef AppendingTypeTableBuilder::getTypeName(TypeIndex Index) {

lib/DebugInfo/CodeView/CVSymbolVisitor.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ CVSymbolVisitor::CVSymbolVisitor(SymbolVisitorCallbacks &Callbacks)
2020
template <typename T>
2121
static Error visitKnownRecord(CVSymbol &Record,
2222
SymbolVisitorCallbacks &Callbacks) {
23-
SymbolRecordKind RK = static_cast<SymbolRecordKind>(Record.Type);
23+
SymbolRecordKind RK = static_cast<SymbolRecordKind>(Record.kind());
2424
T KnownRecord(RK);
2525
if (auto EC = Callbacks.visitKnownRecord(Record, KnownRecord))
2626
return EC;
@@ -29,7 +29,7 @@ static Error visitKnownRecord(CVSymbol &Record,
2929

3030
static Error finishVisitation(CVSymbol &Record,
3131
SymbolVisitorCallbacks &Callbacks) {
32-
switch (Record.Type) {
32+
switch (Record.kind()) {
3333
default:
3434
if (auto EC = Callbacks.visitUnknownSymbol(Record))
3535
return EC;

lib/DebugInfo/CodeView/CVTypeVisitor.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ using namespace llvm::codeview;
2222

2323
template <typename T>
2424
static Error visitKnownRecord(CVType &Record, TypeVisitorCallbacks &Callbacks) {
25-
TypeRecordKind RK = static_cast<TypeRecordKind>(Record.Type);
25+
TypeRecordKind RK = static_cast<TypeRecordKind>(Record.kind());
2626
T KnownRecord(RK);
2727
if (auto EC = Callbacks.visitKnownRecord(Record, KnownRecord))
2828
return EC;
@@ -96,7 +96,7 @@ CVTypeVisitor::CVTypeVisitor(TypeVisitorCallbacks &Callbacks)
9696
: Callbacks(Callbacks) {}
9797

9898
Error CVTypeVisitor::finishVisitation(CVType &Record) {
99-
switch (Record.Type) {
99+
switch (Record.kind()) {
100100
default:
101101
if (auto EC = Callbacks.visitUnknownType(Record))
102102
return EC;

lib/DebugInfo/CodeView/ContinuationRecordBuilder.cpp

+6-14
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,11 @@ void ContinuationRecordBuilder::begin(ContinuationRecordKind RecordKind) {
6666
InjectedSegmentBytes =
6767
ArrayRef<uint8_t>(FLIB, FLIB + sizeof(SegmentInjection));
6868

69-
CVType Type;
70-
Type.Type = getTypeLeafKind(RecordKind);
69+
// Seed the first record with an appropriate record prefix.
70+
RecordPrefix Prefix(getTypeLeafKind(RecordKind));
71+
CVType Type(&Prefix, sizeof(Prefix));
7172
cantFail(Mapping.visitTypeBegin(Type));
7273

73-
// Seed the first trecord with an appropriate record prefix.
74-
RecordPrefix Prefix;
75-
Prefix.RecordLen = 0;
76-
Prefix.RecordKind = Type.Type;
7774
cantFail(SegmentWriter.writeObject(Prefix));
7875
}
7976

@@ -156,14 +153,9 @@ CVType ContinuationRecordBuilder::createSegmentRecord(
156153
MutableArrayRef<uint8_t> Data = Buffer.data();
157154
Data = Data.slice(OffBegin, OffEnd - OffBegin);
158155

159-
CVType Type;
160-
Type.Type = getTypeLeafKind(*Kind);
161-
Type.RecordData = Data;
162-
163156
// Write the length to the RecordPrefix, making sure it does not include
164157
// sizeof(RecordPrefix.Length)
165158
RecordPrefix *Prefix = reinterpret_cast<RecordPrefix *>(Data.data());
166-
assert(Prefix->RecordKind == Type.Type);
167159
Prefix->RecordLen = Data.size() - sizeof(RecordPrefix::RecordLen);
168160

169161
if (RefersTo.hasValue()) {
@@ -175,12 +167,12 @@ CVType ContinuationRecordBuilder::createSegmentRecord(
175167
CR->IndexRef = RefersTo->getIndex();
176168
}
177169

178-
return Type;
170+
return CVType(Data);
179171
}
180172

181173
std::vector<CVType> ContinuationRecordBuilder::end(TypeIndex Index) {
182-
CVType Type;
183-
Type.Type = getTypeLeafKind(*Kind);
174+
RecordPrefix Prefix(getTypeLeafKind(*Kind));
175+
CVType Type(&Prefix, sizeof(Prefix));
184176
cantFail(Mapping.visitTypeEnd(Type));
185177

186178
// We're now done, and we have a series of segments each beginning at an

lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp

+1-8
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,7 @@ Optional<TypeIndex> GlobalTypeTableBuilder::getNext(TypeIndex Prev) {
5252
}
5353

5454
CVType GlobalTypeTableBuilder::getType(TypeIndex Index) {
55-
CVType Type;
56-
Type.RecordData = SeenRecords[Index.toArrayIndex()];
57-
if (!Type.RecordData.empty()) {
58-
assert(Type.RecordData.size() >= sizeof(RecordPrefix));
59-
const RecordPrefix *P =
60-
reinterpret_cast<const RecordPrefix *>(Type.RecordData.data());
61-
Type.Type = static_cast<TypeLeafKind>(uint16_t(P->RecordKind));
62-
}
55+
CVType Type(SeenRecords[Index.toArrayIndex()]);
6356
return Type;
6457
}
6558

lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp

+1-5
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,7 @@ Optional<TypeIndex> MergingTypeTableBuilder::getNext(TypeIndex Prev) {
5252
}
5353

5454
CVType MergingTypeTableBuilder::getType(TypeIndex Index) {
55-
CVType Type;
56-
Type.RecordData = SeenRecords[Index.toArrayIndex()];
57-
const RecordPrefix *P =
58-
reinterpret_cast<const RecordPrefix *>(Type.RecordData.data());
59-
Type.Type = static_cast<TypeLeafKind>(uint16_t(P->RecordKind));
55+
CVType Type(SeenRecords[Index.toArrayIndex()]);
6056
return Type;
6157
}
6258

lib/DebugInfo/CodeView/SimpleTypeSerializer.cpp

+6-12
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,6 @@
33
using namespace llvm;
44
using namespace llvm::codeview;
55

6-
static void writeRecordPrefix(BinaryStreamWriter &Writer, TypeLeafKind Kind) {
7-
RecordPrefix Prefix;
8-
Prefix.RecordKind = Kind;
9-
Prefix.RecordLen = 0;
10-
cantFail(Writer.writeObject(Prefix));
11-
}
12-
136
static void addPadding(BinaryStreamWriter &Writer) {
147
uint32_t Align = Writer.getOffset() % 4;
158
if (Align == 0)
@@ -32,19 +25,20 @@ ArrayRef<uint8_t> SimpleTypeSerializer::serialize(T &Record) {
3225
BinaryStreamWriter Writer(ScratchBuffer, support::little);
3326
TypeRecordMapping Mapping(Writer);
3427

35-
CVType CVT;
36-
CVT.Type = static_cast<TypeLeafKind>(Record.getKind());
28+
// Write the record prefix first with a dummy length but real kind.
29+
RecordPrefix DummyPrefix(uint16_t(Record.getKind()));
30+
cantFail(Writer.writeObject(DummyPrefix));
3731

38-
writeRecordPrefix(Writer, CVT.Type);
32+
RecordPrefix *Prefix = reinterpret_cast<RecordPrefix *>(ScratchBuffer.data());
33+
CVType CVT(Prefix, sizeof(RecordPrefix));
3934

4035
cantFail(Mapping.visitTypeBegin(CVT));
4136
cantFail(Mapping.visitKnownRecord(CVT, Record));
4237
cantFail(Mapping.visitTypeEnd(CVT));
4338

4439
addPadding(Writer);
4540

46-
RecordPrefix *Prefix = reinterpret_cast<RecordPrefix *>(ScratchBuffer.data());
47-
41+
// Update the size and kind after serialization.
4842
Prefix->RecordKind = CVT.kind();
4943
Prefix->RecordLen = Writer.getOffset() - sizeof(uint16_t);
5044

lib/DebugInfo/CodeView/SymbolDumper.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,10 @@ void CVSymbolDumperImpl::printTypeIndex(StringRef FieldName, TypeIndex TI) {
101101
}
102102

103103
Error CVSymbolDumperImpl::visitSymbolBegin(CVSymbol &CVR) {
104-
W.startLine() << getSymbolKindName(CVR.Type);
104+
W.startLine() << getSymbolKindName(CVR.kind());
105105
W.getOStream() << " {\n";
106106
W.indent();
107-
W.printEnum("Kind", unsigned(CVR.Type), getSymbolTypeNames());
107+
W.printEnum("Kind", unsigned(CVR.kind()), getSymbolTypeNames());
108108
return Error::success();
109109
}
110110

lib/DebugInfo/CodeView/TypeDumpVisitor.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,11 @@ Error TypeDumpVisitor::visitTypeBegin(CVType &Record) {
171171
}
172172

173173
Error TypeDumpVisitor::visitTypeBegin(CVType &Record, TypeIndex Index) {
174-
W->startLine() << getLeafTypeName(Record.Type);
174+
W->startLine() << getLeafTypeName(Record.kind());
175175
W->getOStream() << " (" << HexNumber(Index.getIndex()) << ")";
176176
W->getOStream() << " {\n";
177177
W->indent();
178-
W->printEnum("TypeLeafKind", unsigned(Record.Type),
178+
W->printEnum("TypeLeafKind", unsigned(Record.kind()),
179179
makeArrayRef(LeafTypeNames));
180180
return Error::success();
181181
}

lib/DebugInfo/CodeView/TypeRecordMapping.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,11 @@ Error TypeRecordMapping::visitTypeBegin(CVType &CVR) {
8888
// split with continuation records. All other record types cannot be
8989
// longer than the maximum record length.
9090
Optional<uint32_t> MaxLen;
91-
if (CVR.Type != TypeLeafKind::LF_FIELDLIST &&
92-
CVR.Type != TypeLeafKind::LF_METHODLIST)
91+
if (CVR.kind() != TypeLeafKind::LF_FIELDLIST &&
92+
CVR.kind() != TypeLeafKind::LF_METHODLIST)
9393
MaxLen = MaxRecordLength - sizeof(RecordPrefix);
9494
error(IO.beginRecord(MaxLen));
95-
TypeKind = CVR.Type;
95+
TypeKind = CVR.kind();
9696
return Error::success();
9797
}
9898

@@ -211,9 +211,9 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ArrayRecord &Record) {
211211
}
212212

213213
Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ClassRecord &Record) {
214-
assert((CVR.Type == TypeLeafKind::LF_STRUCTURE) ||
215-
(CVR.Type == TypeLeafKind::LF_CLASS) ||
216-
(CVR.Type == TypeLeafKind::LF_INTERFACE));
214+
assert((CVR.kind() == TypeLeafKind::LF_STRUCTURE) ||
215+
(CVR.kind() == TypeLeafKind::LF_CLASS) ||
216+
(CVR.kind() == TypeLeafKind::LF_INTERFACE));
217217

218218
error(IO.mapInteger(Record.MemberCount));
219219
error(IO.mapEnum(Record.Options));

lib/DebugInfo/CodeView/TypeTableCollection.cpp

+1-5
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,7 @@ Optional<TypeIndex> TypeTableCollection::getNext(TypeIndex Prev) {
3636

3737
CVType TypeTableCollection::getType(TypeIndex Index) {
3838
assert(Index.toArrayIndex() < Records.size());
39-
ArrayRef<uint8_t> Bytes = Records[Index.toArrayIndex()];
40-
const RecordPrefix *Prefix =
41-
reinterpret_cast<const RecordPrefix *>(Bytes.data());
42-
TypeLeafKind Kind = static_cast<TypeLeafKind>(uint16_t(Prefix->RecordKind));
43-
return CVType(Kind, Bytes);
39+
return CVType(Records[Index.toArrayIndex()]);
4440
}
4541

4642
StringRef TypeTableCollection::getTypeName(TypeIndex Index) {

lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ struct llvm::pdb::GSIHashStreamBuilder {
3636
return Empty;
3737
}
3838
static inline CVSymbol getTombstoneKey() {
39-
static CVSymbol Tombstone(static_cast<SymbolKind>(-1),
40-
ArrayRef<uint8_t>());
39+
static CVSymbol Tombstone(
40+
DenseMapInfo<ArrayRef<uint8_t>>::getTombstoneKey());
4141
return Tombstone;
4242
}
4343
static unsigned getHashValue(const CVSymbol &Val) {

lib/ObjectYAML/CodeViewYAMLSymbols.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ struct UnknownSymbolRecord : public SymbolRecordBase {
248248
uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen);
249249
::memcpy(Buffer, &Prefix, sizeof(RecordPrefix));
250250
::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size());
251-
return CVSymbol(Kind, ArrayRef<uint8_t>(Buffer, TotalLen));
251+
return CVSymbol(ArrayRef<uint8_t>(Buffer, TotalLen));
252252
}
253253

254254
Error fromCodeViewSymbol(CVSymbol CVS) override {

lib/ObjectYAML/CodeViewYAMLTypes.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ template <typename T> struct LeafRecordImpl : public LeafRecordBase {
9898

9999
CVType toCodeViewRecord(AppendingTypeTableBuilder &TS) const override {
100100
TS.writeLeafType(Record);
101-
return CVType(Kind, TS.records().back());
101+
return CVType(TS.records().back());
102102
}
103103

104104
mutable T Record;
@@ -496,7 +496,7 @@ CVType LeafRecordImpl<FieldListRecord>::toCodeViewRecord(
496496
Member.Member->writeTo(CRB);
497497
}
498498
TS.insertRecord(CRB);
499-
return CVType(Kind, TS.records().back());
499+
return CVType(TS.records().back());
500500
}
501501

502502
void MappingTraits<OneMethodRecord>::mapping(IO &io, OneMethodRecord &Record) {

0 commit comments

Comments
 (0)