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