1fe6060f1SDimitry Andric //===- llvm/TextAPI/InterfaceFile.h - TAPI Interface File -------*- C++ -*-===// 2fe6060f1SDimitry Andric // 3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fe6060f1SDimitry Andric // 7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 8fe6060f1SDimitry Andric // 9fe6060f1SDimitry Andric // A generic and abstract interface representation for linkable objects. This 10fe6060f1SDimitry Andric // could be an MachO executable, bundle, dylib, or text-based stub file. 11fe6060f1SDimitry Andric // 12fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 13fe6060f1SDimitry Andric 14349cc55cSDimitry Andric #ifndef LLVM_TEXTAPI_INTERFACEFILE_H 15349cc55cSDimitry Andric #define LLVM_TEXTAPI_INTERFACEFILE_H 16fe6060f1SDimitry Andric 17fe6060f1SDimitry Andric #include "llvm/ADT/Hashing.h" 18fe6060f1SDimitry Andric #include "llvm/ADT/StringRef.h" 19fe6060f1SDimitry Andric #include "llvm/ADT/iterator.h" 20fe6060f1SDimitry Andric #include "llvm/Support/Allocator.h" 21fe6060f1SDimitry Andric #include "llvm/TextAPI/ArchitectureSet.h" 22*0fca6ea1SDimitry Andric #include "llvm/TextAPI/FileTypes.h" 23fe6060f1SDimitry Andric #include "llvm/TextAPI/PackedVersion.h" 24fe6060f1SDimitry Andric #include "llvm/TextAPI/Platform.h" 25*0fca6ea1SDimitry Andric #include "llvm/TextAPI/RecordsSlice.h" 26fe6060f1SDimitry Andric #include "llvm/TextAPI/Symbol.h" 2706c3fb27SDimitry Andric #include "llvm/TextAPI/SymbolSet.h" 28fe6060f1SDimitry Andric #include "llvm/TextAPI/Target.h" 29fe6060f1SDimitry Andric 30fe6060f1SDimitry Andric namespace llvm { 31fe6060f1SDimitry Andric namespace MachO { 32fe6060f1SDimitry Andric 33fe6060f1SDimitry Andric /// Defines a list of Objective-C constraints. 34fe6060f1SDimitry Andric enum class ObjCConstraintType : unsigned { 35fe6060f1SDimitry Andric /// No constraint. 36fe6060f1SDimitry Andric None = 0, 37fe6060f1SDimitry Andric 38fe6060f1SDimitry Andric /// Retain/Release. 39fe6060f1SDimitry Andric Retain_Release = 1, 40fe6060f1SDimitry Andric 41fe6060f1SDimitry Andric /// Retain/Release for Simulator. 42fe6060f1SDimitry Andric Retain_Release_For_Simulator = 2, 43fe6060f1SDimitry Andric 44fe6060f1SDimitry Andric /// Retain/Release or Garbage Collection. 45fe6060f1SDimitry Andric Retain_Release_Or_GC = 3, 46fe6060f1SDimitry Andric 47fe6060f1SDimitry Andric /// Garbage Collection. 48fe6060f1SDimitry Andric GC = 4, 49fe6060f1SDimitry Andric }; 50fe6060f1SDimitry Andric 51fe6060f1SDimitry Andric /// Reference to an interface file. 52fe6060f1SDimitry Andric class InterfaceFileRef { 53fe6060f1SDimitry Andric public: 54fe6060f1SDimitry Andric InterfaceFileRef() = default; 55fe6060f1SDimitry Andric 56fe6060f1SDimitry Andric InterfaceFileRef(StringRef InstallName) : InstallName(InstallName) {} 57fe6060f1SDimitry Andric 58fe6060f1SDimitry Andric InterfaceFileRef(StringRef InstallName, const TargetList Targets) 59fe6060f1SDimitry Andric : InstallName(InstallName), Targets(std::move(Targets)) {} 60fe6060f1SDimitry Andric 61fe6060f1SDimitry Andric StringRef getInstallName() const { return InstallName; }; 62fe6060f1SDimitry Andric 63fe6060f1SDimitry Andric void addTarget(const Target &Target); 64fe6060f1SDimitry Andric template <typename RangeT> void addTargets(RangeT &&Targets) { 65fe6060f1SDimitry Andric for (const auto &Target : Targets) 66fe6060f1SDimitry Andric addTarget(Target(Target)); 67fe6060f1SDimitry Andric } 68fe6060f1SDimitry Andric 695f757f3fSDimitry Andric bool hasTarget(Target &Targ) const { 705f757f3fSDimitry Andric return llvm::is_contained(Targets, Targ); 715f757f3fSDimitry Andric } 725f757f3fSDimitry Andric 73fe6060f1SDimitry Andric using const_target_iterator = TargetList::const_iterator; 74fe6060f1SDimitry Andric using const_target_range = llvm::iterator_range<const_target_iterator>; 75fe6060f1SDimitry Andric const_target_range targets() const { return {Targets}; } 76fe6060f1SDimitry Andric 77fe6060f1SDimitry Andric ArchitectureSet getArchitectures() const { 78fe6060f1SDimitry Andric return mapToArchitectureSet(Targets); 79fe6060f1SDimitry Andric } 80fe6060f1SDimitry Andric 81fe6060f1SDimitry Andric PlatformSet getPlatforms() const { return mapToPlatformSet(Targets); } 82fe6060f1SDimitry Andric 83fe6060f1SDimitry Andric bool operator==(const InterfaceFileRef &O) const { 84fe6060f1SDimitry Andric return std::tie(InstallName, Targets) == std::tie(O.InstallName, O.Targets); 85fe6060f1SDimitry Andric } 86fe6060f1SDimitry Andric 87fe6060f1SDimitry Andric bool operator!=(const InterfaceFileRef &O) const { 88fe6060f1SDimitry Andric return std::tie(InstallName, Targets) != std::tie(O.InstallName, O.Targets); 89fe6060f1SDimitry Andric } 90fe6060f1SDimitry Andric 91fe6060f1SDimitry Andric bool operator<(const InterfaceFileRef &O) const { 92fe6060f1SDimitry Andric return std::tie(InstallName, Targets) < std::tie(O.InstallName, O.Targets); 93fe6060f1SDimitry Andric } 94fe6060f1SDimitry Andric 95fe6060f1SDimitry Andric private: 96fe6060f1SDimitry Andric std::string InstallName; 97fe6060f1SDimitry Andric TargetList Targets; 98fe6060f1SDimitry Andric }; 99fe6060f1SDimitry Andric 100fe6060f1SDimitry Andric } // end namespace MachO. 101fe6060f1SDimitry Andric 102fe6060f1SDimitry Andric namespace MachO { 103fe6060f1SDimitry Andric 104fe6060f1SDimitry Andric /// Defines the interface file. 105fe6060f1SDimitry Andric class InterfaceFile { 106fe6060f1SDimitry Andric public: 10706c3fb27SDimitry Andric InterfaceFile(std::unique_ptr<SymbolSet> &&InputSymbols) 10806c3fb27SDimitry Andric : SymbolsSet(std::move(InputSymbols)) {} 10906c3fb27SDimitry Andric 11006c3fb27SDimitry Andric InterfaceFile() : SymbolsSet(std::make_unique<SymbolSet>()){}; 111fe6060f1SDimitry Andric /// Set the path from which this file was generated (if applicable). 112fe6060f1SDimitry Andric /// 113fe6060f1SDimitry Andric /// \param Path_ The path to the source file. 114fe6060f1SDimitry Andric void setPath(StringRef Path_) { Path = std::string(Path_); } 115fe6060f1SDimitry Andric 116fe6060f1SDimitry Andric /// Get the path from which this file was generated (if applicable). 117fe6060f1SDimitry Andric /// 118fe6060f1SDimitry Andric /// \return The path to the source file or empty. 119fe6060f1SDimitry Andric StringRef getPath() const { return Path; } 120fe6060f1SDimitry Andric 121fe6060f1SDimitry Andric /// Set the file type. 122fe6060f1SDimitry Andric /// 123fe6060f1SDimitry Andric /// This is used by the YAML writer to identify the specification it should 124fe6060f1SDimitry Andric /// use for writing the file. 125fe6060f1SDimitry Andric /// 126fe6060f1SDimitry Andric /// \param Kind The file type. 127fe6060f1SDimitry Andric void setFileType(FileType Kind) { FileKind = Kind; } 128fe6060f1SDimitry Andric 129fe6060f1SDimitry Andric /// Get the file type. 130fe6060f1SDimitry Andric /// 131fe6060f1SDimitry Andric /// \return The file type. 132fe6060f1SDimitry Andric FileType getFileType() const { return FileKind; } 133fe6060f1SDimitry Andric 134fe6060f1SDimitry Andric /// Get the architectures. 135fe6060f1SDimitry Andric /// 136fe6060f1SDimitry Andric /// \return The applicable architectures. 137fe6060f1SDimitry Andric ArchitectureSet getArchitectures() const { 138fe6060f1SDimitry Andric return mapToArchitectureSet(Targets); 139fe6060f1SDimitry Andric } 140fe6060f1SDimitry Andric 141fe6060f1SDimitry Andric /// Get the platforms. 142fe6060f1SDimitry Andric /// 143fe6060f1SDimitry Andric /// \return The applicable platforms. 144fe6060f1SDimitry Andric PlatformSet getPlatforms() const { return mapToPlatformSet(Targets); } 145fe6060f1SDimitry Andric 146fe6060f1SDimitry Andric /// Set and add target. 147fe6060f1SDimitry Andric /// 148fe6060f1SDimitry Andric /// \param Target the target to add into. 149fe6060f1SDimitry Andric void addTarget(const Target &Target); 150fe6060f1SDimitry Andric 1515f757f3fSDimitry Andric /// Determine if target triple slice exists in file. 1525f757f3fSDimitry Andric /// 1535f757f3fSDimitry Andric /// \param Targ the value to find. 1545f757f3fSDimitry Andric bool hasTarget(const Target &Targ) const { 1555f757f3fSDimitry Andric return llvm::is_contained(Targets, Targ); 1565f757f3fSDimitry Andric } 1575f757f3fSDimitry Andric 158fe6060f1SDimitry Andric /// Set and add targets. 159fe6060f1SDimitry Andric /// 160fe6060f1SDimitry Andric /// Add the subset of llvm::triples that is supported by Tapi 161fe6060f1SDimitry Andric /// 162fe6060f1SDimitry Andric /// \param Targets the collection of targets. 163fe6060f1SDimitry Andric template <typename RangeT> void addTargets(RangeT &&Targets) { 164fe6060f1SDimitry Andric for (const auto &Target_ : Targets) 165fe6060f1SDimitry Andric addTarget(Target(Target_)); 166fe6060f1SDimitry Andric } 167fe6060f1SDimitry Andric 168fe6060f1SDimitry Andric using const_target_iterator = TargetList::const_iterator; 169fe6060f1SDimitry Andric using const_target_range = llvm::iterator_range<const_target_iterator>; 170fe6060f1SDimitry Andric const_target_range targets() const { return {Targets}; } 171fe6060f1SDimitry Andric 172fe6060f1SDimitry Andric using const_filtered_target_iterator = 173fe6060f1SDimitry Andric llvm::filter_iterator<const_target_iterator, 174fe6060f1SDimitry Andric std::function<bool(const Target &)>>; 175fe6060f1SDimitry Andric using const_filtered_target_range = 176fe6060f1SDimitry Andric llvm::iterator_range<const_filtered_target_iterator>; 177fe6060f1SDimitry Andric const_filtered_target_range targets(ArchitectureSet Archs) const; 178fe6060f1SDimitry Andric 179fe6060f1SDimitry Andric /// Set the install name of the library. 180fe6060f1SDimitry Andric void setInstallName(StringRef InstallName_) { 181fe6060f1SDimitry Andric InstallName = std::string(InstallName_); 182fe6060f1SDimitry Andric } 183fe6060f1SDimitry Andric 184fe6060f1SDimitry Andric /// Get the install name of the library. 185fe6060f1SDimitry Andric StringRef getInstallName() const { return InstallName; } 186fe6060f1SDimitry Andric 187fe6060f1SDimitry Andric /// Set the current version of the library. 188fe6060f1SDimitry Andric void setCurrentVersion(PackedVersion Version) { CurrentVersion = Version; } 189fe6060f1SDimitry Andric 190fe6060f1SDimitry Andric /// Get the current version of the library. 191fe6060f1SDimitry Andric PackedVersion getCurrentVersion() const { return CurrentVersion; } 192fe6060f1SDimitry Andric 193fe6060f1SDimitry Andric /// Set the compatibility version of the library. 194fe6060f1SDimitry Andric void setCompatibilityVersion(PackedVersion Version) { 195fe6060f1SDimitry Andric CompatibilityVersion = Version; 196fe6060f1SDimitry Andric } 197fe6060f1SDimitry Andric 198fe6060f1SDimitry Andric /// Get the compatibility version of the library. 199fe6060f1SDimitry Andric PackedVersion getCompatibilityVersion() const { return CompatibilityVersion; } 200fe6060f1SDimitry Andric 201fe6060f1SDimitry Andric /// Set the Swift ABI version of the library. 202fe6060f1SDimitry Andric void setSwiftABIVersion(uint8_t Version) { SwiftABIVersion = Version; } 203fe6060f1SDimitry Andric 204fe6060f1SDimitry Andric /// Get the Swift ABI version of the library. 205fe6060f1SDimitry Andric uint8_t getSwiftABIVersion() const { return SwiftABIVersion; } 206fe6060f1SDimitry Andric 207fe6060f1SDimitry Andric /// Specify if the library uses two-level namespace (or flat namespace). 208fe6060f1SDimitry Andric void setTwoLevelNamespace(bool V = true) { IsTwoLevelNamespace = V; } 209fe6060f1SDimitry Andric 210fe6060f1SDimitry Andric /// Check if the library uses two-level namespace. 211fe6060f1SDimitry Andric bool isTwoLevelNamespace() const { return IsTwoLevelNamespace; } 212fe6060f1SDimitry Andric 2135f757f3fSDimitry Andric /// Specify if the library is an OS library but not shared cache eligible. 2145f757f3fSDimitry Andric void setOSLibNotForSharedCache(bool V = true) { 2155f757f3fSDimitry Andric IsOSLibNotForSharedCache = V; 2165f757f3fSDimitry Andric } 2175f757f3fSDimitry Andric 2185f757f3fSDimitry Andric /// Check if the library is an OS library that is not shared cache eligible. 2195f757f3fSDimitry Andric bool isOSLibNotForSharedCache() const { return IsOSLibNotForSharedCache; } 2205f757f3fSDimitry Andric 221fe6060f1SDimitry Andric /// Specify if the library is application extension safe (or not). 222fe6060f1SDimitry Andric void setApplicationExtensionSafe(bool V = true) { IsAppExtensionSafe = V; } 223fe6060f1SDimitry Andric 224fe6060f1SDimitry Andric /// Check if the library is application extension safe. 225fe6060f1SDimitry Andric bool isApplicationExtensionSafe() const { return IsAppExtensionSafe; } 226fe6060f1SDimitry Andric 2275f757f3fSDimitry Andric /// Check if the library has simulator support. 2285f757f3fSDimitry Andric bool hasSimulatorSupport() const { return HasSimSupport; } 2295f757f3fSDimitry Andric 2305f757f3fSDimitry Andric /// Specify if the library has simulator support. 2315f757f3fSDimitry Andric void setSimulatorSupport(bool V = true) { HasSimSupport = V; } 2325f757f3fSDimitry Andric 233fe6060f1SDimitry Andric /// Set the Objective-C constraint. 234fe6060f1SDimitry Andric void setObjCConstraint(ObjCConstraintType Constraint) { 235fe6060f1SDimitry Andric ObjcConstraint = Constraint; 236fe6060f1SDimitry Andric } 237fe6060f1SDimitry Andric 238fe6060f1SDimitry Andric /// Get the Objective-C constraint. 239fe6060f1SDimitry Andric ObjCConstraintType getObjCConstraint() const { return ObjcConstraint; } 240fe6060f1SDimitry Andric 241fe6060f1SDimitry Andric /// Set the parent umbrella frameworks. 242fe6060f1SDimitry Andric /// \param Target_ The target applicable to Parent 243fe6060f1SDimitry Andric /// \param Parent The name of Parent 244fe6060f1SDimitry Andric void addParentUmbrella(const Target &Target_, StringRef Parent); 245fe6060f1SDimitry Andric 246fe6060f1SDimitry Andric /// Get the list of Parent Umbrella frameworks. 247fe6060f1SDimitry Andric /// 248fe6060f1SDimitry Andric /// \return Returns a list of target information and install name of parent 249fe6060f1SDimitry Andric /// umbrellas. 250fe6060f1SDimitry Andric const std::vector<std::pair<Target, std::string>> &umbrellas() const { 251fe6060f1SDimitry Andric return ParentUmbrellas; 252fe6060f1SDimitry Andric } 253fe6060f1SDimitry Andric 254fe6060f1SDimitry Andric /// Add an allowable client. 255fe6060f1SDimitry Andric /// 256fe6060f1SDimitry Andric /// Mach-O Dynamic libraries have the concept of allowable clients that are 257fe6060f1SDimitry Andric /// checked during static link time. The name of the application or library 258fe6060f1SDimitry Andric /// that is being generated needs to match one of the allowable clients or the 259fe6060f1SDimitry Andric /// linker refuses to link this library. 260fe6060f1SDimitry Andric /// 261fe6060f1SDimitry Andric /// \param InstallName The name of the client that is allowed to link this 262fe6060f1SDimitry Andric /// library. 263fe6060f1SDimitry Andric /// \param Target The target triple for which this applies. 264fe6060f1SDimitry Andric void addAllowableClient(StringRef InstallName, const Target &Target); 265fe6060f1SDimitry Andric 266fe6060f1SDimitry Andric /// Get the list of allowable clients. 267fe6060f1SDimitry Andric /// 268fe6060f1SDimitry Andric /// \return Returns a list of allowable clients. 269fe6060f1SDimitry Andric const std::vector<InterfaceFileRef> &allowableClients() const { 270fe6060f1SDimitry Andric return AllowableClients; 271fe6060f1SDimitry Andric } 272fe6060f1SDimitry Andric 273fe6060f1SDimitry Andric /// Add a re-exported library. 274fe6060f1SDimitry Andric /// 275fe6060f1SDimitry Andric /// \param InstallName The name of the library to re-export. 276fe6060f1SDimitry Andric /// \param Target The target triple for which this applies. 277fe6060f1SDimitry Andric void addReexportedLibrary(StringRef InstallName, const Target &Target); 278fe6060f1SDimitry Andric 279fe6060f1SDimitry Andric /// Get the list of re-exported libraries. 280fe6060f1SDimitry Andric /// 281fe6060f1SDimitry Andric /// \return Returns a list of re-exported libraries. 282fe6060f1SDimitry Andric const std::vector<InterfaceFileRef> &reexportedLibraries() const { 283fe6060f1SDimitry Andric return ReexportedLibraries; 284fe6060f1SDimitry Andric } 285fe6060f1SDimitry Andric 286fe6060f1SDimitry Andric /// Add a library for inlining to top level library. 287fe6060f1SDimitry Andric /// 288fe6060f1SDimitry Andric ///\param Document The library to inline with top level library. 289fe6060f1SDimitry Andric void addDocument(std::shared_ptr<InterfaceFile> &&Document); 290fe6060f1SDimitry Andric 291fe6060f1SDimitry Andric /// Returns the pointer to parent document if exists or nullptr otherwise. 292fe6060f1SDimitry Andric InterfaceFile *getParent() const { return Parent; } 293fe6060f1SDimitry Andric 294fe6060f1SDimitry Andric /// Get the list of inlined libraries. 295fe6060f1SDimitry Andric /// 296fe6060f1SDimitry Andric /// \return Returns a list of the inlined frameworks. 297fe6060f1SDimitry Andric const std::vector<std::shared_ptr<InterfaceFile>> &documents() const { 298fe6060f1SDimitry Andric return Documents; 299fe6060f1SDimitry Andric } 300fe6060f1SDimitry Andric 30106c3fb27SDimitry Andric /// Set the runpath search paths. 30206c3fb27SDimitry Andric /// \param RPath The name of runpath. 303*0fca6ea1SDimitry Andric /// \param InputTarget The target applicable to runpath search path. 304*0fca6ea1SDimitry Andric void addRPath(StringRef RPath, const Target &InputTarget); 30506c3fb27SDimitry Andric 30606c3fb27SDimitry Andric /// Get the list of runpath search paths. 30706c3fb27SDimitry Andric /// 30806c3fb27SDimitry Andric /// \return Returns a list of the rpaths per target. 30906c3fb27SDimitry Andric const std::vector<std::pair<Target, std::string>> &rpaths() const { 31006c3fb27SDimitry Andric return RPaths; 31106c3fb27SDimitry Andric } 31206c3fb27SDimitry Andric 31306c3fb27SDimitry Andric /// Get symbol if exists in file. 31406c3fb27SDimitry Andric /// 31506c3fb27SDimitry Andric /// \param Kind The kind of global symbol to record. 31606c3fb27SDimitry Andric /// \param Name The name of the symbol. 317*0fca6ea1SDimitry Andric /// \param ObjCIF The ObjCInterface symbol type, if applicable. 318*0fca6ea1SDimitry Andric std::optional<const Symbol *> 319*0fca6ea1SDimitry Andric getSymbol(EncodeKind Kind, StringRef Name, 320*0fca6ea1SDimitry Andric ObjCIFSymbolKind ObjCIF = ObjCIFSymbolKind::None) const { 321*0fca6ea1SDimitry Andric if (auto *Sym = SymbolsSet->findSymbol(Kind, Name, ObjCIF)) 32206c3fb27SDimitry Andric return Sym; 32306c3fb27SDimitry Andric return std::nullopt; 32406c3fb27SDimitry Andric } 32506c3fb27SDimitry Andric 326fe6060f1SDimitry Andric /// Add a symbol to the symbols list or extend an existing one. 3275f757f3fSDimitry Andric template <typename RangeT, typename ElT = std::remove_reference_t< 3285f757f3fSDimitry Andric decltype(*std::begin(std::declval<RangeT>()))>> 329*0fca6ea1SDimitry Andric void addSymbol(EncodeKind Kind, StringRef Name, RangeT &&Targets, 33006c3fb27SDimitry Andric SymbolFlags Flags = SymbolFlags::None) { 33106c3fb27SDimitry Andric SymbolsSet->addGlobal(Kind, Name, Flags, Targets); 332fe6060f1SDimitry Andric } 333fe6060f1SDimitry Andric 33406c3fb27SDimitry Andric /// Add Symbol with multiple targets. 33506c3fb27SDimitry Andric /// 33606c3fb27SDimitry Andric /// \param Kind The kind of global symbol to record. 33706c3fb27SDimitry Andric /// \param Name The name of the symbol. 33806c3fb27SDimitry Andric /// \param Targets The list of targets the symbol is defined in. 33906c3fb27SDimitry Andric /// \param Flags The properties the symbol holds. 340*0fca6ea1SDimitry Andric void addSymbol(EncodeKind Kind, StringRef Name, TargetList &&Targets, 34106c3fb27SDimitry Andric SymbolFlags Flags = SymbolFlags::None) { 34206c3fb27SDimitry Andric SymbolsSet->addGlobal(Kind, Name, Flags, Targets); 343fe6060f1SDimitry Andric } 344fe6060f1SDimitry Andric 34506c3fb27SDimitry Andric /// Add Symbol with single target. 34606c3fb27SDimitry Andric /// 34706c3fb27SDimitry Andric /// \param Kind The kind of global symbol to record. 34806c3fb27SDimitry Andric /// \param Name The name of the symbol. 34906c3fb27SDimitry Andric /// \param Target The target the symbol is defined in. 35006c3fb27SDimitry Andric /// \param Flags The properties the symbol holds. 351*0fca6ea1SDimitry Andric void addSymbol(EncodeKind Kind, StringRef Name, Target &Target, 35206c3fb27SDimitry Andric SymbolFlags Flags = SymbolFlags::None) { 35306c3fb27SDimitry Andric SymbolsSet->addGlobal(Kind, Name, Flags, Target); 35406c3fb27SDimitry Andric } 35506c3fb27SDimitry Andric 35606c3fb27SDimitry Andric /// Get size of symbol set. 35706c3fb27SDimitry Andric /// \return The number of symbols the file holds. 35806c3fb27SDimitry Andric size_t symbolsCount() const { return SymbolsSet->size(); } 35906c3fb27SDimitry Andric 36006c3fb27SDimitry Andric using const_symbol_range = SymbolSet::const_symbol_range; 36106c3fb27SDimitry Andric using const_filtered_symbol_range = SymbolSet::const_filtered_symbol_range; 36206c3fb27SDimitry Andric 36306c3fb27SDimitry Andric const_symbol_range symbols() const { return SymbolsSet->symbols(); }; 36406c3fb27SDimitry Andric const_filtered_symbol_range exports() const { return SymbolsSet->exports(); }; 36506c3fb27SDimitry Andric const_filtered_symbol_range reexports() const { 36606c3fb27SDimitry Andric return SymbolsSet->reexports(); 36706c3fb27SDimitry Andric }; 368fe6060f1SDimitry Andric const_filtered_symbol_range undefineds() const { 36906c3fb27SDimitry Andric return SymbolsSet->undefineds(); 370fe6060f1SDimitry Andric }; 371fe6060f1SDimitry Andric 3725f757f3fSDimitry Andric /// Extract architecture slice from Interface. 3735f757f3fSDimitry Andric /// 3745f757f3fSDimitry Andric /// \param Arch architecture to extract from. 3755f757f3fSDimitry Andric /// \return New InterfaceFile with extracted architecture slice. 3765f757f3fSDimitry Andric llvm::Expected<std::unique_ptr<InterfaceFile>> 3775f757f3fSDimitry Andric extract(Architecture Arch) const; 3785f757f3fSDimitry Andric 3795f757f3fSDimitry Andric /// Remove architecture slice from Interface. 3805f757f3fSDimitry Andric /// 3815f757f3fSDimitry Andric /// \param Arch architecture to remove. 3825f757f3fSDimitry Andric /// \return New Interface File with removed architecture slice. 3835f757f3fSDimitry Andric llvm::Expected<std::unique_ptr<InterfaceFile>> 3845f757f3fSDimitry Andric remove(Architecture Arch) const; 3855f757f3fSDimitry Andric 3865f757f3fSDimitry Andric /// Merge Interfaces for the same library. The following library attributes 3875f757f3fSDimitry Andric /// must match. 3885f757f3fSDimitry Andric /// * Install name, Current & Compatibility version, 3895f757f3fSDimitry Andric /// * Two-level namespace enablement, and App extension enablement. 3905f757f3fSDimitry Andric /// 3915f757f3fSDimitry Andric /// \param O The Interface to merge. 3925f757f3fSDimitry Andric /// \return New Interface File that was merged. 3935f757f3fSDimitry Andric llvm::Expected<std::unique_ptr<InterfaceFile>> 3945f757f3fSDimitry Andric merge(const InterfaceFile *O) const; 3955f757f3fSDimitry Andric 3965f757f3fSDimitry Andric /// Inline reexported library into Interface. 3975f757f3fSDimitry Andric /// 3985f757f3fSDimitry Andric /// \param Library Interface of reexported library. 3995f757f3fSDimitry Andric /// \param Overwrite Whether to overwrite preexisting inlined library. 4005f757f3fSDimitry Andric void inlineLibrary(std::shared_ptr<InterfaceFile> Library, 4015f757f3fSDimitry Andric bool Overwrite = false); 4025f757f3fSDimitry Andric 403*0fca6ea1SDimitry Andric /// Set InterfaceFile properties from pre-gathered binary attributes, 404*0fca6ea1SDimitry Andric /// if they are not set already. 405*0fca6ea1SDimitry Andric /// 406*0fca6ea1SDimitry Andric /// \param BA Attributes typically represented in load commands. 407*0fca6ea1SDimitry Andric /// \param Targ MachO Target slice to add attributes to. 408*0fca6ea1SDimitry Andric void setFromBinaryAttrs(const RecordsSlice::BinaryAttrs &BA, 409*0fca6ea1SDimitry Andric const Target &Targ); 410*0fca6ea1SDimitry Andric 411fe6060f1SDimitry Andric /// The equality is determined by attributes that impact linking 41206c3fb27SDimitry Andric /// compatibilities. Path, & FileKind are irrelevant since these by 413fe6060f1SDimitry Andric /// itself should not impact linking. 414fe6060f1SDimitry Andric /// This is an expensive operation. 415fe6060f1SDimitry Andric bool operator==(const InterfaceFile &O) const; 416fe6060f1SDimitry Andric 417fe6060f1SDimitry Andric bool operator!=(const InterfaceFile &O) const { return !(*this == O); } 418fe6060f1SDimitry Andric 419fe6060f1SDimitry Andric private: 420fe6060f1SDimitry Andric llvm::BumpPtrAllocator Allocator; 421fe6060f1SDimitry Andric StringRef copyString(StringRef String) { 422fe6060f1SDimitry Andric if (String.empty()) 423fe6060f1SDimitry Andric return {}; 424fe6060f1SDimitry Andric 425fe6060f1SDimitry Andric void *Ptr = Allocator.Allocate(String.size(), 1); 426fe6060f1SDimitry Andric memcpy(Ptr, String.data(), String.size()); 427fe6060f1SDimitry Andric return StringRef(reinterpret_cast<const char *>(Ptr), String.size()); 428fe6060f1SDimitry Andric } 429fe6060f1SDimitry Andric 430fe6060f1SDimitry Andric TargetList Targets; 431fe6060f1SDimitry Andric std::string Path; 43206c3fb27SDimitry Andric FileType FileKind{FileType::Invalid}; 433fe6060f1SDimitry Andric std::string InstallName; 434fe6060f1SDimitry Andric PackedVersion CurrentVersion; 435fe6060f1SDimitry Andric PackedVersion CompatibilityVersion; 436fe6060f1SDimitry Andric uint8_t SwiftABIVersion{0}; 437fe6060f1SDimitry Andric bool IsTwoLevelNamespace{false}; 4385f757f3fSDimitry Andric bool IsOSLibNotForSharedCache{false}; 439fe6060f1SDimitry Andric bool IsAppExtensionSafe{false}; 4405f757f3fSDimitry Andric bool HasSimSupport{false}; 441fe6060f1SDimitry Andric ObjCConstraintType ObjcConstraint = ObjCConstraintType::None; 442fe6060f1SDimitry Andric std::vector<std::pair<Target, std::string>> ParentUmbrellas; 443fe6060f1SDimitry Andric std::vector<InterfaceFileRef> AllowableClients; 444fe6060f1SDimitry Andric std::vector<InterfaceFileRef> ReexportedLibraries; 445fe6060f1SDimitry Andric std::vector<std::shared_ptr<InterfaceFile>> Documents; 44606c3fb27SDimitry Andric std::vector<std::pair<Target, std::string>> RPaths; 44706c3fb27SDimitry Andric std::unique_ptr<SymbolSet> SymbolsSet; 448fe6060f1SDimitry Andric InterfaceFile *Parent = nullptr; 449fe6060f1SDimitry Andric }; 450fe6060f1SDimitry Andric 45106c3fb27SDimitry Andric // Keep containers that hold InterfaceFileRefs in sorted order and uniqued. 45206c3fb27SDimitry Andric template <typename C> 45306c3fb27SDimitry Andric typename C::iterator addEntry(C &Container, StringRef InstallName) { 45406c3fb27SDimitry Andric auto I = partition_point(Container, [=](const InterfaceFileRef &O) { 45506c3fb27SDimitry Andric return O.getInstallName() < InstallName; 45606c3fb27SDimitry Andric }); 45706c3fb27SDimitry Andric if (I != Container.end() && I->getInstallName() == InstallName) 45806c3fb27SDimitry Andric return I; 45906c3fb27SDimitry Andric 46006c3fb27SDimitry Andric return Container.emplace(I, InstallName); 461fe6060f1SDimitry Andric } 462fe6060f1SDimitry Andric 463fe6060f1SDimitry Andric } // end namespace MachO. 464fe6060f1SDimitry Andric } // end namespace llvm. 465fe6060f1SDimitry Andric 466349cc55cSDimitry Andric #endif // LLVM_TEXTAPI_INTERFACEFILE_H 467