Juergen Ributzka | 32cb594 | 2019-03-22 22:46:52 +0000 | [diff] [blame] | 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. |
| 10 | // |
| 11 | //===----------------------------------------------------------------------===// |
| 12 | |
| 13 | #include "llvm/TextAPI/MachO/InterfaceFile.h" |
| 14 | #include <iomanip> |
| 15 | #include <sstream> |
| 16 | |
Juergen Ributzka | 32cb594 | 2019-03-22 22:46:52 +0000 | [diff] [blame] | 17 | namespace llvm { |
| 18 | namespace MachO { |
| 19 | namespace detail { |
| 20 | template <typename C> |
| 21 | typename C::iterator addEntry(C &Container, StringRef InstallName) { |
Fangrui Song | 78ee2fb | 2019-06-30 11:19:56 +0000 | [diff] [blame] | 22 | auto I = partition_point(Container, [=](const InterfaceFileRef &O) { |
| 23 | return O.getInstallName() < InstallName; |
Fangrui Song | dc8de60 | 2019-06-21 05:40:31 +0000 | [diff] [blame] | 24 | }); |
Fangrui Song | 78ee2fb | 2019-06-30 11:19:56 +0000 | [diff] [blame] | 25 | if (I != Container.end() && I->getInstallName() == InstallName) |
Juergen Ributzka | 32cb594 | 2019-03-22 22:46:52 +0000 | [diff] [blame] | 26 | return I; |
| 27 | |
| 28 | return Container.emplace(I, InstallName); |
| 29 | } |
Cyndy Ishida | 81669d5 | 2019-09-20 14:32:34 +0000 | [diff] [blame] | 30 | |
| 31 | template <typename C> |
| 32 | typename C::iterator addEntry(C &Container, const Target &Target_) { |
| 33 | auto Iter = |
| 34 | lower_bound(Container, Target_, [](const Target &LHS, const Target &RHS) { |
| 35 | return LHS < RHS; |
| 36 | }); |
| 37 | if ((Iter != std::end(Container)) && !(Target_ < *Iter)) |
| 38 | return Iter; |
| 39 | |
| 40 | return Container.insert(Iter, Target_); |
| 41 | } |
Juergen Ributzka | 32cb594 | 2019-03-22 22:46:52 +0000 | [diff] [blame] | 42 | } // end namespace detail. |
| 43 | |
Cyndy Ishida | 81669d5 | 2019-09-20 14:32:34 +0000 | [diff] [blame] | 44 | void InterfaceFileRef::addTarget(const Target &Target) { |
| 45 | detail::addEntry(Targets, Target); |
| 46 | } |
| 47 | |
| 48 | void InterfaceFile::addAllowableClient(StringRef InstallName, |
| 49 | const Target &Target) { |
| 50 | auto Client = detail::addEntry(AllowableClients, InstallName); |
| 51 | Client->addTarget(Target); |
Juergen Ributzka | 32cb594 | 2019-03-22 22:46:52 +0000 | [diff] [blame] | 52 | } |
| 53 | |
| 54 | void InterfaceFile::addReexportedLibrary(StringRef InstallName, |
Cyndy Ishida | 81669d5 | 2019-09-20 14:32:34 +0000 | [diff] [blame] | 55 | const Target &Target) { |
Juergen Ributzka | 32cb594 | 2019-03-22 22:46:52 +0000 | [diff] [blame] | 56 | auto Lib = detail::addEntry(ReexportedLibraries, InstallName); |
Cyndy Ishida | 81669d5 | 2019-09-20 14:32:34 +0000 | [diff] [blame] | 57 | Lib->addTarget(Target); |
Juergen Ributzka | 32cb594 | 2019-03-22 22:46:52 +0000 | [diff] [blame] | 58 | } |
| 59 | |
Cyndy Ishida | 81669d5 | 2019-09-20 14:32:34 +0000 | [diff] [blame] | 60 | void InterfaceFile::addParentUmbrella(const Target &Target_, StringRef Parent) { |
| 61 | auto Iter = lower_bound(ParentUmbrellas, Target_, |
| 62 | [](const std::pair<Target, std::string> &LHS, |
| 63 | Target RHS) { return LHS.first < RHS; }); |
Juergen Ributzka | 32cb594 | 2019-03-22 22:46:52 +0000 | [diff] [blame] | 64 | |
Cyndy Ishida | 81669d5 | 2019-09-20 14:32:34 +0000 | [diff] [blame] | 65 | if ((Iter != ParentUmbrellas.end()) && !(Target_ < Iter->first)) { |
Benjamin Kramer | adcd026 | 2020-01-28 20:23:46 +0100 | [diff] [blame^] | 66 | Iter->second = std::string(Parent); |
Juergen Ributzka | 32cb594 | 2019-03-22 22:46:52 +0000 | [diff] [blame] | 67 | return; |
| 68 | } |
| 69 | |
Cyndy Ishida | 81669d5 | 2019-09-20 14:32:34 +0000 | [diff] [blame] | 70 | ParentUmbrellas.emplace(Iter, Target_, Parent); |
Juergen Ributzka | 32cb594 | 2019-03-22 22:46:52 +0000 | [diff] [blame] | 71 | return; |
| 72 | } |
| 73 | |
Cyndy Ishida | 81669d5 | 2019-09-20 14:32:34 +0000 | [diff] [blame] | 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; }); |
| 78 | |
| 79 | if ((Iter != UUIDs.end()) && !(Target_ < Iter->first)) { |
Benjamin Kramer | adcd026 | 2020-01-28 20:23:46 +0100 | [diff] [blame^] | 80 | Iter->second = std::string(UUID); |
Cyndy Ishida | 81669d5 | 2019-09-20 14:32:34 +0000 | [diff] [blame] | 81 | return; |
| 82 | } |
| 83 | |
| 84 | UUIDs.emplace(Iter, Target_, UUID); |
| 85 | return; |
| 86 | } |
| 87 | |
| 88 | void InterfaceFile::addUUID(const Target &Target, uint8_t UUID[16]) { |
Juergen Ributzka | 32cb594 | 2019-03-22 22:46:52 +0000 | [diff] [blame] | 89 | std::stringstream Stream; |
| 90 | for (unsigned i = 0; i < 16; ++i) { |
| 91 | if (i == 4 || i == 6 || i == 8 || i == 10) |
| 92 | Stream << '-'; |
| 93 | Stream << std::setfill('0') << std::setw(2) << std::uppercase << std::hex |
| 94 | << static_cast<int>(UUID[i]); |
| 95 | } |
Cyndy Ishida | 81669d5 | 2019-09-20 14:32:34 +0000 | [diff] [blame] | 96 | addUUID(Target, Stream.str()); |
| 97 | } |
| 98 | |
| 99 | void InterfaceFile::addTarget(const Target &Target) { |
| 100 | detail::addEntry(Targets, Target); |
| 101 | } |
| 102 | |
| 103 | InterfaceFile::const_filtered_target_range |
| 104 | InterfaceFile::targets(ArchitectureSet Archs) const { |
| 105 | std::function<bool(const Target &)> fn = [Archs](const Target &Target_) { |
| 106 | return Archs.has(Target_.Arch); |
| 107 | }; |
| 108 | return make_filter_range(Targets, fn); |
Juergen Ributzka | 32cb594 | 2019-03-22 22:46:52 +0000 | [diff] [blame] | 109 | } |
| 110 | |
| 111 | void InterfaceFile::addSymbol(SymbolKind Kind, StringRef Name, |
Cyndy Ishida | 81669d5 | 2019-09-20 14:32:34 +0000 | [diff] [blame] | 112 | const TargetList &Targets, SymbolFlags Flags) { |
Juergen Ributzka | 32cb594 | 2019-03-22 22:46:52 +0000 | [diff] [blame] | 113 | Name = copyString(Name); |
| 114 | auto result = Symbols.try_emplace(SymbolsMapKey{Kind, Name}, nullptr); |
| 115 | if (result.second) |
Cyndy Ishida | 81669d5 | 2019-09-20 14:32:34 +0000 | [diff] [blame] | 116 | result.first->second = new (Allocator) Symbol{Kind, Name, Targets, Flags}; |
Juergen Ributzka | 32cb594 | 2019-03-22 22:46:52 +0000 | [diff] [blame] | 117 | else |
Cyndy Ishida | 81669d5 | 2019-09-20 14:32:34 +0000 | [diff] [blame] | 118 | for (const auto &Target : Targets) |
| 119 | result.first->second->addTarget(Target); |
Juergen Ributzka | 32cb594 | 2019-03-22 22:46:52 +0000 | [diff] [blame] | 120 | } |
| 121 | |
| 122 | } // end namespace MachO. |
| 123 | } // end namespace llvm. |