[llvm] r226747 - Rewrite DIExpression::Verify() using an iterator. NFC.

Adrian Prantl aprantl at apple.com
Wed Jan 21 16:00:53 PST 2015


Author: adrian
Date: Wed Jan 21 18:00:52 2015
New Revision: 226747

URL: http://llvm.org/viewvc/llvm-project?rev=226747&view=rev
Log:
Rewrite DIExpression::Verify() using an iterator. NFC.

Addresses review comments for r226627.

Modified:
    llvm/trunk/include/llvm/IR/DebugInfo.h
    llvm/trunk/lib/IR/DebugInfo.cpp

Modified: llvm/trunk/include/llvm/IR/DebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DebugInfo.h?rev=226747&r1=226746&r2=226747&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/DebugInfo.h (original)
+++ llvm/trunk/include/llvm/IR/DebugInfo.h Wed Jan 21 18:00:52 2015
@@ -59,7 +59,7 @@ class DIObjCProperty;
 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;
@@ -834,6 +834,8 @@ public:
   void printExtendedName(raw_ostream &OS) const;
 };
 
+class DIExpressionIterator;
+
 /// \brief A complex location expression.
 class DIExpression : public DIDescriptor {
   friend class DIDescriptor;
@@ -862,8 +864,64 @@ public:
   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 {
+    uint64_t UInt;
+    if (I->getAsInteger(0, UInt))
+      return 0;
+    return UInt;
+  }
+  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.

Modified: llvm/trunk/lib/IR/DebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DebugInfo.cpp?rev=226747&r1=226746&r2=226747&view=diff
==============================================================================
--- llvm/trunk/lib/IR/DebugInfo.cpp (original)
+++ llvm/trunk/lib/IR/DebugInfo.cpp Wed Jan 21 18:00:52 2015
@@ -162,6 +162,14 @@ uint64_t DIExpression::getPieceSize() co
   return getElement(getNumElements()-1);
 }
 
+DIExpressionIterator DIExpression::begin() const {
+  return DIExpressionIterator(*this);
+}
+
+DIExpressionIterator DIExpression::end() const {
+  return DIExpressionIterator();
+}
+
 //===----------------------------------------------------------------------===//
 // Predicates
 //===----------------------------------------------------------------------===//
@@ -595,25 +603,25 @@ bool DIExpression::Verify() const {
   if (!DbgNode)
     return true;
 
-  unsigned N = getNumElements();
-  for (unsigned I = 0; I < N; ++I)
-    switch (getElement(I)) {
+  if (!(isExpression() && DbgNode->getNumOperands() == 1))
+    return false;
+
+  for (auto E = end(), I = begin(); I != E; ++I)
+    switch (*I) {
     case DW_OP_piece:
-      // DW_OP_piece has to be the last element in the expression and take two
-      // arguments.
-      if (getElement(I) == DW_OP_piece && !isVariablePiece())
-        return false;
-      I += 2;
-      break;
+      // Must be the last element of the expression.
+      return std::distance(I.getBase(), DIHeaderFieldIterator()) == 3;
     case DW_OP_plus:
-      // Takes one argument.
-      if (I+1 == N)
+      if (std::distance(I.getBase(), DIHeaderFieldIterator()) < 2)
         return false;
-      I += 1;
       break;
-    default: break;
-  }
-  return isExpression() && DbgNode->getNumOperands() == 1;
+    case DW_OP_deref:
+      break;
+    default:
+      // Other operators are not yet supported by the backend.
+      return false;
+    }
+  return true;
 }
 
 bool DILocation::Verify() const {





More information about the llvm-commits mailing list