[llvm] r268941 - Make TypeIterator generic so it can iterate symbols too.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Mon May 9 10:44:58 PDT 2016


Author: zturner
Date: Mon May  9 12:44:58 2016
New Revision: 268941

URL: http://llvm.org/viewvc/llvm-project?rev=268941&view=rev
Log:
Make TypeIterator generic so it can iterate symbols too.

Reviewed By: amccarth
Differential Revision: http://reviews.llvm.org/D20038

Added:
    llvm/trunk/include/llvm/DebugInfo/CodeView/RecordIterator.h
Modified:
    llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStream.h
    llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp
    llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h?rev=268941&r1=268940&r2=268941&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h Mon May  9 12:44:58 2016
@@ -11,9 +11,9 @@
 #define LLVM_DEBUGINFO_CODEVIEW_CVTYPEVISITOR_H
 
 #include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/RecordIterator.h"
 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/CodeView/TypeStream.h"
 
 namespace llvm {
 namespace codeview {
@@ -51,32 +51,32 @@ public:
 #define MEMBER_RECORD_ALIAS(ClassName, LeafEnum)
 #include "TypeRecords.def"
 
-  void visitTypeRecord(const TypeIterator::TypeRecord &Record) {
-    ArrayRef<uint8_t> LeafData = Record.LeafData;
+  void visitTypeRecord(const TypeIterator::Record &Record) {
+    ArrayRef<uint8_t> LeafData = Record.Data;
     ArrayRef<uint8_t> RecordData = LeafData;
     auto *DerivedThis = static_cast<Derived *>(this);
-    DerivedThis->visitTypeBegin(Record.Leaf, RecordData);
-    switch (Record.Leaf) {
+    DerivedThis->visitTypeBegin(Record.Type, RecordData);
+    switch (Record.Type) {
     default:
-      DerivedThis->visitUnknownType(Record.Leaf);
+      DerivedThis->visitUnknownType(Record.Type);
       break;
     case LF_FIELDLIST:
-      DerivedThis->visitFieldList(Record.Leaf, LeafData);
+      DerivedThis->visitFieldList(Record.Type, LeafData);
       break;
     case LF_METHODLIST:
-      DerivedThis->visitMethodList(Record.Leaf, LeafData);
+      DerivedThis->visitMethodList(Record.Type, LeafData);
       break;
 #define TYPE_RECORD(ClassName, LeafEnum)                                       \
   case LeafEnum: {                                                             \
     const ClassName *Rec;                                                      \
     if (!CVTypeVisitor::consumeObject(LeafData, Rec))                          \
       return;                                                                  \
-    DerivedThis->visit##ClassName(Record.Leaf, Rec, LeafData);                 \
+    DerivedThis->visit##ClassName(Record.Type, Rec, LeafData);                 \
     break;                                                                     \
   }
 #include "TypeRecords.def"
       }
-      DerivedThis->visitTypeEnd(Record.Leaf, RecordData);
+      DerivedThis->visitTypeEnd(Record.Type, RecordData);
   }
 
   /// Visits the type records in Data. Sets the error flag on parse failures.

Added: llvm/trunk/include/llvm/DebugInfo/CodeView/RecordIterator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/RecordIterator.h?rev=268941&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/RecordIterator.h (added)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/RecordIterator.h Mon May  9 12:44:58 2016
@@ -0,0 +1,116 @@
+//===- RecordIterator.h -----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_RECORDITERATOR_H
+#define LLVM_DEBUGINFO_CODEVIEW_RECORDITERATOR_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/support/Endian.h"
+
+namespace llvm {
+namespace codeview {
+// A const input iterator interface to the CodeView record stream.
+template <typename Kind> class RecordIterator {
+private:
+  struct RecordPrefix {
+    support::ulittle16_t Len;  // Record length, starting from &Leaf
+    support::ulittle16_t Kind; // Record kind (a value from the `Kind` enum).
+  };
+
+public:
+  struct Record {
+    std::size_t Length;
+    Kind Type;
+    ArrayRef<uint8_t> Data;
+  };
+
+  explicit RecordIterator(const ArrayRef<uint8_t> &RecordBytes)
+      : Data(RecordBytes), AtEnd(false) {
+    next(); // Prime the pump
+  }
+
+  RecordIterator() : AtEnd(true) {}
+
+  // For iterators to compare equal, they must both point at the same record
+  // in the same data stream, or they must both be at the end of a stream.
+  friend bool operator==(const RecordIterator<Kind> &lhs,
+                         const RecordIterator<Kind> &rhs) {
+    return (lhs.Data.begin() == rhs.Data.begin()) || (lhs.AtEnd && rhs.AtEnd);
+  }
+
+  friend bool operator!=(const RecordIterator<Kind> &lhs,
+                         const RecordIterator<Kind> &rhs) {
+    return !(lhs == rhs);
+  }
+
+  const Record &operator*() const {
+    assert(!AtEnd);
+    return Current;
+  }
+
+  const Record *operator->() const {
+    assert(!AtEnd);
+    return &Current;
+  }
+
+  RecordIterator<Kind> &operator++() {
+    next();
+    return *this;
+  }
+
+  RecordIterator<Kind> operator++(int) {
+    RecordIterator<Kind> Original = *this;
+    ++*this;
+    return Original;
+  }
+
+private:
+  void next() {
+    assert(!AtEnd && "Attempted to advance more than one past the last rec");
+    if (Data.empty()) {
+      // We've advanced past the last record.
+      AtEnd = true;
+      return;
+    }
+
+    // FIXME: Use consumeObject when it deals in ArrayRef<uint8_t>.
+    if (Data.size() < sizeof(RecordPrefix))
+      return;
+    const auto *Rec = reinterpret_cast<const RecordPrefix *>(Data.data());
+    Data = Data.drop_front(sizeof(RecordPrefix));
+
+    Current.Length = Rec->Len;
+    Current.Type = static_cast<Kind>(uint16_t(Rec->Kind));
+    Current.Data = Data.slice(0, Current.Length - 2);
+
+    // The next record starts immediately after this one.
+    Data = Data.drop_front(Current.Data.size());
+
+    // FIXME: The stream contains LF_PAD bytes that we need to ignore, but those
+    // are typically included in LeafData. We may need to call skipPadding() if
+    // we ever find a record that doesn't count those bytes.
+
+    return;
+  }
+
+  ArrayRef<uint8_t> Data;
+  Record Current;
+  bool AtEnd;
+};
+
+template <typename Kind>
+inline iterator_range<RecordIterator<Kind>>
+makeRecordRange(ArrayRef<uint8_t> Data) {
+  return make_range(RecordIterator<Kind>(Data), RecordIterator<Kind>());
+}
+}
+}
+
+#endif

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h?rev=268941&r1=268940&r2=268941&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h Mon May  9 12:44:58 2016
@@ -11,6 +11,7 @@
 #define LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H
 
 #include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/RecordIterator.h"
 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
 #include "llvm/Support/Endian.h"
 
@@ -325,6 +326,12 @@ struct ThreadLocalDataSym {
   // Name: The null-terminated name follows.
 };
 
+typedef RecordIterator<SymbolRecordKind> SymbolIterator;
+
+inline iterator_range<SymbolIterator> makeSymbolRange(ArrayRef<uint8_t> Data) {
+  return make_range(SymbolIterator(Data), SymbolIterator());
+}
+
 } // namespace codeview
 } // namespace llvm
 

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h?rev=268941&r1=268940&r2=268941&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h Mon May  9 12:44:58 2016
@@ -34,7 +34,7 @@ public:
   /// and true otherwise.  This should be called in order, since the dumper
   /// maintains state about previous records which are necessary for cross
   /// type references.
-  bool dump(const TypeIterator::TypeRecord &Record);
+  bool dump(const TypeIterator::Record &Record);
 
   /// Dumps the type records in Data. Returns false if there was a type stream
   /// parse error, and true otherwise.

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h?rev=268941&r1=268940&r2=268941&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h Mon May  9 12:44:58 2016
@@ -275,10 +275,6 @@ private:
 // A CodeView type stream is a sequence of TypeRecords. Records larger than
 // 65536 must chain on to a second record. Each TypeRecord is followed by one of
 // the leaf types described below.
-struct TypeRecordPrefix {
-  ulittle16_t Len;  // Type record length, starting from &Leaf.
-  ulittle16_t Leaf; // Type record kind (TypeLeafKind)
-};
 
 // LF_TYPESERVER2
 struct TypeServer2 {

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStream.h?rev=268941&r1=268940&r2=268941&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStream.h Mon May  9 12:44:58 2016
@@ -10,13 +10,11 @@
 #ifndef LLVM_DEBUGINFO_CODEVIEW_TYPESTREAM_H
 #define LLVM_DEBUGINFO_CODEVIEW_TYPESTREAM_H
 
-#include "llvm/ADT/iterator_range.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/RecordIterator.h"
 #include "llvm/Object/Error.h"
 #include "llvm/Support/Endian.h"
-#include "llvm/Support/ErrorOr.h"
 
 #include <stdint.h>
 
@@ -62,86 +60,7 @@ inline bool decodeNumericLeaf(StringRef
 /// Decode a numeric leaf value that is known to be a uint32_t.
 bool decodeUIntLeaf(ArrayRef<uint8_t> &Data, uint64_t &Num);
 
-// A const input iterator interface to the CodeView type stream.
-class TypeIterator {
-public:
-  struct TypeRecord {
-    std::size_t Length;
-    TypeLeafKind Leaf;
-    ArrayRef<uint8_t> LeafData;
-  };
-
-  explicit TypeIterator(const ArrayRef<uint8_t> &SectionData)
-      : Data(SectionData), AtEnd(false) {
-    next(); // Prime the pump
-  }
-
-  TypeIterator() : AtEnd(true) {}
-
-  // For iterators to compare equal, they must both point at the same record
-  // in the same data stream, or they must both be at the end of a stream.
-  friend bool operator==(const TypeIterator &lhs, const TypeIterator &rhs) {
-    return (lhs.Data.begin() == rhs.Data.begin()) || (lhs.AtEnd && rhs.AtEnd);
-  }
-
-  friend bool operator!=(const TypeIterator &lhs, const TypeIterator &rhs) {
-    return !(lhs == rhs);
-  }
-
-  const TypeRecord &operator*() const {
-    assert(!AtEnd);
-    return Current;
-  }
-
-  const TypeRecord *operator->() const {
-    assert(!AtEnd);
-    return &Current;
-  }
-
-  TypeIterator operator++() {
-    next();
-    return *this;
-  }
-
-  TypeIterator operator++(int) {
-    TypeIterator Original = *this;
-    ++*this;
-    return Original;
-  }
-
-private:
-  void next() {
-    assert(!AtEnd && "Attempted to advance more than one past the last rec");
-    if (Data.empty()) {
-      // We've advanced past the last record.
-      AtEnd = true;
-      return;
-    }
-
-    // FIXME: Use consumeObject when it deals in ArrayRef<uint8_t>.
-    if (Data.size() < sizeof(TypeRecordPrefix))
-      return;
-    const auto *Rec = reinterpret_cast<const TypeRecordPrefix *>(Data.data());
-    Data = Data.drop_front(sizeof(TypeRecordPrefix));
-
-    Current.Length = Rec->Len;
-    Current.Leaf = static_cast<TypeLeafKind>(uint16_t(Rec->Leaf));
-    Current.LeafData = Data.slice(0, Current.Length - 2);
-
-    // The next record starts immediately after this one.
-    Data = Data.drop_front(Current.LeafData.size());
-
-    // FIXME: The stream contains LF_PAD bytes that we need to ignore, but those
-    // are typically included in LeafData. We may need to call skipPadding() if
-    // we ever find a record that doesn't count those bytes.
-
-    return;
-  }
-
-  ArrayRef<uint8_t> Data;
-  TypeRecord Current;
-  bool AtEnd;
-};
+typedef RecordIterator<TypeLeafKind> TypeIterator;
 
 inline iterator_range<TypeIterator> makeTypeRange(ArrayRef<uint8_t> Data) {
   return make_range(TypeIterator(Data), TypeIterator());

Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp?rev=268941&r1=268940&r2=268941&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp Mon May  9 12:44:58 2016
@@ -755,7 +755,7 @@ void CVTypeDumper::printTypeIndex(String
     W.printHex(FieldName, TI.getIndex());
 }
 
-bool CVTypeDumper::dump(const TypeIterator::TypeRecord &Record) {
+bool CVTypeDumper::dump(const TypeIterator::Record &Record) {
   CVTypeDumperImpl Dumper(*this, W, PrintRecordBytes);
   Dumper.visitTypeRecord(Record);
   return !Dumper.hadError();

Modified: llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp?rev=268941&r1=268940&r2=268941&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp Mon May  9 12:44:58 2016
@@ -363,7 +363,7 @@ static Error dumpTpiStream(ScopedPrinter
         TD.dump(Type);
 
       if (opts::DumpTpiRecordBytes)
-        P.printBinaryBlock("Bytes", Type.LeafData);
+        P.printBinaryBlock("Bytes", Type.Data);
     }
   }
   return Error::success();




More information about the llvm-commits mailing list