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

Reply via email to