Move the accessor functions from DIExpression::iterator into a wrapper

DIExpression::Operand, so we can write range-based for loops.

Thanks to David Blaikie for the idea.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226939 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Adrian Prantl 2015-01-23 21:24:41 +00:00
parent d4c7c06a39
commit d5dc4cff6a
3 changed files with 30 additions and 21 deletions

View File

@ -867,16 +867,17 @@ public:
/// \brief Return the size of this piece in bytes. /// \brief Return the size of this piece in bytes.
uint64_t getPieceSize() const; uint64_t getPieceSize() const;
class Operand;
/// \brief An iterator for DIExpression elements. /// \brief An iterator for DIExpression elements.
class iterator : public std::iterator<std::forward_iterator_tag, StringRef, class iterator : public std::iterator<std::forward_iterator_tag, StringRef,
unsigned, const uint64_t *, uint64_t> { unsigned, const uint64_t *, uint64_t> {
DIHeaderFieldIterator I; DIHeaderFieldIterator I;
iterator(DIHeaderFieldIterator I) : I(I) {} iterator(DIHeaderFieldIterator I) : I(I) {}
public: public:
iterator() {} iterator() {}
iterator(const DIExpression &Expr) : I(++Expr.header_begin()) {} iterator(const DIExpression &Expr) : I(++Expr.header_begin()) {}
uint64_t operator*() const { return I.getNumber<uint64_t>(); } Operand operator*() const { return Operand(I); }
iterator &operator++() { iterator &operator++() {
increment(); increment();
return *this; return *this;
@ -889,14 +890,7 @@ public:
bool operator==(const iterator &X) const { return I == X.I; } bool operator==(const iterator &X) const { return I == X.I; }
bool operator!=(const iterator &X) const { return !(*this == X); } bool operator!=(const iterator &X) const { return !(*this == X); }
uint64_t getArg(unsigned N) const {
auto In = I;
std::advance(In, N);
return In.getNumber<uint64_t>();
}
const DIHeaderFieldIterator &getBase() const { return I; } const DIHeaderFieldIterator &getBase() const { return I; }
private: private:
void increment() { void increment() {
switch (**this) { switch (**this) {
@ -911,6 +905,22 @@ public:
iterator begin() const; iterator begin() const;
iterator end() const; iterator end() const;
/// \brief A lightweight wrapper around an element of a DIExpression.
class Operand {
DIHeaderFieldIterator I;
public:
Operand(DIHeaderFieldIterator I) : I(I) {}
/// \brief Operands such as DW_OP_piece have explicit (non-stack) arguments.
/// Argument 0 is the operand itself.
uint64_t getArg(unsigned N) const {
DIHeaderFieldIterator In = I;
std::advance(In, N);
return In.getNumber<uint64_t>();
}
operator uint64_t () const { return I.getNumber<uint64_t>(); }
};
}; };
/// \brief This object holds location information. /// \brief This object holds location information.

View File

@ -210,8 +210,8 @@ bool DwarfExpression::AddMachineRegExpression(DIExpression Expr,
switch (*I) { switch (*I) {
case dwarf::DW_OP_piece: { case dwarf::DW_OP_piece: {
unsigned SizeOfByte = 8; unsigned SizeOfByte = 8;
unsigned OffsetInBits = I.getArg(1) * SizeOfByte; unsigned OffsetInBits = (*I).getArg(1) * SizeOfByte;
unsigned SizeInBits = I.getArg(2) * SizeOfByte; unsigned SizeInBits = (*I).getArg(2) * SizeOfByte;
// 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));
@ -219,7 +219,7 @@ bool DwarfExpression::AddMachineRegExpression(DIExpression Expr,
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].
if (*std::next(I) == dwarf::DW_OP_deref) { if (*std::next(I) == dwarf::DW_OP_deref) {
unsigned Offset = I.getArg(1); unsigned Offset = (*I).getArg(1);
ValidReg = AddMachineRegIndirect(MachineReg, Offset); ValidReg = AddMachineRegIndirect(MachineReg, Offset);
std::advance(I, 2); std::advance(I, 2);
break; break;
@ -248,14 +248,14 @@ void DwarfExpression::AddExpression(DIExpression::iterator I,
switch (*I) { switch (*I) {
case dwarf::DW_OP_piece: { case dwarf::DW_OP_piece: {
unsigned SizeOfByte = 8; unsigned SizeOfByte = 8;
unsigned OffsetInBits = I.getArg(1) * SizeOfByte; unsigned OffsetInBits = (*I).getArg(1) * SizeOfByte;
unsigned SizeInBits = I.getArg(2) * SizeOfByte; unsigned SizeInBits = (*I).getArg(2) * SizeOfByte;
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(1));
break; break;
case dwarf::DW_OP_deref: case dwarf::DW_OP_deref:
EmitOp(dwarf::DW_OP_deref); EmitOp(dwarf::DW_OP_deref);

View File

@ -1406,16 +1406,15 @@ void DIVariable::printInternal(raw_ostream &OS) const {
} }
void DIExpression::printInternal(raw_ostream &OS) const { void DIExpression::printInternal(raw_ostream &OS) const {
for (auto E = end(), I = begin(); I != E; ++I) { for (auto Op : *this) {
uint64_t OpCode = *I; OS << " [" << OperationEncodingString(Op);
OS << " [" << OperationEncodingString(OpCode); switch (Op) {
switch (OpCode) {
case DW_OP_plus: { case DW_OP_plus: {
OS << " " << I.getArg(1); OS << " " << Op.getArg(1);
break; break;
} }
case DW_OP_piece: { case DW_OP_piece: {
OS << " offset=" << I.getArg(1) << ", size=" << I.getArg(2); OS << " offset=" << Op.getArg(1) << ", size=" << Op.getArg(2);
break; break;
} }
case DW_OP_deref: case DW_OP_deref: