blob: 0f3cb549ec77419209556676f0f164f04c1e0440 [file] [log] [blame]
Daniel Dunbar303e2c22008-08-11 02:45:11 +00001//===----- CGObjCRuntime.h - Interface to ObjC Runtimes ---------*- C++ -*-===//
Chris Lattnerb7256cd2008-03-01 08:50:34 +00002//
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 CLANG_CODEGEN_OBCJRUNTIME_H
17#define CLANG_CODEGEN_OBCJRUNTIME_H
Daniel Dunbar221fa942008-08-11 04:54:23 +000018#include "clang/Basic/IdentifierTable.h" // Selector
Fariborz Jahanianf3648b82009-05-05 21:36:57 +000019#include "clang/AST/DeclObjC.h"
Chris Lattnerb7256cd2008-03-01 08:50:34 +000020
Daniel Dunbarcb463852008-11-01 01:53:16 +000021#include "CGBuilder.h"
Daniel Dunbar41cf9de2008-09-09 01:06:48 +000022#include "CGCall.h"
Daniel Dunbarcb463852008-11-01 01:53:16 +000023#include "CGValue.h"
Daniel Dunbar97db84c2008-08-23 03:46:30 +000024
Chris Lattnerb7256cd2008-03-01 08:50:34 +000025namespace llvm {
Chris Lattnerb7256cd2008-03-01 08:50:34 +000026 class Constant;
Daniel Dunbar9fd114d2009-04-22 07:32:20 +000027 class Function;
28 class Module;
29 class StructLayout;
Daniel Dunbar7b4dfc82009-04-22 09:39:34 +000030 class StructType;
Chris Lattnerb7256cd2008-03-01 08:50:34 +000031 class Type;
32 class Value;
Chris Lattnerb7256cd2008-03-01 08:50:34 +000033}
34
35namespace clang {
Daniel Dunbar41cf9de2008-09-09 01:06:48 +000036namespace CodeGen {
37 class CodeGenFunction;
38}
Daniel Dunbar97db84c2008-08-23 03:46:30 +000039
Daniel Dunbar9fd114d2009-04-22 07:32:20 +000040 class FieldDecl;
Anders Carlsson1963b0c2008-09-09 10:04:29 +000041 class ObjCAtTryStmt;
42 class ObjCAtThrowStmt;
Chris Lattnere132e242008-11-15 21:26:17 +000043 class ObjCAtSynchronizedStmt;
Fariborz Jahanian0196a1c2009-01-10 21:06:09 +000044 class ObjCContainerDecl;
Daniel Dunbar92992502008-08-15 22:20:32 +000045 class ObjCCategoryImplDecl;
46 class ObjCImplementationDecl;
Daniel Dunbar7c6d3a72008-08-16 00:25:02 +000047 class ObjCInterfaceDecl;
Daniel Dunbar97db84c2008-08-23 03:46:30 +000048 class ObjCMessageExpr;
Daniel Dunbar92992502008-08-15 22:20:32 +000049 class ObjCMethodDecl;
Daniel Dunbar89da6ad2008-08-13 00:59:25 +000050 class ObjCProtocolDecl;
Chris Lattner6d522c02008-06-26 04:37:12 +000051 class Selector;
Fariborz Jahanian9f84b782009-02-02 20:02:29 +000052 class ObjCIvarDecl;
Steve Naroff66afeb52009-03-31 16:53:37 +000053 class ObjCStringLiteral;
Fariborz Jahanianc05349e2010-08-04 16:57:49 +000054 class BlockDeclRefExpr;
Daniel Dunbar89da6ad2008-08-13 00:59:25 +000055
Chris Lattnerb7256cd2008-03-01 08:50:34 +000056namespace CodeGen {
Chris Lattner87ab27d2008-06-26 04:19:03 +000057 class CodeGenModule;
John McCall351762c2011-02-07 10:33:21 +000058 class CGBlockInfo;
Chris Lattnerb7256cd2008-03-01 08:50:34 +000059
Mike Stump18bb9282009-05-16 07:57:57 +000060// FIXME: Several methods should be pure virtual but aren't to avoid the
61// partially-implemented subclass breaking.
Anton Korobeynikov1200aca2008-06-01 14:13:53 +000062
63/// Implements runtime-specific code generation functions.
Chris Lattnerb7256cd2008-03-01 08:50:34 +000064class CGObjCRuntime {
Daniel Dunbardc406b82010-04-05 21:36:35 +000065protected:
John McCalla729c622012-02-17 03:33:10 +000066 CodeGen::CodeGenModule &CGM;
67 CGObjCRuntime(CodeGen::CodeGenModule &CGM) : CGM(CGM) {}
68
Daniel Dunbar9fd114d2009-04-22 07:32:20 +000069 // Utility functions for unified ivar access. These need to
70 // eventually be folded into other places (the structure layout
71 // code).
72
Daniel Dunbar7b4dfc82009-04-22 09:39:34 +000073 /// Compute an offset to the given ivar, suitable for passing to
74 /// EmitValueForIvarAtOffset. Note that the correct handling of
75 /// bit-fields is carefully coordinated by these two, use caution!
Daniel Dunbar961202372009-05-03 12:57:56 +000076 ///
77 /// The latter overload is suitable for computing the offset of a
78 /// sythesized ivar.
Daniel Dunbar9fd114d2009-04-22 07:32:20 +000079 uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
80 const ObjCInterfaceDecl *OID,
81 const ObjCIvarDecl *Ivar);
Daniel Dunbar961202372009-05-03 12:57:56 +000082 uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
83 const ObjCImplementationDecl *OID,
84 const ObjCIvarDecl *Ivar);
Daniel Dunbar9fd114d2009-04-22 07:32:20 +000085
86 LValue EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
87 const ObjCInterfaceDecl *OID,
88 llvm::Value *BaseValue,
89 const ObjCIvarDecl *Ivar,
90 unsigned CVRQualifiers,
Mike Stump11289f42009-09-09 15:08:12 +000091 llvm::Value *Offset);
David Chisnalld3858d62011-03-25 11:57:33 +000092 /// Emits a try / catch statement. This function is intended to be called by
93 /// subclasses, and provides a generic mechanism for generating these, which
94 /// should be usable by all runtimes. The caller must provide the functions to
95 /// call when entering and exiting a @catch() block, and the function used to
96 /// rethrow exceptions. If the begin and end catch functions are NULL, then
97 /// the function assumes that the EH personality function provides the
98 /// thrown object directly.
99 void EmitTryCatchStmt(CodeGenFunction &CGF,
100 const ObjCAtTryStmt &S,
David Chisnall3fe89562011-05-23 22:33:28 +0000101 llvm::Constant *beginCatchFn,
102 llvm::Constant *endCatchFn,
103 llvm::Constant *exceptionRethrowFn);
David Chisnalld3858d62011-03-25 11:57:33 +0000104 /// Emits an @synchronize() statement, using the syncEnterFn and syncExitFn
105 /// arguments as the functions called to lock and unlock the object. This
106 /// function can be called by subclasses that use zero-cost exception
107 /// handling.
108 void EmitAtSynchronizedStmt(CodeGenFunction &CGF,
109 const ObjCAtSynchronizedStmt &S,
110 llvm::Function *syncEnterFn,
111 llvm::Function *syncExitFn);
Daniel Dunbar48595de2008-08-11 16:50:21 +0000112
Chris Lattnerb7256cd2008-03-01 08:50:34 +0000113public:
114 virtual ~CGObjCRuntime();
Daniel Dunbar92992502008-08-15 22:20:32 +0000115
116 /// Generate the function required to register all Objective-C components in
117 /// this compilation unit with the runtime library.
118 virtual llvm::Function *ModuleInitFunction() = 0;
119
120 /// Get a selector for the specified name and type values. The
121 /// return value should have the LLVM type for pointer-to
122 /// ASTContext::getObjCSelType().
Daniel Dunbarcb463852008-11-01 01:53:16 +0000123 virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
Fariborz Jahanian9240f3d2010-06-17 19:56:20 +0000124 Selector Sel, bool lval=false) = 0;
Daniel Dunbar92992502008-08-15 22:20:32 +0000125
Mike Stump11289f42009-09-09 15:08:12 +0000126 /// Get a typed selector.
Fariborz Jahanianf3648b82009-05-05 21:36:57 +0000127 virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
128 const ObjCMethodDecl *Method) = 0;
129
John McCall2ca705e2010-07-24 00:37:23 +0000130 /// Get the type constant to catch for the given ObjC pointer type.
131 /// This is used externally to implement catching ObjC types in C++.
132 /// Runtimes which don't support this should add the appropriate
133 /// error to Sema.
Fariborz Jahanian831f0fc2011-06-23 19:00:08 +0000134 virtual llvm::Constant *GetEHType(QualType T) = 0;
John McCall2ca705e2010-07-24 00:37:23 +0000135
Daniel Dunbar92992502008-08-15 22:20:32 +0000136 /// Generate a constant string object.
David Chisnall481e3a82010-01-23 02:40:42 +0000137 virtual llvm::Constant *GenerateConstantString(const StringLiteral *) = 0;
Daniel Dunbar92992502008-08-15 22:20:32 +0000138
139 /// Generate a category. A category contains a list of methods (and
140 /// accompanying metadata) and a list of protocols.
141 virtual void GenerateCategory(const ObjCCategoryImplDecl *OCD) = 0;
142
Chris Lattner57540c52011-04-15 05:22:18 +0000143 /// Generate a class structure for this class.
Daniel Dunbar92992502008-08-15 22:20:32 +0000144 virtual void GenerateClass(const ObjCImplementationDecl *OID) = 0;
Mike Stump11289f42009-09-09 15:08:12 +0000145
David Chisnall92d436b2012-01-31 18:59:20 +0000146 /// Register an class alias.
147 virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) = 0;
148
Mike Stump11289f42009-09-09 15:08:12 +0000149 /// Generate an Objective-C message send operation.
Daniel Dunbaraff9fca2009-09-17 04:01:22 +0000150 ///
151 /// \param Method - The method being called, this may be null if synthesizing
152 /// a property setter or getter.
Mike Stump11289f42009-09-09 15:08:12 +0000153 virtual CodeGen::RValue
Daniel Dunbar97db84c2008-08-23 03:46:30 +0000154 GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
John McCall78a15112010-05-22 01:48:05 +0000155 ReturnValueSlot ReturnSlot,
Daniel Dunbar4b8c6db2008-08-30 05:35:15 +0000156 QualType ResultType,
157 Selector Sel,
Daniel Dunbarca8531a2008-08-25 08:19:24 +0000158 llvm::Value *Receiver,
Fariborz Jahanianf3648b82009-05-05 21:36:57 +0000159 const CallArgList &CallArgs,
David Chisnall01aa4672010-04-28 19:33:36 +0000160 const ObjCInterfaceDecl *Class = 0,
Daniel Dunbaraff9fca2009-09-17 04:01:22 +0000161 const ObjCMethodDecl *Method = 0) = 0;
Daniel Dunbar89da6ad2008-08-13 00:59:25 +0000162
Daniel Dunbar92992502008-08-15 22:20:32 +0000163 /// Generate an Objective-C message send operation to the super
Daniel Dunbarca8531a2008-08-25 08:19:24 +0000164 /// class initiated in a method for Class and with the given Self
165 /// object.
Daniel Dunbaraff9fca2009-09-17 04:01:22 +0000166 ///
167 /// \param Method - The method being called, this may be null if synthesizing
168 /// a property setter or getter.
Daniel Dunbar97db84c2008-08-23 03:46:30 +0000169 virtual CodeGen::RValue
170 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
John McCall78a15112010-05-22 01:48:05 +0000171 ReturnValueSlot ReturnSlot,
Daniel Dunbar4b8c6db2008-08-30 05:35:15 +0000172 QualType ResultType,
173 Selector Sel,
Daniel Dunbarca8531a2008-08-25 08:19:24 +0000174 const ObjCInterfaceDecl *Class,
Fariborz Jahanianbac73ac2009-02-28 20:07:56 +0000175 bool isCategoryImpl,
Daniel Dunbarca8531a2008-08-25 08:19:24 +0000176 llvm::Value *Self,
Daniel Dunbarc722b852008-08-30 03:02:31 +0000177 bool IsClassMessage,
Daniel Dunbaraff9fca2009-09-17 04:01:22 +0000178 const CallArgList &CallArgs,
179 const ObjCMethodDecl *Method = 0) = 0;
Daniel Dunbar6630e102008-08-12 05:08:18 +0000180
181 /// Emit the code to return the named protocol as an object, as in a
182 /// @protocol expression.
Daniel Dunbarcb463852008-11-01 01:53:16 +0000183 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
Daniel Dunbar92992502008-08-15 22:20:32 +0000184 const ObjCProtocolDecl *OPD) = 0;
Daniel Dunbar6630e102008-08-12 05:08:18 +0000185
Mike Stump11289f42009-09-09 15:08:12 +0000186 /// Generate the named protocol. Protocols contain method metadata but no
187 /// implementations.
Daniel Dunbar92992502008-08-15 22:20:32 +0000188 virtual void GenerateProtocol(const ObjCProtocolDecl *OPD) = 0;
Daniel Dunbar89da6ad2008-08-13 00:59:25 +0000189
Daniel Dunbar92992502008-08-15 22:20:32 +0000190 /// Generate a function preamble for a method with the specified
Mike Stump11289f42009-09-09 15:08:12 +0000191 /// types.
Daniel Dunbar92992502008-08-15 22:20:32 +0000192
Mike Stump18bb9282009-05-16 07:57:57 +0000193 // FIXME: Current this just generates the Function definition, but really this
194 // should also be generating the loads of the parameters, as the runtime
195 // should have full control over how parameters are passed.
Mike Stump11289f42009-09-09 15:08:12 +0000196 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
Fariborz Jahanian0196a1c2009-01-10 21:06:09 +0000197 const ObjCContainerDecl *CD) = 0;
Daniel Dunbar89da6ad2008-08-13 00:59:25 +0000198
Daniel Dunbara91c3e02008-09-24 03:38:44 +0000199 /// Return the runtime function for getting properties.
Chris Lattnerd4808922009-03-22 21:03:39 +0000200 virtual llvm::Constant *GetPropertyGetFunction() = 0;
Mike Stump11289f42009-09-09 15:08:12 +0000201
Daniel Dunbara91c3e02008-09-24 03:38:44 +0000202 /// Return the runtime function for setting properties.
Chris Lattnerd4808922009-03-22 21:03:39 +0000203 virtual llvm::Constant *GetPropertySetFunction() = 0;
Daniel Dunbara91c3e02008-09-24 03:38:44 +0000204
David Chisnall168b80f2010-12-26 22:13:16 +0000205 // API for atomic copying of qualified aggregates in getter.
206 virtual llvm::Constant *GetGetStructFunction() = 0;
207 // API for atomic copying of qualified aggregates in setter.
208 virtual llvm::Constant *GetSetStructFunction() = 0;
Fariborz Jahanian1e1b5492012-01-06 18:07:23 +0000209 // API for atomic copying of qualified aggregates with non-trivial copy
210 // assignment (c++) in setter/getter.
211 virtual llvm::Constant *GetCppAtomicObjectFunction() = 0;
Fariborz Jahanian5a8c2032010-04-12 18:18:10 +0000212
Daniel Dunbar7c6d3a72008-08-16 00:25:02 +0000213 /// GetClass - Return a reference to the class for the given
214 /// interface decl.
Mike Stump11289f42009-09-09 15:08:12 +0000215 virtual llvm::Value *GetClass(CGBuilderTy &Builder,
Daniel Dunbar7c6d3a72008-08-16 00:25:02 +0000216 const ObjCInterfaceDecl *OID) = 0;
John McCall31168b02011-06-15 23:02:42 +0000217
218
219 virtual llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder) {
David Blaikie83d382b2011-09-23 05:06:16 +0000220 llvm_unreachable("autoreleasepool unsupported in this ABI");
John McCall31168b02011-06-15 23:02:42 +0000221 }
222
Anders Carlsson3f35a262008-08-31 04:05:03 +0000223 /// EnumerationMutationFunction - Return the function that's called by the
224 /// compiler when a mutation is detected during foreach iteration.
Chris Lattnerd4808922009-03-22 21:03:39 +0000225 virtual llvm::Constant *EnumerationMutationFunction() = 0;
Mike Stump11289f42009-09-09 15:08:12 +0000226
John McCallbd309292010-07-06 01:34:17 +0000227 virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
228 const ObjCAtSynchronizedStmt &S) = 0;
229 virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
230 const ObjCAtTryStmt &S) = 0;
Anders Carlsson1963b0c2008-09-09 10:04:29 +0000231 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
232 const ObjCAtThrowStmt &S) = 0;
Daniel Dunbarbe9dae82009-04-21 00:49:20 +0000233 virtual llvm::Value *EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
234 llvm::Value *AddrWeakObj) = 0;
Fariborz Jahanian83f45b552008-11-18 22:37:34 +0000235 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
236 llvm::Value *src, llvm::Value *dest) = 0;
Fariborz Jahaniand7db9642008-11-19 00:59:10 +0000237 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
Fariborz Jahanian217af242010-07-20 20:30:03 +0000238 llvm::Value *src, llvm::Value *dest,
239 bool threadlocal=false) = 0;
Fariborz Jahaniane881b532008-11-20 19:23:36 +0000240 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
Fariborz Jahanian7a95d722009-09-24 22:25:38 +0000241 llvm::Value *src, llvm::Value *dest,
242 llvm::Value *ivarOffset) = 0;
Fariborz Jahaniand7db9642008-11-19 00:59:10 +0000243 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
244 llvm::Value *src, llvm::Value *dest) = 0;
Mike Stump11289f42009-09-09 15:08:12 +0000245
Fariborz Jahanian712bfa62009-02-03 19:03:09 +0000246 virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
247 QualType ObjectTy,
248 llvm::Value *BaseValue,
249 const ObjCIvarDecl *Ivar,
Fariborz Jahanian712bfa62009-02-03 19:03:09 +0000250 unsigned CVRQualifiers) = 0;
Fariborz Jahanian21fc74c2009-02-10 19:02:04 +0000251 virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar722f4242009-04-22 05:08:15 +0000252 const ObjCInterfaceDecl *Interface,
Fariborz Jahanian21fc74c2009-02-10 19:02:04 +0000253 const ObjCIvarDecl *Ivar) = 0;
Fariborz Jahanian5f21d2f2009-07-08 01:18:33 +0000254 virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
Mike Stump11289f42009-09-09 15:08:12 +0000255 llvm::Value *DestPtr,
Fariborz Jahanian5f21d2f2009-07-08 01:18:33 +0000256 llvm::Value *SrcPtr,
Fariborz Jahanian021510e2010-06-15 22:44:06 +0000257 llvm::Value *Size) = 0;
John McCall351762c2011-02-07 10:33:21 +0000258 virtual llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
259 const CodeGen::CGBlockInfo &blockInfo) = 0;
Fariborz Jahanian7bd3d1c2011-05-17 22:21:16 +0000260 virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) = 0;
John McCalla729c622012-02-17 03:33:10 +0000261
262 struct MessageSendInfo {
263 const CGFunctionInfo &CallInfo;
264 llvm::PointerType *MessengerType;
265
266 MessageSendInfo(const CGFunctionInfo &callInfo,
267 llvm::PointerType *messengerType)
268 : CallInfo(callInfo), MessengerType(messengerType) {}
269 };
270
271 MessageSendInfo getMessageSendInfo(const ObjCMethodDecl *method,
272 QualType resultType,
273 CallArgList &callArgs);
Chris Lattnerb7256cd2008-03-01 08:50:34 +0000274};
275
Mike Stump11289f42009-09-09 15:08:12 +0000276/// Creates an instance of an Objective-C runtime class.
Chris Lattner4bd55962008-03-30 23:03:07 +0000277//TODO: This should include some way of selecting which runtime to target.
Daniel Dunbar303e2c22008-08-11 02:45:11 +0000278CGObjCRuntime *CreateGNUObjCRuntime(CodeGenModule &CGM);
279CGObjCRuntime *CreateMacObjCRuntime(CodeGenModule &CGM);
Chris Lattnerb7256cd2008-03-01 08:50:34 +0000280}
281}
282#endif