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