[DWARFFormValue] Cleanup DWARFFormValue interface. (NFC)

DWARFFormValues can be created from a data extractor or by passing its
value directly. Until now this was done by member functions that
modified an existing object's internal state. This patch replaces a
subset of these methods with static method that return a new
DWARFFormValue.

llvm-svn: 354941
This commit is contained in:
Jonas Devlieghere 2019-02-27 00:58:09 +00:00
parent 25838c6dac
commit bb111152b7
7 changed files with 163 additions and 142 deletions

View File

@ -41,6 +41,9 @@ public:
private: private:
struct ValueType { struct ValueType {
ValueType() { uval = 0; } ValueType() { uval = 0; }
ValueType(int64_t V) : sval(V) {}
ValueType(uint64_t V) : uval(V) {}
ValueType(const char *V) : cstr(V) {}
union { union {
uint64_t uval; uint64_t uval;
@ -55,20 +58,22 @@ private:
ValueType Value; /// Contains all data for the form. ValueType Value; /// Contains all data for the form.
const DWARFUnit *U = nullptr; /// Remember the DWARFUnit at extract time. const DWARFUnit *U = nullptr; /// Remember the DWARFUnit at extract time.
const DWARFContext *C = nullptr; /// Context for extract time. const DWARFContext *C = nullptr; /// Context for extract time.
DWARFFormValue(dwarf::Form F, ValueType V) : Form(F), Value(V) {}
public: public:
DWARFFormValue(dwarf::Form F = dwarf::Form(0)) : Form(F) {} DWARFFormValue(dwarf::Form F = dwarf::Form(0)) : Form(F) {}
static DWARFFormValue createFromSValue(dwarf::Form F, int64_t V);
static DWARFFormValue createFromUValue(dwarf::Form F, uint64_t V);
static DWARFFormValue createFromPValue(dwarf::Form F, const char *V);
static DWARFFormValue createFromBlockValue(dwarf::Form F,
ArrayRef<uint8_t> D);
static DWARFFormValue createFromUnit(dwarf::Form F, const DWARFUnit *Unit,
uint32_t *OffsetPtr);
dwarf::Form getForm() const { return Form; } dwarf::Form getForm() const { return Form; }
uint64_t getRawUValue() const { return Value.uval; } uint64_t getRawUValue() const { return Value.uval; }
void setForm(dwarf::Form F) { Form = F; }
void setUValue(uint64_t V) { Value.uval = V; }
void setSValue(int64_t V) { Value.sval = V; }
void setPValue(const char *V) { Value.cstr = V; }
void setBlockValue(const ArrayRef<uint8_t> &Data) {
Value.data = Data.data();
setUValue(Data.size());
}
bool isFormClass(FormClass FC) const; bool isFormClass(FormClass FC) const;
const DWARFUnit *getUnit() const { return U; } const DWARFUnit *getUnit() const { return U; }

View File

@ -163,11 +163,11 @@ Optional<DWARFFormValue> DWARFAbbreviationDeclaration::getAttributeValue(
for (const auto &Spec : AttributeSpecs) { for (const auto &Spec : AttributeSpecs) {
if (*MatchAttrIndex == AttrIndex) { if (*MatchAttrIndex == AttrIndex) {
// We have arrived at the attribute to extract, extract if from Offset. // We have arrived at the attribute to extract, extract if from Offset.
if (Spec.isImplicitConst())
return DWARFFormValue::createFromSValue(Spec.Form,
Spec.getImplicitConstValue());
DWARFFormValue FormValue(Spec.Form); DWARFFormValue FormValue(Spec.Form);
if (Spec.isImplicitConst()) {
FormValue.setSValue(Spec.getImplicitConstValue());
return FormValue;
}
if (FormValue.extractValue(DebugInfoData, &Offset, U.getFormParams(), &U)) if (FormValue.extractValue(DebugInfoData, &Offset, U.getFormParams(), &U))
return FormValue; return FormValue;
} }

View File

@ -144,8 +144,8 @@ parseV2DirFileTables(const DWARFDataExtractor &DebugLineData,
StringRef S = DebugLineData.getCStrRef(OffsetPtr); StringRef S = DebugLineData.getCStrRef(OffsetPtr);
if (S.empty()) if (S.empty())
break; break;
DWARFFormValue Dir(dwarf::DW_FORM_string); DWARFFormValue Dir =
Dir.setPValue(S.data()); DWARFFormValue::createFromPValue(dwarf::DW_FORM_string, S.data());
IncludeDirectories.push_back(Dir); IncludeDirectories.push_back(Dir);
} }
@ -154,8 +154,8 @@ parseV2DirFileTables(const DWARFDataExtractor &DebugLineData,
if (Name.empty()) if (Name.empty())
break; break;
DWARFDebugLine::FileNameEntry FileEntry; DWARFDebugLine::FileNameEntry FileEntry;
FileEntry.Name.setForm(dwarf::DW_FORM_string); FileEntry.Name =
FileEntry.Name.setPValue(Name.data()); DWARFFormValue::createFromPValue(dwarf::DW_FORM_string, Name.data());
FileEntry.DirIdx = DebugLineData.getULEB128(OffsetPtr); FileEntry.DirIdx = DebugLineData.getULEB128(OffsetPtr);
FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr); FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr);
FileEntry.Length = DebugLineData.getULEB128(OffsetPtr); FileEntry.Length = DebugLineData.getULEB128(OffsetPtr);
@ -594,8 +594,8 @@ Error DWARFDebugLine::LineTable::parse(
{ {
FileNameEntry FileEntry; FileNameEntry FileEntry;
const char *Name = DebugLineData.getCStr(OffsetPtr); const char *Name = DebugLineData.getCStr(OffsetPtr);
FileEntry.Name.setForm(dwarf::DW_FORM_string); FileEntry.Name =
FileEntry.Name.setPValue(Name); DWARFFormValue::createFromPValue(dwarf::DW_FORM_string, Name);
FileEntry.DirIdx = DebugLineData.getULEB128(OffsetPtr); FileEntry.DirIdx = DebugLineData.getULEB128(OffsetPtr);
FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr); FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr);
FileEntry.Length = DebugLineData.getULEB128(OffsetPtr); FileEntry.Length = DebugLineData.getULEB128(OffsetPtr);

View File

@ -278,11 +278,7 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
OS << formatv(" [{0}]", Form); OS << formatv(" [{0}]", Form);
DWARFUnit *U = Die.getDwarfUnit(); DWARFUnit *U = Die.getDwarfUnit();
DWARFFormValue formValue(Form); DWARFFormValue FormValue = DWARFFormValue::createFromUnit(Form, U, OffsetPtr);
if (!formValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr,
U->getFormParams(), U))
return;
OS << "\t("; OS << "\t(";
@ -293,35 +289,35 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
Color = HighlightColor::String; Color = HighlightColor::String;
if (const auto *LT = U->getContext().getLineTableForUnit(U)) if (const auto *LT = U->getContext().getLineTableForUnit(U))
if (LT->getFileNameByIndex( if (LT->getFileNameByIndex(
formValue.getAsUnsignedConstant().getValue(), FormValue.getAsUnsignedConstant().getValue(),
U->getCompilationDir(), U->getCompilationDir(),
DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, File)) { DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, File)) {
File = '"' + File + '"'; File = '"' + File + '"';
Name = File; Name = File;
} }
} else if (Optional<uint64_t> Val = formValue.getAsUnsignedConstant()) } else if (Optional<uint64_t> Val = FormValue.getAsUnsignedConstant())
Name = AttributeValueString(Attr, *Val); Name = AttributeValueString(Attr, *Val);
if (!Name.empty()) if (!Name.empty())
WithColor(OS, Color) << Name; WithColor(OS, Color) << Name;
else if (Attr == DW_AT_decl_line || Attr == DW_AT_call_line) else if (Attr == DW_AT_decl_line || Attr == DW_AT_call_line)
OS << *formValue.getAsUnsignedConstant(); OS << *FormValue.getAsUnsignedConstant();
else if (Attr == DW_AT_high_pc && !DumpOpts.ShowForm && !DumpOpts.Verbose && else if (Attr == DW_AT_high_pc && !DumpOpts.ShowForm && !DumpOpts.Verbose &&
formValue.getAsUnsignedConstant()) { FormValue.getAsUnsignedConstant()) {
if (DumpOpts.ShowAddresses) { if (DumpOpts.ShowAddresses) {
// Print the actual address rather than the offset. // Print the actual address rather than the offset.
uint64_t LowPC, HighPC, Index; uint64_t LowPC, HighPC, Index;
if (Die.getLowAndHighPC(LowPC, HighPC, Index)) if (Die.getLowAndHighPC(LowPC, HighPC, Index))
OS << format("0x%016" PRIx64, HighPC); OS << format("0x%016" PRIx64, HighPC);
else else
formValue.dump(OS, DumpOpts); FormValue.dump(OS, DumpOpts);
} }
} else if (Attr == DW_AT_location || Attr == DW_AT_frame_base || } else if (Attr == DW_AT_location || Attr == DW_AT_frame_base ||
Attr == DW_AT_data_member_location || Attr == DW_AT_data_member_location ||
Attr == DW_AT_GNU_call_site_value) Attr == DW_AT_GNU_call_site_value)
dumpLocation(OS, formValue, U, sizeof(BaseIndent) + Indent + 4, DumpOpts); dumpLocation(OS, FormValue, U, sizeof(BaseIndent) + Indent + 4, DumpOpts);
else else
formValue.dump(OS, DumpOpts); FormValue.dump(OS, DumpOpts);
std::string Space = DumpOpts.ShowAddresses ? " " : ""; std::string Space = DumpOpts.ShowAddresses ? " " : "";
@ -330,25 +326,25 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
// interesting. These attributes are handled below. // interesting. These attributes are handled below.
if (Attr == DW_AT_specification || Attr == DW_AT_abstract_origin) { if (Attr == DW_AT_specification || Attr == DW_AT_abstract_origin) {
if (const char *Name = if (const char *Name =
Die.getAttributeValueAsReferencedDie(formValue).getName( Die.getAttributeValueAsReferencedDie(FormValue).getName(
DINameKind::LinkageName)) DINameKind::LinkageName))
OS << Space << "\"" << Name << '\"'; OS << Space << "\"" << Name << '\"';
} else if (Attr == DW_AT_type) { } else if (Attr == DW_AT_type) {
OS << Space << "\""; OS << Space << "\"";
dumpTypeName(OS, Die.getAttributeValueAsReferencedDie(formValue)); dumpTypeName(OS, Die.getAttributeValueAsReferencedDie(FormValue));
OS << '"'; OS << '"';
} else if (Attr == DW_AT_APPLE_property_attribute) { } else if (Attr == DW_AT_APPLE_property_attribute) {
if (Optional<uint64_t> OptVal = formValue.getAsUnsignedConstant()) if (Optional<uint64_t> OptVal = FormValue.getAsUnsignedConstant())
dumpApplePropertyAttribute(OS, *OptVal); dumpApplePropertyAttribute(OS, *OptVal);
} else if (Attr == DW_AT_ranges) { } else if (Attr == DW_AT_ranges) {
const DWARFObject &Obj = Die.getDwarfUnit()->getContext().getDWARFObj(); const DWARFObject &Obj = Die.getDwarfUnit()->getContext().getDWARFObj();
// For DW_FORM_rnglistx we need to dump the offset separately, since // For DW_FORM_rnglistx we need to dump the offset separately, since
// we have only dumped the index so far. // we have only dumped the index so far.
if (formValue.getForm() == DW_FORM_rnglistx) if (FormValue.getForm() == DW_FORM_rnglistx)
if (auto RangeListOffset = if (auto RangeListOffset =
U->getRnglistOffset(*formValue.getAsSectionOffset())) { U->getRnglistOffset(*FormValue.getAsSectionOffset())) {
DWARFFormValue FV(dwarf::DW_FORM_sec_offset); DWARFFormValue FV = DWARFFormValue::createFromUValue(
FV.setUValue(*RangeListOffset); dwarf::DW_FORM_sec_offset, *RangeListOffset);
FV.dump(OS, DumpOpts); FV.dump(OS, DumpOpts);
} }
if (auto RangesOrError = Die.getAddressRanges()) if (auto RangesOrError = Die.getAddressRanges())
@ -689,14 +685,11 @@ void DWARFDie::attribute_iterator::updateForIndex(
AttrValue.Attr = AbbrDecl.getAttrByIndex(Index); AttrValue.Attr = AbbrDecl.getAttrByIndex(Index);
// Add the previous byte size of any previous attribute value. // Add the previous byte size of any previous attribute value.
AttrValue.Offset += AttrValue.ByteSize; AttrValue.Offset += AttrValue.ByteSize;
AttrValue.Value.setForm(AbbrDecl.getFormByIndex(Index));
uint32_t ParseOffset = AttrValue.Offset; uint32_t ParseOffset = AttrValue.Offset;
auto U = Die.getDwarfUnit(); auto U = Die.getDwarfUnit();
assert(U && "Die must have valid DWARF unit"); assert(U && "Die must have valid DWARF unit");
bool b = AttrValue.Value.extractValue(U->getDebugInfoExtractor(), AttrValue.Value = DWARFFormValue::createFromUnit(
&ParseOffset, U->getFormParams(), U); AbbrDecl.getFormByIndex(Index), U, &ParseOffset);
(void)b;
assert(b && "extractValue cannot fail on fully parsed DWARF");
AttrValue.ByteSize = ParseOffset - AttrValue.Offset; AttrValue.ByteSize = ParseOffset - AttrValue.Offset;
} else { } else {
assert(Index == NumAttrs && "Indexes should be [0, NumAttrs) only"); assert(Index == NumAttrs && "Indexes should be [0, NumAttrs) only");

View File

@ -77,6 +77,34 @@ static const DWARFFormValue::FormClass DWARF5FormClasses[] = {
}; };
DWARFFormValue DWARFFormValue::createFromSValue(dwarf::Form F, int64_t V) {
return DWARFFormValue(F, ValueType(V));
}
DWARFFormValue DWARFFormValue::createFromUValue(dwarf::Form F, uint64_t V) {
return DWARFFormValue(F, ValueType(V));
}
DWARFFormValue DWARFFormValue::createFromPValue(dwarf::Form F, const char *V) {
return DWARFFormValue(F, ValueType(V));
}
DWARFFormValue DWARFFormValue::createFromBlockValue(dwarf::Form F,
ArrayRef<uint8_t> D) {
ValueType V;
V.uval = D.size();
V.data = D.data();
return DWARFFormValue(F, V);
}
DWARFFormValue DWARFFormValue::createFromUnit(dwarf::Form F, const DWARFUnit *U,
uint32_t *OffsetPtr) {
DWARFFormValue FormValue(F);
FormValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr,
U->getFormParams(), U);
return FormValue;
}
bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData, bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
uint32_t *OffsetPtr, uint32_t *OffsetPtr,
const dwarf::FormParams Params) { const dwarf::FormParams Params) {

View File

@ -1555,128 +1555,123 @@ TEST(DWARFDebugInfo, TestFindRecurse) {
TEST(DWARFDebugInfo, TestDwarfToFunctions) { TEST(DWARFDebugInfo, TestDwarfToFunctions) {
// Test all of the dwarf::toXXX functions that take a // Test all of the dwarf::toXXX functions that take a
// Optional<DWARFFormValue> and extract the values from it. // Optional<DWARFFormValue> and extract the values from it.
DWARFFormValue FormVal;
uint64_t InvalidU64 = 0xBADBADBADBADBADB; uint64_t InvalidU64 = 0xBADBADBADBADBADB;
int64_t InvalidS64 = 0xBADBADBADBADBADB; int64_t InvalidS64 = 0xBADBADBADBADBADB;
// First test that we don't get valid values back when using an optional with // First test that we don't get valid values back when using an optional with
// no value. // no value.
Optional<DWARFFormValue> FormValOpt; Optional<DWARFFormValue> FormValOpt1 = DWARFFormValue();
EXPECT_FALSE(toString(FormValOpt).hasValue()); EXPECT_FALSE(toString(FormValOpt1).hasValue());
EXPECT_FALSE(toUnsigned(FormValOpt).hasValue()); EXPECT_FALSE(toUnsigned(FormValOpt1).hasValue());
EXPECT_FALSE(toReference(FormValOpt).hasValue()); EXPECT_FALSE(toReference(FormValOpt1).hasValue());
EXPECT_FALSE(toSigned(FormValOpt).hasValue()); EXPECT_FALSE(toSigned(FormValOpt1).hasValue());
EXPECT_FALSE(toAddress(FormValOpt).hasValue()); EXPECT_FALSE(toAddress(FormValOpt1).hasValue());
EXPECT_FALSE(toSectionOffset(FormValOpt).hasValue()); EXPECT_FALSE(toSectionOffset(FormValOpt1).hasValue());
EXPECT_FALSE(toBlock(FormValOpt).hasValue()); EXPECT_FALSE(toBlock(FormValOpt1).hasValue());
EXPECT_EQ(nullptr, toString(FormValOpt, nullptr)); EXPECT_EQ(nullptr, toString(FormValOpt1, nullptr));
EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt, InvalidU64)); EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt1, InvalidU64));
EXPECT_EQ(InvalidU64, toReference(FormValOpt, InvalidU64)); EXPECT_EQ(InvalidU64, toReference(FormValOpt1, InvalidU64));
EXPECT_EQ(InvalidU64, toAddress(FormValOpt, InvalidU64)); EXPECT_EQ(InvalidU64, toAddress(FormValOpt1, InvalidU64));
EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt, InvalidU64)); EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt1, InvalidU64));
EXPECT_EQ(InvalidS64, toSigned(FormValOpt, InvalidS64)); EXPECT_EQ(InvalidS64, toSigned(FormValOpt1, InvalidS64));
// Test successful and unsuccessful address decoding. // Test successful and unsuccessful address decoding.
uint64_t Address = 0x100000000ULL; uint64_t Address = 0x100000000ULL;
FormVal.setForm(DW_FORM_addr); Optional<DWARFFormValue> FormValOpt2 =
FormVal.setUValue(Address); DWARFFormValue::createFromUValue(DW_FORM_addr, Address);
FormValOpt = FormVal;
EXPECT_FALSE(toString(FormValOpt).hasValue()); EXPECT_FALSE(toString(FormValOpt2).hasValue());
EXPECT_FALSE(toUnsigned(FormValOpt).hasValue()); EXPECT_FALSE(toUnsigned(FormValOpt2).hasValue());
EXPECT_FALSE(toReference(FormValOpt).hasValue()); EXPECT_FALSE(toReference(FormValOpt2).hasValue());
EXPECT_FALSE(toSigned(FormValOpt).hasValue()); EXPECT_FALSE(toSigned(FormValOpt2).hasValue());
EXPECT_TRUE(toAddress(FormValOpt).hasValue()); EXPECT_TRUE(toAddress(FormValOpt2).hasValue());
EXPECT_FALSE(toSectionOffset(FormValOpt).hasValue()); EXPECT_FALSE(toSectionOffset(FormValOpt2).hasValue());
EXPECT_FALSE(toBlock(FormValOpt).hasValue()); EXPECT_FALSE(toBlock(FormValOpt2).hasValue());
EXPECT_EQ(nullptr, toString(FormValOpt, nullptr)); EXPECT_EQ(nullptr, toString(FormValOpt2, nullptr));
EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt, InvalidU64)); EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt2, InvalidU64));
EXPECT_EQ(InvalidU64, toReference(FormValOpt, InvalidU64)); EXPECT_EQ(InvalidU64, toReference(FormValOpt2, InvalidU64));
EXPECT_EQ(Address, toAddress(FormValOpt, InvalidU64)); EXPECT_EQ(Address, toAddress(FormValOpt2, InvalidU64));
EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt, InvalidU64)); EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt2, InvalidU64));
EXPECT_EQ(InvalidS64, toSigned(FormValOpt, InvalidU64)); EXPECT_EQ(InvalidS64, toSigned(FormValOpt2, InvalidU64));
// Test successful and unsuccessful unsigned constant decoding. // Test successful and unsuccessful unsigned constant decoding.
uint64_t UData8 = 0x1020304050607080ULL; uint64_t UData8 = 0x1020304050607080ULL;
FormVal.setForm(DW_FORM_udata); Optional<DWARFFormValue> FormValOpt3 =
FormVal.setUValue(UData8); DWARFFormValue::createFromUValue(DW_FORM_udata, UData8);
FormValOpt = FormVal;
EXPECT_FALSE(toString(FormValOpt).hasValue()); EXPECT_FALSE(toString(FormValOpt3).hasValue());
EXPECT_TRUE(toUnsigned(FormValOpt).hasValue()); EXPECT_TRUE(toUnsigned(FormValOpt3).hasValue());
EXPECT_FALSE(toReference(FormValOpt).hasValue()); EXPECT_FALSE(toReference(FormValOpt3).hasValue());
EXPECT_TRUE(toSigned(FormValOpt).hasValue()); EXPECT_TRUE(toSigned(FormValOpt3).hasValue());
EXPECT_FALSE(toAddress(FormValOpt).hasValue()); EXPECT_FALSE(toAddress(FormValOpt3).hasValue());
EXPECT_FALSE(toSectionOffset(FormValOpt).hasValue()); EXPECT_FALSE(toSectionOffset(FormValOpt3).hasValue());
EXPECT_FALSE(toBlock(FormValOpt).hasValue()); EXPECT_FALSE(toBlock(FormValOpt3).hasValue());
EXPECT_EQ(nullptr, toString(FormValOpt, nullptr)); EXPECT_EQ(nullptr, toString(FormValOpt3, nullptr));
EXPECT_EQ(UData8, toUnsigned(FormValOpt, InvalidU64)); EXPECT_EQ(UData8, toUnsigned(FormValOpt3, InvalidU64));
EXPECT_EQ(InvalidU64, toReference(FormValOpt, InvalidU64)); EXPECT_EQ(InvalidU64, toReference(FormValOpt3, InvalidU64));
EXPECT_EQ(InvalidU64, toAddress(FormValOpt, InvalidU64)); EXPECT_EQ(InvalidU64, toAddress(FormValOpt3, InvalidU64));
EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt, InvalidU64)); EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt3, InvalidU64));
EXPECT_EQ((int64_t)UData8, toSigned(FormValOpt, InvalidU64)); EXPECT_EQ((int64_t)UData8, toSigned(FormValOpt3, InvalidU64));
// Test successful and unsuccessful reference decoding. // Test successful and unsuccessful reference decoding.
uint32_t RefData = 0x11223344U; uint32_t RefData = 0x11223344U;
FormVal.setForm(DW_FORM_ref_addr); Optional<DWARFFormValue> FormValOpt4 =
FormVal.setUValue(RefData); DWARFFormValue::createFromUValue(DW_FORM_ref_addr, RefData);
FormValOpt = FormVal;
EXPECT_FALSE(toString(FormValOpt).hasValue()); EXPECT_FALSE(toString(FormValOpt4).hasValue());
EXPECT_FALSE(toUnsigned(FormValOpt).hasValue()); EXPECT_FALSE(toUnsigned(FormValOpt4).hasValue());
EXPECT_TRUE(toReference(FormValOpt).hasValue()); EXPECT_TRUE(toReference(FormValOpt4).hasValue());
EXPECT_FALSE(toSigned(FormValOpt).hasValue()); EXPECT_FALSE(toSigned(FormValOpt4).hasValue());
EXPECT_FALSE(toAddress(FormValOpt).hasValue()); EXPECT_FALSE(toAddress(FormValOpt4).hasValue());
EXPECT_FALSE(toSectionOffset(FormValOpt).hasValue()); EXPECT_FALSE(toSectionOffset(FormValOpt4).hasValue());
EXPECT_FALSE(toBlock(FormValOpt).hasValue()); EXPECT_FALSE(toBlock(FormValOpt4).hasValue());
EXPECT_EQ(nullptr, toString(FormValOpt, nullptr)); EXPECT_EQ(nullptr, toString(FormValOpt4, nullptr));
EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt, InvalidU64)); EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt4, InvalidU64));
EXPECT_EQ(RefData, toReference(FormValOpt, InvalidU64)); EXPECT_EQ(RefData, toReference(FormValOpt4, InvalidU64));
EXPECT_EQ(InvalidU64, toAddress(FormValOpt, InvalidU64)); EXPECT_EQ(InvalidU64, toAddress(FormValOpt4, InvalidU64));
EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt, InvalidU64)); EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt4, InvalidU64));
EXPECT_EQ(InvalidS64, toSigned(FormValOpt, InvalidU64)); EXPECT_EQ(InvalidS64, toSigned(FormValOpt4, InvalidU64));
// Test successful and unsuccessful signed constant decoding. // Test successful and unsuccessful signed constant decoding.
int64_t SData8 = 0x1020304050607080ULL; int64_t SData8 = 0x1020304050607080ULL;
FormVal.setForm(DW_FORM_udata); Optional<DWARFFormValue> FormValOpt5 =
FormVal.setSValue(SData8); DWARFFormValue::createFromSValue(DW_FORM_udata, SData8);
FormValOpt = FormVal;
EXPECT_FALSE(toString(FormValOpt).hasValue()); EXPECT_FALSE(toString(FormValOpt5).hasValue());
EXPECT_TRUE(toUnsigned(FormValOpt).hasValue()); EXPECT_TRUE(toUnsigned(FormValOpt5).hasValue());
EXPECT_FALSE(toReference(FormValOpt).hasValue()); EXPECT_FALSE(toReference(FormValOpt5).hasValue());
EXPECT_TRUE(toSigned(FormValOpt).hasValue()); EXPECT_TRUE(toSigned(FormValOpt5).hasValue());
EXPECT_FALSE(toAddress(FormValOpt).hasValue()); EXPECT_FALSE(toAddress(FormValOpt5).hasValue());
EXPECT_FALSE(toSectionOffset(FormValOpt).hasValue()); EXPECT_FALSE(toSectionOffset(FormValOpt5).hasValue());
EXPECT_FALSE(toBlock(FormValOpt).hasValue()); EXPECT_FALSE(toBlock(FormValOpt5).hasValue());
EXPECT_EQ(nullptr, toString(FormValOpt, nullptr)); EXPECT_EQ(nullptr, toString(FormValOpt5, nullptr));
EXPECT_EQ((uint64_t)SData8, toUnsigned(FormValOpt, InvalidU64)); EXPECT_EQ((uint64_t)SData8, toUnsigned(FormValOpt5, InvalidU64));
EXPECT_EQ(InvalidU64, toReference(FormValOpt, InvalidU64)); EXPECT_EQ(InvalidU64, toReference(FormValOpt5, InvalidU64));
EXPECT_EQ(InvalidU64, toAddress(FormValOpt, InvalidU64)); EXPECT_EQ(InvalidU64, toAddress(FormValOpt5, InvalidU64));
EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt, InvalidU64)); EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt5, InvalidU64));
EXPECT_EQ(SData8, toSigned(FormValOpt, InvalidU64)); EXPECT_EQ(SData8, toSigned(FormValOpt5, InvalidU64));
// Test successful and unsuccessful block decoding. // Test successful and unsuccessful block decoding.
uint8_t Data[] = { 2, 3, 4 }; uint8_t Data[] = { 2, 3, 4 };
ArrayRef<uint8_t> Array(Data); ArrayRef<uint8_t> Array(Data);
FormVal.setForm(DW_FORM_block1); Optional<DWARFFormValue> FormValOpt6 =
FormVal.setBlockValue(Array); DWARFFormValue::createFromBlockValue(DW_FORM_block1, Array);
FormValOpt = FormVal;
EXPECT_FALSE(toString(FormValOpt).hasValue()); EXPECT_FALSE(toString(FormValOpt6).hasValue());
EXPECT_FALSE(toUnsigned(FormValOpt).hasValue()); EXPECT_FALSE(toUnsigned(FormValOpt6).hasValue());
EXPECT_FALSE(toReference(FormValOpt).hasValue()); EXPECT_FALSE(toReference(FormValOpt6).hasValue());
EXPECT_FALSE(toSigned(FormValOpt).hasValue()); EXPECT_FALSE(toSigned(FormValOpt6).hasValue());
EXPECT_FALSE(toAddress(FormValOpt).hasValue()); EXPECT_FALSE(toAddress(FormValOpt6).hasValue());
EXPECT_FALSE(toSectionOffset(FormValOpt).hasValue()); EXPECT_FALSE(toSectionOffset(FormValOpt6).hasValue());
auto BlockOpt = toBlock(FormValOpt); auto BlockOpt = toBlock(FormValOpt6);
EXPECT_TRUE(BlockOpt.hasValue()); EXPECT_TRUE(BlockOpt.hasValue());
EXPECT_EQ(*BlockOpt, Array); EXPECT_EQ(*BlockOpt, Array);
EXPECT_EQ(nullptr, toString(FormValOpt, nullptr)); EXPECT_EQ(nullptr, toString(FormValOpt6, nullptr));
EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt, InvalidU64)); EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt6, InvalidU64));
EXPECT_EQ(InvalidU64, toReference(FormValOpt, InvalidU64)); EXPECT_EQ(InvalidU64, toReference(FormValOpt6, InvalidU64));
EXPECT_EQ(InvalidU64, toAddress(FormValOpt, InvalidU64)); EXPECT_EQ(InvalidU64, toAddress(FormValOpt6, InvalidU64));
EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt, InvalidU64)); EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt6, InvalidU64));
EXPECT_EQ(InvalidS64, toSigned(FormValOpt, InvalidU64)); EXPECT_EQ(InvalidS64, toSigned(FormValOpt6, InvalidU64));
// Test // Test
} }

View File

@ -183,11 +183,11 @@ DWARFDebugLine::Prologue dwarfgen::LineTable::createBasicPrologue() const {
P.LineRange = 14; P.LineRange = 14;
P.OpcodeBase = 13; P.OpcodeBase = 13;
P.StandardOpcodeLengths = {0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1}; P.StandardOpcodeLengths = {0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1};
P.IncludeDirectories.push_back(DWARFFormValue(DW_FORM_string)); P.IncludeDirectories.push_back(
P.IncludeDirectories.back().setPValue("a dir"); DWARFFormValue::createFromPValue(DW_FORM_string, "a dir"));
P.FileNames.push_back(DWARFDebugLine::FileNameEntry()); P.FileNames.push_back(DWARFDebugLine::FileNameEntry());
P.FileNames.back().Name.setPValue("a file"); P.FileNames.back().Name =
P.FileNames.back().Name.setForm(DW_FORM_string); DWARFFormValue::createFromPValue(DW_FORM_string, "a file");
return P; return P;
} }