[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