1 //===- InterfaceFile.cpp --------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // Implements the Interface File.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/TextAPI/InterfaceFile.h"
18 using namespace llvm::MachO
;
22 typename
C::iterator
addEntry(C
&Container
, StringRef InstallName
) {
23 auto I
= partition_point(Container
, [=](const InterfaceFileRef
&O
) {
24 return O
.getInstallName() < InstallName
;
26 if (I
!= Container
.end() && I
->getInstallName() == InstallName
)
29 return Container
.emplace(I
, InstallName
);
33 typename
C::iterator
addEntry(C
&Container
, const Target
&Target_
) {
35 lower_bound(Container
, Target_
, [](const Target
&LHS
, const Target
&RHS
) {
38 if ((Iter
!= std::end(Container
)) && !(Target_
< *Iter
))
41 return Container
.insert(Iter
, Target_
);
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
);
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
);
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)
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);
115 result
.first
->second
= new (Allocator
) Symbol
{Kind
, Name
, Targets
, Flags
};
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
)
134 if (InstallName
!= O
.InstallName
)
136 if ((CurrentVersion
!= O
.CurrentVersion
) ||
137 (CompatibilityVersion
!= O
.CompatibilityVersion
))
139 if (SwiftABIVersion
!= O
.SwiftABIVersion
)
141 if (IsTwoLevelNamespace
!= O
.IsTwoLevelNamespace
)
143 if (IsAppExtensionSafe
!= O
.IsAppExtensionSafe
)
145 if (IsInstallAPI
!= O
.IsInstallAPI
)
147 if (ParentUmbrellas
!= O
.ParentUmbrellas
)
149 if (AllowableClients
!= O
.AllowableClients
)
151 if (ReexportedLibraries
!= O
.ReexportedLibraries
)
153 if (Symbols
!= O
.Symbols
)
155 if (!std::equal(Documents
.begin(), Documents
.end(), O
.Documents
.begin(),
157 [](const std::shared_ptr
<InterfaceFile
> LHS
,
158 const std::shared_ptr
<InterfaceFile
> RHS
) {