================
@@ -0,0 +1,209 @@
+//===- WPASuite.cpp 
-------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "JSONFormatImpl.h"
+
+#include 
"clang/ScalableStaticAnalysisFramework/Core/WholeProgramAnalysis/WPASuite.h"
+
+namespace clang::ssaf {
+
+//----------------------------------------------------------------------------
+// AnalysisResultMapEntry
+//----------------------------------------------------------------------------
+
+llvm::Expected<std::pair<AnalysisName, std::unique_ptr<AnalysisResult>>>
+JSONFormat::analysisResultMapEntryFromJSON(const Object &Entry) const {
+  auto OptName = Entry.getString("analysis_name");
+  if (!OptName) {
+    return ErrorBuilder::create(std::errc::invalid_argument,
+                                ErrorMessages::FailedToReadObjectAtField,
+                                "AnalysisName", "analysis_name", "string")
+        .build();
+  }
+
+  AnalysisName Name = analysisNameFromJSON(*OptName);
+
+  auto ExpectedFns = AnalysisResultRegistry::lookup(Name);
+  if (!ExpectedFns) {
+    return ExpectedFns.takeError();
+  }
+
+  const Object *ResultObj = Entry.getObject("result");
+  if (!ResultObj) {
+    return ErrorBuilder::create(std::errc::invalid_argument,
+                                ErrorMessages::FailedToReadObjectAtField,
+                                "AnalysisResult", "result", "object")
+        .build();
+  }
+
+  auto ExpectedResult =
+      ExpectedFns->second(*ResultObj, &entityIdFromJSONObject);
+  if (!ExpectedResult) {
+    return ExpectedResult.takeError();
+  }
+
+  return std::make_pair(std::move(Name), std::move(*ExpectedResult));
+}
+
+llvm::Expected<Object> JSONFormat::analysisResultMapEntryToJSON(
+    const AnalysisName &Name,
+    const std::unique_ptr<AnalysisResult> &Result) const {
+  auto ExpectedFns = AnalysisResultRegistry::lookup(Name);
+  if (!ExpectedFns) {
+    return ExpectedFns.takeError();
+  }
+
+  Object Entry;
+  Entry["analysis_name"] = analysisNameToJSON(Name);
+  Entry["result"] = ExpectedFns->first(*Result, &entityIdToJSONObject);
+  return Entry;
+}
+
+//----------------------------------------------------------------------------
+// AnalysisResultMap
+//----------------------------------------------------------------------------
+
+llvm::Expected<std::map<AnalysisName, std::unique_ptr<AnalysisResult>>>
+JSONFormat::analysisResultMapFromJSON(const Array &ResultsArray) const {
+  std::map<AnalysisName, std::unique_ptr<AnalysisResult>> Results;
+  for (size_t I = 0; I < ResultsArray.size(); ++I) {
+    const Object *Entry = ResultsArray[I].getAsObject();
+    if (!Entry) {
+      return ErrorBuilder::create(std::errc::invalid_argument,
+                                  ErrorMessages::FailedToReadObjectAtIndex,
+                                  "WPA result entry", I, "object")
+          .build();
+    }
+
+    auto ExpectedPair = analysisResultMapEntryFromJSON(*Entry);
+    if (!ExpectedPair) {
+      return ErrorBuilder::wrap(ExpectedPair.takeError())
+          .context(ErrorMessages::ReadingFromIndex, "WPA result entry", I)
+          .build();
+    }
+
+    auto [Name, Result] = std::move(*ExpectedPair);
+    bool Inserted = Results.try_emplace(Name, std::move(Result)).second;
+    if (!Inserted) {
+      return ErrorBuilder::create(std::errc::invalid_argument,
+                                  ErrorMessages::FailedInsertionOnDuplication,
+                                  "WPA result", I, Name)
+          .build();
+    }
+  }
+  return Results;
+}
+
+llvm::Expected<Array> JSONFormat::analysisResultMapToJSON(
+    const std::map<AnalysisName, std::unique_ptr<AnalysisResult>> &Data) const 
{
+  Array Results;
+  for (const auto &[Name, Result] : Data) {
+    auto ExpectedEntry = analysisResultMapEntryToJSON(Name, Result);
+    if (!ExpectedEntry) {
+      return ExpectedEntry.takeError();
+    }
+    Results.push_back(std::move(*ExpectedEntry));
+  }
+  return Results;
+}
+
+//----------------------------------------------------------------------------
+// WPASuite
+//----------------------------------------------------------------------------
+
+llvm::Expected<WPASuite> JSONFormat::readWPASuite(llvm::StringRef Path) {
+  auto ExpectedJSON = readJSON(Path);
+  if (!ExpectedJSON) {
+    return ErrorBuilder::wrap(ExpectedJSON.takeError())
+        .context(ErrorMessages::ReadingFromFile, "WPASuite", Path)
+        .build();
+  }
+
+  Object *RootObjectPtr = ExpectedJSON->getAsObject();
+  if (!RootObjectPtr) {
+    return ErrorBuilder::create(std::errc::invalid_argument,
+                                ErrorMessages::FailedToReadObject, "WPASuite",
+                                "object")
+        .context(ErrorMessages::ReadingFromFile, "WPASuite", Path)
+        .build();
+  }
+
+  const Object &RootObject = *RootObjectPtr;
+
+  WPASuite Suite = makeWPASuite();
+
+  {
+    const Array *IdTableArray = RootObject.getArray("id_table");
+    if (!IdTableArray) {
+      return ErrorBuilder::create(std::errc::invalid_argument,
+                                  ErrorMessages::FailedToReadObjectAtField,
+                                  "IdTable", "id_table", "array")
+          .context(ErrorMessages::ReadingFromFile, "WPASuite", Path)
+          .build();
+    }
+
+    auto ExpectedIdTable = entityIdTableFromJSON(*IdTableArray);
+    if (!ExpectedIdTable) {
+      return ErrorBuilder::wrap(ExpectedIdTable.takeError())
+          .context(ErrorMessages::ReadingFromField, "IdTable", "id_table")
+          .context(ErrorMessages::ReadingFromFile, "WPASuite", Path)
+          .build();
+    }
+
+    getIdTable(Suite) = std::move(*ExpectedIdTable);
+  }
+
+  {
+    const Array *ResultsArray = RootObject.getArray("results");
+    if (!ResultsArray) {
+      return ErrorBuilder::create(std::errc::invalid_argument,
+                                  ErrorMessages::FailedToReadObjectAtField,
+                                  "WPA results", "results", "array")
+          .context(ErrorMessages::ReadingFromFile, "WPASuite", Path)
+          .build();
+    }
+
+    auto ExpectedResultsMap = analysisResultMapFromJSON(*ResultsArray);
+    if (!ExpectedResultsMap) {
+      return ErrorBuilder::wrap(ExpectedResultsMap.takeError())
+          .context(ErrorMessages::ReadingFromField, "WPA results", "results")
+          .context(ErrorMessages::ReadingFromFile, "WPASuite", Path)
+          .build();
+    }
+
+    getData(Suite) = std::move(*ExpectedResultsMap);
+  }
+
+  return Suite;
----------------
steakhal wrote:

```suggestion
  return std::move(Suite);
```

https://github.com/llvm/llvm-project/pull/187403
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to