LLVM 22.0.0git
InterfaceFile.h
Go to the documentation of this file.
1//===- llvm/TextAPI/InterfaceFile.h - TAPI Interface File -------*- C++ -*-===//
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// A generic and abstract interface representation for linkable objects. This
10// could be an MachO executable, bundle, dylib, or text-based stub file.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_TEXTAPI_INTERFACEFILE_H
15#define LLVM_TEXTAPI_INTERFACEFILE_H
16
17#include "llvm/ADT/Hashing.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/ADT/iterator.h"
27#include "llvm/TextAPI/Symbol.h"
29#include "llvm/TextAPI/Target.h"
30
31namespace llvm {
32namespace MachO {
33
34/// Defines a list of Objective-C constraints.
35enum class ObjCConstraintType : unsigned {
36 /// No constraint.
37 None = 0,
38
39 /// Retain/Release.
41
42 /// Retain/Release for Simulator.
44
45 /// Retain/Release or Garbage Collection.
47
48 /// Garbage Collection.
49 GC = 4,
50};
51
52/// Reference to an interface file.
54public:
55 InterfaceFileRef() = default;
56
57 InterfaceFileRef(StringRef InstallName) : InstallName(InstallName) {}
58
59 InterfaceFileRef(StringRef InstallName, const TargetList Targets)
60 : InstallName(InstallName), Targets(std::move(Targets)) {}
61
62 StringRef getInstallName() const { return InstallName; };
63
64 LLVM_ABI void addTarget(const Target &Target);
65 template <typename RangeT> void addTargets(RangeT &&Targets) {
66 for (const auto &Target : Targets)
68 }
69
70 bool hasTarget(Target &Targ) const {
71 return llvm::is_contained(Targets, Targ);
72 }
73
76 const_target_range targets() const { return {Targets}; }
77
79 return mapToArchitectureSet(Targets);
80 }
81
82 PlatformSet getPlatforms() const { return mapToPlatformSet(Targets); }
83
84 bool operator==(const InterfaceFileRef &O) const {
85 return std::tie(InstallName, Targets) == std::tie(O.InstallName, O.Targets);
86 }
87
88 bool operator!=(const InterfaceFileRef &O) const {
89 return std::tie(InstallName, Targets) != std::tie(O.InstallName, O.Targets);
90 }
91
92 bool operator<(const InterfaceFileRef &O) const {
93 return std::tie(InstallName, Targets) < std::tie(O.InstallName, O.Targets);
94 }
95
96private:
97 std::string InstallName;
98 TargetList Targets;
99};
100
101} // end namespace MachO.
102
103namespace MachO {
104
105/// Defines the interface file.
107public:
108 InterfaceFile(std::unique_ptr<SymbolSet> &&InputSymbols)
109 : SymbolsSet(std::move(InputSymbols)) {}
110
111 InterfaceFile() : SymbolsSet(std::make_unique<SymbolSet>()){};
112 /// Set the path from which this file was generated (if applicable).
113 ///
114 /// \param Path_ The path to the source file.
115 void setPath(StringRef Path_) { Path = std::string(Path_); }
116
117 /// Get the path from which this file was generated (if applicable).
118 ///
119 /// \return The path to the source file or empty.
120 StringRef getPath() const { return Path; }
121
122 /// Set the file type.
123 ///
124 /// This is used by the YAML writer to identify the specification it should
125 /// use for writing the file.
126 ///
127 /// \param Kind The file type.
128 void setFileType(FileType Kind) { FileKind = Kind; }
129
130 /// Get the file type.
131 ///
132 /// \return The file type.
133 FileType getFileType() const { return FileKind; }
134
135 /// Get the architectures.
136 ///
137 /// \return The applicable architectures.
139 return mapToArchitectureSet(Targets);
140 }
141
142 /// Get the platforms.
143 ///
144 /// \return The applicable platforms.
145 PlatformSet getPlatforms() const { return mapToPlatformSet(Targets); }
146
147 /// Set and add target.
148 ///
149 /// \param Target the target to add into.
150 LLVM_ABI void addTarget(const Target &Target);
151
152 /// Determine if target triple slice exists in file.
153 ///
154 /// \param Targ the value to find.
155 bool hasTarget(const Target &Targ) const {
156 return llvm::is_contained(Targets, Targ);
157 }
158
159 /// Set and add targets.
160 ///
161 /// Add the subset of llvm::triples that is supported by Tapi
162 ///
163 /// \param Targets the collection of targets.
164 template <typename RangeT> void addTargets(RangeT &&Targets) {
165 for (const auto &Target_ : Targets)
166 addTarget(Target(Target_));
167 }
168
171 const_target_range targets() const { return {Targets}; }
172
175 std::function<bool(const Target &)>>;
179
180 /// Set the install name of the library.
181 void setInstallName(StringRef InstallName_) {
182 InstallName = std::string(InstallName_);
183 }
184
185 /// Get the install name of the library.
186 StringRef getInstallName() const { return InstallName; }
187
188 /// Set the current version of the library.
189 void setCurrentVersion(PackedVersion Version) { CurrentVersion = Version; }
190
191 /// Get the current version of the library.
192 PackedVersion getCurrentVersion() const { return CurrentVersion; }
193
194 /// Set the compatibility version of the library.
196 CompatibilityVersion = Version;
197 }
198
199 /// Get the compatibility version of the library.
200 PackedVersion getCompatibilityVersion() const { return CompatibilityVersion; }
201
202 /// Set the Swift ABI version of the library.
203 void setSwiftABIVersion(uint8_t Version) { SwiftABIVersion = Version; }
204
205 /// Get the Swift ABI version of the library.
206 uint8_t getSwiftABIVersion() const { return SwiftABIVersion; }
207
208 /// Specify if the library uses two-level namespace (or flat namespace).
209 void setTwoLevelNamespace(bool V = true) { IsTwoLevelNamespace = V; }
210
211 /// Check if the library uses two-level namespace.
212 bool isTwoLevelNamespace() const { return IsTwoLevelNamespace; }
213
214 /// Specify if the library is an OS library but not shared cache eligible.
215 void setOSLibNotForSharedCache(bool V = true) {
216 IsOSLibNotForSharedCache = V;
217 }
218
219 /// Check if the library is an OS library that is not shared cache eligible.
220 bool isOSLibNotForSharedCache() const { return IsOSLibNotForSharedCache; }
221
222 /// Specify if the library is application extension safe (or not).
223 void setApplicationExtensionSafe(bool V = true) { IsAppExtensionSafe = V; }
224
225 /// Check if the library is application extension safe.
226 bool isApplicationExtensionSafe() const { return IsAppExtensionSafe; }
227
228 /// Check if the library has simulator support.
229 bool hasSimulatorSupport() const { return HasSimSupport; }
230
231 /// Specify if the library has simulator support.
232 void setSimulatorSupport(bool V = true) { HasSimSupport = V; }
233
234 /// Set the Objective-C constraint.
236 ObjcConstraint = Constraint;
237 }
238
239 /// Get the Objective-C constraint.
240 ObjCConstraintType getObjCConstraint() const { return ObjcConstraint; }
241
242 /// Set the parent umbrella frameworks.
243 /// \param Target_ The target applicable to Parent
244 /// \param Parent The name of Parent
245 LLVM_ABI void addParentUmbrella(const Target &Target_, StringRef Parent);
246
247 /// Get the list of Parent Umbrella frameworks.
248 ///
249 /// \return Returns a list of target information and install name of parent
250 /// umbrellas.
251 const std::vector<std::pair<Target, std::string>> &umbrellas() const {
252 return ParentUmbrellas;
253 }
254
255 /// Add an allowable client.
256 ///
257 /// Mach-O Dynamic libraries have the concept of allowable clients that are
258 /// checked during static link time. The name of the application or library
259 /// that is being generated needs to match one of the allowable clients or the
260 /// linker refuses to link this library.
261 ///
262 /// \param InstallName The name of the client that is allowed to link this
263 /// library.
264 /// \param Target The target triple for which this applies.
265 LLVM_ABI void addAllowableClient(StringRef InstallName, const Target &Target);
266
267 /// Get the list of allowable clients.
268 ///
269 /// \return Returns a list of allowable clients.
270 const std::vector<InterfaceFileRef> &allowableClients() const {
271 return AllowableClients;
272 }
273
274 /// Add a re-exported library.
275 ///
276 /// \param InstallName The name of the library to re-export.
277 /// \param Target The target triple for which this applies.
278 LLVM_ABI void addReexportedLibrary(StringRef InstallName,
279 const Target &Target);
280
281 /// Get the list of re-exported libraries.
282 ///
283 /// \return Returns a list of re-exported libraries.
284 const std::vector<InterfaceFileRef> &reexportedLibraries() const {
285 return ReexportedLibraries;
286 }
287
288 /// Add a library for inlining to top level library.
289 ///
290 ///\param Document The library to inline with top level library.
291 LLVM_ABI void addDocument(std::shared_ptr<InterfaceFile> &&Document);
292
293 /// Returns the pointer to parent document if exists or nullptr otherwise.
294 InterfaceFile *getParent() const { return Parent; }
295
296 /// Get the list of inlined libraries.
297 ///
298 /// \return Returns a list of the inlined frameworks.
299 const std::vector<std::shared_ptr<InterfaceFile>> &documents() const {
300 return Documents;
301 }
302
303 /// Set the runpath search paths.
304 /// \param RPath The name of runpath.
305 /// \param InputTarget The target applicable to runpath search path.
306 LLVM_ABI void addRPath(StringRef RPath, const Target &InputTarget);
307
308 /// Get the list of runpath search paths.
309 ///
310 /// \return Returns a list of the rpaths per target.
311 const std::vector<std::pair<Target, std::string>> &rpaths() const {
312 return RPaths;
313 }
314
315 /// Get symbol if exists in file.
316 ///
317 /// \param Kind The kind of global symbol to record.
318 /// \param Name The name of the symbol.
319 /// \param ObjCIF The ObjCInterface symbol type, if applicable.
320 std::optional<const Symbol *>
323 if (auto *Sym = SymbolsSet->findSymbol(Kind, Name, ObjCIF))
324 return Sym;
325 return std::nullopt;
326 }
327
328 /// Add a symbol to the symbols list or extend an existing one.
329 template <typename RangeT, typename ElT = std::remove_reference_t<
330 decltype(*std::begin(std::declval<RangeT>()))>>
331 void addSymbol(EncodeKind Kind, StringRef Name, RangeT &&Targets,
333 SymbolsSet->addGlobal(Kind, Name, Flags, Targets);
334 }
335
336 /// Add Symbol with multiple targets.
337 ///
338 /// \param Kind The kind of global symbol to record.
339 /// \param Name The name of the symbol.
340 /// \param Targets The list of targets the symbol is defined in.
341 /// \param Flags The properties the symbol holds.
344 SymbolsSet->addGlobal(Kind, Name, Flags, Targets);
345 }
346
347 /// Add Symbol with single target.
348 ///
349 /// \param Kind The kind of global symbol to record.
350 /// \param Name The name of the symbol.
351 /// \param Target The target the symbol is defined in.
352 /// \param Flags The properties the symbol holds.
355 SymbolsSet->addGlobal(Kind, Name, Flags, Target);
356 }
357
358 /// Get size of symbol set.
359 /// \return The number of symbols the file holds.
360 size_t symbolsCount() const { return SymbolsSet->size(); }
361
364
365 const_symbol_range symbols() const { return SymbolsSet->symbols(); };
366 const_filtered_symbol_range exports() const { return SymbolsSet->exports(); };
368 return SymbolsSet->reexports();
369 };
371 return SymbolsSet->undefineds();
372 };
373
374 /// Extract architecture slice from Interface.
375 ///
376 /// \param Arch architecture to extract from.
377 /// \return New InterfaceFile with extracted architecture slice.
379 extract(Architecture Arch) const;
380
381 /// Remove architecture slice from Interface.
382 ///
383 /// \param Arch architecture to remove.
384 /// \return New Interface File with removed architecture slice.
386 remove(Architecture Arch) const;
387
388 /// Merge Interfaces for the same library. The following library attributes
389 /// must match.
390 /// * Install name, Current & Compatibility version,
391 /// * Two-level namespace enablement, and App extension enablement.
392 ///
393 /// \param O The Interface to merge.
394 /// \return New Interface File that was merged.
396 merge(const InterfaceFile *O) const;
397
398 /// Inline reexported library into Interface.
399 ///
400 /// \param Library Interface of reexported library.
401 /// \param Overwrite Whether to overwrite preexisting inlined library.
402 LLVM_ABI void inlineLibrary(std::shared_ptr<InterfaceFile> Library,
403 bool Overwrite = false);
404
405 /// Set InterfaceFile properties from pre-gathered binary attributes,
406 /// if they are not set already.
407 ///
408 /// \param BA Attributes typically represented in load commands.
409 /// \param Targ MachO Target slice to add attributes to.
411 const Target &Targ);
412
413 /// The equality is determined by attributes that impact linking
414 /// compatibilities. Path, & FileKind are irrelevant since these by
415 /// itself should not impact linking.
416 /// This is an expensive operation.
417 LLVM_ABI bool operator==(const InterfaceFile &O) const;
418
419 bool operator!=(const InterfaceFile &O) const { return !(*this == O); }
420
421private:
422 llvm::BumpPtrAllocator Allocator;
423 StringRef copyString(StringRef String) {
424 if (String.empty())
425 return {};
426
427 void *Ptr = Allocator.Allocate(String.size(), 1);
428 memcpy(Ptr, String.data(), String.size());
429 return StringRef(reinterpret_cast<const char *>(Ptr), String.size());
430 }
431
432 TargetList Targets;
433 std::string Path;
434 FileType FileKind{FileType::Invalid};
435 std::string InstallName;
436 PackedVersion CurrentVersion;
437 PackedVersion CompatibilityVersion;
438 uint8_t SwiftABIVersion{0};
439 bool IsTwoLevelNamespace{false};
440 bool IsOSLibNotForSharedCache{false};
441 bool IsAppExtensionSafe{false};
442 bool HasSimSupport{false};
444 std::vector<std::pair<Target, std::string>> ParentUmbrellas;
445 std::vector<InterfaceFileRef> AllowableClients;
446 std::vector<InterfaceFileRef> ReexportedLibraries;
447 std::vector<std::shared_ptr<InterfaceFile>> Documents;
448 std::vector<std::pair<Target, std::string>> RPaths;
449 std::unique_ptr<SymbolSet> SymbolsSet;
450 InterfaceFile *Parent = nullptr;
451};
452
453// Keep containers that hold InterfaceFileRefs in sorted order and uniqued.
454template <typename C>
455typename C::iterator addEntry(C &Container, StringRef InstallName) {
456 auto I = partition_point(Container, [=](const InterfaceFileRef &O) {
457 return O.getInstallName() < InstallName;
458 });
459 if (I != Container.end() && I->getInstallName() == InstallName)
460 return I;
461
462 return Container.emplace(I, InstallName);
463}
464
465} // end namespace MachO.
466} // end namespace llvm.
467
468#endif // LLVM_TEXTAPI_INTERFACEFILE_H
This file defines the BumpPtrAllocator interface.
#define LLVM_ABI
Definition: Compiler.h:213
std::string Name
Symbol * Sym
Definition: ELF_riscv.cpp:479
loop extract
#define I(x, y, z)
Definition: MD5.cpp:58
Implements the TAPI Record Collection Type.
Basic Register Allocator
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:67
Tagged union holding either a T or a Error.
Definition: Error.h:485
Reference to an interface file.
Definition: InterfaceFile.h:53
InterfaceFileRef(StringRef InstallName, const TargetList Targets)
Definition: InterfaceFile.h:59
bool hasTarget(Target &Targ) const
Definition: InterfaceFile.h:70
bool operator!=(const InterfaceFileRef &O) const
Definition: InterfaceFile.h:88
void addTargets(RangeT &&Targets)
Definition: InterfaceFile.h:65
PlatformSet getPlatforms() const
Definition: InterfaceFile.h:82
LLVM_ABI void addTarget(const Target &Target)
const_target_range targets() const
Definition: InterfaceFile.h:76
StringRef getInstallName() const
Definition: InterfaceFile.h:62
bool operator==(const InterfaceFileRef &O) const
Definition: InterfaceFile.h:84
ArchitectureSet getArchitectures() const
Definition: InterfaceFile.h:78
InterfaceFileRef(StringRef InstallName)
Definition: InterfaceFile.h:57
bool operator<(const InterfaceFileRef &O) const
Definition: InterfaceFile.h:92
Defines the interface file.
std::optional< const Symbol * > getSymbol(EncodeKind Kind, StringRef Name, ObjCIFSymbolKind ObjCIF=ObjCIFSymbolKind::None) const
Get symbol if exists in file.
LLVM_ABI void addDocument(std::shared_ptr< InterfaceFile > &&Document)
Add a library for inlining to top level library.
StringRef getPath() const
Get the path from which this file was generated (if applicable).
LLVM_ABI void addReexportedLibrary(StringRef InstallName, const Target &Target)
Add a re-exported library.
void setPath(StringRef Path_)
Set the path from which this file was generated (if applicable).
LLVM_ABI void setFromBinaryAttrs(const RecordsSlice::BinaryAttrs &BA, const Target &Targ)
Set InterfaceFile properties from pre-gathered binary attributes, if they are not set already.
LLVM_ABI void addParentUmbrella(const Target &Target_, StringRef Parent)
Set the parent umbrella frameworks.
const_target_range targets() const
void setOSLibNotForSharedCache(bool V=true)
Specify if the library is an OS library but not shared cache eligible.
bool isOSLibNotForSharedCache() const
Check if the library is an OS library that is not shared cache eligible.
const_filtered_symbol_range reexports() const
LLVM_ABI llvm::Expected< std::unique_ptr< InterfaceFile > > remove(Architecture Arch) const
Remove architecture slice from Interface.
void setObjCConstraint(ObjCConstraintType Constraint)
Set the Objective-C constraint.
bool isTwoLevelNamespace() const
Check if the library uses two-level namespace.
PackedVersion getCompatibilityVersion() const
Get the compatibility version of the library.
size_t symbolsCount() const
Get size of symbol set.
bool operator!=(const InterfaceFile &O) const
LLVM_ABI void addTarget(const Target &Target)
Set and add target.
const_filtered_symbol_range exports() const
bool isApplicationExtensionSafe() const
Check if the library is application extension safe.
void addSymbol(EncodeKind Kind, StringRef Name, TargetList &&Targets, SymbolFlags Flags=SymbolFlags::None)
Add Symbol with multiple targets.
void setSimulatorSupport(bool V=true)
Specify if the library has simulator support.
PlatformSet getPlatforms() const
Get the platforms.
const std::vector< std::pair< Target, std::string > > & rpaths() const
Get the list of runpath search paths.
const std::vector< InterfaceFileRef > & allowableClients() const
Get the list of allowable clients.
void addSymbol(EncodeKind Kind, StringRef Name, RangeT &&Targets, SymbolFlags Flags=SymbolFlags::None)
Add a symbol to the symbols list or extend an existing one.
void setInstallName(StringRef InstallName_)
Set the install name of the library.
void addTargets(RangeT &&Targets)
Set and add targets.
const std::vector< std::shared_ptr< InterfaceFile > > & documents() const
Get the list of inlined libraries.
const std::vector< std::pair< Target, std::string > > & umbrellas() const
Get the list of Parent Umbrella frameworks.
InterfaceFile(std::unique_ptr< SymbolSet > &&InputSymbols)
const std::vector< InterfaceFileRef > & reexportedLibraries() const
Get the list of re-exported libraries.
InterfaceFile * getParent() const
Returns the pointer to parent document if exists or nullptr otherwise.
const_symbol_range symbols() const
void setFileType(FileType Kind)
Set the file type.
uint8_t getSwiftABIVersion() const
Get the Swift ABI version of the library.
PackedVersion getCurrentVersion() const
Get the current version of the library.
void addSymbol(EncodeKind Kind, StringRef Name, Target &Target, SymbolFlags Flags=SymbolFlags::None)
Add Symbol with single target.
LLVM_ABI void addRPath(StringRef RPath, const Target &InputTarget)
Set the runpath search paths.
const_filtered_symbol_range undefineds() const
void setCompatibilityVersion(PackedVersion Version)
Set the compatibility version of the library.
ArchitectureSet getArchitectures() const
Get the architectures.
StringRef getInstallName() const
Get the install name of the library.
LLVM_ABI llvm::Expected< std::unique_ptr< InterfaceFile > > merge(const InterfaceFile *O) const
Merge Interfaces for the same library.
ObjCConstraintType getObjCConstraint() const
Get the Objective-C constraint.
FileType getFileType() const
Get the file type.
void setApplicationExtensionSafe(bool V=true)
Specify if the library is application extension safe (or not).
LLVM_ABI void addAllowableClient(StringRef InstallName, const Target &Target)
Add an allowable client.
LLVM_ABI void inlineLibrary(std::shared_ptr< InterfaceFile > Library, bool Overwrite=false)
Inline reexported library into Interface.
bool hasTarget(const Target &Targ) const
Determine if target triple slice exists in file.
void setSwiftABIVersion(uint8_t Version)
Set the Swift ABI version of the library.
void setCurrentVersion(PackedVersion Version)
Set the current version of the library.
TargetList::const_iterator const_target_iterator
void setTwoLevelNamespace(bool V=true)
Specify if the library uses two-level namespace (or flat namespace).
bool hasSimulatorSupport() const
Check if the library has simulator support.
iterator_range< const_symbol_iterator > const_symbol_range
Definition: SymbolSet.h:131
iterator_range< const_filtered_symbol_iterator > const_filtered_symbol_range
Definition: SymbolSet.h:137
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:134
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
Specialization of filter_iterator_base for forward iteration only.
Definition: STLExtras.h:506
A range adaptor for a pair of iterators.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
FileType
Defines the file type TextAPI files can represent.
Definition: FileTypes.h:15
@ Invalid
Invalid file type.
Definition: FileTypes.h:17
C::iterator addEntry(C &Container, StringRef InstallName)
LLVM_ABI PlatformSet mapToPlatformSet(ArrayRef< Triple > Targets)
Definition: Platform.cpp:62
ObjCConstraintType
Defines a list of Objective-C constraints.
Definition: InterfaceFile.h:35
@ Retain_Release_For_Simulator
Retain/Release for Simulator.
@ Retain_Release_Or_GC
Retain/Release or Garbage Collection.
Architecture
Defines the architecture slices that are supported by Text-based Stub files.
Definition: Architecture.h:28
SmallVector< Target, 5 > TargetList
Definition: Symbol.h:82
ObjCIFSymbolKind
ObjC Interface symbol mappings.
Definition: Symbol.h:70
EncodeKind
Mapping of entry types in TextStubs.
Definition: Symbol.h:56
SymbolFlags
Symbol flags.
Definition: Symbol.h:25
LLVM_ABI ArchitectureSet mapToArchitectureSet(ArrayRef< Target > Targets)
Definition: Target.cpp:69
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto partition_point(R &&Range, Predicate P)
Binary search for the first iterator in a range where a predicate is false.
Definition: STLExtras.h:2090
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1886
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition: STLExtras.h:1916
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:856