[llvm] r346978 - [BinaryFormat] Add MsgPackTypes

via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 16 08:38:06 PST 2018


Sorry for the delay, I was just able to get back to a terminal this 
morning. I don't see any warnings in trunk; with modules enabled I see 
an error in the Clang build, and when I compile only LLVM I don't see 
any diagnostics at all.

If I understand how the modulemap works then the existing `umbrella 
"BinaryFormat" module * { export * }` in include/llvm/module.modulemap 
should include the new include/llvm/BinaryFormat/MsgPackTypes.h in 
LLVM_BinaryFormat

Scott

On 2018-11-15 16:11, scott at scottlinder.com wrote:
> That sounds likely. I am building with -DLLVM_ENABLE_MODULES=On now to
> see for myself, but any hints about what I missed would be helpful.
> I'm not very familiar with C++ modules. Is the relevant file
> include/llvm/module.modulemap ?
> 
> Scott
> 
> On 2018-11-15 15:48, Adrian Prantl wrote:
>> Looks like you forgot to update the module map?
>> 
>> [53/1303] Building CXX object
>> lib/Bina...LVMBinaryFormat.dir/MsgPackTypes.cpp.o
>> ../LIB/BINARYFORMAT/MSGPACKTYPES.CPP:15:2: WARNING: MISSING SUBMODULE
>> 'LLVM_BINARYFORMAT.MSGPACKTYPES' [-WINCOMPLETE-UMBRELLA]
>> #include "llvm/BinaryFormat/MsgPackTypes.h"
>>  ^       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> 1 warning generated.
>> 
>> -- adrian
>> 
>>> On Nov 15, 2018, at 10:50 AM, Scott Linder via llvm-commits
>>> <llvm-commits at lists.llvm.org> wrote:
>>> 
>>> Author: scott.linder
>>> Date: Thu Nov 15 10:50:01 2018
>>> New Revision: 346978
>>> 
>>> URL: http://llvm.org/viewvc/llvm-project?rev=346978&view=rev [1]
>>> Log:
>>> [BinaryFormat] Add MsgPackTypes
>>> 
>>> Add data structure to represent MessagePack "documents" and convert
>>> to/from both MessagePack and YAML encodings.
>>> 
>>> Differential Revision: https://reviews.llvm.org/D48175 [2]
>>> 
>>> Added:
>>> llvm/trunk/include/llvm/BinaryFormat/MsgPackTypes.h
>>> llvm/trunk/lib/BinaryFormat/MsgPackTypes.cpp
>>> llvm/trunk/unittests/BinaryFormat/MsgPackTypesTest.cpp
>>> Modified:
>>> llvm/trunk/lib/BinaryFormat/CMakeLists.txt
>>> llvm/trunk/unittests/BinaryFormat/CMakeLists.txt
>>> 
>>> Added: llvm/trunk/include/llvm/BinaryFormat/MsgPackTypes.h
>>> URL:
>>> 
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BinaryFormat/MsgPackTypes.h?rev=346978&view=auto
>>> [3]
>>> 
>> ==============================================================================
>>> --- llvm/trunk/include/llvm/BinaryFormat/MsgPackTypes.h (added)
>>> +++ llvm/trunk/include/llvm/BinaryFormat/MsgPackTypes.h Thu Nov 15
>>> 10:50:01 2018
>>> @@ -0,0 +1,372 @@
>>> +//===- MsgPackTypes.h - MsgPack Types ---------------------------*-
>>> C++ -*-===//
>>> +//
>>> +// The LLVM Compiler Infrastructure
>>> +//
>>> +// This file is distributed under the University of Illinois Open
>>> Source
>>> +// License. See LICENSE.TXT for details.
>>> +//
>>> 
>> +//===----------------------------------------------------------------------===//
>>> +//
>>> +/// \file
>>> +/// This is a data structure for representing MessagePack
>>> "documents", with
>>> +/// methods to go to and from MessagePack. The types also
>>> specialize YAMLIO
>>> +/// traits in order to go to and from YAML.
>>> +//
>>> 
>> +//===----------------------------------------------------------------------===//
>>> +
>>> +#include "llvm/ADT/Optional.h"
>>> +#include "llvm/BinaryFormat/MsgPackReader.h"
>>> +#include "llvm/BinaryFormat/MsgPackWriter.h"
>>> +#include "llvm/Support/Casting.h"
>>> +#include "llvm/Support/YAMLTraits.h"
>>> +#include <vector>
>>> +
>>> +#ifndef LLVM_BINARYFORMAT_MSGPACKTYPES_H
>>> +#define LLVM_BINARYFORMAT_MSGPACKTYPES_H
>>> +
>>> +namespace llvm {
>>> +namespace msgpack {
>>> +
>>> +class Node;
>>> +
>>> +/// Short-hand for a Node pointer.
>>> +using NodePtr = std::shared_ptr<Node>;
>>> +
>>> +/// Short-hand for an Optional Node pointer.
>>> +using OptNodePtr = Optional<NodePtr>;
>>> +
>>> +/// Abstract base-class which can be any MessagePack type.
>>> +class Node {
>>> +public:
>>> + enum NodeKind {
>>> + NK_Scalar,
>>> + NK_Array,
>>> + NK_Map,
>>> + };
>>> +
>>> +private:
>>> + virtual void anchor() = 0;
>>> + const NodeKind Kind;
>>> +
>>> + static Expected<OptNodePtr> readArray(Reader &MPReader, size_t
>>> Length);
>>> + static Expected<OptNodePtr> readMap(Reader &MPReader, size_t
>>> Length);
>>> +
>>> +public:
>>> + NodeKind getKind() const { return Kind; }
>>> +
>>> + /// Construct a Node. Used by derived classes to track kind
>>> information.
>>> + Node(NodeKind Kind) : Kind(Kind) {}
>>> +
>>> + virtual ~Node() = default;
>>> +
>>> + /// Read from a MessagePack reader \p MPReader, returning an error
>>> if one is
>>> + /// encountered, or None if \p MPReader is at the end of stream,
>>> or some Node
>>> + /// pointer if some type is read.
>>> + static Expected<OptNodePtr> read(Reader &MPReader);
>>> +
>>> + /// Write to a MessagePack writer \p MPWriter.
>>> + virtual void write(Writer &MPWriter) = 0;
>>> +};
>>> +
>>> +/// A MessagePack scalar.
>>> +class ScalarNode : public Node {
>>> +public:
>>> + enum ScalarKind {
>>> + SK_Int,
>>> + SK_UInt,
>>> + SK_Nil,
>>> + SK_Boolean,
>>> + SK_Float,
>>> + SK_String,
>>> + SK_Binary,
>>> + };
>>> +
>>> +private:
>>> + void anchor() override;
>>> +
>>> + void destroy();
>>> +
>>> + ScalarKind SKind;
>>> +
>>> + union {
>>> + int64_t IntValue;
>>> + uint64_t UIntValue;
>>> + bool BoolValue;
>>> + double FloatValue;
>>> + std::string StringValue;
>>> + };
>>> +
>>> +public:
>>> + /// Construct an Int ScalarNode.
>>> + ScalarNode(int64_t IntValue);
>>> + /// Construct an Int ScalarNode.
>>> + ScalarNode(int32_t IntValue);
>>> + /// Construct an UInt ScalarNode.
>>> + ScalarNode(uint64_t UIntValue);
>>> + /// Construct an UInt ScalarNode.
>>> + ScalarNode(uint32_t UIntValue);
>>> + /// Construct a Nil ScalarNode.
>>> + ScalarNode();
>>> + /// Construct a Boolean ScalarNode.
>>> + ScalarNode(bool BoolValue);
>>> + /// Construct a Float ScalarNode.
>>> + ScalarNode(double FloatValue);
>>> + /// Construct a String ScalarNode.
>>> + ScalarNode(StringRef StringValue);
>>> + /// Construct a String ScalarNode.
>>> + ScalarNode(const char *StringValue);
>>> + /// Construct a String ScalarNode.
>>> + ScalarNode(std::string &&StringValue);
>>> + /// Construct a Binary ScalarNode.
>>> + ScalarNode(MemoryBufferRef BinaryValue);
>>> +
>>> + ~ScalarNode();
>>> +
>>> + ScalarNode &operator=(const ScalarNode &RHS) = delete;
>>> + /// A ScalarNode can only be move assigned.
>>> + ScalarNode &operator=(ScalarNode &&RHS);
>>> +
>>> + /// Change the kind of this ScalarNode, zero initializing it to
>>> the new type.
>>> + void setScalarKind(ScalarKind SKind) {
>>> + switch (SKind) {
>>> + case SK_Int:
>>> + *this = int64_t(0);
>>> + break;
>>> + case SK_UInt:
>>> + *this = uint64_t(0);
>>> + break;
>>> + case SK_Boolean:
>>> + *this = false;
>>> + break;
>>> + case SK_Float:
>>> + *this = 0.0;
>>> + break;
>>> + case SK_String:
>>> + *this = StringRef();
>>> + break;
>>> + case SK_Binary:
>>> + *this = MemoryBufferRef("", "");
>>> + break;
>>> + case SK_Nil:
>>> + *this = ScalarNode();
>>> + break;
>>> + }
>>> + }
>>> +
>>> + /// Get the current kind of ScalarNode.
>>> + ScalarKind getScalarKind() { return SKind; }
>>> +
>>> + /// Get the value of an Int scalar.
>>> + ///
>>> + /// \warning Assumes getScalarKind() == SK_Int
>>> + int64_t getInt() {
>>> + assert(SKind == SK_Int);
>>> + return IntValue;
>>> + }
>>> +
>>> + /// Get the value of a UInt scalar.
>>> + ///
>>> + /// \warning Assumes getScalarKind() == SK_UInt
>>> + uint64_t getUInt() {
>>> + assert(SKind == SK_UInt);
>>> + return UIntValue;
>>> + }
>>> +
>>> + /// Get the value of an Boolean scalar.
>>> + ///
>>> + /// \warning Assumes getScalarKind() == SK_Boolean
>>> + bool getBool() {
>>> + assert(SKind == SK_Boolean);
>>> + return BoolValue;
>>> + }
>>> +
>>> + /// Get the value of an Float scalar.
>>> + ///
>>> + /// \warning Assumes getScalarKind() == SK_Float
>>> + double getFloat() {
>>> + assert(SKind == SK_Float);
>>> + return FloatValue;
>>> + }
>>> +
>>> + /// Get the value of a String scalar.
>>> + ///
>>> + /// \warning Assumes getScalarKind() == SK_String
>>> + StringRef getString() {
>>> + assert(SKind == SK_String);
>>> + return StringValue;
>>> + }
>>> +
>>> + /// Get the value of a Binary scalar.
>>> + ///
>>> + /// \warning Assumes getScalarKind() == SK_Binary
>>> + StringRef getBinary() {
>>> + assert(SKind == SK_Binary);
>>> + return StringValue;
>>> + }
>>> +
>>> + static bool classof(const Node *N) { return N->getKind() ==
>>> NK_Scalar; }
>>> +
>>> + void write(Writer &MPWriter) override;
>>> +
>>> + /// Parse a YAML scalar of the current ScalarKind from \p
>>> ScalarStr.
>>> + ///
>>> + /// \returns An empty string on success, otherwise an error
>>> message.
>>> + StringRef inputYAML(StringRef ScalarStr);
>>> +
>>> + /// Output a YAML scalar of the current ScalarKind into \p OS.
>>> + void outputYAML(raw_ostream &OS) const;
>>> +
>>> + /// Determine which YAML quoting type the current value would need
>>> when
>>> + /// output.
>>> + yaml::QuotingType mustQuoteYAML(StringRef ScalarStr) const;
>>> +
>>> + /// Get the YAML tag for the current ScalarKind.
>>> + StringRef getYAMLTag() const;
>>> +
>>> + /// Flag which affects how the type handles YAML tags when reading
>>> and
>>> + /// writing.
>>> + ///
>>> + /// When false, tags are used when reading and writing. When
>>> reading, the tag
>>> + /// is used to decide the ScalarKind before parsing. When writing,
>>> the tag is
>>> + /// output along with the value.
>>> + ///
>>> + /// When true, tags are ignored when reading and writing. When
>>> reading, the
>>> + /// ScalarKind is always assumed to be String. When writing, the
>>> tag is not
>>> + /// output.
>>> + bool IgnoreTag = false;
>>> +
>>> + static const char *IntTag;
>>> + static const char *NilTag;
>>> + static const char *BooleanTag;
>>> + static const char *FloatTag;
>>> + static const char *StringTag;
>>> + static const char *BinaryTag;
>>> +};
>>> +
>>> +class ArrayNode : public Node, public std::vector<NodePtr> {
>>> + void anchor() override;
>>> +
>>> +public:
>>> + ArrayNode() : Node(NK_Array) {}
>>> + static bool classof(const Node *N) { return N->getKind() ==
>>> NK_Array; }
>>> +
>>> + void write(Writer &MPWriter) override {
>>> + MPWriter.writeArraySize(this->size());
>>> + for (auto &N : *this)
>>> + N->write(MPWriter);
>>> + }
>>> +};
>>> +
>>> +class MapNode : public Node, public StringMap<NodePtr> {
>>> + void anchor() override;
>>> +
>>> +public:
>>> + MapNode() : Node(NK_Map) {}
>>> + static bool classof(const Node *N) { return N->getKind() ==
>>> NK_Map; }
>>> +
>>> + void write(Writer &MPWriter) override {
>>> + MPWriter.writeMapSize(this->size());
>>> + for (auto &N : *this) {
>>> + MPWriter.write(N.first());
>>> + N.second->write(MPWriter);
>>> + }
>>> + }
>>> +};
>>> +
>>> +} // end namespace msgpack
>>> +
>>> +namespace yaml {
>>> +
>>> +template <> struct PolymorphicTraits<msgpack::NodePtr> {
>>> + static NodeKind getKind(const msgpack::NodePtr &N) {
>>> + if (isa<msgpack::ScalarNode>(*N))
>>> + return NodeKind::Scalar;
>>> + if (isa<msgpack::MapNode>(*N))
>>> + return NodeKind::Map;
>>> + if (isa<msgpack::ArrayNode>(*N))
>>> + return NodeKind::Sequence;
>>> + llvm_unreachable("NodeKind not supported");
>>> + }
>>> + static msgpack::ScalarNode &getAsScalar(msgpack::NodePtr &N) {
>>> + if (!N || !isa<msgpack::ScalarNode>(*N))
>>> + N.reset(new msgpack::ScalarNode());
>>> + return *cast<msgpack::ScalarNode>(N.get());
>>> + }
>>> + static msgpack::MapNode &getAsMap(msgpack::NodePtr &N) {
>>> + if (!N || !isa<msgpack::MapNode>(*N))
>>> + N.reset(new msgpack::MapNode());
>>> + return *cast<msgpack::MapNode>(N.get());
>>> + }
>>> + static msgpack::ArrayNode &getAsSequence(msgpack::NodePtr &N) {
>>> + if (!N || !isa<msgpack::ArrayNode>(*N))
>>> + N.reset(new msgpack::ArrayNode());
>>> + return *cast<msgpack::ArrayNode>(N.get());
>>> + }
>>> +};
>>> +
>>> +template <> struct TaggedScalarTraits<msgpack::ScalarNode> {
>>> + static void output(const msgpack::ScalarNode &S, void *Ctxt,
>>> + raw_ostream &ScalarOS, raw_ostream &TagOS) {
>>> + if (!S.IgnoreTag)
>>> + TagOS << S.getYAMLTag();
>>> + S.outputYAML(ScalarOS);
>>> + }
>>> +
>>> + static StringRef input(StringRef ScalarStr, StringRef Tag, void
>>> *Ctxt,
>>> + msgpack::ScalarNode &S) {
>>> + if (Tag == msgpack::ScalarNode::IntTag) {
>>> + S.setScalarKind(msgpack::ScalarNode::SK_UInt);
>>> + if (S.inputYAML(ScalarStr) == StringRef())
>>> + return StringRef();
>>> + S.setScalarKind(msgpack::ScalarNode::SK_Int);
>>> + return S.inputYAML(ScalarStr);
>>> + }
>>> +
>>> + if (S.IgnoreTag || Tag == msgpack::ScalarNode::StringTag ||
>>> + Tag == "tag:yaml.org [4],2002:str")
>>> + S.setScalarKind(msgpack::ScalarNode::SK_String);
>>> + else if (Tag == msgpack::ScalarNode::NilTag)
>>> + S.setScalarKind(msgpack::ScalarNode::SK_Nil);
>>> + else if (Tag == msgpack::ScalarNode::BooleanTag)
>>> + S.setScalarKind(msgpack::ScalarNode::SK_Boolean);
>>> + else if (Tag == msgpack::ScalarNode::FloatTag)
>>> + S.setScalarKind(msgpack::ScalarNode::SK_Float);
>>> + else if (Tag == msgpack::ScalarNode::StringTag)
>>> + S.setScalarKind(msgpack::ScalarNode::SK_String);
>>> + else if (Tag == msgpack::ScalarNode::BinaryTag)
>>> + S.setScalarKind(msgpack::ScalarNode::SK_Binary);
>>> + else
>>> + return "Unsupported messagepack tag";
>>> +
>>> + return S.inputYAML(ScalarStr);
>>> + }
>>> +
>>> + static QuotingType mustQuote(const msgpack::ScalarNode &S,
>>> StringRef Str) {
>>> + return S.mustQuoteYAML(Str);
>>> + }
>>> +};
>>> +
>>> +template <> struct CustomMappingTraits<msgpack::MapNode> {
>>> + static void inputOne(IO &IO, StringRef Key, msgpack::MapNode &M) {
>>> + IO.mapRequired(Key.str().c_str(), M[Key]);
>>> + }
>>> + static void output(IO &IO, msgpack::MapNode &M) {
>>> + for (auto &N : M)
>>> + IO.mapRequired(N.getKey().str().c_str(), N.getValue());
>>> + }
>>> +};
>>> +
>>> +template <> struct SequenceTraits<msgpack::ArrayNode> {
>>> + static size_t size(IO &IO, msgpack::ArrayNode &A) { return
>>> A.size(); }
>>> + static msgpack::NodePtr &element(IO &IO, msgpack::ArrayNode &A,
>>> + size_t Index) {
>>> + if (Index >= A.size())
>>> + A.resize(Index + 1);
>>> + return A[Index];
>>> + }
>>> +};
>>> +
>>> +} // end namespace yaml
>>> +} // end namespace llvm
>>> +
>>> +#endif // LLVM_BINARYFORMAT_MSGPACKTYPES_H
>>> 
>>> Modified: llvm/trunk/lib/BinaryFormat/CMakeLists.txt
>>> URL:
>>> 
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/BinaryFormat/CMakeLists.txt?rev=346978&r1=346977&r2=346978&view=diff
>>> [5]
>>> 
>> ==============================================================================
>>> --- llvm/trunk/lib/BinaryFormat/CMakeLists.txt (original)
>>> +++ llvm/trunk/lib/BinaryFormat/CMakeLists.txt Thu Nov 15 10:50:01
>>> 2018
>>> @@ -2,6 +2,7 @@ add_llvm_library(LLVMBinaryFormat
>>> Dwarf.cpp
>>> Magic.cpp
>>> MsgPackReader.cpp
>>> + MsgPackTypes.cpp
>>> MsgPackWriter.cpp
>>> Wasm.cpp
>>> 
>>> Added: llvm/trunk/lib/BinaryFormat/MsgPackTypes.cpp
>>> URL:
>>> 
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/BinaryFormat/MsgPackTypes.cpp?rev=346978&view=auto
>>> [6]
>>> 
>> ==============================================================================
>>> --- llvm/trunk/lib/BinaryFormat/MsgPackTypes.cpp (added)
>>> +++ llvm/trunk/lib/BinaryFormat/MsgPackTypes.cpp Thu Nov 15 10:50:01
>>> 2018
>>> @@ -0,0 +1,303 @@
>>> +//===- MsgPackTypes.cpp - MsgPack Types -------------------------*-
>>> C++ -*-===//
>>> +//
>>> +// The LLVM Compiler Infrastructure
>>> +//
>>> +// This file is distributed under the University of Illinois Open
>>> Source
>>> +// License. See LICENSE.TXT for details.
>>> +//
>>> 
>> +//===----------------------------------------------------------------------===//
>>> +//
>>> +/// \file
>>> +/// Implementation of types representing MessagePack "documents".
>>> +//
>>> 
>> +//===----------------------------------------------------------------------===//
>>> +
>>> +#include "llvm/BinaryFormat/MsgPackTypes.h"
>>> +#include "llvm/Support/Error.h"
>>> +
>>> +using namespace llvm;
>>> +using namespace msgpack;
>>> +
>>> +namespace llvm {
>>> +namespace msgpack {
>>> +void ScalarNode::anchor() {}
>>> +void ArrayNode::anchor() {}
>>> +void MapNode::anchor() {}
>>> +}
>>> +}
>>> +
>>> +Expected<OptNodePtr> Node::readArray(Reader &MPReader, size_t
>>> Length) {
>>> + auto A = std::make_shared<ArrayNode>();
>>> + for (size_t I = 0; I < Length; ++I) {
>>> + auto OptNodeOrErr = Node::read(MPReader);
>>> + if (auto Err = OptNodeOrErr.takeError())
>>> + return std::move(Err);
>>> + if (!*OptNodeOrErr)
>>> + return make_error<StringError>(
>>> + "Insufficient array elements",
>>> + std::make_error_code(std::errc::invalid_argument));
>>> + A->push_back(std::move(**OptNodeOrErr));
>>> + }
>>> + return OptNodePtr(std::move(A));
>>> +}
>>> +
>>> +Expected<OptNodePtr> Node::readMap(Reader &MPReader, size_t Length)
>>> {
>>> + auto M = std::make_shared<MapNode>();
>>> + for (size_t I = 0; I < Length; ++I) {
>>> + auto OptKeyOrErr = Node::read(MPReader);
>>> + if (auto Err = OptKeyOrErr.takeError())
>>> + return std::move(Err);
>>> + if (!*OptKeyOrErr)
>>> + return make_error<StringError>(
>>> + "Insufficient map elements",
>>> + std::make_error_code(std::errc::invalid_argument));
>>> + auto OptValOrErr = Node::read(MPReader);
>>> + if (auto Err = OptValOrErr.takeError())
>>> + return std::move(Err);
>>> + if (!*OptValOrErr)
>>> + return make_error<StringError>(
>>> + "Insufficient map elements",
>>> + std::make_error_code(std::errc::invalid_argument));
>>> + auto *Key = dyn_cast<ScalarNode>((*OptKeyOrErr)->get());
>>> + if (!Key)
>>> + return make_error<StringError>(
>>> + "Only string map keys are supported",
>>> + std::make_error_code(std::errc::invalid_argument));
>>> + if (Key->getScalarKind() != ScalarNode::SK_String)
>>> + return make_error<StringError>(
>>> + "Only string map keys are supported",
>>> + std::make_error_code(std::errc::invalid_argument));
>>> + M->try_emplace(Key->getString(), std::move(**OptValOrErr));
>>> + }
>>> + return OptNodePtr(std::move(M));
>>> +}
>>> +
>>> +Expected<OptNodePtr> Node::read(Reader &MPReader) {
>>> + Object Obj;
>>> +
>>> + auto ContinueOrErr = MPReader.read(Obj);
>>> + if (auto Err = ContinueOrErr.takeError())
>>> + return std::move(Err);
>>> + if (!*ContinueOrErr)
>>> + return None;
>>> +
>>> + switch (Obj.Kind) {
>>> + case Type::Int:
>>> + return OptNodePtr(std::make_shared<ScalarNode>(Obj.Int));
>>> + case Type::UInt:
>>> + return OptNodePtr(std::make_shared<ScalarNode>(Obj.UInt));
>>> + case Type::Nil:
>>> + return OptNodePtr(std::make_shared<ScalarNode>());
>>> + case Type::Boolean:
>>> + return OptNodePtr(std::make_shared<ScalarNode>(Obj.Bool));
>>> + case Type::Float:
>>> + return OptNodePtr(std::make_shared<ScalarNode>(Obj.Float));
>>> + case Type::String:
>>> + return OptNodePtr(std::make_shared<ScalarNode>(Obj.Raw));
>>> + case Type::Binary:
>>> + return OptNodePtr(std::make_shared<ScalarNode>(Obj.Raw));
>>> + case Type::Array:
>>> + return Node::readArray(MPReader, Obj.Length);
>>> + case Type::Map:
>>> + return Node::readMap(MPReader, Obj.Length);
>>> + case Type::Extension:
>>> + return make_error<StringError>(
>>> + "Extension types are not supported",
>>> + std::make_error_code(std::errc::invalid_argument));
>>> + }
>>> + llvm_unreachable("msgpack::Type not handled");
>>> +}
>>> +
>>> +void ScalarNode::destroy() {
>>> + switch (SKind) {
>>> + case SK_String:
>>> + case SK_Binary:
>>> + StringValue.~basic_string();
>>> + break;
>>> + default:
>>> + // POD types do not require destruction
>>> + break;
>>> + }
>>> +}
>>> +
>>> +ScalarNode::ScalarNode(int64_t IntValue)
>>> + : Node(NK_Scalar), SKind(SK_Int), IntValue(IntValue) {}
>>> +
>>> +ScalarNode::ScalarNode(int32_t IntValue)
>>> + : ScalarNode(static_cast<int64_t>(IntValue)) {}
>>> +
>>> +ScalarNode::ScalarNode(uint64_t UIntValue)
>>> + : Node(NK_Scalar), SKind(SK_UInt), UIntValue(UIntValue) {}
>>> +
>>> +ScalarNode::ScalarNode(uint32_t IntValue)
>>> + : ScalarNode(static_cast<uint64_t>(IntValue)) {}
>>> +
>>> +ScalarNode::ScalarNode() : Node(NK_Scalar), SKind(SK_Nil) {}
>>> +
>>> +ScalarNode::ScalarNode(bool BoolValue)
>>> + : Node(NK_Scalar), SKind(SK_Boolean), BoolValue(BoolValue) {}
>>> +
>>> +ScalarNode::ScalarNode(double FloatValue)
>>> + : Node(NK_Scalar), SKind(SK_Float), BoolValue(FloatValue) {}
>>> +
>>> +ScalarNode::ScalarNode(StringRef StringValue)
>>> + : Node(NK_Scalar), SKind(SK_String) {
>>> + new (&this->StringValue) std::string(StringValue);
>>> +}
>>> +
>>> +ScalarNode::ScalarNode(const char *StringValue)
>>> + : ScalarNode(StringRef(StringValue)) {}
>>> +
>>> +ScalarNode::ScalarNode(std::string &&StringValue)
>>> + : Node(NK_Scalar), SKind(SK_String) {
>>> + new (&this->StringValue) std::string(StringValue);
>>> +}
>>> +
>>> +ScalarNode::ScalarNode(MemoryBufferRef BinaryValue)
>>> + : Node(NK_Scalar), SKind(SK_Binary) {
>>> + new (&StringValue) std::string(BinaryValue.getBuffer());
>>> +}
>>> +
>>> +ScalarNode::~ScalarNode() { destroy(); }
>>> +
>>> +ScalarNode &ScalarNode::operator=(ScalarNode &&RHS) {
>>> + destroy();
>>> + switch (SKind = RHS.SKind) {
>>> + case SK_Int:
>>> + IntValue = RHS.IntValue;
>>> + break;
>>> + case SK_UInt:
>>> + UIntValue = RHS.UIntValue;
>>> + break;
>>> + case SK_Boolean:
>>> + BoolValue = RHS.BoolValue;
>>> + break;
>>> + case SK_Float:
>>> + FloatValue = RHS.FloatValue;
>>> + break;
>>> + case SK_String:
>>> + case SK_Binary:
>>> + new (&StringValue) std::string(std::move(RHS.StringValue));
>>> + break;
>>> + case SK_Nil:
>>> + // pass
>>> + break;
>>> + }
>>> + return *this;
>>> +}
>>> +
>>> +StringRef ScalarNode::inputYAML(StringRef ScalarStr) {
>>> + switch (SKind) {
>>> + case SK_Int:
>>> + return yaml::ScalarTraits<int64_t>::input(ScalarStr, nullptr,
>>> IntValue);
>>> + case SK_UInt:
>>> + return yaml::ScalarTraits<uint64_t>::input(ScalarStr, nullptr,
>>> UIntValue);
>>> + case SK_Nil:
>>> + return StringRef();
>>> + case SK_Boolean:
>>> + return yaml::ScalarTraits<bool>::input(ScalarStr, nullptr,
>>> BoolValue);
>>> + case SK_Float:
>>> + return yaml::ScalarTraits<double>::input(ScalarStr, nullptr,
>>> FloatValue);
>>> + case SK_Binary:
>>> + case SK_String:
>>> + return yaml::ScalarTraits<std::string>::input(ScalarStr, nullptr,
>>> + StringValue);
>>> + }
>>> + llvm_unreachable("unrecognized ScalarKind");
>>> +}
>>> +
>>> +void ScalarNode::outputYAML(raw_ostream &OS) const {
>>> + switch (SKind) {
>>> + case SK_Int:
>>> + yaml::ScalarTraits<int64_t>::output(IntValue, nullptr, OS);
>>> + break;
>>> + case SK_UInt:
>>> + yaml::ScalarTraits<uint64_t>::output(UIntValue, nullptr, OS);
>>> + break;
>>> + case SK_Nil:
>>> + yaml::ScalarTraits<StringRef>::output("", nullptr, OS);
>>> + break;
>>> + case SK_Boolean:
>>> + yaml::ScalarTraits<bool>::output(BoolValue, nullptr, OS);
>>> + break;
>>> + case SK_Float:
>>> + yaml::ScalarTraits<double>::output(FloatValue, nullptr, OS);
>>> + break;
>>> + case SK_Binary:
>>> + case SK_String:
>>> + yaml::ScalarTraits<std::string>::output(StringValue, nullptr, OS);
>>> + break;
>>> + }
>>> +}
>>> +
>>> +yaml::QuotingType ScalarNode::mustQuoteYAML(StringRef ScalarStr)
>>> const {
>>> + switch (SKind) {
>>> + case SK_Int:
>>> + return yaml::ScalarTraits<int64_t>::mustQuote(ScalarStr);
>>> + case SK_UInt:
>>> + return yaml::ScalarTraits<uint64_t>::mustQuote(ScalarStr);
>>> + case SK_Nil:
>>> + return yaml::ScalarTraits<StringRef>::mustQuote(ScalarStr);
>>> + case SK_Boolean:
>>> + return yaml::ScalarTraits<bool>::mustQuote(ScalarStr);
>>> + case SK_Float:
>>> + return yaml::ScalarTraits<double>::mustQuote(ScalarStr);
>>> + case SK_Binary:
>>> + case SK_String:
>>> + return yaml::ScalarTraits<std::string>::mustQuote(ScalarStr);
>>> + }
>>> + llvm_unreachable("unrecognized ScalarKind");
>>> +}
>>> +
>>> +const char *ScalarNode::IntTag = "!int";
>>> +const char *ScalarNode::NilTag = "!nil";
>>> +const char *ScalarNode::BooleanTag = "!bool";
>>> +const char *ScalarNode::FloatTag = "!float";
>>> +const char *ScalarNode::StringTag = "!str";
>>> +const char *ScalarNode::BinaryTag = "!bin";
>>> +
>>> +StringRef ScalarNode::getYAMLTag() const {
>>> + switch (SKind) {
>>> + case SK_Int:
>>> + return IntTag;
>>> + case SK_UInt:
>>> + return IntTag;
>>> + case SK_Nil:
>>> + return NilTag;
>>> + case SK_Boolean:
>>> + return BooleanTag;
>>> + case SK_Float:
>>> + return FloatTag;
>>> + case SK_String:
>>> + return StringTag;
>>> + case SK_Binary:
>>> + return BinaryTag;
>>> + }
>>> + llvm_unreachable("unrecognized ScalarKind");
>>> +}
>>> +
>>> +void ScalarNode::write(Writer &MPWriter) {
>>> + switch (SKind) {
>>> + case SK_Int:
>>> + MPWriter.write(IntValue);
>>> + break;
>>> + case SK_UInt:
>>> + MPWriter.write(UIntValue);
>>> + break;
>>> + case SK_Nil:
>>> + MPWriter.writeNil();
>>> + break;
>>> + case SK_Boolean:
>>> + MPWriter.write(BoolValue);
>>> + break;
>>> + case SK_Float:
>>> + MPWriter.write(FloatValue);
>>> + break;
>>> + case SK_String:
>>> + MPWriter.write(StringValue);
>>> + break;
>>> + case SK_Binary:
>>> + MPWriter.write(MemoryBufferRef(StringValue, ""));
>>> + break;
>>> + }
>>> +}
>>> 
>>> Modified: llvm/trunk/unittests/BinaryFormat/CMakeLists.txt
>>> URL:
>>> 
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/BinaryFormat/CMakeLists.txt?rev=346978&r1=346977&r2=346978&view=diff
>>> [7]
>>> 
>> ==============================================================================
>>> --- llvm/trunk/unittests/BinaryFormat/CMakeLists.txt (original)
>>> +++ llvm/trunk/unittests/BinaryFormat/CMakeLists.txt Thu Nov 15
>>> 10:50:01 2018
>>> @@ -6,6 +6,7 @@ add_llvm_unittest(BinaryFormatTests
>>> DwarfTest.cpp
>>> MachOTest.cpp
>>> MsgPackReaderTest.cpp
>>> + MsgPackTypesTest.cpp
>>> MsgPackWriterTest.cpp
>>> TestFileMagic.cpp
>>> )
>>> 
>>> Added: llvm/trunk/unittests/BinaryFormat/MsgPackTypesTest.cpp
>>> URL:
>>> 
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/BinaryFormat/MsgPackTypesTest.cpp?rev=346978&view=auto
>>> [8]
>>> 
>> ==============================================================================
>>> --- llvm/trunk/unittests/BinaryFormat/MsgPackTypesTest.cpp (added)
>>> +++ llvm/trunk/unittests/BinaryFormat/MsgPackTypesTest.cpp Thu Nov
>>> 15 10:50:01 2018
>>> @@ -0,0 +1,188 @@
>>> +//===- MsgPackTypesTest.cpp -------------------------------------*-
>>> C++ -*-===//
>>> +//
>>> +// The LLVM Compiler Infrastructure
>>> +//
>>> +// This file is distributed under the University of Illinois Open
>>> Source
>>> +// License. See LICENSE.TXT for details.
>>> +//
>>> 
>> +//===----------------------------------------------------------------------===//
>>> +
>>> +#include "llvm/BinaryFormat/MsgPackTypes.h"
>>> +#include "gtest/gtest.h"
>>> +
>>> +using namespace llvm;
>>> +using namespace msgpack;
>>> +
>>> +TEST(MsgPackTypes, TestReadInt) {
>>> + Reader MPReader(StringRef("\xd0\x00", 2));
>>> + auto OptNodeOrErr = Node::read(MPReader);
>>> + ASSERT_TRUE(static_cast<bool>(OptNodeOrErr));
>>> + ASSERT_TRUE(*OptNodeOrErr);
>>> + auto *S = dyn_cast<ScalarNode>((*OptNodeOrErr)->get());
>>> + ASSERT_TRUE(S);
>>> + ASSERT_EQ(S->getScalarKind(), ScalarNode::SK_Int);
>>> + ASSERT_EQ(S->getInt(), 0);
>>> +}
>>> +
>>> +TEST(MsgPackTypes, TestReadArray) {
>>> + Reader MPReader(StringRef("\x92\xd0\x01\xc0"));
>>> + auto OptNodeOrErr = Node::read(MPReader);
>>> + ASSERT_TRUE(static_cast<bool>(OptNodeOrErr));
>>> + ASSERT_TRUE(*OptNodeOrErr);
>>> + auto *A = dyn_cast<ArrayNode>((*OptNodeOrErr)->get());
>>> + ASSERT_TRUE(A);
>>> + ASSERT_EQ(A->size(), 2u);
>>> + auto *SI = dyn_cast<ScalarNode>((*A)[0].get());
>>> + ASSERT_TRUE(SI);
>>> + ASSERT_EQ(SI->getScalarKind(), ScalarNode::SK_Int);
>>> + ASSERT_EQ(SI->getInt(), 1);
>>> + auto *SN = dyn_cast<ScalarNode>((*A)[1].get());
>>> + ASSERT_TRUE(SN);
>>> + ASSERT_EQ(SN->getScalarKind(), ScalarNode::SK_Nil);
>>> +}
>>> +
>>> +TEST(MsgPackTypes, TestReadMap) {
>>> + Reader MPReader(StringRef("\x82\xa3"
>>> + "foo"
>>> + "\xd0\x01\xa3"
>>> + "bar"
>>> + "\xd0\x02"));
>>> + auto OptNodeOrErr = Node::read(MPReader);
>>> + ASSERT_TRUE(static_cast<bool>(OptNodeOrErr));
>>> + ASSERT_TRUE(*OptNodeOrErr);
>>> + auto *A = dyn_cast<MapNode>((*OptNodeOrErr)->get());
>>> + ASSERT_TRUE(A);
>>> + ASSERT_EQ(A->size(), 2u);
>>> + auto *FooS = dyn_cast<ScalarNode>((*A)["foo"].get());
>>> + ASSERT_TRUE(FooS);
>>> + ASSERT_EQ(FooS->getScalarKind(), ScalarNode::SK_Int);
>>> + ASSERT_EQ(FooS->getInt(), 1);
>>> + auto *BarS = dyn_cast<ScalarNode>((*A)["bar"].get());
>>> + ASSERT_TRUE(BarS);
>>> + ASSERT_EQ(BarS->getScalarKind(), ScalarNode::SK_Int);
>>> + ASSERT_EQ(BarS->getInt(), 2);
>>> +}
>>> +
>>> +TEST(MsgPackTypes, TestWriteInt) {
>>> + std::string Buffer;
>>> + raw_string_ostream OStream(Buffer);
>>> + Writer MPWriter(OStream);
>>> + ScalarNode I(int64_t(1));
>>> + I.write(MPWriter);
>>> + ASSERT_EQ(OStream.str(), "\x01");
>>> +}
>>> +
>>> +TEST(MsgPackTypes, TestWriteArray) {
>>> + std::string Buffer;
>>> + raw_string_ostream OStream(Buffer);
>>> + Writer MPWriter(OStream);
>>> + ArrayNode A;
>>> + A.push_back(std::make_shared<ScalarNode>(int64_t(1)));
>>> + A.push_back(std::make_shared<ScalarNode>());
>>> + A.write(MPWriter);
>>> + ASSERT_EQ(OStream.str(), "\x92\x01\xc0");
>>> +}
>>> +
>>> +TEST(MsgPackTypes, TestWriteMap) {
>>> + std::string Buffer;
>>> + raw_string_ostream OStream(Buffer);
>>> + Writer MPWriter(OStream);
>>> + MapNode M;
>>> + M["foo"] = std::make_shared<ScalarNode>(int64_t(1));
>>> + M["bar"] = std::make_shared<ScalarNode>(int64_t(2));
>>> + M.write(MPWriter);
>>> + ASSERT_EQ(OStream.str(), "\x82\xa3"
>>> + "foo"
>>> + "\x01\xa3"
>>> + "bar"
>>> + "\x02");
>>> +}
>>> +
>>> +TEST(MsgPackTypes, TestOutputYAMLArray) {
>>> + std::string Buffer;
>>> + raw_string_ostream OStream(Buffer);
>>> + yaml::Output yout(OStream);
>>> + ArrayNode A;
>>> + A.push_back(std::make_shared<ScalarNode>(int64_t(1)));
>>> + A.push_back(std::make_shared<ScalarNode>(int64_t(2)));
>>> + yout << A;
>>> + ASSERT_EQ(OStream.str(), "---\n- !int 1\n- !int 2\n...\n");
>>> +}
>>> +
>>> +TEST(MsgPackTypes, TestInputYAMLArray) {
>>> + NodePtr RootNode;
>>> + yaml::Input yin("---\n- !int 1\n- !str 2\n...\n");
>>> + yin >> RootNode;
>>> + auto *A = dyn_cast<ArrayNode>(RootNode.get());
>>> + ASSERT_TRUE(A);
>>> + ASSERT_EQ(A->size(), 2u);
>>> + auto *SI = dyn_cast<ScalarNode>((*A)[0].get());
>>> + ASSERT_TRUE(SI);
>>> + ASSERT_EQ(SI->getScalarKind(), ScalarNode::SK_UInt);
>>> + ASSERT_EQ(SI->getUInt(), 1u);
>>> + auto *SS = dyn_cast<ScalarNode>((*A)[1].get());
>>> + ASSERT_TRUE(SS);
>>> + ASSERT_EQ(SS->getScalarKind(), ScalarNode::SK_String);
>>> + ASSERT_EQ(SS->getString(), "2");
>>> +}
>>> +
>>> +TEST(MsgPackTypes, TestOutputYAMLMap) {
>>> + std::string Buffer;
>>> + raw_string_ostream OStream(Buffer);
>>> + yaml::Output yout(OStream);
>>> + MapNode M;
>>> + M["foo"] = std::make_shared<ScalarNode>(int64_t(1));
>>> + M["bar"] = std::make_shared<ScalarNode>(uint64_t(2));
>>> + auto N = std::make_shared<MapNode>();
>>> + (*N)["baz"] = std::make_shared<ScalarNode>(true);
>>> + M["qux"] = std::move(N);
>>> + yout << M;
>>> + ASSERT_EQ(OStream.str(), "---\nfoo: !int 1\nbar: "
>>> + "!int 2\nqux: \n baz: "
>>> + "!bool true\n...\n");
>>> +}
>>> +
>>> +TEST(MsgPackTypes, TestInputYAMLMap) {
>>> + NodePtr RootNode;
>>> + yaml::Input yin("---\nfoo: !int 1\nbaz: !str 2\n...\n");
>>> + yin >> RootNode;
>>> + auto *M = dyn_cast<MapNode>(RootNode.get());
>>> + ASSERT_TRUE(M);
>>> + ASSERT_EQ(M->size(), 2u);
>>> + auto *SI = dyn_cast<ScalarNode>((*M)["foo"].get());
>>> + ASSERT_TRUE(SI);
>>> + ASSERT_EQ(SI->getScalarKind(), ScalarNode::SK_UInt);
>>> + ASSERT_EQ(SI->getUInt(), 1u);
>>> + auto *SS = dyn_cast<ScalarNode>((*M)["baz"].get());
>>> + ASSERT_TRUE(SS);
>>> + ASSERT_EQ(SS->getScalarKind(), ScalarNode::SK_String);
>>> + ASSERT_EQ(SS->getString(), "2");
>>> +}
>>> +
>>> +// Test that the document is parsed into a tree of shared_ptr where
>>> each node
>>> +// can have multiple owners.
>>> +TEST(MsgPackTypes, TestInputShared) {
>>> + yaml::Input yin("---\nfoo:\n bar: !int 1\n...\n");
>>> + NodePtr InnerMap;
>>> + NodePtr IntNode;
>>> + {
>>> + {
>>> + {
>>> + NodePtr RootNode;
>>> + yin >> RootNode;
>>> + auto *M = dyn_cast<MapNode>(RootNode.get());
>>> + ASSERT_TRUE(M);
>>> + ASSERT_EQ(M->size(), 1u);
>>> + InnerMap = (*M)["foo"];
>>> + }
>>> + auto *N = dyn_cast<MapNode>(InnerMap.get());
>>> + ASSERT_TRUE(N);
>>> + ASSERT_EQ(N->size(), 1u);
>>> + IntNode = (*N)["bar"];
>>> + }
>>> + auto *S = dyn_cast<ScalarNode>(IntNode.get());
>>> + ASSERT_TRUE(S);
>>> + ASSERT_EQ(S->getScalarKind(), ScalarNode::SK_UInt);
>>> + ASSERT_EQ(S->getUInt(), 1u);
>>> + }
>>> +}
>>> 
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>> 
>> 
>> 
>> Links:
>> ------
>> [1] http://llvm.org/viewvc/llvm-project?rev=346978&view=rev
>> [2] https://reviews.llvm.org/D48175
>> [3]
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BinaryFormat/MsgPackTypes.h?rev=346978&view=auto
>> [4] http://yaml.org
>> [5]
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/BinaryFormat/CMakeLists.txt?rev=346978&r1=346977&r2=346978&view=diff
>> [6]
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/BinaryFormat/MsgPackTypes.cpp?rev=346978&view=auto
>> [7]
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/BinaryFormat/CMakeLists.txt?rev=346978&r1=346977&r2=346978&view=diff
>> [8]
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/BinaryFormat/MsgPackTypesTest.cpp?rev=346978&view=auto


More information about the llvm-commits mailing list