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/FileTypes.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 Linkage The linkage of symbol. 54 /// \param GV The kind of global. 55 /// \param Flags The flags that describe attributes of the symbol. 56 /// \param Inlined Whether declaration is inlined, only applicable to 57 /// functions. 58 /// \return The non-owning pointer to added record in slice. 59 GlobalRecord *addGlobal(StringRef Name, RecordLinkage Linkage, 60 GlobalRecord::Kind GV, 61 SymbolFlags Flags = SymbolFlags::None, 62 bool Inlined = false); 63 64 /// Add ObjC Class record. 65 /// 66 /// \param Name The name of class, not symbol. 67 /// \param Linkage The linkage of symbol. 68 /// \param SymType The symbols this class represents. 69 /// \return The non-owning pointer to added record in slice. 70 ObjCInterfaceRecord *addObjCInterface(StringRef Name, RecordLinkage Linkage, 71 ObjCIFSymbolKind SymType); 72 73 /// Add ObjC IVar record. 74 /// 75 /// \param Container Owning pointer for instance variable. 76 /// \param Name The name of ivar, not symbol. 77 /// \param Linkage The linkage of symbol. 78 /// \return The non-owning pointer to added record in slice. 79 ObjCIVarRecord *addObjCIVar(ObjCContainerRecord *Container, StringRef Name, 80 RecordLinkage Linkage); 81 82 /// Add ObjC Category record. 83 /// 84 /// \param ClassToExtend The name of class that is being extended by the 85 /// category, not symbol. 86 /// \param Category The name of category. 87 /// \return The non-owning pointer to added record in slice. 88 ObjCCategoryRecord *addObjCCategory(StringRef ClassToExtend, 89 StringRef Category); 90 91 /// Find ObjC Class. 92 /// 93 /// \param Name name of class, not full symbol name. 94 /// \return The non-owning pointer to record in slice. 95 ObjCInterfaceRecord *findObjCInterface(StringRef Name) const; 96 97 /// Find ObjC Category. 98 /// 99 /// \param ClassToExtend The name of class, not full symbol name. 100 /// \param Category The name of category. 101 /// \return The non-owning pointer to record in slice. 102 ObjCCategoryRecord *findObjCCategory(StringRef ClassToExtend, 103 StringRef Category) const; 104 105 /// Find ObjC Container. This is commonly used for assigning for looking up 106 /// instance variables that are assigned to either a category or class. 107 /// 108 /// \param IsIVar If true, the name is the name of the IVar, otherwise it will 109 /// be looked up as the name of the container. 110 /// \param Name Either the name of ivar or name of container. 111 /// \return The non-owning pointer to record in 112 /// slice. 113 ObjCContainerRecord *findContainer(bool IsIVar, StringRef Name) const; 114 115 /// Find ObjC instance variable. 116 /// 117 /// \param IsScopedName This is used to determine how to parse the name. 118 /// \param Name Either the full name of the symbol or just the ivar. 119 /// \return The non-owning pointer to record in slice. 120 ObjCIVarRecord *findObjCIVar(bool IsScopedName, StringRef Name) const; 121 122 /// Find non-objc global. 123 /// 124 /// \param Name The name of symbol. 125 /// \param GV The Kind of global to find. 126 /// \return The non-owning pointer to record in slice. 127 GlobalRecord * 128 findGlobal(StringRef Name, 129 GlobalRecord::Kind GV = GlobalRecord::Kind::Unknown) const; 130 131 // Determine if library attributes were assigned. hasBinaryAttrs()132 bool hasBinaryAttrs() const { return BA.get(); } 133 134 // Determine if record slice is unassigned. empty()135 bool empty() const { 136 return !hasBinaryAttrs() && Globals.empty() && Classes.empty() && 137 Categories.empty(); 138 } 139 140 // Visit all records known to RecordsSlice. 141 void visit(RecordVisitor &V) const; 142 143 struct BinaryAttrs { 144 std::vector<StringRef> AllowableClients; 145 std::vector<StringRef> RexportedLibraries; 146 std::vector<StringRef> RPaths; 147 StringRef ParentUmbrella; 148 StringRef InstallName; 149 StringRef UUID; 150 StringRef Path; 151 FileType File = FileType::Invalid; 152 llvm::MachO::PackedVersion CurrentVersion; 153 llvm::MachO::PackedVersion CompatVersion; 154 uint8_t SwiftABI = 0; 155 bool TwoLevelNamespace = false; 156 bool AppExtensionSafe = false; 157 bool OSLibNotForSharedCache = false; 158 }; 159 160 /// Return reference to BinaryAttrs. 161 BinaryAttrs &getBinaryAttrs(); 162 163 /// Store any strings owned by RecordSlice into allocator and return back 164 /// reference to that. 165 StringRef copyString(StringRef String); 166 167 private: 168 const llvm::Triple TargetTriple; 169 // Hold tapi converted triple to avoid unecessary casts. 170 const Target TAPITarget; 171 172 /// BumpPtrAllocator to store generated/copied strings. 173 llvm::BumpPtrAllocator StringAllocator; 174 175 /// Promote linkage of requested record. It is no-op if linkage type is lower 176 /// than the current assignment. 177 /// 178 /// \param R The record to update. 179 /// \param L Linkage type to update to. updateLinkage(Record * R,RecordLinkage L)180 void updateLinkage(Record *R, RecordLinkage L) { 181 R->Linkage = std::max(R->Linkage, L); 182 } 183 184 /// Update set flags of requested record. 185 /// 186 /// \param R The record to update. 187 /// \param F Flags to update to. updateFlags(Record * R,SymbolFlags F)188 void updateFlags(Record *R, SymbolFlags F) { R->Flags |= F; } 189 190 RecordMap<GlobalRecord> Globals; 191 RecordMap<ObjCInterfaceRecord> Classes; 192 RecordMap<ObjCCategoryRecord, std::pair<StringRef, StringRef>> Categories; 193 194 std::unique_ptr<BinaryAttrs> BA{nullptr}; 195 }; 196 197 using Records = llvm::SmallVector<std::shared_ptr<RecordsSlice>, 4>; 198 class InterfaceFile; 199 std::unique_ptr<InterfaceFile> convertToInterfaceFile(const Records &Slices); 200 201 } // namespace MachO 202 } // namespace llvm 203 #endif // LLVM_TEXTAPI_RECORDSLICE_H 204