index 5c85d6d528249b755b4c1b3ee4e295e473c85aaa..fc4d95cfc14712dffa0675c2fed7ee2ff76ba8e4 100644 (file)
typedef DenseMap<const MDString *, MDNode *> DITypeIdentifierMap;
class DIHeaderFieldIterator
- : public std::iterator<std::input_iterator_tag, StringRef, std::ptrdiff_t,
+ : public std::iterator<std::forward_iterator_tag, StringRef, std::ptrdiff_t,
const StringRef *, StringRef> {
StringRef Header;
StringRef Current;
return Header.slice(Current.end() - Header.begin() + 1, StringRef::npos);
}
+ /// \brief Get the current field as a number.
+ ///
+ /// Convert the current field into a number. Return \c 0 on error.
+ template <class T> T getNumber() const {
+ T Int;
+ if (getCurrent().getAsInteger(0, Int))
+ return 0;
+ return Int;
+ }
+
private:
void increment() {
assert(Current.data() != nullptr && "Cannot increment past the end");
FlagObjectPointer = 1 << 10,
FlagVector = 1 << 11,
FlagStaticMember = 1 << 12,
- FlagIndirectVariable = 1 << 13,
- FlagLValueReference = 1 << 14,
- FlagRValueReference = 1 << 15
+ FlagLValueReference = 1 << 13,
+ FlagRValueReference = 1 << 14
};
protected:
DIHeaderFieldIterator());
}
- StringRef getHeaderField(unsigned Index) const {
+ 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)
if (!Index)
- return *I;
+ return I;
return StringRef();
}
+ StringRef getHeaderField(unsigned Index) const {
+ return *getHeaderIterator(Index);
+ }
+
template <class T> T getHeaderFieldAs(unsigned Index) const {
- T Int;
- if (getHeaderField(Index).getAsInteger(0, Int))
- return 0;
- return Int;
+ return getHeaderIterator(Index).getNumber<T>();
}
uint16_t getTag() const { return getHeaderFieldAs<uint16_t>(0); }
return (getHeaderFieldAs<unsigned>(3) & FlagObjectPointer) != 0;
}
- /// \brief Return true if this variable is represented as a pointer.
- bool isIndirect() const {
- return (getHeaderFieldAs<unsigned>(3) & FlagIndirectVariable) != 0;
- }
-
/// \brief If this variable is inlined then return inline location.
MDNode *getInlinedAt() const;
void printExtendedName(raw_ostream &OS) const;
};
+class DIExpressionIterator;
+
/// \brief A complex location expression.
class DIExpression : public DIDescriptor {
friend class DIDescriptor;
uint64_t getPieceOffset() 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 This object holds location information.
///
/// This object is not associated with any DWARF tag.
/// \brief Process DILocation.
void processLocation(const Module &M, DILocation Loc);
+ /// \brief Process DIExpression.
+ void processExpression(DIExpression Expr);
+
/// \brief Clear all lists.
void reset();