#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
case EnumName: { \
SymbolRecordKind RK = static_cast<SymbolRecordKind>(EnumName); \
- auto Result = Name::deserialize(RK, RecordOffset, Data); \
- if (Result.getError()) \
+ auto ExpectedResult = Name::deserialize(RK, RecordOffset, Data); \
+ if (!ExpectedResult) { \
+ consumeError(ExpectedResult.takeError()); \
return parseError(); \
- DerivedThis->visit##Name(Record.Type, *Result); \
+ } \
+ DerivedThis->visit##Name(Record.Type, *ExpectedResult); \
break; \
}
#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Endian.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
#include <cinttypes>
#include <tuple>
/// there are not enough bytes remaining. Reinterprets the consumed bytes as a
/// T object and points 'Res' at them.
template <typename T, typename U>
-inline std::error_code consumeObject(U &Data, const T *&Res) {
+inline Error consumeObject(U &Data, const T *&Res) {
if (Data.size() < sizeof(*Res))
- return std::make_error_code(std::errc::illegal_byte_sequence);
+ return make_error<CodeViewError>(
+ cv_error_code::insufficient_buffer,
+ "Error consuming object. Not enough data for requested object size.");
Res = reinterpret_cast<const T *>(Data.data());
Data = Data.drop_front(sizeof(*Res));
- return std::error_code();
+ return Error::success();
}
-inline std::error_code consume(ArrayRef<uint8_t> &Data) {
- return std::error_code();
-}
+inline Error consume(ArrayRef<uint8_t> &Data) { return Error::success(); }
/// Decodes a numeric "leaf" value. These are integer literals encountered in
/// the type stream. If the value is positive and less than LF_NUMERIC (1 <<
/// 15), it is emitted directly in Data. Otherwise, it has a tag like LF_CHAR
/// that indicates the bitwidth and sign of the numeric data.
-std::error_code consume(ArrayRef<uint8_t> &Data, APSInt &Num);
-std::error_code consume(StringRef &Data, APSInt &Num);
+Error consume(ArrayRef<uint8_t> &Data, APSInt &Num);
+Error consume(StringRef &Data, APSInt &Num);
/// Decodes a numeric leaf value that is known to be a particular type.
-std::error_code consume_numeric(ArrayRef<uint8_t> &Data, uint64_t &Value);
+Error consume_numeric(ArrayRef<uint8_t> &Data, uint64_t &Value);
/// Decodes signed and unsigned fixed-length integers.
-std::error_code consume(ArrayRef<uint8_t> &Data, uint32_t &Item);
-std::error_code consume(StringRef &Data, uint32_t &Item);
-std::error_code consume(ArrayRef<uint8_t> &Data, int32_t &Item);
+Error consume(ArrayRef<uint8_t> &Data, uint32_t &Item);
+Error consume(StringRef &Data, uint32_t &Item);
+Error consume(ArrayRef<uint8_t> &Data, int32_t &Item);
/// Decodes a null terminated string.
-std::error_code consume(ArrayRef<uint8_t> &Data, StringRef &Item);
+Error consume(ArrayRef<uint8_t> &Data, StringRef &Item);
/// Decodes an arbitrary object whose layout matches that of the underlying
/// byte sequence, and returns a pointer to the object.
-template <typename T>
-std::error_code consume(ArrayRef<uint8_t> &Data, T *&Item) {
+template <typename T> Error consume(ArrayRef<uint8_t> &Data, T *&Item) {
return consumeObject(Data, Item);
}
template <typename T, typename U> struct serialize_conditional_impl {
serialize_conditional_impl(T &Item, U Func) : Item(Item), Func(Func) {}
- std::error_code deserialize(ArrayRef<uint8_t> &Data) const {
+ Error deserialize(ArrayRef<uint8_t> &Data) const {
if (!Func())
- return std::error_code();
+ return Error::success();
return consume(Data, Item);
}
template <typename T, typename U> struct serialize_array_impl {
serialize_array_impl(ArrayRef<T> &Item, U Func) : Item(Item), Func(Func) {}
- std::error_code deserialize(ArrayRef<uint8_t> &Data) const {
+ Error deserialize(ArrayRef<uint8_t> &Data) const {
uint32_t N = Func();
if (N == 0)
- return std::error_code();
+ return Error::success();
uint32_t Size = sizeof(T) * N;
if (Size / sizeof(T) != N)
- return std::make_error_code(std::errc::illegal_byte_sequence);
+ return make_error<CodeViewError>(
+ cv_error_code::corrupt_record,
+ "Array<T> length is not a multiple of sizeof(T)");
if (Data.size() < Size)
- return std::make_error_code(std::errc::illegal_byte_sequence);
+ return make_error<CodeViewError>(
+ cv_error_code::corrupt_record,
+ "Array<T> does not contain enough data for all elements");
Item = ArrayRef<T>(reinterpret_cast<const T *>(Data.data()), N);
Data = Data.drop_front(Size);
- return std::error_code();
+ return Error::success();
}
ArrayRef<T> &Item;
template <typename T> struct serialize_vector_tail_impl {
serialize_vector_tail_impl(std::vector<T> &Item) : Item(Item) {}
- std::error_code deserialize(ArrayRef<uint8_t> &Data) const {
+ Error deserialize(ArrayRef<uint8_t> &Data) const {
T Field;
// Stop when we run out of bytes or we hit record padding bytes.
while (!Data.empty() && Data.front() < LF_PAD0) {
return EC;
Item.push_back(Field);
}
- return std::error_code();
+ return Error::success();
}
std::vector<T> &Item;
serialize_null_term_string_array_impl(std::vector<StringRef> &Item)
: Item(Item) {}
- std::error_code deserialize(ArrayRef<uint8_t> &Data) const {
+ Error deserialize(ArrayRef<uint8_t> &Data) const {
if (Data.empty())
- return std::make_error_code(std::errc::illegal_byte_sequence);
+ return make_error<CodeViewError>(
+ cv_error_code::insufficient_buffer,
+ "Null terminated string buffer is empty!");
StringRef Field;
// Stop when we run out of bytes or we hit record padding bytes.
return EC;
Item.push_back(Field);
if (Data.empty())
- return std::make_error_code(std::errc::illegal_byte_sequence);
+ return make_error<CodeViewError>(
+ cv_error_code::insufficient_buffer,
+ "Null terminated string buffer is empty!");
}
Data = Data.drop_front(1);
- return std::error_code();
+ return Error::success();
}
std::vector<StringRef> &Item;
template <typename T> struct serialize_arrayref_tail_impl {
serialize_arrayref_tail_impl(ArrayRef<T> &Item) : Item(Item) {}
- std::error_code deserialize(ArrayRef<uint8_t> &Data) const {
+ Error deserialize(ArrayRef<uint8_t> &Data) const {
uint32_t Count = Data.size() / sizeof(T);
Item = ArrayRef<T>(reinterpret_cast<const T *>(Data.begin()), Count);
- return std::error_code();
+ return Error::success();
}
ArrayRef<T> &Item;
template <typename T> struct serialize_numeric_impl {
serialize_numeric_impl(T &Item) : Item(Item) {}
- std::error_code deserialize(ArrayRef<uint8_t> &Data) const {
+ Error deserialize(ArrayRef<uint8_t> &Data) const {
return consume_numeric(Data, Item);
}
#define CV_NUMERIC_FIELD(I) serialize_numeric(I)
template <typename T, typename U>
-std::error_code consume(ArrayRef<uint8_t> &Data,
- const serialize_conditional_impl<T, U> &Item) {
+Error consume(ArrayRef<uint8_t> &Data,
+ const serialize_conditional_impl<T, U> &Item) {
return Item.deserialize(Data);
}
template <typename T, typename U>
-std::error_code consume(ArrayRef<uint8_t> &Data,
- const serialize_array_impl<T, U> &Item) {
+Error consume(ArrayRef<uint8_t> &Data, const serialize_array_impl<T, U> &Item) {
return Item.deserialize(Data);
}
-inline std::error_code
-consume(ArrayRef<uint8_t> &Data,
- const serialize_null_term_string_array_impl &Item) {
+inline Error consume(ArrayRef<uint8_t> &Data,
+ const serialize_null_term_string_array_impl &Item) {
return Item.deserialize(Data);
}
template <typename T>
-std::error_code consume(ArrayRef<uint8_t> &Data,
- const serialize_vector_tail_impl<T> &Item) {
+Error consume(ArrayRef<uint8_t> &Data,
+ const serialize_vector_tail_impl<T> &Item) {
return Item.deserialize(Data);
}
template <typename T>
-std::error_code consume(ArrayRef<uint8_t> &Data,
- const serialize_arrayref_tail_impl<T> &Item) {
+Error consume(ArrayRef<uint8_t> &Data,
+ const serialize_arrayref_tail_impl<T> &Item) {
return Item.deserialize(Data);
}
template <typename T>
-std::error_code consume(ArrayRef<uint8_t> &Data,
- const serialize_numeric_impl<T> &Item) {
+Error consume(ArrayRef<uint8_t> &Data, const serialize_numeric_impl<T> &Item) {
return Item.deserialize(Data);
}
template <typename T, typename U, typename... Args>
-std::error_code consume(ArrayRef<uint8_t> &Data, T &&X, U &&Y,
- Args &&... Rest) {
+Error consume(ArrayRef<uint8_t> &Data, T &&X, U &&Y, Args &&... Rest) {
if (auto EC = consume(Data, X))
return EC;
return consume(Data, Y, std::forward<Args>(Rest)...);
#define CV_DESERIALIZE(...) \
if (auto EC = consume(__VA_ARGS__)) \
- return EC;
+ return std::move(EC);
}
}
: SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*H), Name(Name) {
}
- static ErrorOr<ProcSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<ProcSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, H, Name);
: SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*H), Name(Name),
VariantData(VariantData) {}
- static ErrorOr<Thunk32Sym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<Thunk32Sym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
StringRef Name;
ArrayRef<uint8_t> VariantData;
TrampolineSym(SymbolRecordKind Kind, uint32_t RecordOffset, const Hdr *H)
: SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*H) {}
- static ErrorOr<TrampolineSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<TrampolineSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
CV_DESERIALIZE(Data, H);
: SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*H), Name(Name) {
}
- static ErrorOr<SectionSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<SectionSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
StringRef Name;
: SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*H), Name(Name) {
}
- static ErrorOr<CoffGroupSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<CoffGroupSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
StringRef Name;
ScopeEndSym(SymbolRecordKind Kind, uint32_t RecordOffset)
: SymbolRecord(Kind), RecordOffset(RecordOffset) {}
- static ErrorOr<ScopeEndSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<ScopeEndSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
return ScopeEndSym(Kind, RecordOffset);
}
uint32_t RecordOffset;
: SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*Header),
Indices(Indices) {}
- static ErrorOr<CallerSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<CallerSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *Header;
ArrayRef<TypeIndex> Indices;
: SymbolRecord(SymbolRecordKind::InlineSiteSym),
RecordOffset(RecordOffset), Header(*H), Annotations(Annotations) {}
- static ErrorOr<InlineSiteSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<InlineSiteSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
ArrayRef<uint8_t> Annotations;
CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Annotations));
: SymbolRecord(SymbolRecordKind::PublicSym32), RecordOffset(RecordOffset),
Header(*H), Name(Name) {}
- static ErrorOr<PublicSym32> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<PublicSym32> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, H, Name);
: SymbolRecord(SymbolRecordKind::RegisterSym), RecordOffset(RecordOffset),
Header(*H), Name(Name) {}
- static ErrorOr<RegisterSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<RegisterSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, H, Name);
: SymbolRecord(SymbolRecordKind::ProcRefSym), RecordOffset(RecordOffset),
Header(*H), Name(Name) {}
- static ErrorOr<ProcRefSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<ProcRefSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, H, Name);
: SymbolRecord(SymbolRecordKind::LocalSym), RecordOffset(RecordOffset),
Header(*H), Name(Name) {}
- static ErrorOr<LocalSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<LocalSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, H, Name);
: SymbolRecord(SymbolRecordKind::DefRangeSym), RecordOffset(RecordOffset),
Header(*H), Gaps(Gaps) {}
- static ErrorOr<DefRangeSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<DefRangeSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
ArrayRef<LocalVariableAddrGap> Gaps;
CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps));
: SymbolRecord(SymbolRecordKind::DefRangeSubfieldSym),
RecordOffset(RecordOffset), Header(*H), Gaps(Gaps) {}
- static ErrorOr<DefRangeSubfieldSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<DefRangeSubfieldSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
ArrayRef<LocalVariableAddrGap> Gaps;
CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps));
Header.Range.Range = Range;
}
- static ErrorOr<DefRangeRegisterSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<DefRangeRegisterSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
ArrayRef<LocalVariableAddrGap> Gaps;
CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps));
Header.OffsetInParent = OffsetInParent;
}
- static ErrorOr<DefRangeSubfieldRegisterSym>
+ static Expected<DefRangeSubfieldRegisterSym>
deserialize(SymbolRecordKind Kind, uint32_t RecordOffset,
ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
: SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelSym),
RecordOffset(RecordOffset), Header(*H), Gaps(Gaps) {}
- static ErrorOr<DefRangeFramePointerRelSym>
+ static Expected<DefRangeFramePointerRelSym>
deserialize(SymbolRecordKind Kind, uint32_t RecordOffset,
ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
Header.Range.Range = Range;
}
- static ErrorOr<DefRangeRegisterRelSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<DefRangeRegisterRelSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
ArrayRef<LocalVariableAddrGap> Gaps;
CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps));
: SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelFullScopeSym),
RecordOffset(RecordOffset), Header(*H) {}
- static ErrorOr<DefRangeFramePointerRelFullScopeSym>
+ static Expected<DefRangeFramePointerRelFullScopeSym>
deserialize(SymbolRecordKind Kind, uint32_t RecordOffset,
ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
: SymbolRecord(SymbolRecordKind::BlockSym), RecordOffset(RecordOffset),
Header(*H), Name(Name) {}
- static ErrorOr<BlockSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<BlockSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, H, Name);
: SymbolRecord(SymbolRecordKind::LabelSym), RecordOffset(RecordOffset),
Header(*H), Name(Name) {}
- static ErrorOr<LabelSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<LabelSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, H, Name);
: SymbolRecord(SymbolRecordKind::ObjNameSym), RecordOffset(RecordOffset),
Header(*H), Name(Name) {}
- static ErrorOr<ObjNameSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<ObjNameSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, H, Name);
: SymbolRecord(SymbolRecordKind::EnvBlockSym), RecordOffset(RecordOffset),
Header(*H), Fields(Fields) {}
- static ErrorOr<EnvBlockSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<EnvBlockSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
std::vector<StringRef> Fields;
CV_DESERIALIZE(Data, H, CV_STRING_ARRAY_NULL_TERM(Fields));
: SymbolRecord(SymbolRecordKind::ExportSym), RecordOffset(RecordOffset),
Header(*H), Name(Name) {}
- static ErrorOr<ExportSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<ExportSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, H, Name);
: SymbolRecord(SymbolRecordKind::FileStaticSym),
RecordOffset(RecordOffset), Header(*H), Name(Name) {}
- static ErrorOr<FileStaticSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<FileStaticSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, H, Name);
: SymbolRecord(SymbolRecordKind::Compile2Sym), RecordOffset(RecordOffset),
Header(*H), Version(Version) {}
- static ErrorOr<Compile2Sym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<Compile2Sym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
StringRef Version;
CV_DESERIALIZE(Data, H, Version);
: SymbolRecord(SymbolRecordKind::Compile3Sym), RecordOffset(RecordOffset),
Header(*H), Version(Version) {}
- static ErrorOr<Compile3Sym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<Compile3Sym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
StringRef Version;
CV_DESERIALIZE(Data, H, Version);
: SymbolRecord(SymbolRecordKind::FrameProcSym),
RecordOffset(RecordOffset), Header(*H) {}
- static ErrorOr<FrameProcSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<FrameProcSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
CV_DESERIALIZE(Data, H);
: SymbolRecord(SymbolRecordKind::CallSiteInfoSym),
RecordOffset(RecordOffset), Header(*H) {}
- static ErrorOr<CallSiteInfoSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<CallSiteInfoSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
CV_DESERIALIZE(Data, H);
: SymbolRecord(SymbolRecordKind::HeapAllocationSiteSym),
RecordOffset(RecordOffset), Header(*H) {}
- static ErrorOr<HeapAllocationSiteSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<HeapAllocationSiteSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
CV_DESERIALIZE(Data, H);
: SymbolRecord(SymbolRecordKind::FrameCookieSym),
RecordOffset(RecordOffset), Header(*H) {}
- static ErrorOr<FrameCookieSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<FrameCookieSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
CV_DESERIALIZE(Data, H);
: SymbolRecord(SymbolRecordKind::UDTSym), RecordOffset(RecordOffset),
Header(*H), Name(Name) {}
- static ErrorOr<UDTSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<UDTSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, H, Name);
: SymbolRecord(SymbolRecordKind::BuildInfoSym),
RecordOffset(RecordOffset), Header(*H) {}
- static ErrorOr<BuildInfoSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<BuildInfoSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
CV_DESERIALIZE(Data, H);
: SymbolRecord(SymbolRecordKind::BPRelativeSym),
RecordOffset(RecordOffset), Header(*H), Name(Name) {}
- static ErrorOr<BPRelativeSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<BPRelativeSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, H, Name);
: SymbolRecord(SymbolRecordKind::RegRelativeSym),
RecordOffset(RecordOffset), Header(*H), Name(Name) {}
- static ErrorOr<RegRelativeSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<RegRelativeSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, H, Name);
: SymbolRecord(SymbolRecordKind::ConstantSym), RecordOffset(RecordOffset),
Header(*H), Value(Value), Name(Name) {}
- static ErrorOr<ConstantSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<ConstantSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
APSInt Value;
StringRef Name;
: SymbolRecord(SymbolRecordKind::DataSym), RecordOffset(RecordOffset),
Header(*H), Name(Name) {}
- static ErrorOr<DataSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<DataSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, H, Name);
: SymbolRecord(SymbolRecordKind::ThreadLocalDataSym),
RecordOffset(RecordOffset), Header(*H), Name(Name) {}
- static ErrorOr<ThreadLocalDataSym> deserialize(SymbolRecordKind Kind,
- uint32_t RecordOffset,
- ArrayRef<uint8_t> &Data) {
+ static Expected<ThreadLocalDataSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
const Hdr *H = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, H, Name);
#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/Error.h"
#include <cinttypes>
#include <utility>
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<MemberPointerInfo> deserialize(ArrayRef<uint8_t> &Data);
+ static Expected<MemberPointerInfo> deserialize(ArrayRef<uint8_t> &Data);
TypeIndex getContainingType() const { return ContainingType; }
PointerToMemberRepresentation getRepresentation() const {
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<ModifierRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<ModifierRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
TypeIndex getModifiedType() const { return ModifiedType; }
ModifierOptions getModifiers() const { return Modifiers; }
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<ProcedureRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<ProcedureRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
static uint32_t getLayoutSize() { return 2 + sizeof(Layout); }
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<MemberFunctionRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<MemberFunctionRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
TypeIndex getReturnType() const { return ReturnType; }
TypeIndex getClassType() const { return ClassType; }
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<MemberFuncIdRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<MemberFuncIdRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
TypeIndex getClassType() const { return ClassType; }
TypeIndex getFunctionType() const { return FunctionType; }
StringRef getName() const { return Name; }
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<ArgListRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<ArgListRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
ArrayRef<TypeIndex> getIndices() const { return StringIndices; }
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<PointerRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<PointerRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
TypeIndex getReferentType() const { return ReferentType; }
PointerKind getPointerKind() const { return PtrKind; }
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<NestedTypeRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<NestedTypeRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
TypeIndex getNestedType() const { return Type; }
StringRef getName() const { return Name; }
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<ArrayRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<ArrayRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
TypeIndex getElementType() const { return ElementType; }
TypeIndex getIndexType() const { return IndexType; }
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<ClassRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<ClassRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
HfaKind getHfa() const { return Hfa; }
WindowsRTClassKind getWinRTKind() const { return WinRTKind; }
UniqueName),
Hfa(Hfa), Size(Size) {}
- static ErrorOr<UnionRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<UnionRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
HfaKind getHfa() const { return Hfa; }
uint64_t getSize() const { return Size; }
/// Rewrite member type indices with IndexMap. Returns false if a type index is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<EnumRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<EnumRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
TypeIndex getUnderlyingType() const { return UnderlyingType; }
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<BitFieldRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<BitFieldRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
TypeIndex getType() const { return Type; }
uint8_t getBitOffset() const { return BitOffset; }
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<VFTableShapeRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<VFTableShapeRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
ArrayRef<VFTableSlotKind> getSlots() const {
if (!SlotsRef.empty())
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<TypeServer2Record> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<TypeServer2Record> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
StringRef getGuid() const { return Guid; }
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<StringIdRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<StringIdRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
TypeIndex getId() const { return Id; }
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<FuncIdRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<FuncIdRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
TypeIndex getParentScope() const { return ParentScope; }
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<UdtSourceLineRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<UdtSourceLineRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
TypeIndex getUDT() const { return UDT; }
TypeIndex getSourceFile() const { return SourceFile; }
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<UdtModSourceLineRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data) {
+ static Expected<UdtModSourceLineRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
CV_DESERIALIZE(Data, L);
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<BuildInfoRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<BuildInfoRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
ArrayRef<TypeIndex> getArgs() const { return ArgIndices; }
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<VFTableRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<VFTableRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
TypeIndex getCompleteClass() const { return CompleteClass; }
TypeIndex getOverriddenVTable() const { return OverriddenVFTable; }
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<OneMethodRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<OneMethodRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
TypeIndex getType() const { return Type; }
MethodKind getKind() const { return Kind; }
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<MethodOverloadListRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<MethodOverloadListRecord>
+ deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data);
ArrayRef<OneMethodRecord> getMethods() const { return Methods; }
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<OverloadedMethodRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<OverloadedMethodRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
uint16_t getNumOverloads() const { return NumOverloads; }
TypeIndex getMethodList() const { return MethodList; }
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<DataMemberRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<DataMemberRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
MemberAccess getAccess() const { return Access; }
TypeIndex getType() const { return Type; }
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<StaticDataMemberRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<StaticDataMemberRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
MemberAccess getAccess() const { return Access; }
TypeIndex getType() const { return Type; }
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<EnumeratorRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<EnumeratorRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
MemberAccess getAccess() const { return Access; }
APSInt getValue() const { return Value; }
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<VFPtrRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<VFPtrRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
TypeIndex getType() const { return Type; }
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<BaseClassRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<BaseClassRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
MemberAccess getAccess() const { return Access; }
TypeIndex getBaseType() const { return Type; }
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<VirtualBaseClassRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<VirtualBaseClassRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
MemberAccess getAccess() const { return Access; }
TypeIndex getBaseType() const { return BaseType; }
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- static ErrorOr<ListContinuationRecord> deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data);
+ static Expected<ListContinuationRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
private:
struct Layout {
#define TYPE_RECORD(EnumName, EnumVal, Name) \
case EnumName: { \
TypeRecordKind RK = static_cast<TypeRecordKind>(EnumName); \
- auto Result = Name##Record::deserialize(RK, LeafData); \
- if (Result.getError()) \
- return llvm::make_error<CodeViewError>(cv_error_code::corrupt_record); \
- if (auto EC = Callbacks.visit##Name(*Result)) \
+ auto ExpectedRecord = Name##Record::deserialize(RK, LeafData); \
+ if (!ExpectedRecord) \
+ return ExpectedRecord.takeError(); \
+ if (auto EC = Callbacks.visit##Name(*ExpectedRecord)) \
return EC; \
break; \
}
#define MEMBER_RECORD(EnumName, EnumVal, Name) \
case EnumName: { \
TypeRecordKind RK = static_cast<TypeRecordKind>(EnumName); \
- auto Result = Name##Record::deserialize(RK, RecordData); \
- if (Result.getError()) \
- return llvm::make_error<CodeViewError>(cv_error_code::corrupt_record); \
- if (auto EC = Callbacks.visit##Name(*Result)) \
+ auto ExpectedRecord = Name##Record::deserialize(RK, RecordData); \
+ if (!ExpectedRecord) \
+ return ExpectedRecord.takeError(); \
+ if (auto EC = Callbacks.visit##Name(*ExpectedRecord)) \
return EC; \
break; \
}
#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
using namespace llvm;
return getBytesAsCharacters(LeafData).split('\0').first;
}
-std::error_code llvm::codeview::consume(ArrayRef<uint8_t> &Data, APSInt &Num) {
+Error llvm::codeview::consume(ArrayRef<uint8_t> &Data, APSInt &Num) {
// Used to avoid overload ambiguity on APInt construtor.
bool FalseVal = false;
if (Data.size() < 2)
- return std::make_error_code(std::errc::illegal_byte_sequence);
+ return make_error<CodeViewError>(
+ cv_error_code::insufficient_buffer,
+ "Buffer does not contain enough data for an APSInt");
uint16_t Short = *reinterpret_cast<const ulittle16_t *>(Data.data());
Data = Data.drop_front(2);
if (Short < LF_NUMERIC) {
Num = APSInt(APInt(/*numBits=*/16, Short, /*isSigned=*/false),
/*isUnsigned=*/true);
- return std::error_code();
+ return Error::success();
}
switch (Short) {
case LF_CHAR:
if (Data.size() < 1)
- return std::make_error_code(std::errc::illegal_byte_sequence);
+ return make_error<CodeViewError>(
+ cv_error_code::insufficient_buffer,
+ "Buffer does not contain enough data for an LF_CHAR");
Num = APSInt(APInt(/*numBits=*/8,
*reinterpret_cast<const int8_t *>(Data.data()),
/*isSigned=*/true),
/*isUnsigned=*/false);
Data = Data.drop_front(1);
- return std::error_code();
+ return Error::success();
case LF_SHORT:
if (Data.size() < 2)
- return std::make_error_code(std::errc::illegal_byte_sequence);
+ return make_error<CodeViewError>(
+ cv_error_code::insufficient_buffer,
+ "Buffer does not contain enough data for an LF_SHORT");
Num = APSInt(APInt(/*numBits=*/16,
*reinterpret_cast<const little16_t *>(Data.data()),
/*isSigned=*/true),
/*isUnsigned=*/false);
Data = Data.drop_front(2);
- return std::error_code();
+ return Error::success();
case LF_USHORT:
if (Data.size() < 2)
- return std::make_error_code(std::errc::illegal_byte_sequence);
+ return make_error<CodeViewError>(
+ cv_error_code::insufficient_buffer,
+ "Buffer does not contain enough data for an LF_USHORT");
Num = APSInt(APInt(/*numBits=*/16,
*reinterpret_cast<const ulittle16_t *>(Data.data()),
/*isSigned=*/false),
/*isUnsigned=*/true);
Data = Data.drop_front(2);
- return std::error_code();
+ return Error::success();
case LF_LONG:
if (Data.size() < 4)
- return std::make_error_code(std::errc::illegal_byte_sequence);
+ return make_error<CodeViewError>(
+ cv_error_code::insufficient_buffer,
+ "Buffer does not contain enough data for an LF_LONG");
Num = APSInt(APInt(/*numBits=*/32,
*reinterpret_cast<const little32_t *>(Data.data()),
/*isSigned=*/true),
/*isUnsigned=*/false);
Data = Data.drop_front(4);
- return std::error_code();
+ return Error::success();
case LF_ULONG:
if (Data.size() < 4)
- return std::make_error_code(std::errc::illegal_byte_sequence);
+ return make_error<CodeViewError>(
+ cv_error_code::insufficient_buffer,
+ "Buffer does not contain enough data for an LF_ULONG");
Num = APSInt(APInt(/*numBits=*/32,
*reinterpret_cast<const ulittle32_t *>(Data.data()),
/*isSigned=*/FalseVal),
/*isUnsigned=*/true);
Data = Data.drop_front(4);
- return std::error_code();
+ return Error::success();
case LF_QUADWORD:
if (Data.size() < 8)
- return std::make_error_code(std::errc::illegal_byte_sequence);
+ return make_error<CodeViewError>(
+ cv_error_code::insufficient_buffer,
+ "Buffer does not contain enough data for an LF_QUADWORD");
Num = APSInt(APInt(/*numBits=*/64,
*reinterpret_cast<const little64_t *>(Data.data()),
/*isSigned=*/true),
/*isUnsigned=*/false);
Data = Data.drop_front(8);
- return std::error_code();
+ return Error::success();
case LF_UQUADWORD:
if (Data.size() < 8)
- return std::make_error_code(std::errc::illegal_byte_sequence);
+ return make_error<CodeViewError>(
+ cv_error_code::insufficient_buffer,
+ "Buffer does not contain enough data for an LF_UQUADWORD");
Num = APSInt(APInt(/*numBits=*/64,
*reinterpret_cast<const ulittle64_t *>(Data.data()),
/*isSigned=*/false),
/*isUnsigned=*/true);
Data = Data.drop_front(8);
- return std::error_code();
+ return Error::success();
}
- return std::make_error_code(std::errc::illegal_byte_sequence);
+ return make_error<CodeViewError>(cv_error_code::corrupt_record,
+ "Buffer contains invalid APSInt type");
}
-std::error_code llvm::codeview::consume(StringRef &Data, APSInt &Num) {
+Error llvm::codeview::consume(StringRef &Data, APSInt &Num) {
ArrayRef<uint8_t> Bytes(Data.bytes_begin(), Data.bytes_end());
auto EC = consume(Bytes, Num);
Data = StringRef(reinterpret_cast<const char *>(Bytes.data()), Bytes.size());
}
/// Decode a numeric leaf value that is known to be a uint64_t.
-std::error_code llvm::codeview::consume_numeric(ArrayRef<uint8_t> &Data,
- uint64_t &Num) {
+Error llvm::codeview::consume_numeric(ArrayRef<uint8_t> &Data, uint64_t &Num) {
APSInt N;
if (auto EC = consume(Data, N))
return EC;
if (N.isSigned() || !N.isIntN(64))
- return std::make_error_code(std::errc::illegal_byte_sequence);
+ return make_error<CodeViewError>(cv_error_code::corrupt_record,
+ "Data is not a numeric value!");
Num = N.getLimitedValue();
- return std::error_code();
+ return Error::success();
}
-std::error_code llvm::codeview::consume(ArrayRef<uint8_t> &Data,
- uint32_t &Item) {
+Error llvm::codeview::consume(ArrayRef<uint8_t> &Data, uint32_t &Item) {
const support::ulittle32_t *IntPtr;
if (auto EC = consumeObject(Data, IntPtr))
return EC;
Item = *IntPtr;
- return std::error_code();
+ return Error::success();
}
-std::error_code llvm::codeview::consume(StringRef &Data, uint32_t &Item) {
+Error llvm::codeview::consume(StringRef &Data, uint32_t &Item) {
ArrayRef<uint8_t> Bytes(Data.bytes_begin(), Data.bytes_end());
auto EC = consume(Bytes, Item);
Data = StringRef(reinterpret_cast<const char *>(Bytes.data()), Bytes.size());
return EC;
}
-std::error_code llvm::codeview::consume(ArrayRef<uint8_t> &Data,
- int32_t &Item) {
+Error llvm::codeview::consume(ArrayRef<uint8_t> &Data, int32_t &Item) {
const support::little32_t *IntPtr;
if (auto EC = consumeObject(Data, IntPtr))
return EC;
Item = *IntPtr;
- return std::error_code();
+ return Error::success();
}
-std::error_code llvm::codeview::consume(ArrayRef<uint8_t> &Data,
- StringRef &Item) {
+Error llvm::codeview::consume(ArrayRef<uint8_t> &Data, StringRef &Item) {
if (Data.empty())
- return std::make_error_code(std::errc::illegal_byte_sequence);
+ return make_error<CodeViewError>(cv_error_code::corrupt_record,
+ "Null terminated string buffer is empty!");
StringRef Rest;
std::tie(Item, Rest) = getBytesAsCharacters(Data).split('\0');
// We expect this to be null terminated. If it was not, it is an error.
if (Data.size() == Item.size())
- return std::make_error_code(std::errc::illegal_byte_sequence);
+ return make_error<CodeViewError>(cv_error_code::corrupt_record,
+ "Expected null terminator!");
Data = ArrayRef<uint8_t>(Rest.bytes_begin(), Rest.bytes_end());
- return std::error_code();
+ return Error::success();
}
// Type record deserialization
//===----------------------------------------------------------------------===//
-ErrorOr<MemberPointerInfo>
+Expected<MemberPointerInfo>
MemberPointerInfo::deserialize(ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
if (auto EC = consumeObject(Data, L))
- return EC;
+ return std::move(EC);
TypeIndex T = L->ClassType;
uint16_t R = L->Representation;
return MemberPointerInfo(T, PMR);
}
-ErrorOr<ModifierRecord> ModifierRecord::deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data) {
+Expected<ModifierRecord> ModifierRecord::deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
if (auto EC = consumeObject(Data, L))
- return EC;
+ return std::move(EC);
TypeIndex M = L->ModifiedType;
uint16_t O = L->Modifiers;
return ModifierRecord(M, MO);
}
-ErrorOr<ProcedureRecord> ProcedureRecord::deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data) {
+Expected<ProcedureRecord>
+ProcedureRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
if (auto EC = consumeObject(Data, L))
- return EC;
+ return std::move(EC);
return ProcedureRecord(L->ReturnType, L->CallConv, L->Options,
L->NumParameters, L->ArgListType);
}
-ErrorOr<MemberFunctionRecord>
+Expected<MemberFunctionRecord>
MemberFunctionRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
L->ArgListType, L->ThisAdjustment);
}
-ErrorOr<MemberFuncIdRecord>
+Expected<MemberFuncIdRecord>
MemberFuncIdRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
return MemberFuncIdRecord(L->ClassType, L->FunctionType, Name);
}
-ErrorOr<ArgListRecord> ArgListRecord::deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data) {
+Expected<ArgListRecord> ArgListRecord::deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data) {
if (Kind != TypeRecordKind::StringList && Kind != TypeRecordKind::ArgList)
- return std::make_error_code(std::errc::illegal_byte_sequence);
+ return make_error<CodeViewError>(
+ cv_error_code::corrupt_record,
+ "ArgListRecord contains unexpected TypeRecordKind");
const Layout *L = nullptr;
ArrayRef<TypeIndex> Indices;
return ArgListRecord(Kind, Indices);
}
-ErrorOr<PointerRecord> PointerRecord::deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data) {
+Expected<PointerRecord> PointerRecord::deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
if (auto EC = consumeObject(Data, L))
- return EC;
+ return std::move(EC);
PointerKind PtrKind = L->getPtrKind();
PointerMode Mode = L->getPtrMode();
uint8_t Size = L->getPtrSize();
if (L->isPointerToMember()) {
- auto E = MemberPointerInfo::deserialize(Data);
- if (E.getError())
- return std::make_error_code(std::errc::illegal_byte_sequence);
- return PointerRecord(L->PointeeType, PtrKind, Mode, Options, Size, *E);
+ if (auto ExpectedMPI = MemberPointerInfo::deserialize(Data))
+ return PointerRecord(L->PointeeType, PtrKind, Mode, Options, Size,
+ *ExpectedMPI);
+ else
+ return ExpectedMPI.takeError();
}
return PointerRecord(L->PointeeType, PtrKind, Mode, Options, Size);
}
-ErrorOr<NestedTypeRecord>
+Expected<NestedTypeRecord>
NestedTypeRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
return NestedTypeRecord(L->Type, Name);
}
-ErrorOr<ArrayRecord> ArrayRecord::deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data) {
+Expected<ArrayRecord> ArrayRecord::deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
uint64_t Size;
StringRef Name;
return ArrayRecord(L->ElementType, L->IndexType, Size, Name);
}
-ErrorOr<ClassRecord> ClassRecord::deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data) {
+Expected<ClassRecord> ClassRecord::deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data) {
uint64_t Size = 0;
StringRef Name;
StringRef UniqueName;
L->DerivedFrom, L->VShape, Size, Name, UniqueName);
}
-ErrorOr<UnionRecord> UnionRecord::deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data) {
+Expected<UnionRecord> UnionRecord::deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data) {
uint64_t Size = 0;
StringRef Name;
StringRef UniqueName;
UniqueName);
}
-ErrorOr<EnumRecord> EnumRecord::deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data) {
+Expected<EnumRecord> EnumRecord::deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
StringRef UniqueName;
UniqueName, L->UnderlyingType);
}
-ErrorOr<BitFieldRecord> BitFieldRecord::deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data) {
+Expected<BitFieldRecord> BitFieldRecord::deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
CV_DESERIALIZE(Data, L);
return BitFieldRecord(L->Type, L->BitSize, L->BitOffset);
}
-ErrorOr<VFTableShapeRecord>
+Expected<VFTableShapeRecord>
VFTableShapeRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
if (auto EC = consumeObject(Data, L))
- return EC;
+ return std::move(EC);
std::vector<VFTableSlotKind> Slots;
uint16_t Count = L->VFEntryCount;
while (Count > 0) {
if (Data.empty())
- return std::make_error_code(std::errc::illegal_byte_sequence);
+ return make_error<CodeViewError>(cv_error_code::corrupt_record,
+ "VTableShapeRecord contains no entries");
// Process up to 2 nibbles at a time (if there are at least 2 remaining)
uint8_t Value = Data[0] & 0x0F;
return VFTableShapeRecord(Slots);
}
-ErrorOr<TypeServer2Record>
+Expected<TypeServer2Record>
TypeServer2Record::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
return TypeServer2Record(StringRef(L->Guid, 16), L->Age, Name);
}
-ErrorOr<StringIdRecord> StringIdRecord::deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data) {
+Expected<StringIdRecord> StringIdRecord::deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, L, Name);
return StringIdRecord(L->id, Name);
}
-ErrorOr<FuncIdRecord> FuncIdRecord::deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data) {
+Expected<FuncIdRecord> FuncIdRecord::deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, L, Name);
return FuncIdRecord(L->ParentScope, L->FunctionType, Name);
}
-ErrorOr<UdtSourceLineRecord>
+Expected<UdtSourceLineRecord>
UdtSourceLineRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
CV_DESERIALIZE(Data, L);
return UdtSourceLineRecord(L->UDT, L->SourceFile, L->LineNumber);
}
-ErrorOr<BuildInfoRecord> BuildInfoRecord::deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data) {
+Expected<BuildInfoRecord>
+BuildInfoRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
ArrayRef<TypeIndex> Indices;
CV_DESERIALIZE(Data, L, CV_ARRAY_FIELD_N(Indices, L->NumArgs));
return BuildInfoRecord(Indices);
}
-ErrorOr<VFTableRecord> VFTableRecord::deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data) {
+Expected<VFTableRecord> VFTableRecord::deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
std::vector<StringRef> Names;
Name, Names);
}
-ErrorOr<OneMethodRecord> OneMethodRecord::deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data) {
+Expected<OneMethodRecord>
+OneMethodRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
int32_t VFTableOffset = -1;
Name);
// Validate the vftable offset.
if (Method.isIntroducingVirtual() && Method.getVFTableOffset() < 0)
- return std::make_error_code(std::errc::illegal_byte_sequence);
+ return make_error<CodeViewError>(cv_error_code::corrupt_record,
+ "Invalid VFTableOffset");
return Method;
}
-ErrorOr<MethodOverloadListRecord>
+Expected<MethodOverloadListRecord>
MethodOverloadListRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
std::vector<OneMethodRecord> Methods;
// Validate the vftable offset.
auto &Method = Methods.back();
if (Method.isIntroducingVirtual() && Method.getVFTableOffset() < 0)
- return std::make_error_code(std::errc::illegal_byte_sequence);
+ return make_error<CodeViewError>(cv_error_code::corrupt_record,
+ "Invalid VFTableOffset");
}
return MethodOverloadListRecord(Methods);
}
-ErrorOr<OverloadedMethodRecord>
+Expected<OverloadedMethodRecord>
OverloadedMethodRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
return OverloadedMethodRecord(L->MethodCount, L->MethList, Name);
}
-ErrorOr<DataMemberRecord>
+Expected<DataMemberRecord>
DataMemberRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
uint64_t Offset;
return DataMemberRecord(L->Attrs.getAccess(), L->Type, Offset, Name);
}
-ErrorOr<StaticDataMemberRecord>
+Expected<StaticDataMemberRecord>
StaticDataMemberRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
return StaticDataMemberRecord(L->Attrs.getAccess(), L->Type, Name);
}
-ErrorOr<EnumeratorRecord>
+Expected<EnumeratorRecord>
EnumeratorRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
APSInt Value;
return EnumeratorRecord(L->Attrs.getAccess(), Value, Name);
}
-ErrorOr<VFPtrRecord> VFPtrRecord::deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data) {
+Expected<VFPtrRecord> VFPtrRecord::deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
if (auto EC = consumeObject(Data, L))
- return EC;
+ return std::move(EC);
return VFPtrRecord(L->Type);
}
-ErrorOr<BaseClassRecord> BaseClassRecord::deserialize(TypeRecordKind Kind,
- ArrayRef<uint8_t> &Data) {
+Expected<BaseClassRecord>
+BaseClassRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
uint64_t Offset;
CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Offset));
return BaseClassRecord(L->Attrs.getAccess(), L->BaseType, Offset);
}
-ErrorOr<VirtualBaseClassRecord>
+Expected<VirtualBaseClassRecord>
VirtualBaseClassRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
Offset, Index);
}
-ErrorOr<ListContinuationRecord>
+Expected<ListContinuationRecord>
ListContinuationRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
exit(1);
}
+void error(llvm::Error EC) {
+ if (!EC)
+ return;
+
+ handleAllErrors(std::move(EC),
+ [&](ErrorInfoBase &EI) { reportError(EI.message()); });
+}
+
void error(std::error_code EC) {
if (!EC)
return;
// Various helper functions.
LLVM_ATTRIBUTE_NORETURN void reportError(Twine Msg);
void error(std::error_code ec);
+ void error(llvm::Error EC);
template <class T> T unwrapOrError(ErrorOr<T> EO) {
if (EO)
return *EO;