/src/llvm-project/clang/lib/CodeGen/CGObjCRuntime.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===----- CGObjCRuntime.h - Interface to ObjC Runtimes ---------*- 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 | | // This provides an abstract class for Objective-C code generation. Concrete |
10 | | // subclasses of this implement code generation for specific Objective-C |
11 | | // runtime libraries. |
12 | | // |
13 | | //===----------------------------------------------------------------------===// |
14 | | |
15 | | #ifndef LLVM_CLANG_LIB_CODEGEN_CGOBJCRUNTIME_H |
16 | | #define LLVM_CLANG_LIB_CODEGEN_CGOBJCRUNTIME_H |
17 | | #include "CGBuilder.h" |
18 | | #include "CGCall.h" |
19 | | #include "CGCleanup.h" |
20 | | #include "CGValue.h" |
21 | | #include "clang/AST/DeclObjC.h" |
22 | | #include "clang/Basic/IdentifierTable.h" // Selector |
23 | | #include "llvm/ADT/UniqueVector.h" |
24 | | |
25 | | namespace llvm { |
26 | | class Constant; |
27 | | class Function; |
28 | | class Module; |
29 | | class StructLayout; |
30 | | class StructType; |
31 | | class Type; |
32 | | class Value; |
33 | | } |
34 | | |
35 | | namespace clang { |
36 | | namespace CodeGen { |
37 | | class CGFunctionInfo; |
38 | | class CodeGenFunction; |
39 | | } |
40 | | |
41 | | class FieldDecl; |
42 | | class ObjCAtTryStmt; |
43 | | class ObjCAtThrowStmt; |
44 | | class ObjCAtSynchronizedStmt; |
45 | | class ObjCContainerDecl; |
46 | | class ObjCCategoryImplDecl; |
47 | | class ObjCImplementationDecl; |
48 | | class ObjCInterfaceDecl; |
49 | | class ObjCMessageExpr; |
50 | | class ObjCMethodDecl; |
51 | | class ObjCProtocolDecl; |
52 | | class Selector; |
53 | | class ObjCIvarDecl; |
54 | | class ObjCStringLiteral; |
55 | | class BlockDeclRefExpr; |
56 | | |
57 | | namespace CodeGen { |
58 | | class CodeGenModule; |
59 | | class CGBlockInfo; |
60 | | |
61 | | // FIXME: Several methods should be pure virtual but aren't to avoid the |
62 | | // partially-implemented subclass breaking. |
63 | | |
64 | | /// Implements runtime-specific code generation functions. |
65 | | class CGObjCRuntime { |
66 | | protected: |
67 | | CodeGen::CodeGenModule &CGM; |
68 | 23 | CGObjCRuntime(CodeGen::CodeGenModule &CGM) : CGM(CGM) {} |
69 | | |
70 | | // Utility functions for unified ivar access. These need to |
71 | | // eventually be folded into other places (the structure layout |
72 | | // code). |
73 | | |
74 | | /// Compute an offset to the given ivar, suitable for passing to |
75 | | /// EmitValueForIvarAtOffset. Note that the correct handling of |
76 | | /// bit-fields is carefully coordinated by these two, use caution! |
77 | | /// |
78 | | /// The latter overload is suitable for computing the offset of a |
79 | | /// sythesized ivar. |
80 | | uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, |
81 | | const ObjCInterfaceDecl *OID, |
82 | | const ObjCIvarDecl *Ivar); |
83 | | uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, |
84 | | const ObjCImplementationDecl *OID, |
85 | | const ObjCIvarDecl *Ivar); |
86 | | |
87 | | LValue EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, |
88 | | const ObjCInterfaceDecl *OID, |
89 | | llvm::Value *BaseValue, |
90 | | const ObjCIvarDecl *Ivar, |
91 | | unsigned CVRQualifiers, |
92 | | llvm::Value *Offset); |
93 | | /// Emits a try / catch statement. This function is intended to be called by |
94 | | /// subclasses, and provides a generic mechanism for generating these, which |
95 | | /// should be usable by all runtimes. The caller must provide the functions |
96 | | /// to call when entering and exiting a \@catch() block, and the function |
97 | | /// used to rethrow exceptions. If the begin and end catch functions are |
98 | | /// NULL, then the function assumes that the EH personality function provides |
99 | | /// the thrown object directly. |
100 | | void EmitTryCatchStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S, |
101 | | llvm::FunctionCallee beginCatchFn, |
102 | | llvm::FunctionCallee endCatchFn, |
103 | | llvm::FunctionCallee exceptionRethrowFn); |
104 | | |
105 | | void EmitInitOfCatchParam(CodeGenFunction &CGF, llvm::Value *exn, |
106 | | const VarDecl *paramDecl); |
107 | | |
108 | | /// Emits an \@synchronize() statement, using the \p syncEnterFn and |
109 | | /// \p syncExitFn arguments as the functions called to lock and unlock |
110 | | /// the object. This function can be called by subclasses that use |
111 | | /// zero-cost exception handling. |
112 | | void EmitAtSynchronizedStmt(CodeGenFunction &CGF, |
113 | | const ObjCAtSynchronizedStmt &S, |
114 | | llvm::FunctionCallee syncEnterFn, |
115 | | llvm::FunctionCallee syncExitFn); |
116 | | |
117 | | public: |
118 | | virtual ~CGObjCRuntime(); |
119 | | |
120 | | std::string getSymbolNameForMethod(const ObjCMethodDecl *method, |
121 | | bool includeCategoryName = true); |
122 | | |
123 | | /// Generate the function required to register all Objective-C components in |
124 | | /// this compilation unit with the runtime library. |
125 | | virtual llvm::Function *ModuleInitFunction() = 0; |
126 | | |
127 | | /// Get a selector for the specified name and type values. |
128 | | /// The result should have the LLVM type for ASTContext::getObjCSelType(). |
129 | | virtual llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel) = 0; |
130 | | |
131 | | /// Get the address of a selector for the specified name and type values. |
132 | | /// This is a rarely-used language extension, but sadly it exists. |
133 | | /// |
134 | | /// The result should have the LLVM type for a pointer to |
135 | | /// ASTContext::getObjCSelType(). |
136 | | virtual Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) = 0; |
137 | | |
138 | | /// Get a typed selector. |
139 | | virtual llvm::Value *GetSelector(CodeGenFunction &CGF, |
140 | | const ObjCMethodDecl *Method) = 0; |
141 | | |
142 | | /// Get the type constant to catch for the given ObjC pointer type. |
143 | | /// This is used externally to implement catching ObjC types in C++. |
144 | | /// Runtimes which don't support this should add the appropriate |
145 | | /// error to Sema. |
146 | | virtual llvm::Constant *GetEHType(QualType T) = 0; |
147 | | |
148 | 0 | virtual CatchTypeInfo getCatchAllTypeInfo() { return { nullptr, 0 }; } |
149 | | |
150 | | /// Generate a constant string object. |
151 | | virtual ConstantAddress GenerateConstantString(const StringLiteral *) = 0; |
152 | | |
153 | | /// Generate a category. A category contains a list of methods (and |
154 | | /// accompanying metadata) and a list of protocols. |
155 | | virtual void GenerateCategory(const ObjCCategoryImplDecl *OCD) = 0; |
156 | | |
157 | | /// Generate a class structure for this class. |
158 | | virtual void GenerateClass(const ObjCImplementationDecl *OID) = 0; |
159 | | |
160 | | /// Register an class alias. |
161 | | virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) = 0; |
162 | | |
163 | | /// Generate an Objective-C message send operation. |
164 | | /// |
165 | | /// \param Method - The method being called, this may be null if synthesizing |
166 | | /// a property setter or getter. |
167 | | virtual CodeGen::RValue |
168 | | GenerateMessageSend(CodeGen::CodeGenFunction &CGF, |
169 | | ReturnValueSlot ReturnSlot, |
170 | | QualType ResultType, |
171 | | Selector Sel, |
172 | | llvm::Value *Receiver, |
173 | | const CallArgList &CallArgs, |
174 | | const ObjCInterfaceDecl *Class = nullptr, |
175 | | const ObjCMethodDecl *Method = nullptr) = 0; |
176 | | |
177 | | /// Generate an Objective-C message send operation. |
178 | | /// |
179 | | /// This variant allows for the call to be substituted with an optimized |
180 | | /// variant. |
181 | | CodeGen::RValue |
182 | | GeneratePossiblySpecializedMessageSend(CodeGenFunction &CGF, |
183 | | ReturnValueSlot Return, |
184 | | QualType ResultType, |
185 | | Selector Sel, |
186 | | llvm::Value *Receiver, |
187 | | const CallArgList& Args, |
188 | | const ObjCInterfaceDecl *OID, |
189 | | const ObjCMethodDecl *Method, |
190 | | bool isClassMessage); |
191 | | |
192 | | /// Generate an Objective-C message send operation to the super |
193 | | /// class initiated in a method for Class and with the given Self |
194 | | /// object. |
195 | | /// |
196 | | /// \param Method - The method being called, this may be null if synthesizing |
197 | | /// a property setter or getter. |
198 | | virtual CodeGen::RValue |
199 | | GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, |
200 | | ReturnValueSlot ReturnSlot, |
201 | | QualType ResultType, |
202 | | Selector Sel, |
203 | | const ObjCInterfaceDecl *Class, |
204 | | bool isCategoryImpl, |
205 | | llvm::Value *Self, |
206 | | bool IsClassMessage, |
207 | | const CallArgList &CallArgs, |
208 | | const ObjCMethodDecl *Method = nullptr) = 0; |
209 | | |
210 | | /// Walk the list of protocol references from a class, category or |
211 | | /// protocol to traverse the DAG formed from it's inheritance hierarchy. Find |
212 | | /// the list of protocols that ends each walk at either a runtime |
213 | | /// protocol or a non-runtime protocol with no parents. For the common case of |
214 | | /// just a list of standard runtime protocols this just returns the same list |
215 | | /// that was passed in. |
216 | | std::vector<const ObjCProtocolDecl *> |
217 | | GetRuntimeProtocolList(ObjCProtocolDecl::protocol_iterator begin, |
218 | | ObjCProtocolDecl::protocol_iterator end); |
219 | | |
220 | | /// Emit the code to return the named protocol as an object, as in a |
221 | | /// \@protocol expression. |
222 | | virtual llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF, |
223 | | const ObjCProtocolDecl *OPD) = 0; |
224 | | |
225 | | /// Generate the named protocol. Protocols contain method metadata but no |
226 | | /// implementations. |
227 | | virtual void GenerateProtocol(const ObjCProtocolDecl *OPD) = 0; |
228 | | |
229 | | /// GetOrEmitProtocol - Get the protocol object for the given |
230 | | /// declaration, emitting it if necessary. The return value has type |
231 | | /// ProtocolPtrTy. |
232 | | virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) = 0; |
233 | | |
234 | | /// Generate a function preamble for a method with the specified |
235 | | /// types. |
236 | | |
237 | | // FIXME: Current this just generates the Function definition, but really this |
238 | | // should also be generating the loads of the parameters, as the runtime |
239 | | // should have full control over how parameters are passed. |
240 | | virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD, |
241 | | const ObjCContainerDecl *CD) = 0; |
242 | | |
243 | | /// Generates prologue for direct Objective-C Methods. |
244 | | virtual void GenerateDirectMethodPrologue(CodeGenFunction &CGF, |
245 | | llvm::Function *Fn, |
246 | | const ObjCMethodDecl *OMD, |
247 | | const ObjCContainerDecl *CD) = 0; |
248 | | |
249 | | /// Return the runtime function for getting properties. |
250 | | virtual llvm::FunctionCallee GetPropertyGetFunction() = 0; |
251 | | |
252 | | /// Return the runtime function for setting properties. |
253 | | virtual llvm::FunctionCallee GetPropertySetFunction() = 0; |
254 | | |
255 | | /// Return the runtime function for optimized setting properties. |
256 | | virtual llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic, |
257 | | bool copy) = 0; |
258 | | |
259 | | // API for atomic copying of qualified aggregates in getter. |
260 | | virtual llvm::FunctionCallee GetGetStructFunction() = 0; |
261 | | // API for atomic copying of qualified aggregates in setter. |
262 | | virtual llvm::FunctionCallee GetSetStructFunction() = 0; |
263 | | /// API for atomic copying of qualified aggregates with non-trivial copy |
264 | | /// assignment (c++) in setter. |
265 | | virtual llvm::FunctionCallee GetCppAtomicObjectSetFunction() = 0; |
266 | | /// API for atomic copying of qualified aggregates with non-trivial copy |
267 | | /// assignment (c++) in getter. |
268 | | virtual llvm::FunctionCallee GetCppAtomicObjectGetFunction() = 0; |
269 | | |
270 | | /// GetClass - Return a reference to the class for the given |
271 | | /// interface decl. |
272 | | virtual llvm::Value *GetClass(CodeGenFunction &CGF, |
273 | | const ObjCInterfaceDecl *OID) = 0; |
274 | | |
275 | | |
276 | 0 | virtual llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) { |
277 | 0 | llvm_unreachable("autoreleasepool unsupported in this ABI"); |
278 | 0 | } |
279 | | |
280 | | /// EnumerationMutationFunction - Return the function that's called by the |
281 | | /// compiler when a mutation is detected during foreach iteration. |
282 | | virtual llvm::FunctionCallee EnumerationMutationFunction() = 0; |
283 | | |
284 | | virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, |
285 | | const ObjCAtSynchronizedStmt &S) = 0; |
286 | | virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF, |
287 | | const ObjCAtTryStmt &S) = 0; |
288 | | virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, |
289 | | const ObjCAtThrowStmt &S, |
290 | | bool ClearInsertionPoint=true) = 0; |
291 | | virtual llvm::Value *EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, |
292 | | Address AddrWeakObj) = 0; |
293 | | virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, |
294 | | llvm::Value *src, Address dest) = 0; |
295 | | virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, |
296 | | llvm::Value *src, Address dest, |
297 | | bool threadlocal=false) = 0; |
298 | | virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, |
299 | | llvm::Value *src, Address dest, |
300 | | llvm::Value *ivarOffset) = 0; |
301 | | virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, |
302 | | llvm::Value *src, Address dest) = 0; |
303 | | |
304 | | virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, |
305 | | QualType ObjectTy, |
306 | | llvm::Value *BaseValue, |
307 | | const ObjCIvarDecl *Ivar, |
308 | | unsigned CVRQualifiers) = 0; |
309 | | virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF, |
310 | | const ObjCInterfaceDecl *Interface, |
311 | | const ObjCIvarDecl *Ivar) = 0; |
312 | | virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, |
313 | | Address DestPtr, |
314 | | Address SrcPtr, |
315 | | llvm::Value *Size) = 0; |
316 | | virtual llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM, |
317 | | const CodeGen::CGBlockInfo &blockInfo) = 0; |
318 | | virtual llvm::Constant *BuildRCBlockLayout(CodeGen::CodeGenModule &CGM, |
319 | | const CodeGen::CGBlockInfo &blockInfo) = 0; |
320 | | virtual std::string getRCBlockLayoutStr(CodeGen::CodeGenModule &CGM, |
321 | 0 | const CGBlockInfo &blockInfo) { |
322 | 0 | return {}; |
323 | 0 | } |
324 | | |
325 | | /// Returns an i8* which points to the byref layout information. |
326 | | virtual llvm::Constant *BuildByrefLayout(CodeGen::CodeGenModule &CGM, |
327 | | QualType T) = 0; |
328 | | |
329 | | struct MessageSendInfo { |
330 | | const CGFunctionInfo &CallInfo; |
331 | | llvm::PointerType *MessengerType; |
332 | | |
333 | | MessageSendInfo(const CGFunctionInfo &callInfo, |
334 | | llvm::PointerType *messengerType) |
335 | 0 | : CallInfo(callInfo), MessengerType(messengerType) {} |
336 | | }; |
337 | | |
338 | | MessageSendInfo getMessageSendInfo(const ObjCMethodDecl *method, |
339 | | QualType resultType, |
340 | | CallArgList &callArgs); |
341 | | bool canMessageReceiverBeNull(CodeGenFunction &CGF, |
342 | | const ObjCMethodDecl *method, |
343 | | bool isSuper, |
344 | | const ObjCInterfaceDecl *classReceiver, |
345 | | llvm::Value *receiver); |
346 | | static bool isWeakLinkedClass(const ObjCInterfaceDecl *cls); |
347 | | |
348 | | /// Destroy the callee-destroyed arguments of the given method, |
349 | | /// if it has any. Used for nil-receiver paths in message sends. |
350 | | /// Never does anything if the method does not satisfy |
351 | | /// hasParamDestroyedInCallee(). |
352 | | /// |
353 | | /// \param callArgs - just the formal arguments, not including implicit |
354 | | /// arguments such as self and cmd |
355 | | static void destroyCalleeDestroyedArguments(CodeGenFunction &CGF, |
356 | | const ObjCMethodDecl *method, |
357 | | const CallArgList &callArgs); |
358 | | |
359 | | // FIXME: This probably shouldn't be here, but the code to compute |
360 | | // it is here. |
361 | | unsigned ComputeBitfieldBitOffset(CodeGen::CodeGenModule &CGM, |
362 | | const ObjCInterfaceDecl *ID, |
363 | | const ObjCIvarDecl *Ivar); |
364 | | }; |
365 | | |
366 | | /// Creates an instance of an Objective-C runtime class. |
367 | | //TODO: This should include some way of selecting which runtime to target. |
368 | | CGObjCRuntime *CreateGNUObjCRuntime(CodeGenModule &CGM); |
369 | | CGObjCRuntime *CreateMacObjCRuntime(CodeGenModule &CGM); |
370 | | } |
371 | | } |
372 | | #endif |