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