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