[llvm] r346978 - [BinaryFormat] Add MsgPackTypes

Adrian Prantl via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 15 12:48:10 PST 2018


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
> 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
> 
> 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
> ==============================================================================
> --- 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,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
> ==============================================================================
> --- 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
> ==============================================================================
> --- 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
> ==============================================================================
> --- 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
> ==============================================================================
> --- 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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181115/dfbfda4f/attachment-0001.html>


More information about the llvm-commits mailing list