17 using namespace llvm::codeview;
19 bool TypeSerializer::isInFieldList()
const {
23 TypeIndex TypeSerializer::calcNextTypeIndex()
const {
30 TypeIndex TypeSerializer::incrementTypeIndex() {
32 LastTypeIndex = calcNextTypeIndex();
38 return getCurrentRecordData().
drop_front(CurrentSegment.length());
56 assert(Record.
size() % 4 == 0 &&
"Record is not aligned to 4 bytes!");
60 TypeIndex NextTypeIndex = calcNextTypeIndex();
61 auto Result = HashedRecords.try_emplace(S, NextTypeIndex);
63 LastTypeIndex = NextTypeIndex;
66 return Result.first->getValue();
75 int PaddingBytes = 4 - Align;
77 while (PaddingBytes > 0) {
78 uint8_t Pad =
static_cast<uint8_t
>(LF_PAD0 + PaddingBytes);
87 : RecordStorage(Storage), LastTypeIndex(),
88 RecordBuffer(
MaxRecordLength * 2), Stream(RecordBuffer), Writer(Stream),
105 return insertRecordBytesPrivate(Record);
112 if (
auto EC = writeRecordPrefix(Record.
kind()))
125 return std::move(
EC);
129 auto ThisRecordData = getCurrentRecordData();
130 auto ExpectedData = addPadding(ThisRecordData);
132 return ExpectedData.takeError();
133 ThisRecordData = *ExpectedData;
136 reinterpret_cast<RecordPrefix *
>(ThisRecordData.data());
137 Prefix->
RecordLen = ThisRecordData.size() -
sizeof(uint16_t);
139 uint8_t *
Copy = RecordStorage.
Allocate<uint8_t>(ThisRecordData.size());
140 ::memcpy(Copy, ThisRecordData.data(), ThisRecordData.size());
143 TypeIndex InsertedTypeIndex = insertRecordBytesPrivate(ThisRecordData);
147 for (
auto X :
reverse(FieldListSegments)) {
148 auto CIBytes =
X.take_back(
sizeof(
uint32_t));
151 assert(*CI == 0xB0C0B0C0 &&
"Invalid TypeIndex placeholder");
153 InsertedTypeIndex = insertRecordBytesPrivate(
X);
158 FieldListSegments.
clear();
159 CurrentSegment.SubRecords.clear();
161 return InsertedTypeIndex;
167 return ExpectedIndex.takeError();
172 assert(isInFieldList() &&
"Not in a field list!");
174 MemberKind = Record.
Kind;
191 SubRecord LastSubRecord = CurrentSegment.SubRecords.back();
192 uint32_t CopySize = CurrentSegment.length() - LastSubRecord.Size;
194 auto LeftOverData = Data.
drop_front(CopySize);
195 assert(LastSubRecord.Size == LeftOverData.size());
199 uint16_t LengthWithSize = CopySize + ContinuationLength;
202 Prefix->
RecordLen = LengthWithSize -
sizeof(uint16_t);
204 uint8_t *SegmentBytes = RecordStorage.
Allocate<uint8_t>(LengthWithSize);
210 if (
auto EC = CW.
writeEnum(TypeLeafKind::LF_INDEX))
216 FieldListSegments.
push_back(SavedSegment);
221 if (
auto EC = writeRecordPrefix(TypeLeafKind::LF_FIELDLIST))
229 LeftOverData.size());
233 CurrentSegment.SubRecords.clear();
234 CurrentSegment.SubRecords.push_back(LastSubRecord);
239 Record.
Data = getCurrentSubRecordData();
void push_back(const T &Elt)
void setOffset(uint32_t Off)
MutableArrayRef< T > take_front(size_t N=1) const
Return a copy of *this with only the first N elements.
TypeLeafKind
Duplicate copy of the above enum, but using the official CV names.
Error visitMemberBegin(CVMemberRecord &Record) override
Error visitTypeEnd(CVType &Record) override
Error visitMemberEnd(CVMemberRecord &Record) override
Tagged union holding either a T or a Error.
Error visitTypeEnd(CVType &Record) override
CVRecord< TypeLeafKind > CVType
Error writeObject(const T &Obj)
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
ArrayRef< MutableArrayRef< uint8_t > > records() const
Error visitTypeBegin(CVType &Record) override
Paired begin/end actions for all types.
static const uint32_t FirstNonSimpleIndex
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
size_t size() const
size - Get the array size.
Error writeBytes(ArrayRef< uint8_t > Buffer)
uint32_t getIndex() const
Error visitTypeBegin(CVType &Record) override
Paired begin/end actions for all types.
Allocate memory in an ever growing pool, as if by bump-pointer.
LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * Allocate(size_t Size, size_t Alignment)
Allocate space at the specified alignment.
TypeIndex insertRecordBytes(MutableArrayRef< uint8_t > Record)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
MutableArrayRef< uint8_t > data() const
Error writeInteger(uint8_t Int)
static ErrorSuccess success()
Create a success value.
TypeIndex getLastTypeIndex() const
uint32_t getOffset() const
MutableArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
Error visitMemberEnd(CVMemberRecord &Record) override
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Lightweight error class with error context and mandatory checking.
StringRef - Represent a constant reference to a string, i.e.
Error visitMemberBegin(CVMemberRecord &Record) override
TypeSerializer(BumpPtrAllocator &Storage)
Expected< TypeIndex > visitTypeEndGetIndex(CVType &Record)