DebugInfo: Remove special iterators from DIExpression

Remove special iterators from `DIExpression` in favour of same in
`MDExpression`.  There should be no functionality change here.

Note that the APIs are slightly different: `getArg(unsigned)` counts
from 0, not 1, in the `MDExpression` version of the iterator.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234285 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan P. N. Exon Smith
2015-04-07 03:45:57 +00:00
parent ad8a6b66d9
commit fb2e97e4aa
7 changed files with 27 additions and 83 deletions

View File

@ -872,66 +872,6 @@ public:
uint64_t getBitPieceOffset() const; uint64_t getBitPieceOffset() const;
/// \brief Return the size of this piece in bits. /// \brief Return the size of this piece in bits.
uint64_t getBitPieceSize() const; uint64_t getBitPieceSize() const;
class iterator;
/// \brief A lightweight wrapper around an element of a DIExpression.
class Operand {
friend class iterator;
MDExpression::element_iterator I;
Operand() {}
Operand(MDExpression::element_iterator I) : I(I) {}
public:
/// \brief Operands such as DW_OP_piece have explicit (non-stack) arguments.
/// Argument 0 is the operand itself.
uint64_t getArg(unsigned N) const {
MDExpression::element_iterator In = I;
std::advance(In, N);
return *In;
}
operator uint64_t () const { return *I; }
/// \brief Returns underlying MDExpression::element_iterator.
const MDExpression::element_iterator &getBase() const { return I; }
/// \brief Returns the next operand.
iterator getNext() const;
};
/// \brief An iterator for DIExpression elements.
class iterator : public std::iterator<std::input_iterator_tag, StringRef,
unsigned, const Operand*, Operand> {
friend class Operand;
MDExpression::element_iterator I;
Operand Tmp;
public:
iterator(MDExpression::element_iterator I) : I(I) {}
const Operand &operator*() { return Tmp = Operand(I); }
const Operand *operator->() { return &(Tmp = Operand(I)); }
iterator &operator++() {
increment();
return *this;
}
iterator operator++(int) {
iterator X(*this);
increment();
return X;
}
bool operator==(const iterator &X) const { return I == X.I; }
bool operator!=(const iterator &X) const { return !(*this == X); }
private:
void increment() {
switch (**this) {
case dwarf::DW_OP_bit_piece: std::advance(I, 3); break;
case dwarf::DW_OP_plus: std::advance(I, 2); break;
case dwarf::DW_OP_deref: std::advance(I, 1); break;
default:
llvm_unreachable("unsupported operand");
}
}
};
iterator begin() const { return get()->elements_begin(); }
iterator end() const { return get()->elements_end(); }
}; };
/// \brief This object holds location information. /// \brief This object holds location information.

View File

@ -1885,6 +1885,13 @@ public:
return T; return T;
} }
/// \brief Get the next iterator.
///
/// \a std::next() doesn't work because this is technically an
/// input_iterator, but it's a perfectly valid operation. This is an
/// accessor to provide the same functionality.
expr_op_iterator getNext() const { return ++expr_op_iterator(*this); }
bool operator==(const expr_op_iterator &X) const { bool operator==(const expr_op_iterator &X) const {
return getBase() == X.getBase(); return getBase() == X.getBase();
} }

View File

@ -523,7 +523,7 @@ DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
assert(Expr != DV.getExpression().end() && assert(Expr != DV.getExpression().end() &&
"Wrong number of expressions"); "Wrong number of expressions");
DwarfExpr.AddMachineRegIndirect(FrameReg, Offset); DwarfExpr.AddMachineRegIndirect(FrameReg, Offset);
DwarfExpr.AddExpression(Expr->begin(), Expr->end()); DwarfExpr.AddExpression((*Expr)->expr_op_begin(), (*Expr)->expr_op_end());
++Expr; ++Expr;
} }
addBlock(*VariableDie, dwarf::DW_AT_location, Loc); addBlock(*VariableDie, dwarf::DW_AT_location, Loc);
@ -773,7 +773,7 @@ void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die,
ValidReg = DwarfExpr.AddMachineRegIndirect(Location.getReg(), ValidReg = DwarfExpr.AddMachineRegIndirect(Location.getReg(),
Location.getOffset()); Location.getOffset());
if (ValidReg) if (ValidReg)
DwarfExpr.AddExpression(Expr.begin(), Expr.end()); DwarfExpr.AddExpression(Expr->expr_op_begin(), Expr->expr_op_end());
} else } else
ValidReg = DwarfExpr.AddMachineRegExpression(Expr, Location.getReg()); ValidReg = DwarfExpr.AddMachineRegExpression(Expr, Location.getReg());

View File

@ -1511,7 +1511,8 @@ static void emitDebugLocValue(const AsmPrinter &AP,
// Complex address entry. // Complex address entry.
if (Loc.getOffset()) { if (Loc.getOffset()) {
DwarfExpr.AddMachineRegIndirect(Loc.getReg(), Loc.getOffset()); DwarfExpr.AddMachineRegIndirect(Loc.getReg(), Loc.getOffset());
DwarfExpr.AddExpression(Expr.begin(), Expr.end(), PieceOffsetInBits); DwarfExpr.AddExpression(Expr->expr_op_begin(), Expr->expr_op_end(),
PieceOffsetInBits);
} else } else
DwarfExpr.AddMachineRegExpression(Expr, Loc.getReg(), DwarfExpr.AddMachineRegExpression(Expr, Loc.getReg(),
PieceOffsetInBits); PieceOffsetInBits);

View File

@ -195,27 +195,27 @@ static unsigned getOffsetOrZero(unsigned OffsetInBits,
bool DwarfExpression::AddMachineRegExpression(DIExpression Expr, bool DwarfExpression::AddMachineRegExpression(DIExpression Expr,
unsigned MachineReg, unsigned MachineReg,
unsigned PieceOffsetInBits) { unsigned PieceOffsetInBits) {
auto I = Expr.begin(); auto I = Expr->expr_op_begin();
auto E = Expr.end(); auto E = Expr->expr_op_end();
if (I == E) if (I == E)
return AddMachineRegPiece(MachineReg); return AddMachineRegPiece(MachineReg);
// Pattern-match combinations for which more efficient representations exist // Pattern-match combinations for which more efficient representations exist
// first. // first.
bool ValidReg = false; bool ValidReg = false;
switch (*I) { switch (I->getOp()) {
case dwarf::DW_OP_bit_piece: { case dwarf::DW_OP_bit_piece: {
unsigned OffsetInBits = I->getArg(1); unsigned OffsetInBits = I->getArg(0);
unsigned SizeInBits = I->getArg(2); unsigned SizeInBits = I->getArg(1);
// Piece always comes at the end of the expression. // Piece always comes at the end of the expression.
return AddMachineRegPiece(MachineReg, SizeInBits, return AddMachineRegPiece(MachineReg, SizeInBits,
getOffsetOrZero(OffsetInBits, PieceOffsetInBits)); getOffsetOrZero(OffsetInBits, PieceOffsetInBits));
} }
case dwarf::DW_OP_plus: { case dwarf::DW_OP_plus: {
// [DW_OP_reg,Offset,DW_OP_plus,DW_OP_deref] --> [DW_OP_breg,Offset]. // [DW_OP_reg,Offset,DW_OP_plus,DW_OP_deref] --> [DW_OP_breg,Offset].
auto N = I->getNext(); auto N = I.getNext();
if ((N != E) && (*N == dwarf::DW_OP_deref)) { if (N != E && N->getOp() == dwarf::DW_OP_deref) {
unsigned Offset = I->getArg(1); unsigned Offset = I->getArg(0);
ValidReg = AddMachineRegIndirect(MachineReg, Offset); ValidReg = AddMachineRegIndirect(MachineReg, Offset);
std::advance(I, 2); std::advance(I, 2);
break; break;
@ -240,20 +240,20 @@ bool DwarfExpression::AddMachineRegExpression(DIExpression Expr,
return true; return true;
} }
void DwarfExpression::AddExpression(DIExpression::iterator I, void DwarfExpression::AddExpression(MDExpression::expr_op_iterator I,
DIExpression::iterator E, MDExpression::expr_op_iterator E,
unsigned PieceOffsetInBits) { unsigned PieceOffsetInBits) {
for (; I != E; ++I) { for (; I != E; ++I) {
switch (*I) { switch (I->getOp()) {
case dwarf::DW_OP_bit_piece: { case dwarf::DW_OP_bit_piece: {
unsigned OffsetInBits = I->getArg(1); unsigned OffsetInBits = I->getArg(0);
unsigned SizeInBits = I->getArg(2); unsigned SizeInBits = I->getArg(1);
AddOpPiece(SizeInBits, getOffsetOrZero(OffsetInBits, PieceOffsetInBits)); AddOpPiece(SizeInBits, getOffsetOrZero(OffsetInBits, PieceOffsetInBits));
break; break;
} }
case dwarf::DW_OP_plus: case dwarf::DW_OP_plus:
EmitOp(dwarf::DW_OP_plus_uconst); EmitOp(dwarf::DW_OP_plus_uconst);
EmitUnsigned(I->getArg(1)); EmitUnsigned(I->getArg(0));
break; break;
case dwarf::DW_OP_deref: case dwarf::DW_OP_deref:
EmitOp(dwarf::DW_OP_deref); EmitOp(dwarf::DW_OP_deref);

View File

@ -97,7 +97,8 @@ public:
/// Emit a the operations remaining the DIExpressionIterator I. /// Emit a the operations remaining the DIExpressionIterator I.
/// \param PieceOffsetInBits If this is one piece out of a fragmented /// \param PieceOffsetInBits If this is one piece out of a fragmented
/// location, this is the offset of the piece inside the entire variable. /// location, this is the offset of the piece inside the entire variable.
void AddExpression(DIExpression::iterator I, DIExpression::iterator E, void AddExpression(MDExpression::expr_op_iterator I,
MDExpression::expr_op_iterator E,
unsigned PieceOffsetInBits = 0); unsigned PieceOffsetInBits = 0);
}; };

View File

@ -80,11 +80,6 @@ uint64_t DIExpression::getBitPieceSize() const {
return getElement(getNumElements()-1); return getElement(getNumElements()-1);
} }
DIExpression::iterator DIExpression::Operand::getNext() const {
iterator it(I);
return ++it;
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Simple Descriptor Constructors and other Methods // Simple Descriptor Constructors and other Methods
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//