CGObjCRuntime.h revision 249423
1176771Sraj//===----- CGObjCRuntime.h - Interface to ObjC Runtimes ---------*- C++ -*-===//
2192532Sraj//
3176771Sraj//                     The LLVM Compiler Infrastructure
4176771Sraj//
5176771Sraj// This file is distributed under the University of Illinois Open Source
6176771Sraj// License. See LICENSE.TXT for details.
7176771Sraj//
8176771Sraj//===----------------------------------------------------------------------===//
9176771Sraj//
10176771Sraj// This provides an abstract class for Objective-C code generation.  Concrete
11176771Sraj// subclasses of this implement code generation for specific Objective-C
12176771Sraj// runtime libraries.
13176771Sraj//
14176771Sraj//===----------------------------------------------------------------------===//
15176771Sraj
16176771Sraj#ifndef CLANG_CODEGEN_OBCJRUNTIME_H
17176771Sraj#define CLANG_CODEGEN_OBCJRUNTIME_H
18176771Sraj#include "CGBuilder.h"
19176771Sraj#include "CGCall.h"
20176771Sraj#include "CGValue.h"
21176771Sraj#include "clang/AST/DeclObjC.h"
22176771Sraj#include "clang/Basic/IdentifierTable.h" // Selector
23176771Sraj
24176771Srajnamespace llvm {
25176771Sraj  class Constant;
26176771Sraj  class Function;
27176771Sraj  class Module;
28176771Sraj  class StructLayout;
29176771Sraj  class StructType;
30176771Sraj  class Type;
31186229Sraj  class Value;
32191375Sraj}
33176771Sraj
34176771Srajnamespace clang {
35176771Srajnamespace CodeGen {
36176771Sraj  class CodeGenFunction;
37176771Sraj}
38176771Sraj
39176771Sraj  class FieldDecl;
40182198Sraj  class ObjCAtTryStmt;
41182198Sraj  class ObjCAtThrowStmt;
42184319Smarcel  class ObjCAtSynchronizedStmt;
43184319Smarcel  class ObjCContainerDecl;
44184319Smarcel  class ObjCCategoryImplDecl;
45184319Smarcel  class ObjCImplementationDecl;
46176771Sraj  class ObjCInterfaceDecl;
47176771Sraj  class ObjCMessageExpr;
48176771Sraj  class ObjCMethodDecl;
49176771Sraj  class ObjCProtocolDecl;
50176771Sraj  class Selector;
51176771Sraj  class ObjCIvarDecl;
52176771Sraj  class ObjCStringLiteral;
53176771Sraj  class BlockDeclRefExpr;
54176771Sraj
55176771Srajnamespace CodeGen {
56176771Sraj  class CodeGenModule;
57176771Sraj  class CGBlockInfo;
58176771Sraj
59176771Sraj// FIXME: Several methods should be pure virtual but aren't to avoid the
60176771Sraj// partially-implemented subclass breaking.
61186229Sraj
62176771Sraj/// Implements runtime-specific code generation functions.
63176771Srajclass CGObjCRuntime {
64176771Srajprotected:
65186229Sraj  CodeGen::CodeGenModule &CGM;
66176771Sraj  CGObjCRuntime(CodeGen::CodeGenModule &CGM) : CGM(CGM) {}
67186229Sraj
68176771Sraj  // Utility functions for unified ivar access. These need to
69186229Sraj  // eventually be folded into other places (the structure layout
70176771Sraj  // code).
71176771Sraj
72176771Sraj  /// Compute an offset to the given ivar, suitable for passing to
73176771Sraj  /// EmitValueForIvarAtOffset.  Note that the correct handling of
74186229Sraj  /// bit-fields is carefully coordinated by these two, use caution!
75176771Sraj  ///
76186229Sraj  /// The latter overload is suitable for computing the offset of a
77176771Sraj  /// sythesized ivar.
78186229Sraj  uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
79176771Sraj                                 const ObjCInterfaceDecl *OID,
80186229Sraj                                 const ObjCIvarDecl *Ivar);
81176771Sraj  uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
82176771Sraj                                 const ObjCImplementationDecl *OID,
83186229Sraj                                 const ObjCIvarDecl *Ivar);
84176771Sraj
85186229Sraj  LValue EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
86224611Smarcel                                  const ObjCInterfaceDecl *OID,
87222400Smarcel                                  llvm::Value *BaseValue,
88222400Smarcel                                  const ObjCIvarDecl *Ivar,
89222400Smarcel                                  unsigned CVRQualifiers,
90176771Sraj                                  llvm::Value *Offset);
91176771Sraj  /// Emits a try / catch statement.  This function is intended to be called by
92176771Sraj  /// subclasses, and provides a generic mechanism for generating these, which
93222400Smarcel  /// should be usable by all runtimes.  The caller must provide the functions
94176771Sraj  /// to call when entering and exiting a \@catch() block, and the function
95222400Smarcel  /// used to rethrow exceptions.  If the begin and end catch functions are
96222400Smarcel  /// NULL, then the function assumes that the EH personality function provides
97176771Sraj  /// the thrown object directly.
98176771Sraj  void EmitTryCatchStmt(CodeGenFunction &CGF,
99176771Sraj                        const ObjCAtTryStmt &S,
100176771Sraj                        llvm::Constant *beginCatchFn,
101186229Sraj                        llvm::Constant *endCatchFn,
102186229Sraj                        llvm::Constant *exceptionRethrowFn);
103176771Sraj  /// Emits an \@synchronize() statement, using the \p syncEnterFn and
104176771Sraj  /// \p syncExitFn arguments as the functions called to lock and unlock
105191375Sraj  /// the object.  This function can be called by subclasses that use
106191375Sraj  /// zero-cost exception handling.
107191375Sraj  void EmitAtSynchronizedStmt(CodeGenFunction &CGF,
108191375Sraj                            const ObjCAtSynchronizedStmt &S,
109191375Sraj                            llvm::Function *syncEnterFn,
110191375Sraj                            llvm::Function *syncExitFn);
111191375Sraj
112191375Srajpublic:
113191375Sraj  virtual ~CGObjCRuntime();
114186229Sraj
115186229Sraj  /// Generate the function required to register all Objective-C components in
116186229Sraj  /// this compilation unit with the runtime library.
117176771Sraj  virtual llvm::Function *ModuleInitFunction() = 0;
118224611Smarcel
119224611Smarcel  /// Get a selector for the specified name and type values. The
120224611Smarcel  /// return value should have the LLVM type for pointer-to
121176771Sraj  /// ASTContext::getObjCSelType().
122186229Sraj  virtual llvm::Value *GetSelector(CodeGenFunction &CGF,
123176771Sraj                                   Selector Sel, bool lval=false) = 0;
124186229Sraj
125186229Sraj  /// Get a typed selector.
126222400Smarcel  virtual llvm::Value *GetSelector(CodeGenFunction &CGF,
127176771Sraj                                   const ObjCMethodDecl *Method) = 0;
128186229Sraj
129242526Smarcel  /// Get the type constant to catch for the given ObjC pointer type.
130176771Sraj  /// This is used externally to implement catching ObjC types in C++.
131186229Sraj  /// Runtimes which don't support this should add the appropriate
132176771Sraj  /// error to Sema.
133242526Smarcel  virtual llvm::Constant *GetEHType(QualType T) = 0;
134186229Sraj
135176771Sraj  /// Generate a constant string object.
136186229Sraj  virtual llvm::Constant *GenerateConstantString(const StringLiteral *) = 0;
137186229Sraj
138186229Sraj  /// Generate a category.  A category contains a list of methods (and
139186229Sraj  /// accompanying metadata) and a list of protocols.
140186229Sraj  virtual void GenerateCategory(const ObjCCategoryImplDecl *OCD) = 0;
141186229Sraj
142186229Sraj  /// Generate a class structure for this class.
143176771Sraj  virtual void GenerateClass(const ObjCImplementationDecl *OID) = 0;
144176771Sraj
145176771Sraj  /// Register an class alias.
146176771Sraj  virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) = 0;
147176771Sraj
148222400Smarcel  /// Generate an Objective-C message send operation.
149176771Sraj  ///
150176771Sraj  /// \param Method - The method being called, this may be null if synthesizing
151176771Sraj  /// a property setter or getter.
152176771Sraj  virtual CodeGen::RValue
153176771Sraj  GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
154176771Sraj                      ReturnValueSlot ReturnSlot,
155186229Sraj                      QualType ResultType,
156222391Smarcel                      Selector Sel,
157186229Sraj                      llvm::Value *Receiver,
158186229Sraj                      const CallArgList &CallArgs,
159176771Sraj                      const ObjCInterfaceDecl *Class = 0,
160176771Sraj                      const ObjCMethodDecl *Method = 0) = 0;
161265996Sian
162186229Sraj  /// Generate an Objective-C message send operation to the super
163186229Sraj  /// class initiated in a method for Class and with the given Self
164176771Sraj  /// object.
165176771Sraj  ///
166186229Sraj  /// \param Method - The method being called, this may be null if synthesizing
167186229Sraj  /// a property setter or getter.
168192532Sraj  virtual CodeGen::RValue
169192532Sraj  GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
170192532Sraj                           ReturnValueSlot ReturnSlot,
171186229Sraj                           QualType ResultType,
172176771Sraj                           Selector Sel,
173176771Sraj                           const ObjCInterfaceDecl *Class,
174186229Sraj                           bool isCategoryImpl,
175186229Sraj                           llvm::Value *Self,
176186229Sraj                           bool IsClassMessage,
177186229Sraj                           const CallArgList &CallArgs,
178186229Sraj                           const ObjCMethodDecl *Method = 0) = 0;
179186229Sraj
180176771Sraj  /// Emit the code to return the named protocol as an object, as in a
181176771Sraj  /// \@protocol expression.
182176771Sraj  virtual llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
183176771Sraj                                           const ObjCProtocolDecl *OPD) = 0;
184176771Sraj
185176771Sraj  /// Generate the named protocol.  Protocols contain method metadata but no
186186229Sraj  /// implementations.
187186229Sraj  virtual void GenerateProtocol(const ObjCProtocolDecl *OPD) = 0;
188186229Sraj
189186229Sraj  /// Generate a function preamble for a method with the specified
190186229Sraj  /// types.
191186229Sraj
192186229Sraj  // FIXME: Current this just generates the Function definition, but really this
193186229Sraj  // should also be generating the loads of the parameters, as the runtime
194186229Sraj  // should have full control over how parameters are passed.
195176771Sraj  virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
196176771Sraj                                         const ObjCContainerDecl *CD) = 0;
197176771Sraj
198176771Sraj  /// Return the runtime function for getting properties.
199176771Sraj  virtual llvm::Constant *GetPropertyGetFunction() = 0;
200222400Smarcel
201176771Sraj  /// Return the runtime function for setting properties.
202176771Sraj  virtual llvm::Constant *GetPropertySetFunction() = 0;
203224611Smarcel
204186229Sraj  /// Return the runtime function for optimized setting properties.
205186229Sraj  virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
206176771Sraj                                                          bool copy) = 0;
207176771Sraj
208182198Sraj  // API for atomic copying of qualified aggregates in getter.
209182198Sraj  virtual llvm::Constant *GetGetStructFunction() = 0;
210182198Sraj  // API for atomic copying of qualified aggregates in setter.
211176771Sraj  virtual llvm::Constant *GetSetStructFunction() = 0;
212176771Sraj  /// API for atomic copying of qualified aggregates with non-trivial copy
213186289Sraj  /// assignment (c++) in setter.
214176771Sraj  virtual llvm::Constant *GetCppAtomicObjectSetFunction() = 0;
215176771Sraj  /// API for atomic copying of qualified aggregates with non-trivial copy
216176771Sraj  /// assignment (c++) in getter.
217176771Sraj  virtual llvm::Constant *GetCppAtomicObjectGetFunction() = 0;
218186229Sraj
219176771Sraj  /// GetClass - Return a reference to the class for the given
220222400Smarcel  /// interface decl.
221222400Smarcel  virtual llvm::Value *GetClass(CodeGenFunction &CGF,
222176771Sraj                                const ObjCInterfaceDecl *OID) = 0;
223236141Sraj
224222400Smarcel
225182198Sraj  virtual llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
226186229Sraj    llvm_unreachable("autoreleasepool unsupported in this ABI");
227182198Sraj  }
228182198Sraj
229182198Sraj  /// EnumerationMutationFunction - Return the function that's called by the
230182198Sraj  /// compiler when a mutation is detected during foreach iteration.
231186229Sraj  virtual llvm::Constant *EnumerationMutationFunction() = 0;
232186229Sraj
233186229Sraj  virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
234186229Sraj                                    const ObjCAtSynchronizedStmt &S) = 0;
235176771Sraj  virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
236192532Sraj                           const ObjCAtTryStmt &S) = 0;
237192532Sraj  virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
238192532Sraj                             const ObjCAtThrowStmt &S,
239192532Sraj                             bool ClearInsertionPoint=true) = 0;
240192532Sraj  virtual llvm::Value *EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
241192532Sraj                                        llvm::Value *AddrWeakObj) = 0;
242192532Sraj  virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
243192532Sraj                                  llvm::Value *src, llvm::Value *dest) = 0;
244192532Sraj  virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
245192532Sraj                                    llvm::Value *src, llvm::Value *dest,
246192532Sraj                                    bool threadlocal=false) = 0;
247242526Smarcel  virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
248242526Smarcel                                  llvm::Value *src, llvm::Value *dest,
249192532Sraj                                  llvm::Value *ivarOffset) = 0;
250192532Sraj  virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
251242526Smarcel                                        llvm::Value *src, llvm::Value *dest) = 0;
252242526Smarcel
253242526Smarcel  virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
254235932Smarcel                                      QualType ObjectTy,
255242526Smarcel                                      llvm::Value *BaseValue,
256242526Smarcel                                      const ObjCIvarDecl *Ivar,
257242526Smarcel                                      unsigned CVRQualifiers) = 0;
258186229Sraj  virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
259192532Sraj                                      const ObjCInterfaceDecl *Interface,
260192532Sraj                                      const ObjCIvarDecl *Ivar) = 0;
261242526Smarcel  virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
262235932Smarcel                                        llvm::Value *DestPtr,
263192532Sraj                                        llvm::Value *SrcPtr,
264192532Sraj                                        llvm::Value *Size) = 0;
265192532Sraj  virtual llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
266192532Sraj                                  const CodeGen::CGBlockInfo &blockInfo) = 0;
267192532Sraj  virtual llvm::Constant *BuildRCBlockLayout(CodeGen::CodeGenModule &CGM,
268192532Sraj                                  const CodeGen::CGBlockInfo &blockInfo) = 0;
269192532Sraj  virtual llvm::Constant *BuildByrefLayout(CodeGen::CodeGenModule &CGM,
270192532Sraj                                           QualType T) = 0;
271192532Sraj  virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) = 0;
272192532Sraj
273192532Sraj  struct MessageSendInfo {
274192532Sraj    const CGFunctionInfo &CallInfo;
275192532Sraj    llvm::PointerType *MessengerType;
276192532Sraj
277192532Sraj    MessageSendInfo(const CGFunctionInfo &callInfo,
278192532Sraj                    llvm::PointerType *messengerType)
279192532Sraj      : CallInfo(callInfo), MessengerType(messengerType) {}
280192532Sraj  };
281192532Sraj
282192532Sraj  MessageSendInfo getMessageSendInfo(const ObjCMethodDecl *method,
283192532Sraj                                     QualType resultType,
284192532Sraj                                     CallArgList &callArgs);
285192532Sraj
286192532Sraj  // FIXME: This probably shouldn't be here, but the code to compute
287222400Smarcel  // it is here.
288192532Sraj  unsigned ComputeBitfieldBitOffset(CodeGen::CodeGenModule &CGM,
289192532Sraj                                    const ObjCInterfaceDecl *ID,
290242526Smarcel                                    const ObjCIvarDecl *Ivar);
291192532Sraj};
292192532Sraj
293192532Sraj/// Creates an instance of an Objective-C runtime class.
294242526Smarcel//TODO: This should include some way of selecting which runtime to target.
295192532SrajCGObjCRuntime *CreateGNUObjCRuntime(CodeGenModule &CGM);
296192532SrajCGObjCRuntime *CreateMacObjCRuntime(CodeGenModule &CGM);
297192532Sraj}
298192532Sraj}
299192532Sraj#endif
300192532Sraj