summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorScott Linder <scott@scottlinder.com>2018-11-15 18:50:01 +0000
committerScott Linder <scott@scottlinder.com>2018-11-15 18:50:01 +0000
commit919fbbbcca6a6c137b2319aecf70cfb0f48136a0 (patch)
tree60ddbab178d0fbdb895335d91ac13ec8ecabff5b /llvm/lib
parent6cda87463fbb32c310d43e840684133a210963dd (diff)
downloadbcm5719-llvm-919fbbbcca6a6c137b2319aecf70cfb0f48136a0.tar.gz
bcm5719-llvm-919fbbbcca6a6c137b2319aecf70cfb0f48136a0.zip
[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 llvm-svn: 346978
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/BinaryFormat/CMakeLists.txt1
-rw-r--r--llvm/lib/BinaryFormat/MsgPackTypes.cpp303
2 files changed, 304 insertions, 0 deletions
diff --git a/llvm/lib/BinaryFormat/CMakeLists.txt b/llvm/lib/BinaryFormat/CMakeLists.txt
index 93bb8b07763..94d08ee3a15 100644
--- a/llvm/lib/BinaryFormat/CMakeLists.txt
+++ b/llvm/lib/BinaryFormat/CMakeLists.txt
@@ -2,6 +2,7 @@ add_llvm_library(LLVMBinaryFormat
Dwarf.cpp
Magic.cpp
MsgPackReader.cpp
+ MsgPackTypes.cpp
MsgPackWriter.cpp
Wasm.cpp
diff --git a/llvm/lib/BinaryFormat/MsgPackTypes.cpp b/llvm/lib/BinaryFormat/MsgPackTypes.cpp
new file mode 100644
index 00000000000..4a8f70b10fb
--- /dev/null
+++ b/llvm/lib/BinaryFormat/MsgPackTypes.cpp
@@ -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;
+ }
+}
OpenPOWER on IntegriCloud