1 //===- llvm/TextAPI/RecordSlice.h - TAPI RecordSlice ------------*- 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 /// \file 10 /// \brief Implements the TAPI Record Collection Type. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_TEXTAPI_RECORDSLICE_H 15 #define LLVM_TEXTAPI_RECORDSLICE_H 16 17 #include "llvm/Support/Allocator.h" 18 #include "llvm/TextAPI/InterfaceFile.h" 19 #include "llvm/TextAPI/PackedVersion.h" 20 #include "llvm/TextAPI/Record.h" 21 #include "llvm/TextAPI/RecordVisitor.h" 22 23 namespace llvm { 24 namespace MachO { 25 26 // Define collection of records for a library that are tied to a darwin target 27 // triple. 28 class RecordsSlice { 29 public: RecordsSlice(const llvm::Triple & T)30 RecordsSlice(const llvm::Triple &T) : TargetTriple(T), TAPITarget(T) {} 31 /// Get target triple. getTriple()32 const llvm::Triple &getTriple() const { return TargetTriple; } 33 /// Get TAPI converted target. getTarget()34 const Target &getTarget() const { return TAPITarget; } 35 36 /// Add unspecified record to slice. 37 /// 38 /// Assign specific record type based on properties and symbol name. 39 /// 40 /// \param Name The name of symbol. 41 /// \param Flags The flags that describe attributes of the symbol. 42 /// \param GV The kind of global, if this represents a non obj-c global 43 /// symbol. 44 /// \param Linkage The linkage of symbol. 45 /// \return The non-owning pointer to added record in slice. 46 Record *addRecord(StringRef Name, SymbolFlags Flags, 47 GlobalRecord::Kind GV = GlobalRecord::Kind::Unknown, 48 RecordLinkage Linkage = RecordLinkage::Unknown); 49 50 /// Add non-ObjC global record. 51 /// 52 /// \param Name The name of symbol. 53 /// \param Flags The flags that describe attributes of the symbol. 54 /// \param GV The kind of global. 55 /// \param Linkage The linkage of symbol. 56 /// \return The non-owning pointer to added record in slice. 57 GlobalRecord *addGlobal(StringRef Name, RecordLinkage Linkage, 58 GlobalRecord::Kind GV, 59 SymbolFlags Flags = SymbolFlags::None); 60 61 /// Add ObjC Class record. 62 /// 63 /// \param Name The name of class, not symbol. 64 /// \param Linkage The linkage of symbol. 65 /// \param HasEHType Whether symbol represents an eh_type. 66 /// \return The non-owning pointer to added record in slice. 67 ObjCInterfaceRecord *addObjCInterface(StringRef Name, RecordLinkage Linkage, 68 bool HasEHType = false); 69 70 /// Add ObjC IVar record. 71 /// 72 /// \param Name The name of ivar, not symbol. 73 /// \param Linkage The linkage of symbol. 74 /// \return The non-owning pointer to added record in slice. 75 ObjCIVarRecord *addObjCIVar(ObjCContainerRecord *Container, StringRef Name, 76 RecordLinkage Linkage); 77 78 /// Add ObjC Category record. 79 /// 80 /// \param ClassToExtend The name of class that is being extended by the 81 /// category, not symbol. 82 /// \param Category The name of category. 83 /// \return The non-owning pointer to added record in slice. 84 ObjCCategoryRecord *addObjCCategory(StringRef ClassToExtend, 85 StringRef Category); 86 87 /// Find ObjC Class. 88 /// 89 /// \param Name name of class, not full symbol name. 90 /// \return The non-owning pointer to record in slice. 91 ObjCInterfaceRecord *findObjCInterface(StringRef Name) const; 92 93 /// Find ObjC Category. 94 /// 95 /// \param ClassToExtend The name of class, not full symbol name. 96 /// \param Categories The name of category. 97 /// \return The non-owning pointer to record in slice. 98 ObjCCategoryRecord *findObjCCategory(StringRef ClassToExtend, 99 StringRef Category) const; 100 101 /// Find ObjC Container. This is commonly used for assigning for looking up 102 /// instance variables that are assigned to either a category or class. 103 /// 104 /// \param IsIVar If true, the name is the name of the IVar, otherwise it will 105 /// be looked up as the name of the container. 106 /// \param Name Either the name of ivar or name of container. 107 /// \return The non-owning pointer to record in 108 /// slice. 109 ObjCContainerRecord *findContainer(bool IsIVar, StringRef Name) const; 110 111 /// Find ObjC instance variable. 112 /// 113 /// \param IsScopedName This is used to determine how to parse the name. 114 /// \param Name Either the full name of the symbol or just the ivar. 115 /// \return The non-owning pointer to record in slice. 116 ObjCIVarRecord *findObjCIVar(bool IsScopedName, StringRef Name) const; 117 118 /// Find non-objc global. 119 /// 120 /// \param Name The name of symbol. 121 /// \param GV The Kind of global to find. 122 /// \return The non-owning pointer to record in slice. 123 GlobalRecord * 124 findGlobal(StringRef Name, 125 GlobalRecord::Kind GV = GlobalRecord::Kind::Unknown) const; 126 127 // Determine if library attributes were assigned. hasBinaryAttrs()128 bool hasBinaryAttrs() const { return BA.get(); } 129 130 // Determine if record slice is unassigned. empty()131 bool empty() const { 132 return !hasBinaryAttrs() && Globals.empty() && Classes.empty() && 133 Categories.empty(); 134 } 135 136 // Visit all records known to RecordsSlice. 137 void visit(RecordVisitor &V) const; 138 139 struct BinaryAttrs { 140 std::vector<StringRef> AllowableClients; 141 std::vector<StringRef> RexportedLibraries; 142 std::vector<StringRef> RPaths; 143 StringRef ParentUmbrella; 144 StringRef InstallName; 145 StringRef UUID; 146 StringRef Path; 147 FileType File = FileType::Invalid; 148 llvm::MachO::PackedVersion CurrentVersion; 149 llvm::MachO::PackedVersion CompatVersion; 150 uint8_t SwiftABI = 0; 151 bool TwoLevelNamespace = false; 152 bool AppExtensionSafe = false; 153 bool OSLibNotForSharedCache = false; 154 }; 155 156 /// Return reference to BinaryAttrs. 157 BinaryAttrs &getBinaryAttrs(); 158 159 /// Store any strings owned by RecordSlice into allocator and return back 160 /// reference to that. 161 StringRef copyString(StringRef String); 162 163 private: 164 const llvm::Triple TargetTriple; 165 // Hold tapi converted triple to avoid unecessary casts. 166 const Target TAPITarget; 167 168 /// BumpPtrAllocator to store generated/copied strings. 169 llvm::BumpPtrAllocator StringAllocator; 170 171 /// Promote linkage of requested record. It is no-op if linkage type is lower 172 /// than the current assignment. 173 /// 174 /// \param R The record to update. 175 /// \param L Linkage type to update to. updateLinkage(Record * R,RecordLinkage L)176 void updateLinkage(Record *R, RecordLinkage L) { 177 R->Linkage = std::max(R->Linkage, L); 178 } 179 180 /// Update set flags of requested record. 181 /// 182 /// \param R The global record to update. 183 /// \param F Flags to update to. updateFlags(GlobalRecord * R,SymbolFlags F)184 void updateFlags(GlobalRecord *R, SymbolFlags F) { R->Flags = F; } 185 186 RecordMap<GlobalRecord> Globals; 187 RecordMap<ObjCInterfaceRecord> Classes; 188 RecordMap<ObjCCategoryRecord, std::pair<StringRef, StringRef>> Categories; 189 190 std::unique_ptr<BinaryAttrs> BA{nullptr}; 191 }; 192 193 using Records = llvm::SmallVector<std::shared_ptr<RecordsSlice>, 4>; 194 std::unique_ptr<InterfaceFile> convertToInterfaceFile(const Records &Slices); 195 196 } // namespace MachO 197 } // namespace llvm 198 #endif // LLVM_TEXTAPI_RECORDSLICE_H 199