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