File indexing completed on 2026-05-10 08:44:37
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_TEXTAPI_INTERFACEFILE_H
0015 #define LLVM_TEXTAPI_INTERFACEFILE_H
0016
0017 #include "llvm/ADT/Hashing.h"
0018 #include "llvm/ADT/StringRef.h"
0019 #include "llvm/ADT/iterator.h"
0020 #include "llvm/Support/Allocator.h"
0021 #include "llvm/TextAPI/ArchitectureSet.h"
0022 #include "llvm/TextAPI/FileTypes.h"
0023 #include "llvm/TextAPI/PackedVersion.h"
0024 #include "llvm/TextAPI/Platform.h"
0025 #include "llvm/TextAPI/RecordsSlice.h"
0026 #include "llvm/TextAPI/Symbol.h"
0027 #include "llvm/TextAPI/SymbolSet.h"
0028 #include "llvm/TextAPI/Target.h"
0029
0030 namespace llvm {
0031 namespace MachO {
0032
0033
0034 enum class ObjCConstraintType : unsigned {
0035
0036 None = 0,
0037
0038
0039 Retain_Release = 1,
0040
0041
0042 Retain_Release_For_Simulator = 2,
0043
0044
0045 Retain_Release_Or_GC = 3,
0046
0047
0048 GC = 4,
0049 };
0050
0051
0052 class InterfaceFileRef {
0053 public:
0054 InterfaceFileRef() = default;
0055
0056 InterfaceFileRef(StringRef InstallName) : InstallName(InstallName) {}
0057
0058 InterfaceFileRef(StringRef InstallName, const TargetList Targets)
0059 : InstallName(InstallName), Targets(std::move(Targets)) {}
0060
0061 StringRef getInstallName() const { return InstallName; };
0062
0063 void addTarget(const Target &Target);
0064 template <typename RangeT> void addTargets(RangeT &&Targets) {
0065 for (const auto &Target : Targets)
0066 addTarget(Target(Target));
0067 }
0068
0069 bool hasTarget(Target &Targ) const {
0070 return llvm::is_contained(Targets, Targ);
0071 }
0072
0073 using const_target_iterator = TargetList::const_iterator;
0074 using const_target_range = llvm::iterator_range<const_target_iterator>;
0075 const_target_range targets() const { return {Targets}; }
0076
0077 ArchitectureSet getArchitectures() const {
0078 return mapToArchitectureSet(Targets);
0079 }
0080
0081 PlatformSet getPlatforms() const { return mapToPlatformSet(Targets); }
0082
0083 bool operator==(const InterfaceFileRef &O) const {
0084 return std::tie(InstallName, Targets) == std::tie(O.InstallName, O.Targets);
0085 }
0086
0087 bool operator!=(const InterfaceFileRef &O) const {
0088 return std::tie(InstallName, Targets) != std::tie(O.InstallName, O.Targets);
0089 }
0090
0091 bool operator<(const InterfaceFileRef &O) const {
0092 return std::tie(InstallName, Targets) < std::tie(O.InstallName, O.Targets);
0093 }
0094
0095 private:
0096 std::string InstallName;
0097 TargetList Targets;
0098 };
0099
0100 }
0101
0102 namespace MachO {
0103
0104
0105 class InterfaceFile {
0106 public:
0107 InterfaceFile(std::unique_ptr<SymbolSet> &&InputSymbols)
0108 : SymbolsSet(std::move(InputSymbols)) {}
0109
0110 InterfaceFile() : SymbolsSet(std::make_unique<SymbolSet>()){};
0111
0112
0113
0114 void setPath(StringRef Path_) { Path = std::string(Path_); }
0115
0116
0117
0118
0119 StringRef getPath() const { return Path; }
0120
0121
0122
0123
0124
0125
0126
0127 void setFileType(FileType Kind) { FileKind = Kind; }
0128
0129
0130
0131
0132 FileType getFileType() const { return FileKind; }
0133
0134
0135
0136
0137 ArchitectureSet getArchitectures() const {
0138 return mapToArchitectureSet(Targets);
0139 }
0140
0141
0142
0143
0144 PlatformSet getPlatforms() const { return mapToPlatformSet(Targets); }
0145
0146
0147
0148
0149 void addTarget(const Target &Target);
0150
0151
0152
0153
0154 bool hasTarget(const Target &Targ) const {
0155 return llvm::is_contained(Targets, Targ);
0156 }
0157
0158
0159
0160
0161
0162
0163 template <typename RangeT> void addTargets(RangeT &&Targets) {
0164 for (const auto &Target_ : Targets)
0165 addTarget(Target(Target_));
0166 }
0167
0168 using const_target_iterator = TargetList::const_iterator;
0169 using const_target_range = llvm::iterator_range<const_target_iterator>;
0170 const_target_range targets() const { return {Targets}; }
0171
0172 using const_filtered_target_iterator =
0173 llvm::filter_iterator<const_target_iterator,
0174 std::function<bool(const Target &)>>;
0175 using const_filtered_target_range =
0176 llvm::iterator_range<const_filtered_target_iterator>;
0177 const_filtered_target_range targets(ArchitectureSet Archs) const;
0178
0179
0180 void setInstallName(StringRef InstallName_) {
0181 InstallName = std::string(InstallName_);
0182 }
0183
0184
0185 StringRef getInstallName() const { return InstallName; }
0186
0187
0188 void setCurrentVersion(PackedVersion Version) { CurrentVersion = Version; }
0189
0190
0191 PackedVersion getCurrentVersion() const { return CurrentVersion; }
0192
0193
0194 void setCompatibilityVersion(PackedVersion Version) {
0195 CompatibilityVersion = Version;
0196 }
0197
0198
0199 PackedVersion getCompatibilityVersion() const { return CompatibilityVersion; }
0200
0201
0202 void setSwiftABIVersion(uint8_t Version) { SwiftABIVersion = Version; }
0203
0204
0205 uint8_t getSwiftABIVersion() const { return SwiftABIVersion; }
0206
0207
0208 void setTwoLevelNamespace(bool V = true) { IsTwoLevelNamespace = V; }
0209
0210
0211 bool isTwoLevelNamespace() const { return IsTwoLevelNamespace; }
0212
0213
0214 void setOSLibNotForSharedCache(bool V = true) {
0215 IsOSLibNotForSharedCache = V;
0216 }
0217
0218
0219 bool isOSLibNotForSharedCache() const { return IsOSLibNotForSharedCache; }
0220
0221
0222 void setApplicationExtensionSafe(bool V = true) { IsAppExtensionSafe = V; }
0223
0224
0225 bool isApplicationExtensionSafe() const { return IsAppExtensionSafe; }
0226
0227
0228 bool hasSimulatorSupport() const { return HasSimSupport; }
0229
0230
0231 void setSimulatorSupport(bool V = true) { HasSimSupport = V; }
0232
0233
0234 void setObjCConstraint(ObjCConstraintType Constraint) {
0235 ObjcConstraint = Constraint;
0236 }
0237
0238
0239 ObjCConstraintType getObjCConstraint() const { return ObjcConstraint; }
0240
0241
0242
0243
0244 void addParentUmbrella(const Target &Target_, StringRef Parent);
0245
0246
0247
0248
0249
0250 const std::vector<std::pair<Target, std::string>> &umbrellas() const {
0251 return ParentUmbrellas;
0252 }
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264 void addAllowableClient(StringRef InstallName, const Target &Target);
0265
0266
0267
0268
0269 const std::vector<InterfaceFileRef> &allowableClients() const {
0270 return AllowableClients;
0271 }
0272
0273
0274
0275
0276
0277 void addReexportedLibrary(StringRef InstallName, const Target &Target);
0278
0279
0280
0281
0282 const std::vector<InterfaceFileRef> &reexportedLibraries() const {
0283 return ReexportedLibraries;
0284 }
0285
0286
0287
0288
0289 void addDocument(std::shared_ptr<InterfaceFile> &&Document);
0290
0291
0292 InterfaceFile *getParent() const { return Parent; }
0293
0294
0295
0296
0297 const std::vector<std::shared_ptr<InterfaceFile>> &documents() const {
0298 return Documents;
0299 }
0300
0301
0302
0303
0304 void addRPath(StringRef RPath, const Target &InputTarget);
0305
0306
0307
0308
0309 const std::vector<std::pair<Target, std::string>> &rpaths() const {
0310 return RPaths;
0311 }
0312
0313
0314
0315
0316
0317
0318 std::optional<const Symbol *>
0319 getSymbol(EncodeKind Kind, StringRef Name,
0320 ObjCIFSymbolKind ObjCIF = ObjCIFSymbolKind::None) const {
0321 if (auto *Sym = SymbolsSet->findSymbol(Kind, Name, ObjCIF))
0322 return Sym;
0323 return std::nullopt;
0324 }
0325
0326
0327 template <typename RangeT, typename ElT = std::remove_reference_t<
0328 decltype(*std::begin(std::declval<RangeT>()))>>
0329 void addSymbol(EncodeKind Kind, StringRef Name, RangeT &&Targets,
0330 SymbolFlags Flags = SymbolFlags::None) {
0331 SymbolsSet->addGlobal(Kind, Name, Flags, Targets);
0332 }
0333
0334
0335
0336
0337
0338
0339
0340 void addSymbol(EncodeKind Kind, StringRef Name, TargetList &&Targets,
0341 SymbolFlags Flags = SymbolFlags::None) {
0342 SymbolsSet->addGlobal(Kind, Name, Flags, Targets);
0343 }
0344
0345
0346
0347
0348
0349
0350
0351 void addSymbol(EncodeKind Kind, StringRef Name, Target &Target,
0352 SymbolFlags Flags = SymbolFlags::None) {
0353 SymbolsSet->addGlobal(Kind, Name, Flags, Target);
0354 }
0355
0356
0357
0358 size_t symbolsCount() const { return SymbolsSet->size(); }
0359
0360 using const_symbol_range = SymbolSet::const_symbol_range;
0361 using const_filtered_symbol_range = SymbolSet::const_filtered_symbol_range;
0362
0363 const_symbol_range symbols() const { return SymbolsSet->symbols(); };
0364 const_filtered_symbol_range exports() const { return SymbolsSet->exports(); };
0365 const_filtered_symbol_range reexports() const {
0366 return SymbolsSet->reexports();
0367 };
0368 const_filtered_symbol_range undefineds() const {
0369 return SymbolsSet->undefineds();
0370 };
0371
0372
0373
0374
0375
0376 llvm::Expected<std::unique_ptr<InterfaceFile>>
0377 extract(Architecture Arch) const;
0378
0379
0380
0381
0382
0383 llvm::Expected<std::unique_ptr<InterfaceFile>>
0384 remove(Architecture Arch) const;
0385
0386
0387
0388
0389
0390
0391
0392
0393 llvm::Expected<std::unique_ptr<InterfaceFile>>
0394 merge(const InterfaceFile *O) const;
0395
0396
0397
0398
0399
0400 void inlineLibrary(std::shared_ptr<InterfaceFile> Library,
0401 bool Overwrite = false);
0402
0403
0404
0405
0406
0407
0408 void setFromBinaryAttrs(const RecordsSlice::BinaryAttrs &BA,
0409 const Target &Targ);
0410
0411
0412
0413
0414
0415 bool operator==(const InterfaceFile &O) const;
0416
0417 bool operator!=(const InterfaceFile &O) const { return !(*this == O); }
0418
0419 private:
0420 llvm::BumpPtrAllocator Allocator;
0421 StringRef copyString(StringRef String) {
0422 if (String.empty())
0423 return {};
0424
0425 void *Ptr = Allocator.Allocate(String.size(), 1);
0426 memcpy(Ptr, String.data(), String.size());
0427 return StringRef(reinterpret_cast<const char *>(Ptr), String.size());
0428 }
0429
0430 TargetList Targets;
0431 std::string Path;
0432 FileType FileKind{FileType::Invalid};
0433 std::string InstallName;
0434 PackedVersion CurrentVersion;
0435 PackedVersion CompatibilityVersion;
0436 uint8_t SwiftABIVersion{0};
0437 bool IsTwoLevelNamespace{false};
0438 bool IsOSLibNotForSharedCache{false};
0439 bool IsAppExtensionSafe{false};
0440 bool HasSimSupport{false};
0441 ObjCConstraintType ObjcConstraint = ObjCConstraintType::None;
0442 std::vector<std::pair<Target, std::string>> ParentUmbrellas;
0443 std::vector<InterfaceFileRef> AllowableClients;
0444 std::vector<InterfaceFileRef> ReexportedLibraries;
0445 std::vector<std::shared_ptr<InterfaceFile>> Documents;
0446 std::vector<std::pair<Target, std::string>> RPaths;
0447 std::unique_ptr<SymbolSet> SymbolsSet;
0448 InterfaceFile *Parent = nullptr;
0449 };
0450
0451
0452 template <typename C>
0453 typename C::iterator addEntry(C &Container, StringRef InstallName) {
0454 auto I = partition_point(Container, [=](const InterfaceFileRef &O) {
0455 return O.getInstallName() < InstallName;
0456 });
0457 if (I != Container.end() && I->getInstallName() == InstallName)
0458 return I;
0459
0460 return Container.emplace(I, InstallName);
0461 }
0462
0463 }
0464 }
0465
0466 #endif