<div dir="ltr">This change breaks the build:<div><br></div><div><a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/12486/steps/check-llvm%20ubsan/logs/stdio" class="cremed">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/12486/steps/check-llvm%20ubsan/logs/stdio</a></div><div><br></div><div><div>FAILED: /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm_build0/bin/clang++ -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Itools/llvm-pdbdump -I/mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/llvm-pdbdump -Iinclude -I/mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/include -fsanitize=undefined -w -fPIC -fvisibility-inlines-hidden -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wcovered-switch-default -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -std=c++11 -fno-omit-frame-pointer -O1 -fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all -fcolor-diagnostics -g -fno-exceptions -fno-rtti -MMD -MT tools/llvm-pdbdump/CMakeFiles/llvm-pdbdump.dir/llvm-pdbdump.cpp.o -MF tools/llvm-pdbdump/CMakeFiles/llvm-pdbdump.dir/llvm-pdbdump.cpp.o.d -o tools/llvm-pdbdump/CMakeFiles/llvm-pdbdump.dir/llvm-pdbdump.cpp.o -c /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp</div><div>/mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp:157:30: error: no matching function for call to 'min'</div><div> uint32_t BytesThisLine = std::min(Bytes.size(), BytesPerRow);</div><div> ^~~~~~~~</div><div>/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/algorithmfwd.h:367:5: note: candidate template ignored: deduced conflicting types for parameter '_Tp' ('unsigned long' vs. 'unsigned int')</div><div> min(const _Tp&, const _Tp&);</div><div> ^</div><div>/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/stl_algo.h:3444:5: note: candidate template ignored: could not match 'initializer_list<type-parameter-0-0>' against 'unsigned long'</div><div> min(initializer_list<_Tp> __l, _Compare __comp)</div><div> ^</div><div>/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/algorithmfwd.h:371:5: note: candidate function template not viable: requires 3 arguments, but 2 were provided</div><div> min(const _Tp&, const _Tp&, _Compare);</div><div> ^</div><div>/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/stl_algo.h:3439:5: note: candidate function template not viable: requires single argument '__l', but 2 arguments were provided</div><div> min(initializer_list<_Tp> __l)</div><div> ^</div><div>1 error generated.</div><div><br></div><br><div class="gmail_quote"><div dir="ltr">On Tue, May 3, 2016 at 3:24 PM Zachary Turner via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: zturner<br>
Date: Tue May 3 17:18:17 2016<br>
New Revision: 268454<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=268454&view=rev" rel="noreferrer" target="_blank" class="cremed">http://llvm.org/viewvc/llvm-project?rev=268454&view=rev</a><br>
Log:<br>
Move CodeViewTypeStream to DebugInfo/CodeView<br>
<br>
Ability to parse codeview type streams is also needed by<br>
DebugInfoPDB for parsing PDBs, so moving this into a library<br>
gives us this option. Since DebugInfoPDB had already hand<br>
rolled some code to do this, that code is now convereted over<br>
to using this common abstraction.<br>
<br>
Differential Revision: <a href="http://reviews.llvm.org/D19887" rel="noreferrer" target="_blank" class="cremed">http://reviews.llvm.org/D19887</a><br>
Reviewed By: dblaikie, amccarth<br>
<br>
Added:<br>
llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStream.h<br>
Modified:<br>
llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStream.h<br>
llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp<br>
llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp<br>
llvm/trunk/tools/llvm-readobj/COFFDumper.cpp<br>
<br>
Added: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStream.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStream.h?rev=268454&view=auto" rel="noreferrer" target="_blank" class="cremed">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStream.h?rev=268454&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStream.h (added)<br>
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStream.h Tue May 3 17:18:17 2016<br>
@@ -0,0 +1,130 @@<br>
+//===- TypeStream.h ---------------------------------------------*- C++ -*-===//<br>
+//<br>
+// The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPESTREAM_H<br>
+#define LLVM_DEBUGINFO_CODEVIEW_TYPESTREAM_H<br>
+<br>
+#include "llvm/ADT/iterator_range.h"<br>
+#include "llvm/ADT/StringRef.h"<br>
+#include "llvm/DebugInfo/CodeView/CodeView.h"<br>
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"<br>
+#include "llvm/Object/Error.h"<br>
+#include "llvm/Support/Endian.h"<br>
+#include "llvm/Support/ErrorOr.h"<br>
+<br>
+#include <stdint.h><br>
+<br>
+namespace llvm {<br>
+namespace codeview {<br>
+<br>
+/// Consumes sizeof(T) bytes from the given byte sequence. Returns an error if<br>
+/// there are not enough bytes remaining. Reinterprets the consumed bytes as a<br>
+/// T object and points 'Res' at them.<br>
+template <typename T><br>
+inline std::error_code consumeObject(StringRef &Data, const T *&Res) {<br>
+ if (Data.size() < sizeof(*Res))<br>
+ return object::object_error::parse_failed;<br>
+ Res = reinterpret_cast<const T *>(Data.data());<br>
+ Data = Data.drop_front(sizeof(*Res));<br>
+ return std::error_code();<br>
+}<br>
+<br>
+inline std::error_code consumeUInt32(StringRef &Data, uint32_t &Res) {<br>
+ const support::ulittle32_t *IntPtr;<br>
+ if (auto EC = consumeObject(Data, IntPtr))<br>
+ return EC;<br>
+ Res = *IntPtr;<br>
+ return std::error_code();<br>
+}<br>
+<br>
+// A const input iterator interface to the CodeView type stream.<br>
+class TypeIterator {<br>
+public:<br>
+ struct TypeRecord {<br>
+ std::size_t Length;<br>
+ TypeLeafKind Leaf;<br>
+ StringRef LeafData;<br>
+ };<br>
+<br>
+ explicit TypeIterator(const StringRef &SectionData)<br>
+ : Data(SectionData), AtEnd(false) {<br>
+ next(); // Prime the pump<br>
+ }<br>
+<br>
+ TypeIterator() : AtEnd(true) {}<br>
+<br>
+ // For iterators to compare equal, they must both point at the same record<br>
+ // in the same data stream, or they must both be at the end of a stream.<br>
+ friend bool operator==(const TypeIterator &lhs, const TypeIterator &rhs) {<br>
+ return (lhs.Data.begin() == rhs.Data.begin()) || (lhs.AtEnd && rhs.AtEnd);<br>
+ }<br>
+<br>
+ friend bool operator!=(const TypeIterator &lhs, const TypeIterator &rhs) {<br>
+ return !(lhs == rhs);<br>
+ }<br>
+<br>
+ const TypeRecord &operator*() const {<br>
+ assert(!AtEnd);<br>
+ return Current;<br>
+ }<br>
+<br>
+ const TypeRecord *operator->() const {<br>
+ assert(!AtEnd);<br>
+ return &Current;<br>
+ }<br>
+<br>
+ TypeIterator operator++() {<br>
+ next();<br>
+ return *this;<br>
+ }<br>
+<br>
+ TypeIterator operator++(int) {<br>
+ TypeIterator Original = *this;<br>
+ ++*this;<br>
+ return Original;<br>
+ }<br>
+<br>
+private:<br>
+ void next() {<br>
+ assert(!AtEnd && "Attempted to advance more than one past the last rec");<br>
+ if (Data.empty()) {<br>
+ // We've advanced past the last record.<br>
+ AtEnd = true;<br>
+ return;<br>
+ }<br>
+<br>
+ const TypeRecordPrefix *Rec;<br>
+ if (consumeObject(Data, Rec))<br>
+ return;<br>
+ Current.Length = Rec->Len;<br>
+ Current.Leaf = static_cast<TypeLeafKind>(uint16_t(Rec->Leaf));<br>
+ Current.LeafData = Data.substr(0, Current.Length - 2);<br>
+<br>
+ // The next record starts immediately after this one.<br>
+ Data = Data.drop_front(Current.LeafData.size());<br>
+<br>
+ // FIXME: The stream contains LF_PAD bytes that we need to ignore, but those<br>
+ // are typically included in LeafData. We may need to call skipPadding() if<br>
+ // we ever find a record that doesn't count those bytes.<br>
+<br>
+ return;<br>
+ }<br>
+<br>
+ StringRef Data;<br>
+ TypeRecord Current;<br>
+ bool AtEnd;<br>
+};<br>
+<br>
+inline iterator_range<TypeIterator> makeTypeRange(StringRef Data) {<br>
+ return make_range(TypeIterator(Data), TypeIterator());<br>
+}<br>
+}<br>
+}<br>
+<br>
+#endif<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStream.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStream.h?rev=268454&r1=268453&r2=268454&view=diff" rel="noreferrer" target="_blank" class="cremed">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStream.h?rev=268454&r1=268453&r2=268454&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStream.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStream.h Tue May 3 17:18:17 2016<br>
@@ -10,6 +10,7 @@<br>
#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBTPISTREAM_H<br>
#define LLVM_DEBUGINFO_PDB_RAW_PDBTPISTREAM_H<br>
<br>
+#include "llvm/DebugInfo/CodeView/TypeStream.h"<br>
#include "llvm/DebugInfo/PDB/PDBTypes.h"<br>
#include "llvm/DebugInfo/PDB/Raw/ByteStream.h"<br>
#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"<br>
@@ -25,12 +26,6 @@ class TpiStream {<br>
struct HeaderInfo;<br>
<br>
public:<br>
- struct HashedTypeRecord {<br>
- uint32_t Hash;<br>
- codeview::TypeLeafKind Kind;<br>
- ArrayRef<uint8_t> Record;<br>
- };<br>
-<br>
TpiStream(PDBFile &File);<br>
~TpiStream();<br>
std::error_code reload();<br>
@@ -41,7 +36,7 @@ public:<br>
uint32_t TypeIndexEnd() const;<br>
uint32_t NumTypeRecords() const;<br>
<br>
- ArrayRef<HashedTypeRecord> records() const;<br>
+ iterator_range<codeview::TypeIterator> types() const;<br>
<br>
private:<br>
PDBFile &Pdb;<br>
@@ -53,7 +48,6 @@ private:<br>
ByteStream HashValuesBuffer;<br>
ByteStream HashAdjBuffer;<br>
<br>
- std::vector<HashedTypeRecord> TypeRecords;<br>
std::unique_ptr<HeaderInfo> Header;<br>
};<br>
}<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp?rev=268454&r1=268453&r2=268454&view=diff" rel="noreferrer" target="_blank" class="cremed">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp?rev=268454&r1=268453&r2=268454&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp Tue May 3 17:18:17 2016<br>
@@ -88,25 +88,6 @@ std::error_code TpiStream::reload() {<br>
<br>
// The actual type records themselves come from this stream<br>
RecordsBuffer.initialize(Reader, Header->TypeRecordBytes);<br>
- TypeRecords.resize(TypeIndexEnd() - ::MinTypeIndex);<br>
- StreamReader RecordsReader(RecordsBuffer);<br>
- for (uint32_t I = TypeIndexBegin(); I < TypeIndexEnd(); ++I) {<br>
- HashedTypeRecord &Record = TypeRecords[I - ::MinTypeIndex];<br>
- codeview::TypeRecordPrefix Prefix;<br>
- if (auto EC = RecordsReader.readObject(&Prefix))<br>
- return EC;<br>
-<br>
- Record.Kind =<br>
- static_cast<codeview::TypeLeafKind>(static_cast<uint16_t>(Prefix.Leaf));<br>
-<br>
- // Since we read this entire buffer into a ByteStream, we are guaranteed<br>
- // that the entire buffer is contiguous (i.e. there's no longer a chance<br>
- // that it splits across a page boundary. So we can request a reference<br>
- // directly into the stream buffer to avoid unnecessary memory copies.<br>
- uint32_t RecordSize = Prefix.Len - sizeof(Prefix.Leaf);<br>
- if (auto EC = RecordsReader.getArrayRef(Record.Record, RecordSize))<br>
- return EC;<br>
- }<br>
<br>
// Hash indices, hash values, etc come from the hash stream.<br>
MappedBlockStream HS(Header->HashStreamIndex, Pdb);<br>
@@ -136,8 +117,6 @@ uint32_t TpiStream::NumTypeRecords() con<br>
return TypeIndexEnd() - TypeIndexBegin();<br>
}<br>
<br>
-ArrayRef<TpiStream::HashedTypeRecord> TpiStream::records() const {<br>
- const HashedTypeRecord *Begin =<br>
- &TypeRecords[TypeIndexBegin() - ::MinTypeIndex];<br>
- return ArrayRef<HashedTypeRecord>(Begin, NumTypeRecords());<br>
+iterator_range<codeview::TypeIterator> TpiStream::types() const {<br>
+ return codeview::makeTypeRange(RecordsBuffer.str());<br>
}<br>
<br>
Modified: llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp?rev=268454&r1=268453&r2=268454&view=diff" rel="noreferrer" target="_blank" class="cremed">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp?rev=268454&r1=268453&r2=268454&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp (original)<br>
+++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp Tue May 3 17:18:17 2016<br>
@@ -149,27 +149,24 @@ cl::opt<bool> NoEnumDefs("no-enum-defini<br>
cl::cat(FilterCategory));<br>
}<br>
<br>
-static void dumpBytes(raw_ostream &S, ArrayRef<uint8_t> Bytes,<br>
- uint32_t BytesPerRow, uint32_t Indent) {<br>
+static void dumpBytes(raw_ostream &S, StringRef Bytes, uint32_t BytesPerRow,<br>
+ uint32_t Indent) {<br>
S << "[";<br>
- uint32_t I = 0;<br>
<br>
- uint32_t BytesRemaining = Bytes.size();<br>
- while (BytesRemaining > 0) {<br>
- uint32_t BytesThisLine = std::min(BytesRemaining, BytesPerRow);<br>
- for (size_t L = 0; L < BytesThisLine; ++L, ++I) {<br>
- S << format_hex_no_prefix(Bytes[I], 2, true);<br>
- if (L + 1 < BytesThisLine)<br>
+ while (!Bytes.empty()) {<br>
+ uint32_t BytesThisLine = std::min(Bytes.size(), BytesPerRow);<br>
+ while (BytesThisLine > 0) {<br>
+ S << format_hex_no_prefix(uint8_t(Bytes.front()), 2, true);<br>
+ Bytes = Bytes.drop_front();<br>
+ if (--BytesThisLine > 0)<br>
S << ' ';<br>
}<br>
- BytesRemaining -= BytesThisLine;<br>
- if (BytesRemaining > 0) {<br>
+ if (!Bytes.empty()) {<br>
S << '\n';<br>
S.indent(Indent);<br>
}<br>
}<br>
S << ']';<br>
- S.flush();<br>
}<br>
<br>
static void dumpStructure(RawSession &RS) {<br>
@@ -321,10 +318,10 @@ static void dumpStructure(RawSession &RS<br>
TpiStream &Tpi = File.getPDBTpiStream();<br>
outs() << "TPI Version: " << Tpi.getTpiVersion() << '\n';<br>
outs() << "Record count: " << Tpi.NumTypeRecords() << '\n';<br>
- for (auto &Record : Tpi.records()) {<br>
- outs().indent(2) << "Kind: 0x" << Record.Kind;<br>
+ for (auto &Type : Tpi.types()) {<br>
+ outs().indent(2) << "Kind: 0x" << Type.Leaf;<br>
outs().indent(2) << "Bytes: ";<br>
- dumpBytes(outs(), Record.Record, 16, 24);<br>
+ dumpBytes(outs(), Type.LeafData, 16, 24);<br>
outs() << '\n';<br>
}<br>
}<br>
<br>
Modified: llvm/trunk/tools/llvm-readobj/COFFDumper.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/COFFDumper.cpp?rev=268454&r1=268453&r2=268454&view=diff" rel="noreferrer" target="_blank" class="cremed">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/COFFDumper.cpp?rev=268454&r1=268453&r2=268454&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-readobj/COFFDumper.cpp (original)<br>
+++ llvm/trunk/tools/llvm-readobj/COFFDumper.cpp Tue May 3 17:18:17 2016<br>
@@ -28,6 +28,7 @@<br>
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"<br>
#include "llvm/DebugInfo/CodeView/TypeIndex.h"<br>
#include "llvm/DebugInfo/CodeView/TypeRecord.h"<br>
+#include "llvm/DebugInfo/CodeView/TypeStream.h"<br>
#include "llvm/Object/COFF.h"<br>
#include "llvm/Object/ObjectFile.h"<br>
#include "llvm/Support/COFF.h"<br>
@@ -958,26 +959,6 @@ void COFFDumper::printCodeViewDebugInfo(<br>
}<br>
}<br>
<br>
-/// Consumes sizeof(T) bytes from the given byte sequence. Returns an error if<br>
-/// there are not enough bytes remaining. Reinterprets the consumed bytes as a<br>
-/// T object and points 'Res' at them.<br>
-template <typename T><br>
-static std::error_code consumeObject(StringRef &Data, const T *&Res) {<br>
- if (Data.size() < sizeof(*Res))<br>
- return object_error::parse_failed;<br>
- Res = reinterpret_cast<const T *>(Data.data());<br>
- Data = Data.drop_front(sizeof(*Res));<br>
- return std::error_code();<br>
-}<br>
-<br>
-static std::error_code consumeUInt32(StringRef &Data, uint32_t &Res) {<br>
- const ulittle32_t *IntPtr;<br>
- if (auto EC = consumeObject(Data, IntPtr))<br>
- return EC;<br>
- Res = *IntPtr;<br>
- return std::error_code();<br>
-}<br>
-<br>
void COFFDumper::initializeFileAndStringTables(StringRef Data) {<br>
while (!Data.empty() && (CVFileChecksumTable.data() == nullptr ||<br>
CVStringTable.data() == nullptr)) {<br>
@@ -1964,113 +1945,6 @@ static StringRef getLeafTypeName(TypeLea<br>
return "UnknownLeaf";<br>
}<br>
<br>
-// A const input iterator interface to the CodeView type stream.<br>
-class CodeViewTypeIterator {<br>
-public:<br>
- struct TypeRecord {<br>
- std::size_t Length;<br>
- TypeLeafKind Leaf;<br>
- StringRef LeafData;<br>
- };<br>
-<br>
- explicit CodeViewTypeIterator(const StringRef &SectionData)<br>
- : Data(SectionData), AtEnd(false) {<br>
- if (Data.size() >= 4) {<br>
- Magic = *reinterpret_cast<const ulittle32_t *>(Data.data());<br>
- Data = Data.drop_front(4);<br>
- }<br>
- next(); // Prime the pump<br>
- }<br>
-<br>
- CodeViewTypeIterator() : AtEnd(true) {}<br>
-<br>
- // For iterators to compare equal, they must both point at the same record<br>
- // in the same data stream, or they must both be at the end of a stream.<br>
- friend bool operator==(const CodeViewTypeIterator &lhs,<br>
- const CodeViewTypeIterator &rhs);<br>
-<br>
- friend bool operator!=(const CodeViewTypeIterator &lhs,<br>
- const CodeViewTypeIterator &rhs);<br>
-<br>
- unsigned getMagic() const { return Magic; }<br>
-<br>
- const TypeRecord &operator*() const {<br>
- assert(!AtEnd);<br>
- return Current;<br>
- }<br>
-<br>
- const TypeRecord *operator->() const {<br>
- assert(!AtEnd);<br>
- return &Current;<br>
- }<br>
-<br>
- CodeViewTypeIterator operator++() {<br>
- next();<br>
- return *this;<br>
- }<br>
-<br>
- CodeViewTypeIterator operator++(int) {<br>
- CodeViewTypeIterator Original = *this;<br>
- ++*this;<br>
- return Original;<br>
- }<br>
-<br>
-private:<br>
- void next() {<br>
- assert(!AtEnd && "Attempted to advance more than one past the last rec");<br>
- if (Data.empty()) {<br>
- // We've advanced past the last record.<br>
- AtEnd = true;<br>
- return;<br>
- }<br>
-<br>
- const TypeRecordPrefix *Rec;<br>
- if (consumeObject(Data, Rec))<br>
- return;<br>
- Current.Length = Rec->Len;<br>
- Current.Leaf = static_cast<TypeLeafKind>(uint16_t(Rec->Leaf));<br>
- Current.LeafData = Data.substr(0, Current.Length - 2);<br>
-<br>
- // The next record starts immediately after this one.<br>
- Data = Data.drop_front(Current.LeafData.size());<br>
-<br>
- // FIXME: The stream contains LF_PAD bytes that we need to ignore, but those<br>
- // are typically included in LeafData. We may need to call skipPadding() if<br>
- // we ever find a record that doesn't count those bytes.<br>
-<br>
- return;<br>
- }<br>
-<br>
- StringRef Data;<br>
- unsigned Magic = 0;<br>
- TypeRecord Current;<br>
- bool AtEnd;<br>
-};<br>
-<br>
-bool operator==(const CodeViewTypeIterator &lhs,<br>
- const CodeViewTypeIterator &rhs) {<br>
- return (lhs.Data.begin() == rhs.Data.begin()) || (lhs.AtEnd && rhs.AtEnd);<br>
-}<br>
-<br>
-bool operator!=(const CodeViewTypeIterator &lhs,<br>
- const CodeViewTypeIterator &rhs) {<br>
- return !(lhs == rhs);<br>
-}<br>
-<br>
-struct CodeViewTypeStream {<br>
- CodeViewTypeIterator begin;<br>
- CodeViewTypeIterator end;<br>
- unsigned Magic;<br>
-};<br>
-<br>
-CodeViewTypeStream CreateCodeViewTypeIter(const StringRef &Data) {<br>
- CodeViewTypeStream Stream;<br>
- Stream.begin = CodeViewTypeIterator(Data);<br>
- Stream.end = CodeViewTypeIterator();<br>
- Stream.Magic = Stream.begin.getMagic();<br>
-<br>
- return Stream;<br>
-}<br>
<br>
void COFFDumper::printCodeViewTypeSection(StringRef SectionName,<br>
const SectionRef &Section) {<br>
@@ -2081,31 +1955,34 @@ void COFFDumper::printCodeViewTypeSectio<br>
error(Section.getContents(Data));<br>
if (opts::CodeViewSubsectionBytes)<br>
W.printBinaryBlock("Data", Data);<br>
-<br>
CVTD.dump(Data);<br>
}<br>
<br>
void CVTypeDumper::dump(StringRef Data) {<br>
- CodeViewTypeStream Stream = CreateCodeViewTypeIter(Data);<br>
- W.printHex("Magic", Stream.Magic);<br>
+ uint32_t Magic;<br>
+ if (consumeUInt32(Data, Magic))<br>
+ return;<br>
+ if (Magic != COFF::DEBUG_SECTION_MAGIC)<br>
+ return;<br>
<br>
- for (auto Iter = Stream.begin; Iter != Stream.end; ++Iter) {<br>
- StringRef LeafData = Iter->LeafData;<br>
+ W.printHex("Magic", Magic);<br>
+ for (const auto &Record : makeTypeRange(Data)) {<br>
+ StringRef LeafData = Record.LeafData;<br>
<br>
// Find the name of this leaf type.<br>
- StringRef LeafName = getLeafTypeName(Iter->Leaf);<br>
+ StringRef LeafName = getLeafTypeName(Record.Leaf);<br>
DictScope S(W, LeafName);<br>
unsigned NextTypeIndex = 0x1000 + CVUDTNames.size();<br>
- W.printEnum("TypeLeafKind", unsigned(Iter->Leaf),<br>
+ W.printEnum("TypeLeafKind", unsigned(Record.Leaf),<br>
makeArrayRef(LeafTypeNames));<br>
W.printHex("TypeIndex", NextTypeIndex);<br>
<br>
// Fill this in inside the switch to get something in CVUDTNames.<br>
StringRef Name;<br>
<br>
- switch (Iter->Leaf) {<br>
+ switch (Record.Leaf) {<br>
default: {<br>
- W.printHex("Size", Iter->Length);<br>
+ W.printHex("Size", Record.Length);<br>
break;<br>
}<br>
<br>
@@ -2121,7 +1998,7 @@ void CVTypeDumper::dump(StringRef Data)<br>
}<br>
<br>
case LF_FIELDLIST: {<br>
- W.printHex("Size", Iter->Length);<br>
+ W.printHex("Size", Record.Length);<br>
// FieldList has no fixed prefix that can be described with a struct. All<br>
// the bytes must be interpreted as more records.<br>
printCodeViewFieldList(LeafData);<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank" class="cremed">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank" class="cremed">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div></div><div dir="ltr">-- <br></div>Mike<br>Sent from phone