clang 23.0.0git
JSONFormatImpl.cpp
Go to the documentation of this file.
1//===- JSONFormatImpl.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
9#include "JSONFormatImpl.h"
10
12#include "llvm/Support/Registry.h"
13#include "llvm/TargetParser/Triple.h"
14
15using namespace clang;
16using namespace ssaf;
17
18LLVM_DEFINE_REGISTRY_EX(CLANG_ABI_EXPORT,
19 llvm::Registry<JSONFormat::FormatInfo>)
21 CLANG_ABI_EXPORT, llvm::Registry<JSONFormat::AnalysisResultRegistry::Codec>)
22
23static SerializationFormatRegistry::Add<JSONFormat>
24 RegisterJSONFormat("json", "JSON serialization format");
25
26namespace clang::ssaf {
27
28// NOLINTNEXTLINE(misc-use-internal-linkage)
29volatile int JSONFormatAnchorSource = 0;
30
31//----------------------------------------------------------------------------
32// JSON Reader and Writer
33//----------------------------------------------------------------------------
34
35llvm::Expected<Value> readJSON(llvm::StringRef Path) {
36 if (!llvm::sys::fs::exists(Path)) {
37 return ErrorBuilder::create(std::errc::no_such_file_or_directory,
40 .build();
41 }
42
43 if (llvm::sys::fs::is_directory(Path)) {
44 return ErrorBuilder::create(std::errc::is_a_directory,
47 .build();
48 }
49
50 if (!Path.ends_with(JSONFormatFileExtension)) {
51 return ErrorBuilder::create(std::errc::invalid_argument,
53 llvm::formatv(ErrorMessages::FileIsNotJSON,
55 .build();
56 }
57
58 auto BufferOrError = llvm::MemoryBuffer::getFile(Path);
59 if (!BufferOrError) {
60 const std::error_code EC = BufferOrError.getError();
62 EC.message())
63 .build();
64 }
65
66 return llvm::json::parse(BufferOrError.get()->getBuffer());
67}
68
69llvm::Error writeJSON(Value &&V, llvm::StringRef Path) {
70 if (llvm::sys::fs::exists(Path)) {
71 return ErrorBuilder::create(std::errc::file_exists,
74 .build();
75 }
76
77 llvm::StringRef Dir = llvm::sys::path::parent_path(Path);
78 if (!Dir.empty() && !llvm::sys::fs::is_directory(Dir)) {
79 return ErrorBuilder::create(std::errc::no_such_file_or_directory,
82 .build();
83 }
84
85 if (!Path.ends_with(JSONFormatFileExtension)) {
86 return ErrorBuilder::create(std::errc::invalid_argument,
88 llvm::formatv(ErrorMessages::FileIsNotJSON,
90 .build();
91 }
92
93 std::error_code EC;
94 llvm::raw_fd_ostream OutStream(Path, EC, llvm::sys::fs::OF_Text);
95
96 if (EC) {
98 EC.message())
99 .build();
100 }
101
102 OutStream << llvm::formatv("{0:2}\n", V);
103 OutStream.flush();
104
105 // This path handles post-write stream errors (e.g. ENOSPC after buffered
106 // writes). It is difficult to exercise in unit tests so it is intentionally
107 // left without test coverage.
108 if (OutStream.has_error()) {
109 return ErrorBuilder::create(OutStream.error(),
111 OutStream.error().message())
112 .build();
113 }
114
115 return llvm::Error::success();
116}
117
118//----------------------------------------------------------------------------
119// JSONFormat Static Methods
120//----------------------------------------------------------------------------
121
122std::map<SummaryName, JSONFormat::FormatInfo> JSONFormat::initFormatInfos() {
123 std::map<SummaryName, FormatInfo> FormatInfos;
124 for (const auto &FormatInfoEntry : llvm::Registry<FormatInfo>::entries()) {
125 std::unique_ptr<FormatInfo> Info = FormatInfoEntry.instantiate();
126 bool Inserted = FormatInfos.try_emplace(Info->ForSummary, *Info).second;
127 if (!Inserted) {
128 llvm::report_fatal_error(
129 "FormatInfo is already registered for summary: " +
130 Info->ForSummary.str());
131 }
132 }
133 return FormatInfos;
134}
135
137 llvm::function_ref<void(llvm::StringRef, llvm::StringRef)> Callback) const {
138 for (const auto &Entry : llvm::Registry<FormatInfo>::entries())
139 Callback(Entry.getName(), Entry.getDesc());
140}
141
142//----------------------------------------------------------------------------
143// SummaryName
144//----------------------------------------------------------------------------
145
146SummaryName summaryNameFromJSON(llvm::StringRef SummaryNameStr) {
147 return SummaryName(SummaryNameStr.str());
148}
149
150llvm::StringRef summaryNameToJSON(const SummaryName &SN) { return SN.str(); }
151
152//----------------------------------------------------------------------------
153// Summary Type field
154//----------------------------------------------------------------------------
155
157 std::optional<llvm::StringRef> OptType = RootObject.getString(JSONTypeKey);
158 if (!OptType) {
159 return ErrorBuilder::create(std::errc::invalid_argument,
161 "summary type", JSONTypeKey, "string")
162 .build();
163 }
164 return *OptType;
165}
166
167llvm::Error checkSummaryType(const Object &RootObject,
168 llvm::StringRef ExpectedType) {
169 auto ExpectedActual = readSummaryType(RootObject);
170 if (!ExpectedActual) {
171 return ExpectedActual.takeError();
172 }
173 if (*ExpectedActual != ExpectedType) {
174 return ErrorBuilder::create(std::errc::invalid_argument,
176 ExpectedType, JSONTypeKey, *ExpectedActual)
177 .build();
178 }
179 return llvm::Error::success();
180}
181
182//----------------------------------------------------------------------------
183// AnalysisName
184//----------------------------------------------------------------------------
185
186AnalysisName analysisNameFromJSON(llvm::StringRef AnalysisNameStr) {
187 return AnalysisName(AnalysisNameStr.str());
188}
189
190llvm::StringRef analysisNameToJSON(const AnalysisName &AN) { return AN.str(); }
191
192//----------------------------------------------------------------------------
193// EntityId
194//----------------------------------------------------------------------------
195
196EntityId JSONFormat::entityIdFromJSON(const uint64_t EntityIdIndex) const {
197 return makeEntityId(static_cast<size_t>(EntityIdIndex));
198}
199
200uint64_t JSONFormat::entityIdToJSON(EntityId EI) const {
201 return static_cast<uint64_t>(getIndex(EI));
202}
203
204llvm::Expected<EntityId>
205JSONFormat::entityIdFromJSONObject(const Object &EntityIdObject) {
206 if (EntityIdObject.size() != 1) {
207 return ErrorBuilder::create(std::errc::invalid_argument,
210 .build();
211 }
212
213 const llvm::json::Value *AtVal = EntityIdObject.get(JSONEntityIdKey);
214 if (!AtVal) {
215 return ErrorBuilder::create(std::errc::invalid_argument,
218 .build();
219 }
220
221 std::optional<uint64_t> OptEntityIdIndex = AtVal->getAsUINT64();
222 if (!OptEntityIdIndex) {
223 return ErrorBuilder::create(std::errc::invalid_argument,
226 .build();
227 }
228
229 return makeEntityId(static_cast<size_t>(*OptEntityIdIndex));
230}
231
232Object JSONFormat::entityIdToJSONObject(EntityId EI) {
233 Object Result;
234 Result[JSONEntityIdKey] = static_cast<uint64_t>(getIndex(EI));
235 return Result;
236}
237
238//----------------------------------------------------------------------------
239// BuildNamespaceKind
240//----------------------------------------------------------------------------
241
242llvm::Expected<BuildNamespaceKind>
243buildNamespaceKindFromJSON(llvm::StringRef BuildNamespaceKindStr) {
244 auto OptBuildNamespaceKind =
245 buildNamespaceKindFromString(BuildNamespaceKindStr);
246 if (!OptBuildNamespaceKind) {
247 return ErrorBuilder::create(std::errc::invalid_argument,
249 BuildNamespaceKindStr)
250 .build();
251 }
252 return *OptBuildNamespaceKind;
253}
254
255// Provided for consistency with respect to rest of the codebase.
257 return buildNamespaceKindToString(BNK);
258}
259
260//----------------------------------------------------------------------------
261// BuildNamespace
262//----------------------------------------------------------------------------
263
265JSONFormat::buildNamespaceFromJSON(const Object &BuildNamespaceObject) const {
266 auto OptBuildNamespaceKindStr = BuildNamespaceObject.getString("kind");
267 if (!OptBuildNamespaceKindStr) {
268 return ErrorBuilder::create(std::errc::invalid_argument,
270 "BuildNamespaceKind", "kind", "string")
271 .build();
272 }
273
274 auto ExpectedKind = buildNamespaceKindFromJSON(*OptBuildNamespaceKindStr);
275 if (!ExpectedKind) {
276 return ErrorBuilder::wrap(ExpectedKind.takeError())
277 .context(ErrorMessages::ReadingFromField, "BuildNamespaceKind", "kind")
278 .build();
279 }
280
281 auto OptNameStr = BuildNamespaceObject.getString("name");
282 if (!OptNameStr) {
283 return ErrorBuilder::create(std::errc::invalid_argument,
285 "BuildNamespaceName", "name", "string")
286 .build();
287 }
288
289 return {BuildNamespace(*ExpectedKind, *OptNameStr)};
290}
291
292Object JSONFormat::buildNamespaceToJSON(const BuildNamespace &BN) const {
293 Object Result;
295 Result["name"] = getName(BN);
296 return Result;
297}
298
299//----------------------------------------------------------------------------
300// NestedBuildNamespace
301//----------------------------------------------------------------------------
302
303llvm::Expected<NestedBuildNamespace> JSONFormat::nestedBuildNamespaceFromJSON(
304 const Array &NestedBuildNamespaceArray) const {
305 std::vector<BuildNamespace> Namespaces;
306
307 size_t NamespaceCount = NestedBuildNamespaceArray.size();
308 Namespaces.reserve(NamespaceCount);
309
310 for (const auto &[Index, BuildNamespaceValue] :
311 llvm::enumerate(NestedBuildNamespaceArray)) {
312 const Object *BuildNamespaceObject = BuildNamespaceValue.getAsObject();
313 if (!BuildNamespaceObject) {
314 return ErrorBuilder::create(std::errc::invalid_argument,
316 "BuildNamespace", Index, "object")
317 .build();
318 }
319
320 auto ExpectedBuildNamespace = buildNamespaceFromJSON(*BuildNamespaceObject);
321 if (!ExpectedBuildNamespace) {
322 return ErrorBuilder::wrap(ExpectedBuildNamespace.takeError())
323 .context(ErrorMessages::ReadingFromIndex, "BuildNamespace", Index)
324 .build();
325 }
326
327 Namespaces.push_back(std::move(*ExpectedBuildNamespace));
328 }
329
330 return NestedBuildNamespace(std::move(Namespaces));
331}
332
333Array JSONFormat::nestedBuildNamespaceToJSON(
334 const NestedBuildNamespace &NBN) const {
335 Array Result;
336 const auto &Namespaces = getNamespaces(NBN);
337 Result.reserve(Namespaces.size());
338
339 for (const auto &BN : Namespaces) {
340 Result.push_back(buildNamespaceToJSON(BN));
341 }
342
343 return Result;
344}
345
346//----------------------------------------------------------------------------
347// EntityName
348//----------------------------------------------------------------------------
349
350/// Reads "usr" and "suffix" fields from an EntityName JSON object.
351/// Shared core logic for both TU and LU entity name deserialization.
352static llvm::Expected<std::pair<llvm::StringRef, llvm::StringRef>>
353entityNameCoreFromJSON(const Object &EntityNameObject) {
354 const auto OptUSR = EntityNameObject.getString("usr");
355 if (!OptUSR) {
356 return ErrorBuilder::create(std::errc::invalid_argument,
358 "usr", "string")
359 .build();
360 }
361
362 const auto OptSuffix = EntityNameObject.getString("suffix");
363 if (!OptSuffix) {
364 return ErrorBuilder::create(std::errc::invalid_argument,
366 "Suffix", "suffix", "string")
367 .build();
368 }
369
370 return std::make_pair(*OptUSR, *OptSuffix);
371}
372
374JSONFormat::tuEntityNameFromJSON(const Object &EntityNameObject) const {
375 auto ExpectedCore = entityNameCoreFromJSON(EntityNameObject);
376 if (!ExpectedCore)
377 return ExpectedCore.takeError();
378
379 auto [USR, Suffix] = *ExpectedCore;
380 return EntityName{USR, Suffix, NestedBuildNamespace()};
381}
382
383Object JSONFormat::tuEntityNameToJSON(const EntityName &EN) const {
384 Object Result;
385 Result["usr"] = getUSR(EN);
386 Result["suffix"] = getSuffix(EN);
387 return Result;
388}
389
390llvm::Expected<EntityName>
391JSONFormat::luEntityNameFromJSON(const Object &EntityNameObject) const {
392 auto ExpectedCore = entityNameCoreFromJSON(EntityNameObject);
393 if (!ExpectedCore)
394 return ExpectedCore.takeError();
395
396 auto [USR, Suffix] = *ExpectedCore;
397
398 const Array *OptNamespaceArray = EntityNameObject.getArray("namespace");
399 if (!OptNamespaceArray) {
400 return ErrorBuilder::create(std::errc::invalid_argument,
402 "NestedBuildNamespace", "namespace", "array")
403 .build();
404 }
405
406 auto ExpectedNamespace = nestedBuildNamespaceFromJSON(*OptNamespaceArray);
407 if (!ExpectedNamespace) {
408 return ErrorBuilder::wrap(ExpectedNamespace.takeError())
409 .context(ErrorMessages::ReadingFromField, "NestedBuildNamespace",
410 "namespace")
411 .build();
412 }
413
414 return EntityName{USR, Suffix, std::move(*ExpectedNamespace)};
415}
416
417Object JSONFormat::luEntityNameToJSON(const EntityName &EN) const {
418 Object Result;
419 Result["usr"] = getUSR(EN);
420 Result["suffix"] = getSuffix(EN);
421 Result["namespace"] = nestedBuildNamespaceToJSON(getNamespace(EN));
422 return Result;
423}
424
425//----------------------------------------------------------------------------
426// EntityLinkageType
427//----------------------------------------------------------------------------
428
429llvm::Expected<EntityLinkageType>
430entityLinkageTypeFromJSON(llvm::StringRef EntityLinkageTypeStr) {
431 auto OptEntityLinkageType = entityLinkageTypeFromString(EntityLinkageTypeStr);
432 if (!OptEntityLinkageType) {
433 return ErrorBuilder::create(std::errc::invalid_argument,
435 EntityLinkageTypeStr)
436 .build();
437 }
438 return *OptEntityLinkageType;
439}
440
441// Provided for consistency with respect to rest of the codebase.
443 return entityLinkageTypeToString(LT);
444}
445
446//----------------------------------------------------------------------------
447// TargetTriple
448//----------------------------------------------------------------------------
449
450llvm::Error validateNormalizedTargetTriple(llvm::StringRef Triple) {
451 std::string Normalized = llvm::Triple::normalize(Triple);
452 if (Normalized != Triple) {
453 return ErrorBuilder::create(std::errc::invalid_argument,
455 Triple, Normalized)
456 .build();
457 }
458 return llvm::Error::success();
459}
460
461//----------------------------------------------------------------------------
462// EntityLinkage
463//----------------------------------------------------------------------------
464
466JSONFormat::entityLinkageFromJSON(const Object &EntityLinkageObject) const {
467 auto OptLinkageStr = EntityLinkageObject.getString("type");
468 if (!OptLinkageStr) {
469 return ErrorBuilder::create(std::errc::invalid_argument,
471 "EntityLinkageType", "type", "string")
472 .build();
473 }
474
475 auto ExpectedLinkageType = entityLinkageTypeFromJSON(*OptLinkageStr);
476 if (!ExpectedLinkageType) {
477 return ErrorBuilder::wrap(ExpectedLinkageType.takeError())
478 .context(ErrorMessages::ReadingFromField, "EntityLinkageType", "type")
479 .build();
480 }
481
482 return EntityLinkage(*ExpectedLinkageType);
483}
484
485Object JSONFormat::entityLinkageToJSON(const EntityLinkage &EL) const {
486 Object Result;
487 Result["type"] = entityLinkageTypeToJSON(getLinkage(EL));
488 return Result;
489}
490
491//----------------------------------------------------------------------------
492// EntityIdTableEntry
493//----------------------------------------------------------------------------
494
495/// Shared logic for reading the "id" field from an EntityIdTableEntry object.
496static llvm::Expected<EntityId>
497entityIdTableEntryIdFromJSON(const Object &EntityIdTableEntryObject,
498 llvm::function_ref<EntityId(uint64_t)> MakeId) {
499 const Value *EntityIdIntValue = EntityIdTableEntryObject.get("id");
500 if (!EntityIdIntValue) {
501 return ErrorBuilder::create(std::errc::invalid_argument,
503 "EntityId", "id",
504 "number (unsigned 64-bit integer)")
505 .build();
506 }
507
508 const std::optional<uint64_t> OptEntityIdInt =
509 EntityIdIntValue->getAsUINT64();
510 if (!OptEntityIdInt) {
511 return ErrorBuilder::create(std::errc::invalid_argument,
513 "EntityId", "id",
514 "number (unsigned 64-bit integer)")
515 .build();
516 }
517
518 return MakeId(*OptEntityIdInt);
519}
520
522JSONFormat::tuEntityIdTableEntryFromJSON(
523 const Object &EntityIdTableEntryObject) const {
524
525 const Object *OptEntityNameObject =
526 EntityIdTableEntryObject.getObject("name");
527 if (!OptEntityNameObject) {
528 return ErrorBuilder::create(std::errc::invalid_argument,
530 "EntityName", "name", "object")
531 .build();
532 }
533
534 auto ExpectedEntityName = tuEntityNameFromJSON(*OptEntityNameObject);
535 if (!ExpectedEntityName) {
536 return ErrorBuilder::wrap(ExpectedEntityName.takeError())
537 .context(ErrorMessages::ReadingFromField, "EntityName", "name")
538 .build();
539 }
540
541 auto ExpectedId = entityIdTableEntryIdFromJSON(
542 EntityIdTableEntryObject,
543 [this](uint64_t V) { return entityIdFromJSON(V); });
544 if (!ExpectedId)
545 return ExpectedId.takeError();
546
547 return std::make_pair(std::move(*ExpectedEntityName), std::move(*ExpectedId));
548}
549
550Object JSONFormat::tuEntityIdTableEntryToJSON(const EntityName &EN,
551 EntityId EI) const {
552 Object Entry;
553 Entry["id"] = entityIdToJSON(EI);
554 Entry["name"] = tuEntityNameToJSON(EN);
555 return Entry;
556}
557
558llvm::Expected<std::pair<EntityName, EntityId>>
559JSONFormat::luEntityIdTableEntryFromJSON(
560 const Object &EntityIdTableEntryObject) const {
561
562 const Object *OptEntityNameObject =
563 EntityIdTableEntryObject.getObject("name");
564 if (!OptEntityNameObject) {
565 return ErrorBuilder::create(std::errc::invalid_argument,
567 "EntityName", "name", "object")
568 .build();
569 }
570
571 auto ExpectedEntityName = luEntityNameFromJSON(*OptEntityNameObject);
572 if (!ExpectedEntityName) {
573 return ErrorBuilder::wrap(ExpectedEntityName.takeError())
574 .context(ErrorMessages::ReadingFromField, "EntityName", "name")
575 .build();
576 }
577
578 auto ExpectedId = entityIdTableEntryIdFromJSON(
579 EntityIdTableEntryObject,
580 [this](uint64_t V) { return entityIdFromJSON(V); });
581 if (!ExpectedId)
582 return ExpectedId.takeError();
583
584 return std::make_pair(std::move(*ExpectedEntityName), std::move(*ExpectedId));
585}
586
587Object JSONFormat::luEntityIdTableEntryToJSON(const EntityName &EN,
588 EntityId EI) const {
589 Object Entry;
590 Entry["id"] = entityIdToJSON(EI);
591 Entry["name"] = luEntityNameToJSON(EN);
592 return Entry;
593}
594
595//----------------------------------------------------------------------------
596// EntityIdTable
597//----------------------------------------------------------------------------
598
599/// Shared logic for deserializing an EntityIdTable from a JSON array.
600/// \p EntryReader is called for each entry object to produce an
601/// (EntityName, EntityId) pair.
603 const Array &EntityIdTableArray,
604 llvm::function_ref<
605 llvm::Expected<std::pair<EntityName, EntityId>>(const Object &)>
606 EntryReader,
607 llvm::function_ref<std::map<EntityName, EntityId> &(EntityIdTable &)>
608 GetEntities) {
609 EntityIdTable IdTable;
610 std::map<EntityName, EntityId> &Entities = GetEntities(IdTable);
611
612 for (const auto &[Index, EntityIdTableEntryValue] :
613 llvm::enumerate(EntityIdTableArray)) {
614 const Object *OptEntityIdTableEntryObject =
615 EntityIdTableEntryValue.getAsObject();
616 if (!OptEntityIdTableEntryObject) {
617 return ErrorBuilder::create(std::errc::invalid_argument,
619 "EntityIdTable entry", Index, "object")
620 .build();
621 }
622
623 auto ExpectedEntityIdTableEntry = EntryReader(*OptEntityIdTableEntryObject);
624 if (!ExpectedEntityIdTableEntry) {
625 return ErrorBuilder::wrap(ExpectedEntityIdTableEntry.takeError())
626 .context(ErrorMessages::ReadingFromIndex, "EntityIdTable entry",
627 Index)
628 .build();
629 }
630
631 auto [EntityIt, EntityInserted] =
632 Entities.emplace(std::move(*ExpectedEntityIdTableEntry));
633 if (!EntityInserted) {
634 return ErrorBuilder::create(std::errc::invalid_argument,
636 "EntityIdTable entry", Index,
637 EntityIt->second)
638 .build();
639 }
640 }
641
642 return IdTable;
643}
644
646JSONFormat::tuEntityIdTableFromJSON(const Array &EntityIdTableArray) const {
648 EntityIdTableArray,
649 [this](const Object &O) { return tuEntityIdTableEntryFromJSON(O); },
650 [](EntityIdTable &T) -> std::map<EntityName, EntityId> & {
651 return getEntities(T);
652 });
653}
654
655Array JSONFormat::tuEntityIdTableToJSON(const EntityIdTable &IdTable) const {
656 Array EntityIdTableArray;
657 const auto &Entities = getEntities(IdTable);
658 EntityIdTableArray.reserve(Entities.size());
659
660 for (const auto &[EntityName, EntityId] : Entities) {
661 EntityIdTableArray.push_back(
662 tuEntityIdTableEntryToJSON(EntityName, EntityId));
663 }
664
665 return EntityIdTableArray;
666}
667
668llvm::Expected<EntityIdTable>
669JSONFormat::luEntityIdTableFromJSON(const Array &EntityIdTableArray) const {
671 EntityIdTableArray,
672 [this](const Object &O) { return luEntityIdTableEntryFromJSON(O); },
673 [](EntityIdTable &T) -> std::map<EntityName, EntityId> & {
674 return getEntities(T);
675 });
676}
677
678Array JSONFormat::luEntityIdTableToJSON(const EntityIdTable &IdTable) const {
679 Array EntityIdTableArray;
680 const auto &Entities = getEntities(IdTable);
681 EntityIdTableArray.reserve(Entities.size());
682
683 for (const auto &[EntityName, EntityId] : Entities) {
684 EntityIdTableArray.push_back(
685 luEntityIdTableEntryToJSON(EntityName, EntityId));
686 }
687
688 return EntityIdTableArray;
689}
690
691//----------------------------------------------------------------------------
692// LinkageTableEntry
693//----------------------------------------------------------------------------
694
695llvm::Expected<std::pair<EntityId, EntityLinkage>>
696JSONFormat::linkageTableEntryFromJSON(
697 const Object &LinkageTableEntryObject) const {
698 const Value *EntityIdIntValue = LinkageTableEntryObject.get("id");
699 if (!EntityIdIntValue) {
700 return ErrorBuilder::create(std::errc::invalid_argument,
702 "EntityId", "id",
703 "number (unsigned 64-bit integer)")
704 .build();
705 }
706
707 const std::optional<uint64_t> OptEntityIdInt =
708 EntityIdIntValue->getAsUINT64();
709 if (!OptEntityIdInt) {
710 return ErrorBuilder::create(std::errc::invalid_argument,
712 "EntityId", "id",
713 "number (unsigned 64-bit integer)")
714 .build();
715 }
716
717 EntityId EI = entityIdFromJSON(*OptEntityIdInt);
718
719 const Object *OptEntityLinkageObject =
720 LinkageTableEntryObject.getObject("linkage");
721 if (!OptEntityLinkageObject) {
722 return ErrorBuilder::create(std::errc::invalid_argument,
724 "EntityLinkage", "linkage", "object")
725 .build();
726 }
727
728 auto ExpectedEntityLinkage = entityLinkageFromJSON(*OptEntityLinkageObject);
729 if (!ExpectedEntityLinkage) {
730 return ErrorBuilder::wrap(ExpectedEntityLinkage.takeError())
731 .context(ErrorMessages::ReadingFromField, "EntityLinkage", "linkage")
732 .build();
733 }
734
735 return std::make_pair(std::move(EI), std::move(*ExpectedEntityLinkage));
736}
737
738Object JSONFormat::linkageTableEntryToJSON(EntityId EI,
739 const EntityLinkage &EL) const {
740 Object Entry;
741 Entry["id"] = entityIdToJSON(EI);
742 Entry["linkage"] = entityLinkageToJSON(EL);
743 return Entry;
744}
745
746//----------------------------------------------------------------------------
747// LinkageTable
748//----------------------------------------------------------------------------
749
750// ExpectedIds is the set of EntityIds from the IdTable that must appear in the
751// linkage table—no more, no fewer. It is taken by value because it is consumed
752// during parsing: each successfully matched id is erased from the set, and any
753// ids remaining at the end are reported as missing.
754llvm::Expected<std::map<EntityId, EntityLinkage>>
755JSONFormat::linkageTableFromJSON(const Array &LinkageTableArray,
756 std::set<EntityId> ExpectedIds) const {
757 std::map<EntityId, EntityLinkage> LinkageTable;
758
759 for (const auto &[Index, LinkageTableEntryValue] :
760 llvm::enumerate(LinkageTableArray)) {
761 const Object *OptLinkageTableEntryObject =
762 LinkageTableEntryValue.getAsObject();
763 if (!OptLinkageTableEntryObject) {
764 return ErrorBuilder::create(std::errc::invalid_argument,
766 "LinkageTable entry", Index, "object")
767 .build();
768 }
769
770 auto ExpectedLinkageTableEntry =
771 linkageTableEntryFromJSON(*OptLinkageTableEntryObject);
772 if (!ExpectedLinkageTableEntry) {
773 return ErrorBuilder::wrap(ExpectedLinkageTableEntry.takeError())
774 .context(ErrorMessages::ReadingFromIndex, "LinkageTable entry", Index)
775 .build();
776 }
777
778 const EntityId EI = ExpectedLinkageTableEntry->first;
779
780 auto [It, Inserted] =
781 LinkageTable.insert(std::move(*ExpectedLinkageTableEntry));
782 if (!Inserted) {
783 return ErrorBuilder::create(std::errc::invalid_argument,
785 "LinkageTable entry", Index, It->first)
786 .build();
787 }
788
789 if (ExpectedIds.erase(EI) == 0) {
791 std::errc::invalid_argument,
793 .context(ErrorMessages::ReadingFromIndex, "LinkageTable entry", Index)
794 .build();
795 }
796 }
797
798 if (!ExpectedIds.empty()) {
800 std::errc::invalid_argument,
802 *ExpectedIds.begin())
803 .build();
804 }
805
806 return LinkageTable;
807}
808
809Array JSONFormat::linkageTableToJSON(
810 const std::map<EntityId, EntityLinkage> &LinkageTable) const {
811 Array Result;
812 Result.reserve(LinkageTable.size());
813
814 for (const auto &[EI, EL] : LinkageTable) {
815 Result.push_back(linkageTableEntryToJSON(EI, EL));
816 }
817
818 return Result;
819}
820
821//----------------------------------------------------------------------------
822// EntitySummary
823//----------------------------------------------------------------------------
824
825llvm::Expected<std::unique_ptr<EntitySummary>>
826JSONFormat::entitySummaryFromJSON(const SummaryName &SN,
827 const Object &EntitySummaryObject,
828 EntityIdTable &IdTable) const {
829 auto InfoIt = FormatInfos.find(SN);
830 if (InfoIt == FormatInfos.end()) {
832 std::errc::invalid_argument,
834 .build();
835 }
836
837 const auto &InfoEntry = InfoIt->second;
838 assert(InfoEntry.ForSummary == SN);
839
840 return InfoEntry.Deserialize(EntitySummaryObject, IdTable,
841 entityIdFromJSONObject);
842}
843
844llvm::Expected<Object>
845JSONFormat::entitySummaryToJSON(const SummaryName &SN,
846 const EntitySummary &ES) const {
847 auto InfoIt = FormatInfos.find(SN);
848 if (InfoIt == FormatInfos.end()) {
850 std::errc::invalid_argument,
852 .build();
853 }
854
855 const auto &InfoEntry = InfoIt->second;
856 assert(InfoEntry.ForSummary == SN);
857
858 return InfoEntry.Serialize(ES, entityIdToJSONObject);
859}
860
861//----------------------------------------------------------------------------
862// EntityDataMapEntry
863//----------------------------------------------------------------------------
864
865llvm::Expected<std::pair<EntityId, std::unique_ptr<EntitySummary>>>
866JSONFormat::entityDataMapEntryFromJSON(const Object &EntityDataMapEntryObject,
867 const SummaryName &SN,
868 EntityIdTable &IdTable) const {
869
870 const Value *EntityIdIntValue = EntityDataMapEntryObject.get("entity_id");
871 if (!EntityIdIntValue) {
872 return ErrorBuilder::create(std::errc::invalid_argument,
874 "EntityId", "entity_id",
875 "number (unsigned 64-bit integer)")
876 .build();
877 }
878
879 const std::optional<uint64_t> OptEntityIdInt =
880 EntityIdIntValue->getAsUINT64();
881 if (!OptEntityIdInt) {
882 return ErrorBuilder::create(std::errc::invalid_argument,
884 "EntityId", "entity_id",
885 "number (unsigned 64-bit integer)")
886 .build();
887 }
888
889 EntityId EI = entityIdFromJSON(*OptEntityIdInt);
890
891 const Object *OptEntitySummaryObject =
892 EntityDataMapEntryObject.getObject("entity_summary");
893 if (!OptEntitySummaryObject) {
894 return ErrorBuilder::create(std::errc::invalid_argument,
896 "EntitySummary", "entity_summary", "object")
897 .build();
898 }
899
900 auto ExpectedEntitySummary =
901 entitySummaryFromJSON(SN, *OptEntitySummaryObject, IdTable);
902 if (!ExpectedEntitySummary) {
903 return ErrorBuilder::wrap(ExpectedEntitySummary.takeError())
905 "entity_summary")
906 .build();
907 }
908
909 if (*ExpectedEntitySummary == nullptr) {
911 std::errc::invalid_argument,
913 .build();
914 }
915
916 auto ActualSN = (*ExpectedEntitySummary)->getSummaryName();
917 if (SN != ActualSN) {
919 std::errc::invalid_argument,
920 ErrorMessages::
921 FailedToDeserializeEntitySummaryMismatchedSummaryName,
922 SN, ActualSN)
923 .build();
924 }
925
926 return std::make_pair(std::move(EI), std::move(*ExpectedEntitySummary));
927}
928
929llvm::Expected<Object> JSONFormat::entityDataMapEntryToJSON(
930 const EntityId EI, const std::unique_ptr<EntitySummary> &EntitySummary,
931 const SummaryName &SN) const {
932 Object Entry;
933
934 Entry["entity_id"] = entityIdToJSON(EI);
935
936 if (!EntitySummary) {
939 }
940
941 const auto ActualSN = EntitySummary->getSummaryName();
942 if (SN != ActualSN) {
945 ActualSN);
946 }
947
948 auto ExpectedEntitySummaryObject = entitySummaryToJSON(SN, *EntitySummary);
949 if (!ExpectedEntitySummaryObject) {
950 return ErrorBuilder::wrap(ExpectedEntitySummaryObject.takeError())
951 .context(ErrorMessages::WritingToField, "EntitySummary",
952 "entity_summary")
953 .build();
954 }
955
956 Entry["entity_summary"] = std::move(*ExpectedEntitySummaryObject);
957
958 return Entry;
959}
960
961//----------------------------------------------------------------------------
962// EntityDataMap
963//----------------------------------------------------------------------------
964
965llvm::Expected<std::map<EntityId, std::unique_ptr<EntitySummary>>>
966JSONFormat::entityDataMapFromJSON(const SummaryName &SN,
967 const Array &EntityDataArray,
968 EntityIdTable &IdTable) const {
969 std::map<EntityId, std::unique_ptr<EntitySummary>> EntityDataMap;
970
971 for (const auto &[Index, EntityDataMapEntryValue] :
972 llvm::enumerate(EntityDataArray)) {
973 const Object *OptEntityDataMapEntryObject =
974 EntityDataMapEntryValue.getAsObject();
975 if (!OptEntityDataMapEntryObject) {
976 return ErrorBuilder::create(std::errc::invalid_argument,
978 "EntitySummary entry", Index, "object")
979 .build();
980 }
981
982 auto ExpectedEntityDataMapEntry =
983 entityDataMapEntryFromJSON(*OptEntityDataMapEntryObject, SN, IdTable);
984 if (!ExpectedEntityDataMapEntry) {
985 return ErrorBuilder::wrap(ExpectedEntityDataMapEntry.takeError())
986 .context(ErrorMessages::ReadingFromIndex, "EntitySummary entry",
987 Index)
988 .build();
989 }
990
991 auto [DataIt, DataInserted] =
992 EntityDataMap.insert(std::move(*ExpectedEntityDataMapEntry));
993 if (!DataInserted) {
994 return ErrorBuilder::create(std::errc::invalid_argument,
996 "EntitySummary entry", Index, DataIt->first)
997 .build();
998 }
999 }
1000
1001 return std::move(EntityDataMap);
1002}
1003
1004llvm::Expected<Array> JSONFormat::entityDataMapToJSON(
1005 const SummaryName &SN,
1006 const std::map<EntityId, std::unique_ptr<EntitySummary>> &EntityDataMap)
1007 const {
1008 Array Result;
1009 Result.reserve(EntityDataMap.size());
1010
1011 for (const auto &[Index, EntityDataMapEntry] :
1012 llvm::enumerate(EntityDataMap)) {
1013 const auto &[EntityId, EntitySummary] = EntityDataMapEntry;
1014
1015 auto ExpectedEntityDataMapEntryObject =
1016 entityDataMapEntryToJSON(EntityId, EntitySummary, SN);
1017
1018 if (!ExpectedEntityDataMapEntryObject) {
1019 return ErrorBuilder::wrap(ExpectedEntityDataMapEntryObject.takeError())
1020 .context(ErrorMessages::WritingToIndex, "EntitySummary entry", Index)
1021 .build();
1022 }
1023
1024 Result.push_back(std::move(*ExpectedEntityDataMapEntryObject));
1025 }
1026
1027 return Result;
1028}
1029
1030//----------------------------------------------------------------------------
1031// SummaryDataMapEntry
1032//----------------------------------------------------------------------------
1033
1034llvm::Expected<
1035 std::pair<SummaryName, std::map<EntityId, std::unique_ptr<EntitySummary>>>>
1036JSONFormat::summaryDataMapEntryFromJSON(const Object &SummaryDataMapEntryObject,
1037 EntityIdTable &IdTable) const {
1038
1039 std::optional<llvm::StringRef> OptSummaryNameStr =
1040 SummaryDataMapEntryObject.getString("summary_name");
1041 if (!OptSummaryNameStr) {
1042 return ErrorBuilder::create(std::errc::invalid_argument,
1044 "SummaryName", "summary_name", "string")
1045 .build();
1046 }
1047
1048 SummaryName SN = summaryNameFromJSON(*OptSummaryNameStr);
1049
1050 const Array *OptEntityDataArray =
1051 SummaryDataMapEntryObject.getArray("summary_data");
1052 if (!OptEntityDataArray) {
1053 return ErrorBuilder::create(std::errc::invalid_argument,
1055 "EntitySummary entries", "summary_data",
1056 "array")
1057 .build();
1058 }
1059
1060 auto ExpectedEntityDataMap =
1061 entityDataMapFromJSON(SN, *OptEntityDataArray, IdTable);
1062 if (!ExpectedEntityDataMap) {
1063 return ErrorBuilder::wrap(ExpectedEntityDataMap.takeError())
1064 .context(ErrorMessages::ReadingFromField, "EntitySummary entries",
1065 "summary_data")
1066 .build();
1067 }
1068
1069 return std::make_pair(std::move(SN), std::move(*ExpectedEntityDataMap));
1070}
1071
1072llvm::Expected<Object> JSONFormat::summaryDataMapEntryToJSON(
1073 const SummaryName &SN,
1074 const std::map<EntityId, std::unique_ptr<EntitySummary>> &SD) const {
1075 Object Result;
1076
1077 Result["summary_name"] = summaryNameToJSON(SN);
1078
1079 auto ExpectedSummaryDataArray = entityDataMapToJSON(SN, SD);
1080 if (!ExpectedSummaryDataArray) {
1081 return ErrorBuilder::wrap(ExpectedSummaryDataArray.takeError())
1082 .context(ErrorMessages::WritingToField, "EntitySummary entries",
1083 "summary_data")
1084 .build();
1085 }
1086
1087 Result["summary_data"] = std::move(*ExpectedSummaryDataArray);
1088
1089 return Result;
1090}
1091
1092//----------------------------------------------------------------------------
1093// SummaryDataMap
1094//----------------------------------------------------------------------------
1095
1096llvm::Expected<
1097 std::map<SummaryName, std::map<EntityId, std::unique_ptr<EntitySummary>>>>
1098JSONFormat::summaryDataMapFromJSON(const Array &SummaryDataArray,
1099 EntityIdTable &IdTable) const {
1100 std::map<SummaryName, std::map<EntityId, std::unique_ptr<EntitySummary>>>
1101 SummaryDataMap;
1102
1103 for (const auto &[Index, SummaryDataMapEntryValue] :
1104 llvm::enumerate(SummaryDataArray)) {
1105 const Object *OptSummaryDataMapEntryObject =
1106 SummaryDataMapEntryValue.getAsObject();
1107 if (!OptSummaryDataMapEntryObject) {
1108 return ErrorBuilder::create(std::errc::invalid_argument,
1110 "SummaryData entry", Index, "object")
1111 .build();
1112 }
1113
1114 auto ExpectedSummaryDataMapEntry =
1115 summaryDataMapEntryFromJSON(*OptSummaryDataMapEntryObject, IdTable);
1116 if (!ExpectedSummaryDataMapEntry) {
1117 return ErrorBuilder::wrap(ExpectedSummaryDataMapEntry.takeError())
1118 .context(ErrorMessages::ReadingFromIndex, "SummaryData entry", Index)
1119 .build();
1120 }
1121
1122 auto [SummaryIt, SummaryInserted] =
1123 SummaryDataMap.emplace(std::move(*ExpectedSummaryDataMapEntry));
1124 if (!SummaryInserted) {
1125 return ErrorBuilder::create(std::errc::invalid_argument,
1127 "SummaryData entry", Index, SummaryIt->first)
1128 .build();
1129 }
1130 }
1131
1132 return std::move(SummaryDataMap);
1133}
1134
1135llvm::Expected<Array> JSONFormat::summaryDataMapToJSON(
1136 const std::map<SummaryName,
1137 std::map<EntityId, std::unique_ptr<EntitySummary>>>
1138 &SummaryDataMap) const {
1139 Array Result;
1140 Result.reserve(SummaryDataMap.size());
1141
1142 for (const auto &[Index, SummaryDataMapEntry] :
1143 llvm::enumerate(SummaryDataMap)) {
1144 const auto &[SummaryName, DataMap] = SummaryDataMapEntry;
1145
1146 auto ExpectedSummaryDataMapObject =
1147 summaryDataMapEntryToJSON(SummaryName, DataMap);
1148 if (!ExpectedSummaryDataMapObject) {
1149 return ErrorBuilder::wrap(ExpectedSummaryDataMapObject.takeError())
1150 .context(ErrorMessages::WritingToIndex, "SummaryData entry", Index)
1151 .build();
1152 }
1153
1154 Result.push_back(std::move(*ExpectedSummaryDataMapObject));
1155 }
1156
1157 return std::move(Result);
1158}
1159
1160//----------------------------------------------------------------------------
1161// EncodingDataMapEntry
1162//----------------------------------------------------------------------------
1163
1164llvm::Expected<std::pair<EntityId, std::unique_ptr<EntitySummaryEncoding>>>
1165JSONFormat::encodingDataMapEntryFromJSON(
1166 const Object &EntityDataMapEntryObject) const {
1167 const Value *EntityIdIntValue = EntityDataMapEntryObject.get("entity_id");
1168 if (!EntityIdIntValue) {
1169 return ErrorBuilder::create(std::errc::invalid_argument,
1171 "EntityId", "entity_id",
1172 "number (unsigned 64-bit integer)")
1173 .build();
1174 }
1175
1176 const std::optional<uint64_t> OptEntityIdInt =
1177 EntityIdIntValue->getAsUINT64();
1178 if (!OptEntityIdInt) {
1179 return ErrorBuilder::create(std::errc::invalid_argument,
1181 "EntityId", "entity_id",
1182 "number (unsigned 64-bit integer)")
1183 .build();
1184 }
1185
1186 EntityId EI = entityIdFromJSON(*OptEntityIdInt);
1187
1188 const Object *OptEntitySummaryObject =
1189 EntityDataMapEntryObject.getObject("entity_summary");
1190 if (!OptEntitySummaryObject) {
1191 return ErrorBuilder::create(std::errc::invalid_argument,
1193 "EntitySummary", "entity_summary", "object")
1194 .build();
1195 }
1196
1197 std::unique_ptr<EntitySummaryEncoding> Encoding(
1198 new JSONEntitySummaryEncoding(Value(Object(*OptEntitySummaryObject))));
1199
1200 return std::make_pair(std::move(EI), std::move(Encoding));
1201}
1202
1203Object JSONFormat::encodingDataMapEntryToJSON(
1204 EntityId EI, const std::unique_ptr<EntitySummaryEncoding> &Encoding) const {
1205 Object Entry;
1206 Entry["entity_id"] = entityIdToJSON(EI);
1207
1208 // All EntitySummaryEncoding objects stored in a TUSummaryEncoding or
1209 // LUSummaryEncoding read by JSONFormat are JSONEntitySummaryEncoding
1210 // instances, since encodingDataMapEntryFromJSON is the only place that
1211 // creates them.
1212 auto *JSONEncoding = static_cast<JSONEntitySummaryEncoding *>(Encoding.get());
1213 Entry["entity_summary"] = JSONEncoding->Data;
1214
1215 return Entry;
1216}
1217
1218//----------------------------------------------------------------------------
1219// EncodingDataMap
1220//----------------------------------------------------------------------------
1221
1222llvm::Expected<std::map<EntityId, std::unique_ptr<EntitySummaryEncoding>>>
1223JSONFormat::encodingDataMapFromJSON(const Array &EntityDataArray) const {
1224 std::map<EntityId, std::unique_ptr<EntitySummaryEncoding>> EncodingDataMap;
1225
1226 for (const auto &[Index, EntityDataMapEntryValue] :
1227 llvm::enumerate(EntityDataArray)) {
1228 const Object *OptEntityDataMapEntryObject =
1229 EntityDataMapEntryValue.getAsObject();
1230 if (!OptEntityDataMapEntryObject) {
1231 return ErrorBuilder::create(std::errc::invalid_argument,
1233 "EntitySummary entry", Index, "object")
1234 .build();
1235 }
1236
1237 auto ExpectedEntry =
1238 encodingDataMapEntryFromJSON(*OptEntityDataMapEntryObject);
1239 if (!ExpectedEntry) {
1240 return ErrorBuilder::wrap(ExpectedEntry.takeError())
1241 .context(ErrorMessages::ReadingFromIndex, "EntitySummary entry",
1242 Index)
1243 .build();
1244 }
1245
1246 auto [DataIt, DataInserted] =
1247 EncodingDataMap.insert(std::move(*ExpectedEntry));
1248 if (!DataInserted) {
1249 return ErrorBuilder::create(std::errc::invalid_argument,
1251 "EntitySummary entry", Index, DataIt->first)
1252 .build();
1253 }
1254 }
1255
1256 return std::move(EncodingDataMap);
1257}
1258
1259Array JSONFormat::encodingDataMapToJSON(
1260 const std::map<EntityId, std::unique_ptr<EntitySummaryEncoding>>
1261 &EncodingDataMap) const {
1262 Array Result;
1263 Result.reserve(EncodingDataMap.size());
1264
1265 for (const auto &[EI, Encoding] : EncodingDataMap) {
1266 Result.push_back(encodingDataMapEntryToJSON(EI, Encoding));
1267 }
1268
1269 return Result;
1270}
1271
1272//----------------------------------------------------------------------------
1273// EncodingSummaryDataMapEntry
1274//----------------------------------------------------------------------------
1275
1276llvm::Expected<std::pair<
1277 SummaryName, std::map<EntityId, std::unique_ptr<EntitySummaryEncoding>>>>
1278JSONFormat::encodingSummaryDataMapEntryFromJSON(
1279 const Object &SummaryDataMapEntryObject) const {
1280 std::optional<llvm::StringRef> OptSummaryNameStr =
1281 SummaryDataMapEntryObject.getString("summary_name");
1282 if (!OptSummaryNameStr) {
1283 return ErrorBuilder::create(std::errc::invalid_argument,
1285 "SummaryName", "summary_name", "string")
1286 .build();
1287 }
1288
1289 SummaryName SN = summaryNameFromJSON(*OptSummaryNameStr);
1290
1291 const Array *OptEntityDataArray =
1292 SummaryDataMapEntryObject.getArray("summary_data");
1293 if (!OptEntityDataArray) {
1294 return ErrorBuilder::create(std::errc::invalid_argument,
1296 "EntitySummary entries", "summary_data",
1297 "array")
1298 .build();
1299 }
1300
1301 auto ExpectedEncodingDataMap = encodingDataMapFromJSON(*OptEntityDataArray);
1302 if (!ExpectedEncodingDataMap) {
1303 return ErrorBuilder::wrap(ExpectedEncodingDataMap.takeError())
1304 .context(ErrorMessages::ReadingFromField, "EntitySummary entries",
1305 "summary_data")
1306 .build();
1307 }
1308
1309 return std::make_pair(std::move(SN), std::move(*ExpectedEncodingDataMap));
1310}
1311
1312Object JSONFormat::encodingSummaryDataMapEntryToJSON(
1313 const SummaryName &SN,
1314 const std::map<EntityId, std::unique_ptr<EntitySummaryEncoding>>
1315 &EncodingMap) const {
1316 Object Result;
1317
1318 Result["summary_name"] = summaryNameToJSON(SN);
1319 Result["summary_data"] = encodingDataMapToJSON(EncodingMap);
1320
1321 return Result;
1322}
1323
1324//----------------------------------------------------------------------------
1325// EncodingSummaryDataMap
1326//----------------------------------------------------------------------------
1327
1328llvm::Expected<std::map<
1329 SummaryName, std::map<EntityId, std::unique_ptr<EntitySummaryEncoding>>>>
1330JSONFormat::encodingSummaryDataMapFromJSON(
1331 const Array &SummaryDataArray) const {
1332 std::map<SummaryName,
1333 std::map<EntityId, std::unique_ptr<EntitySummaryEncoding>>>
1334 EncodingSummaryDataMap;
1335
1336 for (const auto &[Index, SummaryDataMapEntryValue] :
1337 llvm::enumerate(SummaryDataArray)) {
1338 const Object *OptSummaryDataMapEntryObject =
1339 SummaryDataMapEntryValue.getAsObject();
1340 if (!OptSummaryDataMapEntryObject) {
1341 return ErrorBuilder::create(std::errc::invalid_argument,
1343 "SummaryData entry", Index, "object")
1344 .build();
1345 }
1346
1347 auto ExpectedEntry =
1348 encodingSummaryDataMapEntryFromJSON(*OptSummaryDataMapEntryObject);
1349 if (!ExpectedEntry) {
1350 return ErrorBuilder::wrap(ExpectedEntry.takeError())
1351 .context(ErrorMessages::ReadingFromIndex, "SummaryData entry", Index)
1352 .build();
1353 }
1354
1355 auto [SummaryIt, SummaryInserted] =
1356 EncodingSummaryDataMap.emplace(std::move(*ExpectedEntry));
1357 if (!SummaryInserted) {
1358 return ErrorBuilder::create(std::errc::invalid_argument,
1360 "SummaryData entry", Index, SummaryIt->first)
1361 .build();
1362 }
1363 }
1364
1365 return std::move(EncodingSummaryDataMap);
1366}
1367
1368Array JSONFormat::encodingSummaryDataMapToJSON(
1369 const std::map<SummaryName,
1370 std::map<EntityId, std::unique_ptr<EntitySummaryEncoding>>>
1371 &EncodingSummaryDataMap) const {
1372 Array Result;
1373 Result.reserve(EncodingSummaryDataMap.size());
1374
1375 for (const auto &[SN, EncodingMap] : EncodingSummaryDataMap) {
1376 Result.push_back(encodingSummaryDataMapEntryToJSON(SN, EncodingMap));
1377 }
1378
1379 return Result;
1380}
1381
1382} // namespace clang::ssaf
#define V(N, I)
static std::optional< NonLoc > getIndex(ProgramStateRef State, const ElementRegion *ER, CharKind CK)
static Decl::Kind getKind(const Decl *D)
static std::string getUSR(const Decl *D)
static llvm::Registry< JSONFormat::AnalysisResultRegistry::Codec > SerializationFormatRegistry::Add< JSONFormat > RegisterJSONFormat("json", "JSON serialization format")
LLVM_DEFINE_REGISTRY_EX(CLANG_ABI_EXPORT, llvm::Registry< JSONFormat::FormatInfo >) LLVM_DEFINE_REGISTRY_EX(CLANG_ABI_EXPORT
llvm::json::Object Object
Uniquely identifies a whole-program analysis and the AnalysisResult it produces.
llvm::StringRef str() const
Explicit conversion to the underlying string representation.
Represents a single namespace in the build process.
Manages entity name interning and provides efficient EntityId handles.
Lightweight opaque handle representing an entity in an EntityIdTable.
Definition EntityId.h:31
Represents the linkage properties of an entity in the program model.
Uniquely identifies an entity in a program.
Definition EntityName.h:28
Base class for analysis-specific summary data.
static ErrorBuilder create(std::error_code EC, const char *Fmt, Args &&...ArgVals)
Create an ErrorBuilder with an error code and formatted message.
static void fatal(const char *Fmt, Args &&...ArgVals)
Report a fatal error with formatted message and terminate execution.
ErrorBuilder & context(const char *Msg)
Add context information as a plain string.
llvm::Error build() const
Build and return the final error.
static ErrorBuilder wrap(llvm::Error E)
Wrap an existing error and optionally add context.
friend class JSONEntitySummaryEncoding
Definition JSONFormat.h:36
void forEachRegisteredAnalysis(llvm::function_ref< void(llvm::StringRef Name, llvm::StringRef Desc)> Callback) const override
Invokes Callback once for each analysis that has registered serialization support for this format.
Represents a hierarchical sequence of build namespaces.
static EntityId makeEntityId(const size_t Index)
Uniquely identifies an analysis summary.
Definition SummaryName.h:22
llvm::StringRef str() const
Explicit conversion to the underlying string representation.
Definition SummaryName.h:31
StringRef getName(const HeaderType T)
Definition HeaderFile.h:38
constexpr const char * FailedToSerializeEntitySummaryMismatchedSummaryName
constexpr const char * InvalidBuildNamespaceKind
constexpr const char * ReadingFromField
constexpr const char * MismatchedSummaryType
constexpr const char * FailedToReadObjectAtIndex
constexpr const char * FailedToDeserializeEntitySummaryNoFormatInfo
constexpr const char * InvalidEntityLinkageType
constexpr const char * FileIsDirectory
constexpr const char * FileNotFound
constexpr const char * FailedToReadObjectAtField
constexpr const char * FileExists
constexpr const char * FailedToReadEntityIdObject
constexpr const char * ReadingFromIndex
constexpr const char * WritingToField
constexpr const char * TargetTripleNotNormalized
constexpr const char * FailedInsertionOnDuplication
constexpr const char * FailedToDeserializeLinkageTableExtraId
constexpr const char * FailedToSerializeEntitySummaryMissingData
constexpr const char * FailedToDeserializeEntitySummaryMissingData
constexpr const char * FailedToWriteFile
constexpr const char * FailedToDeserializeLinkageTableMissingId
constexpr const char * FileIsNotJSON
constexpr const char * FailedToReadFile
constexpr const char * ParentDirectoryNotFound
constexpr const char * FailedToSerializeEntitySummaryNoFormatInfo
constexpr const char * WritingToIndex
SummaryName summaryNameFromJSON(llvm::StringRef SummaryNameStr)
llvm::StringRef summaryNameToJSON(const SummaryName &SN)
std::optional< EntityLinkageType > entityLinkageTypeFromString(llvm::StringRef Str)
Parses a string produced by entityLinkageTypeToString().
llvm::json::Array Array
std::optional< BuildNamespaceKind > buildNamespaceKindFromString(llvm::StringRef Str)
Parses a string produced by buildNamespaceKindToString().
constexpr const char * JSONTypeKey
Root-object key naming the summary kind so files are self-describing.
llvm::Expected< llvm::StringRef > readSummaryType(const Object &RootObject)
Reads the JSONTypeKey field from the root object as a string.
llvm::Expected< EntityLinkageType > entityLinkageTypeFromJSON(llvm::StringRef EntityLinkageTypeStr)
constexpr const char * JSONEntityIdKey
An entity ID is encoded as the single-key object {"@": <index>}.
llvm::StringRef analysisNameToJSON(const AnalysisName &AN)
llvm::json::Value Value
static llvm::Expected< std::pair< llvm::StringRef, llvm::StringRef > > entityNameCoreFromJSON(const Object &EntityNameObject)
Reads "usr" and "suffix" fields from an EntityName JSON object.
AnalysisName analysisNameFromJSON(llvm::StringRef AnalysisNameStr)
llvm::Error validateNormalizedTargetTriple(llvm::StringRef Triple)
Validates that Triple is a target triple string in normalized form.
llvm::Expected< BuildNamespaceKind > buildNamespaceKindFromJSON(llvm::StringRef BuildNamespaceKindStr)
llvm::json::Object Object
llvm::Expected< Value > readJSON(llvm::StringRef Path)
llvm::Error checkSummaryType(const Object &RootObject, llvm::StringRef ExpectedType)
Reads the JSONTypeKey field from the root object and verifies it equals ExpectedType.
static llvm::Expected< EntityId > entityIdTableEntryIdFromJSON(const Object &EntityIdTableEntryObject, llvm::function_ref< EntityId(uint64_t)> MakeId)
Shared logic for reading the "id" field from an EntityIdTableEntry object.
constexpr const char * JSONFormatFileExtension
llvm::StringRef buildNamespaceKindToJSON(BuildNamespaceKind BNK)
static llvm::Expected< EntityIdTable > entityIdTableFromJSONImpl(const Array &EntityIdTableArray, llvm::function_ref< llvm::Expected< std::pair< EntityName, EntityId > >(const Object &)> EntryReader, llvm::function_ref< std::map< EntityName, EntityId > &(EntityIdTable &)> GetEntities)
Shared logic for deserializing an EntityIdTable from a JSON array.
llvm::StringRef entityLinkageTypeToJSON(EntityLinkageType LT)
llvm::Error writeJSON(Value &&V, llvm::StringRef Path)
llvm::StringRef buildNamespaceKindToString(BuildNamespaceKind BNK)
Returns the canonical string representation of BNK used for serialization and display (e....
volatile int JSONFormatAnchorSource
llvm::StringRef entityLinkageTypeToString(EntityLinkageType LT)
Returns the canonical string representation of LT used for serialization and display (e....
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
Definition TypeBase.h:905
llvm::Expected< QualType > ExpectedType
unsigned long uint64_t