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