diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h @@ -122,6 +122,10 @@ return Op; } + iterator skipBytes(uint64_t Add) { + return iterator(Expr, Op.EndOffset + Add); + } + // Comparison operators are provided out of line. friend bool operator==(const iterator &, const iterator &); }; diff --git a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp @@ -401,6 +401,27 @@ S << format("%+" PRId64, Offset); break; } + case dwarf::DW_OP_entry_value: + case dwarf::DW_OP_GNU_entry_value: { + // DW_OP_entry_value contains a sub-expression which must be rendered + // separately. + uint64_t SubExprLength = Op.getRawOperand(0); + DWARFExpression::iterator SubExprEnd = I.skipBytes(SubExprLength); + ++I; + raw_svector_ostream S(Stack.emplace_back().String); + S << "entry("; + printCompactDWARFExpr(S, I, SubExprEnd, MRI); + S << ")"; + I = SubExprEnd; + continue; + } + case dwarf::DW_OP_stack_value: { + // The top stack entry should be treated as the actual value of tne + // variable, rather than the address of the variable in memory. + assert(!Stack.empty()); + Stack.back().Kind = PrintedExpr::Value; + break; + } default: if (Opcode >= dwarf::DW_OP_reg0 && Opcode <= dwarf::DW_OP_reg31) { // DW_OP_reg: A register, with the register num implied by the diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp --- a/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp @@ -98,3 +98,18 @@ TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_bregx) { TestExprPrinter({DW_OP_bregx, 0x0d, 0x28}, "[SP+40]"); } + +TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_stack_value) { + TestExprPrinter({DW_OP_breg13, 0x04, DW_OP_stack_value}, "SP+4"); +} + +TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_entry_value) { + TestExprPrinter({DW_OP_entry_value, 0x01, DW_OP_reg0, DW_OP_stack_value}, + "entry(R0)"); +} + +TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_entry_value_mem) { + TestExprPrinter( + {DW_OP_entry_value, 0x02, DW_OP_breg13, 0x10, DW_OP_stack_value}, + "entry([SP+16])"); +}