[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / llvm / lib / TextAPI / InterfaceFile.cpp
blob1156a39228e7aed403118e449bc178a580447e3b
1 //===- InterfaceFile.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 // Implements the Interface File.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/TextAPI/InterfaceFile.h"
14 #include <iomanip>
15 #include <sstream>
17 using namespace llvm;
18 using namespace llvm::MachO;
20 namespace {
21 template <typename C>
22 typename C::iterator addEntry(C &Container, StringRef InstallName) {
23 auto I = partition_point(Container, [=](const InterfaceFileRef &O) {
24 return O.getInstallName() < InstallName;
25 });
26 if (I != Container.end() && I->getInstallName() == InstallName)
27 return I;
29 return Container.emplace(I, InstallName);
32 template <typename C>
33 typename C::iterator addEntry(C &Container, const Target &Target_) {
34 auto Iter =
35 lower_bound(Container, Target_, [](const Target &LHS, const Target &RHS) {
36 return LHS < RHS;
37 });
38 if ((Iter != std::end(Container)) && !(Target_ < *Iter))
39 return Iter;
41 return Container.insert(Iter, Target_);
43 } // end namespace
45 void InterfaceFileRef::addTarget(const Target &Target) {
46 addEntry(Targets, Target);
49 void InterfaceFile::addAllowableClient(StringRef InstallName,
50 const Target &Target) {
51 auto Client = addEntry(AllowableClients, InstallName);
52 Client->addTarget(Target);
55 void InterfaceFile::addReexportedLibrary(StringRef InstallName,
56 const Target &Target) {
57 auto Lib = addEntry(ReexportedLibraries, InstallName);
58 Lib->addTarget(Target);
61 void InterfaceFile::addParentUmbrella(const Target &Target_, StringRef Parent) {
62 auto Iter = lower_bound(ParentUmbrellas, Target_,
63 [](const std::pair<Target, std::string> &LHS,
64 Target RHS) { return LHS.first < RHS; });
66 if ((Iter != ParentUmbrellas.end()) && !(Target_ < Iter->first)) {
67 Iter->second = std::string(Parent);
68 return;
71 ParentUmbrellas.emplace(Iter, Target_, std::string(Parent));
74 void InterfaceFile::addUUID(const Target &Target_, StringRef UUID) {
75 auto Iter = lower_bound(UUIDs, Target_,
76 [](const std::pair<Target, std::string> &LHS,
77 Target RHS) { return LHS.first < RHS; });
79 if ((Iter != UUIDs.end()) && !(Target_ < Iter->first)) {
80 Iter->second = std::string(UUID);
81 return;
84 UUIDs.emplace(Iter, Target_, std::string(UUID));
87 void InterfaceFile::addUUID(const Target &Target, uint8_t UUID[16]) {
88 std::stringstream Stream;
89 for (unsigned i = 0; i < 16; ++i) {
90 if (i == 4 || i == 6 || i == 8 || i == 10)
91 Stream << '-';
92 Stream << std::setfill('0') << std::setw(2) << std::uppercase << std::hex
93 << static_cast<int>(UUID[i]);
95 addUUID(Target, Stream.str());
98 void InterfaceFile::addTarget(const Target &Target) {
99 addEntry(Targets, Target);
102 InterfaceFile::const_filtered_target_range
103 InterfaceFile::targets(ArchitectureSet Archs) const {
104 std::function<bool(const Target &)> fn = [Archs](const Target &Target_) {
105 return Archs.has(Target_.Arch);
107 return make_filter_range(Targets, fn);
110 void InterfaceFile::addSymbol(SymbolKind Kind, StringRef Name,
111 const TargetList &Targets, SymbolFlags Flags) {
112 Name = copyString(Name);
113 auto result = Symbols.try_emplace(SymbolsMapKey{Kind, Name}, nullptr);
114 if (result.second)
115 result.first->second = new (Allocator) Symbol{Kind, Name, Targets, Flags};
116 else
117 for (const auto &Target : Targets)
118 result.first->second->addTarget(Target);
121 void InterfaceFile::addDocument(std::shared_ptr<InterfaceFile> &&Document) {
122 auto Pos = llvm::lower_bound(Documents, Document,
123 [](const std::shared_ptr<InterfaceFile> &LHS,
124 const std::shared_ptr<InterfaceFile> &RHS) {
125 return LHS->InstallName < RHS->InstallName;
127 Document->Parent = this;
128 Documents.insert(Pos, Document);
131 bool InterfaceFile::operator==(const InterfaceFile &O) const {
132 if (Targets != O.Targets)
133 return false;
134 if (InstallName != O.InstallName)
135 return false;
136 if ((CurrentVersion != O.CurrentVersion) ||
137 (CompatibilityVersion != O.CompatibilityVersion))
138 return false;
139 if (SwiftABIVersion != O.SwiftABIVersion)
140 return false;
141 if (IsTwoLevelNamespace != O.IsTwoLevelNamespace)
142 return false;
143 if (IsAppExtensionSafe != O.IsAppExtensionSafe)
144 return false;
145 if (IsInstallAPI != O.IsInstallAPI)
146 return false;
147 if (ParentUmbrellas != O.ParentUmbrellas)
148 return false;
149 if (AllowableClients != O.AllowableClients)
150 return false;
151 if (ReexportedLibraries != O.ReexportedLibraries)
152 return false;
153 if (Symbols != O.Symbols)
154 return false;
155 if (!std::equal(Documents.begin(), Documents.end(), O.Documents.begin(),
156 O.Documents.end(),
157 [](const std::shared_ptr<InterfaceFile> LHS,
158 const std::shared_ptr<InterfaceFile> RHS) {
159 return *LHS == *RHS;
161 return false;
162 return true;