Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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