diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h @@ -77,7 +77,10 @@ dwarf::Form getForm() const { return Form; } uint64_t getRawUValue() const { return Value.uval; } - bool isFormClass(FormClass FC) const; + /// Returns true if current value is of \p FC form class. + /// If current value does not have reference to original DWARFUnit + /// then \p DwarfVersion might be used to check form class of value. + bool isFormClass(FormClass FC, uint16_t DwarfVersion = 3) const; const DWARFUnit *getUnit() const { return U; } void dump(raw_ostream &OS, DIDumpOptions DumpOpts = DIDumpOptions()) const; void dumpSectionedAddress(raw_ostream &OS, DIDumpOptions DumpOpts, diff --git a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp @@ -213,7 +213,7 @@ return true; } -bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const { +bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC, uint16_t DwarfVersion) const { // First, check DWARF5 form classes. if (Form < ArrayRef(DWARF5FormClasses).size() && DWARF5FormClasses[Form] == FC) @@ -238,8 +238,12 @@ return true; // In DWARF3 DW_FORM_data4 and DW_FORM_data8 served also as a section // offset. If we don't have a DWARFUnit, default to the old behavior. - if (Form == DW_FORM_data4 || Form == DW_FORM_data8) - return !U || U->getVersion() <= 3; + if (Form == DW_FORM_data4 || Form == DW_FORM_data8) { + if (U) + return U->getVersion() <= 3; + + return DwarfVersion <= 3; + } } return false; diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp --- a/llvm/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp @@ -25,11 +25,17 @@ return DWARFFormValue(Form).isFormClass(FC); } +bool isFormClass(dwarf::Form Form, DWARFFormValue::FormClass FC, uint16_t DwarfVersion) { + return DWARFFormValue(Form).isFormClass(FC, DwarfVersion); +} + TEST(DWARFFormValue, FormClass) { EXPECT_TRUE(isFormClass(DW_FORM_addr, DWARFFormValue::FC_Address)); EXPECT_FALSE(isFormClass(DW_FORM_data8, DWARFFormValue::FC_Address)); EXPECT_TRUE(isFormClass(DW_FORM_data8, DWARFFormValue::FC_Constant)); EXPECT_TRUE(isFormClass(DW_FORM_data8, DWARFFormValue::FC_SectionOffset)); + EXPECT_TRUE(isFormClass(DW_FORM_data8, DWARFFormValue::FC_SectionOffset, 3)); + EXPECT_FALSE(isFormClass(DW_FORM_data8, DWARFFormValue::FC_SectionOffset, 5)); EXPECT_TRUE( isFormClass(DW_FORM_sec_offset, DWARFFormValue::FC_SectionOffset)); EXPECT_TRUE(isFormClass(DW_FORM_GNU_str_index, DWARFFormValue::FC_String));