1e6d15924SDimitry Andric //===- InterfaceFile.cpp --------------------------------------------------===//
2e6d15924SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e6d15924SDimitry Andric //
7e6d15924SDimitry Andric //===----------------------------------------------------------------------===//
8e6d15924SDimitry Andric //
9e6d15924SDimitry Andric // Implements the Interface File.
10e6d15924SDimitry Andric //
11e6d15924SDimitry Andric //===----------------------------------------------------------------------===//
12e6d15924SDimitry Andric
13344a3780SDimitry Andric #include "llvm/TextAPI/InterfaceFile.h"
14ac9a064cSDimitry Andric #include "llvm/TextAPI/RecordsSlice.h"
15b1c73532SDimitry Andric #include "llvm/TextAPI/TextAPIError.h"
16e6d15924SDimitry Andric #include <iomanip>
17e6d15924SDimitry Andric #include <sstream>
18e6d15924SDimitry Andric
19cfca06d7SDimitry Andric using namespace llvm;
20cfca06d7SDimitry Andric using namespace llvm::MachO;
21cfca06d7SDimitry Andric
addTarget(const Target & Target)221d5ae102SDimitry Andric void InterfaceFileRef::addTarget(const Target &Target) {
23cfca06d7SDimitry Andric addEntry(Targets, Target);
241d5ae102SDimitry Andric }
251d5ae102SDimitry Andric
addAllowableClient(StringRef InstallName,const Target & Target)261d5ae102SDimitry Andric void InterfaceFile::addAllowableClient(StringRef InstallName,
271d5ae102SDimitry Andric const Target &Target) {
28950076cdSDimitry Andric if (InstallName.empty())
29950076cdSDimitry Andric return;
30cfca06d7SDimitry Andric auto Client = addEntry(AllowableClients, InstallName);
311d5ae102SDimitry Andric Client->addTarget(Target);
32e6d15924SDimitry Andric }
33e6d15924SDimitry Andric
addReexportedLibrary(StringRef InstallName,const Target & Target)34e6d15924SDimitry Andric void InterfaceFile::addReexportedLibrary(StringRef InstallName,
351d5ae102SDimitry Andric const Target &Target) {
36950076cdSDimitry Andric if (InstallName.empty())
37950076cdSDimitry Andric return;
38cfca06d7SDimitry Andric auto Lib = addEntry(ReexportedLibraries, InstallName);
391d5ae102SDimitry Andric Lib->addTarget(Target);
40e6d15924SDimitry Andric }
41e6d15924SDimitry Andric
addParentUmbrella(const Target & Target_,StringRef Parent)421d5ae102SDimitry Andric void InterfaceFile::addParentUmbrella(const Target &Target_, StringRef Parent) {
43950076cdSDimitry Andric if (Parent.empty())
44950076cdSDimitry Andric return;
451d5ae102SDimitry Andric auto Iter = lower_bound(ParentUmbrellas, Target_,
461d5ae102SDimitry Andric [](const std::pair<Target, std::string> &LHS,
471d5ae102SDimitry Andric Target RHS) { return LHS.first < RHS; });
48e6d15924SDimitry Andric
491d5ae102SDimitry Andric if ((Iter != ParentUmbrellas.end()) && !(Target_ < Iter->first)) {
50cfca06d7SDimitry Andric Iter->second = std::string(Parent);
51e6d15924SDimitry Andric return;
52e6d15924SDimitry Andric }
53e6d15924SDimitry Andric
54cfca06d7SDimitry Andric ParentUmbrellas.emplace(Iter, Target_, std::string(Parent));
55e6d15924SDimitry Andric }
56e6d15924SDimitry Andric
addRPath(StringRef RPath,const Target & InputTarget)57ac9a064cSDimitry Andric void InterfaceFile::addRPath(StringRef RPath, const Target &InputTarget) {
58950076cdSDimitry Andric if (RPath.empty())
59950076cdSDimitry Andric return;
60b1c73532SDimitry Andric using RPathEntryT = const std::pair<Target, std::string>;
61b1c73532SDimitry Andric RPathEntryT Entry(InputTarget, RPath);
62b1c73532SDimitry Andric auto Iter =
63b1c73532SDimitry Andric lower_bound(RPaths, Entry,
64b1c73532SDimitry Andric [](RPathEntryT &LHS, RPathEntryT &RHS) { return LHS < RHS; });
651d5ae102SDimitry Andric
66b1c73532SDimitry Andric if ((Iter != RPaths.end()) && (*Iter == Entry))
671d5ae102SDimitry Andric return;
681d5ae102SDimitry Andric
69b1c73532SDimitry Andric RPaths.emplace(Iter, Entry);
701d5ae102SDimitry Andric }
711d5ae102SDimitry Andric
addTarget(const Target & Target)721d5ae102SDimitry Andric void InterfaceFile::addTarget(const Target &Target) {
73cfca06d7SDimitry Andric addEntry(Targets, Target);
741d5ae102SDimitry Andric }
751d5ae102SDimitry Andric
761d5ae102SDimitry Andric InterfaceFile::const_filtered_target_range
targets(ArchitectureSet Archs) const771d5ae102SDimitry Andric InterfaceFile::targets(ArchitectureSet Archs) const {
781d5ae102SDimitry Andric std::function<bool(const Target &)> fn = [Archs](const Target &Target_) {
791d5ae102SDimitry Andric return Archs.has(Target_.Arch);
801d5ae102SDimitry Andric };
811d5ae102SDimitry Andric return make_filter_range(Targets, fn);
82e6d15924SDimitry Andric }
83e6d15924SDimitry Andric
addDocument(std::shared_ptr<InterfaceFile> && Document)84344a3780SDimitry Andric void InterfaceFile::addDocument(std::shared_ptr<InterfaceFile> &&Document) {
85344a3780SDimitry Andric auto Pos = llvm::lower_bound(Documents, Document,
86344a3780SDimitry Andric [](const std::shared_ptr<InterfaceFile> &LHS,
87344a3780SDimitry Andric const std::shared_ptr<InterfaceFile> &RHS) {
88344a3780SDimitry Andric return LHS->InstallName < RHS->InstallName;
89344a3780SDimitry Andric });
90344a3780SDimitry Andric Document->Parent = this;
91344a3780SDimitry Andric Documents.insert(Pos, Document);
92344a3780SDimitry Andric }
93344a3780SDimitry Andric
inlineLibrary(std::shared_ptr<InterfaceFile> Library,bool Overwrite)94b1c73532SDimitry Andric void InterfaceFile::inlineLibrary(std::shared_ptr<InterfaceFile> Library,
95b1c73532SDimitry Andric bool Overwrite) {
96b1c73532SDimitry Andric auto AddFwk = [&](std::shared_ptr<InterfaceFile> &&Reexport) {
97b1c73532SDimitry Andric auto It = lower_bound(
98b1c73532SDimitry Andric Documents, Reexport->getInstallName(),
99b1c73532SDimitry Andric [](std::shared_ptr<InterfaceFile> &Lhs, const StringRef Rhs) {
100b1c73532SDimitry Andric return Lhs->getInstallName() < Rhs;
101b1c73532SDimitry Andric });
102b1c73532SDimitry Andric
103b1c73532SDimitry Andric if (Overwrite && It != Documents.end() &&
104b1c73532SDimitry Andric Reexport->getInstallName() == (*It)->getInstallName()) {
105b1c73532SDimitry Andric std::replace(Documents.begin(), Documents.end(), *It,
106b1c73532SDimitry Andric std::move(Reexport));
107b1c73532SDimitry Andric return;
108b1c73532SDimitry Andric }
109b1c73532SDimitry Andric
110b1c73532SDimitry Andric if ((It != Documents.end()) &&
111b1c73532SDimitry Andric !(Reexport->getInstallName() < (*It)->getInstallName()))
112b1c73532SDimitry Andric return;
113b1c73532SDimitry Andric
114b1c73532SDimitry Andric Documents.emplace(It, std::move(Reexport));
115b1c73532SDimitry Andric };
116b1c73532SDimitry Andric for (auto Doc : Library->documents())
117b1c73532SDimitry Andric AddFwk(std::move(Doc));
118b1c73532SDimitry Andric
119b1c73532SDimitry Andric Library->Documents.clear();
120b1c73532SDimitry Andric AddFwk(std::move(Library));
121b1c73532SDimitry Andric }
122b1c73532SDimitry Andric
123b1c73532SDimitry Andric Expected<std::unique_ptr<InterfaceFile>>
merge(const InterfaceFile * O) const124b1c73532SDimitry Andric InterfaceFile::merge(const InterfaceFile *O) const {
125b1c73532SDimitry Andric // Verify files can be merged.
126b1c73532SDimitry Andric if (getInstallName() != O->getInstallName()) {
127b1c73532SDimitry Andric return make_error<StringError>("install names do not match",
128b1c73532SDimitry Andric inconvertibleErrorCode());
129b1c73532SDimitry Andric }
130b1c73532SDimitry Andric
131b1c73532SDimitry Andric if (getCurrentVersion() != O->getCurrentVersion()) {
132b1c73532SDimitry Andric return make_error<StringError>("current versions do not match",
133b1c73532SDimitry Andric inconvertibleErrorCode());
134b1c73532SDimitry Andric }
135b1c73532SDimitry Andric
136b1c73532SDimitry Andric if (getCompatibilityVersion() != O->getCompatibilityVersion()) {
137b1c73532SDimitry Andric return make_error<StringError>("compatibility versions do not match",
138b1c73532SDimitry Andric inconvertibleErrorCode());
139b1c73532SDimitry Andric }
140b1c73532SDimitry Andric
141b1c73532SDimitry Andric if ((getSwiftABIVersion() != 0) && (O->getSwiftABIVersion() != 0) &&
142b1c73532SDimitry Andric (getSwiftABIVersion() != O->getSwiftABIVersion())) {
143b1c73532SDimitry Andric return make_error<StringError>("swift ABI versions do not match",
144b1c73532SDimitry Andric inconvertibleErrorCode());
145b1c73532SDimitry Andric }
146b1c73532SDimitry Andric
147b1c73532SDimitry Andric if (isTwoLevelNamespace() != O->isTwoLevelNamespace()) {
148b1c73532SDimitry Andric return make_error<StringError>("two level namespace flags do not match",
149b1c73532SDimitry Andric inconvertibleErrorCode());
150b1c73532SDimitry Andric }
151b1c73532SDimitry Andric
152b1c73532SDimitry Andric if (isApplicationExtensionSafe() != O->isApplicationExtensionSafe()) {
153b1c73532SDimitry Andric return make_error<StringError>(
154b1c73532SDimitry Andric "application extension safe flags do not match",
155b1c73532SDimitry Andric inconvertibleErrorCode());
156b1c73532SDimitry Andric }
157b1c73532SDimitry Andric
158b1c73532SDimitry Andric std::unique_ptr<InterfaceFile> IF(new InterfaceFile());
159b1c73532SDimitry Andric IF->setFileType(std::max(getFileType(), O->getFileType()));
160b1c73532SDimitry Andric IF->setPath(getPath());
161b1c73532SDimitry Andric IF->setInstallName(getInstallName());
162b1c73532SDimitry Andric IF->setCurrentVersion(getCurrentVersion());
163b1c73532SDimitry Andric IF->setCompatibilityVersion(getCompatibilityVersion());
164b1c73532SDimitry Andric
165b1c73532SDimitry Andric if (getSwiftABIVersion() == 0)
166b1c73532SDimitry Andric IF->setSwiftABIVersion(O->getSwiftABIVersion());
167b1c73532SDimitry Andric else
168b1c73532SDimitry Andric IF->setSwiftABIVersion(getSwiftABIVersion());
169b1c73532SDimitry Andric
170b1c73532SDimitry Andric IF->setTwoLevelNamespace(isTwoLevelNamespace());
171b1c73532SDimitry Andric IF->setApplicationExtensionSafe(isApplicationExtensionSafe());
172b1c73532SDimitry Andric
173b1c73532SDimitry Andric for (const auto &It : umbrellas()) {
174b1c73532SDimitry Andric if (!It.second.empty())
175b1c73532SDimitry Andric IF->addParentUmbrella(It.first, It.second);
176b1c73532SDimitry Andric }
177b1c73532SDimitry Andric for (const auto &It : O->umbrellas()) {
178b1c73532SDimitry Andric if (!It.second.empty())
179b1c73532SDimitry Andric IF->addParentUmbrella(It.first, It.second);
180b1c73532SDimitry Andric }
181b1c73532SDimitry Andric IF->addTargets(targets());
182b1c73532SDimitry Andric IF->addTargets(O->targets());
183b1c73532SDimitry Andric
184b1c73532SDimitry Andric for (const auto &Lib : allowableClients())
185b1c73532SDimitry Andric for (const auto &Target : Lib.targets())
186b1c73532SDimitry Andric IF->addAllowableClient(Lib.getInstallName(), Target);
187b1c73532SDimitry Andric
188b1c73532SDimitry Andric for (const auto &Lib : O->allowableClients())
189b1c73532SDimitry Andric for (const auto &Target : Lib.targets())
190b1c73532SDimitry Andric IF->addAllowableClient(Lib.getInstallName(), Target);
191b1c73532SDimitry Andric
192b1c73532SDimitry Andric for (const auto &Lib : reexportedLibraries())
193b1c73532SDimitry Andric for (const auto &Target : Lib.targets())
194b1c73532SDimitry Andric IF->addReexportedLibrary(Lib.getInstallName(), Target);
195b1c73532SDimitry Andric
196b1c73532SDimitry Andric for (const auto &Lib : O->reexportedLibraries())
197b1c73532SDimitry Andric for (const auto &Target : Lib.targets())
198b1c73532SDimitry Andric IF->addReexportedLibrary(Lib.getInstallName(), Target);
199b1c73532SDimitry Andric
200b1c73532SDimitry Andric for (const auto &[Target, Path] : rpaths())
201ac9a064cSDimitry Andric IF->addRPath(Path, Target);
202b1c73532SDimitry Andric for (const auto &[Target, Path] : O->rpaths())
203ac9a064cSDimitry Andric IF->addRPath(Path, Target);
204b1c73532SDimitry Andric
205b1c73532SDimitry Andric for (const auto *Sym : symbols()) {
206b1c73532SDimitry Andric IF->addSymbol(Sym->getKind(), Sym->getName(), Sym->targets(),
207b1c73532SDimitry Andric Sym->getFlags());
208b1c73532SDimitry Andric }
209b1c73532SDimitry Andric
210b1c73532SDimitry Andric for (const auto *Sym : O->symbols()) {
211b1c73532SDimitry Andric IF->addSymbol(Sym->getKind(), Sym->getName(), Sym->targets(),
212b1c73532SDimitry Andric Sym->getFlags());
213b1c73532SDimitry Andric }
214b1c73532SDimitry Andric
215b1c73532SDimitry Andric return std::move(IF);
216b1c73532SDimitry Andric }
217b1c73532SDimitry Andric
218b1c73532SDimitry Andric Expected<std::unique_ptr<InterfaceFile>>
remove(Architecture Arch) const219b1c73532SDimitry Andric InterfaceFile::remove(Architecture Arch) const {
220b1c73532SDimitry Andric if (getArchitectures() == Arch)
221b1c73532SDimitry Andric return make_error<StringError>("cannot remove last architecture slice '" +
222b1c73532SDimitry Andric getArchitectureName(Arch) + "'",
223b1c73532SDimitry Andric inconvertibleErrorCode());
224b1c73532SDimitry Andric
225b1c73532SDimitry Andric if (!getArchitectures().has(Arch)) {
226b1c73532SDimitry Andric bool Found = false;
227b1c73532SDimitry Andric for (auto &Doc : Documents) {
228b1c73532SDimitry Andric if (Doc->getArchitectures().has(Arch)) {
229b1c73532SDimitry Andric Found = true;
230b1c73532SDimitry Andric break;
231b1c73532SDimitry Andric }
232b1c73532SDimitry Andric }
233b1c73532SDimitry Andric
234b1c73532SDimitry Andric if (!Found)
235b1c73532SDimitry Andric return make_error<TextAPIError>(TextAPIErrorCode::NoSuchArchitecture);
236b1c73532SDimitry Andric }
237b1c73532SDimitry Andric
238b1c73532SDimitry Andric std::unique_ptr<InterfaceFile> IF(new InterfaceFile());
239b1c73532SDimitry Andric IF->setFileType(getFileType());
240b1c73532SDimitry Andric IF->setPath(getPath());
241b1c73532SDimitry Andric IF->addTargets(targets(ArchitectureSet::All().clear(Arch)));
242b1c73532SDimitry Andric IF->setInstallName(getInstallName());
243b1c73532SDimitry Andric IF->setCurrentVersion(getCurrentVersion());
244b1c73532SDimitry Andric IF->setCompatibilityVersion(getCompatibilityVersion());
245b1c73532SDimitry Andric IF->setSwiftABIVersion(getSwiftABIVersion());
246b1c73532SDimitry Andric IF->setTwoLevelNamespace(isTwoLevelNamespace());
247b1c73532SDimitry Andric IF->setApplicationExtensionSafe(isApplicationExtensionSafe());
248b1c73532SDimitry Andric for (const auto &It : umbrellas())
249b1c73532SDimitry Andric if (It.first.Arch != Arch)
250b1c73532SDimitry Andric IF->addParentUmbrella(It.first, It.second);
251b1c73532SDimitry Andric
252b1c73532SDimitry Andric for (const auto &Lib : allowableClients()) {
253b1c73532SDimitry Andric for (const auto &Target : Lib.targets())
254b1c73532SDimitry Andric if (Target.Arch != Arch)
255b1c73532SDimitry Andric IF->addAllowableClient(Lib.getInstallName(), Target);
256b1c73532SDimitry Andric }
257b1c73532SDimitry Andric
258b1c73532SDimitry Andric for (const auto &Lib : reexportedLibraries()) {
259b1c73532SDimitry Andric for (const auto &Target : Lib.targets())
260b1c73532SDimitry Andric if (Target.Arch != Arch)
261b1c73532SDimitry Andric IF->addReexportedLibrary(Lib.getInstallName(), Target);
262b1c73532SDimitry Andric }
263b1c73532SDimitry Andric
264b1c73532SDimitry Andric for (const auto *Sym : symbols()) {
265b1c73532SDimitry Andric auto Archs = Sym->getArchitectures();
266b1c73532SDimitry Andric Archs.clear(Arch);
267b1c73532SDimitry Andric if (Archs.empty())
268b1c73532SDimitry Andric continue;
269b1c73532SDimitry Andric
270b1c73532SDimitry Andric IF->addSymbol(Sym->getKind(), Sym->getName(), Sym->targets(Archs),
271b1c73532SDimitry Andric Sym->getFlags());
272b1c73532SDimitry Andric }
273b1c73532SDimitry Andric
274b1c73532SDimitry Andric for (auto &Doc : Documents) {
275b1c73532SDimitry Andric // Skip the inlined document if the to be removed architecture is the
276b1c73532SDimitry Andric // only one left.
277b1c73532SDimitry Andric if (Doc->getArchitectures() == Arch)
278b1c73532SDimitry Andric continue;
279b1c73532SDimitry Andric
280b1c73532SDimitry Andric // If the document doesn't contain the arch, then no work is to be done
281b1c73532SDimitry Andric // and it can be copied over.
282b1c73532SDimitry Andric if (!Doc->getArchitectures().has(Arch)) {
283b1c73532SDimitry Andric auto NewDoc = Doc;
284b1c73532SDimitry Andric IF->addDocument(std::move(NewDoc));
285b1c73532SDimitry Andric continue;
286b1c73532SDimitry Andric }
287b1c73532SDimitry Andric
288b1c73532SDimitry Andric auto Result = Doc->remove(Arch);
289b1c73532SDimitry Andric if (!Result)
290b1c73532SDimitry Andric return Result;
291b1c73532SDimitry Andric
292b1c73532SDimitry Andric IF->addDocument(std::move(Result.get()));
293b1c73532SDimitry Andric }
294b1c73532SDimitry Andric
295b1c73532SDimitry Andric return std::move(IF);
296b1c73532SDimitry Andric }
297b1c73532SDimitry Andric
298b1c73532SDimitry Andric Expected<std::unique_ptr<InterfaceFile>>
extract(Architecture Arch) const299b1c73532SDimitry Andric InterfaceFile::extract(Architecture Arch) const {
300b1c73532SDimitry Andric if (!getArchitectures().has(Arch)) {
301b1c73532SDimitry Andric return make_error<StringError>("file doesn't have architecture '" +
302b1c73532SDimitry Andric getArchitectureName(Arch) + "'",
303b1c73532SDimitry Andric inconvertibleErrorCode());
304b1c73532SDimitry Andric }
305b1c73532SDimitry Andric
306b1c73532SDimitry Andric std::unique_ptr<InterfaceFile> IF(new InterfaceFile());
307b1c73532SDimitry Andric IF->setFileType(getFileType());
308b1c73532SDimitry Andric IF->setPath(getPath());
309b1c73532SDimitry Andric IF->addTargets(targets(Arch));
310b1c73532SDimitry Andric IF->setInstallName(getInstallName());
311b1c73532SDimitry Andric IF->setCurrentVersion(getCurrentVersion());
312b1c73532SDimitry Andric IF->setCompatibilityVersion(getCompatibilityVersion());
313b1c73532SDimitry Andric IF->setSwiftABIVersion(getSwiftABIVersion());
314b1c73532SDimitry Andric IF->setTwoLevelNamespace(isTwoLevelNamespace());
315b1c73532SDimitry Andric IF->setApplicationExtensionSafe(isApplicationExtensionSafe());
316b1c73532SDimitry Andric for (const auto &It : umbrellas())
317b1c73532SDimitry Andric if (It.first.Arch == Arch)
318b1c73532SDimitry Andric IF->addParentUmbrella(It.first, It.second);
319b1c73532SDimitry Andric
320b1c73532SDimitry Andric for (const auto &It : rpaths())
321b1c73532SDimitry Andric if (It.first.Arch == Arch)
322ac9a064cSDimitry Andric IF->addRPath(It.second, It.first);
323b1c73532SDimitry Andric
324b1c73532SDimitry Andric for (const auto &Lib : allowableClients())
325b1c73532SDimitry Andric for (const auto &Target : Lib.targets())
326b1c73532SDimitry Andric if (Target.Arch == Arch)
327b1c73532SDimitry Andric IF->addAllowableClient(Lib.getInstallName(), Target);
328b1c73532SDimitry Andric
329b1c73532SDimitry Andric for (const auto &Lib : reexportedLibraries())
330b1c73532SDimitry Andric for (const auto &Target : Lib.targets())
331b1c73532SDimitry Andric if (Target.Arch == Arch)
332b1c73532SDimitry Andric IF->addReexportedLibrary(Lib.getInstallName(), Target);
333b1c73532SDimitry Andric
334b1c73532SDimitry Andric for (const auto *Sym : symbols()) {
335b1c73532SDimitry Andric if (Sym->hasArchitecture(Arch))
336b1c73532SDimitry Andric IF->addSymbol(Sym->getKind(), Sym->getName(), Sym->targets(Arch),
337b1c73532SDimitry Andric Sym->getFlags());
338b1c73532SDimitry Andric }
339b1c73532SDimitry Andric
340b1c73532SDimitry Andric for (auto &Doc : Documents) {
341b1c73532SDimitry Andric // Skip documents that don't have the requested architecture.
342b1c73532SDimitry Andric if (!Doc->getArchitectures().has(Arch))
343b1c73532SDimitry Andric continue;
344b1c73532SDimitry Andric
345b1c73532SDimitry Andric auto Result = Doc->extract(Arch);
346b1c73532SDimitry Andric if (!Result)
347b1c73532SDimitry Andric return Result;
348b1c73532SDimitry Andric
349b1c73532SDimitry Andric IF->addDocument(std::move(Result.get()));
350b1c73532SDimitry Andric }
351b1c73532SDimitry Andric
352b1c73532SDimitry Andric return std::move(IF);
353b1c73532SDimitry Andric }
354b1c73532SDimitry Andric
setFromBinaryAttrs(const RecordsSlice::BinaryAttrs & BA,const Target & Targ)355ac9a064cSDimitry Andric void InterfaceFile::setFromBinaryAttrs(const RecordsSlice::BinaryAttrs &BA,
356ac9a064cSDimitry Andric const Target &Targ) {
357ac9a064cSDimitry Andric if (getFileType() != BA.File)
358ac9a064cSDimitry Andric setFileType(BA.File);
359ac9a064cSDimitry Andric if (getInstallName().empty())
360ac9a064cSDimitry Andric setInstallName(BA.InstallName);
361ac9a064cSDimitry Andric if (BA.AppExtensionSafe && !isApplicationExtensionSafe())
362ac9a064cSDimitry Andric setApplicationExtensionSafe();
363ac9a064cSDimitry Andric if (BA.TwoLevelNamespace && !isTwoLevelNamespace())
364ac9a064cSDimitry Andric setTwoLevelNamespace();
365ac9a064cSDimitry Andric if (BA.OSLibNotForSharedCache && !isOSLibNotForSharedCache())
366ac9a064cSDimitry Andric setOSLibNotForSharedCache();
367ac9a064cSDimitry Andric if (getCurrentVersion().empty())
368ac9a064cSDimitry Andric setCurrentVersion(BA.CurrentVersion);
369ac9a064cSDimitry Andric if (getCompatibilityVersion().empty())
370ac9a064cSDimitry Andric setCompatibilityVersion(BA.CompatVersion);
371ac9a064cSDimitry Andric if (getSwiftABIVersion() == 0)
372ac9a064cSDimitry Andric setSwiftABIVersion(BA.SwiftABI);
373ac9a064cSDimitry Andric if (getPath().empty())
374ac9a064cSDimitry Andric setPath(BA.Path);
375ac9a064cSDimitry Andric if (!BA.ParentUmbrella.empty())
376ac9a064cSDimitry Andric addParentUmbrella(Targ, BA.ParentUmbrella);
377ac9a064cSDimitry Andric for (const auto &Client : BA.AllowableClients)
378ac9a064cSDimitry Andric addAllowableClient(Client, Targ);
379ac9a064cSDimitry Andric for (const auto &Lib : BA.RexportedLibraries)
380ac9a064cSDimitry Andric addReexportedLibrary(Lib, Targ);
381ac9a064cSDimitry Andric }
382ac9a064cSDimitry Andric
isYAMLTextStub(const FileType & Kind)3837fa27ce4SDimitry Andric static bool isYAMLTextStub(const FileType &Kind) {
3847fa27ce4SDimitry Andric return (Kind >= FileType::TBD_V1) && (Kind < FileType::TBD_V5);
3857fa27ce4SDimitry Andric }
3867fa27ce4SDimitry Andric
operator ==(const InterfaceFile & O) const387344a3780SDimitry Andric bool InterfaceFile::operator==(const InterfaceFile &O) const {
388344a3780SDimitry Andric if (Targets != O.Targets)
389344a3780SDimitry Andric return false;
390344a3780SDimitry Andric if (InstallName != O.InstallName)
391344a3780SDimitry Andric return false;
392344a3780SDimitry Andric if ((CurrentVersion != O.CurrentVersion) ||
393344a3780SDimitry Andric (CompatibilityVersion != O.CompatibilityVersion))
394344a3780SDimitry Andric return false;
395344a3780SDimitry Andric if (SwiftABIVersion != O.SwiftABIVersion)
396344a3780SDimitry Andric return false;
397344a3780SDimitry Andric if (IsTwoLevelNamespace != O.IsTwoLevelNamespace)
398344a3780SDimitry Andric return false;
399344a3780SDimitry Andric if (IsAppExtensionSafe != O.IsAppExtensionSafe)
400344a3780SDimitry Andric return false;
401b1c73532SDimitry Andric if (IsOSLibNotForSharedCache != O.IsOSLibNotForSharedCache)
402b1c73532SDimitry Andric return false;
403b1c73532SDimitry Andric if (HasSimSupport != O.HasSimSupport)
404b1c73532SDimitry Andric return false;
405344a3780SDimitry Andric if (ParentUmbrellas != O.ParentUmbrellas)
406344a3780SDimitry Andric return false;
407344a3780SDimitry Andric if (AllowableClients != O.AllowableClients)
408344a3780SDimitry Andric return false;
409344a3780SDimitry Andric if (ReexportedLibraries != O.ReexportedLibraries)
410344a3780SDimitry Andric return false;
4117fa27ce4SDimitry Andric if (*SymbolsSet != *O.SymbolsSet)
412344a3780SDimitry Andric return false;
4137fa27ce4SDimitry Andric // Don't compare run search paths for older filetypes that cannot express
4147fa27ce4SDimitry Andric // them.
4157fa27ce4SDimitry Andric if (!(isYAMLTextStub(FileKind)) && !(isYAMLTextStub(O.FileKind))) {
4167fa27ce4SDimitry Andric if (RPaths != O.RPaths)
4177fa27ce4SDimitry Andric return false;
4187fa27ce4SDimitry Andric if (mapToPlatformVersionSet(Targets) != mapToPlatformVersionSet(O.Targets))
4197fa27ce4SDimitry Andric return false;
4207fa27ce4SDimitry Andric }
4217fa27ce4SDimitry Andric
422344a3780SDimitry Andric if (!std::equal(Documents.begin(), Documents.end(), O.Documents.begin(),
423344a3780SDimitry Andric O.Documents.end(),
424344a3780SDimitry Andric [](const std::shared_ptr<InterfaceFile> LHS,
425344a3780SDimitry Andric const std::shared_ptr<InterfaceFile> RHS) {
426344a3780SDimitry Andric return *LHS == *RHS;
427344a3780SDimitry Andric }))
428344a3780SDimitry Andric return false;
429344a3780SDimitry Andric return true;
430344a3780SDimitry Andric }
431