xref: /aosp_15_r20/external/clang/lib/CodeGen/CGObjCRuntime.h (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //===----- CGObjCRuntime.h - Interface to ObjC Runtimes ---------*- C++ -*-===//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This provides an abstract class for Objective-C code generation.  Concrete
11*67e74705SXin Li // subclasses of this implement code generation for specific Objective-C
12*67e74705SXin Li // runtime libraries.
13*67e74705SXin Li //
14*67e74705SXin Li //===----------------------------------------------------------------------===//
15*67e74705SXin Li 
16*67e74705SXin Li #ifndef LLVM_CLANG_LIB_CODEGEN_CGOBJCRUNTIME_H
17*67e74705SXin Li #define LLVM_CLANG_LIB_CODEGEN_CGOBJCRUNTIME_H
18*67e74705SXin Li #include "CGBuilder.h"
19*67e74705SXin Li #include "CGCall.h"
20*67e74705SXin Li #include "CGValue.h"
21*67e74705SXin Li #include "clang/AST/DeclObjC.h"
22*67e74705SXin Li #include "clang/Basic/IdentifierTable.h" // Selector
23*67e74705SXin Li 
24*67e74705SXin Li namespace llvm {
25*67e74705SXin Li   class Constant;
26*67e74705SXin Li   class Function;
27*67e74705SXin Li   class Module;
28*67e74705SXin Li   class StructLayout;
29*67e74705SXin Li   class StructType;
30*67e74705SXin Li   class Type;
31*67e74705SXin Li   class Value;
32*67e74705SXin Li }
33*67e74705SXin Li 
34*67e74705SXin Li namespace clang {
35*67e74705SXin Li namespace CodeGen {
36*67e74705SXin Li   class CodeGenFunction;
37*67e74705SXin Li }
38*67e74705SXin Li 
39*67e74705SXin Li   class FieldDecl;
40*67e74705SXin Li   class ObjCAtTryStmt;
41*67e74705SXin Li   class ObjCAtThrowStmt;
42*67e74705SXin Li   class ObjCAtSynchronizedStmt;
43*67e74705SXin Li   class ObjCContainerDecl;
44*67e74705SXin Li   class ObjCCategoryImplDecl;
45*67e74705SXin Li   class ObjCImplementationDecl;
46*67e74705SXin Li   class ObjCInterfaceDecl;
47*67e74705SXin Li   class ObjCMessageExpr;
48*67e74705SXin Li   class ObjCMethodDecl;
49*67e74705SXin Li   class ObjCProtocolDecl;
50*67e74705SXin Li   class Selector;
51*67e74705SXin Li   class ObjCIvarDecl;
52*67e74705SXin Li   class ObjCStringLiteral;
53*67e74705SXin Li   class BlockDeclRefExpr;
54*67e74705SXin Li 
55*67e74705SXin Li namespace CodeGen {
56*67e74705SXin Li   class CodeGenModule;
57*67e74705SXin Li   class CGBlockInfo;
58*67e74705SXin Li 
59*67e74705SXin Li // FIXME: Several methods should be pure virtual but aren't to avoid the
60*67e74705SXin Li // partially-implemented subclass breaking.
61*67e74705SXin Li 
62*67e74705SXin Li /// Implements runtime-specific code generation functions.
63*67e74705SXin Li class CGObjCRuntime {
64*67e74705SXin Li protected:
65*67e74705SXin Li   CodeGen::CodeGenModule &CGM;
CGObjCRuntime(CodeGen::CodeGenModule & CGM)66*67e74705SXin Li   CGObjCRuntime(CodeGen::CodeGenModule &CGM) : CGM(CGM) {}
67*67e74705SXin Li 
68*67e74705SXin Li   // Utility functions for unified ivar access. These need to
69*67e74705SXin Li   // eventually be folded into other places (the structure layout
70*67e74705SXin Li   // code).
71*67e74705SXin Li 
72*67e74705SXin Li   /// Compute an offset to the given ivar, suitable for passing to
73*67e74705SXin Li   /// EmitValueForIvarAtOffset.  Note that the correct handling of
74*67e74705SXin Li   /// bit-fields is carefully coordinated by these two, use caution!
75*67e74705SXin Li   ///
76*67e74705SXin Li   /// The latter overload is suitable for computing the offset of a
77*67e74705SXin Li   /// sythesized ivar.
78*67e74705SXin Li   uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
79*67e74705SXin Li                                  const ObjCInterfaceDecl *OID,
80*67e74705SXin Li                                  const ObjCIvarDecl *Ivar);
81*67e74705SXin Li   uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
82*67e74705SXin Li                                  const ObjCImplementationDecl *OID,
83*67e74705SXin Li                                  const ObjCIvarDecl *Ivar);
84*67e74705SXin Li 
85*67e74705SXin Li   LValue EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
86*67e74705SXin Li                                   const ObjCInterfaceDecl *OID,
87*67e74705SXin Li                                   llvm::Value *BaseValue,
88*67e74705SXin Li                                   const ObjCIvarDecl *Ivar,
89*67e74705SXin Li                                   unsigned CVRQualifiers,
90*67e74705SXin Li                                   llvm::Value *Offset);
91*67e74705SXin Li   /// Emits a try / catch statement.  This function is intended to be called by
92*67e74705SXin Li   /// subclasses, and provides a generic mechanism for generating these, which
93*67e74705SXin Li   /// should be usable by all runtimes.  The caller must provide the functions
94*67e74705SXin Li   /// to call when entering and exiting a \@catch() block, and the function
95*67e74705SXin Li   /// used to rethrow exceptions.  If the begin and end catch functions are
96*67e74705SXin Li   /// NULL, then the function assumes that the EH personality function provides
97*67e74705SXin Li   /// the thrown object directly.
98*67e74705SXin Li   void EmitTryCatchStmt(CodeGenFunction &CGF,
99*67e74705SXin Li                         const ObjCAtTryStmt &S,
100*67e74705SXin Li                         llvm::Constant *beginCatchFn,
101*67e74705SXin Li                         llvm::Constant *endCatchFn,
102*67e74705SXin Li                         llvm::Constant *exceptionRethrowFn);
103*67e74705SXin Li 
104*67e74705SXin Li   void EmitInitOfCatchParam(CodeGenFunction &CGF, llvm::Value *exn,
105*67e74705SXin Li                             const VarDecl *paramDecl);
106*67e74705SXin Li 
107*67e74705SXin Li   /// Emits an \@synchronize() statement, using the \p syncEnterFn and
108*67e74705SXin Li   /// \p syncExitFn arguments as the functions called to lock and unlock
109*67e74705SXin Li   /// the object.  This function can be called by subclasses that use
110*67e74705SXin Li   /// zero-cost exception handling.
111*67e74705SXin Li   void EmitAtSynchronizedStmt(CodeGenFunction &CGF,
112*67e74705SXin Li                             const ObjCAtSynchronizedStmt &S,
113*67e74705SXin Li                             llvm::Function *syncEnterFn,
114*67e74705SXin Li                             llvm::Function *syncExitFn);
115*67e74705SXin Li 
116*67e74705SXin Li public:
117*67e74705SXin Li   virtual ~CGObjCRuntime();
118*67e74705SXin Li 
119*67e74705SXin Li   /// Generate the function required to register all Objective-C components in
120*67e74705SXin Li   /// this compilation unit with the runtime library.
121*67e74705SXin Li   virtual llvm::Function *ModuleInitFunction() = 0;
122*67e74705SXin Li 
123*67e74705SXin Li   /// Get a selector for the specified name and type values.
124*67e74705SXin Li   /// The result should have the LLVM type for ASTContext::getObjCSelType().
125*67e74705SXin Li   virtual llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel) = 0;
126*67e74705SXin Li 
127*67e74705SXin Li   /// Get the address of a selector for the specified name and type values.
128*67e74705SXin Li   /// This is a rarely-used language extension, but sadly it exists.
129*67e74705SXin Li   ///
130*67e74705SXin Li   /// The result should have the LLVM type for a pointer to
131*67e74705SXin Li   /// ASTContext::getObjCSelType().
132*67e74705SXin Li   virtual Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) = 0;
133*67e74705SXin Li 
134*67e74705SXin Li   /// Get a typed selector.
135*67e74705SXin Li   virtual llvm::Value *GetSelector(CodeGenFunction &CGF,
136*67e74705SXin Li                                    const ObjCMethodDecl *Method) = 0;
137*67e74705SXin Li 
138*67e74705SXin Li   /// Get the type constant to catch for the given ObjC pointer type.
139*67e74705SXin Li   /// This is used externally to implement catching ObjC types in C++.
140*67e74705SXin Li   /// Runtimes which don't support this should add the appropriate
141*67e74705SXin Li   /// error to Sema.
142*67e74705SXin Li   virtual llvm::Constant *GetEHType(QualType T) = 0;
143*67e74705SXin Li 
144*67e74705SXin Li   /// Generate a constant string object.
145*67e74705SXin Li   virtual ConstantAddress GenerateConstantString(const StringLiteral *) = 0;
146*67e74705SXin Li 
147*67e74705SXin Li   /// Generate a category.  A category contains a list of methods (and
148*67e74705SXin Li   /// accompanying metadata) and a list of protocols.
149*67e74705SXin Li   virtual void GenerateCategory(const ObjCCategoryImplDecl *OCD) = 0;
150*67e74705SXin Li 
151*67e74705SXin Li   /// Generate a class structure for this class.
152*67e74705SXin Li   virtual void GenerateClass(const ObjCImplementationDecl *OID) = 0;
153*67e74705SXin Li 
154*67e74705SXin Li   /// Register an class alias.
155*67e74705SXin Li   virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) = 0;
156*67e74705SXin Li 
157*67e74705SXin Li   /// Generate an Objective-C message send operation.
158*67e74705SXin Li   ///
159*67e74705SXin Li   /// \param Method - The method being called, this may be null if synthesizing
160*67e74705SXin Li   /// a property setter or getter.
161*67e74705SXin Li   virtual CodeGen::RValue
162*67e74705SXin Li   GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
163*67e74705SXin Li                       ReturnValueSlot ReturnSlot,
164*67e74705SXin Li                       QualType ResultType,
165*67e74705SXin Li                       Selector Sel,
166*67e74705SXin Li                       llvm::Value *Receiver,
167*67e74705SXin Li                       const CallArgList &CallArgs,
168*67e74705SXin Li                       const ObjCInterfaceDecl *Class = nullptr,
169*67e74705SXin Li                       const ObjCMethodDecl *Method = nullptr) = 0;
170*67e74705SXin Li 
171*67e74705SXin Li   /// Generate an Objective-C message send operation to the super
172*67e74705SXin Li   /// class initiated in a method for Class and with the given Self
173*67e74705SXin Li   /// object.
174*67e74705SXin Li   ///
175*67e74705SXin Li   /// \param Method - The method being called, this may be null if synthesizing
176*67e74705SXin Li   /// a property setter or getter.
177*67e74705SXin Li   virtual CodeGen::RValue
178*67e74705SXin Li   GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
179*67e74705SXin Li                            ReturnValueSlot ReturnSlot,
180*67e74705SXin Li                            QualType ResultType,
181*67e74705SXin Li                            Selector Sel,
182*67e74705SXin Li                            const ObjCInterfaceDecl *Class,
183*67e74705SXin Li                            bool isCategoryImpl,
184*67e74705SXin Li                            llvm::Value *Self,
185*67e74705SXin Li                            bool IsClassMessage,
186*67e74705SXin Li                            const CallArgList &CallArgs,
187*67e74705SXin Li                            const ObjCMethodDecl *Method = nullptr) = 0;
188*67e74705SXin Li 
189*67e74705SXin Li   /// Emit the code to return the named protocol as an object, as in a
190*67e74705SXin Li   /// \@protocol expression.
191*67e74705SXin Li   virtual llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
192*67e74705SXin Li                                            const ObjCProtocolDecl *OPD) = 0;
193*67e74705SXin Li 
194*67e74705SXin Li   /// Generate the named protocol.  Protocols contain method metadata but no
195*67e74705SXin Li   /// implementations.
196*67e74705SXin Li   virtual void GenerateProtocol(const ObjCProtocolDecl *OPD) = 0;
197*67e74705SXin Li 
198*67e74705SXin Li   /// Generate a function preamble for a method with the specified
199*67e74705SXin Li   /// types.
200*67e74705SXin Li 
201*67e74705SXin Li   // FIXME: Current this just generates the Function definition, but really this
202*67e74705SXin Li   // should also be generating the loads of the parameters, as the runtime
203*67e74705SXin Li   // should have full control over how parameters are passed.
204*67e74705SXin Li   virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
205*67e74705SXin Li                                          const ObjCContainerDecl *CD) = 0;
206*67e74705SXin Li 
207*67e74705SXin Li   /// Return the runtime function for getting properties.
208*67e74705SXin Li   virtual llvm::Constant *GetPropertyGetFunction() = 0;
209*67e74705SXin Li 
210*67e74705SXin Li   /// Return the runtime function for setting properties.
211*67e74705SXin Li   virtual llvm::Constant *GetPropertySetFunction() = 0;
212*67e74705SXin Li 
213*67e74705SXin Li   /// Return the runtime function for optimized setting properties.
214*67e74705SXin Li   virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
215*67e74705SXin Li                                                           bool copy) = 0;
216*67e74705SXin Li 
217*67e74705SXin Li   // API for atomic copying of qualified aggregates in getter.
218*67e74705SXin Li   virtual llvm::Constant *GetGetStructFunction() = 0;
219*67e74705SXin Li   // API for atomic copying of qualified aggregates in setter.
220*67e74705SXin Li   virtual llvm::Constant *GetSetStructFunction() = 0;
221*67e74705SXin Li   /// API for atomic copying of qualified aggregates with non-trivial copy
222*67e74705SXin Li   /// assignment (c++) in setter.
223*67e74705SXin Li   virtual llvm::Constant *GetCppAtomicObjectSetFunction() = 0;
224*67e74705SXin Li   /// API for atomic copying of qualified aggregates with non-trivial copy
225*67e74705SXin Li   /// assignment (c++) in getter.
226*67e74705SXin Li   virtual llvm::Constant *GetCppAtomicObjectGetFunction() = 0;
227*67e74705SXin Li 
228*67e74705SXin Li   /// GetClass - Return a reference to the class for the given
229*67e74705SXin Li   /// interface decl.
230*67e74705SXin Li   virtual llvm::Value *GetClass(CodeGenFunction &CGF,
231*67e74705SXin Li                                 const ObjCInterfaceDecl *OID) = 0;
232*67e74705SXin Li 
233*67e74705SXin Li 
EmitNSAutoreleasePoolClassRef(CodeGenFunction & CGF)234*67e74705SXin Li   virtual llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
235*67e74705SXin Li     llvm_unreachable("autoreleasepool unsupported in this ABI");
236*67e74705SXin Li   }
237*67e74705SXin Li 
238*67e74705SXin Li   /// EnumerationMutationFunction - Return the function that's called by the
239*67e74705SXin Li   /// compiler when a mutation is detected during foreach iteration.
240*67e74705SXin Li   virtual llvm::Constant *EnumerationMutationFunction() = 0;
241*67e74705SXin Li 
242*67e74705SXin Li   virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
243*67e74705SXin Li                                     const ObjCAtSynchronizedStmt &S) = 0;
244*67e74705SXin Li   virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
245*67e74705SXin Li                            const ObjCAtTryStmt &S) = 0;
246*67e74705SXin Li   virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
247*67e74705SXin Li                              const ObjCAtThrowStmt &S,
248*67e74705SXin Li                              bool ClearInsertionPoint=true) = 0;
249*67e74705SXin Li   virtual llvm::Value *EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
250*67e74705SXin Li                                         Address AddrWeakObj) = 0;
251*67e74705SXin Li   virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
252*67e74705SXin Li                                   llvm::Value *src, Address dest) = 0;
253*67e74705SXin Li   virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
254*67e74705SXin Li                                     llvm::Value *src, Address dest,
255*67e74705SXin Li                                     bool threadlocal=false) = 0;
256*67e74705SXin Li   virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
257*67e74705SXin Li                                   llvm::Value *src, Address dest,
258*67e74705SXin Li                                   llvm::Value *ivarOffset) = 0;
259*67e74705SXin Li   virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
260*67e74705SXin Li                                         llvm::Value *src, Address dest) = 0;
261*67e74705SXin Li 
262*67e74705SXin Li   virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
263*67e74705SXin Li                                       QualType ObjectTy,
264*67e74705SXin Li                                       llvm::Value *BaseValue,
265*67e74705SXin Li                                       const ObjCIvarDecl *Ivar,
266*67e74705SXin Li                                       unsigned CVRQualifiers) = 0;
267*67e74705SXin Li   virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
268*67e74705SXin Li                                       const ObjCInterfaceDecl *Interface,
269*67e74705SXin Li                                       const ObjCIvarDecl *Ivar) = 0;
270*67e74705SXin Li   virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
271*67e74705SXin Li                                         Address DestPtr,
272*67e74705SXin Li                                         Address SrcPtr,
273*67e74705SXin Li                                         llvm::Value *Size) = 0;
274*67e74705SXin Li   virtual llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
275*67e74705SXin Li                                   const CodeGen::CGBlockInfo &blockInfo) = 0;
276*67e74705SXin Li   virtual llvm::Constant *BuildRCBlockLayout(CodeGen::CodeGenModule &CGM,
277*67e74705SXin Li                                   const CodeGen::CGBlockInfo &blockInfo) = 0;
278*67e74705SXin Li 
279*67e74705SXin Li   /// Returns an i8* which points to the byref layout information.
280*67e74705SXin Li   virtual llvm::Constant *BuildByrefLayout(CodeGen::CodeGenModule &CGM,
281*67e74705SXin Li                                            QualType T) = 0;
282*67e74705SXin Li 
283*67e74705SXin Li   virtual llvm::GlobalVariable *GetClassGlobal(StringRef Name,
284*67e74705SXin Li                                                bool Weak = false) = 0;
285*67e74705SXin Li 
286*67e74705SXin Li   struct MessageSendInfo {
287*67e74705SXin Li     const CGFunctionInfo &CallInfo;
288*67e74705SXin Li     llvm::PointerType *MessengerType;
289*67e74705SXin Li 
MessageSendInfoMessageSendInfo290*67e74705SXin Li     MessageSendInfo(const CGFunctionInfo &callInfo,
291*67e74705SXin Li                     llvm::PointerType *messengerType)
292*67e74705SXin Li       : CallInfo(callInfo), MessengerType(messengerType) {}
293*67e74705SXin Li   };
294*67e74705SXin Li 
295*67e74705SXin Li   MessageSendInfo getMessageSendInfo(const ObjCMethodDecl *method,
296*67e74705SXin Li                                      QualType resultType,
297*67e74705SXin Li                                      CallArgList &callArgs);
298*67e74705SXin Li 
299*67e74705SXin Li   // FIXME: This probably shouldn't be here, but the code to compute
300*67e74705SXin Li   // it is here.
301*67e74705SXin Li   unsigned ComputeBitfieldBitOffset(CodeGen::CodeGenModule &CGM,
302*67e74705SXin Li                                     const ObjCInterfaceDecl *ID,
303*67e74705SXin Li                                     const ObjCIvarDecl *Ivar);
304*67e74705SXin Li };
305*67e74705SXin Li 
306*67e74705SXin Li /// Creates an instance of an Objective-C runtime class.
307*67e74705SXin Li //TODO: This should include some way of selecting which runtime to target.
308*67e74705SXin Li CGObjCRuntime *CreateGNUObjCRuntime(CodeGenModule &CGM);
309*67e74705SXin Li CGObjCRuntime *CreateMacObjCRuntime(CodeGenModule &CGM);
310*67e74705SXin Li }
311*67e74705SXin Li }
312*67e74705SXin Li #endif
313