clang 24.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
24namespace {
25constexpr const char *const PointerFlowKey = "PointerFlow";
26} // namespace
27
28// Writes an EdgeSet as an array of arrays of EntityPointerLevels:
29// [
30// [ [src-node], [dest-node], [dest-node], ...],
31// [ [src-node], [dest-node], [dest-node], ...],
32// ...
33// ]
35 llvm::iterator_range<EdgeSet::const_iterator> Edges,
36 JSONFormat::EntityIdToJSONFn EntityId2JSON) {
37 Array EdgesData;
38
39 for (const auto &[LHS, RHSSet] : Edges) {
40 Array EdgeEntry;
41 EdgeEntry.push_back(entityPointerLevelToJSON(LHS, EntityId2JSON));
42 for (const auto &RHS : RHSSet)
43 EdgeEntry.push_back(entityPointerLevelToJSON(RHS, EntityId2JSON));
44 EdgesData.push_back(Value(std::move(EdgeEntry)));
45 }
46 return EdgesData;
47}
48
51 JSONFormat::EntityIdFromJSONFn EntityIdFromJSON) {
52 EdgeSet Edges;
53
54 for (const auto &EdgesEntryData : EdgesData) {
55 const auto *EPLArray = EdgesEntryData.getAsArray();
56
57 if (!EPLArray || EPLArray->size() <= 1)
59 EdgesEntryData, "a JSON array of EntityPointerLevels with a size "
60 "greater than 1: [src, dest, dest, ...]");
61
62 auto SrcEPL =
63 entityPointerLevelFromJSON(*EPLArray->begin(), EntityIdFromJSON);
64
65 if (!SrcEPL)
66 return SrcEPL.takeError();
67 for (const auto &EPLData :
68 llvm::make_range(EPLArray->begin() + 1, EPLArray->end())) {
69 auto EPL = entityPointerLevelFromJSON(EPLData, EntityIdFromJSON);
70 if (!EPL)
71 return EPL.takeError();
72 Edges[*SrcEPL].insert(*EPL);
73 }
74 }
75 return Edges;
76}
77
78static llvm::json::Object
80 JSONFormat::EntityIdToJSONFn EntityId2JSON) {
82 Data[PointerFlowKey] = Value(
83 edgeSetToJSON(getEdges(static_cast<const PointerFlowEntitySummary &>(ES)),
84 EntityId2JSON));
85 return Data;
86}
87
90 JSONFormat::EntityIdFromJSONFn EntityIdFromJSON) {
91 const Value *EdgesData = Data.get(PointerFlowKey);
92
93 if (!EdgesData)
95 Object(Data), "a JSON object with the key: %s", PointerFlowKey);
96
97 const auto *EdgesDataAsArr = EdgesData->getAsArray();
98
99 if (!EdgesDataAsArr)
101 *EdgesData, "a JSON array of array of EntityPointerLevels");
102
103 auto Edges = edgeSetFromJSON(*EdgesDataAsArr, EntityIdFromJSON);
104
105 if (!Edges)
106 return Edges.takeError();
107 return std::make_unique<PointerFlowEntitySummary>(
108 buildPointerFlowEntitySummary(std::move(*Edges)));
109}
110
111namespace {
112struct PointerFlowJSONFormatInfo final : JSONFormat::FormatInfo {
113 PointerFlowJSONFormatInfo()
114 : JSONFormat::FormatInfo(PointerFlowEntitySummary::summaryName(),
116};
117} // namespace
118
119static llvm::Registry<JSONFormat::FormatInfo>::Add<PointerFlowJSONFormatInfo>
121 "PointerFlow", "JSON Format info for PointerFlowEntitySummary");
122
123namespace clang::ssaf {
124// NOLINTNEXTLINE(misc-use-internal-linkage)
126} // namespace clang::ssaf
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)
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:99
FormatInfoEntry< SerializerFn, DeserializerFn > FormatInfo
Definition JSONFormat.h:108
llvm::function_ref< Object(EntityId)> EntityIdToJSONFn
Definition JSONFormat.h:98
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 LHS pointer (source / assignee) to the set of RHS pointers (destinations / assigned values)...
Definition PointerFlow.h:24
llvm::json::Value entityPointerLevelToJSON(const EntityPointerLevel &EPL, JSONFormat::EntityIdToJSONFn EntityId2JSON)
llvm::iterator_range< EdgeSet::const_iterator > getEdges(const PointerFlowEntitySummary &)
llvm::Error makeSawButExpectedError(const JSONTy &Saw, llvm::StringRef Expected, const Ts &...ExpectedArgs)
volatile int PointerFlowJSONFormatAnchorSource
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)
Top level wrappers for InstallAPI frontend operations.