public:
DIHeaderFieldIterator() {}
- DIHeaderFieldIterator(StringRef Header)
+ explicit DIHeaderFieldIterator(StringRef Header)
: Header(Header), Current(Header.slice(0, Header.find('\0'))) {}
StringRef operator*() const { return Current; }
const StringRef * operator->() const { return &Current; }
DIHeaderFieldIterator());
}
+ DIHeaderFieldIterator header_begin() const {
+ return DIHeaderFieldIterator(getHeader());
+ }
+ DIHeaderFieldIterator header_end() const { return DIHeaderFieldIterator(); }
+
DIHeaderFieldIterator getHeaderIterator(unsigned Index) const {
// Since callers expect an empty string for out-of-range accesses, we can't
// use std::advance() here.
- for (DIHeaderFieldIterator I(getHeader()), E; I != E; ++I, --Index)
+ for (auto I = header_begin(), E = header_end(); I != E; ++I, --Index)
if (!Index)
return I;
- return StringRef();
+ return header_end();
}
StringRef getHeaderField(unsigned Index) const {
/// \brief Specialize DIRef constructor for DITypeRef.
template <> DIRef<DIType>::DIRef(const Metadata *V);
-/// \briefThis is a wrapper for a type.
+/// \brief This is a wrapper for a type.
///
/// FIXME: Types should be factored much better so that CV qualifiers and
/// others do not require a huge and empty descriptor full of zeros.
void printExtendedName(raw_ostream &OS) const;
};
-class DIExpressionIterator;
-
-/// \brief A complex location expression.
+/// \brief A complex location expression in postfix notation.
+///
+/// This is (almost) a DWARF expression that modifies the location of a
+/// variable or (or the location of a single piece of a variable).
+///
+/// FIXME: Instead of DW_OP_plus taking an argument, this should use DW_OP_const
+/// and have DW_OP_plus consume the topmost elements on the stack.
class DIExpression : public DIDescriptor {
friend class DIDescriptor;
void printInternal(raw_ostream &OS) const;
/// \brief Return the size of this piece in bytes.
uint64_t getPieceSize() const;
- DIExpressionIterator begin() const;
- DIExpressionIterator end() const;
-};
-
-/// \brief An iterator for DIExpression elments.
-class DIExpressionIterator
- : public std::iterator<std::forward_iterator_tag, StringRef, unsigned,
- const uint64_t *, uint64_t> {
- DIHeaderFieldIterator I;
- DIExpressionIterator(DIHeaderFieldIterator I) : I(I) {}
-public:
- DIExpressionIterator() {}
- DIExpressionIterator(const DIExpression Expr)
- : I(Expr.getHeader()) { ++I; }
- uint64_t operator*() const { return I.getNumber<uint64_t>(); }
- DIExpressionIterator &operator++() {
- increment();
- return *this;
- }
- DIExpressionIterator operator++(int) {
- DIExpressionIterator X(*this);
- increment();
- return X;
- }
- bool operator==(const DIExpressionIterator &X) const {
- return I == X.I;
- }
- bool operator!=(const DIExpressionIterator &X) const {
- return !(*this == X);
- }
-
- uint64_t getArg(unsigned N) const {
- auto In = I;
- std::advance(In, N);
- return *DIExpressionIterator(In);
- }
-
- const DIHeaderFieldIterator& getBase() const { return I; }
-
-private:
- void increment() {
- switch (**this) {
- case dwarf::DW_OP_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:
- assert("unsupported operand");
+ /// \brief An iterator for DIExpression elements.
+ class iterator
+ : public std::iterator<std::forward_iterator_tag, StringRef, unsigned,
+ const uint64_t *, uint64_t> {
+ DIHeaderFieldIterator I;
+ iterator(DIHeaderFieldIterator I) : I(I) {}
+ public:
+ iterator() {}
+ iterator(const DIExpression &Expr) : I(++Expr.header_begin()) {}
+ uint64_t operator*() const { return I.getNumber<uint64_t>(); }
+ 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);
+ }
+
+ uint64_t getArg(unsigned N) const {
+ auto In = I;
+ std::advance(In, N);
+ return In.getNumber<uint64_t>();
+ }
+
+ const DIHeaderFieldIterator& getBase() const { return I; }
+
+ private:
+ void increment() {
+ switch (**this) {
+ case dwarf::DW_OP_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:
+ assert("unsupported operand");
+ }
+ }
+ };
+ iterator begin() const;
+ iterator end() const;
+};
/// \brief This object holds location information.
///