[llvm] r301556 - [Support] Make BinaryStreamArray extractors stateless.
Zachary Turner via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 27 09:11:48 PDT 2017
Author: zturner
Date: Thu Apr 27 11:11:47 2017
New Revision: 301556
URL: http://llvm.org/viewvc/llvm-project?rev=301556&view=rev
Log:
[Support] Make BinaryStreamArray extractors stateless.
Instead, we now pass a context memeber through the extraction
process.
Modified:
llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h
llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragment.h
llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h
llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h
llvm/trunk/include/llvm/Support/BinaryStreamArray.h
llvm/trunk/include/llvm/Support/BinaryStreamReader.h
llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp
llvm/trunk/unittests/Support/BinaryStreamTest.cpp
Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h?rev=301556&r1=301555&r2=301556&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h Thu Apr 27 11:11:47 2017
@@ -50,8 +50,10 @@ public:
template <typename Kind>
struct VarStreamArrayExtractor<codeview::CVRecord<Kind>> {
- Error operator()(BinaryStreamRef Stream, uint32_t &Len,
- codeview::CVRecord<Kind> &Item) const {
+ typedef void ContextType;
+
+ static Error extract(BinaryStreamRef Stream, uint32_t &Len,
+ codeview::CVRecord<Kind> &Item, void *Ctx) {
using namespace codeview;
const RecordPrefix *Prefix = nullptr;
BinaryStreamReader Reader(Stream);
Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragment.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragment.h?rev=301556&r1=301555&r2=301556&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragment.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragment.h Thu Apr 27 11:11:47 2017
@@ -74,8 +74,10 @@ typedef VarStreamArray<ModuleDebugFragme
} // namespace codeview
template <> struct VarStreamArrayExtractor<codeview::ModuleDebugFragment> {
- Error operator()(BinaryStreamRef Stream, uint32_t &Length,
- codeview::ModuleDebugFragment &Info) const {
+ typedef void ContextType;
+
+ static Error extract(BinaryStreamRef Stream, uint32_t &Length,
+ codeview::ModuleDebugFragment &Info, void *Ctx) {
if (auto EC = codeview::ModuleDebugFragment::initialize(Stream, Info))
return EC;
Length = Info.getRecordLength();
Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h?rev=301556&r1=301555&r2=301556&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h Thu Apr 27 11:11:47 2017
@@ -71,11 +71,10 @@ Error visitModuleDebugFragment(const Mod
template <> class VarStreamArrayExtractor<codeview::LineColumnEntry> {
public:
- VarStreamArrayExtractor(const codeview::LineFragmentHeader *Header)
- : Header(Header) {}
+ typedef const codeview::LineFragmentHeader ContextType;
- Error operator()(BinaryStreamRef Stream, uint32_t &Len,
- codeview::LineColumnEntry &Item) const {
+ static Error extract(BinaryStreamRef Stream, uint32_t &Len,
+ codeview::LineColumnEntry &Item, ContextType *Header) {
using namespace codeview;
const LineBlockFragmentHeader *BlockHeader;
BinaryStreamReader Reader(Stream);
@@ -104,15 +103,14 @@ public:
}
return Error::success();
}
-
-private:
- const codeview::LineFragmentHeader *Header;
};
template <> class VarStreamArrayExtractor<codeview::FileChecksumEntry> {
public:
- Error operator()(BinaryStreamRef Stream, uint32_t &Len,
- codeview::FileChecksumEntry &Item) const {
+ typedef void ContextType;
+
+ static Error extract(BinaryStreamRef Stream, uint32_t &Len,
+ codeview::FileChecksumEntry &Item, void *Ctx) {
using namespace codeview;
const FileChecksum *Header;
BinaryStreamReader Reader(Stream);
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h?rev=301556&r1=301555&r2=301556&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h Thu Apr 27 11:11:47 2017
@@ -64,8 +64,9 @@ struct ModuleInfoEx {
} // end namespace pdb
template <> struct VarStreamArrayExtractor<pdb::DbiModuleDescriptor> {
- Error operator()(BinaryStreamRef Stream, uint32_t &Length,
- pdb::DbiModuleDescriptor &Info) const {
+ typedef void ContextType;
+ static Error extract(BinaryStreamRef Stream, uint32_t &Length,
+ pdb::DbiModuleDescriptor &Info, void *Ctx) {
if (auto EC = pdb::DbiModuleDescriptor::initialize(Stream, Info))
return EC;
Length = Info.getRecordLength();
Modified: llvm/trunk/include/llvm/Support/BinaryStreamArray.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/BinaryStreamArray.h?rev=301556&r1=301555&r2=301556&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/BinaryStreamArray.h (original)
+++ llvm/trunk/include/llvm/Support/BinaryStreamArray.h Thu Apr 27 11:11:47 2017
@@ -42,10 +42,12 @@ namespace llvm {
/// having to specify a second template argument to VarStreamArray (documented
/// below).
template <typename T> struct VarStreamArrayExtractor {
+ typedef void Context;
+
// Method intentionally deleted. You must provide an explicit specialization
// with the following method implemented.
- Error operator()(BinaryStreamRef Stream, uint32_t &Len,
- T &Item) const = delete;
+ static Error extract(BinaryStreamRef Stream, uint32_t &Len, T &Item,
+ Context *Ctx) = delete;
};
/// VarStreamArray represents an array of variable length records backed by a
@@ -64,74 +66,64 @@ template <typename T> struct VarStreamAr
/// If you do not specify an Extractor type, you are expected to specialize
/// VarStreamArrayExtractor<T> for your ValueType.
///
-/// By default an Extractor is default constructed in the class, but in some
-/// cases you might find it useful for an Extractor to maintain state across
-/// extractions. In this case you can provide your own Extractor through a
-/// secondary constructor. The following examples show various ways of
-/// creating a VarStreamArray.
-///
-/// // Will use VarStreamArrayExtractor<MyType> as the extractor.
-/// VarStreamArray<MyType> MyTypeArray;
-///
-/// // Will use a default-constructed MyExtractor as the extractor.
-/// VarStreamArray<MyType, MyExtractor> MyTypeArray2;
-///
-/// // Will use the specific instance of MyExtractor provided.
-/// // MyExtractor need not be default-constructible in this case.
-/// MyExtractor E(SomeContext);
-/// VarStreamArray<MyType, MyExtractor> MyTypeArray3(E);
+/// The default extractor type is stateless, but by specializing
+/// VarStreamArrayExtractor or defining your own custom extractor type and
+/// adding the appropriate ContextType typedef to the class, you can pass a
+/// context field during construction of the VarStreamArray that will be
+/// passed to each call to extract.
///
-template <typename ValueType, typename Extractor> class VarStreamArrayIterator;
+template <typename ValueType, typename ExtractorType>
+class VarStreamArrayIterator;
template <typename ValueType,
- typename Extractor = VarStreamArrayExtractor<ValueType>>
-
+ typename ExtractorType = VarStreamArrayExtractor<ValueType>>
class VarStreamArray {
- friend class VarStreamArrayIterator<ValueType, Extractor>;
-
public:
- typedef VarStreamArrayIterator<ValueType, Extractor> Iterator;
+ typedef typename ExtractorType::ContextType ContextType;
+ typedef VarStreamArrayIterator<ValueType, ExtractorType> Iterator;
+ friend Iterator;
VarStreamArray() = default;
- explicit VarStreamArray(const Extractor &E) : E(E) {}
- explicit VarStreamArray(BinaryStreamRef Stream) : Stream(Stream) {}
- VarStreamArray(BinaryStreamRef Stream, const Extractor &E)
- : Stream(Stream), E(E) {}
+ explicit VarStreamArray(BinaryStreamRef Stream,
+ ContextType *Context = nullptr)
+ : Stream(Stream), Context(Context) {}
- VarStreamArray(const VarStreamArray<ValueType, Extractor> &Other)
- : Stream(Other.Stream), E(Other.E) {}
+ VarStreamArray(const VarStreamArray<ValueType, ExtractorType> &Other)
+ : Stream(Other.Stream), Context(Other.Context) {}
Iterator begin(bool *HadError = nullptr) const {
- return Iterator(*this, E, HadError);
+ return Iterator(*this, Context, HadError);
}
- Iterator end() const { return Iterator(E); }
-
- const Extractor &getExtractor() const { return E; }
+ Iterator end() const { return Iterator(); }
BinaryStreamRef getUnderlyingStream() const { return Stream; }
+ void setUnderlyingStream(BinaryStreamRef Stream) { this->Stream = Stream; }
private:
BinaryStreamRef Stream;
- Extractor E;
+ ContextType *Context = nullptr;
};
-template <typename ValueType, typename Extractor>
+template <typename ValueType, typename ExtractorType>
class VarStreamArrayIterator
- : public iterator_facade_base<VarStreamArrayIterator<ValueType, Extractor>,
- std::forward_iterator_tag, ValueType> {
- typedef VarStreamArrayIterator<ValueType, Extractor> IterType;
- typedef VarStreamArray<ValueType, Extractor> ArrayType;
+ : public iterator_facade_base<
+ VarStreamArrayIterator<ValueType, ExtractorType>,
+ std::forward_iterator_tag, ValueType> {
+ typedef typename ExtractorType::ContextType ContextType;
+ typedef VarStreamArrayIterator<ValueType, ExtractorType> IterType;
+ typedef VarStreamArray<ValueType, ExtractorType> ArrayType;
public:
- VarStreamArrayIterator(const ArrayType &Array, const Extractor &E,
+ VarStreamArrayIterator(const ArrayType &Array, ContextType *Context,
bool *HadError = nullptr)
- : IterRef(Array.Stream), Array(&Array), HadError(HadError), Extract(E) {
+ : IterRef(Array.Stream), Context(Context), Array(&Array),
+ HadError(HadError) {
if (IterRef.getLength() == 0)
moveToEnd();
else {
- auto EC = Extract(IterRef, ThisLen, ThisValue);
+ auto EC = ExtractorType::extract(IterRef, ThisLen, ThisValue, Context);
if (EC) {
consumeError(std::move(EC));
markError();
@@ -139,7 +131,6 @@ public:
}
}
VarStreamArrayIterator() = default;
- explicit VarStreamArrayIterator(const Extractor &E) : Extract(E) {}
~VarStreamArrayIterator() = default;
bool operator==(const IterType &R) const {
@@ -178,7 +169,7 @@ public:
moveToEnd();
} else {
// There is some data after the current record.
- auto EC = Extract(IterRef, ThisLen, ThisValue);
+ auto EC = ExtractorType::extract(IterRef, ThisLen, ThisValue, Context);
if (EC) {
consumeError(std::move(EC));
markError();
@@ -205,11 +196,11 @@ private:
ValueType ThisValue;
BinaryStreamRef IterRef;
+ ContextType *Context{nullptr};
const ArrayType *Array{nullptr};
uint32_t ThisLen{0};
bool HasError{false};
bool *HadError{nullptr};
- Extractor Extract;
};
template <typename T> class FixedStreamArrayIterator;
Modified: llvm/trunk/include/llvm/Support/BinaryStreamReader.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/BinaryStreamReader.h?rev=301556&r1=301555&r2=301556&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/BinaryStreamReader.h (original)
+++ llvm/trunk/include/llvm/Support/BinaryStreamReader.h Thu Apr 27 11:11:47 2017
@@ -172,11 +172,13 @@ public:
/// \returns a success error code if the data was successfully read, otherwise
/// returns an appropriate error code.
template <typename T, typename U>
- Error readArray(VarStreamArray<T, U> &Array, uint32_t Size) {
+ Error
+ readArray(VarStreamArray<T, U> &Array, uint32_t Size,
+ typename VarStreamArray<T, U>::ContextType *Context = nullptr) {
BinaryStreamRef S;
if (auto EC = readStreamRef(S, Size))
return EC;
- Array = VarStreamArray<T, U>(S, Array.getExtractor());
+ Array = VarStreamArray<T, U>(S, Context);
return Error::success();
}
Modified: llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp?rev=301556&r1=301555&r2=301556&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp Thu Apr 27 11:11:47 2017
@@ -68,9 +68,8 @@ Error llvm::codeview::visitModuleDebugFr
const LineFragmentHeader *Header;
if (auto EC = Reader.readObject(Header))
return EC;
- VarStreamArrayExtractor<LineColumnEntry> E(Header);
- LineInfoArray LineInfos(E);
- if (auto EC = Reader.readArray(LineInfos, Reader.bytesRemaining()))
+ LineInfoArray LineInfos;
+ if (auto EC = Reader.readArray(LineInfos, Reader.bytesRemaining(), Header))
return EC;
return V.visitLines(R.getRecordData(), Header, LineInfos);
}
Modified: llvm/trunk/unittests/Support/BinaryStreamTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/BinaryStreamTest.cpp?rev=301556&r1=301555&r2=301556&view=diff
==============================================================================
--- llvm/trunk/unittests/Support/BinaryStreamTest.cpp (original)
+++ llvm/trunk/unittests/Support/BinaryStreamTest.cpp Thu Apr 27 11:11:47 2017
@@ -358,12 +358,14 @@ TEST_F(BinaryStreamTest, VarStreamArray)
struct StringExtractor {
public:
- Error operator()(BinaryStreamRef Stream, uint32_t &Len, StringRef &Item) {
- if (Index == 0)
+ typedef uint32_t ContextType;
+ static Error extract(BinaryStreamRef Stream, uint32_t &Len, StringRef &Item,
+ uint32_t *Index) {
+ if (*Index == 0)
Len = strlen("1. Test");
- else if (Index == 1)
+ else if (*Index == 1)
Len = strlen("2. Longer Test");
- else if (Index == 2)
+ else if (*Index == 2)
Len = strlen("3. Really Long Test");
else
Len = strlen("4. Super Extra Longest Test Of All");
@@ -372,16 +374,14 @@ TEST_F(BinaryStreamTest, VarStreamArray)
return EC;
Item =
StringRef(reinterpret_cast<const char *>(Bytes.data()), Bytes.size());
- ++Index;
+ ++(*Index);
return Error::success();
}
-
- private:
- uint32_t Index = 0;
};
for (auto &Stream : Streams) {
- VarStreamArray<StringRef, StringExtractor> Array(*Stream.Input);
+ uint32_t Context = 0;
+ VarStreamArray<StringRef, StringExtractor> Array(*Stream.Input, &Context);
auto Iter = Array.begin();
ASSERT_EQ("1. Test", *Iter++);
ASSERT_EQ("2. Longer Test", *Iter++);
More information about the llvm-commits
mailing list