xref: /freebsd/contrib/llvm-project/clang/lib/CodeGen/CGObjCRuntime.h (revision fcaf7f8644a9988098ac6be2165bce3ea4786e91)
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