xref: /freebsd/contrib/llvm-project/llvm/include/llvm/TextAPI/RecordsSlice.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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