1 //===------- CGObjCMac.cpp - Interface to Apple Objective-C Runtime -------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This provides Objective-C code generation targeting the Apple runtime.
12 //===----------------------------------------------------------------------===//
14 #include "CGObjCRuntime.h"
16 #include "CGRecordLayout.h"
17 #include "CodeGenModule.h"
18 #include "CodeGenFunction.h"
20 #include "CGCleanup.h"
21 #include "clang/AST/ASTContext.h"
22 #include "clang/AST/Decl.h"
23 #include "clang/AST/DeclObjC.h"
24 #include "clang/AST/RecordLayout.h"
25 #include "clang/AST/StmtObjC.h"
26 #include "clang/Basic/LangOptions.h"
27 #include "clang/Frontend/CodeGenOptions.h"
29 #include "llvm/InlineAsm.h"
30 #include "llvm/IntrinsicInst.h"
31 #include "llvm/LLVMContext.h"
32 #include "llvm/Module.h"
33 #include "llvm/ADT/DenseSet.h"
34 #include "llvm/ADT/SetVector.h"
35 #include "llvm/ADT/SmallString.h"
36 #include "llvm/ADT/SmallPtrSet.h"
37 #include "llvm/Support/CallSite.h"
38 #include "llvm/Support/raw_ostream.h"
39 #include "llvm/Target/TargetData.h"
42 using namespace clang;
43 using namespace CodeGen;
48 typedef std::vector<llvm::Constant*> ConstantVector;
50 // FIXME: We should find a nicer way to make the labels for metadata, string
51 // concatenation is lame.
53 class ObjCCommonTypesHelper {
55 llvm::LLVMContext &VMContext;
58 // The types of these functions don't really matter because we
59 // should always bitcast before calling them.
61 /// id objc_msgSend (id, SEL, ...)
63 /// The default messenger, used for sends whose ABI is unchanged from
64 /// the all-integer/pointer case.
65 llvm::Constant *getMessageSendFn() const {
66 // Add the non-lazy-bind attribute, since objc_msgSend is likely to
68 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
69 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
72 llvm::Attribute::NonLazyBind);
75 /// void objc_msgSend_stret (id, SEL, ...)
77 /// The messenger used when the return value is an aggregate returned
78 /// by indirect reference in the first argument, and therefore the
79 /// self and selector parameters are shifted over by one.
80 llvm::Constant *getMessageSendStretFn() const {
81 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
82 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,
84 "objc_msgSend_stret");
88 /// [double | long double] objc_msgSend_fpret(id self, SEL op, ...)
90 /// The messenger used when the return value is returned on the x87
91 /// floating-point stack; without a special entrypoint, the nil case
92 /// would be unbalanced.
93 llvm::Constant *getMessageSendFpretFn() const {
94 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
95 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(
96 llvm::Type::getDoubleTy(VMContext),
98 "objc_msgSend_fpret");
102 /// id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
104 /// The messenger used for super calls, which have different dispatch
105 /// semantics. The class passed is the superclass of the current
107 llvm::Constant *getMessageSendSuperFn() const {
108 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
109 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
111 "objc_msgSendSuper");
114 /// id objc_msgSendSuper2(struct objc_super *super, SEL op, ...)
116 /// A slightly different messenger used for super calls. The class
117 /// passed is the current class.
118 llvm::Constant *getMessageSendSuperFn2() const {
119 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
120 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
122 "objc_msgSendSuper2");
125 /// void objc_msgSendSuper_stret(void *stretAddr, struct objc_super *super,
128 /// The messenger used for super calls which return an aggregate indirectly.
129 llvm::Constant *getMessageSendSuperStretFn() const {
130 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
131 return CGM.CreateRuntimeFunction(
132 llvm::FunctionType::get(CGM.VoidTy, params, true),
133 "objc_msgSendSuper_stret");
136 /// void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super,
139 /// objc_msgSendSuper_stret with the super2 semantics.
140 llvm::Constant *getMessageSendSuperStretFn2() const {
141 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
142 return CGM.CreateRuntimeFunction(
143 llvm::FunctionType::get(CGM.VoidTy, params, true),
144 "objc_msgSendSuper2_stret");
147 llvm::Constant *getMessageSendSuperFpretFn() const {
148 // There is no objc_msgSendSuper_fpret? How can that work?
149 return getMessageSendSuperFn();
152 llvm::Constant *getMessageSendSuperFpretFn2() const {
153 // There is no objc_msgSendSuper_fpret? How can that work?
154 return getMessageSendSuperFn2();
158 CodeGen::CodeGenModule &CGM;
161 llvm::Type *ShortTy, *IntTy, *LongTy, *LongLongTy;
162 llvm::Type *Int8PtrTy;
164 /// ObjectPtrTy - LLVM type for object handles (typeof(id))
165 llvm::Type *ObjectPtrTy;
167 /// PtrObjectPtrTy - LLVM type for id *
168 llvm::Type *PtrObjectPtrTy;
170 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
171 llvm::Type *SelectorPtrTy;
172 /// ProtocolPtrTy - LLVM type for external protocol handles
173 /// (typeof(Protocol))
174 llvm::Type *ExternalProtocolPtrTy;
176 // SuperCTy - clang type for struct objc_super.
178 // SuperPtrCTy - clang type for struct objc_super *.
179 QualType SuperPtrCTy;
181 /// SuperTy - LLVM type for struct objc_super.
182 llvm::StructType *SuperTy;
183 /// SuperPtrTy - LLVM type for struct objc_super *.
184 llvm::Type *SuperPtrTy;
186 /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
187 /// in GCC parlance).
188 llvm::StructType *PropertyTy;
190 /// PropertyListTy - LLVM type for struct objc_property_list
191 /// (_prop_list_t in GCC parlance).
192 llvm::StructType *PropertyListTy;
193 /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
194 llvm::Type *PropertyListPtrTy;
196 // MethodTy - LLVM type for struct objc_method.
197 llvm::StructType *MethodTy;
199 /// CacheTy - LLVM type for struct objc_cache.
201 /// CachePtrTy - LLVM type for struct objc_cache *.
202 llvm::Type *CachePtrTy;
204 llvm::Constant *getGetPropertyFn() {
205 CodeGen::CodeGenTypes &Types = CGM.getTypes();
206 ASTContext &Ctx = CGM.getContext();
207 // id objc_getProperty (id, SEL, ptrdiff_t, bool)
208 SmallVector<CanQualType,4> Params;
209 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
210 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
211 Params.push_back(IdType);
212 Params.push_back(SelType);
213 Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
214 Params.push_back(Ctx.BoolTy);
215 llvm::FunctionType *FTy =
216 Types.GetFunctionType(Types.getFunctionInfo(IdType, Params,
217 FunctionType::ExtInfo()),
219 return CGM.CreateRuntimeFunction(FTy, "objc_getProperty");
222 llvm::Constant *getSetPropertyFn() {
223 CodeGen::CodeGenTypes &Types = CGM.getTypes();
224 ASTContext &Ctx = CGM.getContext();
225 // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool)
226 SmallVector<CanQualType,6> Params;
227 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
228 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
229 Params.push_back(IdType);
230 Params.push_back(SelType);
231 Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
232 Params.push_back(IdType);
233 Params.push_back(Ctx.BoolTy);
234 Params.push_back(Ctx.BoolTy);
235 llvm::FunctionType *FTy =
236 Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
237 FunctionType::ExtInfo()),
239 return CGM.CreateRuntimeFunction(FTy, "objc_setProperty");
243 llvm::Constant *getCopyStructFn() {
244 CodeGen::CodeGenTypes &Types = CGM.getTypes();
245 ASTContext &Ctx = CGM.getContext();
246 // void objc_copyStruct (void *, const void *, size_t, bool, bool)
247 SmallVector<CanQualType,5> Params;
248 Params.push_back(Ctx.VoidPtrTy);
249 Params.push_back(Ctx.VoidPtrTy);
250 Params.push_back(Ctx.LongTy);
251 Params.push_back(Ctx.BoolTy);
252 Params.push_back(Ctx.BoolTy);
253 llvm::FunctionType *FTy =
254 Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
255 FunctionType::ExtInfo()),
257 return CGM.CreateRuntimeFunction(FTy, "objc_copyStruct");
260 llvm::Constant *getEnumerationMutationFn() {
261 CodeGen::CodeGenTypes &Types = CGM.getTypes();
262 ASTContext &Ctx = CGM.getContext();
263 // void objc_enumerationMutation (id)
264 SmallVector<CanQualType,1> Params;
265 Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType()));
266 llvm::FunctionType *FTy =
267 Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
268 FunctionType::ExtInfo()),
270 return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
273 /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function.
274 llvm::Constant *getGcReadWeakFn() {
275 // id objc_read_weak (id *)
276 llvm::Type *args[] = { ObjectPtrTy->getPointerTo() };
277 llvm::FunctionType *FTy =
278 llvm::FunctionType::get(ObjectPtrTy, args, false);
279 return CGM.CreateRuntimeFunction(FTy, "objc_read_weak");
282 /// GcAssignWeakFn -- LLVM objc_assign_weak function.
283 llvm::Constant *getGcAssignWeakFn() {
284 // id objc_assign_weak (id, id *)
285 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
286 llvm::FunctionType *FTy =
287 llvm::FunctionType::get(ObjectPtrTy, args, false);
288 return CGM.CreateRuntimeFunction(FTy, "objc_assign_weak");
291 /// GcAssignGlobalFn -- LLVM objc_assign_global function.
292 llvm::Constant *getGcAssignGlobalFn() {
293 // id objc_assign_global(id, id *)
294 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
295 llvm::FunctionType *FTy =
296 llvm::FunctionType::get(ObjectPtrTy, args, false);
297 return CGM.CreateRuntimeFunction(FTy, "objc_assign_global");
300 /// GcAssignThreadLocalFn -- LLVM objc_assign_threadlocal function.
301 llvm::Constant *getGcAssignThreadLocalFn() {
302 // id objc_assign_threadlocal(id src, id * dest)
303 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
304 llvm::FunctionType *FTy =
305 llvm::FunctionType::get(ObjectPtrTy, args, false);
306 return CGM.CreateRuntimeFunction(FTy, "objc_assign_threadlocal");
309 /// GcAssignIvarFn -- LLVM objc_assign_ivar function.
310 llvm::Constant *getGcAssignIvarFn() {
311 // id objc_assign_ivar(id, id *, ptrdiff_t)
312 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo(),
314 llvm::FunctionType *FTy =
315 llvm::FunctionType::get(ObjectPtrTy, args, false);
316 return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar");
319 /// GcMemmoveCollectableFn -- LLVM objc_memmove_collectable function.
320 llvm::Constant *GcMemmoveCollectableFn() {
321 // void *objc_memmove_collectable(void *dst, const void *src, size_t size)
322 llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy };
323 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args, false);
324 return CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable");
327 /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function.
328 llvm::Constant *getGcAssignStrongCastFn() {
329 // id objc_assign_strongCast(id, id *)
330 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
331 llvm::FunctionType *FTy =
332 llvm::FunctionType::get(ObjectPtrTy, args, false);
333 return CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast");
336 /// ExceptionThrowFn - LLVM objc_exception_throw function.
337 llvm::Constant *getExceptionThrowFn() {
338 // void objc_exception_throw(id)
339 llvm::Type *args[] = { ObjectPtrTy };
340 llvm::FunctionType *FTy =
341 llvm::FunctionType::get(CGM.VoidTy, args, false);
342 return CGM.CreateRuntimeFunction(FTy, "objc_exception_throw");
345 /// ExceptionRethrowFn - LLVM objc_exception_rethrow function.
346 llvm::Constant *getExceptionRethrowFn() {
347 // void objc_exception_rethrow(void)
348 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, false);
349 return CGM.CreateRuntimeFunction(FTy, "objc_exception_rethrow");
352 /// SyncEnterFn - LLVM object_sync_enter function.
353 llvm::Constant *getSyncEnterFn() {
354 // void objc_sync_enter (id)
355 llvm::Type *args[] = { ObjectPtrTy };
356 llvm::FunctionType *FTy =
357 llvm::FunctionType::get(CGM.VoidTy, args, false);
358 return CGM.CreateRuntimeFunction(FTy, "objc_sync_enter");
361 /// SyncExitFn - LLVM object_sync_exit function.
362 llvm::Constant *getSyncExitFn() {
363 // void objc_sync_exit (id)
364 llvm::Type *args[] = { ObjectPtrTy };
365 llvm::FunctionType *FTy =
366 llvm::FunctionType::get(CGM.VoidTy, args, false);
367 return CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
370 llvm::Constant *getSendFn(bool IsSuper) const {
371 return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
374 llvm::Constant *getSendFn2(bool IsSuper) const {
375 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
378 llvm::Constant *getSendStretFn(bool IsSuper) const {
379 return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
382 llvm::Constant *getSendStretFn2(bool IsSuper) const {
383 return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
386 llvm::Constant *getSendFpretFn(bool IsSuper) const {
387 return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
390 llvm::Constant *getSendFpretFn2(bool IsSuper) const {
391 return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
394 ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm);
395 ~ObjCCommonTypesHelper(){}
398 /// ObjCTypesHelper - Helper class that encapsulates lazy
399 /// construction of varies types used during ObjC generation.
400 class ObjCTypesHelper : public ObjCCommonTypesHelper {
402 /// SymtabTy - LLVM type for struct objc_symtab.
403 llvm::StructType *SymtabTy;
404 /// SymtabPtrTy - LLVM type for struct objc_symtab *.
405 llvm::Type *SymtabPtrTy;
406 /// ModuleTy - LLVM type for struct objc_module.
407 llvm::StructType *ModuleTy;
409 /// ProtocolTy - LLVM type for struct objc_protocol.
410 llvm::StructType *ProtocolTy;
411 /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
412 llvm::Type *ProtocolPtrTy;
413 /// ProtocolExtensionTy - LLVM type for struct
414 /// objc_protocol_extension.
415 llvm::StructType *ProtocolExtensionTy;
416 /// ProtocolExtensionTy - LLVM type for struct
417 /// objc_protocol_extension *.
418 llvm::Type *ProtocolExtensionPtrTy;
419 /// MethodDescriptionTy - LLVM type for struct
420 /// objc_method_description.
421 llvm::StructType *MethodDescriptionTy;
422 /// MethodDescriptionListTy - LLVM type for struct
423 /// objc_method_description_list.
424 llvm::StructType *MethodDescriptionListTy;
425 /// MethodDescriptionListPtrTy - LLVM type for struct
426 /// objc_method_description_list *.
427 llvm::Type *MethodDescriptionListPtrTy;
428 /// ProtocolListTy - LLVM type for struct objc_property_list.
429 llvm::StructType *ProtocolListTy;
430 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
431 llvm::Type *ProtocolListPtrTy;
432 /// CategoryTy - LLVM type for struct objc_category.
433 llvm::StructType *CategoryTy;
434 /// ClassTy - LLVM type for struct objc_class.
435 llvm::StructType *ClassTy;
436 /// ClassPtrTy - LLVM type for struct objc_class *.
437 llvm::Type *ClassPtrTy;
438 /// ClassExtensionTy - LLVM type for struct objc_class_ext.
439 llvm::StructType *ClassExtensionTy;
440 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
441 llvm::Type *ClassExtensionPtrTy;
442 // IvarTy - LLVM type for struct objc_ivar.
443 llvm::StructType *IvarTy;
444 /// IvarListTy - LLVM type for struct objc_ivar_list.
445 llvm::Type *IvarListTy;
446 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
447 llvm::Type *IvarListPtrTy;
448 /// MethodListTy - LLVM type for struct objc_method_list.
449 llvm::Type *MethodListTy;
450 /// MethodListPtrTy - LLVM type for struct objc_method_list *.
451 llvm::Type *MethodListPtrTy;
453 /// ExceptionDataTy - LLVM type for struct _objc_exception_data.
454 llvm::Type *ExceptionDataTy;
456 /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.
457 llvm::Constant *getExceptionTryEnterFn() {
458 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
459 return CGM.CreateRuntimeFunction(
460 llvm::FunctionType::get(CGM.VoidTy, params, false),
461 "objc_exception_try_enter");
464 /// ExceptionTryExitFn - LLVM objc_exception_try_exit function.
465 llvm::Constant *getExceptionTryExitFn() {
466 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
467 return CGM.CreateRuntimeFunction(
468 llvm::FunctionType::get(CGM.VoidTy, params, false),
469 "objc_exception_try_exit");
472 /// ExceptionExtractFn - LLVM objc_exception_extract function.
473 llvm::Constant *getExceptionExtractFn() {
474 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
475 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
477 "objc_exception_extract");
480 /// ExceptionMatchFn - LLVM objc_exception_match function.
481 llvm::Constant *getExceptionMatchFn() {
482 llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy };
483 return CGM.CreateRuntimeFunction(
484 llvm::FunctionType::get(CGM.Int32Ty, params, false),
485 "objc_exception_match");
489 /// SetJmpFn - LLVM _setjmp function.
490 llvm::Constant *getSetJmpFn() {
491 // This is specifically the prototype for x86.
492 llvm::Type *params[] = { CGM.Int32Ty->getPointerTo() };
493 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty,
499 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
500 ~ObjCTypesHelper() {}
503 /// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's
505 class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {
508 // MethodListnfABITy - LLVM for struct _method_list_t
509 llvm::StructType *MethodListnfABITy;
511 // MethodListnfABIPtrTy - LLVM for struct _method_list_t*
512 llvm::Type *MethodListnfABIPtrTy;
514 // ProtocolnfABITy = LLVM for struct _protocol_t
515 llvm::StructType *ProtocolnfABITy;
517 // ProtocolnfABIPtrTy = LLVM for struct _protocol_t*
518 llvm::Type *ProtocolnfABIPtrTy;
520 // ProtocolListnfABITy - LLVM for struct _objc_protocol_list
521 llvm::StructType *ProtocolListnfABITy;
523 // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list*
524 llvm::Type *ProtocolListnfABIPtrTy;
526 // ClassnfABITy - LLVM for struct _class_t
527 llvm::StructType *ClassnfABITy;
529 // ClassnfABIPtrTy - LLVM for struct _class_t*
530 llvm::Type *ClassnfABIPtrTy;
532 // IvarnfABITy - LLVM for struct _ivar_t
533 llvm::StructType *IvarnfABITy;
535 // IvarListnfABITy - LLVM for struct _ivar_list_t
536 llvm::StructType *IvarListnfABITy;
538 // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t*
539 llvm::Type *IvarListnfABIPtrTy;
541 // ClassRonfABITy - LLVM for struct _class_ro_t
542 llvm::StructType *ClassRonfABITy;
544 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
545 llvm::Type *ImpnfABITy;
547 // CategorynfABITy - LLVM for struct _category_t
548 llvm::StructType *CategorynfABITy;
550 // New types for nonfragile abi messaging.
552 // MessageRefTy - LLVM for:
553 // struct _message_ref_t {
557 llvm::StructType *MessageRefTy;
558 // MessageRefCTy - clang type for struct _message_ref_t
559 QualType MessageRefCTy;
561 // MessageRefPtrTy - LLVM for struct _message_ref_t*
562 llvm::Type *MessageRefPtrTy;
563 // MessageRefCPtrTy - clang type for struct _message_ref_t*
564 QualType MessageRefCPtrTy;
566 // MessengerTy - Type of the messenger (shown as IMP above)
567 llvm::FunctionType *MessengerTy;
569 // SuperMessageRefTy - LLVM for:
570 // struct _super_message_ref_t {
571 // SUPER_IMP messenger;
574 llvm::StructType *SuperMessageRefTy;
576 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
577 llvm::Type *SuperMessageRefPtrTy;
579 llvm::Constant *getMessageSendFixupFn() {
580 // id objc_msgSend_fixup(id, struct message_ref_t*, ...)
581 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
582 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
584 "objc_msgSend_fixup");
587 llvm::Constant *getMessageSendFpretFixupFn() {
588 // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...)
589 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
590 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
592 "objc_msgSend_fpret_fixup");
595 llvm::Constant *getMessageSendStretFixupFn() {
596 // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...)
597 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
598 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
600 "objc_msgSend_stret_fixup");
603 llvm::Constant *getMessageSendSuper2FixupFn() {
604 // id objc_msgSendSuper2_fixup (struct objc_super *,
605 // struct _super_message_ref_t*, ...)
606 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
607 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
609 "objc_msgSendSuper2_fixup");
612 llvm::Constant *getMessageSendSuper2StretFixupFn() {
613 // id objc_msgSendSuper2_stret_fixup(struct objc_super *,
614 // struct _super_message_ref_t*, ...)
615 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
616 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
618 "objc_msgSendSuper2_stret_fixup");
621 llvm::Constant *getObjCEndCatchFn() {
622 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy, false),
627 llvm::Constant *getObjCBeginCatchFn() {
628 llvm::Type *params[] = { Int8PtrTy };
629 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy,
634 llvm::StructType *EHTypeTy;
635 llvm::Type *EHTypePtrTy;
637 ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
638 ~ObjCNonFragileABITypesHelper(){}
641 class CGObjCCommonMac : public CodeGen::CGObjCRuntime {
643 // FIXME - accessibility
646 unsigned ivar_bytepos;
648 GC_IVAR(unsigned bytepos = 0, unsigned size = 0)
649 : ivar_bytepos(bytepos), ivar_size(size) {}
651 // Allow sorting based on byte pos.
652 bool operator<(const GC_IVAR &b) const {
653 return ivar_bytepos < b.ivar_bytepos;
661 SKIP_SCAN(unsigned _skip = 0, unsigned _scan = 0)
662 : skip(_skip), scan(_scan) {}
666 CodeGen::CodeGenModule &CGM;
667 llvm::LLVMContext &VMContext;
668 // FIXME! May not be needing this after all.
671 // gc ivar layout bitmap calculation helper caches.
672 SmallVector<GC_IVAR, 16> SkipIvars;
673 SmallVector<GC_IVAR, 16> IvarsInfo;
675 /// LazySymbols - Symbols to generate a lazy reference for. See
676 /// DefinedSymbols and FinishModule().
677 llvm::SetVector<IdentifierInfo*> LazySymbols;
679 /// DefinedSymbols - External symbols which are defined by this
680 /// module. The symbols in this list and LazySymbols are used to add
681 /// special linker symbols which ensure that Objective-C modules are
683 llvm::SetVector<IdentifierInfo*> DefinedSymbols;
685 /// ClassNames - uniqued class names.
686 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
688 /// MethodVarNames - uniqued method variable names.
689 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
691 /// DefinedCategoryNames - list of category names in form Class_Category.
692 llvm::SetVector<std::string> DefinedCategoryNames;
694 /// MethodVarTypes - uniqued method type signatures. We have to use
695 /// a StringMap here because have no other unique reference.
696 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
698 /// MethodDefinitions - map of methods which have been defined in
699 /// this translation unit.
700 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
702 /// PropertyNames - uniqued method variable names.
703 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
705 /// ClassReferences - uniqued class references.
706 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
708 /// SelectorReferences - uniqued selector references.
709 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
711 /// Protocols - Protocols for which an objc_protocol structure has
712 /// been emitted. Forward declarations are handled by creating an
713 /// empty structure whose initializer is filled in when/if defined.
714 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
716 /// DefinedProtocols - Protocols which have actually been
717 /// defined. We should not need this, see FIXME in GenerateProtocol.
718 llvm::DenseSet<IdentifierInfo*> DefinedProtocols;
720 /// DefinedClasses - List of defined classes.
721 std::vector<llvm::GlobalValue*> DefinedClasses;
723 /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
724 std::vector<llvm::GlobalValue*> DefinedNonLazyClasses;
726 /// DefinedCategories - List of defined categories.
727 std::vector<llvm::GlobalValue*> DefinedCategories;
729 /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
730 std::vector<llvm::GlobalValue*> DefinedNonLazyCategories;
732 /// GetNameForMethod - Return a name for the given method.
733 /// \param[out] NameOut - The return value.
734 void GetNameForMethod(const ObjCMethodDecl *OMD,
735 const ObjCContainerDecl *CD,
736 SmallVectorImpl<char> &NameOut);
738 /// GetMethodVarName - Return a unique constant for the given
739 /// selector's name. The return value has type char *.
740 llvm::Constant *GetMethodVarName(Selector Sel);
741 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
743 /// GetMethodVarType - Return a unique constant for the given
744 /// selector's name. The return value has type char *.
746 // FIXME: This is a horrible name.
747 llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D);
748 llvm::Constant *GetMethodVarType(const FieldDecl *D);
750 /// GetPropertyName - Return a unique constant for the given
751 /// name. The return value has type char *.
752 llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
754 // FIXME: This can be dropped once string functions are unified.
755 llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,
756 const Decl *Container);
758 /// GetClassName - Return a unique constant for the given selector's
759 /// name. The return value has type char *.
760 llvm::Constant *GetClassName(IdentifierInfo *Ident);
762 llvm::Function *GetMethodDefinition(const ObjCMethodDecl *MD);
764 /// BuildIvarLayout - Builds ivar layout bitmap for the class
765 /// implementation for the __strong or __weak case.
767 llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI,
768 bool ForStrongLayout);
770 llvm::Constant *BuildIvarLayoutBitmap(std::string &BitMap);
772 void BuildAggrIvarRecordLayout(const RecordType *RT,
773 unsigned int BytePos, bool ForStrongLayout,
775 void BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
776 const llvm::StructLayout *Layout,
777 const RecordDecl *RD,
778 const SmallVectorImpl<const FieldDecl*> &RecFields,
779 unsigned int BytePos, bool ForStrongLayout,
782 /// GetIvarLayoutName - Returns a unique constant for the given
783 /// ivar layout bitmap.
784 llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident,
785 const ObjCCommonTypesHelper &ObjCTypes);
787 /// EmitPropertyList - Emit the given property list. The return
788 /// value has type PropertyListPtrTy.
789 llvm::Constant *EmitPropertyList(Twine Name,
790 const Decl *Container,
791 const ObjCContainerDecl *OCD,
792 const ObjCCommonTypesHelper &ObjCTypes);
794 /// PushProtocolProperties - Push protocol's property on the input stack.
795 void PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet,
796 std::vector<llvm::Constant*> &Properties,
797 const Decl *Container,
798 const ObjCProtocolDecl *PROTO,
799 const ObjCCommonTypesHelper &ObjCTypes);
801 /// GetProtocolRef - Return a reference to the internal protocol
802 /// description, creating an empty one if it has not been
803 /// defined. The return value has type ProtocolPtrTy.
804 llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD);
806 /// CreateMetadataVar - Create a global variable with internal
807 /// linkage for use by the Objective-C runtime.
809 /// This is a convenience wrapper which not only creates the
810 /// variable, but also sets the section and alignment and adds the
811 /// global to the "llvm.used" list.
813 /// \param Name - The variable name.
814 /// \param Init - The variable initializer; this is also used to
815 /// define the type of the variable.
816 /// \param Section - The section the variable should go into, or 0.
817 /// \param Align - The alignment for the variable, or 0.
818 /// \param AddToUsed - Whether the variable should be added to
820 llvm::GlobalVariable *CreateMetadataVar(Twine Name,
821 llvm::Constant *Init,
826 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
827 ReturnValueSlot Return,
833 const CallArgList &CallArgs,
834 const ObjCMethodDecl *OMD,
835 const ObjCCommonTypesHelper &ObjCTypes);
837 /// EmitImageInfo - Emit the image info marker used to encode some module
838 /// level information.
839 void EmitImageInfo();
842 CGObjCCommonMac(CodeGen::CodeGenModule &cgm) :
843 CGM(cgm), VMContext(cgm.getLLVMContext()) { }
845 virtual llvm::Constant *GenerateConstantString(const StringLiteral *SL);
847 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
848 const ObjCContainerDecl *CD=0);
850 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
852 /// GetOrEmitProtocol - Get the protocol object for the given
853 /// declaration, emitting it if necessary. The return value has type
855 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0;
857 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
858 /// object for the given declaration, emitting it if needed. These
859 /// forward references will be filled in with empty bodies if no
860 /// definition is seen. The return value has type ProtocolPtrTy.
861 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0;
862 virtual llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
863 const CGBlockInfo &blockInfo);
867 class CGObjCMac : public CGObjCCommonMac {
869 ObjCTypesHelper ObjCTypes;
871 /// EmitModuleInfo - Another marker encoding module level
873 void EmitModuleInfo();
875 /// EmitModuleSymols - Emit module symbols, the list of defined
876 /// classes and categories. The result has type SymtabPtrTy.
877 llvm::Constant *EmitModuleSymbols();
879 /// FinishModule - Write out global data structures at the end of
880 /// processing a translation unit.
883 /// EmitClassExtension - Generate the class extension structure used
884 /// to store the weak ivar layout and properties. The return value
885 /// has type ClassExtensionPtrTy.
886 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
888 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
889 /// for the given class.
890 llvm::Value *EmitClassRef(CGBuilderTy &Builder,
891 const ObjCInterfaceDecl *ID);
893 llvm::Value *EmitClassRefFromId(CGBuilderTy &Builder,
896 llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder);
898 /// EmitSuperClassRef - Emits reference to class's main metadata class.
899 llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID);
901 /// EmitIvarList - Emit the ivar list for the given
902 /// implementation. If ForClass is true the list of class ivars
903 /// (i.e. metaclass ivars) is emitted, otherwise the list of
904 /// interface ivars will be emitted. The return value has type
906 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
909 /// EmitMetaClass - Emit a forward reference to the class structure
910 /// for the metaclass of the given interface. The return value has
912 llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID);
914 /// EmitMetaClass - Emit a class structure for the metaclass of the
915 /// given implementation. The return value has type ClassPtrTy.
916 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
917 llvm::Constant *Protocols,
918 const ConstantVector &Methods);
920 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
922 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
924 /// EmitMethodList - Emit the method list for the given
925 /// implementation. The return value has type MethodListPtrTy.
926 llvm::Constant *EmitMethodList(Twine Name,
928 const ConstantVector &Methods);
930 /// EmitMethodDescList - Emit a method description list for a list of
931 /// method declarations.
932 /// - TypeName: The name for the type containing the methods.
933 /// - IsProtocol: True iff these methods are for a protocol.
934 /// - ClassMethds: True iff these are class methods.
935 /// - Required: When true, only "required" methods are
936 /// listed. Similarly, when false only "optional" methods are
937 /// listed. For classes this should always be true.
938 /// - begin, end: The method list to output.
940 /// The return value has type MethodDescriptionListPtrTy.
941 llvm::Constant *EmitMethodDescList(Twine Name,
943 const ConstantVector &Methods);
945 /// GetOrEmitProtocol - Get the protocol object for the given
946 /// declaration, emitting it if necessary. The return value has type
948 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
950 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
951 /// object for the given declaration, emitting it if needed. These
952 /// forward references will be filled in with empty bodies if no
953 /// definition is seen. The return value has type ProtocolPtrTy.
954 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
956 /// EmitProtocolExtension - Generate the protocol extension
957 /// structure used to store optional instance and class methods, and
958 /// protocol properties. The return value has type
959 /// ProtocolExtensionPtrTy.
961 EmitProtocolExtension(const ObjCProtocolDecl *PD,
962 const ConstantVector &OptInstanceMethods,
963 const ConstantVector &OptClassMethods);
965 /// EmitProtocolList - Generate the list of referenced
966 /// protocols. The return value has type ProtocolListPtrTy.
967 llvm::Constant *EmitProtocolList(Twine Name,
968 ObjCProtocolDecl::protocol_iterator begin,
969 ObjCProtocolDecl::protocol_iterator end);
971 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
972 /// for the given selector.
973 llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel,
977 CGObjCMac(CodeGen::CodeGenModule &cgm);
979 virtual llvm::Function *ModuleInitFunction();
981 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
982 ReturnValueSlot Return,
985 llvm::Value *Receiver,
986 const CallArgList &CallArgs,
987 const ObjCInterfaceDecl *Class,
988 const ObjCMethodDecl *Method);
990 virtual CodeGen::RValue
991 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
992 ReturnValueSlot Return,
995 const ObjCInterfaceDecl *Class,
997 llvm::Value *Receiver,
999 const CallArgList &CallArgs,
1000 const ObjCMethodDecl *Method);
1002 virtual llvm::Value *GetClass(CGBuilderTy &Builder,
1003 const ObjCInterfaceDecl *ID);
1005 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel,
1008 /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1010 virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
1011 const ObjCMethodDecl *Method);
1013 virtual llvm::Constant *GetEHType(QualType T);
1015 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
1017 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
1019 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
1020 const ObjCProtocolDecl *PD);
1022 virtual llvm::Constant *GetPropertyGetFunction();
1023 virtual llvm::Constant *GetPropertySetFunction();
1024 virtual llvm::Constant *GetGetStructFunction();
1025 virtual llvm::Constant *GetSetStructFunction();
1026 virtual llvm::Constant *EnumerationMutationFunction();
1028 virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1029 const ObjCAtTryStmt &S);
1030 virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1031 const ObjCAtSynchronizedStmt &S);
1032 void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const Stmt &S);
1033 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
1034 const ObjCAtThrowStmt &S);
1035 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1036 llvm::Value *AddrWeakObj);
1037 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1038 llvm::Value *src, llvm::Value *dst);
1039 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1040 llvm::Value *src, llvm::Value *dest,
1041 bool threadlocal = false);
1042 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
1043 llvm::Value *src, llvm::Value *dest,
1044 llvm::Value *ivarOffset);
1045 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
1046 llvm::Value *src, llvm::Value *dest);
1047 virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1048 llvm::Value *dest, llvm::Value *src,
1051 virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
1053 llvm::Value *BaseValue,
1054 const ObjCIvarDecl *Ivar,
1055 unsigned CVRQualifiers);
1056 virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1057 const ObjCInterfaceDecl *Interface,
1058 const ObjCIvarDecl *Ivar);
1060 /// GetClassGlobal - Return the global variable for the Objective-C
1061 /// class of the given name.
1062 virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) {
1063 llvm_unreachable("CGObjCMac::GetClassGlobal");
1067 class CGObjCNonFragileABIMac : public CGObjCCommonMac {
1069 ObjCNonFragileABITypesHelper ObjCTypes;
1070 llvm::GlobalVariable* ObjCEmptyCacheVar;
1071 llvm::GlobalVariable* ObjCEmptyVtableVar;
1073 /// SuperClassReferences - uniqued super class references.
1074 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
1076 /// MetaClassReferences - uniqued meta class references.
1077 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
1079 /// EHTypeReferences - uniqued class ehtype references.
1080 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
1082 /// VTableDispatchMethods - List of methods for which we generate
1083 /// vtable-based message dispatch.
1084 llvm::DenseSet<Selector> VTableDispatchMethods;
1086 /// DefinedMetaClasses - List of defined meta-classes.
1087 std::vector<llvm::GlobalValue*> DefinedMetaClasses;
1089 /// isVTableDispatchedSelector - Returns true if SEL is a
1090 /// vtable-based selector.
1091 bool isVTableDispatchedSelector(Selector Sel);
1093 /// FinishNonFragileABIModule - Write out global data structures at the end of
1094 /// processing a translation unit.
1095 void FinishNonFragileABIModule();
1097 /// AddModuleClassList - Add the given list of class pointers to the
1098 /// module with the provided symbol and section names.
1099 void AddModuleClassList(const std::vector<llvm::GlobalValue*> &Container,
1100 const char *SymbolName,
1101 const char *SectionName);
1103 llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags,
1104 unsigned InstanceStart,
1105 unsigned InstanceSize,
1106 const ObjCImplementationDecl *ID);
1107 llvm::GlobalVariable * BuildClassMetaData(std::string &ClassName,
1108 llvm::Constant *IsAGV,
1109 llvm::Constant *SuperClassGV,
1110 llvm::Constant *ClassRoGV,
1111 bool HiddenVisibility);
1113 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
1115 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
1117 /// EmitMethodList - Emit the method list for the given
1118 /// implementation. The return value has type MethodListnfABITy.
1119 llvm::Constant *EmitMethodList(Twine Name,
1120 const char *Section,
1121 const ConstantVector &Methods);
1122 /// EmitIvarList - Emit the ivar list for the given
1123 /// implementation. If ForClass is true the list of class ivars
1124 /// (i.e. metaclass ivars) is emitted, otherwise the list of
1125 /// interface ivars will be emitted. The return value has type
1126 /// IvarListnfABIPtrTy.
1127 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID);
1129 llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
1130 const ObjCIvarDecl *Ivar,
1131 unsigned long int offset);
1133 /// GetOrEmitProtocol - Get the protocol object for the given
1134 /// declaration, emitting it if necessary. The return value has type
1136 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
1138 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1139 /// object for the given declaration, emitting it if needed. These
1140 /// forward references will be filled in with empty bodies if no
1141 /// definition is seen. The return value has type ProtocolPtrTy.
1142 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
1144 /// EmitProtocolList - Generate the list of referenced
1145 /// protocols. The return value has type ProtocolListPtrTy.
1146 llvm::Constant *EmitProtocolList(Twine Name,
1147 ObjCProtocolDecl::protocol_iterator begin,
1148 ObjCProtocolDecl::protocol_iterator end);
1150 CodeGen::RValue EmitVTableMessageSend(CodeGen::CodeGenFunction &CGF,
1151 ReturnValueSlot Return,
1152 QualType ResultType,
1154 llvm::Value *Receiver,
1157 const CallArgList &CallArgs,
1158 const ObjCMethodDecl *Method);
1160 /// GetClassGlobal - Return the global variable for the Objective-C
1161 /// class of the given name.
1162 llvm::GlobalVariable *GetClassGlobal(const std::string &Name);
1164 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1165 /// for the given class reference.
1166 llvm::Value *EmitClassRef(CGBuilderTy &Builder,
1167 const ObjCInterfaceDecl *ID);
1169 llvm::Value *EmitClassRefFromId(CGBuilderTy &Builder,
1170 IdentifierInfo *II);
1172 llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder);
1174 /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1175 /// for the given super class reference.
1176 llvm::Value *EmitSuperClassRef(CGBuilderTy &Builder,
1177 const ObjCInterfaceDecl *ID);
1179 /// EmitMetaClassRef - Return a Value * of the address of _class_t
1181 llvm::Value *EmitMetaClassRef(CGBuilderTy &Builder,
1182 const ObjCInterfaceDecl *ID);
1184 /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
1187 llvm::GlobalVariable * ObjCIvarOffsetVariable(
1188 const ObjCInterfaceDecl *ID,
1189 const ObjCIvarDecl *Ivar);
1191 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
1192 /// for the given selector.
1193 llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel,
1196 /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C
1197 /// interface. The return value has type EHTypePtrTy.
1198 llvm::Constant *GetInterfaceEHType(const ObjCInterfaceDecl *ID,
1199 bool ForDefinition);
1201 const char *getMetaclassSymbolPrefix() const {
1202 return "OBJC_METACLASS_$_";
1205 const char *getClassSymbolPrefix() const {
1206 return "OBJC_CLASS_$_";
1209 void GetClassSizeInfo(const ObjCImplementationDecl *OID,
1210 uint32_t &InstanceStart,
1211 uint32_t &InstanceSize);
1213 // Shamelessly stolen from Analysis/CFRefCount.cpp
1214 Selector GetNullarySelector(const char* name) const {
1215 IdentifierInfo* II = &CGM.getContext().Idents.get(name);
1216 return CGM.getContext().Selectors.getSelector(0, &II);
1219 Selector GetUnarySelector(const char* name) const {
1220 IdentifierInfo* II = &CGM.getContext().Idents.get(name);
1221 return CGM.getContext().Selectors.getSelector(1, &II);
1224 /// ImplementationIsNonLazy - Check whether the given category or
1225 /// class implementation is "non-lazy".
1226 bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const;
1229 CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
1230 // FIXME. All stubs for now!
1231 virtual llvm::Function *ModuleInitFunction();
1233 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1234 ReturnValueSlot Return,
1235 QualType ResultType,
1237 llvm::Value *Receiver,
1238 const CallArgList &CallArgs,
1239 const ObjCInterfaceDecl *Class,
1240 const ObjCMethodDecl *Method);
1242 virtual CodeGen::RValue
1243 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1244 ReturnValueSlot Return,
1245 QualType ResultType,
1247 const ObjCInterfaceDecl *Class,
1248 bool isCategoryImpl,
1249 llvm::Value *Receiver,
1250 bool IsClassMessage,
1251 const CallArgList &CallArgs,
1252 const ObjCMethodDecl *Method);
1254 virtual llvm::Value *GetClass(CGBuilderTy &Builder,
1255 const ObjCInterfaceDecl *ID);
1257 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel,
1258 bool lvalue = false)
1259 { return EmitSelector(Builder, Sel, lvalue); }
1261 /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1263 virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
1264 const ObjCMethodDecl *Method)
1265 { return EmitSelector(Builder, Method->getSelector()); }
1267 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
1269 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
1270 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
1271 const ObjCProtocolDecl *PD);
1273 virtual llvm::Constant *GetEHType(QualType T);
1275 virtual llvm::Constant *GetPropertyGetFunction() {
1276 return ObjCTypes.getGetPropertyFn();
1278 virtual llvm::Constant *GetPropertySetFunction() {
1279 return ObjCTypes.getSetPropertyFn();
1282 virtual llvm::Constant *GetSetStructFunction() {
1283 return ObjCTypes.getCopyStructFn();
1285 virtual llvm::Constant *GetGetStructFunction() {
1286 return ObjCTypes.getCopyStructFn();
1289 virtual llvm::Constant *EnumerationMutationFunction() {
1290 return ObjCTypes.getEnumerationMutationFn();
1293 virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1294 const ObjCAtTryStmt &S);
1295 virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1296 const ObjCAtSynchronizedStmt &S);
1297 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
1298 const ObjCAtThrowStmt &S);
1299 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1300 llvm::Value *AddrWeakObj);
1301 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1302 llvm::Value *src, llvm::Value *dst);
1303 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1304 llvm::Value *src, llvm::Value *dest,
1305 bool threadlocal = false);
1306 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
1307 llvm::Value *src, llvm::Value *dest,
1308 llvm::Value *ivarOffset);
1309 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
1310 llvm::Value *src, llvm::Value *dest);
1311 virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1312 llvm::Value *dest, llvm::Value *src,
1314 virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
1316 llvm::Value *BaseValue,
1317 const ObjCIvarDecl *Ivar,
1318 unsigned CVRQualifiers);
1319 virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1320 const ObjCInterfaceDecl *Interface,
1321 const ObjCIvarDecl *Ivar);
1324 /// A helper class for performing the null-initialization of a return
1326 struct NullReturnState {
1327 llvm::BasicBlock *NullBB;
1329 NullReturnState() : NullBB(0) {}
1331 void init(CodeGenFunction &CGF, llvm::Value *receiver) {
1332 // Make blocks for the null-init and call edges.
1333 NullBB = CGF.createBasicBlock("msgSend.nullinit");
1334 llvm::BasicBlock *callBB = CGF.createBasicBlock("msgSend.call");
1336 // Check for a null receiver and, if there is one, jump to the
1338 llvm::Value *isNull = CGF.Builder.CreateIsNull(receiver);
1339 CGF.Builder.CreateCondBr(isNull, NullBB, callBB);
1341 // Otherwise, start performing the call.
1342 CGF.EmitBlock(callBB);
1345 RValue complete(CodeGenFunction &CGF, RValue result, QualType resultType) {
1346 if (!NullBB) return result;
1348 // Finish the call path.
1349 llvm::BasicBlock *contBB = CGF.createBasicBlock("msgSend.cont");
1350 if (CGF.HaveInsertPoint()) CGF.Builder.CreateBr(contBB);
1352 // Emit the null-init block and perform the null-initialization there.
1353 CGF.EmitBlock(NullBB);
1354 assert(result.isAggregate() && "null init of non-aggregate result?");
1355 CGF.EmitNullInitialization(result.getAggregateAddr(), resultType);
1357 // Jump to the continuation block.
1358 CGF.EmitBlock(contBB);
1364 } // end anonymous namespace
1366 /* *** Helper Functions *** */
1368 /// getConstantGEP() - Help routine to construct simple GEPs.
1369 static llvm::Constant *getConstantGEP(llvm::LLVMContext &VMContext,
1373 llvm::Value *Idxs[] = {
1374 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1375 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
1377 return llvm::ConstantExpr::getGetElementPtr(C, Idxs);
1380 /// hasObjCExceptionAttribute - Return true if this class or any super
1381 /// class has the __objc_exception__ attribute.
1382 static bool hasObjCExceptionAttribute(ASTContext &Context,
1383 const ObjCInterfaceDecl *OID) {
1384 if (OID->hasAttr<ObjCExceptionAttr>())
1386 if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
1387 return hasObjCExceptionAttribute(Context, Super);
1391 /* *** CGObjCMac Public Interface *** */
1393 CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm),
1399 /// GetClass - Return a reference to the class for the given interface
1401 llvm::Value *CGObjCMac::GetClass(CGBuilderTy &Builder,
1402 const ObjCInterfaceDecl *ID) {
1403 return EmitClassRef(Builder, ID);
1406 /// GetSelector - Return the pointer to the unique'd string for this selector.
1407 llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, Selector Sel,
1409 return EmitSelector(Builder, Sel, lval);
1411 llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
1413 return EmitSelector(Builder, Method->getSelector());
1416 llvm::Constant *CGObjCMac::GetEHType(QualType T) {
1417 if (T->isObjCIdType() ||
1418 T->isObjCQualifiedIdType()) {
1419 return CGM.GetAddrOfRTTIDescriptor(
1420 CGM.getContext().getObjCIdRedefinitionType(), /*ForEH=*/true);
1422 if (T->isObjCClassType() ||
1423 T->isObjCQualifiedClassType()) {
1424 return CGM.GetAddrOfRTTIDescriptor(
1425 CGM.getContext().getObjCClassRedefinitionType(), /*ForEH=*/true);
1427 if (T->isObjCObjectPointerType())
1428 return CGM.GetAddrOfRTTIDescriptor(T, /*ForEH=*/true);
1430 llvm_unreachable("asking for catch type for ObjC type in fragile runtime");
1434 /// Generate a constant CFString object.
1436 struct __builtin_CFString {
1437 const int *isa; // point to __CFConstantStringClassReference
1444 /// or Generate a constant NSString object.
1446 struct __builtin_NSString {
1447 const int *isa; // point to __NSConstantStringClassReference
1449 unsigned int length;
1453 llvm::Constant *CGObjCCommonMac::GenerateConstantString(
1454 const StringLiteral *SL) {
1455 return (CGM.getLangOptions().NoConstantCFStrings == 0 ?
1456 CGM.GetAddrOfConstantCFString(SL) :
1457 CGM.GetAddrOfConstantString(SL));
1460 /// Generates a message send where the super is the receiver. This is
1461 /// a message send to self with special delivery semantics indicating
1462 /// which class's method should be called.
1464 CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1465 ReturnValueSlot Return,
1466 QualType ResultType,
1468 const ObjCInterfaceDecl *Class,
1469 bool isCategoryImpl,
1470 llvm::Value *Receiver,
1471 bool IsClassMessage,
1472 const CodeGen::CallArgList &CallArgs,
1473 const ObjCMethodDecl *Method) {
1474 // Create and init a super structure; this is a (receiver, class)
1475 // pair we will pass to objc_msgSendSuper.
1476 llvm::Value *ObjCSuper =
1477 CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super");
1478 llvm::Value *ReceiverAsObject =
1479 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
1480 CGF.Builder.CreateStore(ReceiverAsObject,
1481 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
1483 // If this is a class message the metaclass is passed as the target.
1484 llvm::Value *Target;
1485 if (IsClassMessage) {
1486 if (isCategoryImpl) {
1487 // Message sent to 'super' in a class method defined in a category
1488 // implementation requires an odd treatment.
1489 // If we are in a class method, we must retrieve the
1490 // _metaclass_ for the current class, pointed at by
1491 // the class's "isa" pointer. The following assumes that
1492 // isa" is the first ivar in a class (which it must be).
1493 Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
1494 Target = CGF.Builder.CreateStructGEP(Target, 0);
1495 Target = CGF.Builder.CreateLoad(Target);
1497 llvm::Value *MetaClassPtr = EmitMetaClassRef(Class);
1498 llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1);
1499 llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr);
1503 else if (isCategoryImpl)
1504 Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
1506 llvm::Value *ClassPtr = EmitSuperClassRef(Class);
1507 ClassPtr = CGF.Builder.CreateStructGEP(ClassPtr, 1);
1508 Target = CGF.Builder.CreateLoad(ClassPtr);
1510 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
1512 llvm::Type *ClassTy =
1513 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
1514 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
1515 CGF.Builder.CreateStore(Target,
1516 CGF.Builder.CreateStructGEP(ObjCSuper, 1));
1517 return EmitMessageSend(CGF, Return, ResultType,
1518 EmitSelector(CGF.Builder, Sel),
1519 ObjCSuper, ObjCTypes.SuperPtrCTy,
1520 true, CallArgs, Method, ObjCTypes);
1523 /// Generate code for a message send expression.
1524 CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1525 ReturnValueSlot Return,
1526 QualType ResultType,
1528 llvm::Value *Receiver,
1529 const CallArgList &CallArgs,
1530 const ObjCInterfaceDecl *Class,
1531 const ObjCMethodDecl *Method) {
1532 return EmitMessageSend(CGF, Return, ResultType,
1533 EmitSelector(CGF.Builder, Sel),
1534 Receiver, CGF.getContext().getObjCIdType(),
1535 false, CallArgs, Method, ObjCTypes);
1539 CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
1540 ReturnValueSlot Return,
1541 QualType ResultType,
1546 const CallArgList &CallArgs,
1547 const ObjCMethodDecl *Method,
1548 const ObjCCommonTypesHelper &ObjCTypes) {
1549 CallArgList ActualArgs;
1551 Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy);
1552 ActualArgs.add(RValue::get(Arg0), Arg0Ty);
1553 ActualArgs.add(RValue::get(Sel), CGF.getContext().getObjCSelType());
1554 ActualArgs.addFrom(CallArgs);
1556 CodeGenTypes &Types = CGM.getTypes();
1557 const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs,
1558 FunctionType::ExtInfo());
1559 llvm::FunctionType *FTy =
1560 Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false);
1563 assert(CGM.getContext().getCanonicalType(Method->getResultType()) ==
1564 CGM.getContext().getCanonicalType(ResultType) &&
1565 "Result type mismatch!");
1567 NullReturnState nullReturn;
1569 llvm::Constant *Fn = NULL;
1570 if (CGM.ReturnTypeUsesSRet(FnInfo)) {
1571 if (!IsSuper) nullReturn.init(CGF, Arg0);
1572 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
1573 : ObjCTypes.getSendStretFn(IsSuper);
1574 } else if (CGM.ReturnTypeUsesFPRet(ResultType)) {
1575 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
1576 : ObjCTypes.getSendFpretFn(IsSuper);
1578 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
1579 : ObjCTypes.getSendFn(IsSuper);
1581 Fn = llvm::ConstantExpr::getBitCast(Fn, llvm::PointerType::getUnqual(FTy));
1582 RValue rvalue = CGF.EmitCall(FnInfo, Fn, Return, ActualArgs);
1583 return nullReturn.complete(CGF, rvalue, ResultType);
1586 static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT) {
1587 if (FQT.isObjCGCStrong())
1588 return Qualifiers::Strong;
1590 if (FQT.isObjCGCWeak() || FQT.getObjCLifetime() == Qualifiers::OCL_Weak)
1591 return Qualifiers::Weak;
1593 if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
1594 return Qualifiers::Strong;
1596 if (const PointerType *PT = FQT->getAs<PointerType>())
1597 return GetGCAttrTypeForType(Ctx, PT->getPointeeType());
1599 return Qualifiers::GCNone;
1602 llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
1603 const CGBlockInfo &blockInfo) {
1604 llvm::Constant *nullPtr =
1605 llvm::Constant::getNullValue(llvm::Type::getInt8PtrTy(VMContext));
1607 if (CGM.getLangOptions().getGC() == LangOptions::NonGC &&
1608 !CGM.getLangOptions().ObjCAutoRefCount)
1611 bool hasUnion = false;
1614 unsigned WordSizeInBits = CGM.getContext().getTargetInfo().getPointerWidth(0);
1615 unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth();
1617 // __isa is the first field in block descriptor and must assume by runtime's
1618 // convention that it is GC'able.
1619 IvarsInfo.push_back(GC_IVAR(0, 1));
1621 const BlockDecl *blockDecl = blockInfo.getBlockDecl();
1623 // Calculate the basic layout of the block structure.
1624 const llvm::StructLayout *layout =
1625 CGM.getTargetData().getStructLayout(blockInfo.StructureType);
1627 // Ignore the optional 'this' capture: C++ objects are not assumed
1630 // Walk the captured variables.
1631 for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(),
1632 ce = blockDecl->capture_end(); ci != ce; ++ci) {
1633 const VarDecl *variable = ci->getVariable();
1634 QualType type = variable->getType();
1636 const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
1638 // Ignore constant captures.
1639 if (capture.isConstant()) continue;
1641 uint64_t fieldOffset = layout->getElementOffset(capture.getIndex());
1643 // __block variables are passed by their descriptor address.
1644 if (ci->isByRef()) {
1645 IvarsInfo.push_back(GC_IVAR(fieldOffset, /*size in words*/ 1));
1649 assert(!type->isArrayType() && "array variable should not be caught");
1650 if (const RecordType *record = type->getAs<RecordType>()) {
1651 BuildAggrIvarRecordLayout(record, fieldOffset, true, hasUnion);
1655 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), type);
1656 unsigned fieldSize = CGM.getContext().getTypeSize(type);
1658 if (GCAttr == Qualifiers::Strong)
1659 IvarsInfo.push_back(GC_IVAR(fieldOffset,
1660 fieldSize / WordSizeInBits));
1661 else if (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak)
1662 SkipIvars.push_back(GC_IVAR(fieldOffset,
1663 fieldSize / ByteSizeInBits));
1666 if (IvarsInfo.empty())
1669 // Sort on byte position; captures might not be allocated in order,
1670 // and unions can do funny things.
1671 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
1672 llvm::array_pod_sort(SkipIvars.begin(), SkipIvars.end());
1675 llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
1676 if (CGM.getLangOptions().ObjCGCBitmapPrint) {
1677 printf("\n block variable layout for block: ");
1678 const unsigned char *s = (unsigned char*)BitMap.c_str();
1679 for (unsigned i = 0; i < BitMap.size(); i++)
1681 printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
1683 printf("0x%x%s", s[i], s[i] != 0 ? ", " : "");
1690 llvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder,
1691 const ObjCProtocolDecl *PD) {
1692 // FIXME: I don't understand why gcc generates this, or where it is
1693 // resolved. Investigate. Its also wasteful to look this up over and over.
1694 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
1696 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
1697 ObjCTypes.ExternalProtocolPtrTy);
1700 void CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
1701 // FIXME: We shouldn't need this, the protocol decl should contain enough
1702 // information to tell us whether this was a declaration or a definition.
1703 DefinedProtocols.insert(PD->getIdentifier());
1705 // If we have generated a forward reference to this protocol, emit
1706 // it now. Otherwise do nothing, the protocol objects are lazily
1708 if (Protocols.count(PD->getIdentifier()))
1709 GetOrEmitProtocol(PD);
1712 llvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
1713 if (DefinedProtocols.count(PD->getIdentifier()))
1714 return GetOrEmitProtocol(PD);
1716 return GetOrEmitProtocolRef(PD);
1720 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
1721 struct _objc_protocol {
1722 struct _objc_protocol_extension *isa;
1723 char *protocol_name;
1724 struct _objc_protocol_list *protocol_list;
1725 struct _objc__method_prototype_list *instance_methods;
1726 struct _objc__method_prototype_list *class_methods
1729 See EmitProtocolExtension().
1731 llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
1732 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
1734 // Early exit if a defining object has already been generated.
1735 if (Entry && Entry->hasInitializer())
1738 // FIXME: I don't understand why gcc generates this, or where it is
1739 // resolved. Investigate. Its also wasteful to look this up over and over.
1740 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
1742 // Construct method lists.
1743 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
1744 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
1745 for (ObjCProtocolDecl::instmeth_iterator
1746 i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
1747 ObjCMethodDecl *MD = *i;
1748 llvm::Constant *C = GetMethodDescriptionConstant(MD);
1750 return GetOrEmitProtocolRef(PD);
1752 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
1753 OptInstanceMethods.push_back(C);
1755 InstanceMethods.push_back(C);
1759 for (ObjCProtocolDecl::classmeth_iterator
1760 i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
1761 ObjCMethodDecl *MD = *i;
1762 llvm::Constant *C = GetMethodDescriptionConstant(MD);
1764 return GetOrEmitProtocolRef(PD);
1766 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
1767 OptClassMethods.push_back(C);
1769 ClassMethods.push_back(C);
1773 std::vector<llvm::Constant*> Values(5);
1774 Values[0] = EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods);
1775 Values[1] = GetClassName(PD->getIdentifier());
1777 EmitProtocolList("\01L_OBJC_PROTOCOL_REFS_" + PD->getName(),
1778 PD->protocol_begin(),
1779 PD->protocol_end());
1781 EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_" + PD->getName(),
1782 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
1785 EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_" + PD->getName(),
1786 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
1788 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
1792 // Already created, fix the linkage and update the initializer.
1793 Entry->setLinkage(llvm::GlobalValue::InternalLinkage);
1794 Entry->setInitializer(Init);
1797 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,
1798 llvm::GlobalValue::InternalLinkage,
1800 "\01L_OBJC_PROTOCOL_" + PD->getName());
1801 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
1802 // FIXME: Is this necessary? Why only for protocol?
1803 Entry->setAlignment(4);
1805 CGM.AddUsedGlobal(Entry);
1810 llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
1811 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
1814 // We use the initializer as a marker of whether this is a forward
1815 // reference or not. At module finalization we add the empty
1816 // contents for protocols which were referenced but never defined.
1818 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,
1819 llvm::GlobalValue::ExternalLinkage,
1821 "\01L_OBJC_PROTOCOL_" + PD->getName());
1822 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
1823 // FIXME: Is this necessary? Why only for protocol?
1824 Entry->setAlignment(4);
1831 struct _objc_protocol_extension {
1833 struct objc_method_description_list *optional_instance_methods;
1834 struct objc_method_description_list *optional_class_methods;
1835 struct objc_property_list *instance_properties;
1839 CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
1840 const ConstantVector &OptInstanceMethods,
1841 const ConstantVector &OptClassMethods) {
1843 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
1844 std::vector<llvm::Constant*> Values(4);
1845 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
1847 EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_"
1849 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
1850 OptInstanceMethods);
1852 EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_" + PD->getName(),
1853 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
1855 Values[3] = EmitPropertyList("\01L_OBJC_$_PROP_PROTO_LIST_" + PD->getName(),
1858 // Return null if no extension bits are used.
1859 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
1860 Values[3]->isNullValue())
1861 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
1863 llvm::Constant *Init =
1864 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
1866 // No special section, but goes in llvm.used
1867 return CreateMetadataVar("\01L_OBJC_PROTOCOLEXT_" + PD->getName(),
1873 struct objc_protocol_list {
1874 struct objc_protocol_list *next;
1880 CGObjCMac::EmitProtocolList(Twine Name,
1881 ObjCProtocolDecl::protocol_iterator begin,
1882 ObjCProtocolDecl::protocol_iterator end) {
1883 std::vector<llvm::Constant*> ProtocolRefs;
1885 for (; begin != end; ++begin)
1886 ProtocolRefs.push_back(GetProtocolRef(*begin));
1888 // Just return null for empty protocol lists
1889 if (ProtocolRefs.empty())
1890 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
1892 // This list is null terminated.
1893 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
1895 llvm::Constant *Values[3];
1896 // This field is only used by the runtime.
1897 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
1898 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy,
1899 ProtocolRefs.size() - 1);
1901 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
1902 ProtocolRefs.size()),
1905 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
1906 llvm::GlobalVariable *GV =
1907 CreateMetadataVar(Name, Init, "__OBJC,__cat_cls_meth,regular,no_dead_strip",
1909 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
1912 void CGObjCCommonMac::PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet,
1913 std::vector<llvm::Constant*> &Properties,
1914 const Decl *Container,
1915 const ObjCProtocolDecl *PROTO,
1916 const ObjCCommonTypesHelper &ObjCTypes) {
1917 std::vector<llvm::Constant*> Prop(2);
1918 for (ObjCProtocolDecl::protocol_iterator P = PROTO->protocol_begin(),
1919 E = PROTO->protocol_end(); P != E; ++P)
1920 PushProtocolProperties(PropertySet, Properties, Container, (*P), ObjCTypes);
1921 for (ObjCContainerDecl::prop_iterator I = PROTO->prop_begin(),
1922 E = PROTO->prop_end(); I != E; ++I) {
1923 const ObjCPropertyDecl *PD = *I;
1924 if (!PropertySet.insert(PD->getIdentifier()))
1926 Prop[0] = GetPropertyName(PD->getIdentifier());
1927 Prop[1] = GetPropertyTypeString(PD, Container);
1928 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop));
1933 struct _objc_property {
1934 const char * const name;
1935 const char * const attributes;
1938 struct _objc_property_list {
1939 uint32_t entsize; // sizeof (struct _objc_property)
1940 uint32_t prop_count;
1941 struct _objc_property[prop_count];
1944 llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,
1945 const Decl *Container,
1946 const ObjCContainerDecl *OCD,
1947 const ObjCCommonTypesHelper &ObjCTypes) {
1948 std::vector<llvm::Constant*> Properties, Prop(2);
1949 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
1950 for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(),
1951 E = OCD->prop_end(); I != E; ++I) {
1952 const ObjCPropertyDecl *PD = *I;
1953 PropertySet.insert(PD->getIdentifier());
1954 Prop[0] = GetPropertyName(PD->getIdentifier());
1955 Prop[1] = GetPropertyTypeString(PD, Container);
1956 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
1959 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) {
1960 for (ObjCInterfaceDecl::all_protocol_iterator
1961 P = OID->all_referenced_protocol_begin(),
1962 E = OID->all_referenced_protocol_end(); P != E; ++P)
1963 PushProtocolProperties(PropertySet, Properties, Container, (*P),
1966 else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) {
1967 for (ObjCCategoryDecl::protocol_iterator P = CD->protocol_begin(),
1968 E = CD->protocol_end(); P != E; ++P)
1969 PushProtocolProperties(PropertySet, Properties, Container, (*P),
1973 // Return null for empty list.
1974 if (Properties.empty())
1975 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
1977 unsigned PropertySize =
1978 CGM.getTargetData().getTypeAllocSize(ObjCTypes.PropertyTy);
1979 llvm::Constant *Values[3];
1980 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
1981 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
1982 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
1984 Values[2] = llvm::ConstantArray::get(AT, Properties);
1985 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
1987 llvm::GlobalVariable *GV =
1988 CreateMetadataVar(Name, Init,
1989 (ObjCABI == 2) ? "__DATA, __objc_const" :
1990 "__OBJC,__property,regular,no_dead_strip",
1991 (ObjCABI == 2) ? 8 : 4,
1993 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);
1997 struct objc_method_description_list {
1999 struct objc_method_description list[];
2003 CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
2004 std::vector<llvm::Constant*> Desc(2);
2006 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
2007 ObjCTypes.SelectorPtrTy);
2008 Desc[1] = GetMethodVarType(MD);
2012 return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
2016 llvm::Constant *CGObjCMac::EmitMethodDescList(Twine Name,
2017 const char *Section,
2018 const ConstantVector &Methods) {
2019 // Return null for empty list.
2020 if (Methods.empty())
2021 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
2023 llvm::Constant *Values[2];
2024 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
2025 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
2027 Values[1] = llvm::ConstantArray::get(AT, Methods);
2028 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2030 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
2031 return llvm::ConstantExpr::getBitCast(GV,
2032 ObjCTypes.MethodDescriptionListPtrTy);
2036 struct _objc_category {
2037 char *category_name;
2039 struct _objc_method_list *instance_methods;
2040 struct _objc_method_list *class_methods;
2041 struct _objc_protocol_list *protocols;
2042 uint32_t size; // <rdar://4585769>
2043 struct _objc_property_list *instance_properties;
2046 void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
2047 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.CategoryTy);
2049 // FIXME: This is poor design, the OCD should have a pointer to the category
2050 // decl. Additionally, note that Category can be null for the @implementation
2051 // w/o an @interface case. Sema should just create one for us as it does for
2052 // @implementation so everyone else can live life under a clear blue sky.
2053 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
2054 const ObjCCategoryDecl *Category =
2055 Interface->FindCategoryDeclaration(OCD->getIdentifier());
2057 llvm::SmallString<256> ExtName;
2058 llvm::raw_svector_ostream(ExtName) << Interface->getName() << '_'
2061 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
2062 for (ObjCCategoryImplDecl::instmeth_iterator
2063 i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
2064 // Instance methods should always be defined.
2065 InstanceMethods.push_back(GetMethodConstant(*i));
2067 for (ObjCCategoryImplDecl::classmeth_iterator
2068 i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
2069 // Class methods should always be defined.
2070 ClassMethods.push_back(GetMethodConstant(*i));
2073 llvm::Constant *Values[7];
2074 Values[0] = GetClassName(OCD->getIdentifier());
2075 Values[1] = GetClassName(Interface->getIdentifier());
2076 LazySymbols.insert(Interface->getIdentifier());
2078 EmitMethodList("\01L_OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(),
2079 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2082 EmitMethodList("\01L_OBJC_CATEGORY_CLASS_METHODS_" + ExtName.str(),
2083 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2087 EmitProtocolList("\01L_OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
2088 Category->protocol_begin(),
2089 Category->protocol_end());
2091 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2093 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
2095 // If there is no category @interface then there can be no properties.
2097 Values[6] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
2098 OCD, Category, ObjCTypes);
2100 Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
2103 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
2106 llvm::GlobalVariable *GV =
2107 CreateMetadataVar("\01L_OBJC_CATEGORY_" + ExtName.str(), Init,
2108 "__OBJC,__category,regular,no_dead_strip",
2110 DefinedCategories.push_back(GV);
2111 DefinedCategoryNames.insert(ExtName.str());
2112 // method definition entries must be clear for next implementation.
2113 MethodDefinitions.clear();
2116 // FIXME: Get from somewhere?
2118 eClassFlags_Factory = 0x00001,
2119 eClassFlags_Meta = 0x00002,
2121 eClassFlags_HasCXXStructors = 0x02000,
2122 eClassFlags_Hidden = 0x20000,
2123 eClassFlags_ABI2_Hidden = 0x00010,
2124 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634>
2128 struct _objc_class {
2135 struct _objc_ivar_list *ivars;
2136 struct _objc_method_list *methods;
2137 struct _objc_cache *cache;
2138 struct _objc_protocol_list *protocols;
2139 // Objective-C 1.0 extensions (<rdr://4585769>)
2140 const char *ivar_layout;
2141 struct _objc_class_ext *ext;
2144 See EmitClassExtension();
2146 void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
2147 DefinedSymbols.insert(ID->getIdentifier());
2149 std::string ClassName = ID->getNameAsString();
2151 ObjCInterfaceDecl *Interface =
2152 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
2153 llvm::Constant *Protocols =
2154 EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getName(),
2155 Interface->all_referenced_protocol_begin(),
2156 Interface->all_referenced_protocol_end());
2157 unsigned Flags = eClassFlags_Factory;
2158 if (ID->hasCXXStructors())
2159 Flags |= eClassFlags_HasCXXStructors;
2161 CGM.getContext().getASTObjCImplementationLayout(ID).getSize().getQuantity();
2163 // FIXME: Set CXX-structors flag.
2164 if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
2165 Flags |= eClassFlags_Hidden;
2167 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
2168 for (ObjCImplementationDecl::instmeth_iterator
2169 i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
2170 // Instance methods should always be defined.
2171 InstanceMethods.push_back(GetMethodConstant(*i));
2173 for (ObjCImplementationDecl::classmeth_iterator
2174 i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
2175 // Class methods should always be defined.
2176 ClassMethods.push_back(GetMethodConstant(*i));
2179 for (ObjCImplementationDecl::propimpl_iterator
2180 i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
2181 ObjCPropertyImplDecl *PID = *i;
2183 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
2184 ObjCPropertyDecl *PD = PID->getPropertyDecl();
2186 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
2187 if (llvm::Constant *C = GetMethodConstant(MD))
2188 InstanceMethods.push_back(C);
2189 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
2190 if (llvm::Constant *C = GetMethodConstant(MD))
2191 InstanceMethods.push_back(C);
2195 llvm::Constant *Values[12];
2196 Values[ 0] = EmitMetaClass(ID, Protocols, ClassMethods);
2197 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
2198 // Record a reference to the super class.
2199 LazySymbols.insert(Super->getIdentifier());
2202 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
2203 ObjCTypes.ClassPtrTy);
2205 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
2207 Values[ 2] = GetClassName(ID->getIdentifier());
2208 // Version is always 0.
2209 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
2210 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
2211 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
2212 Values[ 6] = EmitIvarList(ID, false);
2214 EmitMethodList("\01L_OBJC_INSTANCE_METHODS_" + ID->getName(),
2215 "__OBJC,__inst_meth,regular,no_dead_strip",
2217 // cache is always NULL.
2218 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
2219 Values[ 9] = Protocols;
2220 Values[10] = BuildIvarLayout(ID, true);
2221 Values[11] = EmitClassExtension(ID);
2222 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
2224 std::string Name("\01L_OBJC_CLASS_");
2226 const char *Section = "__OBJC,__class,regular,no_dead_strip";
2227 // Check for a forward reference.
2228 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
2230 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2231 "Forward metaclass reference has incorrect type.");
2232 GV->setLinkage(llvm::GlobalValue::InternalLinkage);
2233 GV->setInitializer(Init);
2234 GV->setSection(Section);
2235 GV->setAlignment(4);
2236 CGM.AddUsedGlobal(GV);
2239 GV = CreateMetadataVar(Name, Init, Section, 4, true);
2240 DefinedClasses.push_back(GV);
2241 // method definition entries must be clear for next implementation.
2242 MethodDefinitions.clear();
2245 llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
2246 llvm::Constant *Protocols,
2247 const ConstantVector &Methods) {
2248 unsigned Flags = eClassFlags_Meta;
2249 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassTy);
2251 if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
2252 Flags |= eClassFlags_Hidden;
2254 llvm::Constant *Values[12];
2255 // The isa for the metaclass is the root of the hierarchy.
2256 const ObjCInterfaceDecl *Root = ID->getClassInterface();
2257 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
2260 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
2261 ObjCTypes.ClassPtrTy);
2262 // The super class for the metaclass is emitted as the name of the
2263 // super class. The runtime fixes this up to point to the
2264 // *metaclass* for the super class.
2265 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
2267 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
2268 ObjCTypes.ClassPtrTy);
2270 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
2272 Values[ 2] = GetClassName(ID->getIdentifier());
2273 // Version is always 0.
2274 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
2275 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
2276 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
2277 Values[ 6] = EmitIvarList(ID, true);
2279 EmitMethodList("\01L_OBJC_CLASS_METHODS_" + ID->getNameAsString(),
2280 "__OBJC,__cls_meth,regular,no_dead_strip",
2282 // cache is always NULL.
2283 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
2284 Values[ 9] = Protocols;
2285 // ivar_layout for metaclass is always NULL.
2286 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
2287 // The class extension is always unused for metaclasses.
2288 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
2289 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
2292 std::string Name("\01L_OBJC_METACLASS_");
2293 Name += ID->getNameAsCString();
2295 // Check for a forward reference.
2296 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
2298 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2299 "Forward metaclass reference has incorrect type.");
2300 GV->setLinkage(llvm::GlobalValue::InternalLinkage);
2301 GV->setInitializer(Init);
2303 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
2304 llvm::GlobalValue::InternalLinkage,
2307 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
2308 GV->setAlignment(4);
2309 CGM.AddUsedGlobal(GV);
2314 llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
2315 std::string Name = "\01L_OBJC_METACLASS_" + ID->getNameAsString();
2317 // FIXME: Should we look these up somewhere other than the module. Its a bit
2318 // silly since we only generate these while processing an implementation, so
2319 // exactly one pointer would work if know when we entered/exitted an
2320 // implementation block.
2322 // Check for an existing forward reference.
2323 // Previously, metaclass with internal linkage may have been defined.
2324 // pass 'true' as 2nd argument so it is returned.
2325 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name,
2327 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2328 "Forward metaclass reference has incorrect type.");
2331 // Generate as an external reference to keep a consistent
2332 // module. This will be patched up when we emit the metaclass.
2333 return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
2334 llvm::GlobalValue::ExternalLinkage,
2340 llvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) {
2341 std::string Name = "\01L_OBJC_CLASS_" + ID->getNameAsString();
2343 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name,
2345 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2346 "Forward class metadata reference has incorrect type.");
2349 return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
2350 llvm::GlobalValue::ExternalLinkage,
2357 struct objc_class_ext {
2359 const char *weak_ivar_layout;
2360 struct _objc_property_list *properties;
2364 CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
2366 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
2368 llvm::Constant *Values[3];
2369 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
2370 Values[1] = BuildIvarLayout(ID, false);
2371 Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
2372 ID, ID->getClassInterface(), ObjCTypes);
2374 // Return null if no extension bits are used.
2375 if (Values[1]->isNullValue() && Values[2]->isNullValue())
2376 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
2378 llvm::Constant *Init =
2379 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
2380 return CreateMetadataVar("\01L_OBJC_CLASSEXT_" + ID->getName(),
2381 Init, "__OBJC,__class_ext,regular,no_dead_strip",
2392 struct objc_ivar_list {
2394 struct objc_ivar list[count];
2397 llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
2399 std::vector<llvm::Constant*> Ivars, Ivar(3);
2401 // When emitting the root class GCC emits ivar entries for the
2402 // actual class structure. It is not clear if we need to follow this
2403 // behavior; for now lets try and get away with not doing it. If so,
2404 // the cleanest solution would be to make up an ObjCInterfaceDecl
2407 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
2409 const ObjCInterfaceDecl *OID = ID->getClassInterface();
2411 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
2412 IVD; IVD = IVD->getNextIvar()) {
2413 // Ignore unnamed bit-fields.
2414 if (!IVD->getDeclName())
2416 Ivar[0] = GetMethodVarName(IVD->getIdentifier());
2417 Ivar[1] = GetMethodVarType(IVD);
2418 Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy,
2419 ComputeIvarBaseOffset(CGM, OID, IVD));
2420 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar));
2423 // Return null for empty list.
2425 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
2427 llvm::Constant *Values[2];
2428 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
2429 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
2431 Values[1] = llvm::ConstantArray::get(AT, Ivars);
2432 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2434 llvm::GlobalVariable *GV;
2436 GV = CreateMetadataVar("\01L_OBJC_CLASS_VARIABLES_" + ID->getName(),
2437 Init, "__OBJC,__class_vars,regular,no_dead_strip",
2440 GV = CreateMetadataVar("\01L_OBJC_INSTANCE_VARIABLES_" + ID->getName(),
2441 Init, "__OBJC,__instance_vars,regular,no_dead_strip",
2443 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
2447 struct objc_method {
2453 struct objc_method_list {
2454 struct objc_method_list *obsolete;
2456 struct objc_method methods_list[count];
2460 /// GetMethodConstant - Return a struct objc_method constant for the
2461 /// given method if it has been defined. The result is null if the
2462 /// method has not been defined. The return value has type MethodPtrTy.
2463 llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) {
2464 llvm::Function *Fn = GetMethodDefinition(MD);
2468 std::vector<llvm::Constant*> Method(3);
2470 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
2471 ObjCTypes.SelectorPtrTy);
2472 Method[1] = GetMethodVarType(MD);
2473 Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy);
2474 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
2477 llvm::Constant *CGObjCMac::EmitMethodList(Twine Name,
2478 const char *Section,
2479 const ConstantVector &Methods) {
2480 // Return null for empty list.
2481 if (Methods.empty())
2482 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
2484 llvm::Constant *Values[3];
2485 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
2486 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
2487 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
2489 Values[2] = llvm::ConstantArray::get(AT, Methods);
2490 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2492 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
2493 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy);
2496 llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,
2497 const ObjCContainerDecl *CD) {
2498 llvm::SmallString<256> Name;
2499 GetNameForMethod(OMD, CD, Name);
2501 CodeGenTypes &Types = CGM.getTypes();
2502 llvm::FunctionType *MethodTy =
2503 Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic());
2504 llvm::Function *Method =
2505 llvm::Function::Create(MethodTy,
2506 llvm::GlobalValue::InternalLinkage,
2509 MethodDefinitions.insert(std::make_pair(OMD, Method));
2514 llvm::GlobalVariable *
2515 CGObjCCommonMac::CreateMetadataVar(Twine Name,
2516 llvm::Constant *Init,
2517 const char *Section,
2520 llvm::Type *Ty = Init->getType();
2521 llvm::GlobalVariable *GV =
2522 new llvm::GlobalVariable(CGM.getModule(), Ty, false,
2523 llvm::GlobalValue::InternalLinkage, Init, Name);
2525 GV->setSection(Section);
2527 GV->setAlignment(Align);
2529 CGM.AddUsedGlobal(GV);
2533 llvm::Function *CGObjCMac::ModuleInitFunction() {
2534 // Abuse this interface function as a place to finalize.
2539 llvm::Constant *CGObjCMac::GetPropertyGetFunction() {
2540 return ObjCTypes.getGetPropertyFn();
2543 llvm::Constant *CGObjCMac::GetPropertySetFunction() {
2544 return ObjCTypes.getSetPropertyFn();
2547 llvm::Constant *CGObjCMac::GetGetStructFunction() {
2548 return ObjCTypes.getCopyStructFn();
2550 llvm::Constant *CGObjCMac::GetSetStructFunction() {
2551 return ObjCTypes.getCopyStructFn();
2554 llvm::Constant *CGObjCMac::EnumerationMutationFunction() {
2555 return ObjCTypes.getEnumerationMutationFn();
2558 void CGObjCMac::EmitTryStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S) {
2559 return EmitTryOrSynchronizedStmt(CGF, S);
2562 void CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF,
2563 const ObjCAtSynchronizedStmt &S) {
2564 return EmitTryOrSynchronizedStmt(CGF, S);
2568 struct PerformFragileFinally : EHScopeStack::Cleanup {
2570 llvm::Value *SyncArgSlot;
2571 llvm::Value *CallTryExitVar;
2572 llvm::Value *ExceptionData;
2573 ObjCTypesHelper &ObjCTypes;
2574 PerformFragileFinally(const Stmt *S,
2575 llvm::Value *SyncArgSlot,
2576 llvm::Value *CallTryExitVar,
2577 llvm::Value *ExceptionData,
2578 ObjCTypesHelper *ObjCTypes)
2579 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
2580 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
2582 void Emit(CodeGenFunction &CGF, Flags flags) {
2583 // Check whether we need to call objc_exception_try_exit.
2584 // In optimized code, this branch will always be folded.
2585 llvm::BasicBlock *FinallyCallExit =
2586 CGF.createBasicBlock("finally.call_exit");
2587 llvm::BasicBlock *FinallyNoCallExit =
2588 CGF.createBasicBlock("finally.no_call_exit");
2589 CGF.Builder.CreateCondBr(CGF.Builder.CreateLoad(CallTryExitVar),
2590 FinallyCallExit, FinallyNoCallExit);
2592 CGF.EmitBlock(FinallyCallExit);
2593 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryExitFn(), ExceptionData)
2594 ->setDoesNotThrow();
2596 CGF.EmitBlock(FinallyNoCallExit);
2598 if (isa<ObjCAtTryStmt>(S)) {
2599 if (const ObjCAtFinallyStmt* FinallyStmt =
2600 cast<ObjCAtTryStmt>(S).getFinallyStmt()) {
2601 // Save the current cleanup destination in case there's
2602 // control flow inside the finally statement.
2603 llvm::Value *CurCleanupDest =
2604 CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot());
2606 CGF.EmitStmt(FinallyStmt->getFinallyBody());
2608 if (CGF.HaveInsertPoint()) {
2609 CGF.Builder.CreateStore(CurCleanupDest,
2610 CGF.getNormalCleanupDestSlot());
2612 // Currently, the end of the cleanup must always exist.
2613 CGF.EnsureInsertPoint();
2617 // Emit objc_sync_exit(expr); as finally's sole statement for
2619 llvm::Value *SyncArg = CGF.Builder.CreateLoad(SyncArgSlot);
2620 CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg)
2621 ->setDoesNotThrow();
2626 class FragileHazards {
2627 CodeGenFunction &CGF;
2628 SmallVector<llvm::Value*, 20> Locals;
2629 llvm::DenseSet<llvm::BasicBlock*> BlocksBeforeTry;
2631 llvm::InlineAsm *ReadHazard;
2632 llvm::InlineAsm *WriteHazard;
2634 llvm::FunctionType *GetAsmFnType();
2636 void collectLocals();
2637 void emitReadHazard(CGBuilderTy &Builder);
2640 FragileHazards(CodeGenFunction &CGF);
2642 void emitWriteHazard();
2643 void emitHazardsInNewBlocks();
2647 /// Create the fragile-ABI read and write hazards based on the current
2648 /// state of the function, which is presumed to be immediately prior
2649 /// to a @try block. These hazards are used to maintain correct
2650 /// semantics in the face of optimization and the fragile ABI's
2651 /// cavalier use of setjmp/longjmp.
2652 FragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) {
2655 if (Locals.empty()) return;
2657 // Collect all the blocks in the function.
2658 for (llvm::Function::iterator
2659 I = CGF.CurFn->begin(), E = CGF.CurFn->end(); I != E; ++I)
2660 BlocksBeforeTry.insert(&*I);
2662 llvm::FunctionType *AsmFnTy = GetAsmFnType();
2664 // Create a read hazard for the allocas. This inhibits dead-store
2665 // optimizations and forces the values to memory. This hazard is
2666 // inserted before any 'throwing' calls in the protected scope to
2667 // reflect the possibility that the variables might be read from the
2668 // catch block if the call throws.
2670 std::string Constraint;
2671 for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
2672 if (I) Constraint += ',';
2676 ReadHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
2679 // Create a write hazard for the allocas. This inhibits folding
2680 // loads across the hazard. This hazard is inserted at the
2681 // beginning of the catch path to reflect the possibility that the
2682 // variables might have been written within the protected scope.
2684 std::string Constraint;
2685 for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
2686 if (I) Constraint += ',';
2687 Constraint += "=*m";
2690 WriteHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
2694 /// Emit a write hazard at the current location.
2695 void FragileHazards::emitWriteHazard() {
2696 if (Locals.empty()) return;
2698 CGF.Builder.CreateCall(WriteHazard, Locals)->setDoesNotThrow();
2701 void FragileHazards::emitReadHazard(CGBuilderTy &Builder) {
2702 assert(!Locals.empty());
2703 Builder.CreateCall(ReadHazard, Locals)->setDoesNotThrow();
2706 /// Emit read hazards in all the protected blocks, i.e. all the blocks
2707 /// which have been inserted since the beginning of the try.
2708 void FragileHazards::emitHazardsInNewBlocks() {
2709 if (Locals.empty()) return;
2711 CGBuilderTy Builder(CGF.getLLVMContext());
2713 // Iterate through all blocks, skipping those prior to the try.
2714 for (llvm::Function::iterator
2715 FI = CGF.CurFn->begin(), FE = CGF.CurFn->end(); FI != FE; ++FI) {
2716 llvm::BasicBlock &BB = *FI;
2717 if (BlocksBeforeTry.count(&BB)) continue;
2719 // Walk through all the calls in the block.
2720 for (llvm::BasicBlock::iterator
2721 BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
2722 llvm::Instruction &I = *BI;
2724 // Ignore instructions that aren't non-intrinsic calls.
2725 // These are the only calls that can possibly call longjmp.
2726 if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I)) continue;
2727 if (isa<llvm::IntrinsicInst>(I))
2730 // Ignore call sites marked nounwind. This may be questionable,
2731 // since 'nounwind' doesn't necessarily mean 'does not call longjmp'.
2732 llvm::CallSite CS(&I);
2733 if (CS.doesNotThrow()) continue;
2735 // Insert a read hazard before the call. This will ensure that
2736 // any writes to the locals are performed before making the
2737 // call. If the call throws, then this is sufficient to
2738 // guarantee correctness as long as it doesn't also write to any
2740 Builder.SetInsertPoint(&BB, BI);
2741 emitReadHazard(Builder);
2746 static void addIfPresent(llvm::DenseSet<llvm::Value*> &S, llvm::Value *V) {
2750 void FragileHazards::collectLocals() {
2751 // Compute a set of allocas to ignore.
2752 llvm::DenseSet<llvm::Value*> AllocasToIgnore;
2753 addIfPresent(AllocasToIgnore, CGF.ReturnValue);
2754 addIfPresent(AllocasToIgnore, CGF.NormalCleanupDest);
2756 // Collect all the allocas currently in the function. This is
2757 // probably way too aggressive.
2758 llvm::BasicBlock &Entry = CGF.CurFn->getEntryBlock();
2759 for (llvm::BasicBlock::iterator
2760 I = Entry.begin(), E = Entry.end(); I != E; ++I)
2761 if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
2762 Locals.push_back(&*I);
2765 llvm::FunctionType *FragileHazards::GetAsmFnType() {
2766 SmallVector<llvm::Type *, 16> tys(Locals.size());
2767 for (unsigned i = 0, e = Locals.size(); i != e; ++i)
2768 tys[i] = Locals[i]->getType();
2769 return llvm::FunctionType::get(CGF.VoidTy, tys, false);
2774 Objective-C setjmp-longjmp (sjlj) Exception Handling
2777 A catch buffer is a setjmp buffer plus:
2778 - a pointer to the exception that was caught
2779 - a pointer to the previous exception data buffer
2780 - two pointers of reserved storage
2781 Therefore catch buffers form a stack, with a pointer to the top
2782 of the stack kept in thread-local storage.
2784 objc_exception_try_enter pushes a catch buffer onto the EH stack.
2785 objc_exception_try_exit pops the given catch buffer, which is
2786 required to be the top of the EH stack.
2787 objc_exception_throw pops the top of the EH stack, writes the
2788 thrown exception into the appropriate field, and longjmps
2789 to the setjmp buffer. It crashes the process (with a printf
2790 and an abort()) if there are no catch buffers on the stack.
2791 objc_exception_extract just reads the exception pointer out of the
2794 There's no reason an implementation couldn't use a light-weight
2795 setjmp here --- something like __builtin_setjmp, but API-compatible
2796 with the heavyweight setjmp. This will be more important if we ever
2797 want to implement correct ObjC/C++ exception interactions for the
2800 Note that for this use of setjmp/longjmp to be correct, we may need
2801 to mark some local variables volatile: if a non-volatile local
2802 variable is modified between the setjmp and the longjmp, it has
2803 indeterminate value. For the purposes of LLVM IR, it may be
2804 sufficient to make loads and stores within the @try (to variables
2805 declared outside the @try) volatile. This is necessary for
2806 optimized correctness, but is not currently being done; this is
2807 being tracked as rdar://problem/8160285
2809 The basic framework for a @try-catch-finally is as follows:
2811 objc_exception_data d;
2813 bool _call_try_exit = true;
2815 objc_exception_try_enter(&d);
2816 if (!setjmp(d.jmp_buf)) {
2820 id _caught = objc_exception_extract(&d);
2822 // enter new try scope for handlers
2823 if (!setjmp(d.jmp_buf)) {
2824 ... match exception and execute catch blocks ...
2826 // fell off end, rethrow.
2828 ... jump-through-finally to finally_rethrow ...
2830 // exception in catch block
2831 _rethrow = objc_exception_extract(&d);
2832 _call_try_exit = false;
2833 ... jump-through-finally to finally_rethrow ...
2836 ... jump-through-finally to finally_end ...
2840 objc_exception_try_exit(&d);
2842 ... finally block ....
2843 ... dispatch to finally destination ...
2846 objc_exception_throw(_rethrow);
2851 This framework differs slightly from the one gcc uses, in that gcc
2852 uses _rethrow to determine if objc_exception_try_exit should be called
2853 and if the object should be rethrown. This breaks in the face of
2854 throwing nil and introduces unnecessary branches.
2856 We specialize this framework for a few particular circumstances:
2858 - If there are no catch blocks, then we avoid emitting the second
2859 exception handling context.
2861 - If there is a catch-all catch block (i.e. @catch(...) or @catch(id
2862 e)) we avoid emitting the code to rethrow an uncaught exception.
2864 - FIXME: If there is no @finally block we can do a few more
2867 Rethrows and Jumps-Through-Finally
2870 '@throw;' is supported by pushing the currently-caught exception
2871 onto ObjCEHStack while the @catch blocks are emitted.
2873 Branches through the @finally block are handled with an ordinary
2874 normal cleanup. We do not register an EH cleanup; fragile-ABI ObjC
2875 exceptions are not compatible with C++ exceptions, and this is
2876 hardly the only place where this will go wrong.
2878 @synchronized(expr) { stmt; } is emitted as if it were:
2879 id synch_value = expr;
2880 objc_sync_enter(synch_value);
2881 @try { stmt; } @finally { objc_sync_exit(synch_value); }
2884 void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
2886 bool isTry = isa<ObjCAtTryStmt>(S);
2888 // A destination for the fall-through edges of the catch handlers to
2890 CodeGenFunction::JumpDest FinallyEnd =
2891 CGF.getJumpDestInCurrentScope("finally.end");
2893 // A destination for the rethrow edge of the catch handlers to jump
2895 CodeGenFunction::JumpDest FinallyRethrow =
2896 CGF.getJumpDestInCurrentScope("finally.rethrow");
2898 // For @synchronized, call objc_sync_enter(sync.expr). The
2899 // evaluation of the expression must occur before we enter the
2900 // @synchronized. We can't avoid a temp here because we need the
2901 // value to be preserved. If the backend ever does liveness
2902 // correctly after setjmp, this will be unnecessary.
2903 llvm::Value *SyncArgSlot = 0;
2905 llvm::Value *SyncArg =
2906 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
2907 SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
2908 CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg)
2909 ->setDoesNotThrow();
2911 SyncArgSlot = CGF.CreateTempAlloca(SyncArg->getType(), "sync.arg");
2912 CGF.Builder.CreateStore(SyncArg, SyncArgSlot);
2915 // Allocate memory for the setjmp buffer. This needs to be kept
2916 // live throughout the try and catch blocks.
2917 llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy,
2918 "exceptiondata.ptr");
2920 // Create the fragile hazards. Note that this will not capture any
2921 // of the allocas required for exception processing, but will
2922 // capture the current basic block (which extends all the way to the
2923 // setjmp call) as "before the @try".
2924 FragileHazards Hazards(CGF);
2926 // Create a flag indicating whether the cleanup needs to call
2927 // objc_exception_try_exit. This is true except when
2928 // - no catches match and we're branching through the cleanup
2929 // just to rethrow the exception, or
2930 // - a catch matched and we're falling out of the catch handler.
2931 // The setjmp-safety rule here is that we should always store to this
2932 // variable in a place that dominates the branch through the cleanup
2933 // without passing through any setjmps.
2934 llvm::Value *CallTryExitVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(),
2937 // A slot containing the exception to rethrow. Only needed when we
2938 // have both a @catch and a @finally.
2939 llvm::Value *PropagatingExnVar = 0;
2941 // Push a normal cleanup to leave the try scope.
2942 CGF.EHStack.pushCleanup<PerformFragileFinally>(NormalCleanup, &S,
2948 // Enter a try block:
2949 // - Call objc_exception_try_enter to push ExceptionData on top of
2951 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData)
2952 ->setDoesNotThrow();
2954 // - Call setjmp on the exception data buffer.
2955 llvm::Constant *Zero = llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0);
2956 llvm::Value *GEPIndexes[] = { Zero, Zero, Zero };
2957 llvm::Value *SetJmpBuffer =
2958 CGF.Builder.CreateGEP(ExceptionData, GEPIndexes, "setjmp_buffer");
2959 llvm::CallInst *SetJmpResult =
2960 CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result");
2961 SetJmpResult->setDoesNotThrow();
2963 // If setjmp returned 0, enter the protected block; otherwise,
2964 // branch to the handler.
2965 llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
2966 llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
2967 llvm::Value *DidCatch =
2968 CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
2969 CGF.Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
2971 // Emit the protected block.
2972 CGF.EmitBlock(TryBlock);
2973 CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
2974 CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
2975 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
2977 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.Builder.saveAndClearIP();
2979 // Emit the exception handler block.
2980 CGF.EmitBlock(TryHandler);
2982 // Don't optimize loads of the in-scope locals across this point.
2983 Hazards.emitWriteHazard();
2985 // For a @synchronized (or a @try with no catches), just branch
2986 // through the cleanup to the rethrow block.
2987 if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
2988 // Tell the cleanup not to re-pop the exit.
2989 CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
2990 CGF.EmitBranchThroughCleanup(FinallyRethrow);
2992 // Otherwise, we have to match against the caught exceptions.
2994 // Retrieve the exception object. We may emit multiple blocks but
2995 // nothing can cross this so the value is already in SSA form.
2996 llvm::CallInst *Caught =
2997 CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
2998 ExceptionData, "caught");
2999 Caught->setDoesNotThrow();
3001 // Push the exception to rethrow onto the EH value stack for the
3002 // benefit of any @throws in the handlers.
3003 CGF.ObjCEHValueStack.push_back(Caught);
3005 const ObjCAtTryStmt* AtTryStmt = cast<ObjCAtTryStmt>(&S);
3007 bool HasFinally = (AtTryStmt->getFinallyStmt() != 0);
3009 llvm::BasicBlock *CatchBlock = 0;
3010 llvm::BasicBlock *CatchHandler = 0;
3012 // Save the currently-propagating exception before
3013 // objc_exception_try_enter clears the exception slot.
3014 PropagatingExnVar = CGF.CreateTempAlloca(Caught->getType(),
3015 "propagating_exception");
3016 CGF.Builder.CreateStore(Caught, PropagatingExnVar);
3018 // Enter a new exception try block (in case a @catch block
3019 // throws an exception).
3020 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData)
3021 ->setDoesNotThrow();
3023 llvm::CallInst *SetJmpResult =
3024 CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer,
3026 SetJmpResult->setDoesNotThrow();
3028 llvm::Value *Threw =
3029 CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
3031 CatchBlock = CGF.createBasicBlock("catch");
3032 CatchHandler = CGF.createBasicBlock("catch_for_catch");
3033 CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
3035 CGF.EmitBlock(CatchBlock);
3038 CGF.Builder.CreateStore(CGF.Builder.getInt1(HasFinally), CallTryExitVar);
3040 // Handle catch list. As a special case we check if everything is
3041 // matched and avoid generating code for falling off the end if
3043 bool AllMatched = false;
3044 for (unsigned I = 0, N = AtTryStmt->getNumCatchStmts(); I != N; ++I) {
3045 const ObjCAtCatchStmt *CatchStmt = AtTryStmt->getCatchStmt(I);
3047 const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
3048 const ObjCObjectPointerType *OPT = 0;
3050 // catch(...) always matches.
3054 OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>();
3056 // catch(id e) always matches under this ABI, since only
3057 // ObjC exceptions end up here in the first place.
3058 // FIXME: For the time being we also match id<X>; this should
3059 // be rejected by Sema instead.
3060 if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()))
3064 // If this is a catch-all, we don't need to test anything.
3066 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
3069 CGF.EmitAutoVarDecl(*CatchParam);
3070 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
3072 // These types work out because ConvertType(id) == i8*.
3073 CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(CatchParam));
3076 CGF.EmitStmt(CatchStmt->getCatchBody());
3078 // The scope of the catch variable ends right here.
3079 CatchVarCleanups.ForceCleanup();
3081 CGF.EmitBranchThroughCleanup(FinallyEnd);
3085 assert(OPT && "Unexpected non-object pointer type in @catch");
3086 const ObjCObjectType *ObjTy = OPT->getObjectType();
3088 // FIXME: @catch (Class c) ?
3089 ObjCInterfaceDecl *IDecl = ObjTy->getInterface();
3090 assert(IDecl && "Catch parameter must have Objective-C type!");
3092 // Check if the @catch block matches the exception object.
3093 llvm::Value *Class = EmitClassRef(CGF.Builder, IDecl);
3095 llvm::CallInst *Match =
3096 CGF.Builder.CreateCall2(ObjCTypes.getExceptionMatchFn(),
3097 Class, Caught, "match");
3098 Match->setDoesNotThrow();
3100 llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("match");
3101 llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch.next");
3103 CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"),
3104 MatchedBlock, NextCatchBlock);
3106 // Emit the @catch block.
3107 CGF.EmitBlock(MatchedBlock);
3109 // Collect any cleanups for the catch variable. The scope lasts until
3110 // the end of the catch body.
3111 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
3113 CGF.EmitAutoVarDecl(*CatchParam);
3114 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
3116 // Initialize the catch variable.
3118 CGF.Builder.CreateBitCast(Caught,
3119 CGF.ConvertType(CatchParam->getType()));
3120 CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(CatchParam));
3122 CGF.EmitStmt(CatchStmt->getCatchBody());
3124 // We're done with the catch variable.
3125 CatchVarCleanups.ForceCleanup();
3127 CGF.EmitBranchThroughCleanup(FinallyEnd);
3129 CGF.EmitBlock(NextCatchBlock);
3132 CGF.ObjCEHValueStack.pop_back();
3134 // If nothing wanted anything to do with the caught exception,
3135 // kill the extract call.
3136 if (Caught->use_empty())
3137 Caught->eraseFromParent();
3140 CGF.EmitBranchThroughCleanup(FinallyRethrow);
3143 // Emit the exception handler for the @catch blocks.
3144 CGF.EmitBlock(CatchHandler);
3146 // In theory we might now need a write hazard, but actually it's
3147 // unnecessary because there's no local-accessing code between
3148 // the try's write hazard and here.
3149 //Hazards.emitWriteHazard();
3151 // Extract the new exception and save it to the
3152 // propagating-exception slot.
3153 assert(PropagatingExnVar);
3154 llvm::CallInst *NewCaught =
3155 CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
3156 ExceptionData, "caught");
3157 NewCaught->setDoesNotThrow();
3158 CGF.Builder.CreateStore(NewCaught, PropagatingExnVar);
3160 // Don't pop the catch handler; the throw already did.
3161 CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
3162 CGF.EmitBranchThroughCleanup(FinallyRethrow);
3166 // Insert read hazards as required in the new blocks.
3167 Hazards.emitHazardsInNewBlocks();
3170 CGF.Builder.restoreIP(TryFallthroughIP);
3171 if (CGF.HaveInsertPoint())
3172 CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
3173 CGF.PopCleanupBlock();
3174 CGF.EmitBlock(FinallyEnd.getBlock(), true);
3176 // Emit the rethrow block.
3177 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
3178 CGF.EmitBlock(FinallyRethrow.getBlock(), true);
3179 if (CGF.HaveInsertPoint()) {
3180 // If we have a propagating-exception variable, check it.
3181 llvm::Value *PropagatingExn;
3182 if (PropagatingExnVar) {
3183 PropagatingExn = CGF.Builder.CreateLoad(PropagatingExnVar);
3185 // Otherwise, just look in the buffer for the exception to throw.
3187 llvm::CallInst *Caught =
3188 CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
3190 Caught->setDoesNotThrow();
3191 PropagatingExn = Caught;
3194 CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), PropagatingExn)
3195 ->setDoesNotThrow();
3196 CGF.Builder.CreateUnreachable();
3199 CGF.Builder.restoreIP(SavedIP);
3202 void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
3203 const ObjCAtThrowStmt &S) {
3204 llvm::Value *ExceptionAsObject;
3206 if (const Expr *ThrowExpr = S.getThrowExpr()) {
3207 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
3209 CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
3211 assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
3212 "Unexpected rethrow outside @catch block.");
3213 ExceptionAsObject = CGF.ObjCEHValueStack.back();
3216 CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
3217 ->setDoesNotReturn();
3218 CGF.Builder.CreateUnreachable();
3220 // Clear the insertion point to indicate we are in unreachable code.
3221 CGF.Builder.ClearInsertionPoint();
3224 /// EmitObjCWeakRead - Code gen for loading value of a __weak
3225 /// object: objc_read_weak (id *src)
3227 llvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
3228 llvm::Value *AddrWeakObj) {
3229 llvm::Type* DestTy =
3230 cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
3231 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj,
3232 ObjCTypes.PtrObjectPtrTy);
3233 llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(),
3234 AddrWeakObj, "weakread");
3235 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
3239 /// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
3240 /// objc_assign_weak (id src, id *dst)
3242 void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
3243 llvm::Value *src, llvm::Value *dst) {
3244 llvm::Type * SrcTy = src->getType();
3245 if (!isa<llvm::PointerType>(SrcTy)) {
3246 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
3247 assert(Size <= 8 && "does not support size > 8");
3248 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
3249 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
3250 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
3252 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
3253 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
3254 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(),
3255 src, dst, "weakassign");
3259 /// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
3260 /// objc_assign_global (id src, id *dst)
3262 void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
3263 llvm::Value *src, llvm::Value *dst,
3265 llvm::Type * SrcTy = src->getType();
3266 if (!isa<llvm::PointerType>(SrcTy)) {
3267 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
3268 assert(Size <= 8 && "does not support size > 8");
3269 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
3270 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
3271 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
3273 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
3274 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
3276 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(),
3277 src, dst, "globalassign");
3279 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(),
3280 src, dst, "threadlocalassign");
3284 /// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
3285 /// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset)
3287 void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
3288 llvm::Value *src, llvm::Value *dst,
3289 llvm::Value *ivarOffset) {
3290 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL");
3291 llvm::Type * SrcTy = src->getType();
3292 if (!isa<llvm::PointerType>(SrcTy)) {
3293 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
3294 assert(Size <= 8 && "does not support size > 8");
3295 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
3296 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
3297 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
3299 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
3300 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
3301 CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(),
3302 src, dst, ivarOffset);
3306 /// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
3307 /// objc_assign_strongCast (id src, id *dst)
3309 void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
3310 llvm::Value *src, llvm::Value *dst) {
3311 llvm::Type * SrcTy = src->getType();
3312 if (!isa<llvm::PointerType>(SrcTy)) {
3313 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
3314 assert(Size <= 8 && "does not support size > 8");
3315 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
3316 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
3317 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
3319 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
3320 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
3321 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(),
3322 src, dst, "weakassign");
3326 void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
3327 llvm::Value *DestPtr,
3328 llvm::Value *SrcPtr,
3329 llvm::Value *size) {
3330 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
3331 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
3332 CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(),
3333 DestPtr, SrcPtr, size);
3337 /// EmitObjCValueForIvar - Code Gen for ivar reference.
3339 LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
3341 llvm::Value *BaseValue,
3342 const ObjCIvarDecl *Ivar,
3343 unsigned CVRQualifiers) {
3344 const ObjCInterfaceDecl *ID =
3345 ObjectTy->getAs<ObjCObjectType>()->getInterface();
3346 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
3347 EmitIvarOffset(CGF, ID, Ivar));
3350 llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
3351 const ObjCInterfaceDecl *Interface,
3352 const ObjCIvarDecl *Ivar) {
3353 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
3354 return llvm::ConstantInt::get(
3355 CGM.getTypes().ConvertType(CGM.getContext().LongTy),
3359 /* *** Private Interface *** */
3361 /// EmitImageInfo - Emit the image info marker used to encode some module
3362 /// level information.
3364 /// See: <rdr://4810609&4810587&4810587>
3365 /// struct IMAGE_INFO {
3366 /// unsigned version;
3369 enum ImageInfoFlags {
3370 eImageInfo_FixAndContinue = (1 << 0),
3371 eImageInfo_GarbageCollected = (1 << 1),
3372 eImageInfo_GCOnly = (1 << 2),
3373 eImageInfo_OptimizedByDyld = (1 << 3), // FIXME: When is this set.
3375 // A flag indicating that the module has no instances of a @synthesize of a
3376 // superclass variable. <rdar://problem/6803242>
3377 eImageInfo_CorrectedSynthesize = (1 << 4)
3380 void CGObjCCommonMac::EmitImageInfo() {
3381 unsigned version = 0; // Version is unused?
3384 // FIXME: Fix and continue?
3385 if (CGM.getLangOptions().getGC() != LangOptions::NonGC)
3386 flags |= eImageInfo_GarbageCollected;
3387 if (CGM.getLangOptions().getGC() == LangOptions::GCOnly)
3388 flags |= eImageInfo_GCOnly;
3390 // We never allow @synthesize of a superclass property.
3391 flags |= eImageInfo_CorrectedSynthesize;
3393 llvm::Type *Int32Ty = llvm::Type::getInt32Ty(VMContext);
3395 // Emitted as int[2];
3396 llvm::Constant *values[2] = {
3397 llvm::ConstantInt::get(Int32Ty, version),
3398 llvm::ConstantInt::get(Int32Ty, flags)
3400 llvm::ArrayType *AT = llvm::ArrayType::get(Int32Ty, 2);
3402 const char *Section;
3404 Section = "__OBJC, __image_info,regular";
3406 Section = "__DATA, __objc_imageinfo, regular, no_dead_strip";
3407 llvm::GlobalVariable *GV =
3408 CreateMetadataVar("\01L_OBJC_IMAGE_INFO",
3409 llvm::ConstantArray::get(AT, values),
3413 GV->setConstant(true);
3417 // struct objc_module {
3418 // unsigned long version;
3419 // unsigned long size;
3420 // const char *name;
3424 // FIXME: Get from somewhere
3425 static const int ModuleVersion = 7;
3427 void CGObjCMac::EmitModuleInfo() {
3428 uint64_t Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ModuleTy);
3430 std::vector<llvm::Constant*> Values(4);
3431 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
3432 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
3433 // This used to be the filename, now it is unused. <rdr://4327263>
3434 Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
3435 Values[3] = EmitModuleSymbols();
3436 CreateMetadataVar("\01L_OBJC_MODULES",
3437 llvm::ConstantStruct::get(ObjCTypes.ModuleTy, Values),
3438 "__OBJC,__module_info,regular,no_dead_strip",
3442 llvm::Constant *CGObjCMac::EmitModuleSymbols() {
3443 unsigned NumClasses = DefinedClasses.size();
3444 unsigned NumCategories = DefinedCategories.size();
3446 // Return null if no symbols were defined.
3447 if (!NumClasses && !NumCategories)
3448 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
3450 llvm::Constant *Values[5];
3451 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
3452 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
3453 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
3454 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
3456 // The runtime expects exactly the list of defined classes followed
3457 // by the list of defined categories, in a single array.
3458 std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories);
3459 for (unsigned i=0; i<NumClasses; i++)
3460 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
3461 ObjCTypes.Int8PtrTy);
3462 for (unsigned i=0; i<NumCategories; i++)
3463 Symbols[NumClasses + i] =
3464 llvm::ConstantExpr::getBitCast(DefinedCategories[i],
3465 ObjCTypes.Int8PtrTy);
3468 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
3469 NumClasses + NumCategories),
3472 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
3474 llvm::GlobalVariable *GV =
3475 CreateMetadataVar("\01L_OBJC_SYMBOLS", Init,
3476 "__OBJC,__symbols,regular,no_dead_strip",
3478 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
3481 llvm::Value *CGObjCMac::EmitClassRefFromId(CGBuilderTy &Builder,
3482 IdentifierInfo *II) {
3483 LazySymbols.insert(II);
3485 llvm::GlobalVariable *&Entry = ClassReferences[II];
3488 llvm::Constant *Casted =
3489 llvm::ConstantExpr::getBitCast(GetClassName(II),
3490 ObjCTypes.ClassPtrTy);
3492 CreateMetadataVar("\01L_OBJC_CLASS_REFERENCES_", Casted,
3493 "__OBJC,__cls_refs,literal_pointers,no_dead_strip",
3497 return Builder.CreateLoad(Entry);
3500 llvm::Value *CGObjCMac::EmitClassRef(CGBuilderTy &Builder,
3501 const ObjCInterfaceDecl *ID) {
3502 return EmitClassRefFromId(Builder, ID->getIdentifier());
3505 llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder) {
3506 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
3507 return EmitClassRefFromId(Builder, II);
3510 llvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel,
3512 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
3515 llvm::Constant *Casted =
3516 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
3517 ObjCTypes.SelectorPtrTy);
3519 CreateMetadataVar("\01L_OBJC_SELECTOR_REFERENCES_", Casted,
3520 "__OBJC,__message_refs,literal_pointers,no_dead_strip",
3526 return Builder.CreateLoad(Entry);
3529 llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) {
3530 llvm::GlobalVariable *&Entry = ClassNames[Ident];
3533 Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
3534 llvm::ConstantArray::get(VMContext,
3535 Ident->getNameStart()),
3537 "__TEXT,__objc_classname,cstring_literals" :
3538 "__TEXT,__cstring,cstring_literals"),
3541 return getConstantGEP(VMContext, Entry, 0, 0);
3544 llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
3545 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator
3546 I = MethodDefinitions.find(MD);
3547 if (I != MethodDefinitions.end())
3553 /// GetIvarLayoutName - Returns a unique constant for the given
3554 /// ivar layout bitmap.
3555 llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
3556 const ObjCCommonTypesHelper &ObjCTypes) {
3557 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
3560 void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT,
3561 unsigned int BytePos,
3562 bool ForStrongLayout,
3564 const RecordDecl *RD = RT->getDecl();
3565 // FIXME - Use iterator.
3566 SmallVector<const FieldDecl*, 16> Fields(RD->field_begin(), RD->field_end());
3567 llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
3568 const llvm::StructLayout *RecLayout =
3569 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(Ty));
3571 BuildAggrIvarLayout(0, RecLayout, RD, Fields, BytePos,
3572 ForStrongLayout, HasUnion);
3575 void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
3576 const llvm::StructLayout *Layout,
3577 const RecordDecl *RD,
3578 const SmallVectorImpl<const FieldDecl*> &RecFields,
3579 unsigned int BytePos, bool ForStrongLayout,
3581 bool IsUnion = (RD && RD->isUnion());
3582 uint64_t MaxUnionIvarSize = 0;
3583 uint64_t MaxSkippedUnionIvarSize = 0;
3584 const FieldDecl *MaxField = 0;
3585 const FieldDecl *MaxSkippedField = 0;
3586 const FieldDecl *LastFieldBitfieldOrUnnamed = 0;
3587 uint64_t MaxFieldOffset = 0;
3588 uint64_t MaxSkippedFieldOffset = 0;
3589 uint64_t LastBitfieldOrUnnamedOffset = 0;
3590 uint64_t FirstFieldDelta = 0;
3592 if (RecFields.empty())
3594 unsigned WordSizeInBits = CGM.getContext().getTargetInfo().getPointerWidth(0);
3595 unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth();
3596 if (!RD && CGM.getLangOptions().ObjCAutoRefCount) {
3597 const FieldDecl *FirstField = RecFields[0];
3599 ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(FirstField));
3602 for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
3603 const FieldDecl *Field = RecFields[i];
3604 uint64_t FieldOffset;
3606 // Note that 'i' here is actually the field index inside RD of Field,
3607 // although this dependency is hidden.
3608 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
3609 FieldOffset = (RL.getFieldOffset(i) / ByteSizeInBits) - FirstFieldDelta;
3612 ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field)) - FirstFieldDelta;
3614 // Skip over unnamed or bitfields
3615 if (!Field->getIdentifier() || Field->isBitField()) {
3616 LastFieldBitfieldOrUnnamed = Field;
3617 LastBitfieldOrUnnamedOffset = FieldOffset;
3621 LastFieldBitfieldOrUnnamed = 0;
3622 QualType FQT = Field->getType();
3623 if (FQT->isRecordType() || FQT->isUnionType()) {
3624 if (FQT->isUnionType())
3627 BuildAggrIvarRecordLayout(FQT->getAs<RecordType>(),
3628 BytePos + FieldOffset,
3629 ForStrongLayout, HasUnion);
3633 if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
3634 const ConstantArrayType *CArray =
3635 dyn_cast_or_null<ConstantArrayType>(Array);
3636 uint64_t ElCount = CArray->getSize().getZExtValue();
3637 assert(CArray && "only array with known element size is supported");
3638 FQT = CArray->getElementType();
3639 while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
3640 const ConstantArrayType *CArray =
3641 dyn_cast_or_null<ConstantArrayType>(Array);
3642 ElCount *= CArray->getSize().getZExtValue();
3643 FQT = CArray->getElementType();
3646 assert(!FQT->isUnionType() &&
3647 "layout for array of unions not supported");
3648 if (FQT->isRecordType() && ElCount) {
3649 int OldIndex = IvarsInfo.size() - 1;
3650 int OldSkIndex = SkipIvars.size() -1;
3652 const RecordType *RT = FQT->getAs<RecordType>();
3653 BuildAggrIvarRecordLayout(RT, BytePos + FieldOffset,
3654 ForStrongLayout, HasUnion);
3656 // Replicate layout information for each array element. Note that
3657 // one element is already done.
3659 for (int FirstIndex = IvarsInfo.size() - 1,
3660 FirstSkIndex = SkipIvars.size() - 1 ;ElIx < ElCount; ElIx++) {
3661 uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits;
3662 for (int i = OldIndex+1; i <= FirstIndex; ++i)
3663 IvarsInfo.push_back(GC_IVAR(IvarsInfo[i].ivar_bytepos + Size*ElIx,
3664 IvarsInfo[i].ivar_size));
3665 for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i)
3666 SkipIvars.push_back(GC_IVAR(SkipIvars[i].ivar_bytepos + Size*ElIx,
3667 SkipIvars[i].ivar_size));
3672 // At this point, we are done with Record/Union and array there of.
3673 // For other arrays we are down to its element type.
3674 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT);
3676 unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType());
3677 if ((ForStrongLayout && GCAttr == Qualifiers::Strong)
3678 || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
3680 uint64_t UnionIvarSize = FieldSize / WordSizeInBits;
3681 if (UnionIvarSize > MaxUnionIvarSize) {
3682 MaxUnionIvarSize = UnionIvarSize;
3684 MaxFieldOffset = FieldOffset;
3687 IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset,
3688 FieldSize / WordSizeInBits));
3690 } else if ((ForStrongLayout &&
3691 (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak))
3692 || (!ForStrongLayout && GCAttr != Qualifiers::Weak)) {
3694 // FIXME: Why the asymmetry? We divide by word size in bits on other
3696 uint64_t UnionIvarSize = FieldSize;
3697 if (UnionIvarSize > MaxSkippedUnionIvarSize) {
3698 MaxSkippedUnionIvarSize = UnionIvarSize;
3699 MaxSkippedField = Field;
3700 MaxSkippedFieldOffset = FieldOffset;
3703 // FIXME: Why the asymmetry, we divide by byte size in bits here?
3704 SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset,
3705 FieldSize / ByteSizeInBits));
3710 if (LastFieldBitfieldOrUnnamed) {
3711 if (LastFieldBitfieldOrUnnamed->isBitField()) {
3712 // Last field was a bitfield. Must update skip info.
3713 uint64_t BitFieldSize
3714 = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext());
3716 skivar.ivar_bytepos = BytePos + LastBitfieldOrUnnamedOffset;
3717 skivar.ivar_size = (BitFieldSize / ByteSizeInBits)
3718 + ((BitFieldSize % ByteSizeInBits) != 0);
3719 SkipIvars.push_back(skivar);
3721 assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed");
3722 // Last field was unnamed. Must update skip info.
3724 = CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType());
3725 SkipIvars.push_back(GC_IVAR(BytePos + LastBitfieldOrUnnamedOffset,
3726 FieldSize / ByteSizeInBits));
3731 IvarsInfo.push_back(GC_IVAR(BytePos + MaxFieldOffset,
3733 if (MaxSkippedField)
3734 SkipIvars.push_back(GC_IVAR(BytePos + MaxSkippedFieldOffset,
3735 MaxSkippedUnionIvarSize));
3738 /// BuildIvarLayoutBitmap - This routine is the horsework for doing all
3739 /// the computations and returning the layout bitmap (for ivar or blocks) in
3740 /// the given argument BitMap string container. Routine reads
3741 /// two containers, IvarsInfo and SkipIvars which are assumed to be
3742 /// filled already by the caller.
3743 llvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string& BitMap) {
3744 unsigned int WordsToScan, WordsToSkip;
3745 llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext);
3747 // Build the string of skip/scan nibbles
3748 SmallVector<SKIP_SCAN, 32> SkipScanIvars;
3749 unsigned int WordSize =
3750 CGM.getTypes().getTargetData().getTypeAllocSize(PtrTy);
3751 if (IvarsInfo[0].ivar_bytepos == 0) {
3753 WordsToScan = IvarsInfo[0].ivar_size;
3755 WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize;
3756 WordsToScan = IvarsInfo[0].ivar_size;
3758 for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++) {
3759 unsigned int TailPrevGCObjC =
3760 IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize;
3761 if (IvarsInfo[i].ivar_bytepos == TailPrevGCObjC) {
3762 // consecutive 'scanned' object pointers.
3763 WordsToScan += IvarsInfo[i].ivar_size;
3765 // Skip over 'gc'able object pointer which lay over each other.
3766 if (TailPrevGCObjC > IvarsInfo[i].ivar_bytepos)
3768 // Must skip over 1 or more words. We save current skip/scan values
3769 // and start a new pair.
3771 SkScan.skip = WordsToSkip;
3772 SkScan.scan = WordsToScan;
3773 SkipScanIvars.push_back(SkScan);
3776 SkScan.skip = (IvarsInfo[i].ivar_bytepos - TailPrevGCObjC) / WordSize;
3778 SkipScanIvars.push_back(SkScan);
3780 WordsToScan = IvarsInfo[i].ivar_size;
3783 if (WordsToScan > 0) {
3785 SkScan.skip = WordsToSkip;
3786 SkScan.scan = WordsToScan;
3787 SkipScanIvars.push_back(SkScan);
3790 if (!SkipIvars.empty()) {
3791 unsigned int LastIndex = SkipIvars.size()-1;
3792 int LastByteSkipped =
3793 SkipIvars[LastIndex].ivar_bytepos + SkipIvars[LastIndex].ivar_size;
3794 LastIndex = IvarsInfo.size()-1;
3795 int LastByteScanned =
3796 IvarsInfo[LastIndex].ivar_bytepos +
3797 IvarsInfo[LastIndex].ivar_size * WordSize;
3798 // Compute number of bytes to skip at the tail end of the last ivar scanned.
3799 if (LastByteSkipped > LastByteScanned) {
3800 unsigned int TotalWords = (LastByteSkipped + (WordSize -1)) / WordSize;
3802 SkScan.skip = TotalWords - (LastByteScanned/WordSize);
3804 SkipScanIvars.push_back(SkScan);
3807 // Mini optimization of nibbles such that an 0xM0 followed by 0x0N is produced
3809 int SkipScan = SkipScanIvars.size()-1;
3810 for (int i = 0; i <= SkipScan; i++) {
3811 if ((i < SkipScan) && SkipScanIvars[i].skip && SkipScanIvars[i].scan == 0
3812 && SkipScanIvars[i+1].skip == 0 && SkipScanIvars[i+1].scan) {
3813 // 0xM0 followed by 0x0N detected.
3814 SkipScanIvars[i].scan = SkipScanIvars[i+1].scan;
3815 for (int j = i+1; j < SkipScan; j++)
3816 SkipScanIvars[j] = SkipScanIvars[j+1];
3821 // Generate the string.
3822 for (int i = 0; i <= SkipScan; i++) {
3824 unsigned int skip_small = SkipScanIvars[i].skip % 0xf;
3825 unsigned int scan_small = SkipScanIvars[i].scan % 0xf;
3826 unsigned int skip_big = SkipScanIvars[i].skip / 0xf;
3827 unsigned int scan_big = SkipScanIvars[i].scan / 0xf;
3830 for (unsigned int ix = 0; ix < skip_big; ix++)
3831 BitMap += (unsigned char)(0xf0);
3833 // next (skip small, scan)
3835 byte = skip_small << 4;
3839 } else if (scan_small) {
3846 for (unsigned int ix = 0; ix < scan_big; ix++)
3847 BitMap += (unsigned char)(0x0f);
3854 // null terminate string.
3855 unsigned char zero = 0;
3858 llvm::GlobalVariable * Entry =
3859 CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
3860 llvm::ConstantArray::get(VMContext, BitMap.c_str()),
3862 "__TEXT,__objc_classname,cstring_literals" :
3863 "__TEXT,__cstring,cstring_literals"),
3865 return getConstantGEP(VMContext, Entry, 0, 0);
3868 /// BuildIvarLayout - Builds ivar layout bitmap for the class
3869 /// implementation for the __strong or __weak case.
3870 /// The layout map displays which words in ivar list must be skipped
3871 /// and which must be scanned by GC (see below). String is built of bytes.
3872 /// Each byte is divided up in two nibbles (4-bit each). Left nibble is count
3873 /// of words to skip and right nibble is count of words to scan. So, each
3874 /// nibble represents up to 15 workds to skip or scan. Skipping the rest is
3875 /// represented by a 0x00 byte which also ends the string.
3876 /// 1. when ForStrongLayout is true, following ivars are scanned:
3879 /// - __strong anything
3881 /// 2. When ForStrongLayout is false, following ivars are scanned:
3882 /// - __weak anything
3884 llvm::Constant *CGObjCCommonMac::BuildIvarLayout(
3885 const ObjCImplementationDecl *OMD,
3886 bool ForStrongLayout) {
3887 bool hasUnion = false;
3889 llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext);
3890 if (CGM.getLangOptions().getGC() == LangOptions::NonGC &&
3891 !CGM.getLangOptions().ObjCAutoRefCount)
3892 return llvm::Constant::getNullValue(PtrTy);
3894 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
3895 SmallVector<const FieldDecl*, 32> RecFields;
3896 if (CGM.getLangOptions().ObjCAutoRefCount) {
3897 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
3898 IVD; IVD = IVD->getNextIvar())
3899 RecFields.push_back(cast<FieldDecl>(IVD));
3902 SmallVector<const ObjCIvarDecl*, 32> Ivars;
3903 CGM.getContext().DeepCollectObjCIvars(OI, true, Ivars);
3905 // FIXME: This is not ideal; we shouldn't have to do this copy.
3906 RecFields.append(Ivars.begin(), Ivars.end());
3909 if (RecFields.empty())
3910 return llvm::Constant::getNullValue(PtrTy);
3915 BuildAggrIvarLayout(OMD, 0, 0, RecFields, 0, ForStrongLayout, hasUnion);
3916 if (IvarsInfo.empty())
3917 return llvm::Constant::getNullValue(PtrTy);
3918 // Sort on byte position in case we encounterred a union nested in
3920 if (hasUnion && !IvarsInfo.empty())
3921 std::sort(IvarsInfo.begin(), IvarsInfo.end());
3922 if (hasUnion && !SkipIvars.empty())
3923 std::sort(SkipIvars.begin(), SkipIvars.end());
3926 llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
3928 if (CGM.getLangOptions().ObjCGCBitmapPrint) {
3929 printf("\n%s ivar layout for class '%s': ",
3930 ForStrongLayout ? "strong" : "weak",
3931 OMD->getClassInterface()->getName().data());
3932 const unsigned char *s = (unsigned char*)BitMap.c_str();
3933 for (unsigned i = 0; i < BitMap.size(); i++)
3935 printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
3937 printf("0x%x%s", s[i], s[i] != 0 ? ", " : "");
3943 llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
3944 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
3946 // FIXME: Avoid std::string copying.
3948 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_NAME_",
3949 llvm::ConstantArray::get(VMContext, Sel.getAsString()),
3951 "__TEXT,__objc_methname,cstring_literals" :
3952 "__TEXT,__cstring,cstring_literals"),
3955 return getConstantGEP(VMContext, Entry, 0, 0);
3958 // FIXME: Merge into a single cstring creation function.
3959 llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
3960 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
3963 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
3964 std::string TypeStr;
3965 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
3967 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
3970 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_",
3971 llvm::ConstantArray::get(VMContext, TypeStr),
3973 "__TEXT,__objc_methtype,cstring_literals" :
3974 "__TEXT,__cstring,cstring_literals"),
3977 return getConstantGEP(VMContext, Entry, 0, 0);
3980 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D) {
3981 std::string TypeStr;
3982 if (CGM.getContext().getObjCEncodingForMethodDecl(
3983 const_cast<ObjCMethodDecl*>(D),
3987 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
3990 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_",
3991 llvm::ConstantArray::get(VMContext, TypeStr),
3993 "__TEXT,__objc_methtype,cstring_literals" :
3994 "__TEXT,__cstring,cstring_literals"),
3997 return getConstantGEP(VMContext, Entry, 0, 0);
4000 // FIXME: Merge into a single cstring creation function.
4001 llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
4002 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
4005 Entry = CreateMetadataVar("\01L_OBJC_PROP_NAME_ATTR_",
4006 llvm::ConstantArray::get(VMContext,
4007 Ident->getNameStart()),
4008 "__TEXT,__cstring,cstring_literals",
4011 return getConstantGEP(VMContext, Entry, 0, 0);
4014 // FIXME: Merge into a single cstring creation function.
4015 // FIXME: This Decl should be more precise.
4017 CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
4018 const Decl *Container) {
4019 std::string TypeStr;
4020 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
4021 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
4024 void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D,
4025 const ObjCContainerDecl *CD,
4026 SmallVectorImpl<char> &Name) {
4027 llvm::raw_svector_ostream OS(Name);
4028 assert (CD && "Missing container decl in GetNameForMethod");
4029 OS << '\01' << (D->isInstanceMethod() ? '-' : '+')
4030 << '[' << CD->getName();
4031 if (const ObjCCategoryImplDecl *CID =
4032 dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
4033 OS << '(' << CID << ')';
4034 OS << ' ' << D->getSelector().getAsString() << ']';
4037 void CGObjCMac::FinishModule() {
4040 // Emit the dummy bodies for any protocols which were referenced but
4042 for (llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*>::iterator
4043 I = Protocols.begin(), e = Protocols.end(); I != e; ++I) {
4044 if (I->second->hasInitializer())
4047 std::vector<llvm::Constant*> Values(5);
4048 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
4049 Values[1] = GetClassName(I->first);
4050 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
4051 Values[3] = Values[4] =
4052 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
4053 I->second->setLinkage(llvm::GlobalValue::InternalLinkage);
4054 I->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
4056 CGM.AddUsedGlobal(I->second);
4059 // Add assembler directives to add lazy undefined symbol references
4060 // for classes which are referenced but not defined. This is
4061 // important for correct linker interaction.
4063 // FIXME: It would be nice if we had an LLVM construct for this.
4064 if (!LazySymbols.empty() || !DefinedSymbols.empty()) {
4065 llvm::SmallString<256> Asm;
4066 Asm += CGM.getModule().getModuleInlineAsm();
4067 if (!Asm.empty() && Asm.back() != '\n')
4070 llvm::raw_svector_ostream OS(Asm);
4071 for (llvm::SetVector<IdentifierInfo*>::iterator I = DefinedSymbols.begin(),
4072 e = DefinedSymbols.end(); I != e; ++I)
4073 OS << "\t.objc_class_name_" << (*I)->getName() << "=0\n"
4074 << "\t.globl .objc_class_name_" << (*I)->getName() << "\n";
4075 for (llvm::SetVector<IdentifierInfo*>::iterator I = LazySymbols.begin(),
4076 e = LazySymbols.end(); I != e; ++I) {
4077 OS << "\t.lazy_reference .objc_class_name_" << (*I)->getName() << "\n";
4080 for (size_t i = 0; i < DefinedCategoryNames.size(); ++i) {
4081 OS << "\t.objc_category_name_" << DefinedCategoryNames[i] << "=0\n"
4082 << "\t.globl .objc_category_name_" << DefinedCategoryNames[i] << "\n";
4085 CGM.getModule().setModuleInlineAsm(OS.str());
4089 CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
4090 : CGObjCCommonMac(cgm),
4092 ObjCEmptyCacheVar = ObjCEmptyVtableVar = NULL;
4098 ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
4099 : VMContext(cgm.getLLVMContext()), CGM(cgm) {
4100 CodeGen::CodeGenTypes &Types = CGM.getTypes();
4101 ASTContext &Ctx = CGM.getContext();
4103 ShortTy = Types.ConvertType(Ctx.ShortTy);
4104 IntTy = Types.ConvertType(Ctx.IntTy);
4105 LongTy = Types.ConvertType(Ctx.LongTy);
4106 LongLongTy = Types.ConvertType(Ctx.LongLongTy);
4107 Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
4109 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
4110 PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy);
4111 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
4113 // FIXME: It would be nice to unify this with the opaque type, so that the IR
4114 // comes out a bit cleaner.
4115 llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
4116 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
4118 // I'm not sure I like this. The implicit coordination is a bit
4119 // gross. We should solve this in a reasonable fashion because this
4120 // is a pretty common task (match some runtime data structure with
4121 // an LLVM data structure).
4123 // FIXME: This is leaked.
4124 // FIXME: Merge with rewriter code?
4126 // struct _objc_super {
4130 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
4131 Ctx.getTranslationUnitDecl(),
4132 SourceLocation(), SourceLocation(),
4133 &Ctx.Idents.get("_objc_super"));
4134 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
4135 Ctx.getObjCIdType(), 0, 0, false, false));
4136 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
4137 Ctx.getObjCClassType(), 0, 0, false, false));
4138 RD->completeDefinition();
4140 SuperCTy = Ctx.getTagDeclType(RD);
4141 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
4143 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
4144 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
4148 // char *attributes;
4150 PropertyTy = llvm::StructType::create("struct._prop_t",
4151 Int8PtrTy, Int8PtrTy, NULL);
4153 // struct _prop_list_t {
4154 // uint32_t entsize; // sizeof(struct _prop_t)
4155 // uint32_t count_of_properties;
4156 // struct _prop_t prop_list[count_of_properties];
4159 llvm::StructType::create("struct._prop_list_t", IntTy, IntTy,
4160 llvm::ArrayType::get(PropertyTy, 0), NULL);
4161 // struct _prop_list_t *
4162 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
4164 // struct _objc_method {
4166 // char *method_type;
4169 MethodTy = llvm::StructType::create("struct._objc_method",
4170 SelectorPtrTy, Int8PtrTy, Int8PtrTy,
4173 // struct _objc_cache *
4174 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache");
4175 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
4179 ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
4180 : ObjCCommonTypesHelper(cgm) {
4181 // struct _objc_method_description {
4185 MethodDescriptionTy =
4186 llvm::StructType::create("struct._objc_method_description",
4187 SelectorPtrTy, Int8PtrTy, NULL);
4189 // struct _objc_method_description_list {
4191 // struct _objc_method_description[1];
4193 MethodDescriptionListTy =
4194 llvm::StructType::create("struct._objc_method_description_list",
4196 llvm::ArrayType::get(MethodDescriptionTy, 0),NULL);
4198 // struct _objc_method_description_list *
4199 MethodDescriptionListPtrTy =
4200 llvm::PointerType::getUnqual(MethodDescriptionListTy);
4202 // Protocol description structures
4204 // struct _objc_protocol_extension {
4205 // uint32_t size; // sizeof(struct _objc_protocol_extension)
4206 // struct _objc_method_description_list *optional_instance_methods;
4207 // struct _objc_method_description_list *optional_class_methods;
4208 // struct _objc_property_list *instance_properties;
4210 ProtocolExtensionTy =
4211 llvm::StructType::create("struct._objc_protocol_extension",
4212 IntTy, MethodDescriptionListPtrTy,
4213 MethodDescriptionListPtrTy, PropertyListPtrTy,
4216 // struct _objc_protocol_extension *
4217 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
4219 // Handle recursive construction of Protocol and ProtocolList types
4222 llvm::StructType::create(VMContext, "struct._objc_protocol");
4225 llvm::StructType::create(VMContext, "struct._objc_protocol_list");
4226 ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy),
4228 llvm::ArrayType::get(ProtocolTy, 0),
4231 // struct _objc_protocol {
4232 // struct _objc_protocol_extension *isa;
4233 // char *protocol_name;
4234 // struct _objc_protocol **_objc_protocol_list;
4235 // struct _objc_method_description_list *instance_methods;
4236 // struct _objc_method_description_list *class_methods;
4238 ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy,
4239 llvm::PointerType::getUnqual(ProtocolListTy),
4240 MethodDescriptionListPtrTy,
4241 MethodDescriptionListPtrTy,
4244 // struct _objc_protocol_list *
4245 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
4247 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
4249 // Class description structures
4251 // struct _objc_ivar {
4256 IvarTy = llvm::StructType::create("struct._objc_ivar",
4257 Int8PtrTy, Int8PtrTy, IntTy, NULL);
4259 // struct _objc_ivar_list *
4261 llvm::StructType::create(VMContext, "struct._objc_ivar_list");
4262 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
4264 // struct _objc_method_list *
4266 llvm::StructType::create(VMContext, "struct._objc_method_list");
4267 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
4269 // struct _objc_class_extension *
4271 llvm::StructType::create("struct._objc_class_extension",
4272 IntTy, Int8PtrTy, PropertyListPtrTy, NULL);
4273 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
4275 ClassTy = llvm::StructType::create(VMContext, "struct._objc_class");
4277 // struct _objc_class {
4279 // Class super_class;
4283 // long instance_size;
4284 // struct _objc_ivar_list *ivars;
4285 // struct _objc_method_list *methods;
4286 // struct _objc_cache *cache;
4287 // struct _objc_protocol_list *protocols;
4288 // char *ivar_layout;
4289 // struct _objc_class_ext *ext;
4291 ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy),
4292 llvm::PointerType::getUnqual(ClassTy),
4302 ClassExtensionPtrTy,
4305 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
4307 // struct _objc_category {
4308 // char *category_name;
4309 // char *class_name;
4310 // struct _objc_method_list *instance_method;
4311 // struct _objc_method_list *class_method;
4312 // uint32_t size; // sizeof(struct _objc_category)
4313 // struct _objc_property_list *instance_properties;// category's @property
4316 llvm::StructType::create("struct._objc_category",
4317 Int8PtrTy, Int8PtrTy, MethodListPtrTy,
4318 MethodListPtrTy, ProtocolListPtrTy,
4319 IntTy, PropertyListPtrTy, NULL);
4321 // Global metadata structures
4323 // struct _objc_symtab {
4324 // long sel_ref_cnt;
4326 // short cls_def_cnt;
4327 // short cat_def_cnt;
4328 // char *defs[cls_def_cnt + cat_def_cnt];
4331 llvm::StructType::create("struct._objc_symtab",
4332 LongTy, SelectorPtrTy, ShortTy, ShortTy,
4333 llvm::ArrayType::get(Int8PtrTy, 0), NULL);
4334 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
4336 // struct _objc_module {
4338 // long size; // sizeof(struct _objc_module)
4340 // struct _objc_symtab* symtab;
4343 llvm::StructType::create("struct._objc_module",
4344 LongTy, LongTy, Int8PtrTy, SymtabPtrTy, NULL);
4347 // FIXME: This is the size of the setjmp buffer and should be target
4348 // specific. 18 is what's used on 32-bit X86.
4349 uint64_t SetJmpBufferSize = 18;
4352 llvm::Type *StackPtrTy = llvm::ArrayType::get(
4353 llvm::Type::getInt8PtrTy(VMContext), 4);
4356 llvm::StructType::create("struct._objc_exception_data",
4357 llvm::ArrayType::get(llvm::Type::getInt32Ty(VMContext),
4363 ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm)
4364 : ObjCCommonTypesHelper(cgm) {
4365 // struct _method_list_t {
4366 // uint32_t entsize; // sizeof(struct _objc_method)
4367 // uint32_t method_count;
4368 // struct _objc_method method_list[method_count];
4371 llvm::StructType::create("struct.__method_list_t", IntTy, IntTy,
4372 llvm::ArrayType::get(MethodTy, 0), NULL);
4373 // struct method_list_t *
4374 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy);
4376 // struct _protocol_t {
4378 // const char * const protocol_name;
4379 // const struct _protocol_list_t * protocol_list; // super protocols
4380 // const struct method_list_t * const instance_methods;
4381 // const struct method_list_t * const class_methods;
4382 // const struct method_list_t *optionalInstanceMethods;
4383 // const struct method_list_t *optionalClassMethods;
4384 // const struct _prop_list_t * properties;
4385 // const uint32_t size; // sizeof(struct _protocol_t)
4386 // const uint32_t flags; // = 0
4389 // Holder for struct _protocol_list_t *
4390 ProtocolListnfABITy =
4391 llvm::StructType::create(VMContext, "struct._objc_protocol_list");
4394 llvm::StructType::create("struct._protocol_t", ObjectPtrTy, Int8PtrTy,
4395 llvm::PointerType::getUnqual(ProtocolListnfABITy),
4396 MethodListnfABIPtrTy, MethodListnfABIPtrTy,
4397 MethodListnfABIPtrTy, MethodListnfABIPtrTy,
4398 PropertyListPtrTy, IntTy, IntTy, NULL);
4400 // struct _protocol_t*
4401 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy);
4403 // struct _protocol_list_t {
4404 // long protocol_count; // Note, this is 32/64 bit
4405 // struct _protocol_t *[protocol_count];
4407 ProtocolListnfABITy->setBody(LongTy,
4408 llvm::ArrayType::get(ProtocolnfABIPtrTy, 0),
4411 // struct _objc_protocol_list*
4412 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy);
4415 // unsigned long int *offset; // pointer to ivar offset location
4418 // uint32_t alignment;
4422 llvm::StructType::create("struct._ivar_t",
4423 llvm::PointerType::getUnqual(LongTy),
4424 Int8PtrTy, Int8PtrTy, IntTy, IntTy, NULL);
4426 // struct _ivar_list_t {
4427 // uint32 entsize; // sizeof(struct _ivar_t)
4429 // struct _iver_t list[count];
4432 llvm::StructType::create("struct._ivar_list_t", IntTy, IntTy,
4433 llvm::ArrayType::get(IvarnfABITy, 0), NULL);
4435 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy);
4437 // struct _class_ro_t {
4438 // uint32_t const flags;
4439 // uint32_t const instanceStart;
4440 // uint32_t const instanceSize;
4441 // uint32_t const reserved; // only when building for 64bit targets
4442 // const uint8_t * const ivarLayout;
4443 // const char *const name;
4444 // const struct _method_list_t * const baseMethods;
4445 // const struct _objc_protocol_list *const baseProtocols;
4446 // const struct _ivar_list_t *const ivars;
4447 // const uint8_t * const weakIvarLayout;
4448 // const struct _prop_list_t * const properties;
4451 // FIXME. Add 'reserved' field in 64bit abi mode!
4452 ClassRonfABITy = llvm::StructType::create("struct._class_ro_t",
4453 IntTy, IntTy, IntTy, Int8PtrTy,
4454 Int8PtrTy, MethodListnfABIPtrTy,
4455 ProtocolListnfABIPtrTy,
4457 Int8PtrTy, PropertyListPtrTy, NULL);
4459 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
4460 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
4461 ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false)
4464 // struct _class_t {
4465 // struct _class_t *isa;
4466 // struct _class_t * const superclass;
4469 // struct class_ro_t *ro;
4472 ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t");
4473 ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy),
4474 llvm::PointerType::getUnqual(ClassnfABITy),
4476 llvm::PointerType::getUnqual(ImpnfABITy),
4477 llvm::PointerType::getUnqual(ClassRonfABITy),
4480 // LLVM for struct _class_t *
4481 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy);
4483 // struct _category_t {
4484 // const char * const name;
4485 // struct _class_t *const cls;
4486 // const struct _method_list_t * const instance_methods;
4487 // const struct _method_list_t * const class_methods;
4488 // const struct _protocol_list_t * const protocols;
4489 // const struct _prop_list_t * const properties;
4491 CategorynfABITy = llvm::StructType::create("struct._category_t",
4492 Int8PtrTy, ClassnfABIPtrTy,
4493 MethodListnfABIPtrTy,
4494 MethodListnfABIPtrTy,
4495 ProtocolListnfABIPtrTy,
4499 // New types for nonfragile abi messaging.
4500 CodeGen::CodeGenTypes &Types = CGM.getTypes();
4501 ASTContext &Ctx = CGM.getContext();
4503 // MessageRefTy - LLVM for:
4504 // struct _message_ref_t {
4509 // First the clang type for struct _message_ref_t
4510 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
4511 Ctx.getTranslationUnitDecl(),
4512 SourceLocation(), SourceLocation(),
4513 &Ctx.Idents.get("_message_ref_t"));
4514 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
4515 Ctx.VoidPtrTy, 0, 0, false, false));
4516 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
4517 Ctx.getObjCSelType(), 0, 0, false, false));
4518 RD->completeDefinition();
4520 MessageRefCTy = Ctx.getTagDeclType(RD);
4521 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
4522 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
4524 // MessageRefPtrTy - LLVM for struct _message_ref_t*
4525 MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy);
4527 // SuperMessageRefTy - LLVM for:
4528 // struct _super_message_ref_t {
4529 // SUPER_IMP messenger;
4533 llvm::StructType::create("struct._super_message_ref_t",
4534 ImpnfABITy, SelectorPtrTy, NULL);
4536 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
4537 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);
4540 // struct objc_typeinfo {
4541 // const void** vtable; // objc_ehtype_vtable + 2
4542 // const char* name; // c++ typeinfo string
4546 llvm::StructType::create("struct._objc_typeinfo",
4547 llvm::PointerType::getUnqual(Int8PtrTy),
4548 Int8PtrTy, ClassnfABIPtrTy, NULL);
4549 EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy);
4552 llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
4553 FinishNonFragileABIModule();
4558 void CGObjCNonFragileABIMac::AddModuleClassList(const
4559 std::vector<llvm::GlobalValue*>
4561 const char *SymbolName,
4562 const char *SectionName) {
4563 unsigned NumClasses = Container.size();
4568 std::vector<llvm::Constant*> Symbols(NumClasses);
4569 for (unsigned i=0; i<NumClasses; i++)
4570 Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i],
4571 ObjCTypes.Int8PtrTy);
4572 llvm::Constant* Init =
4573 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
4577 llvm::GlobalVariable *GV =
4578 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
4579 llvm::GlobalValue::InternalLinkage,
4582 GV->setAlignment(CGM.getTargetData().getABITypeAlignment(Init->getType()));
4583 GV->setSection(SectionName);
4584 CGM.AddUsedGlobal(GV);
4587 void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
4588 // nonfragile abi has no module definition.
4590 // Build list of all implemented class addresses in array
4591 // L_OBJC_LABEL_CLASS_$.
4592 AddModuleClassList(DefinedClasses,
4593 "\01L_OBJC_LABEL_CLASS_$",
4594 "__DATA, __objc_classlist, regular, no_dead_strip");
4596 for (unsigned i = 0; i < DefinedClasses.size(); i++) {
4597 llvm::GlobalValue *IMPLGV = DefinedClasses[i];
4598 if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage)
4600 IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage);
4603 for (unsigned i = 0; i < DefinedMetaClasses.size(); i++) {
4604 llvm::GlobalValue *IMPLGV = DefinedMetaClasses[i];
4605 if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage)
4607 IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage);
4610 AddModuleClassList(DefinedNonLazyClasses,
4611 "\01L_OBJC_LABEL_NONLAZY_CLASS_$",
4612 "__DATA, __objc_nlclslist, regular, no_dead_strip");
4614 // Build list of all implemented category addresses in array
4615 // L_OBJC_LABEL_CATEGORY_$.
4616 AddModuleClassList(DefinedCategories,
4617 "\01L_OBJC_LABEL_CATEGORY_$",
4618 "__DATA, __objc_catlist, regular, no_dead_strip");
4619 AddModuleClassList(DefinedNonLazyCategories,
4620 "\01L_OBJC_LABEL_NONLAZY_CATEGORY_$",
4621 "__DATA, __objc_nlcatlist, regular, no_dead_strip");
4626 /// isVTableDispatchedSelector - Returns true if SEL is not in the list of
4627 /// VTableDispatchMethods; false otherwise. What this means is that
4628 /// except for the 19 selectors in the list, we generate 32bit-style
4629 /// message dispatch call for all the rest.
4630 bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
4631 // At various points we've experimented with using vtable-based
4632 // dispatch for all methods.
4633 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
4635 llvm_unreachable("Invalid dispatch method!");
4636 case CodeGenOptions::Legacy:
4638 case CodeGenOptions::NonLegacy:
4640 case CodeGenOptions::Mixed:
4644 // If so, see whether this selector is in the white-list of things which must
4645 // use the new dispatch convention. We lazily build a dense set for this.
4646 if (VTableDispatchMethods.empty()) {
4647 VTableDispatchMethods.insert(GetNullarySelector("alloc"));
4648 VTableDispatchMethods.insert(GetNullarySelector("class"));
4649 VTableDispatchMethods.insert(GetNullarySelector("self"));
4650 VTableDispatchMethods.insert(GetNullarySelector("isFlipped"));
4651 VTableDispatchMethods.insert(GetNullarySelector("length"));
4652 VTableDispatchMethods.insert(GetNullarySelector("count"));
4654 // These are vtable-based if GC is disabled.
4655 // Optimistically use vtable dispatch for hybrid compiles.
4656 if (CGM.getLangOptions().getGC() != LangOptions::GCOnly) {
4657 VTableDispatchMethods.insert(GetNullarySelector("retain"));
4658 VTableDispatchMethods.insert(GetNullarySelector("release"));
4659 VTableDispatchMethods.insert(GetNullarySelector("autorelease"));
4662 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone"));
4663 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass"));
4664 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector"));
4665 VTableDispatchMethods.insert(GetUnarySelector("objectForKey"));
4666 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex"));
4667 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString"));
4668 VTableDispatchMethods.insert(GetUnarySelector("isEqual"));
4670 // These are vtable-based if GC is enabled.
4671 // Optimistically use vtable dispatch for hybrid compiles.
4672 if (CGM.getLangOptions().getGC() != LangOptions::NonGC) {
4673 VTableDispatchMethods.insert(GetNullarySelector("hash"));
4674 VTableDispatchMethods.insert(GetUnarySelector("addObject"));
4676 // "countByEnumeratingWithState:objects:count"
4677 IdentifierInfo *KeyIdents[] = {
4678 &CGM.getContext().Idents.get("countByEnumeratingWithState"),
4679 &CGM.getContext().Idents.get("objects"),
4680 &CGM.getContext().Idents.get("count")
4682 VTableDispatchMethods.insert(
4683 CGM.getContext().Selectors.getSelector(3, KeyIdents));
4687 return VTableDispatchMethods.count(Sel);
4691 enum MetaDataDlags {
4695 OBJC2_CLS_HIDDEN = 0x10,
4696 CLS_EXCEPTION = 0x20,
4698 /// (Obsolete) ARC-specific: this class has a .release_ivars method
4699 CLS_HAS_IVAR_RELEASER = 0x40,
4700 /// class was compiled with -fobjc-arr
4701 CLS_COMPILED_BY_ARC = 0x80 // (1<<7)
4703 /// BuildClassRoTInitializer - generate meta-data for:
4704 /// struct _class_ro_t {
4705 /// uint32_t const flags;
4706 /// uint32_t const instanceStart;
4707 /// uint32_t const instanceSize;
4708 /// uint32_t const reserved; // only when building for 64bit targets
4709 /// const uint8_t * const ivarLayout;
4710 /// const char *const name;
4711 /// const struct _method_list_t * const baseMethods;
4712 /// const struct _protocol_list_t *const baseProtocols;
4713 /// const struct _ivar_list_t *const ivars;
4714 /// const uint8_t * const weakIvarLayout;
4715 /// const struct _prop_list_t * const properties;
4718 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
4720 unsigned InstanceStart,
4721 unsigned InstanceSize,
4722 const ObjCImplementationDecl *ID) {
4723 std::string ClassName = ID->getNameAsString();
4724 std::vector<llvm::Constant*> Values(10); // 11 for 64bit targets!
4726 if (CGM.getLangOptions().ObjCAutoRefCount)
4727 flags |= CLS_COMPILED_BY_ARC;
4729 Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags);
4730 Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart);
4731 Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize);
4732 // FIXME. For 64bit targets add 0 here.
4733 Values[ 3] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes)
4734 : BuildIvarLayout(ID, true);
4735 Values[ 4] = GetClassName(ID->getIdentifier());
4736 // const struct _method_list_t * const baseMethods;
4737 std::vector<llvm::Constant*> Methods;
4738 std::string MethodListName("\01l_OBJC_$_");
4739 if (flags & CLS_META) {
4740 MethodListName += "CLASS_METHODS_" + ID->getNameAsString();
4741 for (ObjCImplementationDecl::classmeth_iterator
4742 i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
4743 // Class methods should always be defined.
4744 Methods.push_back(GetMethodConstant(*i));
4747 MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString();
4748 for (ObjCImplementationDecl::instmeth_iterator
4749 i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
4750 // Instance methods should always be defined.
4751 Methods.push_back(GetMethodConstant(*i));
4753 for (ObjCImplementationDecl::propimpl_iterator
4754 i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
4755 ObjCPropertyImplDecl *PID = *i;
4757 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
4758 ObjCPropertyDecl *PD = PID->getPropertyDecl();
4760 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
4761 if (llvm::Constant *C = GetMethodConstant(MD))
4762 Methods.push_back(C);
4763 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
4764 if (llvm::Constant *C = GetMethodConstant(MD))
4765 Methods.push_back(C);
4769 Values[ 5] = EmitMethodList(MethodListName,
4770 "__DATA, __objc_const", Methods);
4772 const ObjCInterfaceDecl *OID = ID->getClassInterface();
4773 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");
4774 Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_"
4776 OID->all_referenced_protocol_begin(),
4777 OID->all_referenced_protocol_end());
4779 if (flags & CLS_META)
4780 Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
4782 Values[ 7] = EmitIvarList(ID);
4783 Values[ 8] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes)
4784 : BuildIvarLayout(ID, false);
4785 if (flags & CLS_META)
4786 Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
4788 Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
4789 ID, ID->getClassInterface(), ObjCTypes);
4790 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy,
4792 llvm::GlobalVariable *CLASS_RO_GV =
4793 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassRonfABITy, false,
4794 llvm::GlobalValue::InternalLinkage,
4796 (flags & CLS_META) ?
4797 std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName :
4798 std::string("\01l_OBJC_CLASS_RO_$_")+ClassName);
4799 CLASS_RO_GV->setAlignment(
4800 CGM.getTargetData().getABITypeAlignment(ObjCTypes.ClassRonfABITy));
4801 CLASS_RO_GV->setSection("__DATA, __objc_const");
4806 /// BuildClassMetaData - This routine defines that to-level meta-data
4807 /// for the given ClassName for:
4808 /// struct _class_t {
4809 /// struct _class_t *isa;
4810 /// struct _class_t * const superclass;
4813 /// struct class_ro_t *ro;
4816 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData(
4817 std::string &ClassName,
4818 llvm::Constant *IsAGV,
4819 llvm::Constant *SuperClassGV,
4820 llvm::Constant *ClassRoGV,
4821 bool HiddenVisibility) {
4822 std::vector<llvm::Constant*> Values(5);
4824 Values[1] = SuperClassGV;
4826 Values[1] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy);
4827 Values[2] = ObjCEmptyCacheVar; // &ObjCEmptyCacheVar
4828 Values[3] = ObjCEmptyVtableVar; // &ObjCEmptyVtableVar
4829 Values[4] = ClassRoGV; // &CLASS_RO_GV
4830 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy,
4832 llvm::GlobalVariable *GV = GetClassGlobal(ClassName);
4833 GV->setInitializer(Init);
4834 GV->setSection("__DATA, __objc_data");
4836 CGM.getTargetData().getABITypeAlignment(ObjCTypes.ClassnfABITy));
4837 if (HiddenVisibility)
4838 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
4843 CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
4844 return OD->getClassMethod(GetNullarySelector("load")) != 0;
4847 void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
4848 uint32_t &InstanceStart,
4849 uint32_t &InstanceSize) {
4850 const ASTRecordLayout &RL =
4851 CGM.getContext().getASTObjCImplementationLayout(OID);
4853 // InstanceSize is really instance end.
4854 InstanceSize = RL.getDataSize().getQuantity();
4856 // If there are no fields, the start is the same as the end.
4857 if (!RL.getFieldCount())
4858 InstanceStart = InstanceSize;
4860 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
4863 void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
4864 std::string ClassName = ID->getNameAsString();
4865 if (!ObjCEmptyCacheVar) {
4866 ObjCEmptyCacheVar = new llvm::GlobalVariable(
4870 llvm::GlobalValue::ExternalLinkage,
4872 "_objc_empty_cache");
4874 ObjCEmptyVtableVar = new llvm::GlobalVariable(
4876 ObjCTypes.ImpnfABITy,
4878 llvm::GlobalValue::ExternalLinkage,
4880 "_objc_empty_vtable");
4882 assert(ID->getClassInterface() &&
4883 "CGObjCNonFragileABIMac::GenerateClass - class is 0");
4884 // FIXME: Is this correct (that meta class size is never computed)?
4885 uint32_t InstanceStart =
4886 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassnfABITy);
4887 uint32_t InstanceSize = InstanceStart;
4888 uint32_t flags = CLS_META;
4889 std::string ObjCMetaClassName(getMetaclassSymbolPrefix());
4890 std::string ObjCClassName(getClassSymbolPrefix());
4892 llvm::GlobalVariable *SuperClassGV, *IsAGV;
4894 bool classIsHidden =
4895 ID->getClassInterface()->getVisibility() == HiddenVisibility;
4897 flags |= OBJC2_CLS_HIDDEN;
4898 if (ID->hasCXXStructors())
4899 flags |= eClassFlags_ABI2_HasCXXStructors;
4900 if (!ID->getClassInterface()->getSuperClass()) {
4903 SuperClassGV = GetClassGlobal(ObjCClassName + ClassName);
4904 IsAGV = GetClassGlobal(ObjCMetaClassName + ClassName);
4906 // Has a root. Current class is not a root.
4907 const ObjCInterfaceDecl *Root = ID->getClassInterface();
4908 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
4910 IsAGV = GetClassGlobal(ObjCMetaClassName + Root->getNameAsString());
4911 if (Root->isWeakImported())
4912 IsAGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
4913 // work on super class metadata symbol.
4914 std::string SuperClassName =
4916 ID->getClassInterface()->getSuperClass()->getNameAsString();
4917 SuperClassGV = GetClassGlobal(SuperClassName);
4918 if (ID->getClassInterface()->getSuperClass()->isWeakImported())
4919 SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
4921 llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags,
4924 std::string TClassName = ObjCMetaClassName + ClassName;
4925 llvm::GlobalVariable *MetaTClass =
4926 BuildClassMetaData(TClassName, IsAGV, SuperClassGV, CLASS_RO_GV,
4928 DefinedMetaClasses.push_back(MetaTClass);
4930 // Metadata for the class
4933 flags |= OBJC2_CLS_HIDDEN;
4934 if (ID->hasCXXStructors())
4935 flags |= eClassFlags_ABI2_HasCXXStructors;
4937 if (hasObjCExceptionAttribute(CGM.getContext(), ID->getClassInterface()))
4938 flags |= CLS_EXCEPTION;
4940 if (!ID->getClassInterface()->getSuperClass()) {
4944 // Has a root. Current class is not a root.
4945 std::string RootClassName =
4946 ID->getClassInterface()->getSuperClass()->getNameAsString();
4947 SuperClassGV = GetClassGlobal(ObjCClassName + RootClassName);
4948 if (ID->getClassInterface()->getSuperClass()->isWeakImported())
4949 SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
4951 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
4952 CLASS_RO_GV = BuildClassRoTInitializer(flags,
4957 TClassName = ObjCClassName + ClassName;
4958 llvm::GlobalVariable *ClassMD =
4959 BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV,
4961 DefinedClasses.push_back(ClassMD);
4963 // Determine if this class is also "non-lazy".
4964 if (ImplementationIsNonLazy(ID))
4965 DefinedNonLazyClasses.push_back(ClassMD);
4967 // Force the definition of the EHType if necessary.
4968 if (flags & CLS_EXCEPTION)
4969 GetInterfaceEHType(ID->getClassInterface(), true);
4970 // Make sure method definition entries are all clear for next implementation.
4971 MethodDefinitions.clear();
4974 /// GenerateProtocolRef - This routine is called to generate code for
4975 /// a protocol reference expression; as in:
4977 /// @protocol(Proto1);
4979 /// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1
4980 /// which will hold address of the protocol meta-data.
4982 llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CGBuilderTy &Builder,
4983 const ObjCProtocolDecl *PD) {
4985 // This routine is called for @protocol only. So, we must build definition
4986 // of protocol's meta-data (not a reference to it!)
4988 llvm::Constant *Init =
4989 llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD),
4990 ObjCTypes.ExternalProtocolPtrTy);
4992 std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_");
4993 ProtocolName += PD->getName();
4995 llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
4997 return Builder.CreateLoad(PTGV);
4998 PTGV = new llvm::GlobalVariable(
5000 Init->getType(), false,
5001 llvm::GlobalValue::WeakAnyLinkage,
5004 PTGV->setSection("__DATA, __objc_protorefs, coalesced, no_dead_strip");
5005 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5006 CGM.AddUsedGlobal(PTGV);
5007 return Builder.CreateLoad(PTGV);
5010 /// GenerateCategory - Build metadata for a category implementation.
5011 /// struct _category_t {
5012 /// const char * const name;
5013 /// struct _class_t *const cls;
5014 /// const struct _method_list_t * const instance_methods;
5015 /// const struct _method_list_t * const class_methods;
5016 /// const struct _protocol_list_t * const protocols;
5017 /// const struct _prop_list_t * const properties;
5020 void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
5021 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
5022 const char *Prefix = "\01l_OBJC_$_CATEGORY_";
5023 std::string ExtCatName(Prefix + Interface->getNameAsString()+
5024 "_$_" + OCD->getNameAsString());
5025 std::string ExtClassName(getClassSymbolPrefix() +
5026 Interface->getNameAsString());
5028 std::vector<llvm::Constant*> Values(6);
5029 Values[0] = GetClassName(OCD->getIdentifier());
5030 // meta-class entry symbol
5031 llvm::GlobalVariable *ClassGV = GetClassGlobal(ExtClassName);
5032 if (Interface->isWeakImported())
5033 ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
5035 Values[1] = ClassGV;
5036 std::vector<llvm::Constant*> Methods;
5037 std::string MethodListName(Prefix);
5038 MethodListName += "INSTANCE_METHODS_" + Interface->getNameAsString() +
5039 "_$_" + OCD->getNameAsString();
5041 for (ObjCCategoryImplDecl::instmeth_iterator
5042 i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
5043 // Instance methods should always be defined.
5044 Methods.push_back(GetMethodConstant(*i));
5047 Values[2] = EmitMethodList(MethodListName,
5048 "__DATA, __objc_const",
5051 MethodListName = Prefix;
5052 MethodListName += "CLASS_METHODS_" + Interface->getNameAsString() + "_$_" +
5053 OCD->getNameAsString();
5055 for (ObjCCategoryImplDecl::classmeth_iterator
5056 i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
5057 // Class methods should always be defined.
5058 Methods.push_back(GetMethodConstant(*i));
5061 Values[3] = EmitMethodList(MethodListName,
5062 "__DATA, __objc_const",
5064 const ObjCCategoryDecl *Category =
5065 Interface->FindCategoryDeclaration(OCD->getIdentifier());
5067 llvm::SmallString<256> ExtName;
5068 llvm::raw_svector_ostream(ExtName) << Interface->getName() << "_$_"
5070 Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_"
5071 + Interface->getName() + "_$_"
5072 + Category->getName(),
5073 Category->protocol_begin(),
5074 Category->protocol_end());
5075 Values[5] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
5076 OCD, Category, ObjCTypes);
5078 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
5079 Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
5082 llvm::Constant *Init =
5083 llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy,
5085 llvm::GlobalVariable *GCATV
5086 = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CategorynfABITy,
5088 llvm::GlobalValue::InternalLinkage,
5091 GCATV->setAlignment(
5092 CGM.getTargetData().getABITypeAlignment(ObjCTypes.CategorynfABITy));
5093 GCATV->setSection("__DATA, __objc_const");
5094 CGM.AddUsedGlobal(GCATV);
5095 DefinedCategories.push_back(GCATV);
5097 // Determine if this category is also "non-lazy".
5098 if (ImplementationIsNonLazy(OCD))
5099 DefinedNonLazyCategories.push_back(GCATV);
5100 // method definition entries must be clear for next implementation.
5101 MethodDefinitions.clear();
5104 /// GetMethodConstant - Return a struct objc_method constant for the
5105 /// given method if it has been defined. The result is null if the
5106 /// method has not been defined. The return value has type MethodPtrTy.
5107 llvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant(
5108 const ObjCMethodDecl *MD) {
5109 llvm::Function *Fn = GetMethodDefinition(MD);
5113 std::vector<llvm::Constant*> Method(3);
5115 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
5116 ObjCTypes.SelectorPtrTy);
5117 Method[1] = GetMethodVarType(MD);
5118 Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy);
5119 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
5122 /// EmitMethodList - Build meta-data for method declarations
5123 /// struct _method_list_t {
5124 /// uint32_t entsize; // sizeof(struct _objc_method)
5125 /// uint32_t method_count;
5126 /// struct _objc_method method_list[method_count];
5129 llvm::Constant *CGObjCNonFragileABIMac::EmitMethodList(Twine Name,
5130 const char *Section,
5131 const ConstantVector &Methods) {
5132 // Return null for empty list.
5133 if (Methods.empty())
5134 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
5136 llvm::Constant *Values[3];
5137 // sizeof(struct _objc_method)
5138 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.MethodTy);
5139 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
5141 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
5142 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
5144 Values[2] = llvm::ConstantArray::get(AT, Methods);
5145 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
5147 llvm::GlobalVariable *GV =
5148 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5149 llvm::GlobalValue::InternalLinkage, Init, Name);
5150 GV->setAlignment(CGM.getTargetData().getABITypeAlignment(Init->getType()));
5151 GV->setSection(Section);
5152 CGM.AddUsedGlobal(GV);
5153 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy);
5156 /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
5158 llvm::GlobalVariable *
5159 CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
5160 const ObjCIvarDecl *Ivar) {
5161 const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
5162 std::string Name = "OBJC_IVAR_$_" + Container->getNameAsString() +
5163 '.' + Ivar->getNameAsString();
5164 llvm::GlobalVariable *IvarOffsetGV =
5165 CGM.getModule().getGlobalVariable(Name);
5168 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.LongTy,
5170 llvm::GlobalValue::ExternalLinkage,
5173 return IvarOffsetGV;
5177 CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
5178 const ObjCIvarDecl *Ivar,
5179 unsigned long int Offset) {
5180 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
5181 IvarOffsetGV->setInitializer(llvm::ConstantInt::get(ObjCTypes.LongTy,
5183 IvarOffsetGV->setAlignment(
5184 CGM.getTargetData().getABITypeAlignment(ObjCTypes.LongTy));
5186 // FIXME: This matches gcc, but shouldn't the visibility be set on the use as
5187 // well (i.e., in ObjCIvarOffsetVariable).
5188 if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
5189 Ivar->getAccessControl() == ObjCIvarDecl::Package ||
5190 ID->getVisibility() == HiddenVisibility)
5191 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5193 IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
5194 IvarOffsetGV->setSection("__DATA, __objc_ivar");
5195 return IvarOffsetGV;
5198 /// EmitIvarList - Emit the ivar list for the given
5199 /// implementation. The return value has type
5200 /// IvarListnfABIPtrTy.
5201 /// struct _ivar_t {
5202 /// unsigned long int *offset; // pointer to ivar offset location
5205 /// uint32_t alignment;
5208 /// struct _ivar_list_t {
5209 /// uint32 entsize; // sizeof(struct _ivar_t)
5211 /// struct _iver_t list[count];
5215 llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
5216 const ObjCImplementationDecl *ID) {
5218 std::vector<llvm::Constant*> Ivars, Ivar(5);
5220 const ObjCInterfaceDecl *OID = ID->getClassInterface();
5221 assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface");
5223 // FIXME. Consolidate this with similar code in GenerateClass.
5225 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
5226 IVD; IVD = IVD->getNextIvar()) {
5227 // Ignore unnamed bit-fields.
5228 if (!IVD->getDeclName())
5230 Ivar[0] = EmitIvarOffsetVar(ID->getClassInterface(), IVD,
5231 ComputeIvarBaseOffset(CGM, ID, IVD));
5232 Ivar[1] = GetMethodVarName(IVD->getIdentifier());
5233 Ivar[2] = GetMethodVarType(IVD);
5234 llvm::Type *FieldTy =
5235 CGM.getTypes().ConvertTypeForMem(IVD->getType());
5236 unsigned Size = CGM.getTargetData().getTypeAllocSize(FieldTy);
5237 unsigned Align = CGM.getContext().getPreferredTypeAlign(
5238 IVD->getType().getTypePtr()) >> 3;
5239 Align = llvm::Log2_32(Align);
5240 Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align);
5241 // NOTE. Size of a bitfield does not match gcc's, because of the
5242 // way bitfields are treated special in each. But I am told that
5243 // 'size' for bitfield ivars is ignored by the runtime so it does
5244 // not matter. If it matters, there is enough info to get the
5246 Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
5247 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar));
5249 // Return null for empty list.
5251 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
5253 llvm::Constant *Values[3];
5254 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.IvarnfABITy);
5255 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
5256 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
5257 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy,
5259 Values[2] = llvm::ConstantArray::get(AT, Ivars);
5260 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
5261 const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_";
5262 llvm::GlobalVariable *GV =
5263 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5264 llvm::GlobalValue::InternalLinkage,
5266 Prefix + OID->getName());
5268 CGM.getTargetData().getABITypeAlignment(Init->getType()));
5269 GV->setSection("__DATA, __objc_const");
5271 CGM.AddUsedGlobal(GV);
5272 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
5275 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
5276 const ObjCProtocolDecl *PD) {
5277 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
5280 // We use the initializer as a marker of whether this is a forward
5281 // reference or not. At module finalization we add the empty
5282 // contents for protocols which were referenced but never defined.
5284 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, false,
5285 llvm::GlobalValue::ExternalLinkage,
5287 "\01l_OBJC_PROTOCOL_$_" + PD->getName());
5288 Entry->setSection("__DATA,__datacoal_nt,coalesced");
5294 /// GetOrEmitProtocol - Generate the protocol meta-data:
5296 /// struct _protocol_t {
5298 /// const char * const protocol_name;
5299 /// const struct _protocol_list_t * protocol_list; // super protocols
5300 /// const struct method_list_t * const instance_methods;
5301 /// const struct method_list_t * const class_methods;
5302 /// const struct method_list_t *optionalInstanceMethods;
5303 /// const struct method_list_t *optionalClassMethods;
5304 /// const struct _prop_list_t * properties;
5305 /// const uint32_t size; // sizeof(struct _protocol_t)
5306 /// const uint32_t flags; // = 0
5311 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
5312 const ObjCProtocolDecl *PD) {
5313 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
5315 // Early exit if a defining object has already been generated.
5316 if (Entry && Entry->hasInitializer())
5319 // Construct method lists.
5320 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
5321 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
5322 for (ObjCProtocolDecl::instmeth_iterator
5323 i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
5324 ObjCMethodDecl *MD = *i;
5325 llvm::Constant *C = GetMethodDescriptionConstant(MD);
5327 return GetOrEmitProtocolRef(PD);
5329 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
5330 OptInstanceMethods.push_back(C);
5332 InstanceMethods.push_back(C);
5336 for (ObjCProtocolDecl::classmeth_iterator
5337 i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
5338 ObjCMethodDecl *MD = *i;
5339 llvm::Constant *C = GetMethodDescriptionConstant(MD);
5341 return GetOrEmitProtocolRef(PD);
5343 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
5344 OptClassMethods.push_back(C);
5346 ClassMethods.push_back(C);
5350 std::vector<llvm::Constant*> Values(10);
5352 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy);
5353 Values[1] = GetClassName(PD->getIdentifier());
5354 Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getName(),
5355 PD->protocol_begin(),
5356 PD->protocol_end());
5358 Values[3] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_"
5360 "__DATA, __objc_const",
5362 Values[4] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_"
5364 "__DATA, __objc_const",
5366 Values[5] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_"
5368 "__DATA, __objc_const",
5369 OptInstanceMethods);
5370 Values[6] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_"
5372 "__DATA, __objc_const",
5374 Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getName(),
5377 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
5378 Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
5379 Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy);
5380 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy,
5384 // Already created, fix the linkage and update the initializer.
5385 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
5386 Entry->setInitializer(Init);
5389 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
5390 false, llvm::GlobalValue::WeakAnyLinkage, Init,
5391 "\01l_OBJC_PROTOCOL_$_" + PD->getName());
5392 Entry->setAlignment(
5393 CGM.getTargetData().getABITypeAlignment(ObjCTypes.ProtocolnfABITy));
5394 Entry->setSection("__DATA,__datacoal_nt,coalesced");
5396 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
5397 CGM.AddUsedGlobal(Entry);
5399 // Use this protocol meta-data to build protocol list table in section
5400 // __DATA, __objc_protolist
5401 llvm::GlobalVariable *PTGV =
5402 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy,
5403 false, llvm::GlobalValue::WeakAnyLinkage, Entry,
5404 "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getName());
5406 CGM.getTargetData().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
5407 PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip");
5408 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5409 CGM.AddUsedGlobal(PTGV);
5413 /// EmitProtocolList - Generate protocol list meta-data:
5415 /// struct _protocol_list_t {
5416 /// long protocol_count; // Note, this is 32/64 bit
5417 /// struct _protocol_t[protocol_count];
5422 CGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
5423 ObjCProtocolDecl::protocol_iterator begin,
5424 ObjCProtocolDecl::protocol_iterator end) {
5425 std::vector<llvm::Constant*> ProtocolRefs;
5427 // Just return null for empty protocol lists
5429 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
5431 // FIXME: We shouldn't need to do this lookup here, should we?
5432 llvm::SmallString<256> TmpName;
5433 Name.toVector(TmpName);
5434 llvm::GlobalVariable *GV =
5435 CGM.getModule().getGlobalVariable(TmpName.str(), true);
5437 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
5439 for (; begin != end; ++begin)
5440 ProtocolRefs.push_back(GetProtocolRef(*begin)); // Implemented???
5442 // This list is null terminated.
5443 ProtocolRefs.push_back(llvm::Constant::getNullValue(
5444 ObjCTypes.ProtocolnfABIPtrTy));
5446 llvm::Constant *Values[2];
5448 llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
5450 llvm::ConstantArray::get(
5451 llvm::ArrayType::get(ObjCTypes.ProtocolnfABIPtrTy,
5452 ProtocolRefs.size()),
5455 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
5456 GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5457 llvm::GlobalValue::InternalLinkage,
5459 GV->setSection("__DATA, __objc_const");
5461 CGM.getTargetData().getABITypeAlignment(Init->getType()));
5462 CGM.AddUsedGlobal(GV);
5463 return llvm::ConstantExpr::getBitCast(GV,
5464 ObjCTypes.ProtocolListnfABIPtrTy);
5467 /// GetMethodDescriptionConstant - This routine build following meta-data:
5468 /// struct _objc_method {
5470 /// char *method_type;
5475 CGObjCNonFragileABIMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
5476 std::vector<llvm::Constant*> Desc(3);
5478 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
5479 ObjCTypes.SelectorPtrTy);
5480 Desc[1] = GetMethodVarType(MD);
5484 // Protocol methods have no implementation. So, this entry is always NULL.
5485 Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
5486 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc);
5489 /// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference.
5490 /// This code gen. amounts to generating code for:
5492 /// (type *)((char *)base + _OBJC_IVAR_$_.ivar;
5495 LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
5496 CodeGen::CodeGenFunction &CGF,
5498 llvm::Value *BaseValue,
5499 const ObjCIvarDecl *Ivar,
5500 unsigned CVRQualifiers) {
5501 ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCObjectType>()->getInterface();
5502 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
5503 EmitIvarOffset(CGF, ID, Ivar));
5506 llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(
5507 CodeGen::CodeGenFunction &CGF,
5508 const ObjCInterfaceDecl *Interface,
5509 const ObjCIvarDecl *Ivar) {
5510 return CGF.Builder.CreateLoad(ObjCIvarOffsetVariable(Interface, Ivar),"ivar");
5513 static void appendSelectorForMessageRefTable(std::string &buffer,
5514 Selector selector) {
5515 if (selector.isUnarySelector()) {
5516 buffer += selector.getNameForSlot(0);
5520 for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) {
5521 buffer += selector.getNameForSlot(i);
5526 /// Emit a "v-table" message send. We emit a weak hidden-visibility
5527 /// struct, initially containing the selector pointer and a pointer to
5528 /// a "fixup" variant of the appropriate objc_msgSend. To call, we
5529 /// load and call the function pointer, passing the address of the
5530 /// struct as the second parameter. The runtime determines whether
5531 /// the selector is currently emitted using vtable dispatch; if so, it
5532 /// substitutes a stub function which simply tail-calls through the
5533 /// appropriate vtable slot, and if not, it substitues a stub function
5534 /// which tail-calls objc_msgSend. Both stubs adjust the selector
5535 /// argument to correctly point to the selector.
5537 CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF,
5538 ReturnValueSlot returnSlot,
5539 QualType resultType,
5544 const CallArgList &formalArgs,
5545 const ObjCMethodDecl *method) {
5546 // Compute the actual arguments.
5549 // First argument: the receiver / super-call structure.
5551 arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy);
5552 args.add(RValue::get(arg0), arg0Type);
5554 // Second argument: a pointer to the message ref structure. Leave
5555 // the actual argument value blank for now.
5556 args.add(RValue::get(0), ObjCTypes.MessageRefCPtrTy);
5558 args.insert(args.end(), formalArgs.begin(), formalArgs.end());
5560 const CGFunctionInfo &fnInfo =
5561 CGM.getTypes().getFunctionInfo(resultType, args,
5562 FunctionType::ExtInfo());
5564 NullReturnState nullReturn;
5566 // Find the function to call and the mangled name for the message
5567 // ref structure. Using a different mangled name wouldn't actually
5568 // be a problem; it would just be a waste.
5570 // The runtime currently never uses vtable dispatch for anything
5571 // except normal, non-super message-sends.
5572 // FIXME: don't use this for that.
5573 llvm::Constant *fn = 0;
5574 std::string messageRefName("\01l_");
5575 if (CGM.ReturnTypeUsesSRet(fnInfo)) {
5577 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
5578 messageRefName += "objc_msgSendSuper2_stret_fixup";
5580 nullReturn.init(CGF, arg0);
5581 fn = ObjCTypes.getMessageSendStretFixupFn();
5582 messageRefName += "objc_msgSend_stret_fixup";
5584 } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) {
5585 fn = ObjCTypes.getMessageSendFpretFixupFn();
5586 messageRefName += "objc_msgSend_fpret_fixup";
5589 fn = ObjCTypes.getMessageSendSuper2FixupFn();
5590 messageRefName += "objc_msgSendSuper2_fixup";
5592 fn = ObjCTypes.getMessageSendFixupFn();
5593 messageRefName += "objc_msgSend_fixup";
5596 assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend");
5597 messageRefName += '_';
5599 // Append the selector name, except use underscores anywhere we
5600 // would have used colons.
5601 appendSelectorForMessageRefTable(messageRefName, selector);
5603 llvm::GlobalVariable *messageRef
5604 = CGM.getModule().getGlobalVariable(messageRefName);
5606 // Build the message ref structure.
5607 llvm::Constant *values[] = { fn, GetMethodVarName(selector) };
5608 llvm::Constant *init = llvm::ConstantStruct::getAnon(values);
5609 messageRef = new llvm::GlobalVariable(CGM.getModule(),
5612 llvm::GlobalValue::WeakAnyLinkage,
5615 messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
5616 messageRef->setAlignment(16);
5617 messageRef->setSection("__DATA, __objc_msgrefs, coalesced");
5620 CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy);
5622 // Update the message ref argument.
5623 args[1].RV = RValue::get(mref);
5625 // Load the function to call from the message ref table.
5626 llvm::Value *callee = CGF.Builder.CreateStructGEP(mref, 0);
5627 callee = CGF.Builder.CreateLoad(callee, "msgSend_fn");
5629 bool variadic = method ? method->isVariadic() : false;
5630 llvm::FunctionType *fnType =
5631 CGF.getTypes().GetFunctionType(fnInfo, variadic);
5632 callee = CGF.Builder.CreateBitCast(callee,
5633 llvm::PointerType::getUnqual(fnType));
5635 RValue result = CGF.EmitCall(fnInfo, callee, returnSlot, args);
5636 return nullReturn.complete(CGF, result, resultType);
5639 /// Generate code for a message send expression in the nonfragile abi.
5641 CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
5642 ReturnValueSlot Return,
5643 QualType ResultType,
5645 llvm::Value *Receiver,
5646 const CallArgList &CallArgs,
5647 const ObjCInterfaceDecl *Class,
5648 const ObjCMethodDecl *Method) {
5649 return isVTableDispatchedSelector(Sel)
5650 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
5651 Receiver, CGF.getContext().getObjCIdType(),
5652 false, CallArgs, Method)
5653 : EmitMessageSend(CGF, Return, ResultType,
5654 EmitSelector(CGF.Builder, Sel),
5655 Receiver, CGF.getContext().getObjCIdType(),
5656 false, CallArgs, Method, ObjCTypes);
5659 llvm::GlobalVariable *
5660 CGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name) {
5661 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
5664 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABITy,
5665 false, llvm::GlobalValue::ExternalLinkage,
5672 llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CGBuilderTy &Builder,
5673 IdentifierInfo *II) {
5674 llvm::GlobalVariable *&Entry = ClassReferences[II];
5677 std::string ClassName(getClassSymbolPrefix() + II->getName().str());
5678 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
5680 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
5681 false, llvm::GlobalValue::InternalLinkage,
5683 "\01L_OBJC_CLASSLIST_REFERENCES_$_");
5684 Entry->setAlignment(
5685 CGM.getTargetData().getABITypeAlignment(
5686 ObjCTypes.ClassnfABIPtrTy));
5687 Entry->setSection("__DATA, __objc_classrefs, regular, no_dead_strip");
5688 CGM.AddUsedGlobal(Entry);
5691 return Builder.CreateLoad(Entry);
5694 llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CGBuilderTy &Builder,
5695 const ObjCInterfaceDecl *ID) {
5696 return EmitClassRefFromId(Builder, ID->getIdentifier());
5699 llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
5700 CGBuilderTy &Builder) {
5701 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
5702 return EmitClassRefFromId(Builder, II);
5706 CGObjCNonFragileABIMac::EmitSuperClassRef(CGBuilderTy &Builder,
5707 const ObjCInterfaceDecl *ID) {
5708 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
5711 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
5712 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
5714 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
5715 false, llvm::GlobalValue::InternalLinkage,
5717 "\01L_OBJC_CLASSLIST_SUP_REFS_$_");
5718 Entry->setAlignment(
5719 CGM.getTargetData().getABITypeAlignment(
5720 ObjCTypes.ClassnfABIPtrTy));
5721 Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
5722 CGM.AddUsedGlobal(Entry);
5725 return Builder.CreateLoad(Entry);
5728 /// EmitMetaClassRef - Return a Value * of the address of _class_t
5731 llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CGBuilderTy &Builder,
5732 const ObjCInterfaceDecl *ID) {
5733 llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];
5735 return Builder.CreateLoad(Entry);
5737 std::string MetaClassName(getMetaclassSymbolPrefix() + ID->getNameAsString());
5738 llvm::GlobalVariable *MetaClassGV = GetClassGlobal(MetaClassName);
5740 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, false,
5741 llvm::GlobalValue::InternalLinkage,
5743 "\01L_OBJC_CLASSLIST_SUP_REFS_$_");
5744 Entry->setAlignment(
5745 CGM.getTargetData().getABITypeAlignment(
5746 ObjCTypes.ClassnfABIPtrTy));
5748 Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
5749 CGM.AddUsedGlobal(Entry);
5751 return Builder.CreateLoad(Entry);
5754 /// GetClass - Return a reference to the class for the given interface
5756 llvm::Value *CGObjCNonFragileABIMac::GetClass(CGBuilderTy &Builder,
5757 const ObjCInterfaceDecl *ID) {
5758 if (ID->isWeakImported()) {
5759 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
5760 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
5761 ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
5764 return EmitClassRef(Builder, ID);
5767 /// Generates a message send where the super is the receiver. This is
5768 /// a message send to self with special delivery semantics indicating
5769 /// which class's method should be called.
5771 CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
5772 ReturnValueSlot Return,
5773 QualType ResultType,
5775 const ObjCInterfaceDecl *Class,
5776 bool isCategoryImpl,
5777 llvm::Value *Receiver,
5778 bool IsClassMessage,
5779 const CodeGen::CallArgList &CallArgs,
5780 const ObjCMethodDecl *Method) {
5782 // Create and init a super structure; this is a (receiver, class)
5783 // pair we will pass to objc_msgSendSuper.
5784 llvm::Value *ObjCSuper =
5785 CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super");
5787 llvm::Value *ReceiverAsObject =
5788 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
5789 CGF.Builder.CreateStore(ReceiverAsObject,
5790 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
5792 // If this is a class message the metaclass is passed as the target.
5793 llvm::Value *Target;
5794 if (IsClassMessage) {
5795 if (isCategoryImpl) {
5796 // Message sent to "super' in a class method defined in
5797 // a category implementation.
5798 Target = EmitClassRef(CGF.Builder, Class);
5799 Target = CGF.Builder.CreateStructGEP(Target, 0);
5800 Target = CGF.Builder.CreateLoad(Target);
5802 Target = EmitMetaClassRef(CGF.Builder, Class);
5804 Target = EmitSuperClassRef(CGF.Builder, Class);
5806 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
5808 llvm::Type *ClassTy =
5809 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
5810 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
5811 CGF.Builder.CreateStore(Target,
5812 CGF.Builder.CreateStructGEP(ObjCSuper, 1));
5814 return (isVTableDispatchedSelector(Sel))
5815 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
5816 ObjCSuper, ObjCTypes.SuperPtrCTy,
5817 true, CallArgs, Method)
5818 : EmitMessageSend(CGF, Return, ResultType,
5819 EmitSelector(CGF.Builder, Sel),
5820 ObjCSuper, ObjCTypes.SuperPtrCTy,
5821 true, CallArgs, Method, ObjCTypes);
5824 llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CGBuilderTy &Builder,
5825 Selector Sel, bool lval) {
5826 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
5829 llvm::Constant *Casted =
5830 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
5831 ObjCTypes.SelectorPtrTy);
5833 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.SelectorPtrTy, false,
5834 llvm::GlobalValue::InternalLinkage,
5835 Casted, "\01L_OBJC_SELECTOR_REFERENCES_");
5836 Entry->setSection("__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
5837 CGM.AddUsedGlobal(Entry);
5842 return Builder.CreateLoad(Entry);
5844 /// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
5845 /// objc_assign_ivar (id src, id *dst, ptrdiff_t)
5847 void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
5850 llvm::Value *ivarOffset) {
5851 llvm::Type * SrcTy = src->getType();
5852 if (!isa<llvm::PointerType>(SrcTy)) {
5853 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
5854 assert(Size <= 8 && "does not support size > 8");
5855 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
5856 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
5857 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5859 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5860 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
5861 CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(),
5862 src, dst, ivarOffset);
5866 /// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
5867 /// objc_assign_strongCast (id src, id *dst)
5869 void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
5870 CodeGen::CodeGenFunction &CGF,
5871 llvm::Value *src, llvm::Value *dst) {
5872 llvm::Type * SrcTy = src->getType();
5873 if (!isa<llvm::PointerType>(SrcTy)) {
5874 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
5875 assert(Size <= 8 && "does not support size > 8");
5876 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
5877 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
5878 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5880 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5881 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
5882 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(),
5883 src, dst, "weakassign");
5887 void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
5888 CodeGen::CodeGenFunction &CGF,
5889 llvm::Value *DestPtr,
5890 llvm::Value *SrcPtr,
5891 llvm::Value *Size) {
5892 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
5893 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
5894 CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(),
5895 DestPtr, SrcPtr, Size);
5899 /// EmitObjCWeakRead - Code gen for loading value of a __weak
5900 /// object: objc_read_weak (id *src)
5902 llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
5903 CodeGen::CodeGenFunction &CGF,
5904 llvm::Value *AddrWeakObj) {
5905 llvm::Type* DestTy =
5906 cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
5907 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
5908 llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(),
5909 AddrWeakObj, "weakread");
5910 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
5914 /// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
5915 /// objc_assign_weak (id src, id *dst)
5917 void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
5918 llvm::Value *src, llvm::Value *dst) {
5919 llvm::Type * SrcTy = src->getType();
5920 if (!isa<llvm::PointerType>(SrcTy)) {
5921 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
5922 assert(Size <= 8 && "does not support size > 8");
5923 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
5924 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
5925 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5927 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5928 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
5929 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(),
5930 src, dst, "weakassign");
5934 /// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
5935 /// objc_assign_global (id src, id *dst)
5937 void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
5938 llvm::Value *src, llvm::Value *dst,
5940 llvm::Type * SrcTy = src->getType();
5941 if (!isa<llvm::PointerType>(SrcTy)) {
5942 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
5943 assert(Size <= 8 && "does not support size > 8");
5944 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
5945 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
5946 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5948 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5949 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
5951 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(),
5952 src, dst, "globalassign");
5954 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(),
5955 src, dst, "threadlocalassign");
5960 CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
5961 const ObjCAtSynchronizedStmt &S) {
5962 EmitAtSynchronizedStmt(CGF, S,
5963 cast<llvm::Function>(ObjCTypes.getSyncEnterFn()),
5964 cast<llvm::Function>(ObjCTypes.getSyncExitFn()));
5968 CGObjCNonFragileABIMac::GetEHType(QualType T) {
5969 // There's a particular fixed type info for 'id'.
5970 if (T->isObjCIdType() ||
5971 T->isObjCQualifiedIdType()) {
5972 llvm::Constant *IDEHType =
5973 CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id");
5976 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy,
5978 llvm::GlobalValue::ExternalLinkage,
5979 0, "OBJC_EHTYPE_id");
5983 // All other types should be Objective-C interface pointer types.
5984 const ObjCObjectPointerType *PT =
5985 T->getAs<ObjCObjectPointerType>();
5986 assert(PT && "Invalid @catch type.");
5987 const ObjCInterfaceType *IT = PT->getInterfaceType();
5988 assert(IT && "Invalid @catch type.");
5989 return GetInterfaceEHType(IT->getDecl(), false);
5992 void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
5993 const ObjCAtTryStmt &S) {
5994 EmitTryCatchStmt(CGF, S,
5995 cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()),
5996 cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()),
5997 cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn()));
6000 /// EmitThrowStmt - Generate code for a throw statement.
6001 void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
6002 const ObjCAtThrowStmt &S) {
6003 if (const Expr *ThrowExpr = S.getThrowExpr()) {
6004 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
6005 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
6006 CGF.EmitCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception)
6007 .setDoesNotReturn();
6009 CGF.EmitCallOrInvoke(ObjCTypes.getExceptionRethrowFn())
6010 .setDoesNotReturn();
6013 CGF.Builder.CreateUnreachable();
6014 CGF.Builder.ClearInsertionPoint();
6018 CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
6019 bool ForDefinition) {
6020 llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
6022 // If we don't need a definition, return the entry if found or check
6023 // if we use an external reference.
6024 if (!ForDefinition) {
6028 // If this type (or a super class) has the __objc_exception__
6029 // attribute, emit an external reference.
6030 if (hasObjCExceptionAttribute(CGM.getContext(), ID))
6032 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
6033 llvm::GlobalValue::ExternalLinkage,
6036 ID->getIdentifier()->getName()));
6039 // Otherwise we need to either make a new entry or fill in the
6041 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition");
6042 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
6043 std::string VTableName = "objc_ehtype_vtable";
6044 llvm::GlobalVariable *VTableGV =
6045 CGM.getModule().getGlobalVariable(VTableName);
6047 VTableGV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy,
6049 llvm::GlobalValue::ExternalLinkage,
6052 llvm::Value *VTableIdx =
6053 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 2);
6055 std::vector<llvm::Constant*> Values(3);
6056 Values[0] = llvm::ConstantExpr::getGetElementPtr(VTableGV, VTableIdx);
6057 Values[1] = GetClassName(ID->getIdentifier());
6058 Values[2] = GetClassGlobal(ClassName);
6059 llvm::Constant *Init =
6060 llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values);
6063 Entry->setInitializer(Init);
6065 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
6066 llvm::GlobalValue::WeakAnyLinkage,
6069 ID->getIdentifier()->getName()));
6072 if (CGM.getLangOptions().getVisibilityMode() == HiddenVisibility)
6073 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
6074 Entry->setAlignment(CGM.getTargetData().getABITypeAlignment(
6075 ObjCTypes.EHTypeTy));
6077 if (ForDefinition) {
6078 Entry->setSection("__DATA,__objc_const");
6079 Entry->setLinkage(llvm::GlobalValue::ExternalLinkage);
6081 Entry->setSection("__DATA,__datacoal_nt,coalesced");
6089 CodeGen::CGObjCRuntime *
6090 CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
6091 if (CGM.getLangOptions().ObjCNonFragileABI)
6092 return new CGObjCNonFragileABIMac(CGM);
6093 return new CGObjCMac(CGM);