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