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   // Utility functions for unified ivar access. These need to
     67   // eventually be folded into other places (the structure layout
     68   // code).
     69 
     70   /// Compute an offset to the given ivar, suitable for passing to
     71   /// EmitValueForIvarAtOffset.  Note that the correct handling of
     72   /// bit-fields is carefully coordinated by these two, use caution!
     73   ///
     74   /// The latter overload is suitable for computing the offset of a
     75   /// sythesized ivar.
     76   uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
     77                                  const ObjCInterfaceDecl *OID,
     78                                  const ObjCIvarDecl *Ivar);
     79   uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
     80                                  const ObjCImplementationDecl *OID,
     81                                  const ObjCIvarDecl *Ivar);
     82 
     83   LValue EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
     84                                   const ObjCInterfaceDecl *OID,
     85                                   llvm::Value *BaseValue,
     86                                   const ObjCIvarDecl *Ivar,
     87                                   unsigned CVRQualifiers,
     88                                   llvm::Value *Offset);
     89   /// Emits a try / catch statement.  This function is intended to be called by
     90   /// subclasses, and provides a generic mechanism for generating these, which
     91   /// should be usable by all runtimes.  The caller must provide the functions to
     92   /// call when entering and exiting a @catch() block, and the function used to
     93   /// rethrow exceptions.  If the begin and end catch functions are NULL, then
     94   /// the function assumes that the EH personality function provides the
     95   /// thrown object directly.
     96   void EmitTryCatchStmt(CodeGenFunction &CGF,
     97                         const ObjCAtTryStmt &S,
     98                         llvm::Constant *beginCatchFn,
     99                         llvm::Constant *endCatchFn,
    100                         llvm::Constant *exceptionRethrowFn);
    101   /// Emits an @synchronize() statement, using the syncEnterFn and syncExitFn
    102   /// arguments as the functions called to lock and unlock the object.  This
    103   /// function can be called by subclasses that use zero-cost exception
    104   /// handling.
    105   void EmitAtSynchronizedStmt(CodeGenFunction &CGF,
    106                             const ObjCAtSynchronizedStmt &S,
    107                             llvm::Function *syncEnterFn,
    108                             llvm::Function *syncExitFn);
    109 
    110 public:
    111   virtual ~CGObjCRuntime();
    112 
    113   /// Generate the function required to register all Objective-C components in
    114   /// this compilation unit with the runtime library.
    115   virtual llvm::Function *ModuleInitFunction() = 0;
    116 
    117   /// Get a selector for the specified name and type values. The
    118   /// return value should have the LLVM type for pointer-to
    119   /// ASTContext::getObjCSelType().
    120   virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
    121                                    Selector Sel, bool lval=false) = 0;
    122 
    123   /// Get a typed selector.
    124   virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
    125                                    const ObjCMethodDecl *Method) = 0;
    126 
    127   /// Get the type constant to catch for the given ObjC pointer type.
    128   /// This is used externally to implement catching ObjC types in C++.
    129   /// Runtimes which don't support this should add the appropriate
    130   /// error to Sema.
    131   virtual llvm::Constant *GetEHType(QualType T) = 0;
    132 
    133   /// Generate a constant string object.
    134   virtual llvm::Constant *GenerateConstantString(const StringLiteral *) = 0;
    135 
    136   /// Generate a category.  A category contains a list of methods (and
    137   /// accompanying metadata) and a list of protocols.
    138   virtual void GenerateCategory(const ObjCCategoryImplDecl *OCD) = 0;
    139 
    140   /// Generate a class structure for this class.
    141   virtual void GenerateClass(const ObjCImplementationDecl *OID) = 0;
    142 
    143   /// Generate an Objective-C message send operation.
    144   ///
    145   /// \param Method - The method being called, this may be null if synthesizing
    146   /// a property setter or getter.
    147   virtual CodeGen::RValue
    148   GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
    149                       ReturnValueSlot ReturnSlot,
    150                       QualType ResultType,
    151                       Selector Sel,
    152                       llvm::Value *Receiver,
    153                       const CallArgList &CallArgs,
    154                       const ObjCInterfaceDecl *Class = 0,
    155                       const ObjCMethodDecl *Method = 0) = 0;
    156 
    157   /// Generate an Objective-C message send operation to the super
    158   /// class initiated in a method for Class and with the given Self
    159   /// object.
    160   ///
    161   /// \param Method - The method being called, this may be null if synthesizing
    162   /// a property setter or getter.
    163   virtual CodeGen::RValue
    164   GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
    165                            ReturnValueSlot ReturnSlot,
    166                            QualType ResultType,
    167                            Selector Sel,
    168                            const ObjCInterfaceDecl *Class,
    169                            bool isCategoryImpl,
    170                            llvm::Value *Self,
    171                            bool IsClassMessage,
    172                            const CallArgList &CallArgs,
    173                            const ObjCMethodDecl *Method = 0) = 0;
    174 
    175   /// Emit the code to return the named protocol as an object, as in a
    176   /// @protocol expression.
    177   virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
    178                                            const ObjCProtocolDecl *OPD) = 0;
    179 
    180   /// Generate the named protocol.  Protocols contain method metadata but no
    181   /// implementations.
    182   virtual void GenerateProtocol(const ObjCProtocolDecl *OPD) = 0;
    183 
    184   /// Generate a function preamble for a method with the specified
    185   /// types.
    186 
    187   // FIXME: Current this just generates the Function definition, but really this
    188   // should also be generating the loads of the parameters, as the runtime
    189   // should have full control over how parameters are passed.
    190   virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
    191                                          const ObjCContainerDecl *CD) = 0;
    192 
    193   /// Return the runtime function for getting properties.
    194   virtual llvm::Constant *GetPropertyGetFunction() = 0;
    195 
    196   /// Return the runtime function for setting properties.
    197   virtual llvm::Constant *GetPropertySetFunction() = 0;
    198 
    199   // API for atomic copying of qualified aggregates in getter.
    200   virtual llvm::Constant *GetGetStructFunction() = 0;
    201   // API for atomic copying of qualified aggregates in setter.
    202   virtual llvm::Constant *GetSetStructFunction() = 0;
    203 
    204   /// GetClass - Return a reference to the class for the given
    205   /// interface decl.
    206   virtual llvm::Value *GetClass(CGBuilderTy &Builder,
    207                                 const ObjCInterfaceDecl *OID) = 0;
    208 
    209 
    210   virtual llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder) {
    211     llvm_unreachable("autoreleasepool unsupported in this ABI");
    212   }
    213 
    214   /// EnumerationMutationFunction - Return the function that's called by the
    215   /// compiler when a mutation is detected during foreach iteration.
    216   virtual llvm::Constant *EnumerationMutationFunction() = 0;
    217 
    218   virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
    219                                     const ObjCAtSynchronizedStmt &S) = 0;
    220   virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
    221                            const ObjCAtTryStmt &S) = 0;
    222   virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
    223                              const ObjCAtThrowStmt &S) = 0;
    224   virtual llvm::Value *EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
    225                                         llvm::Value *AddrWeakObj) = 0;
    226   virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
    227                                   llvm::Value *src, llvm::Value *dest) = 0;
    228   virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
    229                                     llvm::Value *src, llvm::Value *dest,
    230                                     bool threadlocal=false) = 0;
    231   virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
    232                                   llvm::Value *src, llvm::Value *dest,
    233                                   llvm::Value *ivarOffset) = 0;
    234   virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
    235                                         llvm::Value *src, llvm::Value *dest) = 0;
    236 
    237   virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
    238                                       QualType ObjectTy,
    239                                       llvm::Value *BaseValue,
    240                                       const ObjCIvarDecl *Ivar,
    241                                       unsigned CVRQualifiers) = 0;
    242   virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
    243                                       const ObjCInterfaceDecl *Interface,
    244                                       const ObjCIvarDecl *Ivar) = 0;
    245   virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
    246                                         llvm::Value *DestPtr,
    247                                         llvm::Value *SrcPtr,
    248                                         llvm::Value *Size) = 0;
    249   virtual llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
    250                                   const CodeGen::CGBlockInfo &blockInfo) = 0;
    251   virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) = 0;
    252 };
    253 
    254 /// Creates an instance of an Objective-C runtime class.
    255 //TODO: This should include some way of selecting which runtime to target.
    256 CGObjCRuntime *CreateGNUObjCRuntime(CodeGenModule &CGM);
    257 CGObjCRuntime *CreateMacObjCRuntime(CodeGenModule &CGM);
    258 }
    259 }
    260 #endif
    261