clang 24.0.0git
VirtualMethodFamilyFormat.cpp
Go to the documentation of this file.
1//===- VirtualMethodFamilyFormat.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
12#include "llvm/ADT/StringRef.h"
13#include "llvm/Support/Error.h"
14#include "llvm/Support/JSON.h"
15#include "llvm/Support/Registry.h"
16#include <memory>
17#include <utility>
18#include <vector>
19
20using namespace clang;
21using namespace ssaf;
22
23using llvm::Expected;
24using Object = llvm::json::Object;
25using Array = llvm::json::Array;
26
27namespace {
28constexpr llvm::StringLiteral KeyParamEntities = "param_entities";
29constexpr llvm::StringLiteral KeyReturnEntity = "return_entity";
30constexpr llvm::StringLiteral KeyOverriddenMethods = "overridden_methods";
31
32constexpr llvm::StringLiteral KeyRetAndParamFamilyIds = "families";
33constexpr llvm::StringLiteral KeyParamId = "pid";
34constexpr llvm::StringLiteral KeyFamilyId = "fid";
35} // namespace
36
37static Array entityIdVectorToJSON(const std::vector<EntityId> &Ids,
40 Result.reserve(Ids.size());
41 for (EntityId Id : Ids)
42 Result.push_back(IdToJSON(Id));
43 return Result;
44}
45
49 std::vector<EntityId> Result;
50 Result.reserve(Arr.size());
51 for (const auto &V : Arr) {
52 const Object *Obj = V.getAsObject();
53 if (!Obj)
54 return makeSawButExpectedError(V, "an object representing EntityId");
55 auto Id = IdFromJSON(*Obj);
56 if (!Id)
57 return Id.takeError();
58 Result.push_back(*Id);
59 }
60 return Result;
61}
62
63//===----------------------------------------------------------------------===//
64// VirtualMethodSummary <-> JSON
65//===----------------------------------------------------------------------===//
66
67static Object
70 const auto &S = static_cast<const VirtualMethodSummary &>(ES);
71 Object Out;
72 Out[KeyParamEntities] = entityIdVectorToJSON(S.ParamEntities, IdToJSON);
73 if (S.ReturnEntity.has_value())
74 Out[KeyReturnEntity] = IdToJSON(*S.ReturnEntity);
75 Out[KeyOverriddenMethods] =
76 entityIdVectorToJSON(S.OverriddenMethods, IdToJSON);
77 return Out;
78}
79
83 auto Result = std::make_unique<VirtualMethodSummary>();
84
85 const Array *ParamArr = Obj.getArray(KeyParamEntities);
86 if (!ParamArr)
87 return makeSawButExpectedError(Obj, "an object with an array field '%s'",
88 KeyParamEntities.data());
89 auto Params = entityIdVectorFromJSON(*ParamArr, IdFromJSON);
90 if (!Params)
91 return Params.takeError();
92 Result->ParamEntities = std::move(*Params);
93
94 if (const Object *RE = Obj.getObject(KeyReturnEntity)) {
95 auto Id = IdFromJSON(*RE);
96 if (!Id)
97 return Id.takeError();
98 Result->ReturnEntity = *Id;
99 }
100
101 // Tolerant: absent key means no override edges (a root virtual method).
102 if (const Array *OMArr = Obj.getArray(KeyOverriddenMethods)) {
103 auto OM = entityIdVectorFromJSON(*OMArr, IdFromJSON);
104 if (!OM)
105 return OM.takeError();
106 Result->OverriddenMethods = std::move(*OM);
107 }
108
109 return std::move(Result);
110}
111
112//===----------------------------------------------------------------------===//
113// VirtualMethodFamilyAnalysisResult <-> JSON
114//===----------------------------------------------------------------------===//
115
119 Array FamilyDataArr;
120 for (const auto &[ParamId, FamilyId] : R.RetAndParamData) {
121 Object Item;
122 Item[KeyParamId] = IdToJSON(ParamId);
123 Item[KeyFamilyId] = IdToJSON(FamilyId);
124 FamilyDataArr.push_back(std::move(Item));
125 }
126
127 Object Out;
128 Out[KeyRetAndParamFamilyIds] = std::move(FamilyDataArr);
129 return Out;
130}
131
134 const Object &Obj, JSONFormat::EntityIdFromJSONFn IdFromJSON) {
135 const Array *FamilyDataArr = Obj.getArray(KeyRetAndParamFamilyIds);
136 if (!FamilyDataArr)
137 return makeSawButExpectedError(Obj, "an object with an array field '%s'",
138 KeyRetAndParamFamilyIds.data());
139
140 auto Result = std::make_unique<VirtualMethodFamilyAnalysisResult>();
141
142 for (const auto &V : *FamilyDataArr) {
143 const Object *Item = V.getAsObject();
144 if (!Item)
145 return makeSawButExpectedError(V, "an object {pid, fid}");
146 const Object *ParamObj = Item->getObject(KeyParamId);
147 const Object *FamilyObj = Item->getObject(KeyFamilyId);
148 if (!ParamObj || !FamilyObj)
149 return makeSawButExpectedError(*Item,
150 "an object with fields {'%s', '%s'}",
151 KeyParamId.data(), KeyFamilyId.data());
152 auto ParamId = IdFromJSON(*ParamObj);
153 if (!ParamId)
154 return ParamId.takeError();
155 auto FamilyId = IdFromJSON(*FamilyObj);
156 if (!FamilyId)
157 return FamilyId.takeError();
158 Result->RetAndParamData.insert({*ParamId, *FamilyId});
159 }
160 return std::move(Result);
161}
162
163namespace {
164
165struct VirtualMethodSummaryJSONFormatInfo final : JSONFormat::FormatInfo {
166 VirtualMethodSummaryJSONFormatInfo()
167 : JSONFormat::FormatInfo(VirtualMethodSummary::summaryName(),
170};
171} // namespace
172
173static llvm::Registry<JSONFormat::FormatInfo>::Add<
174 VirtualMethodSummaryJSONFormatInfo>
176 "JSON Format info for VirtualMethodSummary");
177
178static JSONFormat::AnalysisResultRegistry::Add<
182
183namespace clang::ssaf {
184// NOLINTNEXTLINE(misc-use-internal-linkage)
186} // namespace clang::ssaf
#define V(N, I)
Result
Implement __builtin_bit_cast and related operations.
llvm::json::Object Object
llvm::json::Array Array
static Expected< std::vector< EntityId > > entityIdVectorFromJSON(const Array &Arr, JSONFormat::EntityIdFromJSONFn IdFromJSON)
static Expected< std::unique_ptr< AnalysisResult > > deserializeVirtualMethodFamilyAnalysisResult(const Object &Obj, JSONFormat::EntityIdFromJSONFn IdFromJSON)
static JSONFormat::AnalysisResultRegistry::Add< VirtualMethodFamilyAnalysisResult > RegisterResultJSONFormat(serializeVirtualMethodFamilyAnalysisResult, deserializeVirtualMethodFamilyAnalysisResult)
static Array entityIdVectorToJSON(const std::vector< EntityId > &Ids, JSONFormat::EntityIdToJSONFn IdToJSON)
static Expected< std::unique_ptr< EntitySummary > > deserializeVirtualMethodSummary(const Object &Obj, EntityIdTable &, JSONFormat::EntityIdFromJSONFn IdFromJSON)
static llvm::Registry< JSONFormat::FormatInfo >::Add< VirtualMethodSummaryJSONFormatInfo > RegisterJSONFormat(VirtualMethodSummary::Name, "JSON Format info for VirtualMethodSummary")
static Object serializeVirtualMethodSummary(const EntitySummary &ES, JSONFormat::EntityIdToJSONFn IdToJSON)
static Object serializeVirtualMethodFamilyAnalysisResult(const VirtualMethodFamilyAnalysisResult &R, JSONFormat::EntityIdToJSONFn IdToJSON)
Manages entity name interning and provides efficient EntityId handles.
Lightweight opaque handle representing an entity in an EntityIdTable.
Definition EntityId.h:31
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
volatile int VirtualMethodFamilyJSONFormatAnchorSource
llvm::Error makeSawButExpectedError(const JSONTy &Saw, llvm::StringRef Expected, const Ts &...ExpectedArgs)
Top level wrappers for InstallAPI frontend operations.
static constexpr llvm::StringLiteral Name