================
@@ -0,0 +1,465 @@
+//===- ExamplePlugin.cpp - Example SSAF plugin 
----------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// A loadable plugin that demonstrates the full SSAF analysis pipeline.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/ScalableStaticAnalysisFramework/Core/Model/EntityId.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/Model/SummaryName.h"
+#include 
"clang/ScalableStaticAnalysisFramework/Core/Serialization/JSONFormat.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/TUSummary/EntitySummary.h"
+#include 
"clang/ScalableStaticAnalysisFramework/Core/WholeProgramAnalysis/AnalysisName.h"
+#include 
"clang/ScalableStaticAnalysisFramework/Core/WholeProgramAnalysis/AnalysisRegistry.h"
+#include 
"clang/ScalableStaticAnalysisFramework/Core/WholeProgramAnalysis/AnalysisResult.h"
+#include 
"clang/ScalableStaticAnalysisFramework/Core/WholeProgramAnalysis/DerivedAnalysis.h"
+#include 
"clang/ScalableStaticAnalysisFramework/Core/WholeProgramAnalysis/SummaryAnalysis.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/JSON.h"
+#include "llvm/Support/Registry.h"
+#include <algorithm>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+using namespace clang::ssaf;
+using namespace llvm;
+
+namespace {
+
+//===----------------------------------------------------------------------===//
+// TagsEntitySummary
+//
+// Per-entity data: a list of string tags. Stored in the LU data section
+// under summary_name "TagsEntitySummary". Serialized as:
+//   { "tags": ["tag1", "tag2", ...] }
+//===----------------------------------------------------------------------===//
+
+struct TagsEntitySummary final : EntitySummary {
+  static SummaryName summaryName() { return SummaryName("TagsEntitySummary"); }
+
+  SummaryName getSummaryName() const override {
+    return SummaryName("TagsEntitySummary");
+  }
+
+  std::vector<std::string> Tags;
+};
+
+json::Object serializeTagsEntitySummary(const EntitySummary &ES,
+                                        JSONFormat::EntityIdToJSONFn) {
+  const auto &S = static_cast<const TagsEntitySummary &>(ES);
+  json::Array TagsArray;
+  for (const auto &Tag : S.Tags) {
+    TagsArray.push_back(Tag);
+  }
+  return json::Object{{"tags", std::move(TagsArray)}};
+}
+
+Expected<std::unique_ptr<EntitySummary>>
+deserializeTagsEntitySummary(const json::Object &Obj, EntityIdTable &,
+                             JSONFormat::EntityIdFromJSONFn) {
+  const json::Array *TagsArray = Obj.getArray("tags");
+  if (!TagsArray) {
+    return createStringError(inconvertibleErrorCode(),
+                             "missing or invalid field 'tags'");
+  }
+
+  auto S = std::make_unique<TagsEntitySummary>();
+  for (const auto &[Index, Val] : llvm::enumerate(*TagsArray)) {
+    auto Str = Val.getAsString();
+    if (!Str) {
+      return createStringError(inconvertibleErrorCode(),
+                               "tags element at index %zu is not a string",
+                               Index);
+    }
+    S->Tags.push_back(Str->str());
+  }
+  return std::move(S);
+}
+
+struct TagsEntitySummaryFormatInfo final : JSONFormat::FormatInfo {
+  TagsEntitySummaryFormatInfo()
+      : JSONFormat::FormatInfo(SummaryName("TagsEntitySummary"),
+                               serializeTagsEntitySummary,
+                               deserializeTagsEntitySummary) {}
+};
+
+llvm::Registry<JSONFormat::FormatInfo>::Add<TagsEntitySummaryFormatInfo>
+    RegisterTagsEntitySummaryForJSON("TagsEntitySummary",
+                                     "JSON format info for TagsEntitySummary");
+
+//===----------------------------------------------------------------------===//
+// PairsEntitySummary
+//
+// Per-entity data: a list of (EntityId, EntityId) pairs. Stored in the LU
+// data section under summary_name "PairsEntitySummary". Serialized as:
+//   { "pairs": [{"first": {...}, "second": {...}}, ...] }
+//===----------------------------------------------------------------------===//
+
+struct PairsEntitySummary final : EntitySummary {
+  static SummaryName summaryName() { return SummaryName("PairsEntitySummary"); 
}
+
+  SummaryName getSummaryName() const override {
+    return SummaryName("PairsEntitySummary");
+  }
+
+  std::vector<std::pair<EntityId, EntityId>> Pairs;
+};
+
+json::Object serializePairsEntitySummary(const EntitySummary &ES,
+                                         JSONFormat::EntityIdToJSONFn ToJSON) {
+  const auto &S = static_cast<const PairsEntitySummary &>(ES);
+  json::Array PairsArray;
+  for (const auto &[First, Second] : S.Pairs) {
+    PairsArray.push_back(json::Object{
+        {"first", ToJSON(First)},
+        {"second", ToJSON(Second)},
+    });
+  }
+  return json::Object{{"pairs", std::move(PairsArray)}};
+}
+
+Expected<std::unique_ptr<EntitySummary>>
+deserializePairsEntitySummary(const json::Object &Obj, EntityIdTable &,
+                              JSONFormat::EntityIdFromJSONFn FromJSON) {
+  auto Result = std::make_unique<PairsEntitySummary>();
+  const json::Array *PairsArray = Obj.getArray("pairs");
+  if (!PairsArray) {
+    return createStringError(inconvertibleErrorCode(),
+                             "missing or invalid field 'pairs'");
+  }
+  for (const auto &[Index, Value] : llvm::enumerate(*PairsArray)) {
+    const json::Object *Pair = Value.getAsObject();
+    if (!Pair) {
+      return createStringError(
+          inconvertibleErrorCode(),
+          "pairs element at index %zu is not a JSON object", Index);
+    }
+    const json::Object *FirstObj = Pair->getObject("first");
+    if (!FirstObj) {
+      return createStringError(
+          inconvertibleErrorCode(),
+          "missing or invalid 'first' field at index '%zu'", Index);
+    }
+    const json::Object *SecondObj = Pair->getObject("second");
+    if (!SecondObj) {
+      return createStringError(
+          inconvertibleErrorCode(),
+          "missing or invalid 'second' field at index '%zu'", Index);
+    }
+    auto ExpectedFirst = FromJSON(*FirstObj);
+    if (!ExpectedFirst) {
+      return createStringError(inconvertibleErrorCode(),
+                               "invalid 'first' entity id at index '%zu': %s",
+                               Index,
+                               toString(ExpectedFirst.takeError()).c_str());
+    }
+    auto ExpectedSecond = FromJSON(*SecondObj);
+    if (!ExpectedSecond) {
+      return createStringError(inconvertibleErrorCode(),
+                               "invalid 'second' entity id at index '%zu': %s",
+                               Index,
+                               toString(ExpectedSecond.takeError()).c_str());
+    }
+    Result->Pairs.emplace_back(*ExpectedFirst, *ExpectedSecond);
+  }
+  return std::move(Result);
+}
+
+struct PairsEntitySummaryFormatInfo final : JSONFormat::FormatInfo {
+  PairsEntitySummaryFormatInfo()
+      : JSONFormat::FormatInfo(SummaryName("PairsEntitySummary"),
+                               serializePairsEntitySummary,
+                               deserializePairsEntitySummary) {}
+};
+
+llvm::Registry<JSONFormat::FormatInfo>::Add<PairsEntitySummaryFormatInfo>
+    RegisterPairsEntitySummaryForJSON(
+        "PairsEntitySummary", "JSON format info for PairsEntitySummary");
+
+//===----------------------------------------------------------------------===//
+// TagsAnalysisResult
+//
+// Sorted, deduplicated list of all tags seen across entities. Serialized as:
+//   { "tags": ["tag1", "tag2", ...] }
+//===----------------------------------------------------------------------===//
+
+struct TagsAnalysisResult final : AnalysisResult {
+  static AnalysisName analysisName() {
+    return AnalysisName("TagsAnalysisResult");
+  }
+
+  std::vector<std::string> Tags;
+};
+
+json::Object serializeTagsAnalysisResult(const TagsAnalysisResult &R,
+                                         JSONFormat::EntityIdToJSONFn) {
+  json::Array TagsArray;
+  for (const auto &Tag : R.Tags) {
+    TagsArray.push_back(Tag);
+  }
----------------
steakhal wrote:

Sniffing reserve and append_range.

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