llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Aviral Goel (aviralg)
<details>
<summary>Changes</summary>
This change extends `SerializationFormat` and `JSONFormat` with APIs to read
and write `LUSummary` and `LUSummaryEncoding`, completing the serialization
interface for both TU-level and LU-level summaries. As part of the
implementation, serialization infrastructure has been extracted into
`JSONFormatImpl.{cpp, h}`, eliminating duplication across the TU and LU
translation units. A comprehensive `LUSummaryTest` suite has been added to test
`LUSummary` and `LUSummaryEncoding`, mirroring the structure of the existing
`TUSummaryTest` suite. Shared testing infrastructure has been extracted into
`JSONFormatTest.{cpp, h}`.
---
Patch is 203.38 KiB, truncated to 20.00 KiB below, full version:
https://github.com/llvm/llvm-project/pull/184037.diff
16 Files Affected:
- (modified) clang/include/clang/Analysis/Scalable/Serialization/JSONFormat.h
(+11)
- (modified)
clang/include/clang/Analysis/Scalable/Serialization/SerializationFormat.h (+12)
- (modified) clang/lib/Analysis/Scalable/CMakeLists.txt (+2)
- (modified)
clang/lib/Analysis/Scalable/Serialization/JSONFormat/JSONFormatImpl.cpp
(+571-9)
- (modified)
clang/lib/Analysis/Scalable/Serialization/JSONFormat/JSONFormatImpl.h (+25)
- (added) clang/lib/Analysis/Scalable/Serialization/JSONFormat/LUSummary.cpp
(+165)
- (added)
clang/lib/Analysis/Scalable/Serialization/JSONFormat/LUSummaryEncoding.cpp
(+162)
- (modified) clang/lib/Analysis/Scalable/Serialization/JSONFormat/TUSummary.cpp
(+3-342)
- (modified)
clang/lib/Analysis/Scalable/Serialization/JSONFormat/TUSummaryEncoding.cpp
(+3-248)
- (modified) clang/unittests/Analysis/Scalable/CMakeLists.txt (+2)
- (modified)
clang/unittests/Analysis/Scalable/Registries/MockSerializationFormat.cpp (+24)
- (modified)
clang/unittests/Analysis/Scalable/Registries/MockSerializationFormat.h (+11)
- (added)
clang/unittests/Analysis/Scalable/Serialization/JSONFormatTest/JSONFormatTest.cpp
(+626)
- (modified)
clang/unittests/Analysis/Scalable/Serialization/JSONFormatTest/JSONFormatTest.h
(+107-132)
- (added)
clang/unittests/Analysis/Scalable/Serialization/JSONFormatTest/LUSummaryTest.cpp
(+2525)
- (modified)
clang/unittests/Analysis/Scalable/Serialization/JSONFormatTest/TUSummaryTest.cpp
(+55-595)
``````````diff
diff --git a/clang/include/clang/Analysis/Scalable/Serialization/JSONFormat.h
b/clang/include/clang/Analysis/Scalable/Serialization/JSONFormat.h
index f69dfd6444685..d93fe41f67972 100644
--- a/clang/include/clang/Analysis/Scalable/Serialization/JSONFormat.h
+++ b/clang/include/clang/Analysis/Scalable/Serialization/JSONFormat.h
@@ -60,6 +60,17 @@ class JSONFormat final : public SerializationFormat {
llvm::Error writeTUSummaryEncoding(const TUSummaryEncoding &SummaryEncoding,
llvm::StringRef Path) override;
+ llvm::Expected<LUSummary> readLUSummary(llvm::StringRef Path) override;
+
+ llvm::Error writeLUSummary(const LUSummary &Summary,
+ llvm::StringRef Path) override;
+
+ llvm::Expected<LUSummaryEncoding>
+ readLUSummaryEncoding(llvm::StringRef Path) override;
+
+ llvm::Error writeLUSummaryEncoding(const LUSummaryEncoding &SummaryEncoding,
+ llvm::StringRef Path) override;
+
using SerializerFn = llvm::function_ref<Object(const EntitySummary &,
const EntityIdConverter &)>;
using DeserializerFn =
diff --git
a/clang/include/clang/Analysis/Scalable/Serialization/SerializationFormat.h
b/clang/include/clang/Analysis/Scalable/Serialization/SerializationFormat.h
index 784e239f4d7a8..c86ca7ef960e9 100644
--- a/clang/include/clang/Analysis/Scalable/Serialization/SerializationFormat.h
+++ b/clang/include/clang/Analysis/Scalable/Serialization/SerializationFormat.h
@@ -42,6 +42,18 @@ class SerializationFormat {
writeTUSummaryEncoding(const TUSummaryEncoding &SummaryEncoding,
llvm::StringRef Path) = 0;
+ virtual llvm::Expected<LUSummary> readLUSummary(llvm::StringRef Path) = 0;
+
+ virtual llvm::Error writeLUSummary(const LUSummary &Summary,
+ llvm::StringRef Path) = 0;
+
+ virtual llvm::Expected<LUSummaryEncoding>
+ readLUSummaryEncoding(llvm::StringRef Path) = 0;
+
+ virtual llvm::Error
+ writeLUSummaryEncoding(const LUSummaryEncoding &SummaryEncoding,
+ llvm::StringRef Path) = 0;
+
protected:
// Helpers providing access to implementation details of basic data
structures
// for efficient serialization/deserialization.
diff --git a/clang/lib/Analysis/Scalable/CMakeLists.txt
b/clang/lib/Analysis/Scalable/CMakeLists.txt
index 5d195174d9f9d..81550df4565cb 100644
--- a/clang/lib/Analysis/Scalable/CMakeLists.txt
+++ b/clang/lib/Analysis/Scalable/CMakeLists.txt
@@ -12,6 +12,8 @@ add_clang_library(clangAnalysisScalable
Model/EntityName.cpp
Model/SummaryName.cpp
Serialization/JSONFormat/JSONFormatImpl.cpp
+ Serialization/JSONFormat/LUSummary.cpp
+ Serialization/JSONFormat/LUSummaryEncoding.cpp
Serialization/JSONFormat/TUSummary.cpp
Serialization/JSONFormat/TUSummaryEncoding.cpp
Serialization/SerializationFormatRegistry.cpp
diff --git
a/clang/lib/Analysis/Scalable/Serialization/JSONFormat/JSONFormatImpl.cpp
b/clang/lib/Analysis/Scalable/Serialization/JSONFormat/JSONFormatImpl.cpp
index 3b9b49439dfa2..aef02eb36c477 100644
--- a/clang/lib/Analysis/Scalable/Serialization/JSONFormat/JSONFormatImpl.cpp
+++ b/clang/lib/Analysis/Scalable/Serialization/JSONFormat/JSONFormatImpl.cpp
@@ -1,4 +1,4 @@
-//===- JSONFormatImpl.cpp -----------------------------------------------===//
+//===- JSONFormatImpl.cpp
-------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM
Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -34,7 +34,7 @@ llvm::Expected<Value> readJSON(llvm::StringRef Path) {
.build();
}
- if (!Path.ends_with_insensitive(JSONFormatFileExtension)) {
+ if (!Path.ends_with(JSONFormatFileExtension)) {
return ErrorBuilder::create(std::errc::invalid_argument,
ErrorMessages::FailedToReadFile, Path,
llvm::formatv(ErrorMessages::FileIsNotJSON,
@@ -53,7 +53,7 @@ llvm::Expected<Value> readJSON(llvm::StringRef Path) {
return llvm::json::parse(BufferOrError.get()->getBuffer());
}
-llvm::Error writeJSON(Value &&Value, llvm::StringRef Path) {
+llvm::Error writeJSON(Value &&Val, llvm::StringRef Path) {
if (llvm::sys::fs::exists(Path)) {
return ErrorBuilder::create(std::errc::file_exists,
ErrorMessages::FailedToWriteFile, Path,
@@ -69,7 +69,7 @@ llvm::Error writeJSON(Value &&Value, llvm::StringRef Path) {
.build();
}
- if (!Path.ends_with_insensitive(JSONFormatFileExtension)) {
+ if (!Path.ends_with(JSONFormatFileExtension)) {
return ErrorBuilder::create(std::errc::invalid_argument,
ErrorMessages::FailedToWriteFile, Path,
llvm::formatv(ErrorMessages::FileIsNotJSON,
@@ -86,7 +86,7 @@ llvm::Error writeJSON(Value &&Value, llvm::StringRef Path) {
.build();
}
- OutStream << llvm::formatv("{0:2}\n", Value);
+ OutStream << llvm::formatv("{0:2}\n", Val);
OutStream.flush();
// This path handles post-write stream errors (e.g. ENOSPC after buffered
@@ -110,7 +110,8 @@ std::map<SummaryName, JSONFormat::FormatInfo>
JSONFormat::initFormatInfos() {
std::map<SummaryName, FormatInfo> FormatInfos;
for (const auto &FormatInfoEntry : llvm::Registry<FormatInfo>::entries()) {
std::unique_ptr<FormatInfo> Info = FormatInfoEntry.instantiate();
- bool Inserted = FormatInfos.try_emplace(Info->ForSummary, *Info).second;
+ bool Inserted =
+ FormatInfos.try_emplace(Info->ForSummary, std::move(*Info)).second;
if (!Inserted) {
llvm::report_fatal_error(
"FormatInfo is already registered for summary: " +
@@ -216,7 +217,6 @@ llvm::Expected<NestedBuildNamespace>
JSONFormat::nestedBuildNamespaceFromJSON(
for (const auto &[Index, BuildNamespaceValue] :
llvm::enumerate(NestedBuildNamespaceArray)) {
-
const Object *BuildNamespaceObject = BuildNamespaceValue.getAsObject();
if (!BuildNamespaceObject) {
return ErrorBuilder::create(std::errc::invalid_argument,
@@ -418,7 +418,6 @@ JSONFormat::entityIdTableFromJSON(const Array
&EntityIdTableArray) const {
for (const auto &[Index, EntityIdTableEntryValue] :
llvm::enumerate(EntityIdTableArray)) {
-
const Object *OptEntityIdTableEntryObject =
EntityIdTableEntryValue.getAsObject();
if (!OptEntityIdTableEntryObject) {
@@ -430,11 +429,12 @@ JSONFormat::entityIdTableFromJSON(const Array
&EntityIdTableArray) const {
auto ExpectedEntityIdTableEntry =
entityIdTableEntryFromJSON(*OptEntityIdTableEntryObject);
- if (!ExpectedEntityIdTableEntry)
+ if (!ExpectedEntityIdTableEntry) {
return ErrorBuilder::wrap(ExpectedEntityIdTableEntry.takeError())
.context(ErrorMessages::ReadingFromIndex, "EntityIdTable entry",
Index)
.build();
+ }
auto [EntityIt, EntityInserted] =
Entities.emplace(std::move(*ExpectedEntityIdTableEntry));
@@ -593,4 +593,566 @@ Array JSONFormat::linkageTableToJSON(
return Result;
}
+//----------------------------------------------------------------------------
+// EntitySummary
+//----------------------------------------------------------------------------
+
+llvm::Expected<std::unique_ptr<EntitySummary>>
+JSONFormat::entitySummaryFromJSON(const SummaryName &SN,
+ const Object &EntitySummaryObject,
+ EntityIdTable &IdTable) const {
+ auto InfoIt = FormatInfos.find(SN);
+ if (InfoIt == FormatInfos.end()) {
+ return ErrorBuilder::create(
+ std::errc::invalid_argument,
+ ErrorMessages::FailedToDeserializeEntitySummaryNoFormatInfo, SN)
+ .build();
+ }
+
+ const auto &InfoEntry = InfoIt->second;
+ assert(InfoEntry.ForSummary == SN);
+
+ EntityIdConverter Converter(*this);
+ return InfoEntry.Deserialize(EntitySummaryObject, IdTable, Converter);
+}
+
+llvm::Expected<Object>
+JSONFormat::entitySummaryToJSON(const SummaryName &SN,
+ const EntitySummary &ES) const {
+ auto InfoIt = FormatInfos.find(SN);
+ if (InfoIt == FormatInfos.end()) {
+ return ErrorBuilder::create(
+ std::errc::invalid_argument,
+ ErrorMessages::FailedToSerializeEntitySummaryNoFormatInfo, SN)
+ .build();
+ }
+
+ const auto &InfoEntry = InfoIt->second;
+ assert(InfoEntry.ForSummary == SN);
+
+ EntityIdConverter Converter(*this);
+ return InfoEntry.Serialize(ES, Converter);
+}
+
+//----------------------------------------------------------------------------
+// EntityDataMapEntry
+//----------------------------------------------------------------------------
+
+llvm::Expected<std::pair<EntityId, std::unique_ptr<EntitySummary>>>
+JSONFormat::entityDataMapEntryFromJSON(const Object &EntityDataMapEntryObject,
+ const SummaryName &SN,
+ EntityIdTable &IdTable) const {
+
+ const Value *EntityIdIntValue = EntityDataMapEntryObject.get("entity_id");
+ if (!EntityIdIntValue) {
+ return ErrorBuilder::create(std::errc::invalid_argument,
+ ErrorMessages::FailedToReadObjectAtField,
+ "EntityId", "entity_id",
+ "number (unsigned 64-bit integer)")
+ .build();
+ }
+
+ const std::optional<uint64_t> OptEntityIdInt =
+ EntityIdIntValue->getAsUINT64();
+ if (!OptEntityIdInt) {
+ return ErrorBuilder::create(std::errc::invalid_argument,
+ ErrorMessages::FailedToReadObjectAtField,
+ "EntityId", "entity_id",
+ "number (unsigned 64-bit integer)")
+ .build();
+ }
+
+ EntityId EI = entityIdFromJSON(*OptEntityIdInt);
+
+ const Object *OptEntitySummaryObject =
+ EntityDataMapEntryObject.getObject("entity_summary");
+ if (!OptEntitySummaryObject) {
+ return ErrorBuilder::create(std::errc::invalid_argument,
+ ErrorMessages::FailedToReadObjectAtField,
+ "EntitySummary", "entity_summary", "object")
+ .build();
+ }
+
+ auto ExpectedEntitySummary =
+ entitySummaryFromJSON(SN, *OptEntitySummaryObject, IdTable);
+ if (!ExpectedEntitySummary) {
+ return ErrorBuilder::wrap(ExpectedEntitySummary.takeError())
+ .context(ErrorMessages::ReadingFromField, "EntitySummary",
+ "entity_summary")
+ .build();
+ }
+
+ if (*ExpectedEntitySummary == nullptr) {
+ return ErrorBuilder::create(
+ std::errc::invalid_argument,
+ ErrorMessages::FailedToDeserializeEntitySummaryMissingData, SN)
+ .build();
+ }
+
+ auto ActualSN = (*ExpectedEntitySummary)->getSummaryName();
+ if (SN != ActualSN) {
+ return ErrorBuilder::create(
+ std::errc::invalid_argument,
+ ErrorMessages::
+ FailedToDeserializeEntitySummaryMismatchedSummaryName,
+ SN, ActualSN)
+ .build();
+ }
+
+ return std::make_pair(std::move(EI), std::move(*ExpectedEntitySummary));
+}
+
+llvm::Expected<Object> JSONFormat::entityDataMapEntryToJSON(
+ const EntityId EI, const std::unique_ptr<EntitySummary> &EntitySummary,
+ const SummaryName &SN) const {
+ Object Entry;
+
+ Entry["entity_id"] = entityIdToJSON(EI);
+
+ if (!EntitySummary) {
+ ErrorBuilder::fatal(
+ ErrorMessages::FailedToSerializeEntitySummaryMissingData, SN);
+ }
+
+ const auto ActualSN = EntitySummary->getSummaryName();
+ if (SN != ActualSN) {
+ ErrorBuilder::fatal(
+ ErrorMessages::FailedToSerializeEntitySummaryMismatchedSummaryName, SN,
+ ActualSN);
+ }
+
+ auto ExpectedEntitySummaryObject = entitySummaryToJSON(SN, *EntitySummary);
+ if (!ExpectedEntitySummaryObject) {
+ return ErrorBuilder::wrap(ExpectedEntitySummaryObject.takeError())
+ .context(ErrorMessages::WritingToField, "EntitySummary",
+ "entity_summary")
+ .build();
+ }
+
+ Entry["entity_summary"] = std::move(*ExpectedEntitySummaryObject);
+
+ return Entry;
+}
+
+//----------------------------------------------------------------------------
+// EntityDataMap
+//----------------------------------------------------------------------------
+
+llvm::Expected<std::map<EntityId, std::unique_ptr<EntitySummary>>>
+JSONFormat::entityDataMapFromJSON(const SummaryName &SN,
+ const Array &EntityDataArray,
+ EntityIdTable &IdTable) const {
+ std::map<EntityId, std::unique_ptr<EntitySummary>> EntityDataMap;
+
+ for (const auto &[Index, EntityDataMapEntryValue] :
+ llvm::enumerate(EntityDataArray)) {
+ const Object *OptEntityDataMapEntryObject =
+ EntityDataMapEntryValue.getAsObject();
+ if (!OptEntityDataMapEntryObject) {
+ return ErrorBuilder::create(std::errc::invalid_argument,
+ ErrorMessages::FailedToReadObjectAtIndex,
+ "EntitySummary entry", Index, "object")
+ .build();
+ }
+
+ auto ExpectedEntityDataMapEntry =
+ entityDataMapEntryFromJSON(*OptEntityDataMapEntryObject, SN, IdTable);
+ if (!ExpectedEntityDataMapEntry) {
+ return ErrorBuilder::wrap(ExpectedEntityDataMapEntry.takeError())
+ .context(ErrorMessages::ReadingFromIndex, "EntitySummary entry",
+ Index)
+ .build();
+ }
+
+ auto [DataIt, DataInserted] =
+ EntityDataMap.insert(std::move(*ExpectedEntityDataMapEntry));
+ if (!DataInserted) {
+ return ErrorBuilder::create(std::errc::invalid_argument,
+ ErrorMessages::FailedInsertionOnDuplication,
+ "EntitySummary entry", Index, DataIt->first)
+ .build();
+ }
+ }
+
+ return std::move(EntityDataMap);
+}
+
+llvm::Expected<Array> JSONFormat::entityDataMapToJSON(
+ const SummaryName &SN,
+ const std::map<EntityId, std::unique_ptr<EntitySummary>> &EntityDataMap)
+ const {
+ Array Result;
+ Result.reserve(EntityDataMap.size());
+
+ for (const auto &[Index, EntityDataMapEntry] :
+ llvm::enumerate(EntityDataMap)) {
+ const auto &[EntityId, EntitySummary] = EntityDataMapEntry;
+
+ auto ExpectedEntityDataMapEntryObject =
+ entityDataMapEntryToJSON(EntityId, EntitySummary, SN);
+
+ if (!ExpectedEntityDataMapEntryObject) {
+ return ErrorBuilder::wrap(ExpectedEntityDataMapEntryObject.takeError())
+ .context(ErrorMessages::WritingToIndex, "EntitySummary entry", Index)
+ .build();
+ }
+
+ Result.push_back(std::move(*ExpectedEntityDataMapEntryObject));
+ }
+
+ return Result;
+}
+
+//----------------------------------------------------------------------------
+// SummaryDataMapEntry
+//----------------------------------------------------------------------------
+
+llvm::Expected<
+ std::pair<SummaryName, std::map<EntityId, std::unique_ptr<EntitySummary>>>>
+JSONFormat::summaryDataMapEntryFromJSON(const Object
&SummaryDataMapEntryObject,
+ EntityIdTable &IdTable) const {
+
+ std::optional<llvm::StringRef> OptSummaryNameStr =
+ SummaryDataMapEntryObject.getString("summary_name");
+ if (!OptSummaryNameStr) {
+ return ErrorBuilder::create(std::errc::invalid_argument,
+ ErrorMessages::FailedToReadObjectAtField,
+ "SummaryName", "summary_name", "string")
+ .build();
+ }
+
+ SummaryName SN = summaryNameFromJSON(*OptSummaryNameStr);
+
+ const Array *OptEntityDataArray =
+ SummaryDataMapEntryObject.getArray("summary_data");
+ if (!OptEntityDataArray) {
+ return ErrorBuilder::create(std::errc::invalid_argument,
+ ErrorMessages::FailedToReadObjectAtField,
+ "EntitySummary entries", "summary_data",
+ "array")
+ .build();
+ }
+
+ auto ExpectedEntityDataMap =
+ entityDataMapFromJSON(SN, *OptEntityDataArray, IdTable);
+ if (!ExpectedEntityDataMap) {
+ return ErrorBuilder::wrap(ExpectedEntityDataMap.takeError())
+ .context(ErrorMessages::ReadingFromField, "EntitySummary entries",
+ "summary_data")
+ .build();
+ }
+
+ return std::make_pair(std::move(SN), std::move(*ExpectedEntityDataMap));
+}
+
+llvm::Expected<Object> JSONFormat::summaryDataMapEntryToJSON(
+ const SummaryName &SN,
+ const std::map<EntityId, std::unique_ptr<EntitySummary>> &SD) const {
+ Object Result;
+
+ Result["summary_name"] = summaryNameToJSON(SN);
+
+ auto ExpectedSummaryDataArray = entityDataMapToJSON(SN, SD);
+ if (!ExpectedSummaryDataArray) {
+ return ErrorBuilder::wrap(ExpectedSummaryDataArray.takeError())
+ .context(ErrorMessages::WritingToField, "EntitySummary entries",
+ "summary_data")
+ .build();
+ }
+
+ Result["summary_data"] = std::move(*ExpectedSummaryDataArray);
+
+ return Result;
+}
+
+//----------------------------------------------------------------------------
+// SummaryDataMap
+//----------------------------------------------------------------------------
+
+llvm::Expected<
+ std::map<SummaryName, std::map<EntityId, std::unique_ptr<EntitySummary>>>>
+JSONFormat::summaryDataMapFromJSON(const Array &SummaryDataArray,
+ EntityIdTable &IdTable) const {
+ std::map<SummaryName, std::map<EntityId, std::unique_ptr<EntitySummary>>>
+ SummaryDataMap;
+
+ for (const auto &[Index, SummaryDataMapEntryValue] :
+ llvm::enumerate(SummaryDataArray)) {
+ const Object *OptSummaryDataMapEntryObject =
+ SummaryDataMapEntryValue.getAsObject();
+ if (!OptSummaryDataMapEntryObject) {
+ return ErrorBuilder::create(std::errc::invalid_argument,
+ ErrorMessages::FailedToReadObjectAtIndex,
+ "SummaryData entry", Index, "object")
+ .build();
+ }
+
+ auto ExpectedSummaryDataMapEntry =
+ summaryDataMapEntryFromJSON(*OptSummaryDataMapEntryObject, IdTable);
+ if (!ExpectedSummaryDataMapEntry) {
+ return ErrorBuilder::wrap(ExpectedSummaryDataMapEntry.takeError())
+ .context(ErrorMessages::ReadingFromIndex, "SummaryData entry", Index)
+ .build();
+ }
+
+ auto [SummaryIt, SummaryInserted] =
+ SummaryDataMap.emplace(std::move(*ExpectedSummaryDataMapEntry));
+ if (!SummaryInserted) {
+ return ErrorBuilder::create(std::errc::invalid_argument,
+ ErrorMessages::FailedInsertionOnDuplication,
+ "SummaryData entry", Index, SummaryIt->first)
+ .build();
+ }
+ }
+
+ return std::move(SummaryDataMap);
+}
+
+llvm::Expected<Array> JSONFormat::summaryDataMapToJSON(
+ const std::map<SummaryName,
+ std::map<EntityId, std::unique_ptr<EntitySummary>>>
+ &SummaryDataMap) const {
+ Array Result;
+ Result.reserve(SummaryDataMap.size());
+
+ for (const auto &[Index, SummaryDataMapEntry] :
+ llvm::enumerate(SummaryDataMap)) {
+ const auto &[SummaryName, DataMap] = SummaryDataMapEntry;
+
+ auto ExpectedSummaryDataMapObject =
+ summaryDataMapEntryToJSON(SummaryName, DataMap);
+ if (!ExpectedSummaryDataMapObject) {
+ return ErrorBuilder::wrap(ExpectedSummaryDataMapObject.takeError())
+ .context(ErrorMessages::WritingToIndex, "SummaryData entry", Index)
+ .build();
+ }
+
+ Result.push_back(std::move(*ExpectedSummaryDataMapObject));
+ }
+
+ return std::move(Result);
+}
+
+//----------------------------------------------------------------------------
+// EncodingDataMapEntry
+//----------------------------------------------------------------------------
+
+llvm::Expected<std::pair<EntityId, std::unique_ptr<EntitySummaryEncoding>>>
+JSONFormat::encodingDataMapEntryFromJSON(
+ const Object &EntityDataMapEntryObject) const {
+ const Value *EntityIdIntValue = EntityDataMapEntryObject.get("entity_id");
+ if (!EntityIdIntValue) {
+ return ErrorBuilder::create(std::errc::invalid_argument,
+ ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/184037
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits