xref: /freebsd-src/contrib/llvm-project/llvm/lib/TextAPI/InterfaceFile.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
1fe6060f1SDimitry Andric //===- InterfaceFile.cpp --------------------------------------------------===//
2fe6060f1SDimitry Andric //
3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fe6060f1SDimitry Andric //
7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
8fe6060f1SDimitry Andric //
9fe6060f1SDimitry Andric // Implements the Interface File.
10fe6060f1SDimitry Andric //
11fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
12fe6060f1SDimitry Andric 
13fe6060f1SDimitry Andric #include "llvm/TextAPI/InterfaceFile.h"
14fe6060f1SDimitry Andric #include <iomanip>
15fe6060f1SDimitry Andric #include <sstream>
16fe6060f1SDimitry Andric 
17fe6060f1SDimitry Andric using namespace llvm;
18fe6060f1SDimitry Andric using namespace llvm::MachO;
19fe6060f1SDimitry Andric 
20fe6060f1SDimitry Andric void InterfaceFileRef::addTarget(const Target &Target) {
21fe6060f1SDimitry Andric   addEntry(Targets, Target);
22fe6060f1SDimitry Andric }
23fe6060f1SDimitry Andric 
24fe6060f1SDimitry Andric void InterfaceFile::addAllowableClient(StringRef InstallName,
25fe6060f1SDimitry Andric                                        const Target &Target) {
26fe6060f1SDimitry Andric   auto Client = addEntry(AllowableClients, InstallName);
27fe6060f1SDimitry Andric   Client->addTarget(Target);
28fe6060f1SDimitry Andric }
29fe6060f1SDimitry Andric 
30fe6060f1SDimitry Andric void InterfaceFile::addReexportedLibrary(StringRef InstallName,
31fe6060f1SDimitry Andric                                          const Target &Target) {
32fe6060f1SDimitry Andric   auto Lib = addEntry(ReexportedLibraries, InstallName);
33fe6060f1SDimitry Andric   Lib->addTarget(Target);
34fe6060f1SDimitry Andric }
35fe6060f1SDimitry Andric 
36fe6060f1SDimitry Andric void InterfaceFile::addParentUmbrella(const Target &Target_, StringRef Parent) {
37fe6060f1SDimitry Andric   auto Iter = lower_bound(ParentUmbrellas, Target_,
38fe6060f1SDimitry Andric                           [](const std::pair<Target, std::string> &LHS,
39fe6060f1SDimitry Andric                              Target RHS) { return LHS.first < RHS; });
40fe6060f1SDimitry Andric 
41fe6060f1SDimitry Andric   if ((Iter != ParentUmbrellas.end()) && !(Target_ < Iter->first)) {
42fe6060f1SDimitry Andric     Iter->second = std::string(Parent);
43fe6060f1SDimitry Andric     return;
44fe6060f1SDimitry Andric   }
45fe6060f1SDimitry Andric 
46fe6060f1SDimitry Andric   ParentUmbrellas.emplace(Iter, Target_, std::string(Parent));
47fe6060f1SDimitry Andric }
48fe6060f1SDimitry Andric 
49*06c3fb27SDimitry Andric void InterfaceFile::addRPath(const Target &InputTarget, StringRef RPath) {
50*06c3fb27SDimitry Andric   auto Iter = lower_bound(RPaths, InputTarget,
51fe6060f1SDimitry Andric                           [](const std::pair<Target, std::string> &LHS,
52fe6060f1SDimitry Andric                              Target RHS) { return LHS.first < RHS; });
53fe6060f1SDimitry Andric 
54*06c3fb27SDimitry Andric   if ((Iter != RPaths.end()) && !(InputTarget < Iter->first)) {
55*06c3fb27SDimitry Andric     Iter->second = std::string(RPath);
56fe6060f1SDimitry Andric     return;
57fe6060f1SDimitry Andric   }
58fe6060f1SDimitry Andric 
59*06c3fb27SDimitry Andric   RPaths.emplace(Iter, InputTarget, std::string(RPath));
60fe6060f1SDimitry Andric }
61fe6060f1SDimitry Andric 
62fe6060f1SDimitry Andric void InterfaceFile::addTarget(const Target &Target) {
63fe6060f1SDimitry Andric   addEntry(Targets, Target);
64fe6060f1SDimitry Andric }
65fe6060f1SDimitry Andric 
66fe6060f1SDimitry Andric InterfaceFile::const_filtered_target_range
67fe6060f1SDimitry Andric InterfaceFile::targets(ArchitectureSet Archs) const {
68fe6060f1SDimitry Andric   std::function<bool(const Target &)> fn = [Archs](const Target &Target_) {
69fe6060f1SDimitry Andric     return Archs.has(Target_.Arch);
70fe6060f1SDimitry Andric   };
71fe6060f1SDimitry Andric   return make_filter_range(Targets, fn);
72fe6060f1SDimitry Andric }
73fe6060f1SDimitry Andric 
74fe6060f1SDimitry Andric void InterfaceFile::addDocument(std::shared_ptr<InterfaceFile> &&Document) {
75fe6060f1SDimitry Andric   auto Pos = llvm::lower_bound(Documents, Document,
76fe6060f1SDimitry Andric                                [](const std::shared_ptr<InterfaceFile> &LHS,
77fe6060f1SDimitry Andric                                   const std::shared_ptr<InterfaceFile> &RHS) {
78fe6060f1SDimitry Andric                                  return LHS->InstallName < RHS->InstallName;
79fe6060f1SDimitry Andric                                });
80fe6060f1SDimitry Andric   Document->Parent = this;
81fe6060f1SDimitry Andric   Documents.insert(Pos, Document);
82fe6060f1SDimitry Andric }
83fe6060f1SDimitry Andric 
84*06c3fb27SDimitry Andric static bool isYAMLTextStub(const FileType &Kind) {
85*06c3fb27SDimitry Andric   return (Kind >= FileType::TBD_V1) && (Kind < FileType::TBD_V5);
86*06c3fb27SDimitry Andric }
87*06c3fb27SDimitry Andric 
88fe6060f1SDimitry Andric bool InterfaceFile::operator==(const InterfaceFile &O) const {
89fe6060f1SDimitry Andric   if (Targets != O.Targets)
90fe6060f1SDimitry Andric     return false;
91fe6060f1SDimitry Andric   if (InstallName != O.InstallName)
92fe6060f1SDimitry Andric     return false;
93fe6060f1SDimitry Andric   if ((CurrentVersion != O.CurrentVersion) ||
94fe6060f1SDimitry Andric       (CompatibilityVersion != O.CompatibilityVersion))
95fe6060f1SDimitry Andric     return false;
96fe6060f1SDimitry Andric   if (SwiftABIVersion != O.SwiftABIVersion)
97fe6060f1SDimitry Andric     return false;
98fe6060f1SDimitry Andric   if (IsTwoLevelNamespace != O.IsTwoLevelNamespace)
99fe6060f1SDimitry Andric     return false;
100fe6060f1SDimitry Andric   if (IsAppExtensionSafe != O.IsAppExtensionSafe)
101fe6060f1SDimitry Andric     return false;
102fe6060f1SDimitry Andric   if (ParentUmbrellas != O.ParentUmbrellas)
103fe6060f1SDimitry Andric     return false;
104fe6060f1SDimitry Andric   if (AllowableClients != O.AllowableClients)
105fe6060f1SDimitry Andric     return false;
106fe6060f1SDimitry Andric   if (ReexportedLibraries != O.ReexportedLibraries)
107fe6060f1SDimitry Andric     return false;
108*06c3fb27SDimitry Andric   if (*SymbolsSet != *O.SymbolsSet)
109fe6060f1SDimitry Andric     return false;
110*06c3fb27SDimitry Andric   // Don't compare run search paths for older filetypes that cannot express
111*06c3fb27SDimitry Andric   // them.
112*06c3fb27SDimitry Andric   if (!(isYAMLTextStub(FileKind)) && !(isYAMLTextStub(O.FileKind))) {
113*06c3fb27SDimitry Andric     if (RPaths != O.RPaths)
114*06c3fb27SDimitry Andric       return false;
115*06c3fb27SDimitry Andric     if (mapToPlatformVersionSet(Targets) != mapToPlatformVersionSet(O.Targets))
116*06c3fb27SDimitry Andric       return false;
117*06c3fb27SDimitry Andric   }
118*06c3fb27SDimitry Andric 
119fe6060f1SDimitry Andric   if (!std::equal(Documents.begin(), Documents.end(), O.Documents.begin(),
120fe6060f1SDimitry Andric                   O.Documents.end(),
121fe6060f1SDimitry Andric                   [](const std::shared_ptr<InterfaceFile> LHS,
122fe6060f1SDimitry Andric                      const std::shared_ptr<InterfaceFile> RHS) {
123fe6060f1SDimitry Andric                     return *LHS == *RHS;
124fe6060f1SDimitry Andric                   }))
125fe6060f1SDimitry Andric     return false;
126fe6060f1SDimitry Andric   return true;
127fe6060f1SDimitry Andric }
128