clang 23.0.0git
StaticLibrary.cpp
Go to the documentation of this file.
1//===- StaticLibrary.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
13#include "llvm/TargetParser/Triple.h"
14
15namespace clang::ssaf {
16
17//----------------------------------------------------------------------------
18// StaticLibrary
19//----------------------------------------------------------------------------
20
21llvm::Expected<StaticLibrary>
22JSONFormat::readStaticLibrary(llvm::StringRef Path) {
23 auto ExpectedJSON = readJSON(Path);
24 if (!ExpectedJSON) {
25 return ErrorBuilder::wrap(ExpectedJSON.takeError())
26 .context(ErrorMessages::ReadingFromFile, "StaticLibrary", Path)
27 .build();
28 }
29
30 Object *RootObjectPtr = ExpectedJSON->getAsObject();
31 if (!RootObjectPtr) {
32 return ErrorBuilder::create(std::errc::invalid_argument,
34 "StaticLibrary", "object")
35 .context(ErrorMessages::ReadingFromFile, "StaticLibrary", Path)
36 .build();
37 }
38
39 if (auto Err = checkSummaryType(*RootObjectPtr, JSONTypeValueStaticLibrary)) {
40 return ErrorBuilder::wrap(std::move(Err))
41 .context(ErrorMessages::ReadingFromFile, "StaticLibrary", Path)
42 .build();
43 }
44
45 auto ExpectedStaticLibrary = readStaticLibraryFromObject(*RootObjectPtr);
46 if (!ExpectedStaticLibrary) {
47 return ErrorBuilder::wrap(ExpectedStaticLibrary.takeError())
48 .context(ErrorMessages::ReadingFromFile, "StaticLibrary", Path)
49 .build();
50 }
51
52 return std::move(*ExpectedStaticLibrary);
53}
54
56JSONFormat::readStaticLibraryFromObject(const Object &RootObject) {
57 auto OptTargetTriple = RootObject.getString("target_triple");
58 if (!OptTargetTriple) {
59 return ErrorBuilder::create(std::errc::invalid_argument,
61 "TargetTriple", "target_triple", "string")
62 .build();
63 }
64
65 if (auto Err = validateNormalizedTargetTriple(*OptTargetTriple)) {
66 return ErrorBuilder::wrap(std::move(Err))
68 "target_triple")
69 .build();
70 }
71
72 llvm::Triple T(*OptTargetTriple);
73
74 const Object *NamespaceObject = RootObject.getObject("namespace");
75 if (!NamespaceObject) {
76 return ErrorBuilder::create(std::errc::invalid_argument,
78 "BuildNamespace", "namespace", "object")
79 .build();
80 }
81
82 auto ExpectedNamespace = buildNamespaceFromJSON(*NamespaceObject);
83 if (!ExpectedNamespace) {
84 return ErrorBuilder::wrap(ExpectedNamespace.takeError())
85 .context(ErrorMessages::ReadingFromField, "BuildNamespace", "namespace")
86 .build();
87 }
88
89 if (getKind(*ExpectedNamespace) != BuildNamespaceKind::StaticLibrary) {
91 std::errc::invalid_argument,
94 "namespace.kind",
95 buildNamespaceKindToJSON(getKind(*ExpectedNamespace)))
96 .build();
97 }
98
99 StaticLibrary S(std::move(T), std::move(*ExpectedNamespace));
100
101 const Array *MembersArray = RootObject.getArray("members");
102 if (!MembersArray) {
103 return ErrorBuilder::create(std::errc::invalid_argument,
105 "StaticLibrary members", "members", "array")
106 .build();
107 }
108
109 auto &Members = getMembers(S);
110 const auto &StaticLibraryTriple = getTargetTriple(S);
111
112 for (const auto &[Index, MemberValue] : llvm::enumerate(*MembersArray)) {
113 const Object *MemberObject = MemberValue.getAsObject();
114 if (!MemberObject) {
115 return ErrorBuilder::create(std::errc::invalid_argument,
117 "StaticLibrary member", Index, "object")
118 .build();
119 }
120
121 if (auto Err = checkSummaryType(*MemberObject, JSONTypeValueTUSummary)) {
122 return ErrorBuilder::wrap(std::move(Err))
123 .context(ErrorMessages::ReadingFromIndex, "StaticLibrary member",
124 Index)
125 .build();
126 }
127
128 auto ExpectedMember = readTUSummaryEncodingFromObject(*MemberObject);
129 if (!ExpectedMember) {
130 return ErrorBuilder::wrap(ExpectedMember.takeError())
131 .context(ErrorMessages::ReadingFromIndex, "StaticLibrary member",
132 Index)
133 .build();
134 }
135
136 if (ExpectedMember->getTargetTriple() != StaticLibraryTriple) {
138 std::errc::invalid_argument,
140 llvm::Triple::normalize(StaticLibraryTriple.str()),
141 "target_triple",
142 llvm::Triple::normalize(
143 ExpectedMember->getTargetTriple().str()))
144 .context(ErrorMessages::ReadingFromIndex, "StaticLibrary member",
145 Index)
146 .build();
147 }
148
149 auto MemberNamespace = getTUNamespace(*ExpectedMember);
150 auto Owned =
151 std::make_unique<TUSummaryEncoding>(std::move(*ExpectedMember));
152 auto [It, Inserted] = Members.insert(std::move(Owned));
153 if (!Inserted) {
154 return ErrorBuilder::create(std::errc::invalid_argument,
156 "StaticLibrary member", Index,
157 MemberNamespace)
158 .build();
159 }
160 }
161
162 return std::move(S);
163}
164
166 llvm::StringRef Path) {
167 Object RootObject;
168
170
171 RootObject["target_triple"] =
172 llvm::Triple::normalize(getTargetTriple(S).str());
173
174 RootObject["namespace"] = buildNamespaceToJSON(getNamespace(S));
175
176 Array MembersArray;
177 MembersArray.reserve(getMembers(S).size());
178 for (const auto &Member : getMembers(S)) {
179 MembersArray.push_back(tuSummaryEncodingToJSON(*Member));
180 }
181 RootObject["members"] = std::move(MembersArray);
182
183 if (auto Error = writeJSON(std::move(RootObject), Path)) {
184 return ErrorBuilder::wrap(std::move(Error))
185 .context(ErrorMessages::WritingToFile, "StaticLibrary", Path)
186 .build();
187 }
188
189 return llvm::Error::success();
190}
191
192} // namespace clang::ssaf
static Decl::Kind getKind(const Decl *D)
llvm::json::Object Object
static ErrorBuilder create(std::error_code EC, const char *Fmt, Args &&...ArgVals)
Create an ErrorBuilder with an error code and formatted message.
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.
llvm::Expected< StaticLibrary > readStaticLibrary(llvm::StringRef Path) override
llvm::Error writeStaticLibrary(const StaticLibrary &S, llvm::StringRef Path) override
Represents a static library of translation unit summary encodings.
constexpr const char * ReadingFromFile
constexpr const char * ReadingFromField
constexpr const char * MismatchedSummaryType
constexpr const char * FailedToReadObjectAtIndex
constexpr const char * FailedToReadObjectAtField
constexpr const char * WritingToFile
constexpr const char * ReadingFromIndex
constexpr const char * FailedInsertionOnDuplication
constexpr const char * FailedToReadObject
constexpr const char * JSONTypeKey
Root-object key naming the summary kind so files are self-describing.
constexpr const char * JSONTypeValueTUSummary
Value written to JSONTypeKey for serialized TUSummary files.
llvm::Error validateNormalizedTargetTriple(llvm::StringRef Triple)
Validates that Triple is a target triple string in normalized form.
constexpr const char * JSONTypeValueStaticLibrary
Value written to JSONTypeKey for serialized StaticLibrary files.
llvm::json::Object Object
llvm::Expected< Value > readJSON(llvm::StringRef Path)
llvm::Error checkSummaryType(const Object &RootObject, llvm::StringRef ExpectedType)
Reads the JSONTypeKey field from the root object and verifies it equals ExpectedType.
llvm::StringRef buildNamespaceKindToJSON(BuildNamespaceKind BNK)
llvm::Error writeJSON(Value &&V, llvm::StringRef Path)