Document DIExpression.
[oota-llvm.git] / include / llvm / IR / DebugInfo.h
index fc4d95cfc14712dffa0675c2fed7ee2ff76ba8e4..6294b797389ad80594793e99bbb3cfc7c1b53cc3 100644 (file)
@@ -66,7 +66,7 @@ class DIHeaderFieldIterator
 
 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; }
@@ -200,13 +200,18 @@ public:
                          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 {
@@ -392,7 +397,7 @@ template <> DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) 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.
@@ -845,9 +850,13 @@ public:
   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;
@@ -876,57 +885,55 @@ public:
   /// \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.
 ///