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: |
30 | RecordsSlice(const llvm::Triple &T) : TargetTriple(T), TAPITarget(T) {} |
31 | /// Get target triple. |
32 | const llvm::Triple &getTriple() const { return TargetTriple; } |
33 | /// Get TAPI converted target. |
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. |
132 | bool hasBinaryAttrs() const { return BA.get(); } |
133 | |
134 | // Determine if record slice is unassigned. |
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. |
180 | void updateLinkage(Record *R, RecordLinkage L) { |
181 | R->Linkage = std::max(a: R->Linkage, b: 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. |
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 | |