10b57cec5SDimitry Andric //===----- CGObjCRuntime.h - Interface to ObjC Runtimes ---------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This provides an abstract class for Objective-C code generation. Concrete 100b57cec5SDimitry Andric // subclasses of this implement code generation for specific Objective-C 110b57cec5SDimitry Andric // runtime libraries. 120b57cec5SDimitry Andric // 130b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_CODEGEN_CGOBJCRUNTIME_H 160b57cec5SDimitry Andric #define LLVM_CLANG_LIB_CODEGEN_CGOBJCRUNTIME_H 170b57cec5SDimitry Andric #include "CGBuilder.h" 180b57cec5SDimitry Andric #include "CGCall.h" 190b57cec5SDimitry Andric #include "CGCleanup.h" 200b57cec5SDimitry Andric #include "CGValue.h" 210b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h" 220b57cec5SDimitry Andric #include "clang/Basic/IdentifierTable.h" // Selector 23e8d8bef9SDimitry Andric #include "llvm/ADT/UniqueVector.h" 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric namespace llvm { 260b57cec5SDimitry Andric class Constant; 270b57cec5SDimitry Andric class Function; 280b57cec5SDimitry Andric class Module; 290b57cec5SDimitry Andric class StructLayout; 300b57cec5SDimitry Andric class StructType; 310b57cec5SDimitry Andric class Type; 320b57cec5SDimitry Andric class Value; 330b57cec5SDimitry Andric } 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric namespace clang { 360b57cec5SDimitry Andric namespace CodeGen { 37*fcaf7f86SDimitry Andric class CGFunctionInfo; 380b57cec5SDimitry Andric class CodeGenFunction; 390b57cec5SDimitry Andric } 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric class FieldDecl; 420b57cec5SDimitry Andric class ObjCAtTryStmt; 430b57cec5SDimitry Andric class ObjCAtThrowStmt; 440b57cec5SDimitry Andric class ObjCAtSynchronizedStmt; 450b57cec5SDimitry Andric class ObjCContainerDecl; 460b57cec5SDimitry Andric class ObjCCategoryImplDecl; 470b57cec5SDimitry Andric class ObjCImplementationDecl; 480b57cec5SDimitry Andric class ObjCInterfaceDecl; 490b57cec5SDimitry Andric class ObjCMessageExpr; 500b57cec5SDimitry Andric class ObjCMethodDecl; 510b57cec5SDimitry Andric class ObjCProtocolDecl; 520b57cec5SDimitry Andric class Selector; 530b57cec5SDimitry Andric class ObjCIvarDecl; 540b57cec5SDimitry Andric class ObjCStringLiteral; 550b57cec5SDimitry Andric class BlockDeclRefExpr; 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric namespace CodeGen { 580b57cec5SDimitry Andric class CodeGenModule; 590b57cec5SDimitry Andric class CGBlockInfo; 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric // FIXME: Several methods should be pure virtual but aren't to avoid the 620b57cec5SDimitry Andric // partially-implemented subclass breaking. 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric /// Implements runtime-specific code generation functions. 650b57cec5SDimitry Andric class CGObjCRuntime { 660b57cec5SDimitry Andric protected: 670b57cec5SDimitry Andric CodeGen::CodeGenModule &CGM; CGObjCRuntime(CodeGen::CodeGenModule & CGM)680b57cec5SDimitry Andric CGObjCRuntime(CodeGen::CodeGenModule &CGM) : CGM(CGM) {} 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric // Utility functions for unified ivar access. These need to 710b57cec5SDimitry Andric // eventually be folded into other places (the structure layout 720b57cec5SDimitry Andric // code). 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric /// Compute an offset to the given ivar, suitable for passing to 750b57cec5SDimitry Andric /// EmitValueForIvarAtOffset. Note that the correct handling of 760b57cec5SDimitry Andric /// bit-fields is carefully coordinated by these two, use caution! 770b57cec5SDimitry Andric /// 780b57cec5SDimitry Andric /// The latter overload is suitable for computing the offset of a 790b57cec5SDimitry Andric /// sythesized ivar. 800b57cec5SDimitry Andric uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, 810b57cec5SDimitry Andric const ObjCInterfaceDecl *OID, 820b57cec5SDimitry Andric const ObjCIvarDecl *Ivar); 830b57cec5SDimitry Andric uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, 840b57cec5SDimitry Andric const ObjCImplementationDecl *OID, 850b57cec5SDimitry Andric const ObjCIvarDecl *Ivar); 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric LValue EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, 880b57cec5SDimitry Andric const ObjCInterfaceDecl *OID, 890b57cec5SDimitry Andric llvm::Value *BaseValue, 900b57cec5SDimitry Andric const ObjCIvarDecl *Ivar, 910b57cec5SDimitry Andric unsigned CVRQualifiers, 920b57cec5SDimitry Andric llvm::Value *Offset); 930b57cec5SDimitry Andric /// Emits a try / catch statement. This function is intended to be called by 940b57cec5SDimitry Andric /// subclasses, and provides a generic mechanism for generating these, which 950b57cec5SDimitry Andric /// should be usable by all runtimes. The caller must provide the functions 960b57cec5SDimitry Andric /// to call when entering and exiting a \@catch() block, and the function 970b57cec5SDimitry Andric /// used to rethrow exceptions. If the begin and end catch functions are 980b57cec5SDimitry Andric /// NULL, then the function assumes that the EH personality function provides 990b57cec5SDimitry Andric /// the thrown object directly. 1000b57cec5SDimitry Andric void EmitTryCatchStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S, 1010b57cec5SDimitry Andric llvm::FunctionCallee beginCatchFn, 1020b57cec5SDimitry Andric llvm::FunctionCallee endCatchFn, 1030b57cec5SDimitry Andric llvm::FunctionCallee exceptionRethrowFn); 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric void EmitInitOfCatchParam(CodeGenFunction &CGF, llvm::Value *exn, 1060b57cec5SDimitry Andric const VarDecl *paramDecl); 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric /// Emits an \@synchronize() statement, using the \p syncEnterFn and 1090b57cec5SDimitry Andric /// \p syncExitFn arguments as the functions called to lock and unlock 1100b57cec5SDimitry Andric /// the object. This function can be called by subclasses that use 1110b57cec5SDimitry Andric /// zero-cost exception handling. 1120b57cec5SDimitry Andric void EmitAtSynchronizedStmt(CodeGenFunction &CGF, 1130b57cec5SDimitry Andric const ObjCAtSynchronizedStmt &S, 1140b57cec5SDimitry Andric llvm::FunctionCallee syncEnterFn, 1150b57cec5SDimitry Andric llvm::FunctionCallee syncExitFn); 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric public: 1180b57cec5SDimitry Andric virtual ~CGObjCRuntime(); 1190b57cec5SDimitry Andric 120e8d8bef9SDimitry Andric std::string getSymbolNameForMethod(const ObjCMethodDecl *method, 121e8d8bef9SDimitry Andric bool includeCategoryName = true); 122e8d8bef9SDimitry Andric 1230b57cec5SDimitry Andric /// Generate the function required to register all Objective-C components in 1240b57cec5SDimitry Andric /// this compilation unit with the runtime library. 1250b57cec5SDimitry Andric virtual llvm::Function *ModuleInitFunction() = 0; 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric /// Get a selector for the specified name and type values. 1280b57cec5SDimitry Andric /// The result should have the LLVM type for ASTContext::getObjCSelType(). 1290b57cec5SDimitry Andric virtual llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel) = 0; 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric /// Get the address of a selector for the specified name and type values. 1320b57cec5SDimitry Andric /// This is a rarely-used language extension, but sadly it exists. 1330b57cec5SDimitry Andric /// 1340b57cec5SDimitry Andric /// The result should have the LLVM type for a pointer to 1350b57cec5SDimitry Andric /// ASTContext::getObjCSelType(). 1360b57cec5SDimitry Andric virtual Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) = 0; 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric /// Get a typed selector. 1390b57cec5SDimitry Andric virtual llvm::Value *GetSelector(CodeGenFunction &CGF, 1400b57cec5SDimitry Andric const ObjCMethodDecl *Method) = 0; 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric /// Get the type constant to catch for the given ObjC pointer type. 1430b57cec5SDimitry Andric /// This is used externally to implement catching ObjC types in C++. 1440b57cec5SDimitry Andric /// Runtimes which don't support this should add the appropriate 1450b57cec5SDimitry Andric /// error to Sema. 1460b57cec5SDimitry Andric virtual llvm::Constant *GetEHType(QualType T) = 0; 1470b57cec5SDimitry Andric getCatchAllTypeInfo()1480b57cec5SDimitry Andric virtual CatchTypeInfo getCatchAllTypeInfo() { return { nullptr, 0 }; } 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric /// Generate a constant string object. 1510b57cec5SDimitry Andric virtual ConstantAddress GenerateConstantString(const StringLiteral *) = 0; 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andric /// Generate a category. A category contains a list of methods (and 1540b57cec5SDimitry Andric /// accompanying metadata) and a list of protocols. 1550b57cec5SDimitry Andric virtual void GenerateCategory(const ObjCCategoryImplDecl *OCD) = 0; 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric /// Generate a class structure for this class. 1580b57cec5SDimitry Andric virtual void GenerateClass(const ObjCImplementationDecl *OID) = 0; 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric /// Register an class alias. 1610b57cec5SDimitry Andric virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) = 0; 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric /// Generate an Objective-C message send operation. 1640b57cec5SDimitry Andric /// 1650b57cec5SDimitry Andric /// \param Method - The method being called, this may be null if synthesizing 1660b57cec5SDimitry Andric /// a property setter or getter. 1670b57cec5SDimitry Andric virtual CodeGen::RValue 1680b57cec5SDimitry Andric GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 1690b57cec5SDimitry Andric ReturnValueSlot ReturnSlot, 1700b57cec5SDimitry Andric QualType ResultType, 1710b57cec5SDimitry Andric Selector Sel, 1720b57cec5SDimitry Andric llvm::Value *Receiver, 1730b57cec5SDimitry Andric const CallArgList &CallArgs, 1740b57cec5SDimitry Andric const ObjCInterfaceDecl *Class = nullptr, 1750b57cec5SDimitry Andric const ObjCMethodDecl *Method = nullptr) = 0; 1760b57cec5SDimitry Andric 177480093f4SDimitry Andric /// Generate an Objective-C message send operation. 178480093f4SDimitry Andric /// 179480093f4SDimitry Andric /// This variant allows for the call to be substituted with an optimized 180480093f4SDimitry Andric /// variant. 181480093f4SDimitry Andric CodeGen::RValue 182480093f4SDimitry Andric GeneratePossiblySpecializedMessageSend(CodeGenFunction &CGF, 183480093f4SDimitry Andric ReturnValueSlot Return, 184480093f4SDimitry Andric QualType ResultType, 185480093f4SDimitry Andric Selector Sel, 186480093f4SDimitry Andric llvm::Value *Receiver, 187480093f4SDimitry Andric const CallArgList& Args, 188480093f4SDimitry Andric const ObjCInterfaceDecl *OID, 189480093f4SDimitry Andric const ObjCMethodDecl *Method, 190480093f4SDimitry Andric bool isClassMessage); 191480093f4SDimitry Andric 1920b57cec5SDimitry Andric /// Generate an Objective-C message send operation to the super 1930b57cec5SDimitry Andric /// class initiated in a method for Class and with the given Self 1940b57cec5SDimitry Andric /// object. 1950b57cec5SDimitry Andric /// 1960b57cec5SDimitry Andric /// \param Method - The method being called, this may be null if synthesizing 1970b57cec5SDimitry Andric /// a property setter or getter. 1980b57cec5SDimitry Andric virtual CodeGen::RValue 1990b57cec5SDimitry Andric GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 2000b57cec5SDimitry Andric ReturnValueSlot ReturnSlot, 2010b57cec5SDimitry Andric QualType ResultType, 2020b57cec5SDimitry Andric Selector Sel, 2030b57cec5SDimitry Andric const ObjCInterfaceDecl *Class, 2040b57cec5SDimitry Andric bool isCategoryImpl, 2050b57cec5SDimitry Andric llvm::Value *Self, 2060b57cec5SDimitry Andric bool IsClassMessage, 2070b57cec5SDimitry Andric const CallArgList &CallArgs, 2080b57cec5SDimitry Andric const ObjCMethodDecl *Method = nullptr) = 0; 2090b57cec5SDimitry Andric 210e8d8bef9SDimitry Andric /// Walk the list of protocol references from a class, category or 211e8d8bef9SDimitry Andric /// protocol to traverse the DAG formed from it's inheritance hierarchy. Find 212e8d8bef9SDimitry Andric /// the list of protocols that ends each walk at either a runtime 213e8d8bef9SDimitry Andric /// protocol or a non-runtime protocol with no parents. For the common case of 214e8d8bef9SDimitry Andric /// just a list of standard runtime protocols this just returns the same list 215e8d8bef9SDimitry Andric /// that was passed in. 216e8d8bef9SDimitry Andric std::vector<const ObjCProtocolDecl *> 217e8d8bef9SDimitry Andric GetRuntimeProtocolList(ObjCProtocolDecl::protocol_iterator begin, 218e8d8bef9SDimitry Andric ObjCProtocolDecl::protocol_iterator end); 219e8d8bef9SDimitry Andric 2200b57cec5SDimitry Andric /// Emit the code to return the named protocol as an object, as in a 2210b57cec5SDimitry Andric /// \@protocol expression. 2220b57cec5SDimitry Andric virtual llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF, 2230b57cec5SDimitry Andric const ObjCProtocolDecl *OPD) = 0; 2240b57cec5SDimitry Andric 2250b57cec5SDimitry Andric /// Generate the named protocol. Protocols contain method metadata but no 2260b57cec5SDimitry Andric /// implementations. 2270b57cec5SDimitry Andric virtual void GenerateProtocol(const ObjCProtocolDecl *OPD) = 0; 2280b57cec5SDimitry Andric 2295ffd83dbSDimitry Andric /// GetOrEmitProtocol - Get the protocol object for the given 2305ffd83dbSDimitry Andric /// declaration, emitting it if necessary. The return value has type 2315ffd83dbSDimitry Andric /// ProtocolPtrTy. 2325ffd83dbSDimitry Andric virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) = 0; 2335ffd83dbSDimitry Andric 2340b57cec5SDimitry Andric /// Generate a function preamble for a method with the specified 2350b57cec5SDimitry Andric /// types. 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric // FIXME: Current this just generates the Function definition, but really this 2380b57cec5SDimitry Andric // should also be generating the loads of the parameters, as the runtime 2390b57cec5SDimitry Andric // should have full control over how parameters are passed. 2400b57cec5SDimitry Andric virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD, 2410b57cec5SDimitry Andric const ObjCContainerDecl *CD) = 0; 2420b57cec5SDimitry Andric 243480093f4SDimitry Andric /// Generates prologue for direct Objective-C Methods. 244480093f4SDimitry Andric virtual void GenerateDirectMethodPrologue(CodeGenFunction &CGF, 245480093f4SDimitry Andric llvm::Function *Fn, 246480093f4SDimitry Andric const ObjCMethodDecl *OMD, 247480093f4SDimitry Andric const ObjCContainerDecl *CD) = 0; 248480093f4SDimitry Andric 2490b57cec5SDimitry Andric /// Return the runtime function for getting properties. 2500b57cec5SDimitry Andric virtual llvm::FunctionCallee GetPropertyGetFunction() = 0; 2510b57cec5SDimitry Andric 2520b57cec5SDimitry Andric /// Return the runtime function for setting properties. 2530b57cec5SDimitry Andric virtual llvm::FunctionCallee GetPropertySetFunction() = 0; 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric /// Return the runtime function for optimized setting properties. 2560b57cec5SDimitry Andric virtual llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic, 2570b57cec5SDimitry Andric bool copy) = 0; 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric // API for atomic copying of qualified aggregates in getter. 2600b57cec5SDimitry Andric virtual llvm::FunctionCallee GetGetStructFunction() = 0; 2610b57cec5SDimitry Andric // API for atomic copying of qualified aggregates in setter. 2620b57cec5SDimitry Andric virtual llvm::FunctionCallee GetSetStructFunction() = 0; 2630b57cec5SDimitry Andric /// API for atomic copying of qualified aggregates with non-trivial copy 2640b57cec5SDimitry Andric /// assignment (c++) in setter. 2650b57cec5SDimitry Andric virtual llvm::FunctionCallee GetCppAtomicObjectSetFunction() = 0; 2660b57cec5SDimitry Andric /// API for atomic copying of qualified aggregates with non-trivial copy 2670b57cec5SDimitry Andric /// assignment (c++) in getter. 2680b57cec5SDimitry Andric virtual llvm::FunctionCallee GetCppAtomicObjectGetFunction() = 0; 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric /// GetClass - Return a reference to the class for the given 2710b57cec5SDimitry Andric /// interface decl. 2720b57cec5SDimitry Andric virtual llvm::Value *GetClass(CodeGenFunction &CGF, 2730b57cec5SDimitry Andric const ObjCInterfaceDecl *OID) = 0; 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric EmitNSAutoreleasePoolClassRef(CodeGenFunction & CGF)2760b57cec5SDimitry Andric virtual llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) { 2770b57cec5SDimitry Andric llvm_unreachable("autoreleasepool unsupported in this ABI"); 2780b57cec5SDimitry Andric } 2790b57cec5SDimitry Andric 2800b57cec5SDimitry Andric /// EnumerationMutationFunction - Return the function that's called by the 2810b57cec5SDimitry Andric /// compiler when a mutation is detected during foreach iteration. 2820b57cec5SDimitry Andric virtual llvm::FunctionCallee EnumerationMutationFunction() = 0; 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andric virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 2850b57cec5SDimitry Andric const ObjCAtSynchronizedStmt &S) = 0; 2860b57cec5SDimitry Andric virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF, 2870b57cec5SDimitry Andric const ObjCAtTryStmt &S) = 0; 2880b57cec5SDimitry Andric virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 2890b57cec5SDimitry Andric const ObjCAtThrowStmt &S, 2900b57cec5SDimitry Andric bool ClearInsertionPoint=true) = 0; 2910b57cec5SDimitry Andric virtual llvm::Value *EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 2920b57cec5SDimitry Andric Address AddrWeakObj) = 0; 2930b57cec5SDimitry Andric virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 2940b57cec5SDimitry Andric llvm::Value *src, Address dest) = 0; 2950b57cec5SDimitry Andric virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 2960b57cec5SDimitry Andric llvm::Value *src, Address dest, 2970b57cec5SDimitry Andric bool threadlocal=false) = 0; 2980b57cec5SDimitry Andric virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 2990b57cec5SDimitry Andric llvm::Value *src, Address dest, 3000b57cec5SDimitry Andric llvm::Value *ivarOffset) = 0; 3010b57cec5SDimitry Andric virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 3020b57cec5SDimitry Andric llvm::Value *src, Address dest) = 0; 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 3050b57cec5SDimitry Andric QualType ObjectTy, 3060b57cec5SDimitry Andric llvm::Value *BaseValue, 3070b57cec5SDimitry Andric const ObjCIvarDecl *Ivar, 3080b57cec5SDimitry Andric unsigned CVRQualifiers) = 0; 3090b57cec5SDimitry Andric virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 3100b57cec5SDimitry Andric const ObjCInterfaceDecl *Interface, 3110b57cec5SDimitry Andric const ObjCIvarDecl *Ivar) = 0; 3120b57cec5SDimitry Andric virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 3130b57cec5SDimitry Andric Address DestPtr, 3140b57cec5SDimitry Andric Address SrcPtr, 3150b57cec5SDimitry Andric llvm::Value *Size) = 0; 3160b57cec5SDimitry Andric virtual llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM, 3170b57cec5SDimitry Andric const CodeGen::CGBlockInfo &blockInfo) = 0; 3180b57cec5SDimitry Andric virtual llvm::Constant *BuildRCBlockLayout(CodeGen::CodeGenModule &CGM, 3190b57cec5SDimitry Andric const CodeGen::CGBlockInfo &blockInfo) = 0; getRCBlockLayoutStr(CodeGen::CodeGenModule & CGM,const CGBlockInfo & blockInfo)3200b57cec5SDimitry Andric virtual std::string getRCBlockLayoutStr(CodeGen::CodeGenModule &CGM, 3210b57cec5SDimitry Andric const CGBlockInfo &blockInfo) { 3220b57cec5SDimitry Andric return {}; 3230b57cec5SDimitry Andric } 3240b57cec5SDimitry Andric 3250b57cec5SDimitry Andric /// Returns an i8* which points to the byref layout information. 3260b57cec5SDimitry Andric virtual llvm::Constant *BuildByrefLayout(CodeGen::CodeGenModule &CGM, 3270b57cec5SDimitry Andric QualType T) = 0; 3280b57cec5SDimitry Andric 3290b57cec5SDimitry Andric struct MessageSendInfo { 3300b57cec5SDimitry Andric const CGFunctionInfo &CallInfo; 3310b57cec5SDimitry Andric llvm::PointerType *MessengerType; 3320b57cec5SDimitry Andric MessageSendInfoMessageSendInfo3330b57cec5SDimitry Andric MessageSendInfo(const CGFunctionInfo &callInfo, 3340b57cec5SDimitry Andric llvm::PointerType *messengerType) 3350b57cec5SDimitry Andric : CallInfo(callInfo), MessengerType(messengerType) {} 3360b57cec5SDimitry Andric }; 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andric MessageSendInfo getMessageSendInfo(const ObjCMethodDecl *method, 3390b57cec5SDimitry Andric QualType resultType, 3400b57cec5SDimitry Andric CallArgList &callArgs); 341349cc55cSDimitry Andric bool canMessageReceiverBeNull(CodeGenFunction &CGF, 342349cc55cSDimitry Andric const ObjCMethodDecl *method, 343349cc55cSDimitry Andric bool isSuper, 344349cc55cSDimitry Andric const ObjCInterfaceDecl *classReceiver, 345349cc55cSDimitry Andric llvm::Value *receiver); 346349cc55cSDimitry Andric static bool isWeakLinkedClass(const ObjCInterfaceDecl *cls); 347349cc55cSDimitry Andric 348349cc55cSDimitry Andric /// Destroy the callee-destroyed arguments of the given method, 349349cc55cSDimitry Andric /// if it has any. Used for nil-receiver paths in message sends. 350349cc55cSDimitry Andric /// Never does anything if the method does not satisfy 351349cc55cSDimitry Andric /// hasParamDestroyedInCallee(). 352349cc55cSDimitry Andric /// 353349cc55cSDimitry Andric /// \param callArgs - just the formal arguments, not including implicit 354349cc55cSDimitry Andric /// arguments such as self and cmd 355349cc55cSDimitry Andric static void destroyCalleeDestroyedArguments(CodeGenFunction &CGF, 356349cc55cSDimitry Andric const ObjCMethodDecl *method, 357349cc55cSDimitry Andric const CallArgList &callArgs); 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric // FIXME: This probably shouldn't be here, but the code to compute 3600b57cec5SDimitry Andric // it is here. 3610b57cec5SDimitry Andric unsigned ComputeBitfieldBitOffset(CodeGen::CodeGenModule &CGM, 3620b57cec5SDimitry Andric const ObjCInterfaceDecl *ID, 3630b57cec5SDimitry Andric const ObjCIvarDecl *Ivar); 3640b57cec5SDimitry Andric }; 3650b57cec5SDimitry Andric 3660b57cec5SDimitry Andric /// Creates an instance of an Objective-C runtime class. 3670b57cec5SDimitry Andric //TODO: This should include some way of selecting which runtime to target. 3680b57cec5SDimitry Andric CGObjCRuntime *CreateGNUObjCRuntime(CodeGenModule &CGM); 3690b57cec5SDimitry Andric CGObjCRuntime *CreateMacObjCRuntime(CodeGenModule &CGM); 3700b57cec5SDimitry Andric } 3710b57cec5SDimitry Andric } 3720b57cec5SDimitry Andric #endif 373