brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.7 KiB · a70290d Raw
103 lines · cpp
1///===- llvm/Frontend/Offloading/PropertySet.cpp --------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/Frontend/Offloading/PropertySet.h"10#include "llvm/Support/Base64.h"11#include "llvm/Support/JSON.h"12#include "llvm/Support/MemoryBufferRef.h"13 14using namespace llvm;15using namespace llvm::offloading;16 17void llvm::offloading::writePropertiesToJSON(18    const PropertySetRegistry &PSRegistry, raw_ostream &Out) {19  json::OStream J(Out);20  J.object([&] {21    for (const auto &[CategoryName, PropSet] : PSRegistry) {22      auto PropSetCapture = PropSet;23      J.attributeObject(CategoryName, [&] {24        for (const auto &[PropName, PropVal] : PropSetCapture) {25          switch (PropVal.index()) {26          case 0:27            J.attribute(PropName, std::get<uint32_t>(PropVal));28            break;29          case 1:30            J.attribute(PropName, encodeBase64(std::get<ByteArray>(PropVal)));31            break;32          default:33            llvm_unreachable("unsupported property type");34          }35        }36      });37    }38  });39}40 41// note: createStringError has an overload that takes a format string,42// but it uses llvm::format instead of llvm::formatv, which does43// not work with json::Value. This is a helper function to use44// llvm::formatv with createStringError.45template <typename... Ts> auto createStringErrorV(Ts &&...Args) {46  return createStringError(formatv(std::forward<Ts>(Args)...));47}48 49Expected<PropertyValue>50readPropertyValueFromJSON(const json::Value &PropValueVal) {51  if (std::optional<uint64_t> Val = PropValueVal.getAsUINT64())52    return PropertyValue(static_cast<uint32_t>(*Val));53 54  if (std::optional<StringRef> Val = PropValueVal.getAsString()) {55    std::vector<char> Decoded;56    if (Error E = decodeBase64(*Val, Decoded))57      return createStringErrorV("unable to base64 decode the string {0}: {1}",58                                Val, toString(std::move(E)));59    return PropertyValue(ByteArray(Decoded.begin(), Decoded.end()));60  }61 62  return createStringErrorV("expected a uint64 or a string, got {0}",63                            PropValueVal);64}65 66Expected<PropertySetRegistry>67llvm::offloading::readPropertiesFromJSON(MemoryBufferRef Buf) {68  PropertySetRegistry Res;69  Expected<json::Value> V = json::parse(Buf.getBuffer());70  if (Error E = V.takeError())71    return E;72 73  const json::Object *O = V->getAsObject();74  if (!O)75    return createStringErrorV(76        "error while deserializing property set registry: "77        "expected JSON object, got {0}",78        *V);79 80  for (const auto &[CategoryName, Value] : *O) {81    const json::Object *PropSetVal = Value.getAsObject();82    if (!PropSetVal)83      return createStringErrorV("error while deserializing property set {0}: "84                                "expected JSON array, got {1}",85                                CategoryName.str(), Value);86 87    PropertySet &PropSet = Res[CategoryName.str()];88    for (const auto &[PropName, PropValueVal] : *PropSetVal) {89      Expected<PropertyValue> Prop = readPropertyValueFromJSON(PropValueVal);90      if (Error E = Prop.takeError())91        return createStringErrorV(92            "error while deserializing property {0} in property set {1}: {2}",93            PropName.str(), CategoryName.str(), toString(std::move(E)));94 95      auto [It, Inserted] =96          PropSet.try_emplace(PropName.str(), std::move(*Prop));97      assert(Inserted && "Property already exists in PropertySet");98      (void)Inserted;99    }100  }101  return Res;102}103