Home | History | Annotate | Download | only in CodeGen
      1 //===----- CGObjCRuntime.h - Interface to ObjC Runtimes ---------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This provides an abstract class for Objective-C code generation.  Concrete
     11 // subclasses of this implement code generation for specific Objective-C
     12 // runtime libraries.
     13 //
     14 //===----------------------------------------------------------------------===//
     15 
     16 #ifndef CLANG_CODEGEN_OBCJRUNTIME_H
     17 #define CLANG_CODEGEN_OBCJRUNTIME_H
     18 #include "clang/Basic/IdentifierTable.h" // Selector
     19 #include "clang/AST/DeclObjC.h"
     20 
     21 #include "CGBuilder.h"
     22 #include "CGCall.h"
     23 #include "CGValue.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   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 to
     95   /// call when entering and exiting a @catch() block, and the function used to
     96   /// rethrow exceptions.  If the begin and end catch functions are NULL, then
     97   /// the function assumes that the EH personality function provides the
     98   /// thrown object directly.
     99   void EmitTryCatchStmt(CodeGenFunction &CGF,
    100                         const ObjCAtTryStmt &S,
    101                         llvm::Constant *beginCatchFn,
    102                         llvm::Constant *endCatchFn,
    103                         llvm::Constant *exceptionRethrowFn);
    104   /// Emits an @synchronize() statement, using the syncEnterFn and syncExitFn
    105   /// arguments as the functions called to lock and unlock the object.  This
    106   /// function can be called by subclasses that use zero-cost exception
    107   /// handling.
    108   void EmitAtSynchronizedStmt(CodeGenFunction &CGF,
    109                             const ObjCAtSynchronizedStmt &S,
    110                             llvm::Function *syncEnterFn,
    111                             llvm::Function *syncExitFn);
    112 
    113 public:
    114   virtual ~CGObjCRuntime();
    115 
    116   /// Generate the function required to register all Objective-C components in
    117   /// this compilation unit with the runtime library.
    118   virtual llvm::Function *ModuleInitFunction() = 0;
    119 
    120   /// Get a selector for the specified name and type values. The
    121   /// return value should have the LLVM type for pointer-to
    122   /// ASTContext::getObjCSelType().
    123   virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
    124                                    Selector Sel, bool lval=false) = 0;
    125 
    126   /// Get a typed selector.
    127   virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
    128                                    const ObjCMethodDecl *Method) = 0;
    129 
    130   /// Get the type constant to catch for the given ObjC pointer type.
    131   /// This is used externally to implement catching ObjC types in C++.
    132   /// Runtimes which don't support this should add the appropriate
    133   /// error to Sema.
    134   virtual llvm::Constant *GetEHType(QualType T) = 0;
    135 
    136   /// Generate a constant string object.
    137   virtual llvm::Constant *GenerateConstantString(const StringLiteral *) = 0;
    138 
    139   /// Generate a category.  A category contains a list of methods (and
    140   /// accompanying metadata) and a list of protocols.
    141   virtual void GenerateCategory(const ObjCCategoryImplDecl *OCD) = 0;
    142 
    143   /// Generate a class structure for this class.
    144   virtual void GenerateClass(const ObjCImplementationDecl *OID) = 0;
    145 
    146   /// Register an class alias.
    147   virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) = 0;
    148 
    149   /// Generate an Objective-C message send operation.
    150   ///
    151   /// \param Method - The method being called, this may be null if synthesizing
    152   /// a property setter or getter.
    153   virtual CodeGen::RValue
    154   GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
    155                       ReturnValueSlot ReturnSlot,
    156                       QualType ResultType,
    157                       Selector Sel,
    158                       llvm::Value *Receiver,
    159                       const CallArgList &CallArgs,
    160                       const ObjCInterfaceDecl *Class = 0,
    161                       const ObjCMethodDecl *Method = 0) = 0;
    162 
    163   /// Generate an Objective-C message send operation to the super
    164   /// class initiated in a method for Class and with the given Self
    165   /// object.
    166   ///
    167   /// \param Method - The method being called, this may be null if synthesizing
    168   /// a property setter or getter.
    169   virtual CodeGen::RValue
    170   GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
    171                            ReturnValueSlot ReturnSlot,
    172                            QualType ResultType,
    173                            Selector Sel,
    174                            const ObjCInterfaceDecl *Class,
    175                            bool isCategoryImpl,
    176                            llvm::Value *Self,
    177                            bool IsClassMessage,
    178                            const CallArgList &CallArgs,
    179                            const ObjCMethodDecl *Method = 0) = 0;
    180 
    181   /// Emit the code to return the named protocol as an object, as in a
    182   /// @protocol expression.
    183   virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
    184                                            const ObjCProtocolDecl *OPD) = 0;
    185 
    186   /// Generate the named protocol.  Protocols contain method metadata but no
    187   /// implementations.
    188   virtual void GenerateProtocol(const ObjCProtocolDecl *OPD) = 0;
    189 
    190   /// Generate a function preamble for a method with the specified
    191   /// types.
    192 
    193   // FIXME: Current this just generates the Function definition, but really this
    194   // should also be generating the loads of the parameters, as the runtime
    195   // should have full control over how parameters are passed.
    196   virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
    197                                          const ObjCContainerDecl *CD) = 0;
    198 
    199   /// Return the runtime function for getting properties.
    200   virtual llvm::Constant *GetPropertyGetFunction() = 0;
    201 
    202   /// Return the runtime function for setting properties.
    203   virtual llvm::Constant *GetPropertySetFunction() = 0;
    204 
    205   /// Return the runtime function for optimized setting properties.
    206   virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
    207                                                           bool copy) = 0;
    208 
    209   // API for atomic copying of qualified aggregates in getter.
    210   virtual llvm::Constant *GetGetStructFunction() = 0;
    211   // API for atomic copying of qualified aggregates in setter.
    212   virtual llvm::Constant *GetSetStructFunction() = 0;
    213   // API for atomic copying of qualified aggregates with non-trivial copy
    214   // assignment (c++) in setter/getter.
    215   virtual llvm::Constant *GetCppAtomicObjectFunction() = 0;
    216 
    217   /// GetClass - Return a reference to the class for the given
    218   /// interface decl.
    219   virtual llvm::Value *GetClass(CGBuilderTy &Builder,
    220                                 const ObjCInterfaceDecl *OID) = 0;
    221 
    222 
    223   virtual llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder) {
    224     llvm_unreachable("autoreleasepool unsupported in this ABI");
    225   }
    226 
    227   /// EnumerationMutationFunction - Return the function that's called by the
    228   /// compiler when a mutation is detected during foreach iteration.
    229   virtual llvm::Constant *EnumerationMutationFunction() = 0;
    230 
    231   virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
    232                                     const ObjCAtSynchronizedStmt &S) = 0;
    233   virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
    234                            const ObjCAtTryStmt &S) = 0;
    235   virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
    236                              const ObjCAtThrowStmt &S) = 0;
    237   virtual llvm::Value *EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
    238                                         llvm::Value *AddrWeakObj) = 0;
    239   virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
    240                                   llvm::Value *src, llvm::Value *dest) = 0;
    241   virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
    242                                     llvm::Value *src, llvm::Value *dest,
    243                                     bool threadlocal=false) = 0;
    244   virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
    245                                   llvm::Value *src, llvm::Value *dest,
    246                                   llvm::Value *ivarOffset) = 0;
    247   virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
    248                                         llvm::Value *src, llvm::Value *dest) = 0;
    249 
    250   virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
    251                                       QualType ObjectTy,
    252                                       llvm::Value *BaseValue,
    253                                       const ObjCIvarDecl *Ivar,
    254                                       unsigned CVRQualifiers) = 0;
    255   virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
    256                                       const ObjCInterfaceDecl *Interface,
    257                                       const ObjCIvarDecl *Ivar) = 0;
    258   virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
    259                                         llvm::Value *DestPtr,
    260                                         llvm::Value *SrcPtr,
    261                                         llvm::Value *Size) = 0;
    262   virtual llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
    263                                   const CodeGen::CGBlockInfo &blockInfo) = 0;
    264   virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) = 0;
    265 
    266   struct MessageSendInfo {
    267     const CGFunctionInfo &CallInfo;
    268     llvm::PointerType *MessengerType;
    269 
    270     MessageSendInfo(const CGFunctionInfo &callInfo,
    271                     llvm::PointerType *messengerType)
    272       : CallInfo(callInfo), MessengerType(messengerType) {}
    273   };
    274 
    275   MessageSendInfo getMessageSendInfo(const ObjCMethodDecl *method,
    276                                      QualType resultType,
    277                                      CallArgList &callArgs);
    278 };
    279 
    280 /// Creates an instance of an Objective-C runtime class.
    281 //TODO: This should include some way of selecting which runtime to target.
    282 CGObjCRuntime *CreateGNUObjCRuntime(CodeGenModule &CGM);
    283 CGObjCRuntime *CreateMacObjCRuntime(CodeGenModule &CGM);
    284 }
    285 }
    286 #endif
    287