llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-static-analyzer-1 Author: Aviral Goel (aviralg) <details> <summary>Changes</summary> This change introduces the `StaticLibrary` data structure, the SSAF analogue of `ar`, `libtool -static`, or `lib.exe`: a single-architecture bundle of `TUSummary` objects. `StaticLibrary` only stores `TUSummaryEncoding` because it will be used by `clang-ssaf-linker` without decoding the summary data. We don't plan to create a decoded variant because there will be no consumer. Support for constructing and linking static libraries will be introduced in future PRs. rdar://180665891 --- Patch is 68.86 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/205946.diff 50 Files Affected: - (added) clang/include/clang/ScalableStaticAnalysis/Core/EntityLinker/StaticLibrary.h (+75) - (modified) clang/include/clang/ScalableStaticAnalysis/Core/EntityLinker/TUSummaryEncoding.h (+1) - (modified) clang/include/clang/ScalableStaticAnalysis/Core/Model/BuildNamespace.h (+5-1) - (modified) clang/include/clang/ScalableStaticAnalysis/Core/Model/PrivateFieldNames.def (+3) - (modified) clang/include/clang/ScalableStaticAnalysis/Core/Serialization/JSONFormat.h (+15) - (modified) clang/include/clang/ScalableStaticAnalysis/Core/Serialization/SerializationFormat.h (+13-1) - (modified) clang/lib/ScalableStaticAnalysis/Core/CMakeLists.txt (+1) - (modified) clang/lib/ScalableStaticAnalysis/Core/ModelStringConversions.h (+4) - (modified) clang/lib/ScalableStaticAnalysis/Core/Serialization/JSONFormat/Artifact.cpp (+16-3) - (modified) clang/lib/ScalableStaticAnalysis/Core/Serialization/JSONFormat/JSONFormatImpl.h (+4-1) - (added) clang/lib/ScalableStaticAnalysis/Core/Serialization/JSONFormat/StaticLibrary.cpp (+192) - (modified) clang/lib/ScalableStaticAnalysis/Core/Serialization/JSONFormat/TUSummaryEncoding.cpp (+12-7) - (added) clang/test/Analysis/Scalable/ssaf-format/Artifact/Inputs/rt-static-library-empty.json (+9) - (modified) clang/test/Analysis/Scalable/ssaf-format/Artifact/round-trip.test (+9) - (modified) clang/test/Analysis/Scalable/ssaf-format/Artifact/top-level.test (+1-1) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/duplicate-member.json (+32) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/invalid-syntax.json (+1) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/member-inner-error.json (+17) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/member-mismatched-type.json (+18) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/member-missing-type.json (+20) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/member-not-object.json (+9) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/member-triple-mismatch.json (+21) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/members-not-array.json (+9) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/mismatched-type.json (+9) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/missing-members.json (+8) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/missing-namespace.json (+5) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/missing-target-triple.json (+8) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/missing-type.json (+8) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/namespace-invalid-kind.json (+9) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/namespace-missing-kind.json (+8) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/namespace-missing-name.json (+8) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/namespace-wrong-kind.json (+9) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/not-json-extension.txt (+1) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/not-normalized-target-triple.json (+9) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/not-object.json (+1) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/rt-empty.json (+9) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/rt-multiple-members.json (+43) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/rt-single-member.json (+21) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/Inputs/unsorted-members-input.json (+43) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/io.test (+49) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/permissions.test (+40) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/round-trip.test (+42) - (added) clang/test/Analysis/Scalable/ssaf-format/StaticLibrary/top-level.test (+125) - (modified) clang/tools/clang-ssaf-format/SSAFFormat.cpp (+10-1) - (modified) clang/unittests/ScalableStaticAnalysis/BuildNamespaceTest.cpp (+8) - (modified) clang/unittests/ScalableStaticAnalysis/Frontend/TUSummaryExtractorFrontendActionTest.cpp (+17) - (modified) clang/unittests/ScalableStaticAnalysis/ModelStringConversionsTest.cpp (+14) - (modified) clang/unittests/ScalableStaticAnalysis/Registries/MockSerializationFormat.cpp (+11) - (modified) clang/unittests/ScalableStaticAnalysis/Registries/MockSerializationFormat.h (+6) - (modified) clang/unittests/ScalableStaticAnalysis/TestFixture.h (+1) ``````````diff diff --git a/clang/include/clang/ScalableStaticAnalysis/Core/EntityLinker/StaticLibrary.h b/clang/include/clang/ScalableStaticAnalysis/Core/EntityLinker/StaticLibrary.h new file mode 100644 index 0000000000000..74b6fb4ea169f --- /dev/null +++ b/clang/include/clang/ScalableStaticAnalysis/Core/EntityLinker/StaticLibrary.h @@ -0,0 +1,75 @@ +//===- StaticLibrary.h ------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the StaticLibrary class, which represents a static +// library of translation unit summary encodings (the SSAF analogue of an +// ar / libtool -static / lib.exe output). +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SCALABLESTATICANALYSIS_CORE_ENTITYLINKER_STATICLIBRARY_H +#define LLVM_CLANG_SCALABLESTATICANALYSIS_CORE_ENTITYLINKER_STATICLIBRARY_H + +#include "clang/ScalableStaticAnalysis/Core/EntityLinker/TUSummaryEncoding.h" +#include "clang/ScalableStaticAnalysis/Core/Model/BuildNamespace.h" +#include "llvm/TargetParser/Triple.h" +#include <memory> +#include <set> + +namespace clang::ssaf { + +/// Represents a static library of translation unit summary encodings. +/// +/// A StaticLibrary bundles member translation units without performing +/// entity resolution, mirroring the role of ar / libtool -static / lib.exe +/// in native build pipelines. The final linker is responsible for +/// selective inclusion when a StaticLibrary appears on its command line. +/// +/// Static libraries are single-architecture: every member's target triple +/// must equal the library's. Multi-architecture static libraries are +/// expressed as a fat wrapper around per-architecture StaticLibrary +/// instances rather than as a single mixed-architecture library. +/// +/// Members are stored as encoded TUSummaryEncoding objects: the archiver +/// tool never decodes per-entity payloads, and the linker consumes them +/// as-is during its selective inclusion pass. +class StaticLibrary { + friend class SerializationFormat; + friend class TestFixture; + + /// Orders members by their TUNamespace. As a nested struct of + /// StaticLibrary, it inherits StaticLibrary's friend access to + /// TUSummaryEncoding's private fields. + struct MemberByNamespace { + bool operator()(const std::unique_ptr<TUSummaryEncoding> &A, + const std::unique_ptr<TUSummaryEncoding> &B) const { + return A->TUNamespace < B->TUNamespace; + } + }; + + // Target triple of the static library. All member TUs must share this + // triple. + llvm::Triple TargetTriple; + + // The namespace identifying this static library (kind=StaticLibrary). + BuildNamespace Namespace; + + // Member translation units, ordered by their TUNamespace. Membership is + // by namespace identity: inserting a TU whose TUNamespace already exists + // in the set is rejected during deserialization. + std::set<std::unique_ptr<TUSummaryEncoding>, MemberByNamespace> Members; + +public: + StaticLibrary(llvm::Triple TargetTriple, BuildNamespace Namespace) + : TargetTriple(std::move(TargetTriple)), Namespace(std::move(Namespace)) { + } +}; + +} // namespace clang::ssaf + +#endif // LLVM_CLANG_SCALABLESTATICANALYSIS_CORE_ENTITYLINKER_STATICLIBRARY_H diff --git a/clang/include/clang/ScalableStaticAnalysis/Core/EntityLinker/TUSummaryEncoding.h b/clang/include/clang/ScalableStaticAnalysis/Core/EntityLinker/TUSummaryEncoding.h index 2c672a55e4873..2ece195ed1fd0 100644 --- a/clang/include/clang/ScalableStaticAnalysis/Core/EntityLinker/TUSummaryEncoding.h +++ b/clang/include/clang/ScalableStaticAnalysis/Core/EntityLinker/TUSummaryEncoding.h @@ -35,6 +35,7 @@ namespace clang::ssaf { class TUSummaryEncoding { friend class EntityLinker; friend class SerializationFormat; + friend class StaticLibrary; friend class TestFixture; // Target triple of the translation unit. diff --git a/clang/include/clang/ScalableStaticAnalysis/Core/Model/BuildNamespace.h b/clang/include/clang/ScalableStaticAnalysis/Core/Model/BuildNamespace.h index 6da5a9e42c4da..1549b357ea50d 100644 --- a/clang/include/clang/ScalableStaticAnalysis/Core/Model/BuildNamespace.h +++ b/clang/include/clang/ScalableStaticAnalysis/Core/Model/BuildNamespace.h @@ -27,7 +27,11 @@ namespace clang::ssaf { -enum class BuildNamespaceKind : unsigned short { CompilationUnit, LinkUnit }; +enum class BuildNamespaceKind : unsigned short { + CompilationUnit, + LinkUnit, + StaticLibrary +}; /// Represents a single namespace in the build process. /// diff --git a/clang/include/clang/ScalableStaticAnalysis/Core/Model/PrivateFieldNames.def b/clang/include/clang/ScalableStaticAnalysis/Core/Model/PrivateFieldNames.def index 44931026ba428..b1c37823dc3fe 100644 --- a/clang/include/clang/ScalableStaticAnalysis/Core/Model/PrivateFieldNames.def +++ b/clang/include/clang/ScalableStaticAnalysis/Core/Model/PrivateFieldNames.def @@ -36,6 +36,9 @@ FIELD(LUSummaryEncoding, IdTable) FIELD(LUSummaryEncoding, LinkageTable) FIELD(LUSummaryEncoding, LUNamespace) FIELD(NestedBuildNamespace, Namespaces) +FIELD(StaticLibrary, Members) +FIELD(StaticLibrary, Namespace) +FIELD(StaticLibrary, TargetTriple) FIELD(TUSummary, TargetTriple) FIELD(TUSummary, Data) FIELD(TUSummary, IdTable) diff --git a/clang/include/clang/ScalableStaticAnalysis/Core/Serialization/JSONFormat.h b/clang/include/clang/ScalableStaticAnalysis/Core/Serialization/JSONFormat.h index 9d9b1ff0bbb51..d4b6cfc0e1690 100644 --- a/clang/include/clang/ScalableStaticAnalysis/Core/Serialization/JSONFormat.h +++ b/clang/include/clang/ScalableStaticAnalysis/Core/Serialization/JSONFormat.h @@ -68,6 +68,12 @@ class JSONFormat final : public SerializationFormat { llvm::Error writeLUSummaryEncoding(const LUSummaryEncoding &SummaryEncoding, llvm::StringRef Path) override; + llvm::Expected<StaticLibrary> + readStaticLibrary(llvm::StringRef Path) override; + + llvm::Error writeStaticLibrary(const StaticLibrary &S, + llvm::StringRef Path) override; + llvm::Expected<WPASuite> readWPASuite(llvm::StringRef Path) override; llvm::Error writeWPASuite(const WPASuite &Suite, @@ -122,6 +128,15 @@ class JSONFormat final : public SerializationFormat { llvm::Expected<LUSummaryEncoding> readLUSummaryEncodingFromObject(const Object &Root); + /// Parses a StaticLibrary from an already-validated root JSON object. + /// See \c readTUSummaryFromObject for caller responsibilities. + llvm::Expected<StaticLibrary> readStaticLibraryFromObject(const Object &Root); + + /// Serializes a TUSummaryEncoding to a JSON object including its + /// self-describing \c type field. Used both by \c writeTUSummaryEncoding + /// and by the StaticLibrary writer to emit member entries. + Object tuSummaryEncodingToJSON(const TUSummaryEncoding &SE) const; + /// Parses a WPASuite from an already-validated root JSON object. See /// \c readTUSummaryFromObject for caller responsibilities. llvm::Expected<WPASuite> readWPASuiteFromObject(const Object &Root); diff --git a/clang/include/clang/ScalableStaticAnalysis/Core/Serialization/SerializationFormat.h b/clang/include/clang/ScalableStaticAnalysis/Core/Serialization/SerializationFormat.h index ca3ee9ce3362c..29b662bc0e380 100644 --- a/clang/include/clang/ScalableStaticAnalysis/Core/Serialization/SerializationFormat.h +++ b/clang/include/clang/ScalableStaticAnalysis/Core/Serialization/SerializationFormat.h @@ -16,6 +16,7 @@ #include "clang/ScalableStaticAnalysis/Core/EntityLinker/LUSummary.h" #include "clang/ScalableStaticAnalysis/Core/EntityLinker/LUSummaryEncoding.h" +#include "clang/ScalableStaticAnalysis/Core/EntityLinker/StaticLibrary.h" #include "clang/ScalableStaticAnalysis/Core/EntityLinker/TUSummaryEncoding.h" #include "clang/ScalableStaticAnalysis/Core/Model/BuildNamespace.h" #include "clang/ScalableStaticAnalysis/Core/Model/SummaryName.h" @@ -40,7 +41,12 @@ using Artifact = std::variant<TUSummary, LUSummary, WPASuite>; /// Lazily-deserialized counterpart of \c Artifact: the same on-disk /// artifacts but with their per-entity summary payloads left as opaque /// format-specific encodings rather than fully resolved analysis results. -using ArtifactEncoding = std::variant<TUSummaryEncoding, LUSummaryEncoding>; +/// +/// \c StaticLibrary appears only in this variant: the archiver tool and +/// the linker pass member payloads through without decoding them, so a +/// fully decoded static-library shape would have no consumer. +using ArtifactEncoding = + std::variant<TUSummaryEncoding, LUSummaryEncoding, StaticLibrary>; /// Abstract base class for serialization formats. class SerializationFormat { @@ -94,6 +100,12 @@ class SerializationFormat { writeLUSummaryEncoding(const LUSummaryEncoding &SummaryEncoding, llvm::StringRef Path) = 0; + virtual llvm::Expected<StaticLibrary> + readStaticLibrary(llvm::StringRef Path) = 0; + + virtual llvm::Error writeStaticLibrary(const StaticLibrary &S, + llvm::StringRef Path) = 0; + virtual llvm::Expected<WPASuite> readWPASuite(llvm::StringRef Path) = 0; virtual llvm::Error writeWPASuite(const WPASuite &Suite, diff --git a/clang/lib/ScalableStaticAnalysis/Core/CMakeLists.txt b/clang/lib/ScalableStaticAnalysis/Core/CMakeLists.txt index b2cde5f225445..0a0ce19d63732 100644 --- a/clang/lib/ScalableStaticAnalysis/Core/CMakeLists.txt +++ b/clang/lib/ScalableStaticAnalysis/Core/CMakeLists.txt @@ -17,6 +17,7 @@ add_clang_library(clangScalableStaticAnalysisCore Serialization/JSONFormat/JSONFormatImpl.cpp Serialization/JSONFormat/LUSummary.cpp Serialization/JSONFormat/LUSummaryEncoding.cpp + Serialization/JSONFormat/StaticLibrary.cpp Serialization/JSONFormat/TUSummary.cpp Serialization/JSONFormat/TUSummaryEncoding.cpp Serialization/JSONFormat/WPASuite.cpp diff --git a/clang/lib/ScalableStaticAnalysis/Core/ModelStringConversions.h b/clang/lib/ScalableStaticAnalysis/Core/ModelStringConversions.h index ee1603e50025f..8d3c932205740 100644 --- a/clang/lib/ScalableStaticAnalysis/Core/ModelStringConversions.h +++ b/clang/lib/ScalableStaticAnalysis/Core/ModelStringConversions.h @@ -36,6 +36,8 @@ inline llvm::StringRef buildNamespaceKindToString(BuildNamespaceKind BNK) { return "CompilationUnit"; case BuildNamespaceKind::LinkUnit: return "LinkUnit"; + case BuildNamespaceKind::StaticLibrary: + return "StaticLibrary"; } llvm_unreachable("Unhandled BuildNamespaceKind variant"); } @@ -48,6 +50,8 @@ buildNamespaceKindFromString(llvm::StringRef Str) { return BuildNamespaceKind::CompilationUnit; if (Str == "LinkUnit") return BuildNamespaceKind::LinkUnit; + if (Str == "StaticLibrary") + return BuildNamespaceKind::StaticLibrary; return std::nullopt; } diff --git a/clang/lib/ScalableStaticAnalysis/Core/Serialization/JSONFormat/Artifact.cpp b/clang/lib/ScalableStaticAnalysis/Core/Serialization/JSONFormat/Artifact.cpp index 424d7368cf33f..e5fc46a8ea952 100644 --- a/clang/lib/ScalableStaticAnalysis/Core/Serialization/JSONFormat/Artifact.cpp +++ b/clang/lib/ScalableStaticAnalysis/Core/Serialization/JSONFormat/Artifact.cpp @@ -145,10 +145,21 @@ JSONFormat::readArtifactEncoding(llvm::StringRef Path) { return ArtifactEncoding{std::move(*ExpectedLU)}; } + if (*ExpectedType == JSONTypeValueStaticLibrary) { + auto ExpectedStaticLibrary = readStaticLibraryFromObject(*RootObjectPtr); + if (!ExpectedStaticLibrary) { + return ErrorBuilder::wrap(ExpectedStaticLibrary.takeError()) + .context(ErrorMessages::ReadingFromFile, "ArtifactEncoding", Path) + .build(); + } + return ArtifactEncoding{std::move(*ExpectedStaticLibrary)}; + } + return ErrorBuilder::create(std::errc::invalid_argument, ErrorMessages::UnknownArtifactEncodingType, *ExpectedType, JSONTypeKey, - JSONTypeValueTUSummary, JSONTypeValueLUSummary) + JSONTypeValueTUSummary, JSONTypeValueLUSummary, + JSONTypeValueStaticLibrary) .context(ErrorMessages::ReadingFromFile, "ArtifactEncoding", Path) .build(); } @@ -160,11 +171,13 @@ llvm::Error JSONFormat::writeArtifactEncoding(const ArtifactEncoding &E, using T = std::decay_t<decltype(Enc)>; if constexpr (std::is_same_v<T, TUSummaryEncoding>) { return writeTUSummaryEncoding(Enc, Path); + } else if constexpr (std::is_same_v<T, LUSummaryEncoding>) { + return writeLUSummaryEncoding(Enc, Path); } else { static_assert( - std::is_same_v<T, LUSummaryEncoding>, + std::is_same_v<T, StaticLibrary>, "ArtifactEncoding visitor must cover all variant alternatives"); - return writeLUSummaryEncoding(Enc, Path); + return writeStaticLibrary(Enc, Path); } }, E); diff --git a/clang/lib/ScalableStaticAnalysis/Core/Serialization/JSONFormat/JSONFormatImpl.h b/clang/lib/ScalableStaticAnalysis/Core/Serialization/JSONFormat/JSONFormatImpl.h index 191be83ccb0e5..e83a8dabac113 100644 --- a/clang/lib/ScalableStaticAnalysis/Core/Serialization/JSONFormat/JSONFormatImpl.h +++ b/clang/lib/ScalableStaticAnalysis/Core/Serialization/JSONFormat/JSONFormatImpl.h @@ -85,7 +85,7 @@ inline constexpr const char *MismatchedSummaryType = inline constexpr const char *UnknownArtifactType = "unknown value '{0}' for field '{1}': expected '{2}', '{3}', or '{4}'"; inline constexpr const char *UnknownArtifactEncodingType = - "unknown value '{0}' for field '{1}': expected '{2}', or '{3}'"; + "unknown value '{0}' for field '{1}': expected '{2}', '{3}', or '{4}'"; inline constexpr const char *FailedToDeserializeEntitySummaryNoFormatInfo = "failed to deserialize EntitySummary: no FormatInfo registered for '{0}'"; @@ -149,6 +149,9 @@ inline constexpr const char *JSONTypeValueTUSummary = "TUSummary"; /// Value written to \c JSONTypeKey for serialized \c LUSummary files. inline constexpr const char *JSONTypeValueLUSummary = "LUSummary"; +/// Value written to \c JSONTypeKey for serialized \c StaticLibrary files. +inline constexpr const char *JSONTypeValueStaticLibrary = "StaticLibrary"; + /// Value written to \c JSONTypeKey for serialized \c WPASuite files. inline constexpr const char *JSONTypeValueWPASuite = "WPASuite"; diff --git a/clang/lib/ScalableStaticAnalysis/Core/Serialization/JSONFormat/StaticLibrary.cpp b/clang/lib/ScalableStaticAnalysis/Core/Serialization/JSONFormat/StaticLibrary.cpp new file mode 100644 index 0000000000000..b34c63b185b0e --- /dev/null +++ b/clang/lib/ScalableStaticAnalysis/Core/Serialization/JSONFormat/StaticLibrary.cpp @@ -0,0 +1,192 @@ +//===- StaticLibrary.cpp --------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "JSONFormatImpl.h" + +#include "clang/ScalableStaticAnalysis/Core/EntityLinker/StaticLibrary.h" +#include "clang/ScalableStaticAnalysis/Core/EntityLinker/TUSummaryEncoding.h" +#include "llvm/TargetParser/Triple.h" + +namespace clang::ssaf { + +//---------------------------------------------------------------------------- +// StaticLibrary +//---------------------------------------------------------------------------- + +llvm::Expected<StaticLibrary> +JSONFormat::readStaticLibrary(llvm::StringRef Path) { + auto ExpectedJSON = readJSON(Path); + if (!ExpectedJSON) { + return ErrorBuilder::wrap(ExpectedJSON.takeError()) + .context(ErrorMessages::ReadingFromFile, "StaticLibrary", Path) + .build(); + } + + Object *RootObjectPtr = ExpectedJSON->getAsObject(); + if (!RootObjectPtr) { + return ErrorBuilder::create(std::errc::invalid_argument, + ErrorMessages::FailedToReadObject, + "StaticLibrary", "object") + .context(ErrorMessages::ReadingFromFile, "StaticLibrary", Path) + .build(); + } + + if (auto Err = checkSummaryType(*RootObjectPtr, JSONTypeValueStaticLibrary)) { + return ErrorBuilder::wrap(std::move(Err)) + .context(ErrorMessages::ReadingFromFile, "StaticLibrary", Path) + .build(); + } + + auto ExpectedStaticLibrary = readStaticLibraryFromObject(*RootObjectPtr); + if (!ExpectedStaticLibrary) { + return ErrorBuilder::wrap(ExpectedStaticLibrary.takeError()) + .context(ErrorMessages::ReadingFromFile, "StaticLibrary", Path) + .build(); + } + + return std::move(*ExpectedStaticLibrary); +} + +llvm::Expected<StaticLibrary> +JSONFormat::readStaticLibraryFromObject(const Object &RootObject) { + auto OptTargetTriple = RootObject.getString("target_triple"); + if (!OptTargetTriple) { + return ErrorBuilder::create(std::errc::invalid_argument, + ErrorMessages::FailedToReadObjectAtField, + "TargetTriple", "target_triple", "string") + .build(); + } + + if (auto Err = validateNormalizedTargetTriple(*OptTargetTriple)) { + return ErrorBuilder::wrap(std::move(Err)) + .context(ErrorMessages::ReadingFromField, "TargetTriple", + "target_triple") + .build(); + } + + llvm::Triple T(*OptTargetTriple); + + const Object *NamespaceObject = RootObject.getObject("namespace"); + if (!NamespaceObject) { + return ErrorBuilder::create(std::errc::invalid_argument, + ErrorMessages::FailedToReadObjectAtField, + "BuildNamespace", "namespace", "object") + .build(); + } + + auto ExpectedNamespace = buildNamespaceFromJSON(*NamespaceObject); + if (!ExpectedNamespace) { + return ErrorBuilder::wrap(ExpectedNamespace.takeError()) + .context(ErrorMessages::ReadingFromField, "BuildNamespace", "namespace") + .build(); + } + + if (getKind(*ExpectedNamespace) != BuildNamespaceKind::StaticLibrary) { + return ErrorBuilder::create( + std::errc::invalid_argument, + ErrorMessages::MismatchedSummaryType, + buildNamespaceKindToJSON(BuildNamespaceKind::StaticLibrary), + "namespace.kind", + buildNamespaceKindToJSON(getKind(*ExpectedNamespace))) + .build(); + } + + StaticLibrary S(std::move(T), std::move(*ExpectedNamespace)); + + const Array *MembersArray = RootObject.getArray("members"); + if (!MembersArray) { + return ErrorBuilder::create(std::errc::invalid_argument, + ErrorMessages::FailedToReadObjectAtField, + "StaticLibrary members", "members", "array") + .build(); + } + + auto &Members = getMembers(S); + const auto &StaticLibraryTriple = getTargetTriple(S); + + for (const auto &[Index, MemberValue] : llvm::enumerate(*MembersArray)) { + const Object *MemberObject = MemberValue.getAsObject(); + if (!MemberObject) { + return ErrorBuilder::create(std::errc::invalid_argument, + ErrorMessages::FailedToReadObjectAtIndex, + "StaticLibrary member", Index, "object") + .build(); + } + + if (auto Err = checkSummaryType(*MemberObject, JSONTypeValueTUSummary)) { + return ErrorBuilder::wrap(std::move(Err)) + .context(ErrorMessages::ReadingFromIndex, "StaticLibrary member", + Index) + .build(); + } + + auto ExpectedMember = readTUSummaryEncodingFromObject(*MemberObject); + if (!ExpectedMember) { + return ErrorBuilder::wrap(ExpectedMember.takeError()) + .context(ErrorMessages::ReadingFromIndex, "StaticLibrary member", + Index) + .build(); + } + + if (ExpectedMember->getTargetTriple() != StaticLibraryTriple) { + ... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/205946 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
