clang 23.0.0git
MultiArchStaticLibrary.cpp
Go to the documentation of this file.
1//===- MultiArchStaticLibrary.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// MultiArchStaticLibrary
19//----------------------------------------------------------------------------
20
21llvm::Expected<MultiArchStaticLibrary>
23 auto ExpectedJSON = readJSON(Path);
24 if (!ExpectedJSON) {
25 return ErrorBuilder::wrap(ExpectedJSON.takeError())
26 .context(ErrorMessages::ReadingFromFile, "MultiArchStaticLibrary", Path)
27 .build();
28 }
29
30 Object *RootObjectPtr = ExpectedJSON->getAsObject();
31 if (!RootObjectPtr) {
32 return ErrorBuilder::create(std::errc::invalid_argument,
34 "MultiArchStaticLibrary", "object")
35 .context(ErrorMessages::ReadingFromFile, "MultiArchStaticLibrary", Path)
36 .build();
37 }
38
39 if (auto Err = checkSummaryType(*RootObjectPtr,
41 return ErrorBuilder::wrap(std::move(Err))
42 .context(ErrorMessages::ReadingFromFile, "MultiArchStaticLibrary", Path)
43 .build();
44 }
45
46 auto ExpectedM = readMultiArchStaticLibraryFromObject(*RootObjectPtr);
47 if (!ExpectedM) {
48 return ErrorBuilder::wrap(ExpectedM.takeError())
49 .context(ErrorMessages::ReadingFromFile, "MultiArchStaticLibrary", Path)
50 .build();
51 }
52
53 return std::move(*ExpectedM);
54}
55
57JSONFormat::readMultiArchStaticLibraryFromObject(const Object &RootObject) {
58 const Object *NamespaceObject = RootObject.getObject("namespace");
59 if (!NamespaceObject) {
60 return ErrorBuilder::create(std::errc::invalid_argument,
62 "BuildNamespace", "namespace", "object")
63 .build();
64 }
65
66 auto ExpectedNamespace = buildNamespaceFromJSON(*NamespaceObject);
67 if (!ExpectedNamespace) {
68 return ErrorBuilder::wrap(ExpectedNamespace.takeError())
69 .context(ErrorMessages::ReadingFromField, "BuildNamespace", "namespace")
70 .build();
71 }
72
73 if (getKind(*ExpectedNamespace) !=
76 std::errc::invalid_argument,
80 "namespace.kind",
81 buildNamespaceKindToJSON(getKind(*ExpectedNamespace)))
82 .build();
83 }
84
85 const Array *MembersArray = RootObject.getArray("members");
86 if (!MembersArray) {
87 return ErrorBuilder::create(std::errc::invalid_argument,
89 "MultiArchStaticLibrary members", "members",
90 "array")
91 .build();
92 }
93
94 MultiArchStaticLibrary M(std::move(*ExpectedNamespace));
95 auto &Members = getMembers(M);
96 const auto &ExpectedName = getName(getNamespace(M));
97
98 for (const auto &[Index, MemberValue] : llvm::enumerate(*MembersArray)) {
99 const Object *MemberObject = MemberValue.getAsObject();
100 if (!MemberObject) {
101 return ErrorBuilder::create(std::errc::invalid_argument,
103 "MultiArchStaticLibrary member", Index,
104 "object")
105 .build();
106 }
107
108 if (auto Err =
110 return ErrorBuilder::wrap(std::move(Err))
112 "MultiArchStaticLibrary member", Index)
113 .build();
114 }
115
116 auto ExpectedMember = readStaticLibraryFromObject(*MemberObject);
117 if (!ExpectedMember) {
118 return ErrorBuilder::wrap(ExpectedMember.takeError())
120 "MultiArchStaticLibrary member", Index)
121 .build();
122 }
123
124 const auto &MemberName = getName(getNamespace(*ExpectedMember));
125 if (MemberName != ExpectedName) {
126 return ErrorBuilder::create(std::errc::invalid_argument,
128 ExpectedName, "namespace.name", MemberName)
130 "MultiArchStaticLibrary member", Index)
131 .build();
132 }
133
134 auto [It, Inserted] = Members.insert(
135 std::make_unique<StaticLibrary>(std::move(*ExpectedMember)));
136 if (!Inserted) {
137 auto MemberTriple = llvm::Triple::normalize(getTargetTriple(**It).str());
138 return ErrorBuilder::create(std::errc::invalid_argument,
140 "MultiArchStaticLibrary member", Index,
141 MemberTriple)
142 .build();
143 }
144 }
145
146 return std::move(M);
147}
148
149llvm::Error
151 llvm::StringRef Path) {
152 Object RootObject;
153
155
156 RootObject["namespace"] = buildNamespaceToJSON(getNamespace(M));
157
158 Array MembersArray;
159 MembersArray.reserve(getMembers(M).size());
160 for (const auto &Member : getMembers(M)) {
161 MembersArray.push_back(staticLibraryToJSON(*Member));
162 }
163 RootObject["members"] = std::move(MembersArray);
164
165 if (auto Error = writeJSON(std::move(RootObject), Path)) {
166 return ErrorBuilder::wrap(std::move(Error))
167 .context(ErrorMessages::WritingToFile, "MultiArchStaticLibrary", Path)
168 .build();
169 }
170
171 return llvm::Error::success();
172}
173
174} // namespace clang::ssaf
static Decl::Kind getKind(const Decl *D)
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< MultiArchStaticLibrary > readMultiArchStaticLibrary(llvm::StringRef Path) override
llvm::Error writeMultiArchStaticLibrary(const MultiArchStaticLibrary &M, llvm::StringRef Path) override
Represents a multi-architecture static library.
StringRef getName(const HeaderType T)
Definition HeaderFile.h:38
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 * JSONTypeValueStaticLibrary
Value written to JSONTypeKey for serialized StaticLibrary files.
llvm::json::Object Object
llvm::Expected< Value > readJSON(llvm::StringRef Path)
constexpr const char * JSONTypeValueMultiArchStaticLibrary
Value written to JSONTypeKey for serialized MultiArchStaticLibrary files.
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)
llvm::Expected< DeclarationName > ExpectedName