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