15#include "llvm/Support/Error.h"
16#include "llvm/Support/JSON.h"
17#include "llvm/Support/Registry.h"
37 static SummaryName summaryName() {
return SummaryName(
"PairsEntitySummary"); }
39 SummaryName getSummaryName()
const override {
40 return SummaryName(
"PairsEntitySummary");
43 std::vector<std::pair<EntityId, EntityId>> Pairs;
46json::Object serializePairsEntitySummary(
const EntitySummary &ES,
48 const auto &S =
static_cast<const PairsEntitySummary &
>(ES);
49 json::Array PairsArray;
50 for (
const auto &[
First, Second] : S.Pairs) {
51 PairsArray.push_back(json::Object{
52 {
"first", ToJSON(
First)},
53 {
"second", ToJSON(Second)},
56 return json::Object{{
"pairs", std::move(PairsArray)}};
60deserializePairsEntitySummary(
const json::Object &Obj,
EntityIdTable &,
62 auto Result = std::make_unique<PairsEntitySummary>();
63 const json::Array *PairsArray = Obj.getArray(
"pairs");
65 return createStringError(inconvertibleErrorCode(),
66 "missing or invalid field 'pairs'");
68 for (
const auto &[Index,
Value] : llvm::enumerate(*PairsArray)) {
69 const json::Object *Pair =
Value.getAsObject();
71 return createStringError(
72 inconvertibleErrorCode(),
73 "pairs element at index %zu is not a JSON object", Index);
75 const json::Object *FirstObj = Pair->getObject(
"first");
77 return createStringError(
78 inconvertibleErrorCode(),
79 "missing or invalid 'first' field at index '%zu'", Index);
81 const json::Object *SecondObj = Pair->getObject(
"second");
83 return createStringError(
84 inconvertibleErrorCode(),
85 "missing or invalid 'second' field at index '%zu'", Index);
87 auto ExpectedFirst = FromJSON(*FirstObj);
89 return createStringError(inconvertibleErrorCode(),
90 "invalid 'first' entity id at index '%zu': %s",
92 toString(ExpectedFirst.takeError()).c_str());
94 auto ExpectedSecond = FromJSON(*SecondObj);
95 if (!ExpectedSecond) {
96 return createStringError(inconvertibleErrorCode(),
97 "invalid 'second' entity id at index '%zu': %s",
99 toString(ExpectedSecond.takeError()).c_str());
101 Result->Pairs.emplace_back(*ExpectedFirst, *ExpectedSecond);
103 return std::move(Result);
107 PairsEntitySummaryFormatInfo()
108 : JSONFormat::FormatInfo(SummaryName(
"PairsEntitySummary"),
109 serializePairsEntitySummary,
110 deserializePairsEntitySummary) {}
113llvm::Registry<JSONFormat::FormatInfo>::Add<PairsEntitySummaryFormatInfo>
114 RegisterPairsEntitySummaryForJSON(
115 "PairsEntitySummary",
"JSON format info for PairsEntitySummary");
127 for (
const auto &[EI, Count] :
R.PairCounts) {
128 Arr.push_back(json::Object{{
"entity_id", ToJSON(EI)}, {
"count", Count}});
130 return json::Object{{
"pair_counts", std::move(Arr)}};
134deserializePairsAnalysisResult(
const json::Object &Obj,
136 const json::Array *Arr = Obj.getArray(
"pair_counts");
138 return createStringError(inconvertibleErrorCode(),
139 "missing or invalid field 'pair_counts'");
142 auto R = std::make_unique<PairsAnalysisResult>();
143 for (
const auto &[Index, Val] : llvm::enumerate(*Arr)) {
144 const json::Object *Entry = Val.getAsObject();
146 return createStringError(
147 inconvertibleErrorCode(),
148 "pair_counts element at index %zu is not an object", Index);
150 const json::Object *EIObj = Entry->getObject(
"entity_id");
152 return createStringError(
153 inconvertibleErrorCode(),
154 "missing or invalid 'entity_id' field at index %zu", Index);
156 auto ExpectedEI = FromJSON(*EIObj);
158 return ExpectedEI.takeError();
161 auto CountVal = Entry->getInteger(
"count");
163 return createStringError(inconvertibleErrorCode(),
164 "missing or invalid 'count' field at index %zu",
167 R->PairCounts.emplace_back(*ExpectedEI,
static_cast<int>(*CountVal));
172JSONFormat::AnalysisResultRegistry::Add<PairsAnalysisResult>
173 RegisterPairsResultForJSON(serializePairsAnalysisResult,
174 deserializePairsAnalysisResult);
183class PairsAnalysis final
186 using ResultType = PairsAnalysisResult;
188 llvm::Error add(EntityId Id,
const PairsEntitySummary &S)
override {
189 result().PairCounts.emplace_back(Id,
static_cast<int>(S.Pairs.size()));
190 return llvm::Error::success();
195 RegisterPairsAnalysis(
"Counts pairs per entity");
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Manages entity name interning and provides efficient EntityId handles.
Base class for analysis-specific summary data.
Typed intermediate that concrete summary analyses inherit from.
Diagnostic wrappers for TextAPI types for error reporting.
Registers AnalysisT with the unified registry.