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 const llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
67 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
72 /// void objc_msgSend_stret (id, SEL, ...)
74 /// The messenger used when the return value is an aggregate returned
75 /// by indirect reference in the first argument, and therefore the
76 /// self and selector parameters are shifted over by one.
77 llvm::Constant *getMessageSendStretFn() const {
78 const llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
79 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,
81 "objc_msgSend_stret");
85 /// [double | long double] objc_msgSend_fpret(id self, SEL op, ...)
87 /// The messenger used when the return value is returned on the x87
88 /// floating-point stack; without a special entrypoint, the nil case
89 /// would be unbalanced.
90 llvm::Constant *getMessageSendFpretFn() const {
91 const llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
92 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(
93 llvm::Type::getDoubleTy(VMContext),
95 "objc_msgSend_fpret");
99 /// id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
101 /// The messenger used for super calls, which have different dispatch
102 /// semantics. The class passed is the superclass of the current
104 llvm::Constant *getMessageSendSuperFn() const {
105 const llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
106 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
108 "objc_msgSendSuper");
111 /// id objc_msgSendSuper2(struct objc_super *super, SEL op, ...)
113 /// A slightly different messenger used for super calls. The class
114 /// passed is the current class.
115 llvm::Constant *getMessageSendSuperFn2() const {
116 const llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
117 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
119 "objc_msgSendSuper2");
122 /// void objc_msgSendSuper_stret(void *stretAddr, struct objc_super *super,
125 /// The messenger used for super calls which return an aggregate indirectly.
126 llvm::Constant *getMessageSendSuperStretFn() const {
127 const llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
128 return CGM.CreateRuntimeFunction(
129 llvm::FunctionType::get(CGM.VoidTy, params, true),
130 "objc_msgSendSuper_stret");
133 /// void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super,
136 /// objc_msgSendSuper_stret with the super2 semantics.
137 llvm::Constant *getMessageSendSuperStretFn2() const {
138 const llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
139 return CGM.CreateRuntimeFunction(
140 llvm::FunctionType::get(CGM.VoidTy, params, true),
141 "objc_msgSendSuper2_stret");
144 llvm::Constant *getMessageSendSuperFpretFn() const {
145 // There is no objc_msgSendSuper_fpret? How can that work?
146 return getMessageSendSuperFn();
149 llvm::Constant *getMessageSendSuperFpretFn2() const {
150 // There is no objc_msgSendSuper_fpret? How can that work?
151 return getMessageSendSuperFn2();
155 CodeGen::CodeGenModule &CGM;
158 const llvm::Type *ShortTy, *IntTy, *LongTy, *LongLongTy;
159 const llvm::Type *Int8PtrTy;
161 /// ObjectPtrTy - LLVM type for object handles (typeof(id))
162 const llvm::Type *ObjectPtrTy;
164 /// PtrObjectPtrTy - LLVM type for id *
165 const llvm::Type *PtrObjectPtrTy;
167 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
168 const llvm::Type *SelectorPtrTy;
169 /// ProtocolPtrTy - LLVM type for external protocol handles
170 /// (typeof(Protocol))
171 const llvm::Type *ExternalProtocolPtrTy;
173 // SuperCTy - clang type for struct objc_super.
175 // SuperPtrCTy - clang type for struct objc_super *.
176 QualType SuperPtrCTy;
178 /// SuperTy - LLVM type for struct objc_super.
179 const llvm::StructType *SuperTy;
180 /// SuperPtrTy - LLVM type for struct objc_super *.
181 const llvm::Type *SuperPtrTy;
183 /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
184 /// in GCC parlance).
185 const llvm::StructType *PropertyTy;
187 /// PropertyListTy - LLVM type for struct objc_property_list
188 /// (_prop_list_t in GCC parlance).
189 const llvm::StructType *PropertyListTy;
190 /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
191 const llvm::Type *PropertyListPtrTy;
193 // MethodTy - LLVM type for struct objc_method.
194 const llvm::StructType *MethodTy;
196 /// CacheTy - LLVM type for struct objc_cache.
197 const llvm::Type *CacheTy;
198 /// CachePtrTy - LLVM type for struct objc_cache *.
199 const llvm::Type *CachePtrTy;
201 llvm::Constant *getGetPropertyFn() {
202 CodeGen::CodeGenTypes &Types = CGM.getTypes();
203 ASTContext &Ctx = CGM.getContext();
204 // id objc_getProperty (id, SEL, ptrdiff_t, bool)
205 llvm::SmallVector<CanQualType,4> Params;
206 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
207 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
208 Params.push_back(IdType);
209 Params.push_back(SelType);
210 Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
211 Params.push_back(Ctx.BoolTy);
212 const llvm::FunctionType *FTy =
213 Types.GetFunctionType(Types.getFunctionInfo(IdType, Params,
214 FunctionType::ExtInfo()),
216 return CGM.CreateRuntimeFunction(FTy, "objc_getProperty");
219 llvm::Constant *getSetPropertyFn() {
220 CodeGen::CodeGenTypes &Types = CGM.getTypes();
221 ASTContext &Ctx = CGM.getContext();
222 // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool)
223 llvm::SmallVector<CanQualType,6> Params;
224 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
225 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
226 Params.push_back(IdType);
227 Params.push_back(SelType);
228 Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
229 Params.push_back(IdType);
230 Params.push_back(Ctx.BoolTy);
231 Params.push_back(Ctx.BoolTy);
232 const llvm::FunctionType *FTy =
233 Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
234 FunctionType::ExtInfo()),
236 return CGM.CreateRuntimeFunction(FTy, "objc_setProperty");
240 llvm::Constant *getCopyStructFn() {
241 CodeGen::CodeGenTypes &Types = CGM.getTypes();
242 ASTContext &Ctx = CGM.getContext();
243 // void objc_copyStruct (void *, const void *, size_t, bool, bool)
244 llvm::SmallVector<CanQualType,5> Params;
245 Params.push_back(Ctx.VoidPtrTy);
246 Params.push_back(Ctx.VoidPtrTy);
247 Params.push_back(Ctx.LongTy);
248 Params.push_back(Ctx.BoolTy);
249 Params.push_back(Ctx.BoolTy);
250 const llvm::FunctionType *FTy =
251 Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
252 FunctionType::ExtInfo()),
254 return CGM.CreateRuntimeFunction(FTy, "objc_copyStruct");
257 llvm::Constant *getEnumerationMutationFn() {
258 CodeGen::CodeGenTypes &Types = CGM.getTypes();
259 ASTContext &Ctx = CGM.getContext();
260 // void objc_enumerationMutation (id)
261 llvm::SmallVector<CanQualType,1> Params;
262 Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType()));
263 const llvm::FunctionType *FTy =
264 Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
265 FunctionType::ExtInfo()),
267 return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
270 /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function.
271 llvm::Constant *getGcReadWeakFn() {
272 // id objc_read_weak (id *)
273 const llvm::Type *args[] = { ObjectPtrTy->getPointerTo() };
274 llvm::FunctionType *FTy =
275 llvm::FunctionType::get(ObjectPtrTy, args, false);
276 return CGM.CreateRuntimeFunction(FTy, "objc_read_weak");
279 /// GcAssignWeakFn -- LLVM objc_assign_weak function.
280 llvm::Constant *getGcAssignWeakFn() {
281 // id objc_assign_weak (id, id *)
282 const llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
283 llvm::FunctionType *FTy =
284 llvm::FunctionType::get(ObjectPtrTy, args, false);
285 return CGM.CreateRuntimeFunction(FTy, "objc_assign_weak");
288 /// GcAssignGlobalFn -- LLVM objc_assign_global function.
289 llvm::Constant *getGcAssignGlobalFn() {
290 // id objc_assign_global(id, id *)
291 const llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
292 llvm::FunctionType *FTy =
293 llvm::FunctionType::get(ObjectPtrTy, args, false);
294 return CGM.CreateRuntimeFunction(FTy, "objc_assign_global");
297 /// GcAssignThreadLocalFn -- LLVM objc_assign_threadlocal function.
298 llvm::Constant *getGcAssignThreadLocalFn() {
299 // id objc_assign_threadlocal(id src, id * dest)
300 const llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
301 llvm::FunctionType *FTy =
302 llvm::FunctionType::get(ObjectPtrTy, args, false);
303 return CGM.CreateRuntimeFunction(FTy, "objc_assign_threadlocal");
306 /// GcAssignIvarFn -- LLVM objc_assign_ivar function.
307 llvm::Constant *getGcAssignIvarFn() {
308 // id objc_assign_ivar(id, id *, ptrdiff_t)
309 const llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo(),
311 llvm::FunctionType *FTy =
312 llvm::FunctionType::get(ObjectPtrTy, args, false);
313 return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar");
316 /// GcMemmoveCollectableFn -- LLVM objc_memmove_collectable function.
317 llvm::Constant *GcMemmoveCollectableFn() {
318 // void *objc_memmove_collectable(void *dst, const void *src, size_t size)
319 const llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy };
320 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args, false);
321 return CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable");
324 /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function.
325 llvm::Constant *getGcAssignStrongCastFn() {
326 // id objc_assign_strongCast(id, id *)
327 const llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
328 llvm::FunctionType *FTy =
329 llvm::FunctionType::get(ObjectPtrTy, args, false);
330 return CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast");
333 /// ExceptionThrowFn - LLVM objc_exception_throw function.
334 llvm::Constant *getExceptionThrowFn() {
335 // void objc_exception_throw(id)
336 const llvm::Type *args[] = { ObjectPtrTy };
337 llvm::FunctionType *FTy =
338 llvm::FunctionType::get(CGM.VoidTy, args, false);
339 return CGM.CreateRuntimeFunction(FTy, "objc_exception_throw");
342 /// ExceptionRethrowFn - LLVM objc_exception_rethrow function.
343 llvm::Constant *getExceptionRethrowFn() {
344 // void objc_exception_rethrow(void)
345 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, false);
346 return CGM.CreateRuntimeFunction(FTy, "objc_exception_rethrow");
349 /// SyncEnterFn - LLVM object_sync_enter function.
350 llvm::Constant *getSyncEnterFn() {
351 // void objc_sync_enter (id)
352 const llvm::Type *args[] = { ObjectPtrTy };
353 llvm::FunctionType *FTy =
354 llvm::FunctionType::get(CGM.VoidTy, args, false);
355 return CGM.CreateRuntimeFunction(FTy, "objc_sync_enter");
358 /// SyncExitFn - LLVM object_sync_exit function.
359 llvm::Constant *getSyncExitFn() {
360 // void objc_sync_exit (id)
361 const llvm::Type *args[] = { ObjectPtrTy };
362 llvm::FunctionType *FTy =
363 llvm::FunctionType::get(CGM.VoidTy, args, false);
364 return CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
367 llvm::Constant *getSendFn(bool IsSuper) const {
368 return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
371 llvm::Constant *getSendFn2(bool IsSuper) const {
372 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
375 llvm::Constant *getSendStretFn(bool IsSuper) const {
376 return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
379 llvm::Constant *getSendStretFn2(bool IsSuper) const {
380 return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
383 llvm::Constant *getSendFpretFn(bool IsSuper) const {
384 return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
387 llvm::Constant *getSendFpretFn2(bool IsSuper) const {
388 return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
391 ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm);
392 ~ObjCCommonTypesHelper(){}
395 /// ObjCTypesHelper - Helper class that encapsulates lazy
396 /// construction of varies types used during ObjC generation.
397 class ObjCTypesHelper : public ObjCCommonTypesHelper {
399 /// SymtabTy - LLVM type for struct objc_symtab.
400 const llvm::StructType *SymtabTy;
401 /// SymtabPtrTy - LLVM type for struct objc_symtab *.
402 const llvm::Type *SymtabPtrTy;
403 /// ModuleTy - LLVM type for struct objc_module.
404 const llvm::StructType *ModuleTy;
406 /// ProtocolTy - LLVM type for struct objc_protocol.
407 const llvm::StructType *ProtocolTy;
408 /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
409 const llvm::Type *ProtocolPtrTy;
410 /// ProtocolExtensionTy - LLVM type for struct
411 /// objc_protocol_extension.
412 const llvm::StructType *ProtocolExtensionTy;
413 /// ProtocolExtensionTy - LLVM type for struct
414 /// objc_protocol_extension *.
415 const llvm::Type *ProtocolExtensionPtrTy;
416 /// MethodDescriptionTy - LLVM type for struct
417 /// objc_method_description.
418 const llvm::StructType *MethodDescriptionTy;
419 /// MethodDescriptionListTy - LLVM type for struct
420 /// objc_method_description_list.
421 const llvm::StructType *MethodDescriptionListTy;
422 /// MethodDescriptionListPtrTy - LLVM type for struct
423 /// objc_method_description_list *.
424 const llvm::Type *MethodDescriptionListPtrTy;
425 /// ProtocolListTy - LLVM type for struct objc_property_list.
426 const llvm::Type *ProtocolListTy;
427 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
428 const llvm::Type *ProtocolListPtrTy;
429 /// CategoryTy - LLVM type for struct objc_category.
430 const llvm::StructType *CategoryTy;
431 /// ClassTy - LLVM type for struct objc_class.
432 const llvm::StructType *ClassTy;
433 /// ClassPtrTy - LLVM type for struct objc_class *.
434 const llvm::Type *ClassPtrTy;
435 /// ClassExtensionTy - LLVM type for struct objc_class_ext.
436 const llvm::StructType *ClassExtensionTy;
437 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
438 const llvm::Type *ClassExtensionPtrTy;
439 // IvarTy - LLVM type for struct objc_ivar.
440 const llvm::StructType *IvarTy;
441 /// IvarListTy - LLVM type for struct objc_ivar_list.
442 const llvm::Type *IvarListTy;
443 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
444 const llvm::Type *IvarListPtrTy;
445 /// MethodListTy - LLVM type for struct objc_method_list.
446 const llvm::Type *MethodListTy;
447 /// MethodListPtrTy - LLVM type for struct objc_method_list *.
448 const llvm::Type *MethodListPtrTy;
450 /// ExceptionDataTy - LLVM type for struct _objc_exception_data.
451 const llvm::Type *ExceptionDataTy;
453 /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.
454 llvm::Constant *getExceptionTryEnterFn() {
455 const llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
456 return CGM.CreateRuntimeFunction(
457 llvm::FunctionType::get(CGM.VoidTy, params, false),
458 "objc_exception_try_enter");
461 /// ExceptionTryExitFn - LLVM objc_exception_try_exit function.
462 llvm::Constant *getExceptionTryExitFn() {
463 const llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
464 return CGM.CreateRuntimeFunction(
465 llvm::FunctionType::get(CGM.VoidTy, params, false),
466 "objc_exception_try_exit");
469 /// ExceptionExtractFn - LLVM objc_exception_extract function.
470 llvm::Constant *getExceptionExtractFn() {
471 const llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
472 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
474 "objc_exception_extract");
477 /// ExceptionMatchFn - LLVM objc_exception_match function.
478 llvm::Constant *getExceptionMatchFn() {
479 const llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy };
480 return CGM.CreateRuntimeFunction(
481 llvm::FunctionType::get(CGM.Int32Ty, params, false),
482 "objc_exception_match");
486 /// SetJmpFn - LLVM _setjmp function.
487 llvm::Constant *getSetJmpFn() {
488 // This is specifically the prototype for x86.
489 const llvm::Type *params[] = { CGM.Int32Ty->getPointerTo() };
490 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty,
496 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
497 ~ObjCTypesHelper() {}
500 /// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's
502 class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {
505 // MethodListnfABITy - LLVM for struct _method_list_t
506 const llvm::StructType *MethodListnfABITy;
508 // MethodListnfABIPtrTy - LLVM for struct _method_list_t*
509 const llvm::Type *MethodListnfABIPtrTy;
511 // ProtocolnfABITy = LLVM for struct _protocol_t
512 const llvm::StructType *ProtocolnfABITy;
514 // ProtocolnfABIPtrTy = LLVM for struct _protocol_t*
515 const llvm::Type *ProtocolnfABIPtrTy;
517 // ProtocolListnfABITy - LLVM for struct _objc_protocol_list
518 const llvm::StructType *ProtocolListnfABITy;
520 // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list*
521 const llvm::Type *ProtocolListnfABIPtrTy;
523 // ClassnfABITy - LLVM for struct _class_t
524 const llvm::StructType *ClassnfABITy;
526 // ClassnfABIPtrTy - LLVM for struct _class_t*
527 const llvm::Type *ClassnfABIPtrTy;
529 // IvarnfABITy - LLVM for struct _ivar_t
530 const llvm::StructType *IvarnfABITy;
532 // IvarListnfABITy - LLVM for struct _ivar_list_t
533 const llvm::StructType *IvarListnfABITy;
535 // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t*
536 const llvm::Type *IvarListnfABIPtrTy;
538 // ClassRonfABITy - LLVM for struct _class_ro_t
539 const llvm::StructType *ClassRonfABITy;
541 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
542 const llvm::Type *ImpnfABITy;
544 // CategorynfABITy - LLVM for struct _category_t
545 const llvm::StructType *CategorynfABITy;
547 // New types for nonfragile abi messaging.
549 // MessageRefTy - LLVM for:
550 // struct _message_ref_t {
554 const llvm::StructType *MessageRefTy;
555 // MessageRefCTy - clang type for struct _message_ref_t
556 QualType MessageRefCTy;
558 // MessageRefPtrTy - LLVM for struct _message_ref_t*
559 const llvm::Type *MessageRefPtrTy;
560 // MessageRefCPtrTy - clang type for struct _message_ref_t*
561 QualType MessageRefCPtrTy;
563 // MessengerTy - Type of the messenger (shown as IMP above)
564 const llvm::FunctionType *MessengerTy;
566 // SuperMessageRefTy - LLVM for:
567 // struct _super_message_ref_t {
568 // SUPER_IMP messenger;
571 const llvm::StructType *SuperMessageRefTy;
573 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
574 const llvm::Type *SuperMessageRefPtrTy;
576 llvm::Constant *getMessageSendFixupFn() {
577 // id objc_msgSend_fixup(id, struct message_ref_t*, ...)
578 const llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
579 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
581 "objc_msgSend_fixup");
584 llvm::Constant *getMessageSendFpretFixupFn() {
585 // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...)
586 const llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
587 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
589 "objc_msgSend_fpret_fixup");
592 llvm::Constant *getMessageSendStretFixupFn() {
593 // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...)
594 const llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
595 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
597 "objc_msgSend_stret_fixup");
600 llvm::Constant *getMessageSendSuper2FixupFn() {
601 // id objc_msgSendSuper2_fixup (struct objc_super *,
602 // struct _super_message_ref_t*, ...)
603 const llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
604 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
606 "objc_msgSendSuper2_fixup");
609 llvm::Constant *getMessageSendSuper2StretFixupFn() {
610 // id objc_msgSendSuper2_stret_fixup(struct objc_super *,
611 // struct _super_message_ref_t*, ...)
612 const llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
613 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
615 "objc_msgSendSuper2_stret_fixup");
618 llvm::Constant *getObjCEndCatchFn() {
619 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy, false),
624 llvm::Constant *getObjCBeginCatchFn() {
625 const llvm::Type *params[] = { Int8PtrTy };
626 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy,
631 const llvm::StructType *EHTypeTy;
632 const llvm::Type *EHTypePtrTy;
634 ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
635 ~ObjCNonFragileABITypesHelper(){}
638 class CGObjCCommonMac : public CodeGen::CGObjCRuntime {
640 // FIXME - accessibility
643 unsigned ivar_bytepos;
645 GC_IVAR(unsigned bytepos = 0, unsigned size = 0)
646 : ivar_bytepos(bytepos), ivar_size(size) {}
648 // Allow sorting based on byte pos.
649 bool operator<(const GC_IVAR &b) const {
650 return ivar_bytepos < b.ivar_bytepos;
658 SKIP_SCAN(unsigned _skip = 0, unsigned _scan = 0)
659 : skip(_skip), scan(_scan) {}
663 CodeGen::CodeGenModule &CGM;
664 llvm::LLVMContext &VMContext;
665 // FIXME! May not be needing this after all.
668 // gc ivar layout bitmap calculation helper caches.
669 llvm::SmallVector<GC_IVAR, 16> SkipIvars;
670 llvm::SmallVector<GC_IVAR, 16> IvarsInfo;
672 /// LazySymbols - Symbols to generate a lazy reference for. See
673 /// DefinedSymbols and FinishModule().
674 llvm::SetVector<IdentifierInfo*> LazySymbols;
676 /// DefinedSymbols - External symbols which are defined by this
677 /// module. The symbols in this list and LazySymbols are used to add
678 /// special linker symbols which ensure that Objective-C modules are
680 llvm::SetVector<IdentifierInfo*> DefinedSymbols;
682 /// ClassNames - uniqued class names.
683 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
685 /// MethodVarNames - uniqued method variable names.
686 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
688 /// DefinedCategoryNames - list of category names in form Class_Category.
689 llvm::SetVector<std::string> DefinedCategoryNames;
691 /// MethodVarTypes - uniqued method type signatures. We have to use
692 /// a StringMap here because have no other unique reference.
693 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
695 /// MethodDefinitions - map of methods which have been defined in
696 /// this translation unit.
697 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
699 /// PropertyNames - uniqued method variable names.
700 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
702 /// ClassReferences - uniqued class references.
703 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
705 /// SelectorReferences - uniqued selector references.
706 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
708 /// Protocols - Protocols for which an objc_protocol structure has
709 /// been emitted. Forward declarations are handled by creating an
710 /// empty structure whose initializer is filled in when/if defined.
711 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
713 /// DefinedProtocols - Protocols which have actually been
714 /// defined. We should not need this, see FIXME in GenerateProtocol.
715 llvm::DenseSet<IdentifierInfo*> DefinedProtocols;
717 /// DefinedClasses - List of defined classes.
718 std::vector<llvm::GlobalValue*> DefinedClasses;
720 /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
721 std::vector<llvm::GlobalValue*> DefinedNonLazyClasses;
723 /// DefinedCategories - List of defined categories.
724 std::vector<llvm::GlobalValue*> DefinedCategories;
726 /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
727 std::vector<llvm::GlobalValue*> DefinedNonLazyCategories;
729 /// GetNameForMethod - Return a name for the given method.
730 /// \param[out] NameOut - The return value.
731 void GetNameForMethod(const ObjCMethodDecl *OMD,
732 const ObjCContainerDecl *CD,
733 llvm::SmallVectorImpl<char> &NameOut);
735 /// GetMethodVarName - Return a unique constant for the given
736 /// selector's name. The return value has type char *.
737 llvm::Constant *GetMethodVarName(Selector Sel);
738 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
740 /// GetMethodVarType - Return a unique constant for the given
741 /// selector's name. The return value has type char *.
743 // FIXME: This is a horrible name.
744 llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D);
745 llvm::Constant *GetMethodVarType(const FieldDecl *D);
747 /// GetPropertyName - Return a unique constant for the given
748 /// name. The return value has type char *.
749 llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
751 // FIXME: This can be dropped once string functions are unified.
752 llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,
753 const Decl *Container);
755 /// GetClassName - Return a unique constant for the given selector's
756 /// name. The return value has type char *.
757 llvm::Constant *GetClassName(IdentifierInfo *Ident);
759 llvm::Function *GetMethodDefinition(const ObjCMethodDecl *MD);
761 /// BuildIvarLayout - Builds ivar layout bitmap for the class
762 /// implementation for the __strong or __weak case.
764 llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI,
765 bool ForStrongLayout);
767 llvm::Constant *BuildIvarLayoutBitmap(std::string &BitMap);
769 void BuildAggrIvarRecordLayout(const RecordType *RT,
770 unsigned int BytePos, bool ForStrongLayout,
772 void BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
773 const llvm::StructLayout *Layout,
774 const RecordDecl *RD,
775 const llvm::SmallVectorImpl<FieldDecl*> &RecFields,
776 unsigned int BytePos, bool ForStrongLayout,
779 /// GetIvarLayoutName - Returns a unique constant for the given
780 /// ivar layout bitmap.
781 llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident,
782 const ObjCCommonTypesHelper &ObjCTypes);
784 /// EmitPropertyList - Emit the given property list. The return
785 /// value has type PropertyListPtrTy.
786 llvm::Constant *EmitPropertyList(llvm::Twine Name,
787 const Decl *Container,
788 const ObjCContainerDecl *OCD,
789 const ObjCCommonTypesHelper &ObjCTypes);
791 /// PushProtocolProperties - Push protocol's property on the input stack.
792 void PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet,
793 std::vector<llvm::Constant*> &Properties,
794 const Decl *Container,
795 const ObjCProtocolDecl *PROTO,
796 const ObjCCommonTypesHelper &ObjCTypes);
798 /// GetProtocolRef - Return a reference to the internal protocol
799 /// description, creating an empty one if it has not been
800 /// defined. The return value has type ProtocolPtrTy.
801 llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD);
803 /// CreateMetadataVar - Create a global variable with internal
804 /// linkage for use by the Objective-C runtime.
806 /// This is a convenience wrapper which not only creates the
807 /// variable, but also sets the section and alignment and adds the
808 /// global to the "llvm.used" list.
810 /// \param Name - The variable name.
811 /// \param Init - The variable initializer; this is also used to
812 /// define the type of the variable.
813 /// \param Section - The section the variable should go into, or 0.
814 /// \param Align - The alignment for the variable, or 0.
815 /// \param AddToUsed - Whether the variable should be added to
817 llvm::GlobalVariable *CreateMetadataVar(llvm::Twine Name,
818 llvm::Constant *Init,
823 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
824 ReturnValueSlot Return,
830 const CallArgList &CallArgs,
831 const ObjCMethodDecl *OMD,
832 const ObjCCommonTypesHelper &ObjCTypes);
834 /// EmitImageInfo - Emit the image info marker used to encode some module
835 /// level information.
836 void EmitImageInfo();
839 CGObjCCommonMac(CodeGen::CodeGenModule &cgm) :
840 CGM(cgm), VMContext(cgm.getLLVMContext()) { }
842 virtual llvm::Constant *GenerateConstantString(const StringLiteral *SL);
844 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
845 const ObjCContainerDecl *CD=0);
847 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
849 /// GetOrEmitProtocol - Get the protocol object for the given
850 /// declaration, emitting it if necessary. The return value has type
852 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0;
854 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
855 /// object for the given declaration, emitting it if needed. These
856 /// forward references will be filled in with empty bodies if no
857 /// definition is seen. The return value has type ProtocolPtrTy.
858 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0;
859 virtual llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
860 const CGBlockInfo &blockInfo);
864 class CGObjCMac : public CGObjCCommonMac {
866 ObjCTypesHelper ObjCTypes;
868 /// EmitModuleInfo - Another marker encoding module level
870 void EmitModuleInfo();
872 /// EmitModuleSymols - Emit module symbols, the list of defined
873 /// classes and categories. The result has type SymtabPtrTy.
874 llvm::Constant *EmitModuleSymbols();
876 /// FinishModule - Write out global data structures at the end of
877 /// processing a translation unit.
880 /// EmitClassExtension - Generate the class extension structure used
881 /// to store the weak ivar layout and properties. The return value
882 /// has type ClassExtensionPtrTy.
883 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
885 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
886 /// for the given class.
887 llvm::Value *EmitClassRef(CGBuilderTy &Builder,
888 const ObjCInterfaceDecl *ID);
890 /// EmitSuperClassRef - Emits reference to class's main metadata class.
891 llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID);
893 /// EmitIvarList - Emit the ivar list for the given
894 /// implementation. If ForClass is true the list of class ivars
895 /// (i.e. metaclass ivars) is emitted, otherwise the list of
896 /// interface ivars will be emitted. The return value has type
898 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
901 /// EmitMetaClass - Emit a forward reference to the class structure
902 /// for the metaclass of the given interface. The return value has
904 llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID);
906 /// EmitMetaClass - Emit a class structure for the metaclass of the
907 /// given implementation. The return value has type ClassPtrTy.
908 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
909 llvm::Constant *Protocols,
910 const ConstantVector &Methods);
912 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
914 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
916 /// EmitMethodList - Emit the method list for the given
917 /// implementation. The return value has type MethodListPtrTy.
918 llvm::Constant *EmitMethodList(llvm::Twine Name,
920 const ConstantVector &Methods);
922 /// EmitMethodDescList - Emit a method description list for a list of
923 /// method declarations.
924 /// - TypeName: The name for the type containing the methods.
925 /// - IsProtocol: True iff these methods are for a protocol.
926 /// - ClassMethds: True iff these are class methods.
927 /// - Required: When true, only "required" methods are
928 /// listed. Similarly, when false only "optional" methods are
929 /// listed. For classes this should always be true.
930 /// - begin, end: The method list to output.
932 /// The return value has type MethodDescriptionListPtrTy.
933 llvm::Constant *EmitMethodDescList(llvm::Twine Name,
935 const ConstantVector &Methods);
937 /// GetOrEmitProtocol - Get the protocol object for the given
938 /// declaration, emitting it if necessary. The return value has type
940 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
942 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
943 /// object for the given declaration, emitting it if needed. These
944 /// forward references will be filled in with empty bodies if no
945 /// definition is seen. The return value has type ProtocolPtrTy.
946 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
948 /// EmitProtocolExtension - Generate the protocol extension
949 /// structure used to store optional instance and class methods, and
950 /// protocol properties. The return value has type
951 /// ProtocolExtensionPtrTy.
953 EmitProtocolExtension(const ObjCProtocolDecl *PD,
954 const ConstantVector &OptInstanceMethods,
955 const ConstantVector &OptClassMethods);
957 /// EmitProtocolList - Generate the list of referenced
958 /// protocols. The return value has type ProtocolListPtrTy.
959 llvm::Constant *EmitProtocolList(llvm::Twine Name,
960 ObjCProtocolDecl::protocol_iterator begin,
961 ObjCProtocolDecl::protocol_iterator end);
963 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
964 /// for the given selector.
965 llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel,
969 CGObjCMac(CodeGen::CodeGenModule &cgm);
971 virtual llvm::Function *ModuleInitFunction();
973 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
974 ReturnValueSlot Return,
977 llvm::Value *Receiver,
978 const CallArgList &CallArgs,
979 const ObjCInterfaceDecl *Class,
980 const ObjCMethodDecl *Method);
982 virtual CodeGen::RValue
983 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
984 ReturnValueSlot Return,
987 const ObjCInterfaceDecl *Class,
989 llvm::Value *Receiver,
991 const CallArgList &CallArgs,
992 const ObjCMethodDecl *Method);
994 virtual llvm::Value *GetClass(CGBuilderTy &Builder,
995 const ObjCInterfaceDecl *ID);
997 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel,
1000 /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1002 virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
1003 const ObjCMethodDecl *Method);
1005 virtual llvm::Constant *GetEHType(QualType T);
1007 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
1009 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
1011 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
1012 const ObjCProtocolDecl *PD);
1014 virtual llvm::Constant *GetPropertyGetFunction();
1015 virtual llvm::Constant *GetPropertySetFunction();
1016 virtual llvm::Constant *GetGetStructFunction();
1017 virtual llvm::Constant *GetSetStructFunction();
1018 virtual llvm::Constant *EnumerationMutationFunction();
1020 virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1021 const ObjCAtTryStmt &S);
1022 virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1023 const ObjCAtSynchronizedStmt &S);
1024 void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const Stmt &S);
1025 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
1026 const ObjCAtThrowStmt &S);
1027 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1028 llvm::Value *AddrWeakObj);
1029 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1030 llvm::Value *src, llvm::Value *dst);
1031 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1032 llvm::Value *src, llvm::Value *dest,
1033 bool threadlocal = false);
1034 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
1035 llvm::Value *src, llvm::Value *dest,
1036 llvm::Value *ivarOffset);
1037 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
1038 llvm::Value *src, llvm::Value *dest);
1039 virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1040 llvm::Value *dest, llvm::Value *src,
1043 virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
1045 llvm::Value *BaseValue,
1046 const ObjCIvarDecl *Ivar,
1047 unsigned CVRQualifiers);
1048 virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1049 const ObjCInterfaceDecl *Interface,
1050 const ObjCIvarDecl *Ivar);
1052 /// GetClassGlobal - Return the global variable for the Objective-C
1053 /// class of the given name.
1054 virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) {
1055 assert(false && "CGObjCMac::GetClassGlobal");
1060 class CGObjCNonFragileABIMac : public CGObjCCommonMac {
1062 ObjCNonFragileABITypesHelper ObjCTypes;
1063 llvm::GlobalVariable* ObjCEmptyCacheVar;
1064 llvm::GlobalVariable* ObjCEmptyVtableVar;
1066 /// SuperClassReferences - uniqued super class references.
1067 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
1069 /// MetaClassReferences - uniqued meta class references.
1070 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
1072 /// EHTypeReferences - uniqued class ehtype references.
1073 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
1075 /// VTableDispatchMethods - List of methods for which we generate
1076 /// vtable-based message dispatch.
1077 llvm::DenseSet<Selector> VTableDispatchMethods;
1079 /// DefinedMetaClasses - List of defined meta-classes.
1080 std::vector<llvm::GlobalValue*> DefinedMetaClasses;
1082 /// isVTableDispatchedSelector - Returns true if SEL is a
1083 /// vtable-based selector.
1084 bool isVTableDispatchedSelector(Selector Sel);
1086 /// FinishNonFragileABIModule - Write out global data structures at the end of
1087 /// processing a translation unit.
1088 void FinishNonFragileABIModule();
1090 /// AddModuleClassList - Add the given list of class pointers to the
1091 /// module with the provided symbol and section names.
1092 void AddModuleClassList(const std::vector<llvm::GlobalValue*> &Container,
1093 const char *SymbolName,
1094 const char *SectionName);
1096 llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags,
1097 unsigned InstanceStart,
1098 unsigned InstanceSize,
1099 const ObjCImplementationDecl *ID);
1100 llvm::GlobalVariable * BuildClassMetaData(std::string &ClassName,
1101 llvm::Constant *IsAGV,
1102 llvm::Constant *SuperClassGV,
1103 llvm::Constant *ClassRoGV,
1104 bool HiddenVisibility);
1106 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
1108 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
1110 /// EmitMethodList - Emit the method list for the given
1111 /// implementation. The return value has type MethodListnfABITy.
1112 llvm::Constant *EmitMethodList(llvm::Twine Name,
1113 const char *Section,
1114 const ConstantVector &Methods);
1115 /// EmitIvarList - Emit the ivar list for the given
1116 /// implementation. If ForClass is true the list of class ivars
1117 /// (i.e. metaclass ivars) is emitted, otherwise the list of
1118 /// interface ivars will be emitted. The return value has type
1119 /// IvarListnfABIPtrTy.
1120 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID);
1122 llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
1123 const ObjCIvarDecl *Ivar,
1124 unsigned long int offset);
1126 /// GetOrEmitProtocol - Get the protocol object for the given
1127 /// declaration, emitting it if necessary. The return value has type
1129 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
1131 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1132 /// object for the given declaration, emitting it if needed. These
1133 /// forward references will be filled in with empty bodies if no
1134 /// definition is seen. The return value has type ProtocolPtrTy.
1135 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
1137 /// EmitProtocolList - Generate the list of referenced
1138 /// protocols. The return value has type ProtocolListPtrTy.
1139 llvm::Constant *EmitProtocolList(llvm::Twine Name,
1140 ObjCProtocolDecl::protocol_iterator begin,
1141 ObjCProtocolDecl::protocol_iterator end);
1143 CodeGen::RValue EmitVTableMessageSend(CodeGen::CodeGenFunction &CGF,
1144 ReturnValueSlot Return,
1145 QualType ResultType,
1147 llvm::Value *Receiver,
1150 const CallArgList &CallArgs,
1151 const ObjCMethodDecl *Method);
1153 /// GetClassGlobal - Return the global variable for the Objective-C
1154 /// class of the given name.
1155 llvm::GlobalVariable *GetClassGlobal(const std::string &Name);
1157 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1158 /// for the given class reference.
1159 llvm::Value *EmitClassRef(CGBuilderTy &Builder,
1160 const ObjCInterfaceDecl *ID);
1162 /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1163 /// for the given super class reference.
1164 llvm::Value *EmitSuperClassRef(CGBuilderTy &Builder,
1165 const ObjCInterfaceDecl *ID);
1167 /// EmitMetaClassRef - Return a Value * of the address of _class_t
1169 llvm::Value *EmitMetaClassRef(CGBuilderTy &Builder,
1170 const ObjCInterfaceDecl *ID);
1172 /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
1175 llvm::GlobalVariable * ObjCIvarOffsetVariable(
1176 const ObjCInterfaceDecl *ID,
1177 const ObjCIvarDecl *Ivar);
1179 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
1180 /// for the given selector.
1181 llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel,
1184 /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C
1185 /// interface. The return value has type EHTypePtrTy.
1186 llvm::Constant *GetInterfaceEHType(const ObjCInterfaceDecl *ID,
1187 bool ForDefinition);
1189 const char *getMetaclassSymbolPrefix() const {
1190 return "OBJC_METACLASS_$_";
1193 const char *getClassSymbolPrefix() const {
1194 return "OBJC_CLASS_$_";
1197 void GetClassSizeInfo(const ObjCImplementationDecl *OID,
1198 uint32_t &InstanceStart,
1199 uint32_t &InstanceSize);
1201 // Shamelessly stolen from Analysis/CFRefCount.cpp
1202 Selector GetNullarySelector(const char* name) const {
1203 IdentifierInfo* II = &CGM.getContext().Idents.get(name);
1204 return CGM.getContext().Selectors.getSelector(0, &II);
1207 Selector GetUnarySelector(const char* name) const {
1208 IdentifierInfo* II = &CGM.getContext().Idents.get(name);
1209 return CGM.getContext().Selectors.getSelector(1, &II);
1212 /// ImplementationIsNonLazy - Check whether the given category or
1213 /// class implementation is "non-lazy".
1214 bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const;
1217 CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
1218 // FIXME. All stubs for now!
1219 virtual llvm::Function *ModuleInitFunction();
1221 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1222 ReturnValueSlot Return,
1223 QualType ResultType,
1225 llvm::Value *Receiver,
1226 const CallArgList &CallArgs,
1227 const ObjCInterfaceDecl *Class,
1228 const ObjCMethodDecl *Method);
1230 virtual CodeGen::RValue
1231 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1232 ReturnValueSlot Return,
1233 QualType ResultType,
1235 const ObjCInterfaceDecl *Class,
1236 bool isCategoryImpl,
1237 llvm::Value *Receiver,
1238 bool IsClassMessage,
1239 const CallArgList &CallArgs,
1240 const ObjCMethodDecl *Method);
1242 virtual llvm::Value *GetClass(CGBuilderTy &Builder,
1243 const ObjCInterfaceDecl *ID);
1245 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel,
1246 bool lvalue = false)
1247 { return EmitSelector(Builder, Sel, lvalue); }
1249 /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1251 virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
1252 const ObjCMethodDecl *Method)
1253 { return EmitSelector(Builder, Method->getSelector()); }
1255 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
1257 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
1258 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
1259 const ObjCProtocolDecl *PD);
1261 virtual llvm::Constant *GetEHType(QualType T);
1263 virtual llvm::Constant *GetPropertyGetFunction() {
1264 return ObjCTypes.getGetPropertyFn();
1266 virtual llvm::Constant *GetPropertySetFunction() {
1267 return ObjCTypes.getSetPropertyFn();
1270 virtual llvm::Constant *GetSetStructFunction() {
1271 return ObjCTypes.getCopyStructFn();
1273 virtual llvm::Constant *GetGetStructFunction() {
1274 return ObjCTypes.getCopyStructFn();
1277 virtual llvm::Constant *EnumerationMutationFunction() {
1278 return ObjCTypes.getEnumerationMutationFn();
1281 virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1282 const ObjCAtTryStmt &S);
1283 virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1284 const ObjCAtSynchronizedStmt &S);
1285 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
1286 const ObjCAtThrowStmt &S);
1287 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1288 llvm::Value *AddrWeakObj);
1289 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1290 llvm::Value *src, llvm::Value *dst);
1291 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1292 llvm::Value *src, llvm::Value *dest,
1293 bool threadlocal = false);
1294 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
1295 llvm::Value *src, llvm::Value *dest,
1296 llvm::Value *ivarOffset);
1297 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
1298 llvm::Value *src, llvm::Value *dest);
1299 virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1300 llvm::Value *dest, llvm::Value *src,
1302 virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
1304 llvm::Value *BaseValue,
1305 const ObjCIvarDecl *Ivar,
1306 unsigned CVRQualifiers);
1307 virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1308 const ObjCInterfaceDecl *Interface,
1309 const ObjCIvarDecl *Ivar);
1312 /// A helper class for performing the null-initialization of a return
1314 struct NullReturnState {
1315 llvm::BasicBlock *NullBB;
1317 NullReturnState() : NullBB(0) {}
1319 void init(CodeGenFunction &CGF, llvm::Value *receiver) {
1320 // Make blocks for the null-init and call edges.
1321 NullBB = CGF.createBasicBlock("msgSend.nullinit");
1322 llvm::BasicBlock *callBB = CGF.createBasicBlock("msgSend.call");
1324 // Check for a null receiver and, if there is one, jump to the
1326 llvm::Value *isNull = CGF.Builder.CreateIsNull(receiver);
1327 CGF.Builder.CreateCondBr(isNull, NullBB, callBB);
1329 // Otherwise, start performing the call.
1330 CGF.EmitBlock(callBB);
1333 RValue complete(CodeGenFunction &CGF, RValue result, QualType resultType) {
1334 if (!NullBB) return result;
1336 // Finish the call path.
1337 llvm::BasicBlock *contBB = CGF.createBasicBlock("msgSend.cont");
1338 if (CGF.HaveInsertPoint()) CGF.Builder.CreateBr(contBB);
1340 // Emit the null-init block and perform the null-initialization there.
1341 CGF.EmitBlock(NullBB);
1342 assert(result.isAggregate() && "null init of non-aggregate result?");
1343 CGF.EmitNullInitialization(result.getAggregateAddr(), resultType);
1345 // Jump to the continuation block.
1346 CGF.EmitBlock(contBB);
1352 } // end anonymous namespace
1354 /* *** Helper Functions *** */
1356 /// getConstantGEP() - Help routine to construct simple GEPs.
1357 static llvm::Constant *getConstantGEP(llvm::LLVMContext &VMContext,
1361 llvm::Value *Idxs[] = {
1362 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1363 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
1365 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
1368 /// hasObjCExceptionAttribute - Return true if this class or any super
1369 /// class has the __objc_exception__ attribute.
1370 static bool hasObjCExceptionAttribute(ASTContext &Context,
1371 const ObjCInterfaceDecl *OID) {
1372 if (OID->hasAttr<ObjCExceptionAttr>())
1374 if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
1375 return hasObjCExceptionAttribute(Context, Super);
1379 /* *** CGObjCMac Public Interface *** */
1381 CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm),
1387 /// GetClass - Return a reference to the class for the given interface
1389 llvm::Value *CGObjCMac::GetClass(CGBuilderTy &Builder,
1390 const ObjCInterfaceDecl *ID) {
1391 return EmitClassRef(Builder, ID);
1394 /// GetSelector - Return the pointer to the unique'd string for this selector.
1395 llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, Selector Sel,
1397 return EmitSelector(Builder, Sel, lval);
1399 llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
1401 return EmitSelector(Builder, Method->getSelector());
1404 llvm::Constant *CGObjCMac::GetEHType(QualType T) {
1405 llvm_unreachable("asking for catch type for ObjC type in fragile runtime");
1409 /// Generate a constant CFString object.
1411 struct __builtin_CFString {
1412 const int *isa; // point to __CFConstantStringClassReference
1419 /// or Generate a constant NSString object.
1421 struct __builtin_NSString {
1422 const int *isa; // point to __NSConstantStringClassReference
1424 unsigned int length;
1428 llvm::Constant *CGObjCCommonMac::GenerateConstantString(
1429 const StringLiteral *SL) {
1430 return (CGM.getLangOptions().NoConstantCFStrings == 0 ?
1431 CGM.GetAddrOfConstantCFString(SL) :
1432 CGM.GetAddrOfConstantString(SL));
1435 /// Generates a message send where the super is the receiver. This is
1436 /// a message send to self with special delivery semantics indicating
1437 /// which class's method should be called.
1439 CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1440 ReturnValueSlot Return,
1441 QualType ResultType,
1443 const ObjCInterfaceDecl *Class,
1444 bool isCategoryImpl,
1445 llvm::Value *Receiver,
1446 bool IsClassMessage,
1447 const CodeGen::CallArgList &CallArgs,
1448 const ObjCMethodDecl *Method) {
1449 // Create and init a super structure; this is a (receiver, class)
1450 // pair we will pass to objc_msgSendSuper.
1451 llvm::Value *ObjCSuper =
1452 CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super");
1453 llvm::Value *ReceiverAsObject =
1454 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
1455 CGF.Builder.CreateStore(ReceiverAsObject,
1456 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
1458 // If this is a class message the metaclass is passed as the target.
1459 llvm::Value *Target;
1460 if (IsClassMessage) {
1461 if (isCategoryImpl) {
1462 // Message sent to 'super' in a class method defined in a category
1463 // implementation requires an odd treatment.
1464 // If we are in a class method, we must retrieve the
1465 // _metaclass_ for the current class, pointed at by
1466 // the class's "isa" pointer. The following assumes that
1467 // isa" is the first ivar in a class (which it must be).
1468 Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
1469 Target = CGF.Builder.CreateStructGEP(Target, 0);
1470 Target = CGF.Builder.CreateLoad(Target);
1472 llvm::Value *MetaClassPtr = EmitMetaClassRef(Class);
1473 llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1);
1474 llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr);
1478 else if (isCategoryImpl)
1479 Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
1481 llvm::Value *ClassPtr = EmitSuperClassRef(Class);
1482 ClassPtr = CGF.Builder.CreateStructGEP(ClassPtr, 1);
1483 Target = CGF.Builder.CreateLoad(ClassPtr);
1485 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
1487 const llvm::Type *ClassTy =
1488 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
1489 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
1490 CGF.Builder.CreateStore(Target,
1491 CGF.Builder.CreateStructGEP(ObjCSuper, 1));
1492 return EmitMessageSend(CGF, Return, ResultType,
1493 EmitSelector(CGF.Builder, Sel),
1494 ObjCSuper, ObjCTypes.SuperPtrCTy,
1495 true, CallArgs, Method, ObjCTypes);
1498 /// Generate code for a message send expression.
1499 CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1500 ReturnValueSlot Return,
1501 QualType ResultType,
1503 llvm::Value *Receiver,
1504 const CallArgList &CallArgs,
1505 const ObjCInterfaceDecl *Class,
1506 const ObjCMethodDecl *Method) {
1507 return EmitMessageSend(CGF, Return, ResultType,
1508 EmitSelector(CGF.Builder, Sel),
1509 Receiver, CGF.getContext().getObjCIdType(),
1510 false, CallArgs, Method, ObjCTypes);
1514 CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
1515 ReturnValueSlot Return,
1516 QualType ResultType,
1521 const CallArgList &CallArgs,
1522 const ObjCMethodDecl *Method,
1523 const ObjCCommonTypesHelper &ObjCTypes) {
1524 CallArgList ActualArgs;
1526 Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy, "tmp");
1527 ActualArgs.add(RValue::get(Arg0), Arg0Ty);
1528 ActualArgs.add(RValue::get(Sel), CGF.getContext().getObjCSelType());
1529 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
1531 CodeGenTypes &Types = CGM.getTypes();
1532 const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs,
1533 FunctionType::ExtInfo());
1534 const llvm::FunctionType *FTy =
1535 Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false);
1538 assert(CGM.getContext().getCanonicalType(Method->getResultType()) ==
1539 CGM.getContext().getCanonicalType(ResultType) &&
1540 "Result type mismatch!");
1542 NullReturnState nullReturn;
1544 llvm::Constant *Fn = NULL;
1545 if (CGM.ReturnTypeUsesSRet(FnInfo)) {
1546 if (!IsSuper) nullReturn.init(CGF, Arg0);
1547 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
1548 : ObjCTypes.getSendStretFn(IsSuper);
1549 } else if (CGM.ReturnTypeUsesFPRet(ResultType)) {
1550 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
1551 : ObjCTypes.getSendFpretFn(IsSuper);
1553 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
1554 : ObjCTypes.getSendFn(IsSuper);
1556 Fn = llvm::ConstantExpr::getBitCast(Fn, llvm::PointerType::getUnqual(FTy));
1557 RValue rvalue = CGF.EmitCall(FnInfo, Fn, Return, ActualArgs);
1558 return nullReturn.complete(CGF, rvalue, ResultType);
1561 static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT) {
1562 if (FQT.isObjCGCStrong())
1563 return Qualifiers::Strong;
1565 if (FQT.isObjCGCWeak())
1566 return Qualifiers::Weak;
1568 if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
1569 return Qualifiers::Strong;
1571 if (const PointerType *PT = FQT->getAs<PointerType>())
1572 return GetGCAttrTypeForType(Ctx, PT->getPointeeType());
1574 return Qualifiers::GCNone;
1577 llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
1578 const CGBlockInfo &blockInfo) {
1579 llvm::Constant *nullPtr =
1580 llvm::Constant::getNullValue(llvm::Type::getInt8PtrTy(VMContext));
1582 if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC)
1585 bool hasUnion = false;
1588 unsigned WordSizeInBits = CGM.getContext().Target.getPointerWidth(0);
1589 unsigned ByteSizeInBits = CGM.getContext().Target.getCharWidth();
1591 // __isa is the first field in block descriptor and must assume by runtime's
1592 // convention that it is GC'able.
1593 IvarsInfo.push_back(GC_IVAR(0, 1));
1595 const BlockDecl *blockDecl = blockInfo.getBlockDecl();
1597 // Calculate the basic layout of the block structure.
1598 const llvm::StructLayout *layout =
1599 CGM.getTargetData().getStructLayout(blockInfo.StructureType);
1601 // Ignore the optional 'this' capture: C++ objects are not assumed
1604 // Walk the captured variables.
1605 for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(),
1606 ce = blockDecl->capture_end(); ci != ce; ++ci) {
1607 const VarDecl *variable = ci->getVariable();
1608 QualType type = variable->getType();
1610 const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
1612 // Ignore constant captures.
1613 if (capture.isConstant()) continue;
1615 uint64_t fieldOffset = layout->getElementOffset(capture.getIndex());
1617 // __block variables are passed by their descriptor address.
1618 if (ci->isByRef()) {
1619 IvarsInfo.push_back(GC_IVAR(fieldOffset, /*size in words*/ 1));
1623 assert(!type->isArrayType() && "array variable should not be caught");
1624 if (const RecordType *record = type->getAs<RecordType>()) {
1625 BuildAggrIvarRecordLayout(record, fieldOffset, true, hasUnion);
1629 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), type);
1630 unsigned fieldSize = CGM.getContext().getTypeSize(type);
1632 if (GCAttr == Qualifiers::Strong)
1633 IvarsInfo.push_back(GC_IVAR(fieldOffset,
1634 fieldSize / WordSizeInBits));
1635 else if (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak)
1636 SkipIvars.push_back(GC_IVAR(fieldOffset,
1637 fieldSize / ByteSizeInBits));
1640 if (IvarsInfo.empty())
1643 // Sort on byte position; captures might not be allocated in order,
1644 // and unions can do funny things.
1645 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
1646 llvm::array_pod_sort(SkipIvars.begin(), SkipIvars.end());
1649 llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
1650 if (CGM.getLangOptions().ObjCGCBitmapPrint) {
1651 printf("\n block variable layout for block: ");
1652 const unsigned char *s = (unsigned char*)BitMap.c_str();
1653 for (unsigned i = 0; i < BitMap.size(); i++)
1655 printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
1657 printf("0x%x%s", s[i], s[i] != 0 ? ", " : "");
1664 llvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder,
1665 const ObjCProtocolDecl *PD) {
1666 // FIXME: I don't understand why gcc generates this, or where it is
1667 // resolved. Investigate. Its also wasteful to look this up over and over.
1668 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
1670 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
1671 ObjCTypes.ExternalProtocolPtrTy);
1674 void CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
1675 // FIXME: We shouldn't need this, the protocol decl should contain enough
1676 // information to tell us whether this was a declaration or a definition.
1677 DefinedProtocols.insert(PD->getIdentifier());
1679 // If we have generated a forward reference to this protocol, emit
1680 // it now. Otherwise do nothing, the protocol objects are lazily
1682 if (Protocols.count(PD->getIdentifier()))
1683 GetOrEmitProtocol(PD);
1686 llvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
1687 if (DefinedProtocols.count(PD->getIdentifier()))
1688 return GetOrEmitProtocol(PD);
1690 return GetOrEmitProtocolRef(PD);
1694 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
1695 struct _objc_protocol {
1696 struct _objc_protocol_extension *isa;
1697 char *protocol_name;
1698 struct _objc_protocol_list *protocol_list;
1699 struct _objc__method_prototype_list *instance_methods;
1700 struct _objc__method_prototype_list *class_methods
1703 See EmitProtocolExtension().
1705 llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
1706 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
1708 // Early exit if a defining object has already been generated.
1709 if (Entry && Entry->hasInitializer())
1712 // FIXME: I don't understand why gcc generates this, or where it is
1713 // resolved. Investigate. Its also wasteful to look this up over and over.
1714 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
1716 // Construct method lists.
1717 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
1718 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
1719 for (ObjCProtocolDecl::instmeth_iterator
1720 i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
1721 ObjCMethodDecl *MD = *i;
1722 llvm::Constant *C = GetMethodDescriptionConstant(MD);
1724 return GetOrEmitProtocolRef(PD);
1726 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
1727 OptInstanceMethods.push_back(C);
1729 InstanceMethods.push_back(C);
1733 for (ObjCProtocolDecl::classmeth_iterator
1734 i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
1735 ObjCMethodDecl *MD = *i;
1736 llvm::Constant *C = GetMethodDescriptionConstant(MD);
1738 return GetOrEmitProtocolRef(PD);
1740 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
1741 OptClassMethods.push_back(C);
1743 ClassMethods.push_back(C);
1747 std::vector<llvm::Constant*> Values(5);
1748 Values[0] = EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods);
1749 Values[1] = GetClassName(PD->getIdentifier());
1751 EmitProtocolList("\01L_OBJC_PROTOCOL_REFS_" + PD->getName(),
1752 PD->protocol_begin(),
1753 PD->protocol_end());
1755 EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_" + PD->getName(),
1756 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
1759 EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_" + PD->getName(),
1760 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
1762 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
1766 // Already created, fix the linkage and update the initializer.
1767 Entry->setLinkage(llvm::GlobalValue::InternalLinkage);
1768 Entry->setInitializer(Init);
1771 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,
1772 llvm::GlobalValue::InternalLinkage,
1774 "\01L_OBJC_PROTOCOL_" + PD->getName());
1775 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
1776 // FIXME: Is this necessary? Why only for protocol?
1777 Entry->setAlignment(4);
1779 CGM.AddUsedGlobal(Entry);
1784 llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
1785 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
1788 // We use the initializer as a marker of whether this is a forward
1789 // reference or not. At module finalization we add the empty
1790 // contents for protocols which were referenced but never defined.
1792 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,
1793 llvm::GlobalValue::ExternalLinkage,
1795 "\01L_OBJC_PROTOCOL_" + PD->getName());
1796 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
1797 // FIXME: Is this necessary? Why only for protocol?
1798 Entry->setAlignment(4);
1805 struct _objc_protocol_extension {
1807 struct objc_method_description_list *optional_instance_methods;
1808 struct objc_method_description_list *optional_class_methods;
1809 struct objc_property_list *instance_properties;
1813 CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
1814 const ConstantVector &OptInstanceMethods,
1815 const ConstantVector &OptClassMethods) {
1817 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
1818 std::vector<llvm::Constant*> Values(4);
1819 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
1821 EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_"
1823 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
1824 OptInstanceMethods);
1826 EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_" + PD->getName(),
1827 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
1829 Values[3] = EmitPropertyList("\01L_OBJC_$_PROP_PROTO_LIST_" + PD->getName(),
1832 // Return null if no extension bits are used.
1833 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
1834 Values[3]->isNullValue())
1835 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
1837 llvm::Constant *Init =
1838 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
1840 // No special section, but goes in llvm.used
1841 return CreateMetadataVar("\01L_OBJC_PROTOCOLEXT_" + PD->getName(),
1847 struct objc_protocol_list {
1848 struct objc_protocol_list *next;
1854 CGObjCMac::EmitProtocolList(llvm::Twine Name,
1855 ObjCProtocolDecl::protocol_iterator begin,
1856 ObjCProtocolDecl::protocol_iterator end) {
1857 std::vector<llvm::Constant*> ProtocolRefs;
1859 for (; begin != end; ++begin)
1860 ProtocolRefs.push_back(GetProtocolRef(*begin));
1862 // Just return null for empty protocol lists
1863 if (ProtocolRefs.empty())
1864 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
1866 // This list is null terminated.
1867 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
1869 std::vector<llvm::Constant*> Values(3);
1870 // This field is only used by the runtime.
1871 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
1872 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy,
1873 ProtocolRefs.size() - 1);
1875 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
1876 ProtocolRefs.size()),
1879 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
1880 llvm::GlobalVariable *GV =
1881 CreateMetadataVar(Name, Init, "__OBJC,__cat_cls_meth,regular,no_dead_strip",
1883 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
1886 void CGObjCCommonMac::PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet,
1887 std::vector<llvm::Constant*> &Properties,
1888 const Decl *Container,
1889 const ObjCProtocolDecl *PROTO,
1890 const ObjCCommonTypesHelper &ObjCTypes) {
1891 std::vector<llvm::Constant*> Prop(2);
1892 for (ObjCProtocolDecl::protocol_iterator P = PROTO->protocol_begin(),
1893 E = PROTO->protocol_end(); P != E; ++P)
1894 PushProtocolProperties(PropertySet, Properties, Container, (*P), ObjCTypes);
1895 for (ObjCContainerDecl::prop_iterator I = PROTO->prop_begin(),
1896 E = PROTO->prop_end(); I != E; ++I) {
1897 const ObjCPropertyDecl *PD = *I;
1898 if (!PropertySet.insert(PD->getIdentifier()))
1900 Prop[0] = GetPropertyName(PD->getIdentifier());
1901 Prop[1] = GetPropertyTypeString(PD, Container);
1902 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop));
1907 struct _objc_property {
1908 const char * const name;
1909 const char * const attributes;
1912 struct _objc_property_list {
1913 uint32_t entsize; // sizeof (struct _objc_property)
1914 uint32_t prop_count;
1915 struct _objc_property[prop_count];
1918 llvm::Constant *CGObjCCommonMac::EmitPropertyList(llvm::Twine Name,
1919 const Decl *Container,
1920 const ObjCContainerDecl *OCD,
1921 const ObjCCommonTypesHelper &ObjCTypes) {
1922 std::vector<llvm::Constant*> Properties, Prop(2);
1923 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
1924 for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(),
1925 E = OCD->prop_end(); I != E; ++I) {
1926 const ObjCPropertyDecl *PD = *I;
1927 PropertySet.insert(PD->getIdentifier());
1928 Prop[0] = GetPropertyName(PD->getIdentifier());
1929 Prop[1] = GetPropertyTypeString(PD, Container);
1930 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
1933 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) {
1934 for (ObjCInterfaceDecl::all_protocol_iterator
1935 P = OID->all_referenced_protocol_begin(),
1936 E = OID->all_referenced_protocol_end(); P != E; ++P)
1937 PushProtocolProperties(PropertySet, Properties, Container, (*P),
1940 else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) {
1941 for (ObjCCategoryDecl::protocol_iterator P = CD->protocol_begin(),
1942 E = CD->protocol_end(); P != E; ++P)
1943 PushProtocolProperties(PropertySet, Properties, Container, (*P),
1947 // Return null for empty list.
1948 if (Properties.empty())
1949 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
1951 unsigned PropertySize =
1952 CGM.getTargetData().getTypeAllocSize(ObjCTypes.PropertyTy);
1953 std::vector<llvm::Constant*> Values(3);
1954 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
1955 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
1956 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
1958 Values[2] = llvm::ConstantArray::get(AT, Properties);
1959 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
1961 llvm::GlobalVariable *GV =
1962 CreateMetadataVar(Name, Init,
1963 (ObjCABI == 2) ? "__DATA, __objc_const" :
1964 "__OBJC,__property,regular,no_dead_strip",
1965 (ObjCABI == 2) ? 8 : 4,
1967 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);
1971 struct objc_method_description_list {
1973 struct objc_method_description list[];
1977 CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
1978 std::vector<llvm::Constant*> Desc(2);
1980 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
1981 ObjCTypes.SelectorPtrTy);
1982 Desc[1] = GetMethodVarType(MD);
1986 return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
1990 llvm::Constant *CGObjCMac::EmitMethodDescList(llvm::Twine Name,
1991 const char *Section,
1992 const ConstantVector &Methods) {
1993 // Return null for empty list.
1994 if (Methods.empty())
1995 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
1997 std::vector<llvm::Constant*> Values(2);
1998 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
1999 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
2001 Values[1] = llvm::ConstantArray::get(AT, Methods);
2002 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
2004 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
2005 return llvm::ConstantExpr::getBitCast(GV,
2006 ObjCTypes.MethodDescriptionListPtrTy);
2010 struct _objc_category {
2011 char *category_name;
2013 struct _objc_method_list *instance_methods;
2014 struct _objc_method_list *class_methods;
2015 struct _objc_protocol_list *protocols;
2016 uint32_t size; // <rdar://4585769>
2017 struct _objc_property_list *instance_properties;
2020 void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
2021 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.CategoryTy);
2023 // FIXME: This is poor design, the OCD should have a pointer to the category
2024 // decl. Additionally, note that Category can be null for the @implementation
2025 // w/o an @interface case. Sema should just create one for us as it does for
2026 // @implementation so everyone else can live life under a clear blue sky.
2027 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
2028 const ObjCCategoryDecl *Category =
2029 Interface->FindCategoryDeclaration(OCD->getIdentifier());
2031 llvm::SmallString<256> ExtName;
2032 llvm::raw_svector_ostream(ExtName) << Interface->getName() << '_'
2035 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
2036 for (ObjCCategoryImplDecl::instmeth_iterator
2037 i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
2038 // Instance methods should always be defined.
2039 InstanceMethods.push_back(GetMethodConstant(*i));
2041 for (ObjCCategoryImplDecl::classmeth_iterator
2042 i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
2043 // Class methods should always be defined.
2044 ClassMethods.push_back(GetMethodConstant(*i));
2047 std::vector<llvm::Constant*> Values(7);
2048 Values[0] = GetClassName(OCD->getIdentifier());
2049 Values[1] = GetClassName(Interface->getIdentifier());
2050 LazySymbols.insert(Interface->getIdentifier());
2052 EmitMethodList("\01L_OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(),
2053 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2056 EmitMethodList("\01L_OBJC_CATEGORY_CLASS_METHODS_" + ExtName.str(),
2057 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2061 EmitProtocolList("\01L_OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
2062 Category->protocol_begin(),
2063 Category->protocol_end());
2065 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2067 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
2069 // If there is no category @interface then there can be no properties.
2071 Values[6] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
2072 OCD, Category, ObjCTypes);
2074 Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
2077 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
2080 llvm::GlobalVariable *GV =
2081 CreateMetadataVar("\01L_OBJC_CATEGORY_" + ExtName.str(), Init,
2082 "__OBJC,__category,regular,no_dead_strip",
2084 DefinedCategories.push_back(GV);
2085 DefinedCategoryNames.insert(ExtName.str());
2086 // method definition entries must be clear for next implementation.
2087 MethodDefinitions.clear();
2090 // FIXME: Get from somewhere?
2092 eClassFlags_Factory = 0x00001,
2093 eClassFlags_Meta = 0x00002,
2095 eClassFlags_HasCXXStructors = 0x02000,
2096 eClassFlags_Hidden = 0x20000,
2097 eClassFlags_ABI2_Hidden = 0x00010,
2098 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634>
2102 struct _objc_class {
2109 struct _objc_ivar_list *ivars;
2110 struct _objc_method_list *methods;
2111 struct _objc_cache *cache;
2112 struct _objc_protocol_list *protocols;
2113 // Objective-C 1.0 extensions (<rdr://4585769>)
2114 const char *ivar_layout;
2115 struct _objc_class_ext *ext;
2118 See EmitClassExtension();
2120 void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
2121 DefinedSymbols.insert(ID->getIdentifier());
2123 std::string ClassName = ID->getNameAsString();
2125 ObjCInterfaceDecl *Interface =
2126 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
2127 llvm::Constant *Protocols =
2128 EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getName(),
2129 Interface->all_referenced_protocol_begin(),
2130 Interface->all_referenced_protocol_end());
2131 unsigned Flags = eClassFlags_Factory;
2132 if (ID->getNumIvarInitializers())
2133 Flags |= eClassFlags_HasCXXStructors;
2135 CGM.getContext().getASTObjCImplementationLayout(ID).getSize().getQuantity();
2137 // FIXME: Set CXX-structors flag.
2138 if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
2139 Flags |= eClassFlags_Hidden;
2141 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
2142 for (ObjCImplementationDecl::instmeth_iterator
2143 i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
2144 // Instance methods should always be defined.
2145 InstanceMethods.push_back(GetMethodConstant(*i));
2147 for (ObjCImplementationDecl::classmeth_iterator
2148 i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
2149 // Class methods should always be defined.
2150 ClassMethods.push_back(GetMethodConstant(*i));
2153 for (ObjCImplementationDecl::propimpl_iterator
2154 i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
2155 ObjCPropertyImplDecl *PID = *i;
2157 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
2158 ObjCPropertyDecl *PD = PID->getPropertyDecl();
2160 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
2161 if (llvm::Constant *C = GetMethodConstant(MD))
2162 InstanceMethods.push_back(C);
2163 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
2164 if (llvm::Constant *C = GetMethodConstant(MD))
2165 InstanceMethods.push_back(C);
2169 std::vector<llvm::Constant*> Values(12);
2170 Values[ 0] = EmitMetaClass(ID, Protocols, ClassMethods);
2171 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
2172 // Record a reference to the super class.
2173 LazySymbols.insert(Super->getIdentifier());
2176 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
2177 ObjCTypes.ClassPtrTy);
2179 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
2181 Values[ 2] = GetClassName(ID->getIdentifier());
2182 // Version is always 0.
2183 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
2184 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
2185 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
2186 Values[ 6] = EmitIvarList(ID, false);
2188 EmitMethodList("\01L_OBJC_INSTANCE_METHODS_" + ID->getName(),
2189 "__OBJC,__inst_meth,regular,no_dead_strip",
2191 // cache is always NULL.
2192 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
2193 Values[ 9] = Protocols;
2194 Values[10] = BuildIvarLayout(ID, true);
2195 Values[11] = EmitClassExtension(ID);
2196 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
2198 std::string Name("\01L_OBJC_CLASS_");
2200 const char *Section = "__OBJC,__class,regular,no_dead_strip";
2201 // Check for a forward reference.
2202 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
2204 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2205 "Forward metaclass reference has incorrect type.");
2206 GV->setLinkage(llvm::GlobalValue::InternalLinkage);
2207 GV->setInitializer(Init);
2208 GV->setSection(Section);
2209 GV->setAlignment(4);
2210 CGM.AddUsedGlobal(GV);
2213 GV = CreateMetadataVar(Name, Init, Section, 4, true);
2214 DefinedClasses.push_back(GV);
2215 // method definition entries must be clear for next implementation.
2216 MethodDefinitions.clear();
2219 llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
2220 llvm::Constant *Protocols,
2221 const ConstantVector &Methods) {
2222 unsigned Flags = eClassFlags_Meta;
2223 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassTy);
2225 if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
2226 Flags |= eClassFlags_Hidden;
2228 std::vector<llvm::Constant*> Values(12);
2229 // The isa for the metaclass is the root of the hierarchy.
2230 const ObjCInterfaceDecl *Root = ID->getClassInterface();
2231 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
2234 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
2235 ObjCTypes.ClassPtrTy);
2236 // The super class for the metaclass is emitted as the name of the
2237 // super class. The runtime fixes this up to point to the
2238 // *metaclass* for the super class.
2239 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
2241 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
2242 ObjCTypes.ClassPtrTy);
2244 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
2246 Values[ 2] = GetClassName(ID->getIdentifier());
2247 // Version is always 0.
2248 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
2249 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
2250 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
2251 Values[ 6] = EmitIvarList(ID, true);
2253 EmitMethodList("\01L_OBJC_CLASS_METHODS_" + ID->getNameAsString(),
2254 "__OBJC,__cls_meth,regular,no_dead_strip",
2256 // cache is always NULL.
2257 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
2258 Values[ 9] = Protocols;
2259 // ivar_layout for metaclass is always NULL.
2260 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
2261 // The class extension is always unused for metaclasses.
2262 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
2263 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
2266 std::string Name("\01L_OBJC_METACLASS_");
2267 Name += ID->getNameAsCString();
2269 // Check for a forward reference.
2270 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
2272 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2273 "Forward metaclass reference has incorrect type.");
2274 GV->setLinkage(llvm::GlobalValue::InternalLinkage);
2275 GV->setInitializer(Init);
2277 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
2278 llvm::GlobalValue::InternalLinkage,
2281 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
2282 GV->setAlignment(4);
2283 CGM.AddUsedGlobal(GV);
2288 llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
2289 std::string Name = "\01L_OBJC_METACLASS_" + ID->getNameAsString();
2291 // FIXME: Should we look these up somewhere other than the module. Its a bit
2292 // silly since we only generate these while processing an implementation, so
2293 // exactly one pointer would work if know when we entered/exitted an
2294 // implementation block.
2296 // Check for an existing forward reference.
2297 // Previously, metaclass with internal linkage may have been defined.
2298 // pass 'true' as 2nd argument so it is returned.
2299 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name,
2301 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2302 "Forward metaclass reference has incorrect type.");
2305 // Generate as an external reference to keep a consistent
2306 // module. This will be patched up when we emit the metaclass.
2307 return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
2308 llvm::GlobalValue::ExternalLinkage,
2314 llvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) {
2315 std::string Name = "\01L_OBJC_CLASS_" + ID->getNameAsString();
2317 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name,
2319 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2320 "Forward class metadata reference has incorrect type.");
2323 return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
2324 llvm::GlobalValue::ExternalLinkage,
2331 struct objc_class_ext {
2333 const char *weak_ivar_layout;
2334 struct _objc_property_list *properties;
2338 CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
2340 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
2342 std::vector<llvm::Constant*> Values(3);
2343 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
2344 Values[1] = BuildIvarLayout(ID, false);
2345 Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
2346 ID, ID->getClassInterface(), ObjCTypes);
2348 // Return null if no extension bits are used.
2349 if (Values[1]->isNullValue() && Values[2]->isNullValue())
2350 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
2352 llvm::Constant *Init =
2353 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
2354 return CreateMetadataVar("\01L_OBJC_CLASSEXT_" + ID->getName(),
2355 Init, "__OBJC,__class_ext,regular,no_dead_strip",
2366 struct objc_ivar_list {
2368 struct objc_ivar list[count];
2371 llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
2373 std::vector<llvm::Constant*> Ivars, Ivar(3);
2375 // When emitting the root class GCC emits ivar entries for the
2376 // actual class structure. It is not clear if we need to follow this
2377 // behavior; for now lets try and get away with not doing it. If so,
2378 // the cleanest solution would be to make up an ObjCInterfaceDecl
2381 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
2383 ObjCInterfaceDecl *OID =
2384 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
2386 llvm::SmallVector<ObjCIvarDecl*, 16> OIvars;
2387 CGM.getContext().ShallowCollectObjCIvars(OID, OIvars);
2389 for (unsigned i = 0, e = OIvars.size(); i != e; ++i) {
2390 ObjCIvarDecl *IVD = OIvars[i];
2391 // Ignore unnamed bit-fields.
2392 if (!IVD->getDeclName())
2394 Ivar[0] = GetMethodVarName(IVD->getIdentifier());
2395 Ivar[1] = GetMethodVarType(IVD);
2396 Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy,
2397 ComputeIvarBaseOffset(CGM, OID, IVD));
2398 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar));
2401 // Return null for empty list.
2403 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
2405 std::vector<llvm::Constant*> Values(2);
2406 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
2407 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
2409 Values[1] = llvm::ConstantArray::get(AT, Ivars);
2410 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
2412 llvm::GlobalVariable *GV;
2414 GV = CreateMetadataVar("\01L_OBJC_CLASS_VARIABLES_" + ID->getName(),
2415 Init, "__OBJC,__class_vars,regular,no_dead_strip",
2418 GV = CreateMetadataVar("\01L_OBJC_INSTANCE_VARIABLES_" + ID->getName(),
2419 Init, "__OBJC,__instance_vars,regular,no_dead_strip",
2421 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
2425 struct objc_method {
2431 struct objc_method_list {
2432 struct objc_method_list *obsolete;
2434 struct objc_method methods_list[count];
2438 /// GetMethodConstant - Return a struct objc_method constant for the
2439 /// given method if it has been defined. The result is null if the
2440 /// method has not been defined. The return value has type MethodPtrTy.
2441 llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) {
2442 llvm::Function *Fn = GetMethodDefinition(MD);
2446 std::vector<llvm::Constant*> Method(3);
2448 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
2449 ObjCTypes.SelectorPtrTy);
2450 Method[1] = GetMethodVarType(MD);
2451 Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy);
2452 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
2455 llvm::Constant *CGObjCMac::EmitMethodList(llvm::Twine Name,
2456 const char *Section,
2457 const ConstantVector &Methods) {
2458 // Return null for empty list.
2459 if (Methods.empty())
2460 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
2462 std::vector<llvm::Constant*> Values(3);
2463 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
2464 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
2465 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
2467 Values[2] = llvm::ConstantArray::get(AT, Methods);
2468 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
2470 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
2471 return llvm::ConstantExpr::getBitCast(GV,
2472 ObjCTypes.MethodListPtrTy);
2475 llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,
2476 const ObjCContainerDecl *CD) {
2477 llvm::SmallString<256> Name;
2478 GetNameForMethod(OMD, CD, Name);
2480 CodeGenTypes &Types = CGM.getTypes();
2481 const llvm::FunctionType *MethodTy =
2482 Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic());
2483 llvm::Function *Method =
2484 llvm::Function::Create(MethodTy,
2485 llvm::GlobalValue::InternalLinkage,
2488 MethodDefinitions.insert(std::make_pair(OMD, Method));
2493 llvm::GlobalVariable *
2494 CGObjCCommonMac::CreateMetadataVar(llvm::Twine Name,
2495 llvm::Constant *Init,
2496 const char *Section,
2499 const llvm::Type *Ty = Init->getType();
2500 llvm::GlobalVariable *GV =
2501 new llvm::GlobalVariable(CGM.getModule(), Ty, false,
2502 llvm::GlobalValue::InternalLinkage, Init, Name);
2504 GV->setSection(Section);
2506 GV->setAlignment(Align);
2508 CGM.AddUsedGlobal(GV);
2512 llvm::Function *CGObjCMac::ModuleInitFunction() {
2513 // Abuse this interface function as a place to finalize.
2518 llvm::Constant *CGObjCMac::GetPropertyGetFunction() {
2519 return ObjCTypes.getGetPropertyFn();
2522 llvm::Constant *CGObjCMac::GetPropertySetFunction() {
2523 return ObjCTypes.getSetPropertyFn();
2526 llvm::Constant *CGObjCMac::GetGetStructFunction() {
2527 return ObjCTypes.getCopyStructFn();
2529 llvm::Constant *CGObjCMac::GetSetStructFunction() {
2530 return ObjCTypes.getCopyStructFn();
2533 llvm::Constant *CGObjCMac::EnumerationMutationFunction() {
2534 return ObjCTypes.getEnumerationMutationFn();
2537 void CGObjCMac::EmitTryStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S) {
2538 return EmitTryOrSynchronizedStmt(CGF, S);
2541 void CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF,
2542 const ObjCAtSynchronizedStmt &S) {
2543 return EmitTryOrSynchronizedStmt(CGF, S);
2547 struct PerformFragileFinally : EHScopeStack::Cleanup {
2549 llvm::Value *SyncArgSlot;
2550 llvm::Value *CallTryExitVar;
2551 llvm::Value *ExceptionData;
2552 ObjCTypesHelper &ObjCTypes;
2553 PerformFragileFinally(const Stmt *S,
2554 llvm::Value *SyncArgSlot,
2555 llvm::Value *CallTryExitVar,
2556 llvm::Value *ExceptionData,
2557 ObjCTypesHelper *ObjCTypes)
2558 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
2559 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
2561 void Emit(CodeGenFunction &CGF, bool IsForEH) {
2562 // Check whether we need to call objc_exception_try_exit.
2563 // In optimized code, this branch will always be folded.
2564 llvm::BasicBlock *FinallyCallExit =
2565 CGF.createBasicBlock("finally.call_exit");
2566 llvm::BasicBlock *FinallyNoCallExit =
2567 CGF.createBasicBlock("finally.no_call_exit");
2568 CGF.Builder.CreateCondBr(CGF.Builder.CreateLoad(CallTryExitVar),
2569 FinallyCallExit, FinallyNoCallExit);
2571 CGF.EmitBlock(FinallyCallExit);
2572 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryExitFn(), ExceptionData)
2573 ->setDoesNotThrow();
2575 CGF.EmitBlock(FinallyNoCallExit);
2577 if (isa<ObjCAtTryStmt>(S)) {
2578 if (const ObjCAtFinallyStmt* FinallyStmt =
2579 cast<ObjCAtTryStmt>(S).getFinallyStmt()) {
2580 // Save the current cleanup destination in case there's
2581 // control flow inside the finally statement.
2582 llvm::Value *CurCleanupDest =
2583 CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot());
2585 CGF.EmitStmt(FinallyStmt->getFinallyBody());
2587 if (CGF.HaveInsertPoint()) {
2588 CGF.Builder.CreateStore(CurCleanupDest,
2589 CGF.getNormalCleanupDestSlot());
2591 // Currently, the end of the cleanup must always exist.
2592 CGF.EnsureInsertPoint();
2596 // Emit objc_sync_exit(expr); as finally's sole statement for
2598 llvm::Value *SyncArg = CGF.Builder.CreateLoad(SyncArgSlot);
2599 CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg)
2600 ->setDoesNotThrow();
2605 class FragileHazards {
2606 CodeGenFunction &CGF;
2607 llvm::SmallVector<llvm::Value*, 20> Locals;
2608 llvm::DenseSet<llvm::BasicBlock*> BlocksBeforeTry;
2610 llvm::InlineAsm *ReadHazard;
2611 llvm::InlineAsm *WriteHazard;
2613 llvm::FunctionType *GetAsmFnType();
2615 void collectLocals();
2616 void emitReadHazard(CGBuilderTy &Builder);
2619 FragileHazards(CodeGenFunction &CGF);
2621 void emitWriteHazard();
2622 void emitHazardsInNewBlocks();
2626 /// Create the fragile-ABI read and write hazards based on the current
2627 /// state of the function, which is presumed to be immediately prior
2628 /// to a @try block. These hazards are used to maintain correct
2629 /// semantics in the face of optimization and the fragile ABI's
2630 /// cavalier use of setjmp/longjmp.
2631 FragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) {
2634 if (Locals.empty()) return;
2636 // Collect all the blocks in the function.
2637 for (llvm::Function::iterator
2638 I = CGF.CurFn->begin(), E = CGF.CurFn->end(); I != E; ++I)
2639 BlocksBeforeTry.insert(&*I);
2641 llvm::FunctionType *AsmFnTy = GetAsmFnType();
2643 // Create a read hazard for the allocas. This inhibits dead-store
2644 // optimizations and forces the values to memory. This hazard is
2645 // inserted before any 'throwing' calls in the protected scope to
2646 // reflect the possibility that the variables might be read from the
2647 // catch block if the call throws.
2649 std::string Constraint;
2650 for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
2651 if (I) Constraint += ',';
2655 ReadHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
2658 // Create a write hazard for the allocas. This inhibits folding
2659 // loads across the hazard. This hazard is inserted at the
2660 // beginning of the catch path to reflect the possibility that the
2661 // variables might have been written within the protected scope.
2663 std::string Constraint;
2664 for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
2665 if (I) Constraint += ',';
2666 Constraint += "=*m";
2669 WriteHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
2673 /// Emit a write hazard at the current location.
2674 void FragileHazards::emitWriteHazard() {
2675 if (Locals.empty()) return;
2677 CGF.Builder.CreateCall(WriteHazard, Locals.begin(), Locals.end())
2678 ->setDoesNotThrow();
2681 void FragileHazards::emitReadHazard(CGBuilderTy &Builder) {
2682 assert(!Locals.empty());
2683 Builder.CreateCall(ReadHazard, Locals.begin(), Locals.end())
2684 ->setDoesNotThrow();
2687 /// Emit read hazards in all the protected blocks, i.e. all the blocks
2688 /// which have been inserted since the beginning of the try.
2689 void FragileHazards::emitHazardsInNewBlocks() {
2690 if (Locals.empty()) return;
2692 CGBuilderTy Builder(CGF.getLLVMContext());
2694 // Iterate through all blocks, skipping those prior to the try.
2695 for (llvm::Function::iterator
2696 FI = CGF.CurFn->begin(), FE = CGF.CurFn->end(); FI != FE; ++FI) {
2697 llvm::BasicBlock &BB = *FI;
2698 if (BlocksBeforeTry.count(&BB)) continue;
2700 // Walk through all the calls in the block.
2701 for (llvm::BasicBlock::iterator
2702 BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
2703 llvm::Instruction &I = *BI;
2705 // Ignore instructions that aren't non-intrinsic calls.
2706 // These are the only calls that can possibly call longjmp.
2707 if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I)) continue;
2708 if (isa<llvm::IntrinsicInst>(I))
2711 // Ignore call sites marked nounwind. This may be questionable,
2712 // since 'nounwind' doesn't necessarily mean 'does not call longjmp'.
2713 llvm::CallSite CS(&I);
2714 if (CS.doesNotThrow()) continue;
2716 // Insert a read hazard before the call. This will ensure that
2717 // any writes to the locals are performed before making the
2718 // call. If the call throws, then this is sufficient to
2719 // guarantee correctness as long as it doesn't also write to any
2721 Builder.SetInsertPoint(&BB, BI);
2722 emitReadHazard(Builder);
2727 static void addIfPresent(llvm::DenseSet<llvm::Value*> &S, llvm::Value *V) {
2731 void FragileHazards::collectLocals() {
2732 // Compute a set of allocas to ignore.
2733 llvm::DenseSet<llvm::Value*> AllocasToIgnore;
2734 addIfPresent(AllocasToIgnore, CGF.ReturnValue);
2735 addIfPresent(AllocasToIgnore, CGF.NormalCleanupDest);
2736 addIfPresent(AllocasToIgnore, CGF.EHCleanupDest);
2738 // Collect all the allocas currently in the function. This is
2739 // probably way too aggressive.
2740 llvm::BasicBlock &Entry = CGF.CurFn->getEntryBlock();
2741 for (llvm::BasicBlock::iterator
2742 I = Entry.begin(), E = Entry.end(); I != E; ++I)
2743 if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
2744 Locals.push_back(&*I);
2747 llvm::FunctionType *FragileHazards::GetAsmFnType() {
2748 llvm::SmallVector<const llvm::Type *, 16> tys(Locals.size());
2749 for (unsigned i = 0, e = Locals.size(); i != e; ++i)
2750 tys[i] = Locals[i]->getType();
2751 return llvm::FunctionType::get(CGF.VoidTy, tys, false);
2756 Objective-C setjmp-longjmp (sjlj) Exception Handling
2759 A catch buffer is a setjmp buffer plus:
2760 - a pointer to the exception that was caught
2761 - a pointer to the previous exception data buffer
2762 - two pointers of reserved storage
2763 Therefore catch buffers form a stack, with a pointer to the top
2764 of the stack kept in thread-local storage.
2766 objc_exception_try_enter pushes a catch buffer onto the EH stack.
2767 objc_exception_try_exit pops the given catch buffer, which is
2768 required to be the top of the EH stack.
2769 objc_exception_throw pops the top of the EH stack, writes the
2770 thrown exception into the appropriate field, and longjmps
2771 to the setjmp buffer. It crashes the process (with a printf
2772 and an abort()) if there are no catch buffers on the stack.
2773 objc_exception_extract just reads the exception pointer out of the
2776 There's no reason an implementation couldn't use a light-weight
2777 setjmp here --- something like __builtin_setjmp, but API-compatible
2778 with the heavyweight setjmp. This will be more important if we ever
2779 want to implement correct ObjC/C++ exception interactions for the
2782 Note that for this use of setjmp/longjmp to be correct, we may need
2783 to mark some local variables volatile: if a non-volatile local
2784 variable is modified between the setjmp and the longjmp, it has
2785 indeterminate value. For the purposes of LLVM IR, it may be
2786 sufficient to make loads and stores within the @try (to variables
2787 declared outside the @try) volatile. This is necessary for
2788 optimized correctness, but is not currently being done; this is
2789 being tracked as rdar://problem/8160285
2791 The basic framework for a @try-catch-finally is as follows:
2793 objc_exception_data d;
2795 bool _call_try_exit = true;
2797 objc_exception_try_enter(&d);
2798 if (!setjmp(d.jmp_buf)) {
2802 id _caught = objc_exception_extract(&d);
2804 // enter new try scope for handlers
2805 if (!setjmp(d.jmp_buf)) {
2806 ... match exception and execute catch blocks ...
2808 // fell off end, rethrow.
2810 ... jump-through-finally to finally_rethrow ...
2812 // exception in catch block
2813 _rethrow = objc_exception_extract(&d);
2814 _call_try_exit = false;
2815 ... jump-through-finally to finally_rethrow ...
2818 ... jump-through-finally to finally_end ...
2822 objc_exception_try_exit(&d);
2824 ... finally block ....
2825 ... dispatch to finally destination ...
2828 objc_exception_throw(_rethrow);
2833 This framework differs slightly from the one gcc uses, in that gcc
2834 uses _rethrow to determine if objc_exception_try_exit should be called
2835 and if the object should be rethrown. This breaks in the face of
2836 throwing nil and introduces unnecessary branches.
2838 We specialize this framework for a few particular circumstances:
2840 - If there are no catch blocks, then we avoid emitting the second
2841 exception handling context.
2843 - If there is a catch-all catch block (i.e. @catch(...) or @catch(id
2844 e)) we avoid emitting the code to rethrow an uncaught exception.
2846 - FIXME: If there is no @finally block we can do a few more
2849 Rethrows and Jumps-Through-Finally
2852 '@throw;' is supported by pushing the currently-caught exception
2853 onto ObjCEHStack while the @catch blocks are emitted.
2855 Branches through the @finally block are handled with an ordinary
2856 normal cleanup. We do not register an EH cleanup; fragile-ABI ObjC
2857 exceptions are not compatible with C++ exceptions, and this is
2858 hardly the only place where this will go wrong.
2860 @synchronized(expr) { stmt; } is emitted as if it were:
2861 id synch_value = expr;
2862 objc_sync_enter(synch_value);
2863 @try { stmt; } @finally { objc_sync_exit(synch_value); }
2866 void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
2868 bool isTry = isa<ObjCAtTryStmt>(S);
2870 // A destination for the fall-through edges of the catch handlers to
2872 CodeGenFunction::JumpDest FinallyEnd =
2873 CGF.getJumpDestInCurrentScope("finally.end");
2875 // A destination for the rethrow edge of the catch handlers to jump
2877 CodeGenFunction::JumpDest FinallyRethrow =
2878 CGF.getJumpDestInCurrentScope("finally.rethrow");
2880 // For @synchronized, call objc_sync_enter(sync.expr). The
2881 // evaluation of the expression must occur before we enter the
2882 // @synchronized. We can't avoid a temp here because we need the
2883 // value to be preserved. If the backend ever does liveness
2884 // correctly after setjmp, this will be unnecessary.
2885 llvm::Value *SyncArgSlot = 0;
2887 llvm::Value *SyncArg =
2888 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
2889 SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
2890 CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg)
2891 ->setDoesNotThrow();
2893 SyncArgSlot = CGF.CreateTempAlloca(SyncArg->getType(), "sync.arg");
2894 CGF.Builder.CreateStore(SyncArg, SyncArgSlot);
2897 // Allocate memory for the setjmp buffer. This needs to be kept
2898 // live throughout the try and catch blocks.
2899 llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy,
2900 "exceptiondata.ptr");
2902 // Create the fragile hazards. Note that this will not capture any
2903 // of the allocas required for exception processing, but will
2904 // capture the current basic block (which extends all the way to the
2905 // setjmp call) as "before the @try".
2906 FragileHazards Hazards(CGF);
2908 // Create a flag indicating whether the cleanup needs to call
2909 // objc_exception_try_exit. This is true except when
2910 // - no catches match and we're branching through the cleanup
2911 // just to rethrow the exception, or
2912 // - a catch matched and we're falling out of the catch handler.
2913 // The setjmp-safety rule here is that we should always store to this
2914 // variable in a place that dominates the branch through the cleanup
2915 // without passing through any setjmps.
2916 llvm::Value *CallTryExitVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(),
2919 // A slot containing the exception to rethrow. Only needed when we
2920 // have both a @catch and a @finally.
2921 llvm::Value *PropagatingExnVar = 0;
2923 // Push a normal cleanup to leave the try scope.
2924 CGF.EHStack.pushCleanup<PerformFragileFinally>(NormalCleanup, &S,
2930 // Enter a try block:
2931 // - Call objc_exception_try_enter to push ExceptionData on top of
2933 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData)
2934 ->setDoesNotThrow();
2936 // - Call setjmp on the exception data buffer.
2937 llvm::Constant *Zero = llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0);
2938 llvm::Value *GEPIndexes[] = { Zero, Zero, Zero };
2939 llvm::Value *SetJmpBuffer =
2940 CGF.Builder.CreateGEP(ExceptionData, GEPIndexes, GEPIndexes+3, "setjmp_buffer");
2941 llvm::CallInst *SetJmpResult =
2942 CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result");
2943 SetJmpResult->setDoesNotThrow();
2945 // If setjmp returned 0, enter the protected block; otherwise,
2946 // branch to the handler.
2947 llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
2948 llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
2949 llvm::Value *DidCatch =
2950 CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
2951 CGF.Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
2953 // Emit the protected block.
2954 CGF.EmitBlock(TryBlock);
2955 CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
2956 CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
2957 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
2959 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.Builder.saveAndClearIP();
2961 // Emit the exception handler block.
2962 CGF.EmitBlock(TryHandler);
2964 // Don't optimize loads of the in-scope locals across this point.
2965 Hazards.emitWriteHazard();
2967 // For a @synchronized (or a @try with no catches), just branch
2968 // through the cleanup to the rethrow block.
2969 if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
2970 // Tell the cleanup not to re-pop the exit.
2971 CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
2972 CGF.EmitBranchThroughCleanup(FinallyRethrow);
2974 // Otherwise, we have to match against the caught exceptions.
2976 // Retrieve the exception object. We may emit multiple blocks but
2977 // nothing can cross this so the value is already in SSA form.
2978 llvm::CallInst *Caught =
2979 CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
2980 ExceptionData, "caught");
2981 Caught->setDoesNotThrow();
2983 // Push the exception to rethrow onto the EH value stack for the
2984 // benefit of any @throws in the handlers.
2985 CGF.ObjCEHValueStack.push_back(Caught);
2987 const ObjCAtTryStmt* AtTryStmt = cast<ObjCAtTryStmt>(&S);
2989 bool HasFinally = (AtTryStmt->getFinallyStmt() != 0);
2991 llvm::BasicBlock *CatchBlock = 0;
2992 llvm::BasicBlock *CatchHandler = 0;
2994 // Save the currently-propagating exception before
2995 // objc_exception_try_enter clears the exception slot.
2996 PropagatingExnVar = CGF.CreateTempAlloca(Caught->getType(),
2997 "propagating_exception");
2998 CGF.Builder.CreateStore(Caught, PropagatingExnVar);
3000 // Enter a new exception try block (in case a @catch block
3001 // throws an exception).
3002 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData)
3003 ->setDoesNotThrow();
3005 llvm::CallInst *SetJmpResult =
3006 CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer,
3008 SetJmpResult->setDoesNotThrow();
3010 llvm::Value *Threw =
3011 CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
3013 CatchBlock = CGF.createBasicBlock("catch");
3014 CatchHandler = CGF.createBasicBlock("catch_for_catch");
3015 CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
3017 CGF.EmitBlock(CatchBlock);
3020 CGF.Builder.CreateStore(CGF.Builder.getInt1(HasFinally), CallTryExitVar);
3022 // Handle catch list. As a special case we check if everything is
3023 // matched and avoid generating code for falling off the end if
3025 bool AllMatched = false;
3026 for (unsigned I = 0, N = AtTryStmt->getNumCatchStmts(); I != N; ++I) {
3027 const ObjCAtCatchStmt *CatchStmt = AtTryStmt->getCatchStmt(I);
3029 const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
3030 const ObjCObjectPointerType *OPT = 0;
3032 // catch(...) always matches.
3036 OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>();
3038 // catch(id e) always matches under this ABI, since only
3039 // ObjC exceptions end up here in the first place.
3040 // FIXME: For the time being we also match id<X>; this should
3041 // be rejected by Sema instead.
3042 if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()))
3046 // If this is a catch-all, we don't need to test anything.
3048 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
3051 CGF.EmitAutoVarDecl(*CatchParam);
3052 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
3054 // These types work out because ConvertType(id) == i8*.
3055 CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(CatchParam));
3058 CGF.EmitStmt(CatchStmt->getCatchBody());
3060 // The scope of the catch variable ends right here.
3061 CatchVarCleanups.ForceCleanup();
3063 CGF.EmitBranchThroughCleanup(FinallyEnd);
3067 assert(OPT && "Unexpected non-object pointer type in @catch");
3068 const ObjCObjectType *ObjTy = OPT->getObjectType();
3070 // FIXME: @catch (Class c) ?
3071 ObjCInterfaceDecl *IDecl = ObjTy->getInterface();
3072 assert(IDecl && "Catch parameter must have Objective-C type!");
3074 // Check if the @catch block matches the exception object.
3075 llvm::Value *Class = EmitClassRef(CGF.Builder, IDecl);
3077 llvm::CallInst *Match =
3078 CGF.Builder.CreateCall2(ObjCTypes.getExceptionMatchFn(),
3079 Class, Caught, "match");
3080 Match->setDoesNotThrow();
3082 llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("match");
3083 llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch.next");
3085 CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"),
3086 MatchedBlock, NextCatchBlock);
3088 // Emit the @catch block.
3089 CGF.EmitBlock(MatchedBlock);
3091 // Collect any cleanups for the catch variable. The scope lasts until
3092 // the end of the catch body.
3093 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
3095 CGF.EmitAutoVarDecl(*CatchParam);
3096 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
3098 // Initialize the catch variable.
3100 CGF.Builder.CreateBitCast(Caught,
3101 CGF.ConvertType(CatchParam->getType()),
3103 CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(CatchParam));
3105 CGF.EmitStmt(CatchStmt->getCatchBody());
3107 // We're done with the catch variable.
3108 CatchVarCleanups.ForceCleanup();
3110 CGF.EmitBranchThroughCleanup(FinallyEnd);
3112 CGF.EmitBlock(NextCatchBlock);
3115 CGF.ObjCEHValueStack.pop_back();
3117 // If nothing wanted anything to do with the caught exception,
3118 // kill the extract call.
3119 if (Caught->use_empty())
3120 Caught->eraseFromParent();
3123 CGF.EmitBranchThroughCleanup(FinallyRethrow);
3126 // Emit the exception handler for the @catch blocks.
3127 CGF.EmitBlock(CatchHandler);
3129 // In theory we might now need a write hazard, but actually it's
3130 // unnecessary because there's no local-accessing code between
3131 // the try's write hazard and here.
3132 //Hazards.emitWriteHazard();
3134 // Extract the new exception and save it to the
3135 // propagating-exception slot.
3136 assert(PropagatingExnVar);
3137 llvm::CallInst *NewCaught =
3138 CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
3139 ExceptionData, "caught");
3140 NewCaught->setDoesNotThrow();
3141 CGF.Builder.CreateStore(NewCaught, PropagatingExnVar);
3143 // Don't pop the catch handler; the throw already did.
3144 CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
3145 CGF.EmitBranchThroughCleanup(FinallyRethrow);
3149 // Insert read hazards as required in the new blocks.
3150 Hazards.emitHazardsInNewBlocks();
3153 CGF.Builder.restoreIP(TryFallthroughIP);
3154 if (CGF.HaveInsertPoint())
3155 CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
3156 CGF.PopCleanupBlock();
3157 CGF.EmitBlock(FinallyEnd.getBlock(), true);
3159 // Emit the rethrow block.
3160 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
3161 CGF.EmitBlock(FinallyRethrow.getBlock(), true);
3162 if (CGF.HaveInsertPoint()) {
3163 // If we have a propagating-exception variable, check it.
3164 llvm::Value *PropagatingExn;
3165 if (PropagatingExnVar) {
3166 PropagatingExn = CGF.Builder.CreateLoad(PropagatingExnVar);
3168 // Otherwise, just look in the buffer for the exception to throw.
3170 llvm::CallInst *Caught =
3171 CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
3173 Caught->setDoesNotThrow();
3174 PropagatingExn = Caught;
3177 CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), PropagatingExn)
3178 ->setDoesNotThrow();
3179 CGF.Builder.CreateUnreachable();
3182 CGF.Builder.restoreIP(SavedIP);
3185 void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
3186 const ObjCAtThrowStmt &S) {
3187 llvm::Value *ExceptionAsObject;
3189 if (const Expr *ThrowExpr = S.getThrowExpr()) {
3190 llvm::Value *Exception = CGF.EmitScalarExpr(ThrowExpr);
3192 CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy, "tmp");
3194 assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
3195 "Unexpected rethrow outside @catch block.");
3196 ExceptionAsObject = CGF.ObjCEHValueStack.back();
3199 CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
3200 ->setDoesNotReturn();
3201 CGF.Builder.CreateUnreachable();
3203 // Clear the insertion point to indicate we are in unreachable code.
3204 CGF.Builder.ClearInsertionPoint();
3207 /// EmitObjCWeakRead - Code gen for loading value of a __weak
3208 /// object: objc_read_weak (id *src)
3210 llvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
3211 llvm::Value *AddrWeakObj) {
3212 const llvm::Type* DestTy =
3213 cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
3214 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj,
3215 ObjCTypes.PtrObjectPtrTy);
3216 llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(),
3217 AddrWeakObj, "weakread");
3218 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
3222 /// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
3223 /// objc_assign_weak (id src, id *dst)
3225 void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
3226 llvm::Value *src, llvm::Value *dst) {
3227 const llvm::Type * SrcTy = src->getType();
3228 if (!isa<llvm::PointerType>(SrcTy)) {
3229 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
3230 assert(Size <= 8 && "does not support size > 8");
3231 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
3232 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
3233 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
3235 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
3236 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
3237 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(),
3238 src, dst, "weakassign");
3242 /// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
3243 /// objc_assign_global (id src, id *dst)
3245 void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
3246 llvm::Value *src, llvm::Value *dst,
3248 const llvm::Type * SrcTy = src->getType();
3249 if (!isa<llvm::PointerType>(SrcTy)) {
3250 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
3251 assert(Size <= 8 && "does not support size > 8");
3252 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
3253 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
3254 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
3256 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
3257 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
3259 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(),
3260 src, dst, "globalassign");
3262 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(),
3263 src, dst, "threadlocalassign");
3267 /// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
3268 /// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset)
3270 void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
3271 llvm::Value *src, llvm::Value *dst,
3272 llvm::Value *ivarOffset) {
3273 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL");
3274 const llvm::Type * SrcTy = src->getType();
3275 if (!isa<llvm::PointerType>(SrcTy)) {
3276 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
3277 assert(Size <= 8 && "does not support size > 8");
3278 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
3279 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
3280 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
3282 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
3283 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
3284 CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(),
3285 src, dst, ivarOffset);
3289 /// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
3290 /// objc_assign_strongCast (id src, id *dst)
3292 void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
3293 llvm::Value *src, llvm::Value *dst) {
3294 const llvm::Type * SrcTy = src->getType();
3295 if (!isa<llvm::PointerType>(SrcTy)) {
3296 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
3297 assert(Size <= 8 && "does not support size > 8");
3298 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
3299 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
3300 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
3302 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
3303 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
3304 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(),
3305 src, dst, "weakassign");
3309 void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
3310 llvm::Value *DestPtr,
3311 llvm::Value *SrcPtr,
3312 llvm::Value *size) {
3313 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
3314 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
3315 CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(),
3316 DestPtr, SrcPtr, size);
3320 /// EmitObjCValueForIvar - Code Gen for ivar reference.
3322 LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
3324 llvm::Value *BaseValue,
3325 const ObjCIvarDecl *Ivar,
3326 unsigned CVRQualifiers) {
3327 const ObjCInterfaceDecl *ID =
3328 ObjectTy->getAs<ObjCObjectType>()->getInterface();
3329 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
3330 EmitIvarOffset(CGF, ID, Ivar));
3333 llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
3334 const ObjCInterfaceDecl *Interface,
3335 const ObjCIvarDecl *Ivar) {
3336 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
3337 return llvm::ConstantInt::get(
3338 CGM.getTypes().ConvertType(CGM.getContext().LongTy),
3342 /* *** Private Interface *** */
3344 /// EmitImageInfo - Emit the image info marker used to encode some module
3345 /// level information.
3347 /// See: <rdr://4810609&4810587&4810587>
3348 /// struct IMAGE_INFO {
3349 /// unsigned version;
3352 enum ImageInfoFlags {
3353 eImageInfo_FixAndContinue = (1 << 0),
3354 eImageInfo_GarbageCollected = (1 << 1),
3355 eImageInfo_GCOnly = (1 << 2),
3356 eImageInfo_OptimizedByDyld = (1 << 3), // FIXME: When is this set.
3358 // A flag indicating that the module has no instances of a @synthesize of a
3359 // superclass variable. <rdar://problem/6803242>
3360 eImageInfo_CorrectedSynthesize = (1 << 4)
3363 void CGObjCCommonMac::EmitImageInfo() {
3364 unsigned version = 0; // Version is unused?
3367 // FIXME: Fix and continue?
3368 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
3369 flags |= eImageInfo_GarbageCollected;
3370 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
3371 flags |= eImageInfo_GCOnly;
3373 // We never allow @synthesize of a superclass property.
3374 flags |= eImageInfo_CorrectedSynthesize;
3376 const llvm::Type *Int32Ty = llvm::Type::getInt32Ty(VMContext);
3378 // Emitted as int[2];
3379 llvm::Constant *values[2] = {
3380 llvm::ConstantInt::get(Int32Ty, version),
3381 llvm::ConstantInt::get(Int32Ty, flags)
3383 llvm::ArrayType *AT = llvm::ArrayType::get(Int32Ty, 2);
3385 const char *Section;
3387 Section = "__OBJC, __image_info,regular";
3389 Section = "__DATA, __objc_imageinfo, regular, no_dead_strip";
3390 llvm::GlobalVariable *GV =
3391 CreateMetadataVar("\01L_OBJC_IMAGE_INFO",
3392 llvm::ConstantArray::get(AT, values, 2),
3396 GV->setConstant(true);
3400 // struct objc_module {
3401 // unsigned long version;
3402 // unsigned long size;
3403 // const char *name;
3407 // FIXME: Get from somewhere
3408 static const int ModuleVersion = 7;
3410 void CGObjCMac::EmitModuleInfo() {
3411 uint64_t Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ModuleTy);
3413 std::vector<llvm::Constant*> Values(4);
3414 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
3415 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
3416 // This used to be the filename, now it is unused. <rdr://4327263>
3417 Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
3418 Values[3] = EmitModuleSymbols();
3419 CreateMetadataVar("\01L_OBJC_MODULES",
3420 llvm::ConstantStruct::get(ObjCTypes.ModuleTy, Values),
3421 "__OBJC,__module_info,regular,no_dead_strip",
3425 llvm::Constant *CGObjCMac::EmitModuleSymbols() {
3426 unsigned NumClasses = DefinedClasses.size();
3427 unsigned NumCategories = DefinedCategories.size();
3429 // Return null if no symbols were defined.
3430 if (!NumClasses && !NumCategories)
3431 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
3433 std::vector<llvm::Constant*> Values(5);
3434 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
3435 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
3436 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
3437 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
3439 // The runtime expects exactly the list of defined classes followed
3440 // by the list of defined categories, in a single array.
3441 std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories);
3442 for (unsigned i=0; i<NumClasses; i++)
3443 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
3444 ObjCTypes.Int8PtrTy);
3445 for (unsigned i=0; i<NumCategories; i++)
3446 Symbols[NumClasses + i] =
3447 llvm::ConstantExpr::getBitCast(DefinedCategories[i],
3448 ObjCTypes.Int8PtrTy);
3451 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
3452 NumClasses + NumCategories),
3455 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
3457 llvm::GlobalVariable *GV =
3458 CreateMetadataVar("\01L_OBJC_SYMBOLS", Init,
3459 "__OBJC,__symbols,regular,no_dead_strip",
3461 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
3464 llvm::Value *CGObjCMac::EmitClassRef(CGBuilderTy &Builder,
3465 const ObjCInterfaceDecl *ID) {
3466 LazySymbols.insert(ID->getIdentifier());
3468 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
3471 llvm::Constant *Casted =
3472 llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()),
3473 ObjCTypes.ClassPtrTy);
3475 CreateMetadataVar("\01L_OBJC_CLASS_REFERENCES_", Casted,
3476 "__OBJC,__cls_refs,literal_pointers,no_dead_strip",
3480 return Builder.CreateLoad(Entry, "tmp");
3483 llvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel,
3485 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
3488 llvm::Constant *Casted =
3489 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
3490 ObjCTypes.SelectorPtrTy);
3492 CreateMetadataVar("\01L_OBJC_SELECTOR_REFERENCES_", Casted,
3493 "__OBJC,__message_refs,literal_pointers,no_dead_strip",
3499 return Builder.CreateLoad(Entry, "tmp");
3502 llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) {
3503 llvm::GlobalVariable *&Entry = ClassNames[Ident];
3506 Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
3507 llvm::ConstantArray::get(VMContext,
3508 Ident->getNameStart()),
3510 "__TEXT,__objc_classname,cstring_literals" :
3511 "__TEXT,__cstring,cstring_literals"),
3514 return getConstantGEP(VMContext, Entry, 0, 0);
3517 llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
3518 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator
3519 I = MethodDefinitions.find(MD);
3520 if (I != MethodDefinitions.end())
3523 if (MD->hasBody() && MD->getPCHLevel() > 0) {
3524 // MD isn't emitted yet because it comes from PCH.
3525 CGM.EmitTopLevelDecl(const_cast<ObjCMethodDecl*>(MD));
3526 assert(MethodDefinitions[MD] && "EmitTopLevelDecl didn't emit the method!");
3527 return MethodDefinitions[MD];
3533 /// GetIvarLayoutName - Returns a unique constant for the given
3534 /// ivar layout bitmap.
3535 llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
3536 const ObjCCommonTypesHelper &ObjCTypes) {
3537 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
3540 void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT,
3541 unsigned int BytePos,
3542 bool ForStrongLayout,
3544 const RecordDecl *RD = RT->getDecl();
3545 // FIXME - Use iterator.
3546 llvm::SmallVector<FieldDecl*, 16> Fields(RD->field_begin(), RD->field_end());
3547 const llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
3548 const llvm::StructLayout *RecLayout =
3549 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(Ty));
3551 BuildAggrIvarLayout(0, RecLayout, RD, Fields, BytePos,
3552 ForStrongLayout, HasUnion);
3555 void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
3556 const llvm::StructLayout *Layout,
3557 const RecordDecl *RD,
3558 const llvm::SmallVectorImpl<FieldDecl*> &RecFields,
3559 unsigned int BytePos, bool ForStrongLayout,
3561 bool IsUnion = (RD && RD->isUnion());
3562 uint64_t MaxUnionIvarSize = 0;
3563 uint64_t MaxSkippedUnionIvarSize = 0;
3564 FieldDecl *MaxField = 0;
3565 FieldDecl *MaxSkippedField = 0;
3566 FieldDecl *LastFieldBitfieldOrUnnamed = 0;
3567 uint64_t MaxFieldOffset = 0;
3568 uint64_t MaxSkippedFieldOffset = 0;
3569 uint64_t LastBitfieldOrUnnamedOffset = 0;
3571 if (RecFields.empty())
3573 unsigned WordSizeInBits = CGM.getContext().Target.getPointerWidth(0);
3574 unsigned ByteSizeInBits = CGM.getContext().Target.getCharWidth();
3576 for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
3577 FieldDecl *Field = RecFields[i];
3578 uint64_t FieldOffset;
3580 // Note that 'i' here is actually the field index inside RD of Field,
3581 // although this dependency is hidden.
3582 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
3583 FieldOffset = RL.getFieldOffset(i) / ByteSizeInBits;
3585 FieldOffset = ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field));
3587 // Skip over unnamed or bitfields
3588 if (!Field->getIdentifier() || Field->isBitField()) {
3589 LastFieldBitfieldOrUnnamed = Field;
3590 LastBitfieldOrUnnamedOffset = FieldOffset;
3594 LastFieldBitfieldOrUnnamed = 0;
3595 QualType FQT = Field->getType();
3596 if (FQT->isRecordType() || FQT->isUnionType()) {
3597 if (FQT->isUnionType())
3600 BuildAggrIvarRecordLayout(FQT->getAs<RecordType>(),
3601 BytePos + FieldOffset,
3602 ForStrongLayout, HasUnion);
3606 if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
3607 const ConstantArrayType *CArray =
3608 dyn_cast_or_null<ConstantArrayType>(Array);
3609 uint64_t ElCount = CArray->getSize().getZExtValue();
3610 assert(CArray && "only array with known element size is supported");
3611 FQT = CArray->getElementType();
3612 while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
3613 const ConstantArrayType *CArray =
3614 dyn_cast_or_null<ConstantArrayType>(Array);
3615 ElCount *= CArray->getSize().getZExtValue();
3616 FQT = CArray->getElementType();
3619 assert(!FQT->isUnionType() &&
3620 "layout for array of unions not supported");
3621 if (FQT->isRecordType() && ElCount) {
3622 int OldIndex = IvarsInfo.size() - 1;
3623 int OldSkIndex = SkipIvars.size() -1;
3625 const RecordType *RT = FQT->getAs<RecordType>();
3626 BuildAggrIvarRecordLayout(RT, BytePos + FieldOffset,
3627 ForStrongLayout, HasUnion);
3629 // Replicate layout information for each array element. Note that
3630 // one element is already done.
3632 for (int FirstIndex = IvarsInfo.size() - 1,
3633 FirstSkIndex = SkipIvars.size() - 1 ;ElIx < ElCount; ElIx++) {
3634 uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits;
3635 for (int i = OldIndex+1; i <= FirstIndex; ++i)
3636 IvarsInfo.push_back(GC_IVAR(IvarsInfo[i].ivar_bytepos + Size*ElIx,
3637 IvarsInfo[i].ivar_size));
3638 for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i)
3639 SkipIvars.push_back(GC_IVAR(SkipIvars[i].ivar_bytepos + Size*ElIx,
3640 SkipIvars[i].ivar_size));
3645 // At this point, we are done with Record/Union and array there of.
3646 // For other arrays we are down to its element type.
3647 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT);
3649 unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType());
3650 if ((ForStrongLayout && GCAttr == Qualifiers::Strong)
3651 || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
3653 uint64_t UnionIvarSize = FieldSize / WordSizeInBits;
3654 if (UnionIvarSize > MaxUnionIvarSize) {
3655 MaxUnionIvarSize = UnionIvarSize;
3657 MaxFieldOffset = FieldOffset;
3660 IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset,
3661 FieldSize / WordSizeInBits));
3663 } else if ((ForStrongLayout &&
3664 (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak))
3665 || (!ForStrongLayout && GCAttr != Qualifiers::Weak)) {
3667 // FIXME: Why the asymmetry? We divide by word size in bits on other
3669 uint64_t UnionIvarSize = FieldSize;
3670 if (UnionIvarSize > MaxSkippedUnionIvarSize) {
3671 MaxSkippedUnionIvarSize = UnionIvarSize;
3672 MaxSkippedField = Field;
3673 MaxSkippedFieldOffset = FieldOffset;
3676 // FIXME: Why the asymmetry, we divide by byte size in bits here?
3677 SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset,
3678 FieldSize / ByteSizeInBits));
3683 if (LastFieldBitfieldOrUnnamed) {
3684 if (LastFieldBitfieldOrUnnamed->isBitField()) {
3685 // Last field was a bitfield. Must update skip info.
3686 Expr *BitWidth = LastFieldBitfieldOrUnnamed->getBitWidth();
3687 uint64_t BitFieldSize =
3688 BitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue();
3690 skivar.ivar_bytepos = BytePos + LastBitfieldOrUnnamedOffset;
3691 skivar.ivar_size = (BitFieldSize / ByteSizeInBits)
3692 + ((BitFieldSize % ByteSizeInBits) != 0);
3693 SkipIvars.push_back(skivar);
3695 assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed");
3696 // Last field was unnamed. Must update skip info.
3698 = CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType());
3699 SkipIvars.push_back(GC_IVAR(BytePos + LastBitfieldOrUnnamedOffset,
3700 FieldSize / ByteSizeInBits));
3705 IvarsInfo.push_back(GC_IVAR(BytePos + MaxFieldOffset,
3707 if (MaxSkippedField)
3708 SkipIvars.push_back(GC_IVAR(BytePos + MaxSkippedFieldOffset,
3709 MaxSkippedUnionIvarSize));
3712 /// BuildIvarLayoutBitmap - This routine is the horsework for doing all
3713 /// the computations and returning the layout bitmap (for ivar or blocks) in
3714 /// the given argument BitMap string container. Routine reads
3715 /// two containers, IvarsInfo and SkipIvars which are assumed to be
3716 /// filled already by the caller.
3717 llvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string& BitMap) {
3718 unsigned int WordsToScan, WordsToSkip;
3719 const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext);
3721 // Build the string of skip/scan nibbles
3722 llvm::SmallVector<SKIP_SCAN, 32> SkipScanIvars;
3723 unsigned int WordSize =
3724 CGM.getTypes().getTargetData().getTypeAllocSize(PtrTy);
3725 if (IvarsInfo[0].ivar_bytepos == 0) {
3727 WordsToScan = IvarsInfo[0].ivar_size;
3729 WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize;
3730 WordsToScan = IvarsInfo[0].ivar_size;
3732 for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++) {
3733 unsigned int TailPrevGCObjC =
3734 IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize;
3735 if (IvarsInfo[i].ivar_bytepos == TailPrevGCObjC) {
3736 // consecutive 'scanned' object pointers.
3737 WordsToScan += IvarsInfo[i].ivar_size;
3739 // Skip over 'gc'able object pointer which lay over each other.
3740 if (TailPrevGCObjC > IvarsInfo[i].ivar_bytepos)
3742 // Must skip over 1 or more words. We save current skip/scan values
3743 // and start a new pair.
3745 SkScan.skip = WordsToSkip;
3746 SkScan.scan = WordsToScan;
3747 SkipScanIvars.push_back(SkScan);
3750 SkScan.skip = (IvarsInfo[i].ivar_bytepos - TailPrevGCObjC) / WordSize;
3752 SkipScanIvars.push_back(SkScan);
3754 WordsToScan = IvarsInfo[i].ivar_size;
3757 if (WordsToScan > 0) {
3759 SkScan.skip = WordsToSkip;
3760 SkScan.scan = WordsToScan;
3761 SkipScanIvars.push_back(SkScan);
3764 if (!SkipIvars.empty()) {
3765 unsigned int LastIndex = SkipIvars.size()-1;
3766 int LastByteSkipped =
3767 SkipIvars[LastIndex].ivar_bytepos + SkipIvars[LastIndex].ivar_size;
3768 LastIndex = IvarsInfo.size()-1;
3769 int LastByteScanned =
3770 IvarsInfo[LastIndex].ivar_bytepos +
3771 IvarsInfo[LastIndex].ivar_size * WordSize;
3772 // Compute number of bytes to skip at the tail end of the last ivar scanned.
3773 if (LastByteSkipped > LastByteScanned) {
3774 unsigned int TotalWords = (LastByteSkipped + (WordSize -1)) / WordSize;
3776 SkScan.skip = TotalWords - (LastByteScanned/WordSize);
3778 SkipScanIvars.push_back(SkScan);
3781 // Mini optimization of nibbles such that an 0xM0 followed by 0x0N is produced
3783 int SkipScan = SkipScanIvars.size()-1;
3784 for (int i = 0; i <= SkipScan; i++) {
3785 if ((i < SkipScan) && SkipScanIvars[i].skip && SkipScanIvars[i].scan == 0
3786 && SkipScanIvars[i+1].skip == 0 && SkipScanIvars[i+1].scan) {
3787 // 0xM0 followed by 0x0N detected.
3788 SkipScanIvars[i].scan = SkipScanIvars[i+1].scan;
3789 for (int j = i+1; j < SkipScan; j++)
3790 SkipScanIvars[j] = SkipScanIvars[j+1];
3795 // Generate the string.
3796 for (int i = 0; i <= SkipScan; i++) {
3798 unsigned int skip_small = SkipScanIvars[i].skip % 0xf;
3799 unsigned int scan_small = SkipScanIvars[i].scan % 0xf;
3800 unsigned int skip_big = SkipScanIvars[i].skip / 0xf;
3801 unsigned int scan_big = SkipScanIvars[i].scan / 0xf;
3804 for (unsigned int ix = 0; ix < skip_big; ix++)
3805 BitMap += (unsigned char)(0xf0);
3807 // next (skip small, scan)
3809 byte = skip_small << 4;
3813 } else if (scan_small) {
3820 for (unsigned int ix = 0; ix < scan_big; ix++)
3821 BitMap += (unsigned char)(0x0f);
3828 // null terminate string.
3829 unsigned char zero = 0;
3832 llvm::GlobalVariable * Entry =
3833 CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
3834 llvm::ConstantArray::get(VMContext, BitMap.c_str()),
3836 "__TEXT,__objc_classname,cstring_literals" :
3837 "__TEXT,__cstring,cstring_literals"),
3839 return getConstantGEP(VMContext, Entry, 0, 0);
3842 /// BuildIvarLayout - Builds ivar layout bitmap for the class
3843 /// implementation for the __strong or __weak case.
3844 /// The layout map displays which words in ivar list must be skipped
3845 /// and which must be scanned by GC (see below). String is built of bytes.
3846 /// Each byte is divided up in two nibbles (4-bit each). Left nibble is count
3847 /// of words to skip and right nibble is count of words to scan. So, each
3848 /// nibble represents up to 15 workds to skip or scan. Skipping the rest is
3849 /// represented by a 0x00 byte which also ends the string.
3850 /// 1. when ForStrongLayout is true, following ivars are scanned:
3853 /// - __strong anything
3855 /// 2. When ForStrongLayout is false, following ivars are scanned:
3856 /// - __weak anything
3858 llvm::Constant *CGObjCCommonMac::BuildIvarLayout(
3859 const ObjCImplementationDecl *OMD,
3860 bool ForStrongLayout) {
3861 bool hasUnion = false;
3863 const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext);
3864 if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC)
3865 return llvm::Constant::getNullValue(PtrTy);
3867 llvm::SmallVector<ObjCIvarDecl*, 32> Ivars;
3868 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
3869 CGM.getContext().DeepCollectObjCIvars(OI, true, Ivars);
3871 llvm::SmallVector<FieldDecl*, 32> RecFields;
3872 for (unsigned k = 0, e = Ivars.size(); k != e; ++k)
3873 RecFields.push_back(cast<FieldDecl>(Ivars[k]));
3875 if (RecFields.empty())
3876 return llvm::Constant::getNullValue(PtrTy);
3881 BuildAggrIvarLayout(OMD, 0, 0, RecFields, 0, ForStrongLayout, hasUnion);
3882 if (IvarsInfo.empty())
3883 return llvm::Constant::getNullValue(PtrTy);
3884 // Sort on byte position in case we encounterred a union nested in
3886 if (hasUnion && !IvarsInfo.empty())
3887 std::sort(IvarsInfo.begin(), IvarsInfo.end());
3888 if (hasUnion && !SkipIvars.empty())
3889 std::sort(SkipIvars.begin(), SkipIvars.end());
3892 llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
3894 if (CGM.getLangOptions().ObjCGCBitmapPrint) {
3895 printf("\n%s ivar layout for class '%s': ",
3896 ForStrongLayout ? "strong" : "weak",
3897 OMD->getClassInterface()->getName().data());
3898 const unsigned char *s = (unsigned char*)BitMap.c_str();
3899 for (unsigned i = 0; i < BitMap.size(); i++)
3901 printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
3903 printf("0x%x%s", s[i], s[i] != 0 ? ", " : "");
3909 llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
3910 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
3912 // FIXME: Avoid std::string copying.
3914 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_NAME_",
3915 llvm::ConstantArray::get(VMContext, Sel.getAsString()),
3917 "__TEXT,__objc_methname,cstring_literals" :
3918 "__TEXT,__cstring,cstring_literals"),
3921 return getConstantGEP(VMContext, Entry, 0, 0);
3924 // FIXME: Merge into a single cstring creation function.
3925 llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
3926 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
3929 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
3930 std::string TypeStr;
3931 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
3933 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
3936 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_",
3937 llvm::ConstantArray::get(VMContext, TypeStr),
3939 "__TEXT,__objc_methtype,cstring_literals" :
3940 "__TEXT,__cstring,cstring_literals"),
3943 return getConstantGEP(VMContext, Entry, 0, 0);
3946 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D) {
3947 std::string TypeStr;
3948 if (CGM.getContext().getObjCEncodingForMethodDecl(
3949 const_cast<ObjCMethodDecl*>(D),
3953 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
3956 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_",
3957 llvm::ConstantArray::get(VMContext, TypeStr),
3959 "__TEXT,__objc_methtype,cstring_literals" :
3960 "__TEXT,__cstring,cstring_literals"),
3963 return getConstantGEP(VMContext, Entry, 0, 0);
3966 // FIXME: Merge into a single cstring creation function.
3967 llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
3968 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
3971 Entry = CreateMetadataVar("\01L_OBJC_PROP_NAME_ATTR_",
3972 llvm::ConstantArray::get(VMContext,
3973 Ident->getNameStart()),
3974 "__TEXT,__cstring,cstring_literals",
3977 return getConstantGEP(VMContext, Entry, 0, 0);
3980 // FIXME: Merge into a single cstring creation function.
3981 // FIXME: This Decl should be more precise.
3983 CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
3984 const Decl *Container) {
3985 std::string TypeStr;
3986 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
3987 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
3990 void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D,
3991 const ObjCContainerDecl *CD,
3992 llvm::SmallVectorImpl<char> &Name) {
3993 llvm::raw_svector_ostream OS(Name);
3994 assert (CD && "Missing container decl in GetNameForMethod");
3995 OS << '\01' << (D->isInstanceMethod() ? '-' : '+')
3996 << '[' << CD->getName();
3997 if (const ObjCCategoryImplDecl *CID =
3998 dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
3999 OS << '(' << CID << ')';
4000 OS << ' ' << D->getSelector().getAsString() << ']';
4003 void CGObjCMac::FinishModule() {
4006 // Emit the dummy bodies for any protocols which were referenced but
4008 for (llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*>::iterator
4009 I = Protocols.begin(), e = Protocols.end(); I != e; ++I) {
4010 if (I->second->hasInitializer())
4013 std::vector<llvm::Constant*> Values(5);
4014 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
4015 Values[1] = GetClassName(I->first);
4016 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
4017 Values[3] = Values[4] =
4018 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
4019 I->second->setLinkage(llvm::GlobalValue::InternalLinkage);
4020 I->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
4022 CGM.AddUsedGlobal(I->second);
4025 // Add assembler directives to add lazy undefined symbol references
4026 // for classes which are referenced but not defined. This is
4027 // important for correct linker interaction.
4029 // FIXME: It would be nice if we had an LLVM construct for this.
4030 if (!LazySymbols.empty() || !DefinedSymbols.empty()) {
4031 llvm::SmallString<256> Asm;
4032 Asm += CGM.getModule().getModuleInlineAsm();
4033 if (!Asm.empty() && Asm.back() != '\n')
4036 llvm::raw_svector_ostream OS(Asm);
4037 for (llvm::SetVector<IdentifierInfo*>::iterator I = DefinedSymbols.begin(),
4038 e = DefinedSymbols.end(); I != e; ++I)
4039 OS << "\t.objc_class_name_" << (*I)->getName() << "=0\n"
4040 << "\t.globl .objc_class_name_" << (*I)->getName() << "\n";
4041 for (llvm::SetVector<IdentifierInfo*>::iterator I = LazySymbols.begin(),
4042 e = LazySymbols.end(); I != e; ++I) {
4043 OS << "\t.lazy_reference .objc_class_name_" << (*I)->getName() << "\n";
4046 for (size_t i = 0; i < DefinedCategoryNames.size(); ++i) {
4047 OS << "\t.objc_category_name_" << DefinedCategoryNames[i] << "=0\n"
4048 << "\t.globl .objc_category_name_" << DefinedCategoryNames[i] << "\n";
4051 CGM.getModule().setModuleInlineAsm(OS.str());
4055 CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
4056 : CGObjCCommonMac(cgm),
4058 ObjCEmptyCacheVar = ObjCEmptyVtableVar = NULL;
4064 ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
4065 : VMContext(cgm.getLLVMContext()), CGM(cgm) {
4066 CodeGen::CodeGenTypes &Types = CGM.getTypes();
4067 ASTContext &Ctx = CGM.getContext();
4069 ShortTy = Types.ConvertType(Ctx.ShortTy);
4070 IntTy = Types.ConvertType(Ctx.IntTy);
4071 LongTy = Types.ConvertType(Ctx.LongTy);
4072 LongLongTy = Types.ConvertType(Ctx.LongLongTy);
4073 Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
4075 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
4076 PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy);
4077 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
4079 // FIXME: It would be nice to unify this with the opaque type, so that the IR
4080 // comes out a bit cleaner.
4081 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
4082 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
4084 // I'm not sure I like this. The implicit coordination is a bit
4085 // gross. We should solve this in a reasonable fashion because this
4086 // is a pretty common task (match some runtime data structure with
4087 // an LLVM data structure).
4089 // FIXME: This is leaked.
4090 // FIXME: Merge with rewriter code?
4092 // struct _objc_super {
4096 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
4097 Ctx.getTranslationUnitDecl(),
4098 SourceLocation(), SourceLocation(),
4099 &Ctx.Idents.get("_objc_super"));
4100 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
4101 Ctx.getObjCIdType(), 0, 0, false, false));
4102 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
4103 Ctx.getObjCClassType(), 0, 0, false, false));
4104 RD->completeDefinition();
4106 SuperCTy = Ctx.getTagDeclType(RD);
4107 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
4109 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
4110 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
4114 // char *attributes;
4116 PropertyTy = llvm::StructType::get(VMContext, Int8PtrTy, Int8PtrTy, NULL);
4117 CGM.getModule().addTypeName("struct._prop_t",
4120 // struct _prop_list_t {
4121 // uint32_t entsize; // sizeof(struct _prop_t)
4122 // uint32_t count_of_properties;
4123 // struct _prop_t prop_list[count_of_properties];
4125 PropertyListTy = llvm::StructType::get(VMContext, IntTy,
4127 llvm::ArrayType::get(PropertyTy, 0),
4129 CGM.getModule().addTypeName("struct._prop_list_t",
4131 // struct _prop_list_t *
4132 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
4134 // struct _objc_method {
4136 // char *method_type;
4139 MethodTy = llvm::StructType::get(VMContext, SelectorPtrTy,
4143 CGM.getModule().addTypeName("struct._objc_method", MethodTy);
4145 // struct _objc_cache *
4146 CacheTy = llvm::OpaqueType::get(VMContext);
4147 CGM.getModule().addTypeName("struct._objc_cache", CacheTy);
4148 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
4151 ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
4152 : ObjCCommonTypesHelper(cgm) {
4153 // struct _objc_method_description {
4157 MethodDescriptionTy =
4158 llvm::StructType::get(VMContext, SelectorPtrTy,
4161 CGM.getModule().addTypeName("struct._objc_method_description",
4162 MethodDescriptionTy);
4164 // struct _objc_method_description_list {
4166 // struct _objc_method_description[1];
4168 MethodDescriptionListTy =
4169 llvm::StructType::get(VMContext, IntTy,
4170 llvm::ArrayType::get(MethodDescriptionTy, 0),
4172 CGM.getModule().addTypeName("struct._objc_method_description_list",
4173 MethodDescriptionListTy);
4175 // struct _objc_method_description_list *
4176 MethodDescriptionListPtrTy =
4177 llvm::PointerType::getUnqual(MethodDescriptionListTy);
4179 // Protocol description structures
4181 // struct _objc_protocol_extension {
4182 // uint32_t size; // sizeof(struct _objc_protocol_extension)
4183 // struct _objc_method_description_list *optional_instance_methods;
4184 // struct _objc_method_description_list *optional_class_methods;
4185 // struct _objc_property_list *instance_properties;
4187 ProtocolExtensionTy =
4188 llvm::StructType::get(VMContext, IntTy,
4189 MethodDescriptionListPtrTy,
4190 MethodDescriptionListPtrTy,
4193 CGM.getModule().addTypeName("struct._objc_protocol_extension",
4194 ProtocolExtensionTy);
4196 // struct _objc_protocol_extension *
4197 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
4199 // Handle recursive construction of Protocol and ProtocolList types
4201 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get(VMContext);
4202 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get(VMContext);
4204 const llvm::Type *T =
4205 llvm::StructType::get(VMContext,
4206 llvm::PointerType::getUnqual(ProtocolListTyHolder),
4208 llvm::ArrayType::get(ProtocolTyHolder, 0),
4210 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
4212 // struct _objc_protocol {
4213 // struct _objc_protocol_extension *isa;
4214 // char *protocol_name;
4215 // struct _objc_protocol **_objc_protocol_list;
4216 // struct _objc_method_description_list *instance_methods;
4217 // struct _objc_method_description_list *class_methods;
4219 T = llvm::StructType::get(VMContext, ProtocolExtensionPtrTy,
4221 llvm::PointerType::getUnqual(ProtocolListTyHolder),
4222 MethodDescriptionListPtrTy,
4223 MethodDescriptionListPtrTy,
4225 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T);
4227 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get());
4228 CGM.getModule().addTypeName("struct._objc_protocol_list",
4230 // struct _objc_protocol_list *
4231 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
4233 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get());
4234 CGM.getModule().addTypeName("struct._objc_protocol", ProtocolTy);
4235 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
4237 // Class description structures
4239 // struct _objc_ivar {
4244 IvarTy = llvm::StructType::get(VMContext, Int8PtrTy,
4248 CGM.getModule().addTypeName("struct._objc_ivar", IvarTy);
4250 // struct _objc_ivar_list *
4251 IvarListTy = llvm::OpaqueType::get(VMContext);
4252 CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy);
4253 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
4255 // struct _objc_method_list *
4256 MethodListTy = llvm::OpaqueType::get(VMContext);
4257 CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy);
4258 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
4260 // struct _objc_class_extension *
4262 llvm::StructType::get(VMContext, IntTy,
4266 CGM.getModule().addTypeName("struct._objc_class_extension", ClassExtensionTy);
4267 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
4269 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get(VMContext);
4271 // struct _objc_class {
4273 // Class super_class;
4277 // long instance_size;
4278 // struct _objc_ivar_list *ivars;
4279 // struct _objc_method_list *methods;
4280 // struct _objc_cache *cache;
4281 // struct _objc_protocol_list *protocols;
4282 // char *ivar_layout;
4283 // struct _objc_class_ext *ext;
4285 T = llvm::StructType::get(VMContext,
4286 llvm::PointerType::getUnqual(ClassTyHolder),
4287 llvm::PointerType::getUnqual(ClassTyHolder),
4297 ClassExtensionPtrTy,
4299 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(T);
4301 ClassTy = cast<llvm::StructType>(ClassTyHolder.get());
4302 CGM.getModule().addTypeName("struct._objc_class", ClassTy);
4303 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
4305 // struct _objc_category {
4306 // char *category_name;
4307 // char *class_name;
4308 // struct _objc_method_list *instance_method;
4309 // struct _objc_method_list *class_method;
4310 // uint32_t size; // sizeof(struct _objc_category)
4311 // struct _objc_property_list *instance_properties;// category's @property
4313 CategoryTy = llvm::StructType::get(VMContext, Int8PtrTy,
4321 CGM.getModule().addTypeName("struct._objc_category", CategoryTy);
4323 // Global metadata structures
4325 // struct _objc_symtab {
4326 // long sel_ref_cnt;
4328 // short cls_def_cnt;
4329 // short cat_def_cnt;
4330 // char *defs[cls_def_cnt + cat_def_cnt];
4332 SymtabTy = llvm::StructType::get(VMContext, LongTy,
4336 llvm::ArrayType::get(Int8PtrTy, 0),
4338 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
4339 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
4341 // struct _objc_module {
4343 // long size; // sizeof(struct _objc_module)
4345 // struct _objc_symtab* symtab;
4348 llvm::StructType::get(VMContext, LongTy,
4353 CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
4356 // FIXME: This is the size of the setjmp buffer and should be target
4357 // specific. 18 is what's used on 32-bit X86.
4358 uint64_t SetJmpBufferSize = 18;
4361 const llvm::Type *StackPtrTy = llvm::ArrayType::get(
4362 llvm::Type::getInt8PtrTy(VMContext), 4);
4365 llvm::StructType::get(VMContext,
4366 llvm::ArrayType::get(llvm::Type::getInt32Ty(VMContext),
4369 CGM.getModule().addTypeName("struct._objc_exception_data",
4374 ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm)
4375 : ObjCCommonTypesHelper(cgm) {
4376 // struct _method_list_t {
4377 // uint32_t entsize; // sizeof(struct _objc_method)
4378 // uint32_t method_count;
4379 // struct _objc_method method_list[method_count];
4381 MethodListnfABITy = llvm::StructType::get(VMContext, IntTy,
4383 llvm::ArrayType::get(MethodTy, 0),
4385 CGM.getModule().addTypeName("struct.__method_list_t",
4387 // struct method_list_t *
4388 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy);
4390 // struct _protocol_t {
4392 // const char * const protocol_name;
4393 // const struct _protocol_list_t * protocol_list; // super protocols
4394 // const struct method_list_t * const instance_methods;
4395 // const struct method_list_t * const class_methods;
4396 // const struct method_list_t *optionalInstanceMethods;
4397 // const struct method_list_t *optionalClassMethods;
4398 // const struct _prop_list_t * properties;
4399 // const uint32_t size; // sizeof(struct _protocol_t)
4400 // const uint32_t flags; // = 0
4403 // Holder for struct _protocol_list_t *
4404 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get(VMContext);
4406 ProtocolnfABITy = llvm::StructType::get(VMContext, ObjectPtrTy,
4408 llvm::PointerType::getUnqual(
4409 ProtocolListTyHolder),
4410 MethodListnfABIPtrTy,
4411 MethodListnfABIPtrTy,
4412 MethodListnfABIPtrTy,
4413 MethodListnfABIPtrTy,
4418 CGM.getModule().addTypeName("struct._protocol_t",
4421 // struct _protocol_t*
4422 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy);
4424 // struct _protocol_list_t {
4425 // long protocol_count; // Note, this is 32/64 bit
4426 // struct _protocol_t *[protocol_count];
4428 ProtocolListnfABITy = llvm::StructType::get(VMContext, LongTy,
4429 llvm::ArrayType::get(
4430 ProtocolnfABIPtrTy, 0),
4432 CGM.getModule().addTypeName("struct._objc_protocol_list",
4433 ProtocolListnfABITy);
4434 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(
4435 ProtocolListnfABITy);
4437 // struct _objc_protocol_list*
4438 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy);
4441 // unsigned long int *offset; // pointer to ivar offset location
4444 // uint32_t alignment;
4447 IvarnfABITy = llvm::StructType::get(VMContext,
4448 llvm::PointerType::getUnqual(LongTy),
4454 CGM.getModule().addTypeName("struct._ivar_t", IvarnfABITy);
4456 // struct _ivar_list_t {
4457 // uint32 entsize; // sizeof(struct _ivar_t)
4459 // struct _iver_t list[count];
4461 IvarListnfABITy = llvm::StructType::get(VMContext, IntTy,
4463 llvm::ArrayType::get(
4466 CGM.getModule().addTypeName("struct._ivar_list_t", IvarListnfABITy);
4468 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy);
4470 // struct _class_ro_t {
4471 // uint32_t const flags;
4472 // uint32_t const instanceStart;
4473 // uint32_t const instanceSize;
4474 // uint32_t const reserved; // only when building for 64bit targets
4475 // const uint8_t * const ivarLayout;
4476 // const char *const name;
4477 // const struct _method_list_t * const baseMethods;
4478 // const struct _objc_protocol_list *const baseProtocols;
4479 // const struct _ivar_list_t *const ivars;
4480 // const uint8_t * const weakIvarLayout;
4481 // const struct _prop_list_t * const properties;
4484 // FIXME. Add 'reserved' field in 64bit abi mode!
4485 ClassRonfABITy = llvm::StructType::get(VMContext, IntTy,
4490 MethodListnfABIPtrTy,
4491 ProtocolListnfABIPtrTy,
4496 CGM.getModule().addTypeName("struct._class_ro_t",
4499 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
4500 const llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
4501 ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false)
4504 // struct _class_t {
4505 // struct _class_t *isa;
4506 // struct _class_t * const superclass;
4509 // struct class_ro_t *ro;
4512 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get(VMContext);
4514 llvm::StructType::get(VMContext,
4515 llvm::PointerType::getUnqual(ClassTyHolder),
4516 llvm::PointerType::getUnqual(ClassTyHolder),
4518 llvm::PointerType::getUnqual(ImpnfABITy),
4519 llvm::PointerType::getUnqual(ClassRonfABITy),
4521 CGM.getModule().addTypeName("struct._class_t", ClassnfABITy);
4523 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(
4526 // LLVM for struct _class_t *
4527 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy);
4529 // struct _category_t {
4530 // const char * const name;
4531 // struct _class_t *const cls;
4532 // const struct _method_list_t * const instance_methods;
4533 // const struct _method_list_t * const class_methods;
4534 // const struct _protocol_list_t * const protocols;
4535 // const struct _prop_list_t * const properties;
4537 CategorynfABITy = llvm::StructType::get(VMContext, Int8PtrTy,
4539 MethodListnfABIPtrTy,
4540 MethodListnfABIPtrTy,
4541 ProtocolListnfABIPtrTy,
4544 CGM.getModule().addTypeName("struct._category_t", CategorynfABITy);
4546 // New types for nonfragile abi messaging.
4547 CodeGen::CodeGenTypes &Types = CGM.getTypes();
4548 ASTContext &Ctx = CGM.getContext();
4550 // MessageRefTy - LLVM for:
4551 // struct _message_ref_t {
4556 // First the clang type for struct _message_ref_t
4557 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
4558 Ctx.getTranslationUnitDecl(),
4559 SourceLocation(), SourceLocation(),
4560 &Ctx.Idents.get("_message_ref_t"));
4561 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
4562 Ctx.VoidPtrTy, 0, 0, false, false));
4563 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
4564 Ctx.getObjCSelType(), 0, 0, false, false));
4565 RD->completeDefinition();
4567 MessageRefCTy = Ctx.getTagDeclType(RD);
4568 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
4569 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
4571 // MessageRefPtrTy - LLVM for struct _message_ref_t*
4572 MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy);
4574 // SuperMessageRefTy - LLVM for:
4575 // struct _super_message_ref_t {
4576 // SUPER_IMP messenger;
4579 SuperMessageRefTy = llvm::StructType::get(VMContext, ImpnfABITy,
4582 CGM.getModule().addTypeName("struct._super_message_ref_t", SuperMessageRefTy);
4584 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
4585 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);
4588 // struct objc_typeinfo {
4589 // const void** vtable; // objc_ehtype_vtable + 2
4590 // const char* name; // c++ typeinfo string
4593 EHTypeTy = llvm::StructType::get(VMContext,
4594 llvm::PointerType::getUnqual(Int8PtrTy),
4598 CGM.getModule().addTypeName("struct._objc_typeinfo", EHTypeTy);
4599 EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy);
4602 llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
4603 FinishNonFragileABIModule();
4608 void CGObjCNonFragileABIMac::AddModuleClassList(const
4609 std::vector<llvm::GlobalValue*>
4611 const char *SymbolName,
4612 const char *SectionName) {
4613 unsigned NumClasses = Container.size();
4618 std::vector<llvm::Constant*> Symbols(NumClasses);
4619 for (unsigned i=0; i<NumClasses; i++)
4620 Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i],
4621 ObjCTypes.Int8PtrTy);
4622 llvm::Constant* Init =
4623 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
4627 llvm::GlobalVariable *GV =
4628 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
4629 llvm::GlobalValue::InternalLinkage,
4632 GV->setAlignment(CGM.getTargetData().getABITypeAlignment(Init->getType()));
4633 GV->setSection(SectionName);
4634 CGM.AddUsedGlobal(GV);
4637 void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
4638 // nonfragile abi has no module definition.
4640 // Build list of all implemented class addresses in array
4641 // L_OBJC_LABEL_CLASS_$.
4642 AddModuleClassList(DefinedClasses,
4643 "\01L_OBJC_LABEL_CLASS_$",
4644 "__DATA, __objc_classlist, regular, no_dead_strip");
4646 for (unsigned i = 0; i < DefinedClasses.size(); i++) {
4647 llvm::GlobalValue *IMPLGV = DefinedClasses[i];
4648 if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage)
4650 IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage);
4653 for (unsigned i = 0; i < DefinedMetaClasses.size(); i++) {
4654 llvm::GlobalValue *IMPLGV = DefinedMetaClasses[i];
4655 if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage)
4657 IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage);
4660 AddModuleClassList(DefinedNonLazyClasses,
4661 "\01L_OBJC_LABEL_NONLAZY_CLASS_$",
4662 "__DATA, __objc_nlclslist, regular, no_dead_strip");
4664 // Build list of all implemented category addresses in array
4665 // L_OBJC_LABEL_CATEGORY_$.
4666 AddModuleClassList(DefinedCategories,
4667 "\01L_OBJC_LABEL_CATEGORY_$",
4668 "__DATA, __objc_catlist, regular, no_dead_strip");
4669 AddModuleClassList(DefinedNonLazyCategories,
4670 "\01L_OBJC_LABEL_NONLAZY_CATEGORY_$",
4671 "__DATA, __objc_nlcatlist, regular, no_dead_strip");
4676 /// isVTableDispatchedSelector - Returns true if SEL is not in the list of
4677 /// VTableDispatchMethods; false otherwise. What this means is that
4678 /// except for the 19 selectors in the list, we generate 32bit-style
4679 /// message dispatch call for all the rest.
4680 bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
4681 // At various points we've experimented with using vtable-based
4682 // dispatch for all methods.
4683 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
4685 llvm_unreachable("Invalid dispatch method!");
4686 case CodeGenOptions::Legacy:
4688 case CodeGenOptions::NonLegacy:
4690 case CodeGenOptions::Mixed:
4694 // If so, see whether this selector is in the white-list of things which must
4695 // use the new dispatch convention. We lazily build a dense set for this.
4696 if (VTableDispatchMethods.empty()) {
4697 VTableDispatchMethods.insert(GetNullarySelector("alloc"));
4698 VTableDispatchMethods.insert(GetNullarySelector("class"));
4699 VTableDispatchMethods.insert(GetNullarySelector("self"));
4700 VTableDispatchMethods.insert(GetNullarySelector("isFlipped"));
4701 VTableDispatchMethods.insert(GetNullarySelector("length"));
4702 VTableDispatchMethods.insert(GetNullarySelector("count"));
4704 // These are vtable-based if GC is disabled.
4705 // Optimistically use vtable dispatch for hybrid compiles.
4706 if (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly) {
4707 VTableDispatchMethods.insert(GetNullarySelector("retain"));
4708 VTableDispatchMethods.insert(GetNullarySelector("release"));
4709 VTableDispatchMethods.insert(GetNullarySelector("autorelease"));
4712 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone"));
4713 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass"));
4714 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector"));
4715 VTableDispatchMethods.insert(GetUnarySelector("objectForKey"));
4716 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex"));
4717 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString"));
4718 VTableDispatchMethods.insert(GetUnarySelector("isEqual"));
4720 // These are vtable-based if GC is enabled.
4721 // Optimistically use vtable dispatch for hybrid compiles.
4722 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) {
4723 VTableDispatchMethods.insert(GetNullarySelector("hash"));
4724 VTableDispatchMethods.insert(GetUnarySelector("addObject"));
4726 // "countByEnumeratingWithState:objects:count"
4727 IdentifierInfo *KeyIdents[] = {
4728 &CGM.getContext().Idents.get("countByEnumeratingWithState"),
4729 &CGM.getContext().Idents.get("objects"),
4730 &CGM.getContext().Idents.get("count")
4732 VTableDispatchMethods.insert(
4733 CGM.getContext().Selectors.getSelector(3, KeyIdents));
4737 return VTableDispatchMethods.count(Sel);
4741 enum MetaDataDlags {
4745 OBJC2_CLS_HIDDEN = 0x10,
4746 CLS_EXCEPTION = 0x20
4748 /// BuildClassRoTInitializer - generate meta-data for:
4749 /// struct _class_ro_t {
4750 /// uint32_t const flags;
4751 /// uint32_t const instanceStart;
4752 /// uint32_t const instanceSize;
4753 /// uint32_t const reserved; // only when building for 64bit targets
4754 /// const uint8_t * const ivarLayout;
4755 /// const char *const name;
4756 /// const struct _method_list_t * const baseMethods;
4757 /// const struct _protocol_list_t *const baseProtocols;
4758 /// const struct _ivar_list_t *const ivars;
4759 /// const uint8_t * const weakIvarLayout;
4760 /// const struct _prop_list_t * const properties;
4763 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
4765 unsigned InstanceStart,
4766 unsigned InstanceSize,
4767 const ObjCImplementationDecl *ID) {
4768 std::string ClassName = ID->getNameAsString();
4769 std::vector<llvm::Constant*> Values(10); // 11 for 64bit targets!
4770 Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags);
4771 Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart);
4772 Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize);
4773 // FIXME. For 64bit targets add 0 here.
4774 Values[ 3] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes)
4775 : BuildIvarLayout(ID, true);
4776 Values[ 4] = GetClassName(ID->getIdentifier());
4777 // const struct _method_list_t * const baseMethods;
4778 std::vector<llvm::Constant*> Methods;
4779 std::string MethodListName("\01l_OBJC_$_");
4780 if (flags & CLS_META) {
4781 MethodListName += "CLASS_METHODS_" + ID->getNameAsString();
4782 for (ObjCImplementationDecl::classmeth_iterator
4783 i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
4784 // Class methods should always be defined.
4785 Methods.push_back(GetMethodConstant(*i));
4788 MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString();
4789 for (ObjCImplementationDecl::instmeth_iterator
4790 i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
4791 // Instance methods should always be defined.
4792 Methods.push_back(GetMethodConstant(*i));
4794 for (ObjCImplementationDecl::propimpl_iterator
4795 i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
4796 ObjCPropertyImplDecl *PID = *i;
4798 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
4799 ObjCPropertyDecl *PD = PID->getPropertyDecl();
4801 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
4802 if (llvm::Constant *C = GetMethodConstant(MD))
4803 Methods.push_back(C);
4804 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
4805 if (llvm::Constant *C = GetMethodConstant(MD))
4806 Methods.push_back(C);
4810 Values[ 5] = EmitMethodList(MethodListName,
4811 "__DATA, __objc_const", Methods);
4813 const ObjCInterfaceDecl *OID = ID->getClassInterface();
4814 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");
4815 Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_"
4817 OID->all_referenced_protocol_begin(),
4818 OID->all_referenced_protocol_end());
4820 if (flags & CLS_META)
4821 Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
4823 Values[ 7] = EmitIvarList(ID);
4824 Values[ 8] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes)
4825 : BuildIvarLayout(ID, false);
4826 if (flags & CLS_META)
4827 Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
4829 Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
4830 ID, ID->getClassInterface(), ObjCTypes);
4831 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy,
4833 llvm::GlobalVariable *CLASS_RO_GV =
4834 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassRonfABITy, false,
4835 llvm::GlobalValue::InternalLinkage,
4837 (flags & CLS_META) ?
4838 std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName :
4839 std::string("\01l_OBJC_CLASS_RO_$_")+ClassName);
4840 CLASS_RO_GV->setAlignment(
4841 CGM.getTargetData().getABITypeAlignment(ObjCTypes.ClassRonfABITy));
4842 CLASS_RO_GV->setSection("__DATA, __objc_const");
4847 /// BuildClassMetaData - This routine defines that to-level meta-data
4848 /// for the given ClassName for:
4849 /// struct _class_t {
4850 /// struct _class_t *isa;
4851 /// struct _class_t * const superclass;
4854 /// struct class_ro_t *ro;
4857 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData(
4858 std::string &ClassName,
4859 llvm::Constant *IsAGV,
4860 llvm::Constant *SuperClassGV,
4861 llvm::Constant *ClassRoGV,
4862 bool HiddenVisibility) {
4863 std::vector<llvm::Constant*> Values(5);
4865 Values[1] = SuperClassGV;
4867 Values[1] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy);
4868 Values[2] = ObjCEmptyCacheVar; // &ObjCEmptyCacheVar
4869 Values[3] = ObjCEmptyVtableVar; // &ObjCEmptyVtableVar
4870 Values[4] = ClassRoGV; // &CLASS_RO_GV
4871 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy,
4873 llvm::GlobalVariable *GV = GetClassGlobal(ClassName);
4874 GV->setInitializer(Init);
4875 GV->setSection("__DATA, __objc_data");
4877 CGM.getTargetData().getABITypeAlignment(ObjCTypes.ClassnfABITy));
4878 if (HiddenVisibility)
4879 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
4884 CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
4885 return OD->getClassMethod(GetNullarySelector("load")) != 0;
4888 void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
4889 uint32_t &InstanceStart,
4890 uint32_t &InstanceSize) {
4891 const ASTRecordLayout &RL =
4892 CGM.getContext().getASTObjCImplementationLayout(OID);
4894 // InstanceSize is really instance end.
4895 InstanceSize = RL.getDataSize().getQuantity();
4897 // If there are no fields, the start is the same as the end.
4898 if (!RL.getFieldCount())
4899 InstanceStart = InstanceSize;
4901 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
4904 void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
4905 std::string ClassName = ID->getNameAsString();
4906 if (!ObjCEmptyCacheVar) {
4907 ObjCEmptyCacheVar = new llvm::GlobalVariable(
4911 llvm::GlobalValue::ExternalLinkage,
4913 "_objc_empty_cache");
4915 ObjCEmptyVtableVar = new llvm::GlobalVariable(
4917 ObjCTypes.ImpnfABITy,
4919 llvm::GlobalValue::ExternalLinkage,
4921 "_objc_empty_vtable");
4923 assert(ID->getClassInterface() &&
4924 "CGObjCNonFragileABIMac::GenerateClass - class is 0");
4925 // FIXME: Is this correct (that meta class size is never computed)?
4926 uint32_t InstanceStart =
4927 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassnfABITy);
4928 uint32_t InstanceSize = InstanceStart;
4929 uint32_t flags = CLS_META;
4930 std::string ObjCMetaClassName(getMetaclassSymbolPrefix());
4931 std::string ObjCClassName(getClassSymbolPrefix());
4933 llvm::GlobalVariable *SuperClassGV, *IsAGV;
4935 bool classIsHidden =
4936 ID->getClassInterface()->getVisibility() == HiddenVisibility;
4938 flags |= OBJC2_CLS_HIDDEN;
4939 if (ID->getNumIvarInitializers())
4940 flags |= eClassFlags_ABI2_HasCXXStructors;
4941 if (!ID->getClassInterface()->getSuperClass()) {
4944 SuperClassGV = GetClassGlobal(ObjCClassName + ClassName);
4945 IsAGV = GetClassGlobal(ObjCMetaClassName + ClassName);
4947 // Has a root. Current class is not a root.
4948 const ObjCInterfaceDecl *Root = ID->getClassInterface();
4949 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
4951 IsAGV = GetClassGlobal(ObjCMetaClassName + Root->getNameAsString());
4952 if (Root->isWeakImported())
4953 IsAGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
4954 // work on super class metadata symbol.
4955 std::string SuperClassName =
4957 ID->getClassInterface()->getSuperClass()->getNameAsString();
4958 SuperClassGV = GetClassGlobal(SuperClassName);
4959 if (ID->getClassInterface()->getSuperClass()->isWeakImported())
4960 SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
4962 llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags,
4965 std::string TClassName = ObjCMetaClassName + ClassName;
4966 llvm::GlobalVariable *MetaTClass =
4967 BuildClassMetaData(TClassName, IsAGV, SuperClassGV, CLASS_RO_GV,
4969 DefinedMetaClasses.push_back(MetaTClass);
4971 // Metadata for the class
4974 flags |= OBJC2_CLS_HIDDEN;
4975 if (ID->getNumIvarInitializers())
4976 flags |= eClassFlags_ABI2_HasCXXStructors;
4978 if (hasObjCExceptionAttribute(CGM.getContext(), ID->getClassInterface()))
4979 flags |= CLS_EXCEPTION;
4981 if (!ID->getClassInterface()->getSuperClass()) {
4985 // Has a root. Current class is not a root.
4986 std::string RootClassName =
4987 ID->getClassInterface()->getSuperClass()->getNameAsString();
4988 SuperClassGV = GetClassGlobal(ObjCClassName + RootClassName);
4989 if (ID->getClassInterface()->getSuperClass()->isWeakImported())
4990 SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
4992 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
4993 CLASS_RO_GV = BuildClassRoTInitializer(flags,
4998 TClassName = ObjCClassName + ClassName;
4999 llvm::GlobalVariable *ClassMD =
5000 BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV,
5002 DefinedClasses.push_back(ClassMD);
5004 // Determine if this class is also "non-lazy".
5005 if (ImplementationIsNonLazy(ID))
5006 DefinedNonLazyClasses.push_back(ClassMD);
5008 // Force the definition of the EHType if necessary.
5009 if (flags & CLS_EXCEPTION)
5010 GetInterfaceEHType(ID->getClassInterface(), true);
5011 // Make sure method definition entries are all clear for next implementation.
5012 MethodDefinitions.clear();
5015 /// GenerateProtocolRef - This routine is called to generate code for
5016 /// a protocol reference expression; as in:
5018 /// @protocol(Proto1);
5020 /// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1
5021 /// which will hold address of the protocol meta-data.
5023 llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CGBuilderTy &Builder,
5024 const ObjCProtocolDecl *PD) {
5026 // This routine is called for @protocol only. So, we must build definition
5027 // of protocol's meta-data (not a reference to it!)
5029 llvm::Constant *Init =
5030 llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD),
5031 ObjCTypes.ExternalProtocolPtrTy);
5033 std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_");
5034 ProtocolName += PD->getName();
5036 llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
5038 return Builder.CreateLoad(PTGV, "tmp");
5039 PTGV = new llvm::GlobalVariable(
5041 Init->getType(), false,
5042 llvm::GlobalValue::WeakAnyLinkage,
5045 PTGV->setSection("__DATA, __objc_protorefs, coalesced, no_dead_strip");
5046 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5047 CGM.AddUsedGlobal(PTGV);
5048 return Builder.CreateLoad(PTGV, "tmp");
5051 /// GenerateCategory - Build metadata for a category implementation.
5052 /// struct _category_t {
5053 /// const char * const name;
5054 /// struct _class_t *const cls;
5055 /// const struct _method_list_t * const instance_methods;
5056 /// const struct _method_list_t * const class_methods;
5057 /// const struct _protocol_list_t * const protocols;
5058 /// const struct _prop_list_t * const properties;
5061 void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
5062 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
5063 const char *Prefix = "\01l_OBJC_$_CATEGORY_";
5064 std::string ExtCatName(Prefix + Interface->getNameAsString()+
5065 "_$_" + OCD->getNameAsString());
5066 std::string ExtClassName(getClassSymbolPrefix() +
5067 Interface->getNameAsString());
5069 std::vector<llvm::Constant*> Values(6);
5070 Values[0] = GetClassName(OCD->getIdentifier());
5071 // meta-class entry symbol
5072 llvm::GlobalVariable *ClassGV = GetClassGlobal(ExtClassName);
5073 if (Interface->isWeakImported())
5074 ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
5076 Values[1] = ClassGV;
5077 std::vector<llvm::Constant*> Methods;
5078 std::string MethodListName(Prefix);
5079 MethodListName += "INSTANCE_METHODS_" + Interface->getNameAsString() +
5080 "_$_" + OCD->getNameAsString();
5082 for (ObjCCategoryImplDecl::instmeth_iterator
5083 i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
5084 // Instance methods should always be defined.
5085 Methods.push_back(GetMethodConstant(*i));
5088 Values[2] = EmitMethodList(MethodListName,
5089 "__DATA, __objc_const",
5092 MethodListName = Prefix;
5093 MethodListName += "CLASS_METHODS_" + Interface->getNameAsString() + "_$_" +
5094 OCD->getNameAsString();
5096 for (ObjCCategoryImplDecl::classmeth_iterator
5097 i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
5098 // Class methods should always be defined.
5099 Methods.push_back(GetMethodConstant(*i));
5102 Values[3] = EmitMethodList(MethodListName,
5103 "__DATA, __objc_const",
5105 const ObjCCategoryDecl *Category =
5106 Interface->FindCategoryDeclaration(OCD->getIdentifier());
5108 llvm::SmallString<256> ExtName;
5109 llvm::raw_svector_ostream(ExtName) << Interface->getName() << "_$_"
5111 Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_"
5112 + Interface->getName() + "_$_"
5113 + Category->getName(),
5114 Category->protocol_begin(),
5115 Category->protocol_end());
5116 Values[5] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
5117 OCD, Category, ObjCTypes);
5119 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
5120 Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
5123 llvm::Constant *Init =
5124 llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy,
5126 llvm::GlobalVariable *GCATV
5127 = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CategorynfABITy,
5129 llvm::GlobalValue::InternalLinkage,
5132 GCATV->setAlignment(
5133 CGM.getTargetData().getABITypeAlignment(ObjCTypes.CategorynfABITy));
5134 GCATV->setSection("__DATA, __objc_const");
5135 CGM.AddUsedGlobal(GCATV);
5136 DefinedCategories.push_back(GCATV);
5138 // Determine if this category is also "non-lazy".
5139 if (ImplementationIsNonLazy(OCD))
5140 DefinedNonLazyCategories.push_back(GCATV);
5141 // method definition entries must be clear for next implementation.
5142 MethodDefinitions.clear();
5145 /// GetMethodConstant - Return a struct objc_method constant for the
5146 /// given method if it has been defined. The result is null if the
5147 /// method has not been defined. The return value has type MethodPtrTy.
5148 llvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant(
5149 const ObjCMethodDecl *MD) {
5150 llvm::Function *Fn = GetMethodDefinition(MD);
5154 std::vector<llvm::Constant*> Method(3);
5156 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
5157 ObjCTypes.SelectorPtrTy);
5158 Method[1] = GetMethodVarType(MD);
5159 Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy);
5160 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
5163 /// EmitMethodList - Build meta-data for method declarations
5164 /// struct _method_list_t {
5165 /// uint32_t entsize; // sizeof(struct _objc_method)
5166 /// uint32_t method_count;
5167 /// struct _objc_method method_list[method_count];
5170 llvm::Constant *CGObjCNonFragileABIMac::EmitMethodList(llvm::Twine Name,
5171 const char *Section,
5172 const ConstantVector &Methods) {
5173 // Return null for empty list.
5174 if (Methods.empty())
5175 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
5177 std::vector<llvm::Constant*> Values(3);
5178 // sizeof(struct _objc_method)
5179 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.MethodTy);
5180 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
5182 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
5183 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
5185 Values[2] = llvm::ConstantArray::get(AT, Methods);
5186 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
5188 llvm::GlobalVariable *GV =
5189 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5190 llvm::GlobalValue::InternalLinkage,
5194 CGM.getTargetData().getABITypeAlignment(Init->getType()));
5195 GV->setSection(Section);
5196 CGM.AddUsedGlobal(GV);
5197 return llvm::ConstantExpr::getBitCast(GV,
5198 ObjCTypes.MethodListnfABIPtrTy);
5201 /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
5203 llvm::GlobalVariable *
5204 CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
5205 const ObjCIvarDecl *Ivar) {
5206 const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
5207 std::string Name = "OBJC_IVAR_$_" + Container->getNameAsString() +
5208 '.' + Ivar->getNameAsString();
5209 llvm::GlobalVariable *IvarOffsetGV =
5210 CGM.getModule().getGlobalVariable(Name);
5213 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.LongTy,
5215 llvm::GlobalValue::ExternalLinkage,
5218 return IvarOffsetGV;
5222 CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
5223 const ObjCIvarDecl *Ivar,
5224 unsigned long int Offset) {
5225 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
5226 IvarOffsetGV->setInitializer(llvm::ConstantInt::get(ObjCTypes.LongTy,
5228 IvarOffsetGV->setAlignment(
5229 CGM.getTargetData().getABITypeAlignment(ObjCTypes.LongTy));
5231 // FIXME: This matches gcc, but shouldn't the visibility be set on the use as
5232 // well (i.e., in ObjCIvarOffsetVariable).
5233 if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
5234 Ivar->getAccessControl() == ObjCIvarDecl::Package ||
5235 ID->getVisibility() == HiddenVisibility)
5236 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5238 IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
5239 IvarOffsetGV->setSection("__DATA, __objc_ivar");
5240 return IvarOffsetGV;
5243 /// EmitIvarList - Emit the ivar list for the given
5244 /// implementation. The return value has type
5245 /// IvarListnfABIPtrTy.
5246 /// struct _ivar_t {
5247 /// unsigned long int *offset; // pointer to ivar offset location
5250 /// uint32_t alignment;
5253 /// struct _ivar_list_t {
5254 /// uint32 entsize; // sizeof(struct _ivar_t)
5256 /// struct _iver_t list[count];
5260 llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
5261 const ObjCImplementationDecl *ID) {
5263 std::vector<llvm::Constant*> Ivars, Ivar(5);
5265 const ObjCInterfaceDecl *OID = ID->getClassInterface();
5266 assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface");
5268 // FIXME. Consolidate this with similar code in GenerateClass.
5270 // Collect declared and synthesized ivars in a small vector.
5271 llvm::SmallVector<ObjCIvarDecl*, 16> OIvars;
5272 CGM.getContext().ShallowCollectObjCIvars(OID, OIvars);
5274 for (unsigned i = 0, e = OIvars.size(); i != e; ++i) {
5275 ObjCIvarDecl *IVD = OIvars[i];
5276 // Ignore unnamed bit-fields.
5277 if (!IVD->getDeclName())
5279 Ivar[0] = EmitIvarOffsetVar(ID->getClassInterface(), IVD,
5280 ComputeIvarBaseOffset(CGM, ID, IVD));
5281 Ivar[1] = GetMethodVarName(IVD->getIdentifier());
5282 Ivar[2] = GetMethodVarType(IVD);
5283 const llvm::Type *FieldTy =
5284 CGM.getTypes().ConvertTypeForMem(IVD->getType());
5285 unsigned Size = CGM.getTargetData().getTypeAllocSize(FieldTy);
5286 unsigned Align = CGM.getContext().getPreferredTypeAlign(
5287 IVD->getType().getTypePtr()) >> 3;
5288 Align = llvm::Log2_32(Align);
5289 Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align);
5290 // NOTE. Size of a bitfield does not match gcc's, because of the
5291 // way bitfields are treated special in each. But I am told that
5292 // 'size' for bitfield ivars is ignored by the runtime so it does
5293 // not matter. If it matters, there is enough info to get the
5295 Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
5296 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar));
5298 // Return null for empty list.
5300 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
5301 std::vector<llvm::Constant*> Values(3);
5302 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.IvarnfABITy);
5303 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
5304 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
5305 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy,
5307 Values[2] = llvm::ConstantArray::get(AT, Ivars);
5308 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
5309 const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_";
5310 llvm::GlobalVariable *GV =
5311 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5312 llvm::GlobalValue::InternalLinkage,
5314 Prefix + OID->getName());
5316 CGM.getTargetData().getABITypeAlignment(Init->getType()));
5317 GV->setSection("__DATA, __objc_const");
5319 CGM.AddUsedGlobal(GV);
5320 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
5323 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
5324 const ObjCProtocolDecl *PD) {
5325 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
5328 // We use the initializer as a marker of whether this is a forward
5329 // reference or not. At module finalization we add the empty
5330 // contents for protocols which were referenced but never defined.
5332 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, false,
5333 llvm::GlobalValue::ExternalLinkage,
5335 "\01l_OBJC_PROTOCOL_$_" + PD->getName());
5336 Entry->setSection("__DATA,__datacoal_nt,coalesced");
5342 /// GetOrEmitProtocol - Generate the protocol meta-data:
5344 /// struct _protocol_t {
5346 /// const char * const protocol_name;
5347 /// const struct _protocol_list_t * protocol_list; // super protocols
5348 /// const struct method_list_t * const instance_methods;
5349 /// const struct method_list_t * const class_methods;
5350 /// const struct method_list_t *optionalInstanceMethods;
5351 /// const struct method_list_t *optionalClassMethods;
5352 /// const struct _prop_list_t * properties;
5353 /// const uint32_t size; // sizeof(struct _protocol_t)
5354 /// const uint32_t flags; // = 0
5359 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
5360 const ObjCProtocolDecl *PD) {
5361 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
5363 // Early exit if a defining object has already been generated.
5364 if (Entry && Entry->hasInitializer())
5367 // Construct method lists.
5368 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
5369 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
5370 for (ObjCProtocolDecl::instmeth_iterator
5371 i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
5372 ObjCMethodDecl *MD = *i;
5373 llvm::Constant *C = GetMethodDescriptionConstant(MD);
5375 return GetOrEmitProtocolRef(PD);
5377 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
5378 OptInstanceMethods.push_back(C);
5380 InstanceMethods.push_back(C);
5384 for (ObjCProtocolDecl::classmeth_iterator
5385 i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
5386 ObjCMethodDecl *MD = *i;
5387 llvm::Constant *C = GetMethodDescriptionConstant(MD);
5389 return GetOrEmitProtocolRef(PD);
5391 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
5392 OptClassMethods.push_back(C);
5394 ClassMethods.push_back(C);
5398 std::vector<llvm::Constant*> Values(10);
5400 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy);
5401 Values[1] = GetClassName(PD->getIdentifier());
5402 Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getName(),
5403 PD->protocol_begin(),
5404 PD->protocol_end());
5406 Values[3] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_"
5408 "__DATA, __objc_const",
5410 Values[4] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_"
5412 "__DATA, __objc_const",
5414 Values[5] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_"
5416 "__DATA, __objc_const",
5417 OptInstanceMethods);
5418 Values[6] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_"
5420 "__DATA, __objc_const",
5422 Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getName(),
5425 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
5426 Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
5427 Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy);
5428 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy,
5432 // Already created, fix the linkage and update the initializer.
5433 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
5434 Entry->setInitializer(Init);
5437 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
5438 false, llvm::GlobalValue::WeakAnyLinkage, Init,
5439 "\01l_OBJC_PROTOCOL_$_" + PD->getName());
5440 Entry->setAlignment(
5441 CGM.getTargetData().getABITypeAlignment(ObjCTypes.ProtocolnfABITy));
5442 Entry->setSection("__DATA,__datacoal_nt,coalesced");
5444 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
5445 CGM.AddUsedGlobal(Entry);
5447 // Use this protocol meta-data to build protocol list table in section
5448 // __DATA, __objc_protolist
5449 llvm::GlobalVariable *PTGV =
5450 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy,
5451 false, llvm::GlobalValue::WeakAnyLinkage, Entry,
5452 "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getName());
5454 CGM.getTargetData().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
5455 PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip");
5456 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5457 CGM.AddUsedGlobal(PTGV);
5461 /// EmitProtocolList - Generate protocol list meta-data:
5463 /// struct _protocol_list_t {
5464 /// long protocol_count; // Note, this is 32/64 bit
5465 /// struct _protocol_t[protocol_count];
5470 CGObjCNonFragileABIMac::EmitProtocolList(llvm::Twine Name,
5471 ObjCProtocolDecl::protocol_iterator begin,
5472 ObjCProtocolDecl::protocol_iterator end) {
5473 std::vector<llvm::Constant*> ProtocolRefs;
5475 // Just return null for empty protocol lists
5477 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
5479 // FIXME: We shouldn't need to do this lookup here, should we?
5480 llvm::SmallString<256> TmpName;
5481 Name.toVector(TmpName);
5482 llvm::GlobalVariable *GV =
5483 CGM.getModule().getGlobalVariable(TmpName.str(), true);
5485 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
5487 for (; begin != end; ++begin)
5488 ProtocolRefs.push_back(GetProtocolRef(*begin)); // Implemented???
5490 // This list is null terminated.
5491 ProtocolRefs.push_back(llvm::Constant::getNullValue(
5492 ObjCTypes.ProtocolnfABIPtrTy));
5494 std::vector<llvm::Constant*> Values(2);
5496 llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
5498 llvm::ConstantArray::get(
5499 llvm::ArrayType::get(ObjCTypes.ProtocolnfABIPtrTy,
5500 ProtocolRefs.size()),
5503 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
5504 GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5505 llvm::GlobalValue::InternalLinkage,
5508 GV->setSection("__DATA, __objc_const");
5510 CGM.getTargetData().getABITypeAlignment(Init->getType()));
5511 CGM.AddUsedGlobal(GV);
5512 return llvm::ConstantExpr::getBitCast(GV,
5513 ObjCTypes.ProtocolListnfABIPtrTy);
5516 /// GetMethodDescriptionConstant - This routine build following meta-data:
5517 /// struct _objc_method {
5519 /// char *method_type;
5524 CGObjCNonFragileABIMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
5525 std::vector<llvm::Constant*> Desc(3);
5527 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
5528 ObjCTypes.SelectorPtrTy);
5529 Desc[1] = GetMethodVarType(MD);
5533 // Protocol methods have no implementation. So, this entry is always NULL.
5534 Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
5535 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc);
5538 /// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference.
5539 /// This code gen. amounts to generating code for:
5541 /// (type *)((char *)base + _OBJC_IVAR_$_.ivar;
5544 LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
5545 CodeGen::CodeGenFunction &CGF,
5547 llvm::Value *BaseValue,
5548 const ObjCIvarDecl *Ivar,
5549 unsigned CVRQualifiers) {
5550 ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCObjectType>()->getInterface();
5551 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
5552 EmitIvarOffset(CGF, ID, Ivar));
5555 llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(
5556 CodeGen::CodeGenFunction &CGF,
5557 const ObjCInterfaceDecl *Interface,
5558 const ObjCIvarDecl *Ivar) {
5559 return CGF.Builder.CreateLoad(ObjCIvarOffsetVariable(Interface, Ivar),"ivar");
5562 static void appendSelectorForMessageRefTable(std::string &buffer,
5563 Selector selector) {
5564 if (selector.isUnarySelector()) {
5565 buffer += selector.getNameForSlot(0);
5569 for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) {
5570 buffer += selector.getNameForSlot(i);
5575 /// Emit a "v-table" message send. We emit a weak hidden-visibility
5576 /// struct, initially containing the selector pointer and a pointer to
5577 /// a "fixup" variant of the appropriate objc_msgSend. To call, we
5578 /// load and call the function pointer, passing the address of the
5579 /// struct as the second parameter. The runtime determines whether
5580 /// the selector is currently emitted using vtable dispatch; if so, it
5581 /// substitutes a stub function which simply tail-calls through the
5582 /// appropriate vtable slot, and if not, it substitues a stub function
5583 /// which tail-calls objc_msgSend. Both stubs adjust the selector
5584 /// argument to correctly point to the selector.
5586 CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF,
5587 ReturnValueSlot returnSlot,
5588 QualType resultType,
5593 const CallArgList &formalArgs,
5594 const ObjCMethodDecl *method) {
5595 // Compute the actual arguments.
5598 // First argument: the receiver / super-call structure.
5600 arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy);
5601 args.add(RValue::get(arg0), arg0Type);
5603 // Second argument: a pointer to the message ref structure. Leave
5604 // the actual argument value blank for now.
5605 args.add(RValue::get(0), ObjCTypes.MessageRefCPtrTy);
5607 args.insert(args.end(), formalArgs.begin(), formalArgs.end());
5609 const CGFunctionInfo &fnInfo =
5610 CGM.getTypes().getFunctionInfo(resultType, args,
5611 FunctionType::ExtInfo());
5613 NullReturnState nullReturn;
5615 // Find the function to call and the mangled name for the message
5616 // ref structure. Using a different mangled name wouldn't actually
5617 // be a problem; it would just be a waste.
5619 // The runtime currently never uses vtable dispatch for anything
5620 // except normal, non-super message-sends.
5621 // FIXME: don't use this for that.
5622 llvm::Constant *fn = 0;
5623 std::string messageRefName("\01l_");
5624 if (CGM.ReturnTypeUsesSRet(fnInfo)) {
5626 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
5627 messageRefName += "objc_msgSendSuper2_stret_fixup";
5629 nullReturn.init(CGF, arg0);
5630 fn = ObjCTypes.getMessageSendStretFixupFn();
5631 messageRefName += "objc_msgSend_stret_fixup";
5633 } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) {
5634 fn = ObjCTypes.getMessageSendFpretFixupFn();
5635 messageRefName += "objc_msgSend_fpret_fixup";
5638 fn = ObjCTypes.getMessageSendSuper2FixupFn();
5639 messageRefName += "objc_msgSendSuper2_fixup";
5641 fn = ObjCTypes.getMessageSendFixupFn();
5642 messageRefName += "objc_msgSend_fixup";
5645 assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend");
5646 messageRefName += '_';
5648 // Append the selector name, except use underscores anywhere we
5649 // would have used colons.
5650 appendSelectorForMessageRefTable(messageRefName, selector);
5652 llvm::GlobalVariable *messageRef
5653 = CGM.getModule().getGlobalVariable(messageRefName);
5655 // Build the message ref structure.
5656 llvm::Constant *values[] = { fn, GetMethodVarName(selector) };
5657 llvm::Constant *init =
5658 llvm::ConstantStruct::get(VMContext, values, 2, false);
5659 messageRef = new llvm::GlobalVariable(CGM.getModule(),
5662 llvm::GlobalValue::WeakAnyLinkage,
5665 messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
5666 messageRef->setAlignment(16);
5667 messageRef->setSection("__DATA, __objc_msgrefs, coalesced");
5670 CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy);
5672 // Update the message ref argument.
5673 args[1].RV = RValue::get(mref);
5675 // Load the function to call from the message ref table.
5676 llvm::Value *callee = CGF.Builder.CreateStructGEP(mref, 0);
5677 callee = CGF.Builder.CreateLoad(callee, "msgSend_fn");
5679 bool variadic = method ? method->isVariadic() : false;
5680 const llvm::FunctionType *fnType =
5681 CGF.getTypes().GetFunctionType(fnInfo, variadic);
5682 callee = CGF.Builder.CreateBitCast(callee,
5683 llvm::PointerType::getUnqual(fnType));
5685 RValue result = CGF.EmitCall(fnInfo, callee, returnSlot, args);
5686 return nullReturn.complete(CGF, result, resultType);
5689 /// Generate code for a message send expression in the nonfragile abi.
5691 CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
5692 ReturnValueSlot Return,
5693 QualType ResultType,
5695 llvm::Value *Receiver,
5696 const CallArgList &CallArgs,
5697 const ObjCInterfaceDecl *Class,
5698 const ObjCMethodDecl *Method) {
5699 return isVTableDispatchedSelector(Sel)
5700 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
5701 Receiver, CGF.getContext().getObjCIdType(),
5702 false, CallArgs, Method)
5703 : EmitMessageSend(CGF, Return, ResultType,
5704 EmitSelector(CGF.Builder, Sel),
5705 Receiver, CGF.getContext().getObjCIdType(),
5706 false, CallArgs, Method, ObjCTypes);
5709 llvm::GlobalVariable *
5710 CGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name) {
5711 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
5714 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABITy,
5715 false, llvm::GlobalValue::ExternalLinkage,
5722 llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CGBuilderTy &Builder,
5723 const ObjCInterfaceDecl *ID) {
5724 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
5727 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
5728 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
5730 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
5731 false, llvm::GlobalValue::InternalLinkage,
5733 "\01L_OBJC_CLASSLIST_REFERENCES_$_");
5734 Entry->setAlignment(
5735 CGM.getTargetData().getABITypeAlignment(
5736 ObjCTypes.ClassnfABIPtrTy));
5737 Entry->setSection("__DATA, __objc_classrefs, regular, no_dead_strip");
5738 CGM.AddUsedGlobal(Entry);
5741 return Builder.CreateLoad(Entry, "tmp");
5745 CGObjCNonFragileABIMac::EmitSuperClassRef(CGBuilderTy &Builder,
5746 const ObjCInterfaceDecl *ID) {
5747 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
5750 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
5751 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
5753 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
5754 false, llvm::GlobalValue::InternalLinkage,
5756 "\01L_OBJC_CLASSLIST_SUP_REFS_$_");
5757 Entry->setAlignment(
5758 CGM.getTargetData().getABITypeAlignment(
5759 ObjCTypes.ClassnfABIPtrTy));
5760 Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
5761 CGM.AddUsedGlobal(Entry);
5764 return Builder.CreateLoad(Entry, "tmp");
5767 /// EmitMetaClassRef - Return a Value * of the address of _class_t
5770 llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CGBuilderTy &Builder,
5771 const ObjCInterfaceDecl *ID) {
5772 llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];
5774 return Builder.CreateLoad(Entry, "tmp");
5776 std::string MetaClassName(getMetaclassSymbolPrefix() + ID->getNameAsString());
5777 llvm::GlobalVariable *MetaClassGV = GetClassGlobal(MetaClassName);
5779 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, false,
5780 llvm::GlobalValue::InternalLinkage,
5782 "\01L_OBJC_CLASSLIST_SUP_REFS_$_");
5783 Entry->setAlignment(
5784 CGM.getTargetData().getABITypeAlignment(
5785 ObjCTypes.ClassnfABIPtrTy));
5787 Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
5788 CGM.AddUsedGlobal(Entry);
5790 return Builder.CreateLoad(Entry, "tmp");
5793 /// GetClass - Return a reference to the class for the given interface
5795 llvm::Value *CGObjCNonFragileABIMac::GetClass(CGBuilderTy &Builder,
5796 const ObjCInterfaceDecl *ID) {
5797 if (ID->isWeakImported()) {
5798 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
5799 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
5800 ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
5803 return EmitClassRef(Builder, ID);
5806 /// Generates a message send where the super is the receiver. This is
5807 /// a message send to self with special delivery semantics indicating
5808 /// which class's method should be called.
5810 CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
5811 ReturnValueSlot Return,
5812 QualType ResultType,
5814 const ObjCInterfaceDecl *Class,
5815 bool isCategoryImpl,
5816 llvm::Value *Receiver,
5817 bool IsClassMessage,
5818 const CodeGen::CallArgList &CallArgs,
5819 const ObjCMethodDecl *Method) {
5821 // Create and init a super structure; this is a (receiver, class)
5822 // pair we will pass to objc_msgSendSuper.
5823 llvm::Value *ObjCSuper =
5824 CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super");
5826 llvm::Value *ReceiverAsObject =
5827 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
5828 CGF.Builder.CreateStore(ReceiverAsObject,
5829 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
5831 // If this is a class message the metaclass is passed as the target.
5832 llvm::Value *Target;
5833 if (IsClassMessage) {
5834 if (isCategoryImpl) {
5835 // Message sent to "super' in a class method defined in
5836 // a category implementation.
5837 Target = EmitClassRef(CGF.Builder, Class);
5838 Target = CGF.Builder.CreateStructGEP(Target, 0);
5839 Target = CGF.Builder.CreateLoad(Target);
5841 Target = EmitMetaClassRef(CGF.Builder, Class);
5843 Target = EmitSuperClassRef(CGF.Builder, Class);
5845 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
5847 const llvm::Type *ClassTy =
5848 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
5849 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
5850 CGF.Builder.CreateStore(Target,
5851 CGF.Builder.CreateStructGEP(ObjCSuper, 1));
5853 return (isVTableDispatchedSelector(Sel))
5854 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
5855 ObjCSuper, ObjCTypes.SuperPtrCTy,
5856 true, CallArgs, Method)
5857 : EmitMessageSend(CGF, Return, ResultType,
5858 EmitSelector(CGF.Builder, Sel),
5859 ObjCSuper, ObjCTypes.SuperPtrCTy,
5860 true, CallArgs, Method, ObjCTypes);
5863 llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CGBuilderTy &Builder,
5864 Selector Sel, bool lval) {
5865 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
5868 llvm::Constant *Casted =
5869 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
5870 ObjCTypes.SelectorPtrTy);
5872 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.SelectorPtrTy, false,
5873 llvm::GlobalValue::InternalLinkage,
5874 Casted, "\01L_OBJC_SELECTOR_REFERENCES_");
5875 Entry->setSection("__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
5876 CGM.AddUsedGlobal(Entry);
5881 return Builder.CreateLoad(Entry, "tmp");
5883 /// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
5884 /// objc_assign_ivar (id src, id *dst, ptrdiff_t)
5886 void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
5889 llvm::Value *ivarOffset) {
5890 const llvm::Type * SrcTy = src->getType();
5891 if (!isa<llvm::PointerType>(SrcTy)) {
5892 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
5893 assert(Size <= 8 && "does not support size > 8");
5894 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
5895 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
5896 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5898 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5899 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
5900 CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(),
5901 src, dst, ivarOffset);
5905 /// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
5906 /// objc_assign_strongCast (id src, id *dst)
5908 void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
5909 CodeGen::CodeGenFunction &CGF,
5910 llvm::Value *src, llvm::Value *dst) {
5911 const llvm::Type * SrcTy = src->getType();
5912 if (!isa<llvm::PointerType>(SrcTy)) {
5913 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
5914 assert(Size <= 8 && "does not support size > 8");
5915 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
5916 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
5917 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5919 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5920 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
5921 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(),
5922 src, dst, "weakassign");
5926 void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
5927 CodeGen::CodeGenFunction &CGF,
5928 llvm::Value *DestPtr,
5929 llvm::Value *SrcPtr,
5930 llvm::Value *Size) {
5931 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
5932 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
5933 CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(),
5934 DestPtr, SrcPtr, Size);
5938 /// EmitObjCWeakRead - Code gen for loading value of a __weak
5939 /// object: objc_read_weak (id *src)
5941 llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
5942 CodeGen::CodeGenFunction &CGF,
5943 llvm::Value *AddrWeakObj) {
5944 const llvm::Type* DestTy =
5945 cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
5946 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
5947 llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(),
5948 AddrWeakObj, "weakread");
5949 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
5953 /// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
5954 /// objc_assign_weak (id src, id *dst)
5956 void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
5957 llvm::Value *src, llvm::Value *dst) {
5958 const llvm::Type * SrcTy = src->getType();
5959 if (!isa<llvm::PointerType>(SrcTy)) {
5960 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
5961 assert(Size <= 8 && "does not support size > 8");
5962 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
5963 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
5964 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5966 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5967 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
5968 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(),
5969 src, dst, "weakassign");
5973 /// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
5974 /// objc_assign_global (id src, id *dst)
5976 void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
5977 llvm::Value *src, llvm::Value *dst,
5979 const llvm::Type * SrcTy = src->getType();
5980 if (!isa<llvm::PointerType>(SrcTy)) {
5981 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
5982 assert(Size <= 8 && "does not support size > 8");
5983 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
5984 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
5985 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5987 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5988 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
5990 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(),
5991 src, dst, "globalassign");
5993 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(),
5994 src, dst, "threadlocalassign");
5999 CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
6000 const ObjCAtSynchronizedStmt &S) {
6001 EmitAtSynchronizedStmt(CGF, S,
6002 cast<llvm::Function>(ObjCTypes.getSyncEnterFn()),
6003 cast<llvm::Function>(ObjCTypes.getSyncExitFn()));
6007 CGObjCNonFragileABIMac::GetEHType(QualType T) {
6008 // There's a particular fixed type info for 'id'.
6009 if (T->isObjCIdType() ||
6010 T->isObjCQualifiedIdType()) {
6011 llvm::Constant *IDEHType =
6012 CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id");
6015 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy,
6017 llvm::GlobalValue::ExternalLinkage,
6018 0, "OBJC_EHTYPE_id");
6022 // All other types should be Objective-C interface pointer types.
6023 const ObjCObjectPointerType *PT =
6024 T->getAs<ObjCObjectPointerType>();
6025 assert(PT && "Invalid @catch type.");
6026 const ObjCInterfaceType *IT = PT->getInterfaceType();
6027 assert(IT && "Invalid @catch type.");
6028 return GetInterfaceEHType(IT->getDecl(), false);
6031 void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
6032 const ObjCAtTryStmt &S) {
6033 EmitTryCatchStmt(CGF, S,
6034 cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()),
6035 cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()),
6036 cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn()));
6039 /// EmitThrowStmt - Generate code for a throw statement.
6040 void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
6041 const ObjCAtThrowStmt &S) {
6042 if (const Expr *ThrowExpr = S.getThrowExpr()) {
6043 llvm::Value *Exception = CGF.EmitScalarExpr(ThrowExpr);
6044 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy,
6046 llvm::Value *Args[] = { Exception };
6047 CGF.EmitCallOrInvoke(ObjCTypes.getExceptionThrowFn(),
6049 .setDoesNotReturn();
6051 CGF.EmitCallOrInvoke(ObjCTypes.getExceptionRethrowFn(), 0, 0)
6052 .setDoesNotReturn();
6055 CGF.Builder.CreateUnreachable();
6056 CGF.Builder.ClearInsertionPoint();
6060 CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
6061 bool ForDefinition) {
6062 llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
6064 // If we don't need a definition, return the entry if found or check
6065 // if we use an external reference.
6066 if (!ForDefinition) {
6070 // If this type (or a super class) has the __objc_exception__
6071 // attribute, emit an external reference.
6072 if (hasObjCExceptionAttribute(CGM.getContext(), ID))
6074 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
6075 llvm::GlobalValue::ExternalLinkage,
6078 ID->getIdentifier()->getName()));
6081 // Otherwise we need to either make a new entry or fill in the
6083 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition");
6084 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
6085 std::string VTableName = "objc_ehtype_vtable";
6086 llvm::GlobalVariable *VTableGV =
6087 CGM.getModule().getGlobalVariable(VTableName);
6089 VTableGV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy,
6091 llvm::GlobalValue::ExternalLinkage,
6094 llvm::Value *VTableIdx =
6095 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 2);
6097 std::vector<llvm::Constant*> Values(3);
6098 Values[0] = llvm::ConstantExpr::getGetElementPtr(VTableGV, &VTableIdx, 1);
6099 Values[1] = GetClassName(ID->getIdentifier());
6100 Values[2] = GetClassGlobal(ClassName);
6101 llvm::Constant *Init =
6102 llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values);
6105 Entry->setInitializer(Init);
6107 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
6108 llvm::GlobalValue::WeakAnyLinkage,
6111 ID->getIdentifier()->getName()));
6114 if (CGM.getLangOptions().getVisibilityMode() == HiddenVisibility)
6115 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
6116 Entry->setAlignment(CGM.getTargetData().getABITypeAlignment(
6117 ObjCTypes.EHTypeTy));
6119 if (ForDefinition) {
6120 Entry->setSection("__DATA,__objc_const");
6121 Entry->setLinkage(llvm::GlobalValue::ExternalLinkage);
6123 Entry->setSection("__DATA,__datacoal_nt,coalesced");
6131 CodeGen::CGObjCRuntime *
6132 CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
6133 if (CGM.getLangOptions().ObjCNonFragileABI)
6134 return new CGObjCNonFragileABIMac(CGM);
6135 return new CGObjCMac(CGM);