clang 23.0.0git
PointerFlowFormat.cpp
Go to the documentation of this file.
1//===- PointerFlowFormat.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-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "SSAFAnalysesCommon.h"
14#include "llvm/ADT/iterator_range.h"
15#include "llvm/Support/Error.h"
16#include "llvm/Support/JSON.h"
17
18using namespace clang;
19using namespace ssaf;
20using Object = llvm::json::Object;
21using Array = llvm::json::Array;
22using Value = llvm::json::Value;
23
26
27llvm::iterator_range<EdgeSet::const_iterator>
28ssaf::getEdges(const PointerFlowEntitySummary &Sum);
29
30namespace {
31constexpr const char *const PointerFlowKey = "PointerFlow";
32} // namespace
33
34// Writes an EdgeSet as an array of arrays of EntityPointerLevels:
35// [
36// [ [src-node], [dest-node], [dest-node], ...],
37// [ [src-node], [dest-node], [dest-node], ...],
38// ...
39// ]
41 llvm::iterator_range<EdgeSet::const_iterator> Edges,
42 JSONFormat::EntityIdToJSONFn EntityId2JSON) {
43 Array EdgesData;
44
45 for (const auto &[LHS, RHSSet] : Edges) {
46 Array EdgeEntry;
47 EdgeEntry.push_back(entityPointerLevelToJSON(LHS, EntityId2JSON));
48 for (const auto &RHS : RHSSet)
49 EdgeEntry.push_back(entityPointerLevelToJSON(RHS, EntityId2JSON));
50 EdgesData.push_back(Value(std::move(EdgeEntry)));
51 }
52 return EdgesData;
53}
54
57 JSONFormat::EntityIdFromJSONFn EntityIdFromJSON) {
58 EdgeSet Edges;
59
60 for (const auto &EdgesEntryData : EdgesData) {
61 const auto *EPLArray = EdgesEntryData.getAsArray();
62
63 if (!EPLArray || EPLArray->size() <= 1)
65 EdgesEntryData, "a JSON array of EntityPointerLevels with a size "
66 "greater than 1: [src, dest, dest, ...]");
67
68 auto SrcEPL =
69 entityPointerLevelFromJSON(*EPLArray->begin(), EntityIdFromJSON);
70
71 if (!SrcEPL)
72 return SrcEPL.takeError();
73 for (const auto &EPLData :
74 llvm::make_range(EPLArray->begin() + 1, EPLArray->end())) {
75 auto EPL = entityPointerLevelFromJSON(EPLData, EntityIdFromJSON);
76 if (!EPL)
77 return EPL.takeError();
78 Edges[*SrcEPL].insert(*EPL);
79 }
80 }
81 return Edges;
82}
83
84static llvm::json::Object
86 JSONFormat::EntityIdToJSONFn EntityId2JSON) {
88 Data[PointerFlowKey] = Value(
89 edgeSetToJSON(getEdges(static_cast<const PointerFlowEntitySummary &>(ES)),
90 EntityId2JSON));
91 return Data;
92}
93
96 JSONFormat::EntityIdFromJSONFn EntityIdFromJSON) {
97 const Value *EdgesData = Data.get(PointerFlowKey);
98
99 if (!EdgesData)
101 Object(Data), "a JSON object with the key: %s", PointerFlowKey);
102
103 const auto *EdgesDataAsArr = EdgesData->getAsArray();
104
105 if (!EdgesDataAsArr)
107 *EdgesData, "a JSON array of array of EntityPointerLevels");
108
109 auto Edges = edgeSetFromJSON(*EdgesDataAsArr, EntityIdFromJSON);
110
111 if (!Edges)
112 return Edges.takeError();
113 return std::make_unique<PointerFlowEntitySummary>(
114 buildPointerFlowEntitySummary(std::move(*Edges)));
115}
116
117namespace {
118struct PointerFlowJSONFormatInfo final : JSONFormat::FormatInfo {
119 PointerFlowJSONFormatInfo()
120 : JSONFormat::FormatInfo(PointerFlowEntitySummary::summaryName(),
122};
123} // namespace
124
125static llvm::Registry<JSONFormat::FormatInfo>::Add<PointerFlowJSONFormatInfo>
127 "PointerFlow", "JSON Format info for PointerFlowEntitySummary");
128
129// NOLINTNEXTLINE(misc-use-internal-linkage)
llvm::json::Object Object
static llvm::Registry< JSONFormat::FormatInfo >::Add< PointerFlowJSONFormatInfo > RegisterPointerFlowJSONFormatInfo("PointerFlow", "JSON Format info for PointerFlowEntitySummary")
static llvm::json::Object summaryToJSON(const EntitySummary &ES, JSONFormat::EntityIdToJSONFn EntityId2JSON)
llvm::json::Value Value
llvm::json::Array Array
static llvm::Expected< std::unique_ptr< EntitySummary > > summaryFromJSON(const Object &Data, EntityIdTable &, JSONFormat::EntityIdFromJSONFn EntityIdFromJSON)
volatile int PointerFlowSSAFJSONFormatAnchorSource
Manages entity name interning and provides efficient EntityId handles.
Base class for analysis-specific summary data.
llvm::function_ref< llvm::Expected< EntityId >(const Object &)> EntityIdFromJSONFn
Definition JSONFormat.h:71
FormatInfoEntry< SerializerFn, DeserializerFn > FormatInfo
Definition JSONFormat.h:80
llvm::function_ref< Object(EntityId)> EntityIdToJSONFn
Definition JSONFormat.h:70
llvm::json::Array edgeSetToJSON(llvm::iterator_range< EdgeSet::const_iterator > Edges, JSONFormat::EntityIdToJSONFn IdToJSON)
Serialize an EdgeSet {(src1, dest1), (src1, dest2), (src2, dest3), (src2, dest4), ....
llvm::json::Array Array
std::map< EntityPointerLevel, EntityPointerLevelSet > EdgeSet
Maps each source node to its destination nodes:
Definition PointerFlow.h:23
llvm::json::Value entityPointerLevelToJSON(const EntityPointerLevel &EPL, JSONFormat::EntityIdToJSONFn EntityId2JSON)
llvm::Error makeSawButExpectedError(const JSONTy &Saw, llvm::StringRef Expected, const Ts &...ExpectedArgs)
llvm::Expected< EdgeSet > edgeSetFromJSON(const llvm::json::Array &EdgesData, JSONFormat::EntityIdFromJSONFn IdFromJSON)
Deserialize an EdgeSet from the array format produced by edgeSetToJSON.
PointerFlowEntitySummary buildPointerFlowEntitySummary(EdgeSet Edges)
Expected< EntityPointerLevel > entityPointerLevelFromJSON(const llvm::json::Value &EPLData, JSONFormat::EntityIdFromJSONFn EntityIdFromJSON)
The JSON file list parser is used to communicate input to InstallAPI.