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