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/BitmaskEnum.h" 18fe6060f1SDimitry Andric #include "llvm/ADT/DenseMap.h" 19fe6060f1SDimitry Andric #include "llvm/ADT/Hashing.h" 20fe6060f1SDimitry Andric #include "llvm/ADT/StringRef.h" 21fe6060f1SDimitry Andric #include "llvm/ADT/iterator.h" 22fe6060f1SDimitry Andric #include "llvm/Support/Allocator.h" 23fe6060f1SDimitry Andric #include "llvm/TextAPI/ArchitectureSet.h" 24fe6060f1SDimitry Andric #include "llvm/TextAPI/PackedVersion.h" 25fe6060f1SDimitry Andric #include "llvm/TextAPI/Platform.h" 26fe6060f1SDimitry Andric #include "llvm/TextAPI/Symbol.h" 27*06c3fb27SDimitry 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 // clang-format off 52fe6060f1SDimitry Andric 53fe6060f1SDimitry Andric /// Defines the file type this file represents. 54fe6060f1SDimitry Andric enum FileType : unsigned { 55fe6060f1SDimitry Andric /// Invalid file type. 56fe6060f1SDimitry Andric Invalid = 0U, 57fe6060f1SDimitry Andric 58fe6060f1SDimitry Andric /// Text-based stub file (.tbd) version 1.0 59fe6060f1SDimitry Andric TBD_V1 = 1U << 0, 60fe6060f1SDimitry Andric 61fe6060f1SDimitry Andric /// Text-based stub file (.tbd) version 2.0 62fe6060f1SDimitry Andric TBD_V2 = 1U << 1, 63fe6060f1SDimitry Andric 64fe6060f1SDimitry Andric /// Text-based stub file (.tbd) version 3.0 65fe6060f1SDimitry Andric TBD_V3 = 1U << 2, 66fe6060f1SDimitry Andric 67fe6060f1SDimitry Andric /// Text-based stub file (.tbd) version 4.0 68fe6060f1SDimitry Andric TBD_V4 = 1U << 3, 69fe6060f1SDimitry Andric 70*06c3fb27SDimitry Andric /// Text-based stub file (.tbd) version 5.0 71*06c3fb27SDimitry Andric TBD_V5 = 1U << 4, 72*06c3fb27SDimitry Andric 73fe6060f1SDimitry Andric All = ~0U, 74fe6060f1SDimitry Andric 75fe6060f1SDimitry Andric LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/All), 76fe6060f1SDimitry Andric }; 77fe6060f1SDimitry Andric 78fe6060f1SDimitry Andric // clang-format on 79fe6060f1SDimitry Andric 80fe6060f1SDimitry Andric /// Reference to an interface file. 81fe6060f1SDimitry Andric class InterfaceFileRef { 82fe6060f1SDimitry Andric public: 83fe6060f1SDimitry Andric InterfaceFileRef() = default; 84fe6060f1SDimitry Andric 85fe6060f1SDimitry Andric InterfaceFileRef(StringRef InstallName) : InstallName(InstallName) {} 86fe6060f1SDimitry Andric 87fe6060f1SDimitry Andric InterfaceFileRef(StringRef InstallName, const TargetList Targets) 88fe6060f1SDimitry Andric : InstallName(InstallName), Targets(std::move(Targets)) {} 89fe6060f1SDimitry Andric 90fe6060f1SDimitry Andric StringRef getInstallName() const { return InstallName; }; 91fe6060f1SDimitry Andric 92fe6060f1SDimitry Andric void addTarget(const Target &Target); 93fe6060f1SDimitry Andric template <typename RangeT> void addTargets(RangeT &&Targets) { 94fe6060f1SDimitry Andric for (const auto &Target : Targets) 95fe6060f1SDimitry Andric addTarget(Target(Target)); 96fe6060f1SDimitry Andric } 97fe6060f1SDimitry Andric 98fe6060f1SDimitry Andric using const_target_iterator = TargetList::const_iterator; 99fe6060f1SDimitry Andric using const_target_range = llvm::iterator_range<const_target_iterator>; 100fe6060f1SDimitry Andric const_target_range targets() const { return {Targets}; } 101fe6060f1SDimitry Andric 102fe6060f1SDimitry Andric ArchitectureSet getArchitectures() const { 103fe6060f1SDimitry Andric return mapToArchitectureSet(Targets); 104fe6060f1SDimitry Andric } 105fe6060f1SDimitry Andric 106fe6060f1SDimitry Andric PlatformSet getPlatforms() const { return mapToPlatformSet(Targets); } 107fe6060f1SDimitry Andric 108fe6060f1SDimitry Andric bool operator==(const InterfaceFileRef &O) const { 109fe6060f1SDimitry Andric return std::tie(InstallName, Targets) == std::tie(O.InstallName, O.Targets); 110fe6060f1SDimitry Andric } 111fe6060f1SDimitry Andric 112fe6060f1SDimitry Andric bool operator!=(const InterfaceFileRef &O) const { 113fe6060f1SDimitry Andric return std::tie(InstallName, Targets) != std::tie(O.InstallName, O.Targets); 114fe6060f1SDimitry Andric } 115fe6060f1SDimitry Andric 116fe6060f1SDimitry Andric bool operator<(const InterfaceFileRef &O) const { 117fe6060f1SDimitry Andric return std::tie(InstallName, Targets) < std::tie(O.InstallName, O.Targets); 118fe6060f1SDimitry Andric } 119fe6060f1SDimitry Andric 120fe6060f1SDimitry Andric private: 121fe6060f1SDimitry Andric std::string InstallName; 122fe6060f1SDimitry Andric TargetList Targets; 123fe6060f1SDimitry Andric }; 124fe6060f1SDimitry Andric 125fe6060f1SDimitry Andric } // end namespace MachO. 126fe6060f1SDimitry Andric 127fe6060f1SDimitry Andric namespace MachO { 128fe6060f1SDimitry Andric 129fe6060f1SDimitry Andric /// Defines the interface file. 130fe6060f1SDimitry Andric class InterfaceFile { 131fe6060f1SDimitry Andric public: 132*06c3fb27SDimitry Andric InterfaceFile(std::unique_ptr<SymbolSet> &&InputSymbols) 133*06c3fb27SDimitry Andric : SymbolsSet(std::move(InputSymbols)) {} 134*06c3fb27SDimitry Andric 135*06c3fb27SDimitry Andric InterfaceFile() : SymbolsSet(std::make_unique<SymbolSet>()){}; 136fe6060f1SDimitry Andric /// Set the path from which this file was generated (if applicable). 137fe6060f1SDimitry Andric /// 138fe6060f1SDimitry Andric /// \param Path_ The path to the source file. 139fe6060f1SDimitry Andric void setPath(StringRef Path_) { Path = std::string(Path_); } 140fe6060f1SDimitry Andric 141fe6060f1SDimitry Andric /// Get the path from which this file was generated (if applicable). 142fe6060f1SDimitry Andric /// 143fe6060f1SDimitry Andric /// \return The path to the source file or empty. 144fe6060f1SDimitry Andric StringRef getPath() const { return Path; } 145fe6060f1SDimitry Andric 146fe6060f1SDimitry Andric /// Set the file type. 147fe6060f1SDimitry Andric /// 148fe6060f1SDimitry Andric /// This is used by the YAML writer to identify the specification it should 149fe6060f1SDimitry Andric /// use for writing the file. 150fe6060f1SDimitry Andric /// 151fe6060f1SDimitry Andric /// \param Kind The file type. 152fe6060f1SDimitry Andric void setFileType(FileType Kind) { FileKind = Kind; } 153fe6060f1SDimitry Andric 154fe6060f1SDimitry Andric /// Get the file type. 155fe6060f1SDimitry Andric /// 156fe6060f1SDimitry Andric /// \return The file type. 157fe6060f1SDimitry Andric FileType getFileType() const { return FileKind; } 158fe6060f1SDimitry Andric 159fe6060f1SDimitry Andric /// Get the architectures. 160fe6060f1SDimitry Andric /// 161fe6060f1SDimitry Andric /// \return The applicable architectures. 162fe6060f1SDimitry Andric ArchitectureSet getArchitectures() const { 163fe6060f1SDimitry Andric return mapToArchitectureSet(Targets); 164fe6060f1SDimitry Andric } 165fe6060f1SDimitry Andric 166fe6060f1SDimitry Andric /// Get the platforms. 167fe6060f1SDimitry Andric /// 168fe6060f1SDimitry Andric /// \return The applicable platforms. 169fe6060f1SDimitry Andric PlatformSet getPlatforms() const { return mapToPlatformSet(Targets); } 170fe6060f1SDimitry Andric 171fe6060f1SDimitry Andric /// Set and add target. 172fe6060f1SDimitry Andric /// 173fe6060f1SDimitry Andric /// \param Target the target to add into. 174fe6060f1SDimitry Andric void addTarget(const Target &Target); 175fe6060f1SDimitry Andric 176fe6060f1SDimitry Andric /// Set and add targets. 177fe6060f1SDimitry Andric /// 178fe6060f1SDimitry Andric /// Add the subset of llvm::triples that is supported by Tapi 179fe6060f1SDimitry Andric /// 180fe6060f1SDimitry Andric /// \param Targets the collection of targets. 181fe6060f1SDimitry Andric template <typename RangeT> void addTargets(RangeT &&Targets) { 182fe6060f1SDimitry Andric for (const auto &Target_ : Targets) 183fe6060f1SDimitry Andric addTarget(Target(Target_)); 184fe6060f1SDimitry Andric } 185fe6060f1SDimitry Andric 186fe6060f1SDimitry Andric using const_target_iterator = TargetList::const_iterator; 187fe6060f1SDimitry Andric using const_target_range = llvm::iterator_range<const_target_iterator>; 188fe6060f1SDimitry Andric const_target_range targets() const { return {Targets}; } 189fe6060f1SDimitry Andric 190fe6060f1SDimitry Andric using const_filtered_target_iterator = 191fe6060f1SDimitry Andric llvm::filter_iterator<const_target_iterator, 192fe6060f1SDimitry Andric std::function<bool(const Target &)>>; 193fe6060f1SDimitry Andric using const_filtered_target_range = 194fe6060f1SDimitry Andric llvm::iterator_range<const_filtered_target_iterator>; 195fe6060f1SDimitry Andric const_filtered_target_range targets(ArchitectureSet Archs) const; 196fe6060f1SDimitry Andric 197fe6060f1SDimitry Andric /// Set the install name of the library. 198fe6060f1SDimitry Andric void setInstallName(StringRef InstallName_) { 199fe6060f1SDimitry Andric InstallName = std::string(InstallName_); 200fe6060f1SDimitry Andric } 201fe6060f1SDimitry Andric 202fe6060f1SDimitry Andric /// Get the install name of the library. 203fe6060f1SDimitry Andric StringRef getInstallName() const { return InstallName; } 204fe6060f1SDimitry Andric 205fe6060f1SDimitry Andric /// Set the current version of the library. 206fe6060f1SDimitry Andric void setCurrentVersion(PackedVersion Version) { CurrentVersion = Version; } 207fe6060f1SDimitry Andric 208fe6060f1SDimitry Andric /// Get the current version of the library. 209fe6060f1SDimitry Andric PackedVersion getCurrentVersion() const { return CurrentVersion; } 210fe6060f1SDimitry Andric 211fe6060f1SDimitry Andric /// Set the compatibility version of the library. 212fe6060f1SDimitry Andric void setCompatibilityVersion(PackedVersion Version) { 213fe6060f1SDimitry Andric CompatibilityVersion = Version; 214fe6060f1SDimitry Andric } 215fe6060f1SDimitry Andric 216fe6060f1SDimitry Andric /// Get the compatibility version of the library. 217fe6060f1SDimitry Andric PackedVersion getCompatibilityVersion() const { return CompatibilityVersion; } 218fe6060f1SDimitry Andric 219fe6060f1SDimitry Andric /// Set the Swift ABI version of the library. 220fe6060f1SDimitry Andric void setSwiftABIVersion(uint8_t Version) { SwiftABIVersion = Version; } 221fe6060f1SDimitry Andric 222fe6060f1SDimitry Andric /// Get the Swift ABI version of the library. 223fe6060f1SDimitry Andric uint8_t getSwiftABIVersion() const { return SwiftABIVersion; } 224fe6060f1SDimitry Andric 225fe6060f1SDimitry Andric /// Specify if the library uses two-level namespace (or flat namespace). 226fe6060f1SDimitry Andric void setTwoLevelNamespace(bool V = true) { IsTwoLevelNamespace = V; } 227fe6060f1SDimitry Andric 228fe6060f1SDimitry Andric /// Check if the library uses two-level namespace. 229fe6060f1SDimitry Andric bool isTwoLevelNamespace() const { return IsTwoLevelNamespace; } 230fe6060f1SDimitry Andric 231fe6060f1SDimitry Andric /// Specify if the library is application extension safe (or not). 232fe6060f1SDimitry Andric void setApplicationExtensionSafe(bool V = true) { IsAppExtensionSafe = V; } 233fe6060f1SDimitry Andric 234fe6060f1SDimitry Andric /// Check if the library is application extension safe. 235fe6060f1SDimitry Andric bool isApplicationExtensionSafe() const { return IsAppExtensionSafe; } 236fe6060f1SDimitry Andric 237fe6060f1SDimitry Andric /// Set the Objective-C constraint. 238fe6060f1SDimitry Andric void setObjCConstraint(ObjCConstraintType Constraint) { 239fe6060f1SDimitry Andric ObjcConstraint = Constraint; 240fe6060f1SDimitry Andric } 241fe6060f1SDimitry Andric 242fe6060f1SDimitry Andric /// Get the Objective-C constraint. 243fe6060f1SDimitry Andric ObjCConstraintType getObjCConstraint() const { return ObjcConstraint; } 244fe6060f1SDimitry Andric 245fe6060f1SDimitry Andric /// Set the parent umbrella frameworks. 246fe6060f1SDimitry Andric /// \param Target_ The target applicable to Parent 247fe6060f1SDimitry Andric /// \param Parent The name of Parent 248fe6060f1SDimitry Andric void addParentUmbrella(const Target &Target_, StringRef Parent); 249fe6060f1SDimitry Andric 250fe6060f1SDimitry Andric /// Get the list of Parent Umbrella frameworks. 251fe6060f1SDimitry Andric /// 252fe6060f1SDimitry Andric /// \return Returns a list of target information and install name of parent 253fe6060f1SDimitry Andric /// umbrellas. 254fe6060f1SDimitry Andric const std::vector<std::pair<Target, std::string>> &umbrellas() const { 255fe6060f1SDimitry Andric return ParentUmbrellas; 256fe6060f1SDimitry Andric } 257fe6060f1SDimitry Andric 258fe6060f1SDimitry Andric /// Add an allowable client. 259fe6060f1SDimitry Andric /// 260fe6060f1SDimitry Andric /// Mach-O Dynamic libraries have the concept of allowable clients that are 261fe6060f1SDimitry Andric /// checked during static link time. The name of the application or library 262fe6060f1SDimitry Andric /// that is being generated needs to match one of the allowable clients or the 263fe6060f1SDimitry Andric /// linker refuses to link this library. 264fe6060f1SDimitry Andric /// 265fe6060f1SDimitry Andric /// \param InstallName The name of the client that is allowed to link this 266fe6060f1SDimitry Andric /// library. 267fe6060f1SDimitry Andric /// \param Target The target triple for which this applies. 268fe6060f1SDimitry Andric void addAllowableClient(StringRef InstallName, const Target &Target); 269fe6060f1SDimitry Andric 270fe6060f1SDimitry Andric /// Get the list of allowable clients. 271fe6060f1SDimitry Andric /// 272fe6060f1SDimitry Andric /// \return Returns a list of allowable clients. 273fe6060f1SDimitry Andric const std::vector<InterfaceFileRef> &allowableClients() const { 274fe6060f1SDimitry Andric return AllowableClients; 275fe6060f1SDimitry Andric } 276fe6060f1SDimitry Andric 277fe6060f1SDimitry Andric /// Add a re-exported library. 278fe6060f1SDimitry Andric /// 279fe6060f1SDimitry Andric /// \param InstallName The name of the library to re-export. 280fe6060f1SDimitry Andric /// \param Target The target triple for which this applies. 281fe6060f1SDimitry Andric void addReexportedLibrary(StringRef InstallName, const Target &Target); 282fe6060f1SDimitry Andric 283fe6060f1SDimitry Andric /// Get the list of re-exported libraries. 284fe6060f1SDimitry Andric /// 285fe6060f1SDimitry Andric /// \return Returns a list of re-exported libraries. 286fe6060f1SDimitry Andric const std::vector<InterfaceFileRef> &reexportedLibraries() const { 287fe6060f1SDimitry Andric return ReexportedLibraries; 288fe6060f1SDimitry Andric } 289fe6060f1SDimitry Andric 290fe6060f1SDimitry Andric /// Add a library for inlining to top level library. 291fe6060f1SDimitry Andric /// 292fe6060f1SDimitry Andric ///\param Document The library to inline with top level library. 293fe6060f1SDimitry Andric void addDocument(std::shared_ptr<InterfaceFile> &&Document); 294fe6060f1SDimitry Andric 295fe6060f1SDimitry Andric /// Returns the pointer to parent document if exists or nullptr otherwise. 296fe6060f1SDimitry Andric InterfaceFile *getParent() const { return Parent; } 297fe6060f1SDimitry Andric 298fe6060f1SDimitry Andric /// Get the list of inlined libraries. 299fe6060f1SDimitry Andric /// 300fe6060f1SDimitry Andric /// \return Returns a list of the inlined frameworks. 301fe6060f1SDimitry Andric const std::vector<std::shared_ptr<InterfaceFile>> &documents() const { 302fe6060f1SDimitry Andric return Documents; 303fe6060f1SDimitry Andric } 304fe6060f1SDimitry Andric 305*06c3fb27SDimitry Andric /// Set the runpath search paths. 306*06c3fb27SDimitry Andric /// \param InputTarget The target applicable to runpath search path. 307*06c3fb27SDimitry Andric /// \param RPath The name of runpath. 308*06c3fb27SDimitry Andric void addRPath(const Target &InputTarget, StringRef RPath); 309*06c3fb27SDimitry Andric 310*06c3fb27SDimitry Andric /// Get the list of runpath search paths. 311*06c3fb27SDimitry Andric /// 312*06c3fb27SDimitry Andric /// \return Returns a list of the rpaths per target. 313*06c3fb27SDimitry Andric const std::vector<std::pair<Target, std::string>> &rpaths() const { 314*06c3fb27SDimitry Andric return RPaths; 315*06c3fb27SDimitry Andric } 316*06c3fb27SDimitry Andric 317*06c3fb27SDimitry Andric /// Get symbol if exists in file. 318*06c3fb27SDimitry Andric /// 319*06c3fb27SDimitry Andric /// \param Kind The kind of global symbol to record. 320*06c3fb27SDimitry Andric /// \param Name The name of the symbol. 321*06c3fb27SDimitry Andric std::optional<const Symbol *> getSymbol(SymbolKind Kind, 322*06c3fb27SDimitry Andric StringRef Name) const { 323*06c3fb27SDimitry Andric if (auto *Sym = SymbolsSet->findSymbol(Kind, Name)) 324*06c3fb27SDimitry Andric return Sym; 325*06c3fb27SDimitry Andric return std::nullopt; 326*06c3fb27SDimitry Andric } 327*06c3fb27SDimitry Andric 328fe6060f1SDimitry Andric /// Add a symbol to the symbols list or extend an existing one. 329*06c3fb27SDimitry Andric template <typename RangeT, 330*06c3fb27SDimitry Andric typename ElT = typename std::remove_reference< 331*06c3fb27SDimitry Andric decltype(*std::begin(std::declval<RangeT>()))>::type> 332*06c3fb27SDimitry Andric void addSymbol(SymbolKind Kind, StringRef Name, RangeT &&Targets, 333*06c3fb27SDimitry Andric SymbolFlags Flags = SymbolFlags::None) { 334*06c3fb27SDimitry Andric SymbolsSet->addGlobal(Kind, Name, Flags, Targets); 335fe6060f1SDimitry Andric } 336fe6060f1SDimitry Andric 337*06c3fb27SDimitry Andric /// Add Symbol with multiple targets. 338*06c3fb27SDimitry Andric /// 339*06c3fb27SDimitry Andric /// \param Kind The kind of global symbol to record. 340*06c3fb27SDimitry Andric /// \param Name The name of the symbol. 341*06c3fb27SDimitry Andric /// \param Targets The list of targets the symbol is defined in. 342*06c3fb27SDimitry Andric /// \param Flags The properties the symbol holds. 343*06c3fb27SDimitry Andric void addSymbol(SymbolKind Kind, StringRef Name, TargetList &&Targets, 344*06c3fb27SDimitry Andric SymbolFlags Flags = SymbolFlags::None) { 345*06c3fb27SDimitry Andric SymbolsSet->addGlobal(Kind, Name, Flags, Targets); 346fe6060f1SDimitry Andric } 347fe6060f1SDimitry Andric 348*06c3fb27SDimitry Andric /// Add Symbol with single target. 349*06c3fb27SDimitry Andric /// 350*06c3fb27SDimitry Andric /// \param Kind The kind of global symbol to record. 351*06c3fb27SDimitry Andric /// \param Name The name of the symbol. 352*06c3fb27SDimitry Andric /// \param Target The target the symbol is defined in. 353*06c3fb27SDimitry Andric /// \param Flags The properties the symbol holds. 354*06c3fb27SDimitry Andric void addSymbol(SymbolKind Kind, StringRef Name, Target &Target, 355*06c3fb27SDimitry Andric SymbolFlags Flags = SymbolFlags::None) { 356*06c3fb27SDimitry Andric SymbolsSet->addGlobal(Kind, Name, Flags, Target); 357*06c3fb27SDimitry Andric } 358*06c3fb27SDimitry Andric 359*06c3fb27SDimitry Andric /// Get size of symbol set. 360*06c3fb27SDimitry Andric /// \return The number of symbols the file holds. 361*06c3fb27SDimitry Andric size_t symbolsCount() const { return SymbolsSet->size(); } 362*06c3fb27SDimitry Andric 363*06c3fb27SDimitry Andric using const_symbol_range = SymbolSet::const_symbol_range; 364*06c3fb27SDimitry Andric using const_filtered_symbol_range = SymbolSet::const_filtered_symbol_range; 365*06c3fb27SDimitry Andric 366*06c3fb27SDimitry Andric const_symbol_range symbols() const { return SymbolsSet->symbols(); }; 367*06c3fb27SDimitry Andric const_filtered_symbol_range exports() const { return SymbolsSet->exports(); }; 368*06c3fb27SDimitry Andric const_filtered_symbol_range reexports() const { 369*06c3fb27SDimitry Andric return SymbolsSet->reexports(); 370*06c3fb27SDimitry Andric }; 371fe6060f1SDimitry Andric const_filtered_symbol_range undefineds() const { 372*06c3fb27SDimitry Andric return SymbolsSet->undefineds(); 373fe6060f1SDimitry Andric }; 374fe6060f1SDimitry Andric 375fe6060f1SDimitry Andric /// The equality is determined by attributes that impact linking 376*06c3fb27SDimitry Andric /// compatibilities. Path, & FileKind are irrelevant since these by 377fe6060f1SDimitry Andric /// itself should not impact linking. 378fe6060f1SDimitry Andric /// This is an expensive operation. 379fe6060f1SDimitry Andric bool operator==(const InterfaceFile &O) const; 380fe6060f1SDimitry Andric 381fe6060f1SDimitry Andric bool operator!=(const InterfaceFile &O) const { return !(*this == O); } 382fe6060f1SDimitry Andric 383fe6060f1SDimitry Andric private: 384fe6060f1SDimitry Andric llvm::BumpPtrAllocator Allocator; 385fe6060f1SDimitry Andric StringRef copyString(StringRef String) { 386fe6060f1SDimitry Andric if (String.empty()) 387fe6060f1SDimitry Andric return {}; 388fe6060f1SDimitry Andric 389fe6060f1SDimitry Andric void *Ptr = Allocator.Allocate(String.size(), 1); 390fe6060f1SDimitry Andric memcpy(Ptr, String.data(), String.size()); 391fe6060f1SDimitry Andric return StringRef(reinterpret_cast<const char *>(Ptr), String.size()); 392fe6060f1SDimitry Andric } 393fe6060f1SDimitry Andric 394fe6060f1SDimitry Andric TargetList Targets; 395fe6060f1SDimitry Andric std::string Path; 396*06c3fb27SDimitry Andric FileType FileKind{FileType::Invalid}; 397fe6060f1SDimitry Andric std::string InstallName; 398fe6060f1SDimitry Andric PackedVersion CurrentVersion; 399fe6060f1SDimitry Andric PackedVersion CompatibilityVersion; 400fe6060f1SDimitry Andric uint8_t SwiftABIVersion{0}; 401fe6060f1SDimitry Andric bool IsTwoLevelNamespace{false}; 402fe6060f1SDimitry Andric bool IsAppExtensionSafe{false}; 403fe6060f1SDimitry Andric ObjCConstraintType ObjcConstraint = ObjCConstraintType::None; 404fe6060f1SDimitry Andric std::vector<std::pair<Target, std::string>> ParentUmbrellas; 405fe6060f1SDimitry Andric std::vector<InterfaceFileRef> AllowableClients; 406fe6060f1SDimitry Andric std::vector<InterfaceFileRef> ReexportedLibraries; 407fe6060f1SDimitry Andric std::vector<std::shared_ptr<InterfaceFile>> Documents; 408*06c3fb27SDimitry Andric std::vector<std::pair<Target, std::string>> RPaths; 409*06c3fb27SDimitry Andric std::unique_ptr<SymbolSet> SymbolsSet; 410fe6060f1SDimitry Andric InterfaceFile *Parent = nullptr; 411fe6060f1SDimitry Andric }; 412fe6060f1SDimitry Andric 413*06c3fb27SDimitry Andric // Keep containers that hold InterfaceFileRefs in sorted order and uniqued. 414*06c3fb27SDimitry Andric template <typename C> 415*06c3fb27SDimitry Andric typename C::iterator addEntry(C &Container, StringRef InstallName) { 416*06c3fb27SDimitry Andric auto I = partition_point(Container, [=](const InterfaceFileRef &O) { 417*06c3fb27SDimitry Andric return O.getInstallName() < InstallName; 418*06c3fb27SDimitry Andric }); 419*06c3fb27SDimitry Andric if (I != Container.end() && I->getInstallName() == InstallName) 420*06c3fb27SDimitry Andric return I; 421*06c3fb27SDimitry Andric 422*06c3fb27SDimitry Andric return Container.emplace(I, InstallName); 423fe6060f1SDimitry Andric } 424fe6060f1SDimitry Andric 425fe6060f1SDimitry Andric } // end namespace MachO. 426fe6060f1SDimitry Andric } // end namespace llvm. 427fe6060f1SDimitry Andric 428349cc55cSDimitry Andric #endif // LLVM_TEXTAPI_INTERFACEFILE_H 429