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;
47 // FIXME: We should find a nicer way to make the labels for metadata, string
48 // concatenation is lame.
50 class ObjCCommonTypesHelper {
52 llvm::LLVMContext &VMContext;
55 // The types of these functions don't really matter because we
56 // should always bitcast before calling them.
58 /// id objc_msgSend (id, SEL, ...)
60 /// The default messenger, used for sends whose ABI is unchanged from
61 /// the all-integer/pointer case.
62 llvm::Constant *getMessageSendFn() const {
63 // Add the non-lazy-bind attribute, since objc_msgSend is likely to
65 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
66 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
69 llvm::Attribute::NonLazyBind);
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 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 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
92 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.DoubleTy,
94 "objc_msgSend_fpret");
98 /// _Complex long double objc_msgSend_fp2ret(id self, SEL op, ...)
100 /// The messenger used when the return value is returned in two values on the
101 /// x87 floating point stack; without a special entrypoint, the nil case
102 /// would be unbalanced. Only used on 64-bit X86.
103 llvm::Constant *getMessageSendFp2retFn() const {
104 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
105 llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(VMContext);
106 llvm::Type *resultType =
107 llvm::StructType::get(longDoubleType, longDoubleType, NULL);
109 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(resultType,
111 "objc_msgSend_fp2ret");
114 /// id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
116 /// The messenger used for super calls, which have different dispatch
117 /// semantics. The class passed is the superclass of the current
119 llvm::Constant *getMessageSendSuperFn() const {
120 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
121 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
123 "objc_msgSendSuper");
126 /// id objc_msgSendSuper2(struct objc_super *super, SEL op, ...)
128 /// A slightly different messenger used for super calls. The class
129 /// passed is the current class.
130 llvm::Constant *getMessageSendSuperFn2() const {
131 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
132 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
134 "objc_msgSendSuper2");
137 /// void objc_msgSendSuper_stret(void *stretAddr, struct objc_super *super,
140 /// The messenger used for super calls which return an aggregate indirectly.
141 llvm::Constant *getMessageSendSuperStretFn() const {
142 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
143 return CGM.CreateRuntimeFunction(
144 llvm::FunctionType::get(CGM.VoidTy, params, true),
145 "objc_msgSendSuper_stret");
148 /// void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super,
151 /// objc_msgSendSuper_stret with the super2 semantics.
152 llvm::Constant *getMessageSendSuperStretFn2() const {
153 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
154 return CGM.CreateRuntimeFunction(
155 llvm::FunctionType::get(CGM.VoidTy, params, true),
156 "objc_msgSendSuper2_stret");
159 llvm::Constant *getMessageSendSuperFpretFn() const {
160 // There is no objc_msgSendSuper_fpret? How can that work?
161 return getMessageSendSuperFn();
164 llvm::Constant *getMessageSendSuperFpretFn2() const {
165 // There is no objc_msgSendSuper_fpret? How can that work?
166 return getMessageSendSuperFn2();
170 CodeGen::CodeGenModule &CGM;
173 llvm::Type *ShortTy, *IntTy, *LongTy, *LongLongTy;
174 llvm::Type *Int8PtrTy, *Int8PtrPtrTy;
176 /// ObjectPtrTy - LLVM type for object handles (typeof(id))
177 llvm::Type *ObjectPtrTy;
179 /// PtrObjectPtrTy - LLVM type for id *
180 llvm::Type *PtrObjectPtrTy;
182 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
183 llvm::Type *SelectorPtrTy;
186 /// ProtocolPtrTy - LLVM type for external protocol handles
187 /// (typeof(Protocol))
188 llvm::Type *ExternalProtocolPtrTy;
191 llvm::Type *getExternalProtocolPtrTy() {
192 if (!ExternalProtocolPtrTy) {
193 // FIXME: It would be nice to unify this with the opaque type, so that the
194 // IR comes out a bit cleaner.
195 CodeGen::CodeGenTypes &Types = CGM.getTypes();
196 ASTContext &Ctx = CGM.getContext();
197 llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
198 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
201 return ExternalProtocolPtrTy;
204 // SuperCTy - clang type for struct objc_super.
206 // SuperPtrCTy - clang type for struct objc_super *.
207 QualType SuperPtrCTy;
209 /// SuperTy - LLVM type for struct objc_super.
210 llvm::StructType *SuperTy;
211 /// SuperPtrTy - LLVM type for struct objc_super *.
212 llvm::Type *SuperPtrTy;
214 /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
215 /// in GCC parlance).
216 llvm::StructType *PropertyTy;
218 /// PropertyListTy - LLVM type for struct objc_property_list
219 /// (_prop_list_t in GCC parlance).
220 llvm::StructType *PropertyListTy;
221 /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
222 llvm::Type *PropertyListPtrTy;
224 // MethodTy - LLVM type for struct objc_method.
225 llvm::StructType *MethodTy;
227 /// CacheTy - LLVM type for struct objc_cache.
229 /// CachePtrTy - LLVM type for struct objc_cache *.
230 llvm::Type *CachePtrTy;
232 llvm::Constant *getGetPropertyFn() {
233 CodeGen::CodeGenTypes &Types = CGM.getTypes();
234 ASTContext &Ctx = CGM.getContext();
235 // id objc_getProperty (id, SEL, ptrdiff_t, bool)
236 SmallVector<CanQualType,4> Params;
237 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
238 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
239 Params.push_back(IdType);
240 Params.push_back(SelType);
241 Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
242 Params.push_back(Ctx.BoolTy);
243 llvm::FunctionType *FTy =
244 Types.GetFunctionType(Types.arrangeFunctionType(IdType, Params,
245 FunctionType::ExtInfo(),
247 return CGM.CreateRuntimeFunction(FTy, "objc_getProperty");
250 llvm::Constant *getSetPropertyFn() {
251 CodeGen::CodeGenTypes &Types = CGM.getTypes();
252 ASTContext &Ctx = CGM.getContext();
253 // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool)
254 SmallVector<CanQualType,6> Params;
255 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
256 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
257 Params.push_back(IdType);
258 Params.push_back(SelType);
259 Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
260 Params.push_back(IdType);
261 Params.push_back(Ctx.BoolTy);
262 Params.push_back(Ctx.BoolTy);
263 llvm::FunctionType *FTy =
264 Types.GetFunctionType(Types.arrangeFunctionType(Ctx.VoidTy, Params,
265 FunctionType::ExtInfo(),
267 return CGM.CreateRuntimeFunction(FTy, "objc_setProperty");
270 llvm::Constant *getOptimizedSetPropertyFn(bool atomic, bool copy) {
271 CodeGen::CodeGenTypes &Types = CGM.getTypes();
272 ASTContext &Ctx = CGM.getContext();
273 // void objc_setProperty_atomic(id self, SEL _cmd,
274 // id newValue, ptrdiff_t offset);
275 // void objc_setProperty_nonatomic(id self, SEL _cmd,
276 // id newValue, ptrdiff_t offset);
277 // void objc_setProperty_atomic_copy(id self, SEL _cmd,
278 // id newValue, ptrdiff_t offset);
279 // void objc_setProperty_nonatomic_copy(id self, SEL _cmd,
280 // id newValue, ptrdiff_t offset);
282 SmallVector<CanQualType,4> Params;
283 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
284 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
285 Params.push_back(IdType);
286 Params.push_back(SelType);
287 Params.push_back(IdType);
288 Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
289 llvm::FunctionType *FTy =
290 Types.GetFunctionType(Types.arrangeFunctionType(Ctx.VoidTy, Params,
291 FunctionType::ExtInfo(),
295 name = "objc_setProperty_atomic_copy";
296 else if (atomic && !copy)
297 name = "objc_setProperty_atomic";
298 else if (!atomic && copy)
299 name = "objc_setProperty_nonatomic_copy";
301 name = "objc_setProperty_nonatomic";
303 return CGM.CreateRuntimeFunction(FTy, name);
306 llvm::Constant *getCopyStructFn() {
307 CodeGen::CodeGenTypes &Types = CGM.getTypes();
308 ASTContext &Ctx = CGM.getContext();
309 // void objc_copyStruct (void *, const void *, size_t, bool, bool)
310 SmallVector<CanQualType,5> Params;
311 Params.push_back(Ctx.VoidPtrTy);
312 Params.push_back(Ctx.VoidPtrTy);
313 Params.push_back(Ctx.LongTy);
314 Params.push_back(Ctx.BoolTy);
315 Params.push_back(Ctx.BoolTy);
316 llvm::FunctionType *FTy =
317 Types.GetFunctionType(Types.arrangeFunctionType(Ctx.VoidTy, Params,
318 FunctionType::ExtInfo(),
320 return CGM.CreateRuntimeFunction(FTy, "objc_copyStruct");
323 /// This routine declares and returns address of:
324 /// void objc_copyCppObjectAtomic(
325 /// void *dest, const void *src,
326 /// void (*copyHelper) (void *dest, const void *source));
327 llvm::Constant *getCppAtomicObjectFunction() {
328 CodeGen::CodeGenTypes &Types = CGM.getTypes();
329 ASTContext &Ctx = CGM.getContext();
330 /// void objc_copyCppObjectAtomic(void *dest, const void *src, void *helper);
331 SmallVector<CanQualType,3> Params;
332 Params.push_back(Ctx.VoidPtrTy);
333 Params.push_back(Ctx.VoidPtrTy);
334 Params.push_back(Ctx.VoidPtrTy);
335 llvm::FunctionType *FTy =
336 Types.GetFunctionType(Types.arrangeFunctionType(Ctx.VoidTy, Params,
337 FunctionType::ExtInfo(),
339 return CGM.CreateRuntimeFunction(FTy, "objc_copyCppObjectAtomic");
342 llvm::Constant *getEnumerationMutationFn() {
343 CodeGen::CodeGenTypes &Types = CGM.getTypes();
344 ASTContext &Ctx = CGM.getContext();
345 // void objc_enumerationMutation (id)
346 SmallVector<CanQualType,1> Params;
347 Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType()));
348 llvm::FunctionType *FTy =
349 Types.GetFunctionType(Types.arrangeFunctionType(Ctx.VoidTy, Params,
350 FunctionType::ExtInfo(),
352 return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
355 /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function.
356 llvm::Constant *getGcReadWeakFn() {
357 // id objc_read_weak (id *)
358 llvm::Type *args[] = { ObjectPtrTy->getPointerTo() };
359 llvm::FunctionType *FTy =
360 llvm::FunctionType::get(ObjectPtrTy, args, false);
361 return CGM.CreateRuntimeFunction(FTy, "objc_read_weak");
364 /// GcAssignWeakFn -- LLVM objc_assign_weak function.
365 llvm::Constant *getGcAssignWeakFn() {
366 // id objc_assign_weak (id, id *)
367 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
368 llvm::FunctionType *FTy =
369 llvm::FunctionType::get(ObjectPtrTy, args, false);
370 return CGM.CreateRuntimeFunction(FTy, "objc_assign_weak");
373 /// GcAssignGlobalFn -- LLVM objc_assign_global function.
374 llvm::Constant *getGcAssignGlobalFn() {
375 // id objc_assign_global(id, id *)
376 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
377 llvm::FunctionType *FTy =
378 llvm::FunctionType::get(ObjectPtrTy, args, false);
379 return CGM.CreateRuntimeFunction(FTy, "objc_assign_global");
382 /// GcAssignThreadLocalFn -- LLVM objc_assign_threadlocal function.
383 llvm::Constant *getGcAssignThreadLocalFn() {
384 // id objc_assign_threadlocal(id src, id * dest)
385 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
386 llvm::FunctionType *FTy =
387 llvm::FunctionType::get(ObjectPtrTy, args, false);
388 return CGM.CreateRuntimeFunction(FTy, "objc_assign_threadlocal");
391 /// GcAssignIvarFn -- LLVM objc_assign_ivar function.
392 llvm::Constant *getGcAssignIvarFn() {
393 // id objc_assign_ivar(id, id *, ptrdiff_t)
394 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo(),
396 llvm::FunctionType *FTy =
397 llvm::FunctionType::get(ObjectPtrTy, args, false);
398 return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar");
401 /// GcMemmoveCollectableFn -- LLVM objc_memmove_collectable function.
402 llvm::Constant *GcMemmoveCollectableFn() {
403 // void *objc_memmove_collectable(void *dst, const void *src, size_t size)
404 llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy };
405 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args, false);
406 return CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable");
409 /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function.
410 llvm::Constant *getGcAssignStrongCastFn() {
411 // id objc_assign_strongCast(id, id *)
412 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
413 llvm::FunctionType *FTy =
414 llvm::FunctionType::get(ObjectPtrTy, args, false);
415 return CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast");
418 /// ExceptionThrowFn - LLVM objc_exception_throw function.
419 llvm::Constant *getExceptionThrowFn() {
420 // void objc_exception_throw(id)
421 llvm::Type *args[] = { ObjectPtrTy };
422 llvm::FunctionType *FTy =
423 llvm::FunctionType::get(CGM.VoidTy, args, false);
424 return CGM.CreateRuntimeFunction(FTy, "objc_exception_throw");
427 /// ExceptionRethrowFn - LLVM objc_exception_rethrow function.
428 llvm::Constant *getExceptionRethrowFn() {
429 // void objc_exception_rethrow(void)
430 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, false);
431 return CGM.CreateRuntimeFunction(FTy, "objc_exception_rethrow");
434 /// SyncEnterFn - LLVM object_sync_enter function.
435 llvm::Constant *getSyncEnterFn() {
436 // void objc_sync_enter (id)
437 llvm::Type *args[] = { ObjectPtrTy };
438 llvm::FunctionType *FTy =
439 llvm::FunctionType::get(CGM.VoidTy, args, false);
440 return CGM.CreateRuntimeFunction(FTy, "objc_sync_enter");
443 /// SyncExitFn - LLVM object_sync_exit function.
444 llvm::Constant *getSyncExitFn() {
445 // void objc_sync_exit (id)
446 llvm::Type *args[] = { ObjectPtrTy };
447 llvm::FunctionType *FTy =
448 llvm::FunctionType::get(CGM.VoidTy, args, false);
449 return CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
452 llvm::Constant *getSendFn(bool IsSuper) const {
453 return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
456 llvm::Constant *getSendFn2(bool IsSuper) const {
457 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
460 llvm::Constant *getSendStretFn(bool IsSuper) const {
461 return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
464 llvm::Constant *getSendStretFn2(bool IsSuper) const {
465 return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
468 llvm::Constant *getSendFpretFn(bool IsSuper) const {
469 return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
472 llvm::Constant *getSendFpretFn2(bool IsSuper) const {
473 return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
476 llvm::Constant *getSendFp2retFn(bool IsSuper) const {
477 return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn();
480 llvm::Constant *getSendFp2RetFn2(bool IsSuper) const {
481 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn();
484 ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm);
485 ~ObjCCommonTypesHelper(){}
488 /// ObjCTypesHelper - Helper class that encapsulates lazy
489 /// construction of varies types used during ObjC generation.
490 class ObjCTypesHelper : public ObjCCommonTypesHelper {
492 /// SymtabTy - LLVM type for struct objc_symtab.
493 llvm::StructType *SymtabTy;
494 /// SymtabPtrTy - LLVM type for struct objc_symtab *.
495 llvm::Type *SymtabPtrTy;
496 /// ModuleTy - LLVM type for struct objc_module.
497 llvm::StructType *ModuleTy;
499 /// ProtocolTy - LLVM type for struct objc_protocol.
500 llvm::StructType *ProtocolTy;
501 /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
502 llvm::Type *ProtocolPtrTy;
503 /// ProtocolExtensionTy - LLVM type for struct
504 /// objc_protocol_extension.
505 llvm::StructType *ProtocolExtensionTy;
506 /// ProtocolExtensionTy - LLVM type for struct
507 /// objc_protocol_extension *.
508 llvm::Type *ProtocolExtensionPtrTy;
509 /// MethodDescriptionTy - LLVM type for struct
510 /// objc_method_description.
511 llvm::StructType *MethodDescriptionTy;
512 /// MethodDescriptionListTy - LLVM type for struct
513 /// objc_method_description_list.
514 llvm::StructType *MethodDescriptionListTy;
515 /// MethodDescriptionListPtrTy - LLVM type for struct
516 /// objc_method_description_list *.
517 llvm::Type *MethodDescriptionListPtrTy;
518 /// ProtocolListTy - LLVM type for struct objc_property_list.
519 llvm::StructType *ProtocolListTy;
520 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
521 llvm::Type *ProtocolListPtrTy;
522 /// CategoryTy - LLVM type for struct objc_category.
523 llvm::StructType *CategoryTy;
524 /// ClassTy - LLVM type for struct objc_class.
525 llvm::StructType *ClassTy;
526 /// ClassPtrTy - LLVM type for struct objc_class *.
527 llvm::Type *ClassPtrTy;
528 /// ClassExtensionTy - LLVM type for struct objc_class_ext.
529 llvm::StructType *ClassExtensionTy;
530 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
531 llvm::Type *ClassExtensionPtrTy;
532 // IvarTy - LLVM type for struct objc_ivar.
533 llvm::StructType *IvarTy;
534 /// IvarListTy - LLVM type for struct objc_ivar_list.
535 llvm::Type *IvarListTy;
536 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
537 llvm::Type *IvarListPtrTy;
538 /// MethodListTy - LLVM type for struct objc_method_list.
539 llvm::Type *MethodListTy;
540 /// MethodListPtrTy - LLVM type for struct objc_method_list *.
541 llvm::Type *MethodListPtrTy;
543 /// ExceptionDataTy - LLVM type for struct _objc_exception_data.
544 llvm::Type *ExceptionDataTy;
546 /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.
547 llvm::Constant *getExceptionTryEnterFn() {
548 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
549 return CGM.CreateRuntimeFunction(
550 llvm::FunctionType::get(CGM.VoidTy, params, false),
551 "objc_exception_try_enter");
554 /// ExceptionTryExitFn - LLVM objc_exception_try_exit function.
555 llvm::Constant *getExceptionTryExitFn() {
556 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
557 return CGM.CreateRuntimeFunction(
558 llvm::FunctionType::get(CGM.VoidTy, params, false),
559 "objc_exception_try_exit");
562 /// ExceptionExtractFn - LLVM objc_exception_extract function.
563 llvm::Constant *getExceptionExtractFn() {
564 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
565 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
567 "objc_exception_extract");
570 /// ExceptionMatchFn - LLVM objc_exception_match function.
571 llvm::Constant *getExceptionMatchFn() {
572 llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy };
573 return CGM.CreateRuntimeFunction(
574 llvm::FunctionType::get(CGM.Int32Ty, params, false),
575 "objc_exception_match");
579 /// SetJmpFn - LLVM _setjmp function.
580 llvm::Constant *getSetJmpFn() {
581 // This is specifically the prototype for x86.
582 llvm::Type *params[] = { CGM.Int32Ty->getPointerTo() };
583 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty,
586 llvm::Attribute::ReturnsTwice);
590 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
591 ~ObjCTypesHelper() {}
594 /// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's
596 class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {
599 // MethodListnfABITy - LLVM for struct _method_list_t
600 llvm::StructType *MethodListnfABITy;
602 // MethodListnfABIPtrTy - LLVM for struct _method_list_t*
603 llvm::Type *MethodListnfABIPtrTy;
605 // ProtocolnfABITy = LLVM for struct _protocol_t
606 llvm::StructType *ProtocolnfABITy;
608 // ProtocolnfABIPtrTy = LLVM for struct _protocol_t*
609 llvm::Type *ProtocolnfABIPtrTy;
611 // ProtocolListnfABITy - LLVM for struct _objc_protocol_list
612 llvm::StructType *ProtocolListnfABITy;
614 // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list*
615 llvm::Type *ProtocolListnfABIPtrTy;
617 // ClassnfABITy - LLVM for struct _class_t
618 llvm::StructType *ClassnfABITy;
620 // ClassnfABIPtrTy - LLVM for struct _class_t*
621 llvm::Type *ClassnfABIPtrTy;
623 // IvarnfABITy - LLVM for struct _ivar_t
624 llvm::StructType *IvarnfABITy;
626 // IvarListnfABITy - LLVM for struct _ivar_list_t
627 llvm::StructType *IvarListnfABITy;
629 // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t*
630 llvm::Type *IvarListnfABIPtrTy;
632 // ClassRonfABITy - LLVM for struct _class_ro_t
633 llvm::StructType *ClassRonfABITy;
635 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
636 llvm::Type *ImpnfABITy;
638 // CategorynfABITy - LLVM for struct _category_t
639 llvm::StructType *CategorynfABITy;
641 // New types for nonfragile abi messaging.
643 // MessageRefTy - LLVM for:
644 // struct _message_ref_t {
648 llvm::StructType *MessageRefTy;
649 // MessageRefCTy - clang type for struct _message_ref_t
650 QualType MessageRefCTy;
652 // MessageRefPtrTy - LLVM for struct _message_ref_t*
653 llvm::Type *MessageRefPtrTy;
654 // MessageRefCPtrTy - clang type for struct _message_ref_t*
655 QualType MessageRefCPtrTy;
657 // MessengerTy - Type of the messenger (shown as IMP above)
658 llvm::FunctionType *MessengerTy;
660 // SuperMessageRefTy - LLVM for:
661 // struct _super_message_ref_t {
662 // SUPER_IMP messenger;
665 llvm::StructType *SuperMessageRefTy;
667 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
668 llvm::Type *SuperMessageRefPtrTy;
670 llvm::Constant *getMessageSendFixupFn() {
671 // id objc_msgSend_fixup(id, struct message_ref_t*, ...)
672 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
673 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
675 "objc_msgSend_fixup");
678 llvm::Constant *getMessageSendFpretFixupFn() {
679 // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...)
680 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
681 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
683 "objc_msgSend_fpret_fixup");
686 llvm::Constant *getMessageSendStretFixupFn() {
687 // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...)
688 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
689 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
691 "objc_msgSend_stret_fixup");
694 llvm::Constant *getMessageSendSuper2FixupFn() {
695 // id objc_msgSendSuper2_fixup (struct objc_super *,
696 // struct _super_message_ref_t*, ...)
697 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
698 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
700 "objc_msgSendSuper2_fixup");
703 llvm::Constant *getMessageSendSuper2StretFixupFn() {
704 // id objc_msgSendSuper2_stret_fixup(struct objc_super *,
705 // struct _super_message_ref_t*, ...)
706 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
707 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
709 "objc_msgSendSuper2_stret_fixup");
712 llvm::Constant *getObjCEndCatchFn() {
713 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy, false),
718 llvm::Constant *getObjCBeginCatchFn() {
719 llvm::Type *params[] = { Int8PtrTy };
720 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy,
725 llvm::StructType *EHTypeTy;
726 llvm::Type *EHTypePtrTy;
728 ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
729 ~ObjCNonFragileABITypesHelper(){}
732 class CGObjCCommonMac : public CodeGen::CGObjCRuntime {
734 // FIXME - accessibility
737 unsigned ivar_bytepos;
739 GC_IVAR(unsigned bytepos = 0, unsigned size = 0)
740 : ivar_bytepos(bytepos), ivar_size(size) {}
742 // Allow sorting based on byte pos.
743 bool operator<(const GC_IVAR &b) const {
744 return ivar_bytepos < b.ivar_bytepos;
752 SKIP_SCAN(unsigned _skip = 0, unsigned _scan = 0)
753 : skip(_skip), scan(_scan) {}
757 llvm::LLVMContext &VMContext;
758 // FIXME! May not be needing this after all.
761 // gc ivar layout bitmap calculation helper caches.
762 SmallVector<GC_IVAR, 16> SkipIvars;
763 SmallVector<GC_IVAR, 16> IvarsInfo;
765 /// LazySymbols - Symbols to generate a lazy reference for. See
766 /// DefinedSymbols and FinishModule().
767 llvm::SetVector<IdentifierInfo*> LazySymbols;
769 /// DefinedSymbols - External symbols which are defined by this
770 /// module. The symbols in this list and LazySymbols are used to add
771 /// special linker symbols which ensure that Objective-C modules are
773 llvm::SetVector<IdentifierInfo*> DefinedSymbols;
775 /// ClassNames - uniqued class names.
776 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
778 /// MethodVarNames - uniqued method variable names.
779 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
781 /// DefinedCategoryNames - list of category names in form Class_Category.
782 llvm::SetVector<std::string> DefinedCategoryNames;
784 /// MethodVarTypes - uniqued method type signatures. We have to use
785 /// a StringMap here because have no other unique reference.
786 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
788 /// MethodDefinitions - map of methods which have been defined in
789 /// this translation unit.
790 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
792 /// PropertyNames - uniqued method variable names.
793 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
795 /// ClassReferences - uniqued class references.
796 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
798 /// SelectorReferences - uniqued selector references.
799 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
801 /// Protocols - Protocols for which an objc_protocol structure has
802 /// been emitted. Forward declarations are handled by creating an
803 /// empty structure whose initializer is filled in when/if defined.
804 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
806 /// DefinedProtocols - Protocols which have actually been
807 /// defined. We should not need this, see FIXME in GenerateProtocol.
808 llvm::DenseSet<IdentifierInfo*> DefinedProtocols;
810 /// DefinedClasses - List of defined classes.
811 llvm::SmallVector<llvm::GlobalValue*, 16> DefinedClasses;
813 /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
814 llvm::SmallVector<llvm::GlobalValue*, 16> DefinedNonLazyClasses;
816 /// DefinedCategories - List of defined categories.
817 llvm::SmallVector<llvm::GlobalValue*, 16> DefinedCategories;
819 /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
820 llvm::SmallVector<llvm::GlobalValue*, 16> DefinedNonLazyCategories;
822 /// GetNameForMethod - Return a name for the given method.
823 /// \param[out] NameOut - The return value.
824 void GetNameForMethod(const ObjCMethodDecl *OMD,
825 const ObjCContainerDecl *CD,
826 SmallVectorImpl<char> &NameOut);
828 /// GetMethodVarName - Return a unique constant for the given
829 /// selector's name. The return value has type char *.
830 llvm::Constant *GetMethodVarName(Selector Sel);
831 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
833 /// GetMethodVarType - Return a unique constant for the given
834 /// method's type encoding string. The return value has type char *.
836 // FIXME: This is a horrible name.
837 llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D,
838 bool Extended = false);
839 llvm::Constant *GetMethodVarType(const FieldDecl *D);
841 /// GetPropertyName - Return a unique constant for the given
842 /// name. The return value has type char *.
843 llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
845 // FIXME: This can be dropped once string functions are unified.
846 llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,
847 const Decl *Container);
849 /// GetClassName - Return a unique constant for the given selector's
850 /// name. The return value has type char *.
851 llvm::Constant *GetClassName(IdentifierInfo *Ident);
853 llvm::Function *GetMethodDefinition(const ObjCMethodDecl *MD);
855 /// BuildIvarLayout - Builds ivar layout bitmap for the class
856 /// implementation for the __strong or __weak case.
858 llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI,
859 bool ForStrongLayout);
861 llvm::Constant *BuildIvarLayoutBitmap(std::string &BitMap);
863 void BuildAggrIvarRecordLayout(const RecordType *RT,
864 unsigned int BytePos, bool ForStrongLayout,
866 void BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
867 const llvm::StructLayout *Layout,
868 const RecordDecl *RD,
869 ArrayRef<const FieldDecl*> RecFields,
870 unsigned int BytePos, bool ForStrongLayout,
873 /// GetIvarLayoutName - Returns a unique constant for the given
874 /// ivar layout bitmap.
875 llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident,
876 const ObjCCommonTypesHelper &ObjCTypes);
878 /// EmitPropertyList - Emit the given property list. The return
879 /// value has type PropertyListPtrTy.
880 llvm::Constant *EmitPropertyList(Twine Name,
881 const Decl *Container,
882 const ObjCContainerDecl *OCD,
883 const ObjCCommonTypesHelper &ObjCTypes);
885 /// EmitProtocolMethodTypes - Generate the array of extended method type
886 /// strings. The return value has type Int8PtrPtrTy.
887 llvm::Constant *EmitProtocolMethodTypes(Twine Name,
888 ArrayRef<llvm::Constant*> MethodTypes,
889 const ObjCCommonTypesHelper &ObjCTypes);
891 /// PushProtocolProperties - Push protocol's property on the input stack.
892 void PushProtocolProperties(
893 llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet,
894 llvm::SmallVectorImpl<llvm::Constant*> &Properties,
895 const Decl *Container,
896 const ObjCProtocolDecl *PROTO,
897 const ObjCCommonTypesHelper &ObjCTypes);
899 /// GetProtocolRef - Return a reference to the internal protocol
900 /// description, creating an empty one if it has not been
901 /// defined. The return value has type ProtocolPtrTy.
902 llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD);
904 /// CreateMetadataVar - Create a global variable with internal
905 /// linkage for use by the Objective-C runtime.
907 /// This is a convenience wrapper which not only creates the
908 /// variable, but also sets the section and alignment and adds the
909 /// global to the "llvm.used" list.
911 /// \param Name - The variable name.
912 /// \param Init - The variable initializer; this is also used to
913 /// define the type of the variable.
914 /// \param Section - The section the variable should go into, or 0.
915 /// \param Align - The alignment for the variable, or 0.
916 /// \param AddToUsed - Whether the variable should be added to
918 llvm::GlobalVariable *CreateMetadataVar(Twine Name,
919 llvm::Constant *Init,
924 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
925 ReturnValueSlot Return,
931 const CallArgList &CallArgs,
932 const ObjCMethodDecl *OMD,
933 const ObjCCommonTypesHelper &ObjCTypes);
935 /// EmitImageInfo - Emit the image info marker used to encode some module
936 /// level information.
937 void EmitImageInfo();
940 CGObjCCommonMac(CodeGen::CodeGenModule &cgm) :
941 CGObjCRuntime(cgm), VMContext(cgm.getLLVMContext()) { }
943 virtual llvm::Constant *GenerateConstantString(const StringLiteral *SL);
945 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
946 const ObjCContainerDecl *CD=0);
948 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
950 /// GetOrEmitProtocol - Get the protocol object for the given
951 /// declaration, emitting it if necessary. The return value has type
953 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0;
955 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
956 /// object for the given declaration, emitting it if needed. These
957 /// forward references will be filled in with empty bodies if no
958 /// definition is seen. The return value has type ProtocolPtrTy.
959 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0;
960 virtual llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
961 const CGBlockInfo &blockInfo);
965 class CGObjCMac : public CGObjCCommonMac {
967 ObjCTypesHelper ObjCTypes;
969 /// EmitModuleInfo - Another marker encoding module level
971 void EmitModuleInfo();
973 /// EmitModuleSymols - Emit module symbols, the list of defined
974 /// classes and categories. The result has type SymtabPtrTy.
975 llvm::Constant *EmitModuleSymbols();
977 /// FinishModule - Write out global data structures at the end of
978 /// processing a translation unit.
981 /// EmitClassExtension - Generate the class extension structure used
982 /// to store the weak ivar layout and properties. The return value
983 /// has type ClassExtensionPtrTy.
984 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
986 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
987 /// for the given class.
988 llvm::Value *EmitClassRef(CGBuilderTy &Builder,
989 const ObjCInterfaceDecl *ID);
991 llvm::Value *EmitClassRefFromId(CGBuilderTy &Builder,
994 llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder);
996 /// EmitSuperClassRef - Emits reference to class's main metadata class.
997 llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID);
999 /// EmitIvarList - Emit the ivar list for the given
1000 /// implementation. If ForClass is true the list of class ivars
1001 /// (i.e. metaclass ivars) is emitted, otherwise the list of
1002 /// interface ivars will be emitted. The return value has type
1004 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
1007 /// EmitMetaClass - Emit a forward reference to the class structure
1008 /// for the metaclass of the given interface. The return value has
1009 /// type ClassPtrTy.
1010 llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID);
1012 /// EmitMetaClass - Emit a class structure for the metaclass of the
1013 /// given implementation. The return value has type ClassPtrTy.
1014 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
1015 llvm::Constant *Protocols,
1016 ArrayRef<llvm::Constant*> Methods);
1018 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
1020 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
1022 /// EmitMethodList - Emit the method list for the given
1023 /// implementation. The return value has type MethodListPtrTy.
1024 llvm::Constant *EmitMethodList(Twine Name,
1025 const char *Section,
1026 ArrayRef<llvm::Constant*> Methods);
1028 /// EmitMethodDescList - Emit a method description list for a list of
1029 /// method declarations.
1030 /// - TypeName: The name for the type containing the methods.
1031 /// - IsProtocol: True iff these methods are for a protocol.
1032 /// - ClassMethds: True iff these are class methods.
1033 /// - Required: When true, only "required" methods are
1034 /// listed. Similarly, when false only "optional" methods are
1035 /// listed. For classes this should always be true.
1036 /// - begin, end: The method list to output.
1038 /// The return value has type MethodDescriptionListPtrTy.
1039 llvm::Constant *EmitMethodDescList(Twine Name,
1040 const char *Section,
1041 ArrayRef<llvm::Constant*> Methods);
1043 /// GetOrEmitProtocol - Get the protocol object for the given
1044 /// declaration, emitting it if necessary. The return value has type
1046 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
1048 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1049 /// object for the given declaration, emitting it if needed. These
1050 /// forward references will be filled in with empty bodies if no
1051 /// definition is seen. The return value has type ProtocolPtrTy.
1052 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
1054 /// EmitProtocolExtension - Generate the protocol extension
1055 /// structure used to store optional instance and class methods, and
1056 /// protocol properties. The return value has type
1057 /// ProtocolExtensionPtrTy.
1059 EmitProtocolExtension(const ObjCProtocolDecl *PD,
1060 ArrayRef<llvm::Constant*> OptInstanceMethods,
1061 ArrayRef<llvm::Constant*> OptClassMethods,
1062 ArrayRef<llvm::Constant*> MethodTypesExt);
1064 /// EmitProtocolList - Generate the list of referenced
1065 /// protocols. The return value has type ProtocolListPtrTy.
1066 llvm::Constant *EmitProtocolList(Twine Name,
1067 ObjCProtocolDecl::protocol_iterator begin,
1068 ObjCProtocolDecl::protocol_iterator end);
1070 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
1071 /// for the given selector.
1072 llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel,
1076 CGObjCMac(CodeGen::CodeGenModule &cgm);
1078 virtual llvm::Function *ModuleInitFunction();
1080 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1081 ReturnValueSlot Return,
1082 QualType ResultType,
1084 llvm::Value *Receiver,
1085 const CallArgList &CallArgs,
1086 const ObjCInterfaceDecl *Class,
1087 const ObjCMethodDecl *Method);
1089 virtual CodeGen::RValue
1090 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1091 ReturnValueSlot Return,
1092 QualType ResultType,
1094 const ObjCInterfaceDecl *Class,
1095 bool isCategoryImpl,
1096 llvm::Value *Receiver,
1097 bool IsClassMessage,
1098 const CallArgList &CallArgs,
1099 const ObjCMethodDecl *Method);
1101 virtual llvm::Value *GetClass(CGBuilderTy &Builder,
1102 const ObjCInterfaceDecl *ID);
1104 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel,
1107 /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1109 virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
1110 const ObjCMethodDecl *Method);
1112 virtual llvm::Constant *GetEHType(QualType T);
1114 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
1116 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
1118 virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {}
1120 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
1121 const ObjCProtocolDecl *PD);
1123 virtual llvm::Constant *GetPropertyGetFunction();
1124 virtual llvm::Constant *GetPropertySetFunction();
1125 virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
1127 virtual llvm::Constant *GetGetStructFunction();
1128 virtual llvm::Constant *GetSetStructFunction();
1129 virtual llvm::Constant *GetCppAtomicObjectFunction();
1130 virtual llvm::Constant *EnumerationMutationFunction();
1132 virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1133 const ObjCAtTryStmt &S);
1134 virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1135 const ObjCAtSynchronizedStmt &S);
1136 void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const Stmt &S);
1137 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
1138 const ObjCAtThrowStmt &S);
1139 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1140 llvm::Value *AddrWeakObj);
1141 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1142 llvm::Value *src, llvm::Value *dst);
1143 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1144 llvm::Value *src, llvm::Value *dest,
1145 bool threadlocal = false);
1146 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
1147 llvm::Value *src, llvm::Value *dest,
1148 llvm::Value *ivarOffset);
1149 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
1150 llvm::Value *src, llvm::Value *dest);
1151 virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1152 llvm::Value *dest, llvm::Value *src,
1155 virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
1157 llvm::Value *BaseValue,
1158 const ObjCIvarDecl *Ivar,
1159 unsigned CVRQualifiers);
1160 virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1161 const ObjCInterfaceDecl *Interface,
1162 const ObjCIvarDecl *Ivar);
1164 /// GetClassGlobal - Return the global variable for the Objective-C
1165 /// class of the given name.
1166 virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) {
1167 llvm_unreachable("CGObjCMac::GetClassGlobal");
1171 class CGObjCNonFragileABIMac : public CGObjCCommonMac {
1173 ObjCNonFragileABITypesHelper ObjCTypes;
1174 llvm::GlobalVariable* ObjCEmptyCacheVar;
1175 llvm::GlobalVariable* ObjCEmptyVtableVar;
1177 /// SuperClassReferences - uniqued super class references.
1178 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
1180 /// MetaClassReferences - uniqued meta class references.
1181 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
1183 /// EHTypeReferences - uniqued class ehtype references.
1184 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
1186 /// VTableDispatchMethods - List of methods for which we generate
1187 /// vtable-based message dispatch.
1188 llvm::DenseSet<Selector> VTableDispatchMethods;
1190 /// DefinedMetaClasses - List of defined meta-classes.
1191 std::vector<llvm::GlobalValue*> DefinedMetaClasses;
1193 /// isVTableDispatchedSelector - Returns true if SEL is a
1194 /// vtable-based selector.
1195 bool isVTableDispatchedSelector(Selector Sel);
1197 /// FinishNonFragileABIModule - Write out global data structures at the end of
1198 /// processing a translation unit.
1199 void FinishNonFragileABIModule();
1201 /// AddModuleClassList - Add the given list of class pointers to the
1202 /// module with the provided symbol and section names.
1203 void AddModuleClassList(ArrayRef<llvm::GlobalValue*> Container,
1204 const char *SymbolName,
1205 const char *SectionName);
1207 llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags,
1208 unsigned InstanceStart,
1209 unsigned InstanceSize,
1210 const ObjCImplementationDecl *ID);
1211 llvm::GlobalVariable * BuildClassMetaData(std::string &ClassName,
1212 llvm::Constant *IsAGV,
1213 llvm::Constant *SuperClassGV,
1214 llvm::Constant *ClassRoGV,
1215 bool HiddenVisibility);
1217 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
1219 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
1221 /// EmitMethodList - Emit the method list for the given
1222 /// implementation. The return value has type MethodListnfABITy.
1223 llvm::Constant *EmitMethodList(Twine Name,
1224 const char *Section,
1225 ArrayRef<llvm::Constant*> Methods);
1226 /// EmitIvarList - Emit the ivar list for the given
1227 /// implementation. If ForClass is true the list of class ivars
1228 /// (i.e. metaclass ivars) is emitted, otherwise the list of
1229 /// interface ivars will be emitted. The return value has type
1230 /// IvarListnfABIPtrTy.
1231 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID);
1233 llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
1234 const ObjCIvarDecl *Ivar,
1235 unsigned long int offset);
1237 /// GetOrEmitProtocol - Get the protocol object for the given
1238 /// declaration, emitting it if necessary. The return value has type
1240 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
1242 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1243 /// object for the given declaration, emitting it if needed. These
1244 /// forward references will be filled in with empty bodies if no
1245 /// definition is seen. The return value has type ProtocolPtrTy.
1246 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
1248 /// EmitProtocolList - Generate the list of referenced
1249 /// protocols. The return value has type ProtocolListPtrTy.
1250 llvm::Constant *EmitProtocolList(Twine Name,
1251 ObjCProtocolDecl::protocol_iterator begin,
1252 ObjCProtocolDecl::protocol_iterator end);
1254 CodeGen::RValue EmitVTableMessageSend(CodeGen::CodeGenFunction &CGF,
1255 ReturnValueSlot Return,
1256 QualType ResultType,
1258 llvm::Value *Receiver,
1261 const CallArgList &CallArgs,
1262 const ObjCMethodDecl *Method);
1264 /// GetClassGlobal - Return the global variable for the Objective-C
1265 /// class of the given name.
1266 llvm::GlobalVariable *GetClassGlobal(const std::string &Name);
1268 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1269 /// for the given class reference.
1270 llvm::Value *EmitClassRef(CGBuilderTy &Builder,
1271 const ObjCInterfaceDecl *ID);
1273 llvm::Value *EmitClassRefFromId(CGBuilderTy &Builder,
1274 IdentifierInfo *II);
1276 llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder);
1278 /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1279 /// for the given super class reference.
1280 llvm::Value *EmitSuperClassRef(CGBuilderTy &Builder,
1281 const ObjCInterfaceDecl *ID);
1283 /// EmitMetaClassRef - Return a Value * of the address of _class_t
1285 llvm::Value *EmitMetaClassRef(CGBuilderTy &Builder,
1286 const ObjCInterfaceDecl *ID);
1288 /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
1291 llvm::GlobalVariable * ObjCIvarOffsetVariable(
1292 const ObjCInterfaceDecl *ID,
1293 const ObjCIvarDecl *Ivar);
1295 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
1296 /// for the given selector.
1297 llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel,
1300 /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C
1301 /// interface. The return value has type EHTypePtrTy.
1302 llvm::Constant *GetInterfaceEHType(const ObjCInterfaceDecl *ID,
1303 bool ForDefinition);
1305 const char *getMetaclassSymbolPrefix() const {
1306 return "OBJC_METACLASS_$_";
1309 const char *getClassSymbolPrefix() const {
1310 return "OBJC_CLASS_$_";
1313 void GetClassSizeInfo(const ObjCImplementationDecl *OID,
1314 uint32_t &InstanceStart,
1315 uint32_t &InstanceSize);
1317 // Shamelessly stolen from Analysis/CFRefCount.cpp
1318 Selector GetNullarySelector(const char* name) const {
1319 IdentifierInfo* II = &CGM.getContext().Idents.get(name);
1320 return CGM.getContext().Selectors.getSelector(0, &II);
1323 Selector GetUnarySelector(const char* name) const {
1324 IdentifierInfo* II = &CGM.getContext().Idents.get(name);
1325 return CGM.getContext().Selectors.getSelector(1, &II);
1328 /// ImplementationIsNonLazy - Check whether the given category or
1329 /// class implementation is "non-lazy".
1330 bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const;
1333 CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
1334 // FIXME. All stubs for now!
1335 virtual llvm::Function *ModuleInitFunction();
1337 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1338 ReturnValueSlot Return,
1339 QualType ResultType,
1341 llvm::Value *Receiver,
1342 const CallArgList &CallArgs,
1343 const ObjCInterfaceDecl *Class,
1344 const ObjCMethodDecl *Method);
1346 virtual CodeGen::RValue
1347 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1348 ReturnValueSlot Return,
1349 QualType ResultType,
1351 const ObjCInterfaceDecl *Class,
1352 bool isCategoryImpl,
1353 llvm::Value *Receiver,
1354 bool IsClassMessage,
1355 const CallArgList &CallArgs,
1356 const ObjCMethodDecl *Method);
1358 virtual llvm::Value *GetClass(CGBuilderTy &Builder,
1359 const ObjCInterfaceDecl *ID);
1361 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel,
1362 bool lvalue = false)
1363 { return EmitSelector(Builder, Sel, lvalue); }
1365 /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1367 virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
1368 const ObjCMethodDecl *Method)
1369 { return EmitSelector(Builder, Method->getSelector()); }
1371 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
1373 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
1375 virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {}
1377 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
1378 const ObjCProtocolDecl *PD);
1380 virtual llvm::Constant *GetEHType(QualType T);
1382 virtual llvm::Constant *GetPropertyGetFunction() {
1383 return ObjCTypes.getGetPropertyFn();
1385 virtual llvm::Constant *GetPropertySetFunction() {
1386 return ObjCTypes.getSetPropertyFn();
1389 virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
1391 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
1394 virtual llvm::Constant *GetSetStructFunction() {
1395 return ObjCTypes.getCopyStructFn();
1397 virtual llvm::Constant *GetGetStructFunction() {
1398 return ObjCTypes.getCopyStructFn();
1400 virtual llvm::Constant *GetCppAtomicObjectFunction() {
1401 return ObjCTypes.getCppAtomicObjectFunction();
1404 virtual llvm::Constant *EnumerationMutationFunction() {
1405 return ObjCTypes.getEnumerationMutationFn();
1408 virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1409 const ObjCAtTryStmt &S);
1410 virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1411 const ObjCAtSynchronizedStmt &S);
1412 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
1413 const ObjCAtThrowStmt &S);
1414 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1415 llvm::Value *AddrWeakObj);
1416 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1417 llvm::Value *src, llvm::Value *dst);
1418 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1419 llvm::Value *src, llvm::Value *dest,
1420 bool threadlocal = false);
1421 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
1422 llvm::Value *src, llvm::Value *dest,
1423 llvm::Value *ivarOffset);
1424 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
1425 llvm::Value *src, llvm::Value *dest);
1426 virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1427 llvm::Value *dest, llvm::Value *src,
1429 virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
1431 llvm::Value *BaseValue,
1432 const ObjCIvarDecl *Ivar,
1433 unsigned CVRQualifiers);
1434 virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1435 const ObjCInterfaceDecl *Interface,
1436 const ObjCIvarDecl *Ivar);
1439 /// A helper class for performing the null-initialization of a return
1441 struct NullReturnState {
1442 llvm::BasicBlock *NullBB;
1443 llvm::BasicBlock *callBB;
1444 NullReturnState() : NullBB(0), callBB(0) {}
1446 void init(CodeGenFunction &CGF, llvm::Value *receiver) {
1447 // Make blocks for the null-init and call edges.
1448 NullBB = CGF.createBasicBlock("msgSend.nullinit");
1449 callBB = CGF.createBasicBlock("msgSend.call");
1451 // Check for a null receiver and, if there is one, jump to the
1453 llvm::Value *isNull = CGF.Builder.CreateIsNull(receiver);
1454 CGF.Builder.CreateCondBr(isNull, NullBB, callBB);
1456 // Otherwise, start performing the call.
1457 CGF.EmitBlock(callBB);
1460 RValue complete(CodeGenFunction &CGF, RValue result, QualType resultType,
1461 const CallArgList &CallArgs,
1462 const ObjCMethodDecl *Method) {
1463 if (!NullBB) return result;
1465 llvm::Value *NullInitPtr = 0;
1466 if (result.isScalar() && !resultType->isVoidType()) {
1467 NullInitPtr = CGF.CreateTempAlloca(result.getScalarVal()->getType());
1468 CGF.Builder.CreateStore(result.getScalarVal(), NullInitPtr);
1471 // Finish the call path.
1472 llvm::BasicBlock *contBB = CGF.createBasicBlock("msgSend.cont");
1473 if (CGF.HaveInsertPoint()) CGF.Builder.CreateBr(contBB);
1475 // Emit the null-init block and perform the null-initialization there.
1476 CGF.EmitBlock(NullBB);
1478 // Release consumed arguments along the null-receiver path.
1480 CallArgList::const_iterator I = CallArgs.begin();
1481 for (ObjCMethodDecl::param_const_iterator i = Method->param_begin(),
1482 e = Method->param_end(); i != e; ++i, ++I) {
1483 const ParmVarDecl *ParamDecl = (*i);
1484 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
1486 assert(RV.isScalar() &&
1487 "NullReturnState::complete - arg not on object");
1488 CGF.EmitARCRelease(RV.getScalarVal(), true);
1493 if (result.isScalar()) {
1495 CGF.EmitNullInitialization(NullInitPtr, resultType);
1496 // Jump to the continuation block.
1497 CGF.EmitBlock(contBB);
1498 return NullInitPtr ? RValue::get(CGF.Builder.CreateLoad(NullInitPtr))
1502 if (!resultType->isAnyComplexType()) {
1503 assert(result.isAggregate() && "null init of non-aggregate result?");
1504 CGF.EmitNullInitialization(result.getAggregateAddr(), resultType);
1505 // Jump to the continuation block.
1506 CGF.EmitBlock(contBB);
1511 // FIXME. Now easy to handle any other scalar type whose result is returned
1512 // in memory due to ABI limitations.
1513 CGF.EmitBlock(contBB);
1514 CodeGenFunction::ComplexPairTy CallCV = result.getComplexVal();
1515 llvm::Type *MemberType = CallCV.first->getType();
1516 llvm::Constant *ZeroCV = llvm::Constant::getNullValue(MemberType);
1517 // Create phi instruction for scalar complex value.
1518 llvm::PHINode *PHIReal = CGF.Builder.CreatePHI(MemberType, 2);
1519 PHIReal->addIncoming(ZeroCV, NullBB);
1520 PHIReal->addIncoming(CallCV.first, callBB);
1521 llvm::PHINode *PHIImag = CGF.Builder.CreatePHI(MemberType, 2);
1522 PHIImag->addIncoming(ZeroCV, NullBB);
1523 PHIImag->addIncoming(CallCV.second, callBB);
1524 return RValue::getComplex(PHIReal, PHIImag);
1528 } // end anonymous namespace
1530 /* *** Helper Functions *** */
1532 /// getConstantGEP() - Help routine to construct simple GEPs.
1533 static llvm::Constant *getConstantGEP(llvm::LLVMContext &VMContext,
1537 llvm::Value *Idxs[] = {
1538 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1539 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
1541 return llvm::ConstantExpr::getGetElementPtr(C, Idxs);
1544 /// hasObjCExceptionAttribute - Return true if this class or any super
1545 /// class has the __objc_exception__ attribute.
1546 static bool hasObjCExceptionAttribute(ASTContext &Context,
1547 const ObjCInterfaceDecl *OID) {
1548 if (OID->hasAttr<ObjCExceptionAttr>())
1550 if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
1551 return hasObjCExceptionAttribute(Context, Super);
1555 /* *** CGObjCMac Public Interface *** */
1557 CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm),
1563 /// GetClass - Return a reference to the class for the given interface
1565 llvm::Value *CGObjCMac::GetClass(CGBuilderTy &Builder,
1566 const ObjCInterfaceDecl *ID) {
1567 return EmitClassRef(Builder, ID);
1570 /// GetSelector - Return the pointer to the unique'd string for this selector.
1571 llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, Selector Sel,
1573 return EmitSelector(Builder, Sel, lval);
1575 llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
1577 return EmitSelector(Builder, Method->getSelector());
1580 llvm::Constant *CGObjCMac::GetEHType(QualType T) {
1581 if (T->isObjCIdType() ||
1582 T->isObjCQualifiedIdType()) {
1583 return CGM.GetAddrOfRTTIDescriptor(
1584 CGM.getContext().getObjCIdRedefinitionType(), /*ForEH=*/true);
1586 if (T->isObjCClassType() ||
1587 T->isObjCQualifiedClassType()) {
1588 return CGM.GetAddrOfRTTIDescriptor(
1589 CGM.getContext().getObjCClassRedefinitionType(), /*ForEH=*/true);
1591 if (T->isObjCObjectPointerType())
1592 return CGM.GetAddrOfRTTIDescriptor(T, /*ForEH=*/true);
1594 llvm_unreachable("asking for catch type for ObjC type in fragile runtime");
1597 /// Generate a constant CFString object.
1599 struct __builtin_CFString {
1600 const int *isa; // point to __CFConstantStringClassReference
1607 /// or Generate a constant NSString object.
1609 struct __builtin_NSString {
1610 const int *isa; // point to __NSConstantStringClassReference
1612 unsigned int length;
1616 llvm::Constant *CGObjCCommonMac::GenerateConstantString(
1617 const StringLiteral *SL) {
1618 return (CGM.getLangOpts().NoConstantCFStrings == 0 ?
1619 CGM.GetAddrOfConstantCFString(SL) :
1620 CGM.GetAddrOfConstantString(SL));
1624 kCFTaggedObjectID_Integer = (1 << 1) + 1
1627 /// Generates a message send where the super is the receiver. This is
1628 /// a message send to self with special delivery semantics indicating
1629 /// which class's method should be called.
1631 CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1632 ReturnValueSlot Return,
1633 QualType ResultType,
1635 const ObjCInterfaceDecl *Class,
1636 bool isCategoryImpl,
1637 llvm::Value *Receiver,
1638 bool IsClassMessage,
1639 const CodeGen::CallArgList &CallArgs,
1640 const ObjCMethodDecl *Method) {
1641 // Create and init a super structure; this is a (receiver, class)
1642 // pair we will pass to objc_msgSendSuper.
1643 llvm::Value *ObjCSuper =
1644 CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super");
1645 llvm::Value *ReceiverAsObject =
1646 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
1647 CGF.Builder.CreateStore(ReceiverAsObject,
1648 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
1650 // If this is a class message the metaclass is passed as the target.
1651 llvm::Value *Target;
1652 if (IsClassMessage) {
1653 if (isCategoryImpl) {
1654 // Message sent to 'super' in a class method defined in a category
1655 // implementation requires an odd treatment.
1656 // If we are in a class method, we must retrieve the
1657 // _metaclass_ for the current class, pointed at by
1658 // the class's "isa" pointer. The following assumes that
1659 // isa" is the first ivar in a class (which it must be).
1660 Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
1661 Target = CGF.Builder.CreateStructGEP(Target, 0);
1662 Target = CGF.Builder.CreateLoad(Target);
1664 llvm::Value *MetaClassPtr = EmitMetaClassRef(Class);
1665 llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1);
1666 llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr);
1670 else if (isCategoryImpl)
1671 Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
1673 llvm::Value *ClassPtr = EmitSuperClassRef(Class);
1674 ClassPtr = CGF.Builder.CreateStructGEP(ClassPtr, 1);
1675 Target = CGF.Builder.CreateLoad(ClassPtr);
1677 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
1679 llvm::Type *ClassTy =
1680 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
1681 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
1682 CGF.Builder.CreateStore(Target,
1683 CGF.Builder.CreateStructGEP(ObjCSuper, 1));
1684 return EmitMessageSend(CGF, Return, ResultType,
1685 EmitSelector(CGF.Builder, Sel),
1686 ObjCSuper, ObjCTypes.SuperPtrCTy,
1687 true, CallArgs, Method, ObjCTypes);
1690 /// Generate code for a message send expression.
1691 CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1692 ReturnValueSlot Return,
1693 QualType ResultType,
1695 llvm::Value *Receiver,
1696 const CallArgList &CallArgs,
1697 const ObjCInterfaceDecl *Class,
1698 const ObjCMethodDecl *Method) {
1699 return EmitMessageSend(CGF, Return, ResultType,
1700 EmitSelector(CGF.Builder, Sel),
1701 Receiver, CGF.getContext().getObjCIdType(),
1702 false, CallArgs, Method, ObjCTypes);
1706 CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
1707 ReturnValueSlot Return,
1708 QualType ResultType,
1713 const CallArgList &CallArgs,
1714 const ObjCMethodDecl *Method,
1715 const ObjCCommonTypesHelper &ObjCTypes) {
1716 CallArgList ActualArgs;
1718 Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy);
1719 ActualArgs.add(RValue::get(Arg0), Arg0Ty);
1720 ActualArgs.add(RValue::get(Sel), CGF.getContext().getObjCSelType());
1721 ActualArgs.addFrom(CallArgs);
1723 // If we're calling a method, use the formal signature.
1724 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
1727 assert(CGM.getContext().getCanonicalType(Method->getResultType()) ==
1728 CGM.getContext().getCanonicalType(ResultType) &&
1729 "Result type mismatch!");
1731 NullReturnState nullReturn;
1733 llvm::Constant *Fn = NULL;
1734 if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) {
1735 if (!IsSuper) nullReturn.init(CGF, Arg0);
1736 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
1737 : ObjCTypes.getSendStretFn(IsSuper);
1738 } else if (CGM.ReturnTypeUsesFPRet(ResultType)) {
1739 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
1740 : ObjCTypes.getSendFpretFn(IsSuper);
1741 } else if (CGM.ReturnTypeUsesFP2Ret(ResultType)) {
1742 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
1743 : ObjCTypes.getSendFp2retFn(IsSuper);
1745 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
1746 : ObjCTypes.getSendFn(IsSuper);
1749 bool requiresnullCheck = false;
1750 if (CGM.getLangOpts().ObjCAutoRefCount && Method)
1751 for (ObjCMethodDecl::param_const_iterator i = Method->param_begin(),
1752 e = Method->param_end(); i != e; ++i) {
1753 const ParmVarDecl *ParamDecl = (*i);
1754 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
1755 if (!nullReturn.NullBB)
1756 nullReturn.init(CGF, Arg0);
1757 requiresnullCheck = true;
1762 Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType);
1763 RValue rvalue = CGF.EmitCall(MSI.CallInfo, Fn, Return, ActualArgs);
1764 return nullReturn.complete(CGF, rvalue, ResultType, CallArgs,
1765 requiresnullCheck ? Method : 0);
1768 static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT) {
1769 if (FQT.isObjCGCStrong())
1770 return Qualifiers::Strong;
1772 if (FQT.isObjCGCWeak() || FQT.getObjCLifetime() == Qualifiers::OCL_Weak)
1773 return Qualifiers::Weak;
1775 // check for __unsafe_unretained
1776 if (FQT.getObjCLifetime() == Qualifiers::OCL_ExplicitNone)
1777 return Qualifiers::GCNone;
1779 if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
1780 return Qualifiers::Strong;
1782 if (const PointerType *PT = FQT->getAs<PointerType>())
1783 return GetGCAttrTypeForType(Ctx, PT->getPointeeType());
1785 return Qualifiers::GCNone;
1788 llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
1789 const CGBlockInfo &blockInfo) {
1790 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
1792 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
1793 !CGM.getLangOpts().ObjCAutoRefCount)
1796 bool hasUnion = false;
1799 unsigned WordSizeInBits = CGM.getContext().getTargetInfo().getPointerWidth(0);
1800 unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth();
1802 // __isa is the first field in block descriptor and must assume by runtime's
1803 // convention that it is GC'able.
1804 IvarsInfo.push_back(GC_IVAR(0, 1));
1806 const BlockDecl *blockDecl = blockInfo.getBlockDecl();
1808 // Calculate the basic layout of the block structure.
1809 const llvm::StructLayout *layout =
1810 CGM.getTargetData().getStructLayout(blockInfo.StructureType);
1812 // Ignore the optional 'this' capture: C++ objects are not assumed
1815 // Walk the captured variables.
1816 for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(),
1817 ce = blockDecl->capture_end(); ci != ce; ++ci) {
1818 const VarDecl *variable = ci->getVariable();
1819 QualType type = variable->getType();
1821 const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
1823 // Ignore constant captures.
1824 if (capture.isConstant()) continue;
1826 uint64_t fieldOffset = layout->getElementOffset(capture.getIndex());
1828 // __block variables are passed by their descriptor address.
1829 if (ci->isByRef()) {
1830 IvarsInfo.push_back(GC_IVAR(fieldOffset, /*size in words*/ 1));
1834 assert(!type->isArrayType() && "array variable should not be caught");
1835 if (const RecordType *record = type->getAs<RecordType>()) {
1836 BuildAggrIvarRecordLayout(record, fieldOffset, true, hasUnion);
1840 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), type);
1841 unsigned fieldSize = CGM.getContext().getTypeSize(type);
1843 if (GCAttr == Qualifiers::Strong)
1844 IvarsInfo.push_back(GC_IVAR(fieldOffset,
1845 fieldSize / WordSizeInBits));
1846 else if (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak)
1847 SkipIvars.push_back(GC_IVAR(fieldOffset,
1848 fieldSize / ByteSizeInBits));
1851 if (IvarsInfo.empty())
1854 // Sort on byte position; captures might not be allocated in order,
1855 // and unions can do funny things.
1856 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
1857 llvm::array_pod_sort(SkipIvars.begin(), SkipIvars.end());
1860 llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
1861 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
1862 printf("\n block variable layout for block: ");
1863 const unsigned char *s = (unsigned char*)BitMap.c_str();
1864 for (unsigned i = 0, e = BitMap.size(); i < e; i++)
1866 printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
1868 printf("0x%x%s", s[i], s[i] != 0 ? ", " : "");
1875 llvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder,
1876 const ObjCProtocolDecl *PD) {
1877 // FIXME: I don't understand why gcc generates this, or where it is
1878 // resolved. Investigate. Its also wasteful to look this up over and over.
1879 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
1881 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
1882 ObjCTypes.getExternalProtocolPtrTy());
1885 void CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
1886 // FIXME: We shouldn't need this, the protocol decl should contain enough
1887 // information to tell us whether this was a declaration or a definition.
1888 DefinedProtocols.insert(PD->getIdentifier());
1890 // If we have generated a forward reference to this protocol, emit
1891 // it now. Otherwise do nothing, the protocol objects are lazily
1893 if (Protocols.count(PD->getIdentifier()))
1894 GetOrEmitProtocol(PD);
1897 llvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
1898 if (DefinedProtocols.count(PD->getIdentifier()))
1899 return GetOrEmitProtocol(PD);
1901 return GetOrEmitProtocolRef(PD);
1905 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
1906 struct _objc_protocol {
1907 struct _objc_protocol_extension *isa;
1908 char *protocol_name;
1909 struct _objc_protocol_list *protocol_list;
1910 struct _objc__method_prototype_list *instance_methods;
1911 struct _objc__method_prototype_list *class_methods
1914 See EmitProtocolExtension().
1916 llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
1917 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
1919 // Early exit if a defining object has already been generated.
1920 if (Entry && Entry->hasInitializer())
1923 // Use the protocol definition, if there is one.
1924 if (const ObjCProtocolDecl *Def = PD->getDefinition())
1927 // FIXME: I don't understand why gcc generates this, or where it is
1928 // resolved. Investigate. Its also wasteful to look this up over and over.
1929 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
1931 // Construct method lists.
1932 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
1933 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
1934 std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt;
1935 for (ObjCProtocolDecl::instmeth_iterator
1936 i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
1937 ObjCMethodDecl *MD = *i;
1938 llvm::Constant *C = GetMethodDescriptionConstant(MD);
1940 return GetOrEmitProtocolRef(PD);
1942 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
1943 OptInstanceMethods.push_back(C);
1944 OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
1946 InstanceMethods.push_back(C);
1947 MethodTypesExt.push_back(GetMethodVarType(MD, true));
1951 for (ObjCProtocolDecl::classmeth_iterator
1952 i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
1953 ObjCMethodDecl *MD = *i;
1954 llvm::Constant *C = GetMethodDescriptionConstant(MD);
1956 return GetOrEmitProtocolRef(PD);
1958 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
1959 OptClassMethods.push_back(C);
1960 OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
1962 ClassMethods.push_back(C);
1963 MethodTypesExt.push_back(GetMethodVarType(MD, true));
1967 MethodTypesExt.insert(MethodTypesExt.end(),
1968 OptMethodTypesExt.begin(), OptMethodTypesExt.end());
1970 llvm::Constant *Values[] = {
1971 EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods,
1973 GetClassName(PD->getIdentifier()),
1974 EmitProtocolList("\01L_OBJC_PROTOCOL_REFS_" + PD->getName(),
1975 PD->protocol_begin(),
1976 PD->protocol_end()),
1977 EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_" + PD->getName(),
1978 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
1980 EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_" + PD->getName(),
1981 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
1984 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
1988 // Already created, fix the linkage and update the initializer.
1989 Entry->setLinkage(llvm::GlobalValue::InternalLinkage);
1990 Entry->setInitializer(Init);
1993 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,
1994 llvm::GlobalValue::InternalLinkage,
1996 "\01L_OBJC_PROTOCOL_" + PD->getName());
1997 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
1998 // FIXME: Is this necessary? Why only for protocol?
1999 Entry->setAlignment(4);
2001 Protocols[PD->getIdentifier()] = Entry;
2003 CGM.AddUsedGlobal(Entry);
2008 llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
2009 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
2012 // We use the initializer as a marker of whether this is a forward
2013 // reference or not. At module finalization we add the empty
2014 // contents for protocols which were referenced but never defined.
2016 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,
2017 llvm::GlobalValue::ExternalLinkage,
2019 "\01L_OBJC_PROTOCOL_" + PD->getName());
2020 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
2021 // FIXME: Is this necessary? Why only for protocol?
2022 Entry->setAlignment(4);
2029 struct _objc_protocol_extension {
2031 struct objc_method_description_list *optional_instance_methods;
2032 struct objc_method_description_list *optional_class_methods;
2033 struct objc_property_list *instance_properties;
2034 const char ** extendedMethodTypes;
2038 CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
2039 ArrayRef<llvm::Constant*> OptInstanceMethods,
2040 ArrayRef<llvm::Constant*> OptClassMethods,
2041 ArrayRef<llvm::Constant*> MethodTypesExt) {
2043 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
2044 llvm::Constant *Values[] = {
2045 llvm::ConstantInt::get(ObjCTypes.IntTy, Size),
2046 EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_"
2048 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2049 OptInstanceMethods),
2050 EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_" + PD->getName(),
2051 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2053 EmitPropertyList("\01L_OBJC_$_PROP_PROTO_LIST_" + PD->getName(), 0, PD,
2055 EmitProtocolMethodTypes("\01L_OBJC_PROTOCOL_METHOD_TYPES_" + PD->getName(),
2056 MethodTypesExt, ObjCTypes)
2059 // Return null if no extension bits are used.
2060 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
2061 Values[3]->isNullValue() && Values[4]->isNullValue())
2062 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
2064 llvm::Constant *Init =
2065 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
2067 // No special section, but goes in llvm.used
2068 return CreateMetadataVar("\01L_OBJC_PROTOCOLEXT_" + PD->getName(),
2074 struct objc_protocol_list {
2075 struct objc_protocol_list *next;
2081 CGObjCMac::EmitProtocolList(Twine Name,
2082 ObjCProtocolDecl::protocol_iterator begin,
2083 ObjCProtocolDecl::protocol_iterator end) {
2084 llvm::SmallVector<llvm::Constant*, 16> ProtocolRefs;
2086 for (; begin != end; ++begin)
2087 ProtocolRefs.push_back(GetProtocolRef(*begin));
2089 // Just return null for empty protocol lists
2090 if (ProtocolRefs.empty())
2091 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2093 // This list is null terminated.
2094 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
2096 llvm::Constant *Values[3];
2097 // This field is only used by the runtime.
2098 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2099 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy,
2100 ProtocolRefs.size() - 1);
2102 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
2103 ProtocolRefs.size()),
2106 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2107 llvm::GlobalVariable *GV =
2108 CreateMetadataVar(Name, Init, "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2110 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
2113 void CGObjCCommonMac::
2114 PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*,16> &PropertySet,
2115 llvm::SmallVectorImpl<llvm::Constant*> &Properties,
2116 const Decl *Container,
2117 const ObjCProtocolDecl *PROTO,
2118 const ObjCCommonTypesHelper &ObjCTypes) {
2119 for (ObjCProtocolDecl::protocol_iterator P = PROTO->protocol_begin(),
2120 E = PROTO->protocol_end(); P != E; ++P)
2121 PushProtocolProperties(PropertySet, Properties, Container, (*P), ObjCTypes);
2122 for (ObjCContainerDecl::prop_iterator I = PROTO->prop_begin(),
2123 E = PROTO->prop_end(); I != E; ++I) {
2124 const ObjCPropertyDecl *PD = *I;
2125 if (!PropertySet.insert(PD->getIdentifier()))
2127 llvm::Constant *Prop[] = {
2128 GetPropertyName(PD->getIdentifier()),
2129 GetPropertyTypeString(PD, Container)
2131 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop));
2136 struct _objc_property {
2137 const char * const name;
2138 const char * const attributes;
2141 struct _objc_property_list {
2142 uint32_t entsize; // sizeof (struct _objc_property)
2143 uint32_t prop_count;
2144 struct _objc_property[prop_count];
2147 llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,
2148 const Decl *Container,
2149 const ObjCContainerDecl *OCD,
2150 const ObjCCommonTypesHelper &ObjCTypes) {
2151 llvm::SmallVector<llvm::Constant*, 16> Properties;
2152 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
2153 for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(),
2154 E = OCD->prop_end(); I != E; ++I) {
2155 const ObjCPropertyDecl *PD = *I;
2156 PropertySet.insert(PD->getIdentifier());
2157 llvm::Constant *Prop[] = {
2158 GetPropertyName(PD->getIdentifier()),
2159 GetPropertyTypeString(PD, Container)
2161 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
2164 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) {
2165 for (ObjCInterfaceDecl::all_protocol_iterator
2166 P = OID->all_referenced_protocol_begin(),
2167 E = OID->all_referenced_protocol_end(); P != E; ++P)
2168 PushProtocolProperties(PropertySet, Properties, Container, (*P),
2171 else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) {
2172 for (ObjCCategoryDecl::protocol_iterator P = CD->protocol_begin(),
2173 E = CD->protocol_end(); P != E; ++P)
2174 PushProtocolProperties(PropertySet, Properties, Container, (*P),
2178 // Return null for empty list.
2179 if (Properties.empty())
2180 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
2182 unsigned PropertySize =
2183 CGM.getTargetData().getTypeAllocSize(ObjCTypes.PropertyTy);
2184 llvm::Constant *Values[3];
2185 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
2186 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
2187 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
2189 Values[2] = llvm::ConstantArray::get(AT, Properties);
2190 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2192 llvm::GlobalVariable *GV =
2193 CreateMetadataVar(Name, Init,
2194 (ObjCABI == 2) ? "__DATA, __objc_const" :
2195 "__OBJC,__property,regular,no_dead_strip",
2196 (ObjCABI == 2) ? 8 : 4,
2198 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);
2202 CGObjCCommonMac::EmitProtocolMethodTypes(Twine Name,
2203 ArrayRef<llvm::Constant*> MethodTypes,
2204 const ObjCCommonTypesHelper &ObjCTypes) {
2205 // Return null for empty list.
2206 if (MethodTypes.empty())
2207 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
2209 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
2210 MethodTypes.size());
2211 llvm::Constant *Init = llvm::ConstantArray::get(AT, MethodTypes);
2213 llvm::GlobalVariable *GV =
2214 CreateMetadataVar(Name, Init,
2215 (ObjCABI == 2) ? "__DATA, __objc_const" : 0,
2216 (ObjCABI == 2) ? 8 : 4,
2218 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.Int8PtrPtrTy);
2222 struct objc_method_description_list {
2224 struct objc_method_description list[];
2228 CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
2229 llvm::Constant *Desc[] = {
2230 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
2231 ObjCTypes.SelectorPtrTy),
2232 GetMethodVarType(MD)
2237 return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
2242 CGObjCMac::EmitMethodDescList(Twine Name, const char *Section,
2243 ArrayRef<llvm::Constant*> Methods) {
2244 // Return null for empty list.
2245 if (Methods.empty())
2246 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
2248 llvm::Constant *Values[2];
2249 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
2250 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
2252 Values[1] = llvm::ConstantArray::get(AT, Methods);
2253 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2255 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
2256 return llvm::ConstantExpr::getBitCast(GV,
2257 ObjCTypes.MethodDescriptionListPtrTy);
2261 struct _objc_category {
2262 char *category_name;
2264 struct _objc_method_list *instance_methods;
2265 struct _objc_method_list *class_methods;
2266 struct _objc_protocol_list *protocols;
2267 uint32_t size; // <rdar://4585769>
2268 struct _objc_property_list *instance_properties;
2271 void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
2272 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.CategoryTy);
2274 // FIXME: This is poor design, the OCD should have a pointer to the category
2275 // decl. Additionally, note that Category can be null for the @implementation
2276 // w/o an @interface case. Sema should just create one for us as it does for
2277 // @implementation so everyone else can live life under a clear blue sky.
2278 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
2279 const ObjCCategoryDecl *Category =
2280 Interface->FindCategoryDeclaration(OCD->getIdentifier());
2282 SmallString<256> ExtName;
2283 llvm::raw_svector_ostream(ExtName) << Interface->getName() << '_'
2286 llvm::SmallVector<llvm::Constant*, 16> InstanceMethods, ClassMethods;
2287 for (ObjCCategoryImplDecl::instmeth_iterator
2288 i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
2289 // Instance methods should always be defined.
2290 InstanceMethods.push_back(GetMethodConstant(*i));
2292 for (ObjCCategoryImplDecl::classmeth_iterator
2293 i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
2294 // Class methods should always be defined.
2295 ClassMethods.push_back(GetMethodConstant(*i));
2298 llvm::Constant *Values[7];
2299 Values[0] = GetClassName(OCD->getIdentifier());
2300 Values[1] = GetClassName(Interface->getIdentifier());
2301 LazySymbols.insert(Interface->getIdentifier());
2303 EmitMethodList("\01L_OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(),
2304 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2307 EmitMethodList("\01L_OBJC_CATEGORY_CLASS_METHODS_" + ExtName.str(),
2308 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2312 EmitProtocolList("\01L_OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
2313 Category->protocol_begin(),
2314 Category->protocol_end());
2316 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2318 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
2320 // If there is no category @interface then there can be no properties.
2322 Values[6] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
2323 OCD, Category, ObjCTypes);
2325 Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
2328 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
2331 llvm::GlobalVariable *GV =
2332 CreateMetadataVar("\01L_OBJC_CATEGORY_" + ExtName.str(), Init,
2333 "__OBJC,__category,regular,no_dead_strip",
2335 DefinedCategories.push_back(GV);
2336 DefinedCategoryNames.insert(ExtName.str());
2337 // method definition entries must be clear for next implementation.
2338 MethodDefinitions.clear();
2341 // FIXME: Get from somewhere?
2343 eClassFlags_Factory = 0x00001,
2344 eClassFlags_Meta = 0x00002,
2346 eClassFlags_HasCXXStructors = 0x02000,
2347 eClassFlags_Hidden = 0x20000,
2348 eClassFlags_ABI2_Hidden = 0x00010,
2349 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634>
2353 struct _objc_class {
2360 struct _objc_ivar_list *ivars;
2361 struct _objc_method_list *methods;
2362 struct _objc_cache *cache;
2363 struct _objc_protocol_list *protocols;
2364 // Objective-C 1.0 extensions (<rdr://4585769>)
2365 const char *ivar_layout;
2366 struct _objc_class_ext *ext;
2369 See EmitClassExtension();
2371 void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
2372 DefinedSymbols.insert(ID->getIdentifier());
2374 std::string ClassName = ID->getNameAsString();
2376 ObjCInterfaceDecl *Interface =
2377 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
2378 llvm::Constant *Protocols =
2379 EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getName(),
2380 Interface->all_referenced_protocol_begin(),
2381 Interface->all_referenced_protocol_end());
2382 unsigned Flags = eClassFlags_Factory;
2383 if (ID->hasCXXStructors())
2384 Flags |= eClassFlags_HasCXXStructors;
2386 CGM.getContext().getASTObjCImplementationLayout(ID).getSize().getQuantity();
2388 // FIXME: Set CXX-structors flag.
2389 if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
2390 Flags |= eClassFlags_Hidden;
2392 llvm::SmallVector<llvm::Constant*, 16> InstanceMethods, ClassMethods;
2393 for (ObjCImplementationDecl::instmeth_iterator
2394 i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
2395 // Instance methods should always be defined.
2396 InstanceMethods.push_back(GetMethodConstant(*i));
2398 for (ObjCImplementationDecl::classmeth_iterator
2399 i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
2400 // Class methods should always be defined.
2401 ClassMethods.push_back(GetMethodConstant(*i));
2404 for (ObjCImplementationDecl::propimpl_iterator
2405 i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
2406 ObjCPropertyImplDecl *PID = *i;
2408 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
2409 ObjCPropertyDecl *PD = PID->getPropertyDecl();
2411 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
2412 if (llvm::Constant *C = GetMethodConstant(MD))
2413 InstanceMethods.push_back(C);
2414 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
2415 if (llvm::Constant *C = GetMethodConstant(MD))
2416 InstanceMethods.push_back(C);
2420 llvm::Constant *Values[12];
2421 Values[ 0] = EmitMetaClass(ID, Protocols, ClassMethods);
2422 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
2423 // Record a reference to the super class.
2424 LazySymbols.insert(Super->getIdentifier());
2427 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
2428 ObjCTypes.ClassPtrTy);
2430 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
2432 Values[ 2] = GetClassName(ID->getIdentifier());
2433 // Version is always 0.
2434 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
2435 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
2436 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
2437 Values[ 6] = EmitIvarList(ID, false);
2439 EmitMethodList("\01L_OBJC_INSTANCE_METHODS_" + ID->getName(),
2440 "__OBJC,__inst_meth,regular,no_dead_strip",
2442 // cache is always NULL.
2443 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
2444 Values[ 9] = Protocols;
2445 Values[10] = BuildIvarLayout(ID, true);
2446 Values[11] = EmitClassExtension(ID);
2447 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
2449 std::string Name("\01L_OBJC_CLASS_");
2451 const char *Section = "__OBJC,__class,regular,no_dead_strip";
2452 // Check for a forward reference.
2453 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
2455 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2456 "Forward metaclass reference has incorrect type.");
2457 GV->setLinkage(llvm::GlobalValue::InternalLinkage);
2458 GV->setInitializer(Init);
2459 GV->setSection(Section);
2460 GV->setAlignment(4);
2461 CGM.AddUsedGlobal(GV);
2464 GV = CreateMetadataVar(Name, Init, Section, 4, true);
2465 DefinedClasses.push_back(GV);
2466 // method definition entries must be clear for next implementation.
2467 MethodDefinitions.clear();
2470 llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
2471 llvm::Constant *Protocols,
2472 ArrayRef<llvm::Constant*> Methods) {
2473 unsigned Flags = eClassFlags_Meta;
2474 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassTy);
2476 if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
2477 Flags |= eClassFlags_Hidden;
2479 llvm::Constant *Values[12];
2480 // The isa for the metaclass is the root of the hierarchy.
2481 const ObjCInterfaceDecl *Root = ID->getClassInterface();
2482 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
2485 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
2486 ObjCTypes.ClassPtrTy);
2487 // The super class for the metaclass is emitted as the name of the
2488 // super class. The runtime fixes this up to point to the
2489 // *metaclass* for the super class.
2490 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
2492 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
2493 ObjCTypes.ClassPtrTy);
2495 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
2497 Values[ 2] = GetClassName(ID->getIdentifier());
2498 // Version is always 0.
2499 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
2500 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
2501 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
2502 Values[ 6] = EmitIvarList(ID, true);
2504 EmitMethodList("\01L_OBJC_CLASS_METHODS_" + ID->getNameAsString(),
2505 "__OBJC,__cls_meth,regular,no_dead_strip",
2507 // cache is always NULL.
2508 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
2509 Values[ 9] = Protocols;
2510 // ivar_layout for metaclass is always NULL.
2511 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
2512 // The class extension is always unused for metaclasses.
2513 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
2514 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
2517 std::string Name("\01L_OBJC_METACLASS_");
2518 Name += ID->getNameAsCString();
2520 // Check for a forward reference.
2521 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
2523 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2524 "Forward metaclass reference has incorrect type.");
2525 GV->setLinkage(llvm::GlobalValue::InternalLinkage);
2526 GV->setInitializer(Init);
2528 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
2529 llvm::GlobalValue::InternalLinkage,
2532 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
2533 GV->setAlignment(4);
2534 CGM.AddUsedGlobal(GV);
2539 llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
2540 std::string Name = "\01L_OBJC_METACLASS_" + ID->getNameAsString();
2542 // FIXME: Should we look these up somewhere other than the module. Its a bit
2543 // silly since we only generate these while processing an implementation, so
2544 // exactly one pointer would work if know when we entered/exitted an
2545 // implementation block.
2547 // Check for an existing forward reference.
2548 // Previously, metaclass with internal linkage may have been defined.
2549 // pass 'true' as 2nd argument so it is returned.
2550 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name,
2552 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2553 "Forward metaclass reference has incorrect type.");
2556 // Generate as an external reference to keep a consistent
2557 // module. This will be patched up when we emit the metaclass.
2558 return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
2559 llvm::GlobalValue::ExternalLinkage,
2565 llvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) {
2566 std::string Name = "\01L_OBJC_CLASS_" + ID->getNameAsString();
2568 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name,
2570 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2571 "Forward class metadata reference has incorrect type.");
2574 return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
2575 llvm::GlobalValue::ExternalLinkage,
2582 struct objc_class_ext {
2584 const char *weak_ivar_layout;
2585 struct _objc_property_list *properties;
2589 CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
2591 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
2593 llvm::Constant *Values[3];
2594 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
2595 Values[1] = BuildIvarLayout(ID, false);
2596 Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
2597 ID, ID->getClassInterface(), ObjCTypes);
2599 // Return null if no extension bits are used.
2600 if (Values[1]->isNullValue() && Values[2]->isNullValue())
2601 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
2603 llvm::Constant *Init =
2604 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
2605 return CreateMetadataVar("\01L_OBJC_CLASSEXT_" + ID->getName(),
2606 Init, "__OBJC,__class_ext,regular,no_dead_strip",
2617 struct objc_ivar_list {
2619 struct objc_ivar list[count];
2622 llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
2624 std::vector<llvm::Constant*> Ivars;
2626 // When emitting the root class GCC emits ivar entries for the
2627 // actual class structure. It is not clear if we need to follow this
2628 // behavior; for now lets try and get away with not doing it. If so,
2629 // the cleanest solution would be to make up an ObjCInterfaceDecl
2632 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
2634 const ObjCInterfaceDecl *OID = ID->getClassInterface();
2636 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
2637 IVD; IVD = IVD->getNextIvar()) {
2638 // Ignore unnamed bit-fields.
2639 if (!IVD->getDeclName())
2641 llvm::Constant *Ivar[] = {
2642 GetMethodVarName(IVD->getIdentifier()),
2643 GetMethodVarType(IVD),
2644 llvm::ConstantInt::get(ObjCTypes.IntTy,
2645 ComputeIvarBaseOffset(CGM, OID, IVD))
2647 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar));
2650 // Return null for empty list.
2652 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
2654 llvm::Constant *Values[2];
2655 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
2656 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
2658 Values[1] = llvm::ConstantArray::get(AT, Ivars);
2659 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2661 llvm::GlobalVariable *GV;
2663 GV = CreateMetadataVar("\01L_OBJC_CLASS_VARIABLES_" + ID->getName(),
2664 Init, "__OBJC,__class_vars,regular,no_dead_strip",
2667 GV = CreateMetadataVar("\01L_OBJC_INSTANCE_VARIABLES_" + ID->getName(),
2668 Init, "__OBJC,__instance_vars,regular,no_dead_strip",
2670 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
2674 struct objc_method {
2680 struct objc_method_list {
2681 struct objc_method_list *obsolete;
2683 struct objc_method methods_list[count];
2687 /// GetMethodConstant - Return a struct objc_method constant for the
2688 /// given method if it has been defined. The result is null if the
2689 /// method has not been defined. The return value has type MethodPtrTy.
2690 llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) {
2691 llvm::Function *Fn = GetMethodDefinition(MD);
2695 llvm::Constant *Method[] = {
2696 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
2697 ObjCTypes.SelectorPtrTy),
2698 GetMethodVarType(MD),
2699 llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy)
2701 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
2704 llvm::Constant *CGObjCMac::EmitMethodList(Twine Name,
2705 const char *Section,
2706 ArrayRef<llvm::Constant*> Methods) {
2707 // Return null for empty list.
2708 if (Methods.empty())
2709 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
2711 llvm::Constant *Values[3];
2712 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
2713 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
2714 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
2716 Values[2] = llvm::ConstantArray::get(AT, Methods);
2717 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2719 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
2720 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy);
2723 llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,
2724 const ObjCContainerDecl *CD) {
2725 SmallString<256> Name;
2726 GetNameForMethod(OMD, CD, Name);
2728 CodeGenTypes &Types = CGM.getTypes();
2729 llvm::FunctionType *MethodTy =
2730 Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
2731 llvm::Function *Method =
2732 llvm::Function::Create(MethodTy,
2733 llvm::GlobalValue::InternalLinkage,
2736 MethodDefinitions.insert(std::make_pair(OMD, Method));
2741 llvm::GlobalVariable *
2742 CGObjCCommonMac::CreateMetadataVar(Twine Name,
2743 llvm::Constant *Init,
2744 const char *Section,
2747 llvm::Type *Ty = Init->getType();
2748 llvm::GlobalVariable *GV =
2749 new llvm::GlobalVariable(CGM.getModule(), Ty, false,
2750 llvm::GlobalValue::InternalLinkage, Init, Name);
2752 GV->setSection(Section);
2754 GV->setAlignment(Align);
2756 CGM.AddUsedGlobal(GV);
2760 llvm::Function *CGObjCMac::ModuleInitFunction() {
2761 // Abuse this interface function as a place to finalize.
2766 llvm::Constant *CGObjCMac::GetPropertyGetFunction() {
2767 return ObjCTypes.getGetPropertyFn();
2770 llvm::Constant *CGObjCMac::GetPropertySetFunction() {
2771 return ObjCTypes.getSetPropertyFn();
2774 llvm::Constant *CGObjCMac::GetOptimizedPropertySetFunction(bool atomic,
2776 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
2779 llvm::Constant *CGObjCMac::GetGetStructFunction() {
2780 return ObjCTypes.getCopyStructFn();
2782 llvm::Constant *CGObjCMac::GetSetStructFunction() {
2783 return ObjCTypes.getCopyStructFn();
2786 llvm::Constant *CGObjCMac::GetCppAtomicObjectFunction() {
2787 return ObjCTypes.getCppAtomicObjectFunction();
2790 llvm::Constant *CGObjCMac::EnumerationMutationFunction() {
2791 return ObjCTypes.getEnumerationMutationFn();
2794 void CGObjCMac::EmitTryStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S) {
2795 return EmitTryOrSynchronizedStmt(CGF, S);
2798 void CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF,
2799 const ObjCAtSynchronizedStmt &S) {
2800 return EmitTryOrSynchronizedStmt(CGF, S);
2804 struct PerformFragileFinally : EHScopeStack::Cleanup {
2806 llvm::Value *SyncArgSlot;
2807 llvm::Value *CallTryExitVar;
2808 llvm::Value *ExceptionData;
2809 ObjCTypesHelper &ObjCTypes;
2810 PerformFragileFinally(const Stmt *S,
2811 llvm::Value *SyncArgSlot,
2812 llvm::Value *CallTryExitVar,
2813 llvm::Value *ExceptionData,
2814 ObjCTypesHelper *ObjCTypes)
2815 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
2816 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
2818 void Emit(CodeGenFunction &CGF, Flags flags) {
2819 // Check whether we need to call objc_exception_try_exit.
2820 // In optimized code, this branch will always be folded.
2821 llvm::BasicBlock *FinallyCallExit =
2822 CGF.createBasicBlock("finally.call_exit");
2823 llvm::BasicBlock *FinallyNoCallExit =
2824 CGF.createBasicBlock("finally.no_call_exit");
2825 CGF.Builder.CreateCondBr(CGF.Builder.CreateLoad(CallTryExitVar),
2826 FinallyCallExit, FinallyNoCallExit);
2828 CGF.EmitBlock(FinallyCallExit);
2829 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryExitFn(), ExceptionData)
2830 ->setDoesNotThrow();
2832 CGF.EmitBlock(FinallyNoCallExit);
2834 if (isa<ObjCAtTryStmt>(S)) {
2835 if (const ObjCAtFinallyStmt* FinallyStmt =
2836 cast<ObjCAtTryStmt>(S).getFinallyStmt()) {
2837 // Save the current cleanup destination in case there's
2838 // control flow inside the finally statement.
2839 llvm::Value *CurCleanupDest =
2840 CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot());
2842 CGF.EmitStmt(FinallyStmt->getFinallyBody());
2844 if (CGF.HaveInsertPoint()) {
2845 CGF.Builder.CreateStore(CurCleanupDest,
2846 CGF.getNormalCleanupDestSlot());
2848 // Currently, the end of the cleanup must always exist.
2849 CGF.EnsureInsertPoint();
2853 // Emit objc_sync_exit(expr); as finally's sole statement for
2855 llvm::Value *SyncArg = CGF.Builder.CreateLoad(SyncArgSlot);
2856 CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg)
2857 ->setDoesNotThrow();
2862 class FragileHazards {
2863 CodeGenFunction &CGF;
2864 SmallVector<llvm::Value*, 20> Locals;
2865 llvm::DenseSet<llvm::BasicBlock*> BlocksBeforeTry;
2867 llvm::InlineAsm *ReadHazard;
2868 llvm::InlineAsm *WriteHazard;
2870 llvm::FunctionType *GetAsmFnType();
2872 void collectLocals();
2873 void emitReadHazard(CGBuilderTy &Builder);
2876 FragileHazards(CodeGenFunction &CGF);
2878 void emitWriteHazard();
2879 void emitHazardsInNewBlocks();
2883 /// Create the fragile-ABI read and write hazards based on the current
2884 /// state of the function, which is presumed to be immediately prior
2885 /// to a @try block. These hazards are used to maintain correct
2886 /// semantics in the face of optimization and the fragile ABI's
2887 /// cavalier use of setjmp/longjmp.
2888 FragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) {
2891 if (Locals.empty()) return;
2893 // Collect all the blocks in the function.
2894 for (llvm::Function::iterator
2895 I = CGF.CurFn->begin(), E = CGF.CurFn->end(); I != E; ++I)
2896 BlocksBeforeTry.insert(&*I);
2898 llvm::FunctionType *AsmFnTy = GetAsmFnType();
2900 // Create a read hazard for the allocas. This inhibits dead-store
2901 // optimizations and forces the values to memory. This hazard is
2902 // inserted before any 'throwing' calls in the protected scope to
2903 // reflect the possibility that the variables might be read from the
2904 // catch block if the call throws.
2906 std::string Constraint;
2907 for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
2908 if (I) Constraint += ',';
2912 ReadHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
2915 // Create a write hazard for the allocas. This inhibits folding
2916 // loads across the hazard. This hazard is inserted at the
2917 // beginning of the catch path to reflect the possibility that the
2918 // variables might have been written within the protected scope.
2920 std::string Constraint;
2921 for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
2922 if (I) Constraint += ',';
2923 Constraint += "=*m";
2926 WriteHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
2930 /// Emit a write hazard at the current location.
2931 void FragileHazards::emitWriteHazard() {
2932 if (Locals.empty()) return;
2934 CGF.Builder.CreateCall(WriteHazard, Locals)->setDoesNotThrow();
2937 void FragileHazards::emitReadHazard(CGBuilderTy &Builder) {
2938 assert(!Locals.empty());
2939 Builder.CreateCall(ReadHazard, Locals)->setDoesNotThrow();
2942 /// Emit read hazards in all the protected blocks, i.e. all the blocks
2943 /// which have been inserted since the beginning of the try.
2944 void FragileHazards::emitHazardsInNewBlocks() {
2945 if (Locals.empty()) return;
2947 CGBuilderTy Builder(CGF.getLLVMContext());
2949 // Iterate through all blocks, skipping those prior to the try.
2950 for (llvm::Function::iterator
2951 FI = CGF.CurFn->begin(), FE = CGF.CurFn->end(); FI != FE; ++FI) {
2952 llvm::BasicBlock &BB = *FI;
2953 if (BlocksBeforeTry.count(&BB)) continue;
2955 // Walk through all the calls in the block.
2956 for (llvm::BasicBlock::iterator
2957 BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
2958 llvm::Instruction &I = *BI;
2960 // Ignore instructions that aren't non-intrinsic calls.
2961 // These are the only calls that can possibly call longjmp.
2962 if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I)) continue;
2963 if (isa<llvm::IntrinsicInst>(I))
2966 // Ignore call sites marked nounwind. This may be questionable,
2967 // since 'nounwind' doesn't necessarily mean 'does not call longjmp'.
2968 llvm::CallSite CS(&I);
2969 if (CS.doesNotThrow()) continue;
2971 // Insert a read hazard before the call. This will ensure that
2972 // any writes to the locals are performed before making the
2973 // call. If the call throws, then this is sufficient to
2974 // guarantee correctness as long as it doesn't also write to any
2976 Builder.SetInsertPoint(&BB, BI);
2977 emitReadHazard(Builder);
2982 static void addIfPresent(llvm::DenseSet<llvm::Value*> &S, llvm::Value *V) {
2986 void FragileHazards::collectLocals() {
2987 // Compute a set of allocas to ignore.
2988 llvm::DenseSet<llvm::Value*> AllocasToIgnore;
2989 addIfPresent(AllocasToIgnore, CGF.ReturnValue);
2990 addIfPresent(AllocasToIgnore, CGF.NormalCleanupDest);
2992 // Collect all the allocas currently in the function. This is
2993 // probably way too aggressive.
2994 llvm::BasicBlock &Entry = CGF.CurFn->getEntryBlock();
2995 for (llvm::BasicBlock::iterator
2996 I = Entry.begin(), E = Entry.end(); I != E; ++I)
2997 if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
2998 Locals.push_back(&*I);
3001 llvm::FunctionType *FragileHazards::GetAsmFnType() {
3002 SmallVector<llvm::Type *, 16> tys(Locals.size());
3003 for (unsigned i = 0, e = Locals.size(); i != e; ++i)
3004 tys[i] = Locals[i]->getType();
3005 return llvm::FunctionType::get(CGF.VoidTy, tys, false);
3010 Objective-C setjmp-longjmp (sjlj) Exception Handling
3013 A catch buffer is a setjmp buffer plus:
3014 - a pointer to the exception that was caught
3015 - a pointer to the previous exception data buffer
3016 - two pointers of reserved storage
3017 Therefore catch buffers form a stack, with a pointer to the top
3018 of the stack kept in thread-local storage.
3020 objc_exception_try_enter pushes a catch buffer onto the EH stack.
3021 objc_exception_try_exit pops the given catch buffer, which is
3022 required to be the top of the EH stack.
3023 objc_exception_throw pops the top of the EH stack, writes the
3024 thrown exception into the appropriate field, and longjmps
3025 to the setjmp buffer. It crashes the process (with a printf
3026 and an abort()) if there are no catch buffers on the stack.
3027 objc_exception_extract just reads the exception pointer out of the
3030 There's no reason an implementation couldn't use a light-weight
3031 setjmp here --- something like __builtin_setjmp, but API-compatible
3032 with the heavyweight setjmp. This will be more important if we ever
3033 want to implement correct ObjC/C++ exception interactions for the
3036 Note that for this use of setjmp/longjmp to be correct, we may need
3037 to mark some local variables volatile: if a non-volatile local
3038 variable is modified between the setjmp and the longjmp, it has
3039 indeterminate value. For the purposes of LLVM IR, it may be
3040 sufficient to make loads and stores within the @try (to variables
3041 declared outside the @try) volatile. This is necessary for
3042 optimized correctness, but is not currently being done; this is
3043 being tracked as rdar://problem/8160285
3045 The basic framework for a @try-catch-finally is as follows:
3047 objc_exception_data d;
3049 bool _call_try_exit = true;
3051 objc_exception_try_enter(&d);
3052 if (!setjmp(d.jmp_buf)) {
3056 id _caught = objc_exception_extract(&d);
3058 // enter new try scope for handlers
3059 if (!setjmp(d.jmp_buf)) {
3060 ... match exception and execute catch blocks ...
3062 // fell off end, rethrow.
3064 ... jump-through-finally to finally_rethrow ...
3066 // exception in catch block
3067 _rethrow = objc_exception_extract(&d);
3068 _call_try_exit = false;
3069 ... jump-through-finally to finally_rethrow ...
3072 ... jump-through-finally to finally_end ...
3076 objc_exception_try_exit(&d);
3078 ... finally block ....
3079 ... dispatch to finally destination ...
3082 objc_exception_throw(_rethrow);
3087 This framework differs slightly from the one gcc uses, in that gcc
3088 uses _rethrow to determine if objc_exception_try_exit should be called
3089 and if the object should be rethrown. This breaks in the face of
3090 throwing nil and introduces unnecessary branches.
3092 We specialize this framework for a few particular circumstances:
3094 - If there are no catch blocks, then we avoid emitting the second
3095 exception handling context.
3097 - If there is a catch-all catch block (i.e. @catch(...) or @catch(id
3098 e)) we avoid emitting the code to rethrow an uncaught exception.
3100 - FIXME: If there is no @finally block we can do a few more
3103 Rethrows and Jumps-Through-Finally
3106 '@throw;' is supported by pushing the currently-caught exception
3107 onto ObjCEHStack while the @catch blocks are emitted.
3109 Branches through the @finally block are handled with an ordinary
3110 normal cleanup. We do not register an EH cleanup; fragile-ABI ObjC
3111 exceptions are not compatible with C++ exceptions, and this is
3112 hardly the only place where this will go wrong.
3114 @synchronized(expr) { stmt; } is emitted as if it were:
3115 id synch_value = expr;
3116 objc_sync_enter(synch_value);
3117 @try { stmt; } @finally { objc_sync_exit(synch_value); }
3120 void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
3122 bool isTry = isa<ObjCAtTryStmt>(S);
3124 // A destination for the fall-through edges of the catch handlers to
3126 CodeGenFunction::JumpDest FinallyEnd =
3127 CGF.getJumpDestInCurrentScope("finally.end");
3129 // A destination for the rethrow edge of the catch handlers to jump
3131 CodeGenFunction::JumpDest FinallyRethrow =
3132 CGF.getJumpDestInCurrentScope("finally.rethrow");
3134 // For @synchronized, call objc_sync_enter(sync.expr). The
3135 // evaluation of the expression must occur before we enter the
3136 // @synchronized. We can't avoid a temp here because we need the
3137 // value to be preserved. If the backend ever does liveness
3138 // correctly after setjmp, this will be unnecessary.
3139 llvm::Value *SyncArgSlot = 0;
3141 llvm::Value *SyncArg =
3142 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
3143 SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
3144 CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg)
3145 ->setDoesNotThrow();
3147 SyncArgSlot = CGF.CreateTempAlloca(SyncArg->getType(), "sync.arg");
3148 CGF.Builder.CreateStore(SyncArg, SyncArgSlot);
3151 // Allocate memory for the setjmp buffer. This needs to be kept
3152 // live throughout the try and catch blocks.
3153 llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy,
3154 "exceptiondata.ptr");
3156 // Create the fragile hazards. Note that this will not capture any
3157 // of the allocas required for exception processing, but will
3158 // capture the current basic block (which extends all the way to the
3159 // setjmp call) as "before the @try".
3160 FragileHazards Hazards(CGF);
3162 // Create a flag indicating whether the cleanup needs to call
3163 // objc_exception_try_exit. This is true except when
3164 // - no catches match and we're branching through the cleanup
3165 // just to rethrow the exception, or
3166 // - a catch matched and we're falling out of the catch handler.
3167 // The setjmp-safety rule here is that we should always store to this
3168 // variable in a place that dominates the branch through the cleanup
3169 // without passing through any setjmps.
3170 llvm::Value *CallTryExitVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(),
3173 // A slot containing the exception to rethrow. Only needed when we
3174 // have both a @catch and a @finally.
3175 llvm::Value *PropagatingExnVar = 0;
3177 // Push a normal cleanup to leave the try scope.
3178 CGF.EHStack.pushCleanup<PerformFragileFinally>(NormalCleanup, &S,
3184 // Enter a try block:
3185 // - Call objc_exception_try_enter to push ExceptionData on top of
3187 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData)
3188 ->setDoesNotThrow();
3190 // - Call setjmp on the exception data buffer.
3191 llvm::Constant *Zero = llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0);
3192 llvm::Value *GEPIndexes[] = { Zero, Zero, Zero };
3193 llvm::Value *SetJmpBuffer =
3194 CGF.Builder.CreateGEP(ExceptionData, GEPIndexes, "setjmp_buffer");
3195 llvm::CallInst *SetJmpResult =
3196 CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result");
3197 SetJmpResult->setDoesNotThrow();
3198 SetJmpResult->setCanReturnTwice();
3200 // If setjmp returned 0, enter the protected block; otherwise,
3201 // branch to the handler.
3202 llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
3203 llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
3204 llvm::Value *DidCatch =
3205 CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
3206 CGF.Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
3208 // Emit the protected block.
3209 CGF.EmitBlock(TryBlock);
3210 CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
3211 CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
3212 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
3214 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.Builder.saveAndClearIP();
3216 // Emit the exception handler block.
3217 CGF.EmitBlock(TryHandler);
3219 // Don't optimize loads of the in-scope locals across this point.
3220 Hazards.emitWriteHazard();
3222 // For a @synchronized (or a @try with no catches), just branch
3223 // through the cleanup to the rethrow block.
3224 if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
3225 // Tell the cleanup not to re-pop the exit.
3226 CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
3227 CGF.EmitBranchThroughCleanup(FinallyRethrow);
3229 // Otherwise, we have to match against the caught exceptions.
3231 // Retrieve the exception object. We may emit multiple blocks but
3232 // nothing can cross this so the value is already in SSA form.
3233 llvm::CallInst *Caught =
3234 CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
3235 ExceptionData, "caught");
3236 Caught->setDoesNotThrow();
3238 // Push the exception to rethrow onto the EH value stack for the
3239 // benefit of any @throws in the handlers.
3240 CGF.ObjCEHValueStack.push_back(Caught);
3242 const ObjCAtTryStmt* AtTryStmt = cast<ObjCAtTryStmt>(&S);
3244 bool HasFinally = (AtTryStmt->getFinallyStmt() != 0);
3246 llvm::BasicBlock *CatchBlock = 0;
3247 llvm::BasicBlock *CatchHandler = 0;
3249 // Save the currently-propagating exception before
3250 // objc_exception_try_enter clears the exception slot.
3251 PropagatingExnVar = CGF.CreateTempAlloca(Caught->getType(),
3252 "propagating_exception");
3253 CGF.Builder.CreateStore(Caught, PropagatingExnVar);
3255 // Enter a new exception try block (in case a @catch block
3256 // throws an exception).
3257 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData)
3258 ->setDoesNotThrow();
3260 llvm::CallInst *SetJmpResult =
3261 CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer,
3263 SetJmpResult->setDoesNotThrow();
3264 SetJmpResult->setCanReturnTwice();
3266 llvm::Value *Threw =
3267 CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
3269 CatchBlock = CGF.createBasicBlock("catch");
3270 CatchHandler = CGF.createBasicBlock("catch_for_catch");
3271 CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
3273 CGF.EmitBlock(CatchBlock);
3276 CGF.Builder.CreateStore(CGF.Builder.getInt1(HasFinally), CallTryExitVar);
3278 // Handle catch list. As a special case we check if everything is
3279 // matched and avoid generating code for falling off the end if
3281 bool AllMatched = false;
3282 for (unsigned I = 0, N = AtTryStmt->getNumCatchStmts(); I != N; ++I) {
3283 const ObjCAtCatchStmt *CatchStmt = AtTryStmt->getCatchStmt(I);
3285 const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
3286 const ObjCObjectPointerType *OPT = 0;
3288 // catch(...) always matches.
3292 OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>();
3294 // catch(id e) always matches under this ABI, since only
3295 // ObjC exceptions end up here in the first place.
3296 // FIXME: For the time being we also match id<X>; this should
3297 // be rejected by Sema instead.
3298 if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()))
3302 // If this is a catch-all, we don't need to test anything.
3304 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
3307 CGF.EmitAutoVarDecl(*CatchParam);
3308 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
3310 // These types work out because ConvertType(id) == i8*.
3311 CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(CatchParam));
3314 CGF.EmitStmt(CatchStmt->getCatchBody());
3316 // The scope of the catch variable ends right here.
3317 CatchVarCleanups.ForceCleanup();
3319 CGF.EmitBranchThroughCleanup(FinallyEnd);
3323 assert(OPT && "Unexpected non-object pointer type in @catch");
3324 const ObjCObjectType *ObjTy = OPT->getObjectType();
3326 // FIXME: @catch (Class c) ?
3327 ObjCInterfaceDecl *IDecl = ObjTy->getInterface();
3328 assert(IDecl && "Catch parameter must have Objective-C type!");
3330 // Check if the @catch block matches the exception object.
3331 llvm::Value *Class = EmitClassRef(CGF.Builder, IDecl);
3333 llvm::CallInst *Match =
3334 CGF.Builder.CreateCall2(ObjCTypes.getExceptionMatchFn(),
3335 Class, Caught, "match");
3336 Match->setDoesNotThrow();
3338 llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("match");
3339 llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch.next");
3341 CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"),
3342 MatchedBlock, NextCatchBlock);
3344 // Emit the @catch block.
3345 CGF.EmitBlock(MatchedBlock);
3347 // Collect any cleanups for the catch variable. The scope lasts until
3348 // the end of the catch body.
3349 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
3351 CGF.EmitAutoVarDecl(*CatchParam);
3352 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
3354 // Initialize the catch variable.
3356 CGF.Builder.CreateBitCast(Caught,
3357 CGF.ConvertType(CatchParam->getType()));
3358 CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(CatchParam));
3360 CGF.EmitStmt(CatchStmt->getCatchBody());
3362 // We're done with the catch variable.
3363 CatchVarCleanups.ForceCleanup();
3365 CGF.EmitBranchThroughCleanup(FinallyEnd);
3367 CGF.EmitBlock(NextCatchBlock);
3370 CGF.ObjCEHValueStack.pop_back();
3372 // If nothing wanted anything to do with the caught exception,
3373 // kill the extract call.
3374 if (Caught->use_empty())
3375 Caught->eraseFromParent();
3378 CGF.EmitBranchThroughCleanup(FinallyRethrow);
3381 // Emit the exception handler for the @catch blocks.
3382 CGF.EmitBlock(CatchHandler);
3384 // In theory we might now need a write hazard, but actually it's
3385 // unnecessary because there's no local-accessing code between
3386 // the try's write hazard and here.
3387 //Hazards.emitWriteHazard();
3389 // Extract the new exception and save it to the
3390 // propagating-exception slot.
3391 assert(PropagatingExnVar);
3392 llvm::CallInst *NewCaught =
3393 CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
3394 ExceptionData, "caught");
3395 NewCaught->setDoesNotThrow();
3396 CGF.Builder.CreateStore(NewCaught, PropagatingExnVar);
3398 // Don't pop the catch handler; the throw already did.
3399 CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
3400 CGF.EmitBranchThroughCleanup(FinallyRethrow);
3404 // Insert read hazards as required in the new blocks.
3405 Hazards.emitHazardsInNewBlocks();
3408 CGF.Builder.restoreIP(TryFallthroughIP);
3409 if (CGF.HaveInsertPoint())
3410 CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
3411 CGF.PopCleanupBlock();
3412 CGF.EmitBlock(FinallyEnd.getBlock(), true);
3414 // Emit the rethrow block.
3415 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
3416 CGF.EmitBlock(FinallyRethrow.getBlock(), true);
3417 if (CGF.HaveInsertPoint()) {
3418 // If we have a propagating-exception variable, check it.
3419 llvm::Value *PropagatingExn;
3420 if (PropagatingExnVar) {
3421 PropagatingExn = CGF.Builder.CreateLoad(PropagatingExnVar);
3423 // Otherwise, just look in the buffer for the exception to throw.
3425 llvm::CallInst *Caught =
3426 CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
3428 Caught->setDoesNotThrow();
3429 PropagatingExn = Caught;
3432 CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), PropagatingExn)
3433 ->setDoesNotThrow();
3434 CGF.Builder.CreateUnreachable();
3437 CGF.Builder.restoreIP(SavedIP);
3440 void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
3441 const ObjCAtThrowStmt &S) {
3442 llvm::Value *ExceptionAsObject;
3444 if (const Expr *ThrowExpr = S.getThrowExpr()) {
3445 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
3447 CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
3449 assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
3450 "Unexpected rethrow outside @catch block.");
3451 ExceptionAsObject = CGF.ObjCEHValueStack.back();
3454 CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
3455 ->setDoesNotReturn();
3456 CGF.Builder.CreateUnreachable();
3458 // Clear the insertion point to indicate we are in unreachable code.
3459 CGF.Builder.ClearInsertionPoint();
3462 /// EmitObjCWeakRead - Code gen for loading value of a __weak
3463 /// object: objc_read_weak (id *src)
3465 llvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
3466 llvm::Value *AddrWeakObj) {
3467 llvm::Type* DestTy =
3468 cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
3469 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj,
3470 ObjCTypes.PtrObjectPtrTy);
3471 llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(),
3472 AddrWeakObj, "weakread");
3473 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
3477 /// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
3478 /// objc_assign_weak (id src, id *dst)
3480 void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
3481 llvm::Value *src, llvm::Value *dst) {
3482 llvm::Type * SrcTy = src->getType();
3483 if (!isa<llvm::PointerType>(SrcTy)) {
3484 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
3485 assert(Size <= 8 && "does not support size > 8");
3486 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
3487 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
3488 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
3490 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
3491 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
3492 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(),
3493 src, dst, "weakassign");
3497 /// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
3498 /// objc_assign_global (id src, id *dst)
3500 void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
3501 llvm::Value *src, llvm::Value *dst,
3503 llvm::Type * SrcTy = src->getType();
3504 if (!isa<llvm::PointerType>(SrcTy)) {
3505 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
3506 assert(Size <= 8 && "does not support size > 8");
3507 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
3508 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
3509 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
3511 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
3512 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
3514 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(),
3515 src, dst, "globalassign");
3517 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(),
3518 src, dst, "threadlocalassign");
3522 /// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
3523 /// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset)
3525 void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
3526 llvm::Value *src, llvm::Value *dst,
3527 llvm::Value *ivarOffset) {
3528 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL");
3529 llvm::Type * SrcTy = src->getType();
3530 if (!isa<llvm::PointerType>(SrcTy)) {
3531 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
3532 assert(Size <= 8 && "does not support size > 8");
3533 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
3534 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
3535 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
3537 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
3538 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
3539 CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(),
3540 src, dst, ivarOffset);
3544 /// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
3545 /// objc_assign_strongCast (id src, id *dst)
3547 void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
3548 llvm::Value *src, llvm::Value *dst) {
3549 llvm::Type * SrcTy = src->getType();
3550 if (!isa<llvm::PointerType>(SrcTy)) {
3551 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
3552 assert(Size <= 8 && "does not support size > 8");
3553 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
3554 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
3555 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
3557 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
3558 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
3559 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(),
3560 src, dst, "weakassign");
3564 void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
3565 llvm::Value *DestPtr,
3566 llvm::Value *SrcPtr,
3567 llvm::Value *size) {
3568 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
3569 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
3570 CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(),
3571 DestPtr, SrcPtr, size);
3575 /// EmitObjCValueForIvar - Code Gen for ivar reference.
3577 LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
3579 llvm::Value *BaseValue,
3580 const ObjCIvarDecl *Ivar,
3581 unsigned CVRQualifiers) {
3582 const ObjCInterfaceDecl *ID =
3583 ObjectTy->getAs<ObjCObjectType>()->getInterface();
3584 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
3585 EmitIvarOffset(CGF, ID, Ivar));
3588 llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
3589 const ObjCInterfaceDecl *Interface,
3590 const ObjCIvarDecl *Ivar) {
3591 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
3592 return llvm::ConstantInt::get(
3593 CGM.getTypes().ConvertType(CGM.getContext().LongTy),
3597 /* *** Private Interface *** */
3599 /// EmitImageInfo - Emit the image info marker used to encode some module
3600 /// level information.
3602 /// See: <rdr://4810609&4810587&4810587>
3603 /// struct IMAGE_INFO {
3604 /// unsigned version;
3607 enum ImageInfoFlags {
3608 eImageInfo_FixAndContinue = (1 << 0),
3609 eImageInfo_GarbageCollected = (1 << 1),
3610 eImageInfo_GCOnly = (1 << 2),
3611 eImageInfo_OptimizedByDyld = (1 << 3), // FIXME: When is this set.
3613 // A flag indicating that the module has no instances of a @synthesize of a
3614 // superclass variable. <rdar://problem/6803242>
3615 eImageInfo_CorrectedSynthesize = (1 << 4)
3618 void CGObjCCommonMac::EmitImageInfo() {
3619 unsigned version = 0; // Version is unused?
3620 const char *Section = (ObjCABI == 1) ?
3621 "__OBJC, __image_info,regular" :
3622 "__DATA, __objc_imageinfo, regular, no_dead_strip";
3624 // Generate module-level named metadata to convey this information to the
3625 // linker and code-gen.
3626 llvm::Module &Mod = CGM.getModule();
3628 // Add the ObjC ABI version to the module flags.
3629 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version", ObjCABI);
3630 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version",
3632 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section",
3633 llvm::MDString::get(VMContext,Section));
3635 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
3636 // Non-GC overrides those files which specify GC.
3637 Mod.addModuleFlag(llvm::Module::Override,
3638 "Objective-C Garbage Collection", (uint32_t)0);
3640 // Add the ObjC garbage collection value.
3641 Mod.addModuleFlag(llvm::Module::Error,
3642 "Objective-C Garbage Collection",
3643 eImageInfo_GarbageCollected);
3645 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
3646 // Add the ObjC GC Only value.
3647 Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only",
3650 // Require that GC be specified and set to eImageInfo_GarbageCollected.
3651 llvm::Value *Ops[2] = {
3652 llvm::MDString::get(VMContext, "Objective-C Garbage Collection"),
3653 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
3654 eImageInfo_GarbageCollected)
3656 Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only",
3657 llvm::MDNode::get(VMContext, Ops));
3662 // struct objc_module {
3663 // unsigned long version;
3664 // unsigned long size;
3665 // const char *name;
3669 // FIXME: Get from somewhere
3670 static const int ModuleVersion = 7;
3672 void CGObjCMac::EmitModuleInfo() {
3673 uint64_t Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ModuleTy);
3675 llvm::Constant *Values[] = {
3676 llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion),
3677 llvm::ConstantInt::get(ObjCTypes.LongTy, Size),
3678 // This used to be the filename, now it is unused. <rdr://4327263>
3679 GetClassName(&CGM.getContext().Idents.get("")),
3682 CreateMetadataVar("\01L_OBJC_MODULES",
3683 llvm::ConstantStruct::get(ObjCTypes.ModuleTy, Values),
3684 "__OBJC,__module_info,regular,no_dead_strip",
3688 llvm::Constant *CGObjCMac::EmitModuleSymbols() {
3689 unsigned NumClasses = DefinedClasses.size();
3690 unsigned NumCategories = DefinedCategories.size();
3692 // Return null if no symbols were defined.
3693 if (!NumClasses && !NumCategories)
3694 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
3696 llvm::Constant *Values[5];
3697 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
3698 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
3699 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
3700 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
3702 // The runtime expects exactly the list of defined classes followed
3703 // by the list of defined categories, in a single array.
3704 SmallVector<llvm::Constant*, 8> Symbols(NumClasses + NumCategories);
3705 for (unsigned i=0; i<NumClasses; i++)
3706 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
3707 ObjCTypes.Int8PtrTy);
3708 for (unsigned i=0; i<NumCategories; i++)
3709 Symbols[NumClasses + i] =
3710 llvm::ConstantExpr::getBitCast(DefinedCategories[i],
3711 ObjCTypes.Int8PtrTy);
3714 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
3718 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
3720 llvm::GlobalVariable *GV =
3721 CreateMetadataVar("\01L_OBJC_SYMBOLS", Init,
3722 "__OBJC,__symbols,regular,no_dead_strip",
3724 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
3727 llvm::Value *CGObjCMac::EmitClassRefFromId(CGBuilderTy &Builder,
3728 IdentifierInfo *II) {
3729 LazySymbols.insert(II);
3731 llvm::GlobalVariable *&Entry = ClassReferences[II];
3734 llvm::Constant *Casted =
3735 llvm::ConstantExpr::getBitCast(GetClassName(II),
3736 ObjCTypes.ClassPtrTy);
3738 CreateMetadataVar("\01L_OBJC_CLASS_REFERENCES_", Casted,
3739 "__OBJC,__cls_refs,literal_pointers,no_dead_strip",
3743 return Builder.CreateLoad(Entry);
3746 llvm::Value *CGObjCMac::EmitClassRef(CGBuilderTy &Builder,
3747 const ObjCInterfaceDecl *ID) {
3748 return EmitClassRefFromId(Builder, ID->getIdentifier());
3751 llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder) {
3752 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
3753 return EmitClassRefFromId(Builder, II);
3756 llvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel,
3758 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
3761 llvm::Constant *Casted =
3762 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
3763 ObjCTypes.SelectorPtrTy);
3765 CreateMetadataVar("\01L_OBJC_SELECTOR_REFERENCES_", Casted,
3766 "__OBJC,__message_refs,literal_pointers,no_dead_strip",
3772 return Builder.CreateLoad(Entry);
3775 llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) {
3776 llvm::GlobalVariable *&Entry = ClassNames[Ident];
3779 Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
3780 llvm::ConstantDataArray::getString(VMContext,
3781 Ident->getNameStart()),
3783 "__TEXT,__objc_classname,cstring_literals" :
3784 "__TEXT,__cstring,cstring_literals"),
3787 return getConstantGEP(VMContext, Entry, 0, 0);
3790 llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
3791 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator
3792 I = MethodDefinitions.find(MD);
3793 if (I != MethodDefinitions.end())
3799 /// GetIvarLayoutName - Returns a unique constant for the given
3800 /// ivar layout bitmap.
3801 llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
3802 const ObjCCommonTypesHelper &ObjCTypes) {
3803 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
3806 void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT,
3807 unsigned int BytePos,
3808 bool ForStrongLayout,
3810 const RecordDecl *RD = RT->getDecl();
3811 // FIXME - Use iterator.
3812 SmallVector<const FieldDecl*, 16> Fields(RD->field_begin(), RD->field_end());
3813 llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
3814 const llvm::StructLayout *RecLayout =
3815 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(Ty));
3817 BuildAggrIvarLayout(0, RecLayout, RD, Fields, BytePos,
3818 ForStrongLayout, HasUnion);
3821 void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
3822 const llvm::StructLayout *Layout,
3823 const RecordDecl *RD,
3824 ArrayRef<const FieldDecl*> RecFields,
3825 unsigned int BytePos, bool ForStrongLayout,
3827 bool IsUnion = (RD && RD->isUnion());
3828 uint64_t MaxUnionIvarSize = 0;
3829 uint64_t MaxSkippedUnionIvarSize = 0;
3830 const FieldDecl *MaxField = 0;
3831 const FieldDecl *MaxSkippedField = 0;
3832 const FieldDecl *LastFieldBitfieldOrUnnamed = 0;
3833 uint64_t MaxFieldOffset = 0;
3834 uint64_t MaxSkippedFieldOffset = 0;
3835 uint64_t LastBitfieldOrUnnamedOffset = 0;
3836 uint64_t FirstFieldDelta = 0;
3838 if (RecFields.empty())
3840 unsigned WordSizeInBits = CGM.getContext().getTargetInfo().getPointerWidth(0);
3841 unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth();
3842 if (!RD && CGM.getLangOpts().ObjCAutoRefCount) {
3843 const FieldDecl *FirstField = RecFields[0];
3845 ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(FirstField));
3848 for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
3849 const FieldDecl *Field = RecFields[i];
3850 uint64_t FieldOffset;
3852 // Note that 'i' here is actually the field index inside RD of Field,
3853 // although this dependency is hidden.
3854 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
3855 FieldOffset = (RL.getFieldOffset(i) / ByteSizeInBits) - FirstFieldDelta;
3858 ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field)) - FirstFieldDelta;
3860 // Skip over unnamed or bitfields
3861 if (!Field->getIdentifier() || Field->isBitField()) {
3862 LastFieldBitfieldOrUnnamed = Field;
3863 LastBitfieldOrUnnamedOffset = FieldOffset;
3867 LastFieldBitfieldOrUnnamed = 0;
3868 QualType FQT = Field->getType();
3869 if (FQT->isRecordType() || FQT->isUnionType()) {
3870 if (FQT->isUnionType())
3873 BuildAggrIvarRecordLayout(FQT->getAs<RecordType>(),
3874 BytePos + FieldOffset,
3875 ForStrongLayout, HasUnion);
3879 if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
3880 const ConstantArrayType *CArray =
3881 dyn_cast_or_null<ConstantArrayType>(Array);
3882 uint64_t ElCount = CArray->getSize().getZExtValue();
3883 assert(CArray && "only array with known element size is supported");
3884 FQT = CArray->getElementType();
3885 while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
3886 const ConstantArrayType *CArray =
3887 dyn_cast_or_null<ConstantArrayType>(Array);
3888 ElCount *= CArray->getSize().getZExtValue();
3889 FQT = CArray->getElementType();
3892 assert(!FQT->isUnionType() &&
3893 "layout for array of unions not supported");
3894 if (FQT->isRecordType() && ElCount) {
3895 int OldIndex = IvarsInfo.size() - 1;
3896 int OldSkIndex = SkipIvars.size() -1;
3898 const RecordType *RT = FQT->getAs<RecordType>();
3899 BuildAggrIvarRecordLayout(RT, BytePos + FieldOffset,
3900 ForStrongLayout, HasUnion);
3902 // Replicate layout information for each array element. Note that
3903 // one element is already done.
3905 for (int FirstIndex = IvarsInfo.size() - 1,
3906 FirstSkIndex = SkipIvars.size() - 1 ;ElIx < ElCount; ElIx++) {
3907 uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits;
3908 for (int i = OldIndex+1; i <= FirstIndex; ++i)
3909 IvarsInfo.push_back(GC_IVAR(IvarsInfo[i].ivar_bytepos + Size*ElIx,
3910 IvarsInfo[i].ivar_size));
3911 for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i)
3912 SkipIvars.push_back(GC_IVAR(SkipIvars[i].ivar_bytepos + Size*ElIx,
3913 SkipIvars[i].ivar_size));
3918 // At this point, we are done with Record/Union and array there of.
3919 // For other arrays we are down to its element type.
3920 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT);
3922 unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType());
3923 if ((ForStrongLayout && GCAttr == Qualifiers::Strong)
3924 || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
3926 uint64_t UnionIvarSize = FieldSize / WordSizeInBits;
3927 if (UnionIvarSize > MaxUnionIvarSize) {
3928 MaxUnionIvarSize = UnionIvarSize;
3930 MaxFieldOffset = FieldOffset;
3933 IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset,
3934 FieldSize / WordSizeInBits));
3936 } else if ((ForStrongLayout &&
3937 (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak))
3938 || (!ForStrongLayout && GCAttr != Qualifiers::Weak)) {
3940 // FIXME: Why the asymmetry? We divide by word size in bits on other
3942 uint64_t UnionIvarSize = FieldSize;
3943 if (UnionIvarSize > MaxSkippedUnionIvarSize) {
3944 MaxSkippedUnionIvarSize = UnionIvarSize;
3945 MaxSkippedField = Field;
3946 MaxSkippedFieldOffset = FieldOffset;
3949 // FIXME: Why the asymmetry, we divide by byte size in bits here?
3950 SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset,
3951 FieldSize / ByteSizeInBits));
3956 if (LastFieldBitfieldOrUnnamed) {
3957 if (LastFieldBitfieldOrUnnamed->isBitField()) {
3958 // Last field was a bitfield. Must update skip info.
3959 uint64_t BitFieldSize
3960 = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext());
3962 skivar.ivar_bytepos = BytePos + LastBitfieldOrUnnamedOffset;
3963 skivar.ivar_size = (BitFieldSize / ByteSizeInBits)
3964 + ((BitFieldSize % ByteSizeInBits) != 0);
3965 SkipIvars.push_back(skivar);
3967 assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed");
3968 // Last field was unnamed. Must update skip info.
3970 = CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType());
3971 SkipIvars.push_back(GC_IVAR(BytePos + LastBitfieldOrUnnamedOffset,
3972 FieldSize / ByteSizeInBits));
3977 IvarsInfo.push_back(GC_IVAR(BytePos + MaxFieldOffset,
3979 if (MaxSkippedField)
3980 SkipIvars.push_back(GC_IVAR(BytePos + MaxSkippedFieldOffset,
3981 MaxSkippedUnionIvarSize));
3984 /// BuildIvarLayoutBitmap - This routine is the horsework for doing all
3985 /// the computations and returning the layout bitmap (for ivar or blocks) in
3986 /// the given argument BitMap string container. Routine reads
3987 /// two containers, IvarsInfo and SkipIvars which are assumed to be
3988 /// filled already by the caller.
3989 llvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string &BitMap) {
3990 unsigned int WordsToScan, WordsToSkip;
3991 llvm::Type *PtrTy = CGM.Int8PtrTy;
3993 // Build the string of skip/scan nibbles
3994 SmallVector<SKIP_SCAN, 32> SkipScanIvars;
3995 unsigned int WordSize =
3996 CGM.getTypes().getTargetData().getTypeAllocSize(PtrTy);
3997 if (IvarsInfo[0].ivar_bytepos == 0) {
3999 WordsToScan = IvarsInfo[0].ivar_size;
4001 WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize;
4002 WordsToScan = IvarsInfo[0].ivar_size;
4004 for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++) {
4005 unsigned int TailPrevGCObjC =
4006 IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize;
4007 if (IvarsInfo[i].ivar_bytepos == TailPrevGCObjC) {
4008 // consecutive 'scanned' object pointers.
4009 WordsToScan += IvarsInfo[i].ivar_size;
4011 // Skip over 'gc'able object pointer which lay over each other.
4012 if (TailPrevGCObjC > IvarsInfo[i].ivar_bytepos)
4014 // Must skip over 1 or more words. We save current skip/scan values
4015 // and start a new pair.
4017 SkScan.skip = WordsToSkip;
4018 SkScan.scan = WordsToScan;
4019 SkipScanIvars.push_back(SkScan);
4022 SkScan.skip = (IvarsInfo[i].ivar_bytepos - TailPrevGCObjC) / WordSize;
4024 SkipScanIvars.push_back(SkScan);
4026 WordsToScan = IvarsInfo[i].ivar_size;
4029 if (WordsToScan > 0) {
4031 SkScan.skip = WordsToSkip;
4032 SkScan.scan = WordsToScan;
4033 SkipScanIvars.push_back(SkScan);
4036 if (!SkipIvars.empty()) {
4037 unsigned int LastIndex = SkipIvars.size()-1;
4038 int LastByteSkipped =
4039 SkipIvars[LastIndex].ivar_bytepos + SkipIvars[LastIndex].ivar_size;
4040 LastIndex = IvarsInfo.size()-1;
4041 int LastByteScanned =
4042 IvarsInfo[LastIndex].ivar_bytepos +
4043 IvarsInfo[LastIndex].ivar_size * WordSize;
4044 // Compute number of bytes to skip at the tail end of the last ivar scanned.
4045 if (LastByteSkipped > LastByteScanned) {
4046 unsigned int TotalWords = (LastByteSkipped + (WordSize -1)) / WordSize;
4048 SkScan.skip = TotalWords - (LastByteScanned/WordSize);
4050 SkipScanIvars.push_back(SkScan);
4053 // Mini optimization of nibbles such that an 0xM0 followed by 0x0N is produced
4055 int SkipScan = SkipScanIvars.size()-1;
4056 for (int i = 0; i <= SkipScan; i++) {
4057 if ((i < SkipScan) && SkipScanIvars[i].skip && SkipScanIvars[i].scan == 0
4058 && SkipScanIvars[i+1].skip == 0 && SkipScanIvars[i+1].scan) {
4059 // 0xM0 followed by 0x0N detected.
4060 SkipScanIvars[i].scan = SkipScanIvars[i+1].scan;
4061 for (int j = i+1; j < SkipScan; j++)
4062 SkipScanIvars[j] = SkipScanIvars[j+1];
4067 // Generate the string.
4068 for (int i = 0; i <= SkipScan; i++) {
4070 unsigned int skip_small = SkipScanIvars[i].skip % 0xf;
4071 unsigned int scan_small = SkipScanIvars[i].scan % 0xf;
4072 unsigned int skip_big = SkipScanIvars[i].skip / 0xf;
4073 unsigned int scan_big = SkipScanIvars[i].scan / 0xf;
4076 for (unsigned int ix = 0; ix < skip_big; ix++)
4077 BitMap += (unsigned char)(0xf0);
4079 // next (skip small, scan)
4081 byte = skip_small << 4;
4085 } else if (scan_small) {
4092 for (unsigned int ix = 0; ix < scan_big; ix++)
4093 BitMap += (unsigned char)(0x0f);
4100 // null terminate string.
4101 unsigned char zero = 0;
4104 llvm::GlobalVariable * Entry =
4105 CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
4106 llvm::ConstantDataArray::getString(VMContext, BitMap,false),
4108 "__TEXT,__objc_classname,cstring_literals" :
4109 "__TEXT,__cstring,cstring_literals"),
4111 return getConstantGEP(VMContext, Entry, 0, 0);
4114 /// BuildIvarLayout - Builds ivar layout bitmap for the class
4115 /// implementation for the __strong or __weak case.
4116 /// The layout map displays which words in ivar list must be skipped
4117 /// and which must be scanned by GC (see below). String is built of bytes.
4118 /// Each byte is divided up in two nibbles (4-bit each). Left nibble is count
4119 /// of words to skip and right nibble is count of words to scan. So, each
4120 /// nibble represents up to 15 workds to skip or scan. Skipping the rest is
4121 /// represented by a 0x00 byte which also ends the string.
4122 /// 1. when ForStrongLayout is true, following ivars are scanned:
4125 /// - __strong anything
4127 /// 2. When ForStrongLayout is false, following ivars are scanned:
4128 /// - __weak anything
4130 llvm::Constant *CGObjCCommonMac::BuildIvarLayout(
4131 const ObjCImplementationDecl *OMD,
4132 bool ForStrongLayout) {
4133 bool hasUnion = false;
4135 llvm::Type *PtrTy = CGM.Int8PtrTy;
4136 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
4137 !CGM.getLangOpts().ObjCAutoRefCount)
4138 return llvm::Constant::getNullValue(PtrTy);
4140 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
4141 SmallVector<const FieldDecl*, 32> RecFields;
4142 if (CGM.getLangOpts().ObjCAutoRefCount) {
4143 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
4144 IVD; IVD = IVD->getNextIvar())
4145 RecFields.push_back(cast<FieldDecl>(IVD));
4148 SmallVector<const ObjCIvarDecl*, 32> Ivars;
4149 CGM.getContext().DeepCollectObjCIvars(OI, true, Ivars);
4151 // FIXME: This is not ideal; we shouldn't have to do this copy.
4152 RecFields.append(Ivars.begin(), Ivars.end());
4155 if (RecFields.empty())
4156 return llvm::Constant::getNullValue(PtrTy);
4161 BuildAggrIvarLayout(OMD, 0, 0, RecFields, 0, ForStrongLayout, hasUnion);
4162 if (IvarsInfo.empty())
4163 return llvm::Constant::getNullValue(PtrTy);
4164 // Sort on byte position in case we encounterred a union nested in
4166 if (hasUnion && !IvarsInfo.empty())
4167 std::sort(IvarsInfo.begin(), IvarsInfo.end());
4168 if (hasUnion && !SkipIvars.empty())
4169 std::sort(SkipIvars.begin(), SkipIvars.end());
4172 llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
4174 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
4175 printf("\n%s ivar layout for class '%s': ",
4176 ForStrongLayout ? "strong" : "weak",
4177 OMD->getClassInterface()->getName().data());
4178 const unsigned char *s = (unsigned char*)BitMap.c_str();
4179 for (unsigned i = 0, e = BitMap.size(); i < e; i++)
4181 printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
4183 printf("0x%x%s", s[i], s[i] != 0 ? ", " : "");
4189 llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
4190 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
4192 // FIXME: Avoid std::string in "Sel.getAsString()"
4194 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_NAME_",
4195 llvm::ConstantDataArray::getString(VMContext, Sel.getAsString()),
4197 "__TEXT,__objc_methname,cstring_literals" :
4198 "__TEXT,__cstring,cstring_literals"),
4201 return getConstantGEP(VMContext, Entry, 0, 0);
4204 // FIXME: Merge into a single cstring creation function.
4205 llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
4206 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
4209 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
4210 std::string TypeStr;
4211 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
4213 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
4216 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_",
4217 llvm::ConstantDataArray::getString(VMContext, TypeStr),
4219 "__TEXT,__objc_methtype,cstring_literals" :
4220 "__TEXT,__cstring,cstring_literals"),
4223 return getConstantGEP(VMContext, Entry, 0, 0);
4226 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
4228 std::string TypeStr;
4229 if (CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr, Extended))
4232 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
4235 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_",
4236 llvm::ConstantDataArray::getString(VMContext, TypeStr),
4238 "__TEXT,__objc_methtype,cstring_literals" :
4239 "__TEXT,__cstring,cstring_literals"),
4242 return getConstantGEP(VMContext, Entry, 0, 0);
4245 // FIXME: Merge into a single cstring creation function.
4246 llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
4247 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
4250 Entry = CreateMetadataVar("\01L_OBJC_PROP_NAME_ATTR_",
4251 llvm::ConstantDataArray::getString(VMContext,
4252 Ident->getNameStart()),
4253 "__TEXT,__cstring,cstring_literals",
4256 return getConstantGEP(VMContext, Entry, 0, 0);
4259 // FIXME: Merge into a single cstring creation function.
4260 // FIXME: This Decl should be more precise.
4262 CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
4263 const Decl *Container) {
4264 std::string TypeStr;
4265 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
4266 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
4269 void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D,
4270 const ObjCContainerDecl *CD,
4271 SmallVectorImpl<char> &Name) {
4272 llvm::raw_svector_ostream OS(Name);
4273 assert (CD && "Missing container decl in GetNameForMethod");
4274 OS << '\01' << (D->isInstanceMethod() ? '-' : '+')
4275 << '[' << CD->getName();
4276 if (const ObjCCategoryImplDecl *CID =
4277 dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
4278 OS << '(' << *CID << ')';
4279 OS << ' ' << D->getSelector().getAsString() << ']';
4282 void CGObjCMac::FinishModule() {
4285 // Emit the dummy bodies for any protocols which were referenced but
4287 for (llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*>::iterator
4288 I = Protocols.begin(), e = Protocols.end(); I != e; ++I) {
4289 if (I->second->hasInitializer())
4292 llvm::Constant *Values[5];
4293 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
4294 Values[1] = GetClassName(I->first);
4295 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
4296 Values[3] = Values[4] =
4297 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
4298 I->second->setLinkage(llvm::GlobalValue::InternalLinkage);
4299 I->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
4301 CGM.AddUsedGlobal(I->second);
4304 // Add assembler directives to add lazy undefined symbol references
4305 // for classes which are referenced but not defined. This is
4306 // important for correct linker interaction.
4308 // FIXME: It would be nice if we had an LLVM construct for this.
4309 if (!LazySymbols.empty() || !DefinedSymbols.empty()) {
4310 SmallString<256> Asm;
4311 Asm += CGM.getModule().getModuleInlineAsm();
4312 if (!Asm.empty() && Asm.back() != '\n')
4315 llvm::raw_svector_ostream OS(Asm);
4316 for (llvm::SetVector<IdentifierInfo*>::iterator I = DefinedSymbols.begin(),
4317 e = DefinedSymbols.end(); I != e; ++I)
4318 OS << "\t.objc_class_name_" << (*I)->getName() << "=0\n"
4319 << "\t.globl .objc_class_name_" << (*I)->getName() << "\n";
4320 for (llvm::SetVector<IdentifierInfo*>::iterator I = LazySymbols.begin(),
4321 e = LazySymbols.end(); I != e; ++I) {
4322 OS << "\t.lazy_reference .objc_class_name_" << (*I)->getName() << "\n";
4325 for (size_t i = 0, e = DefinedCategoryNames.size(); i < e; ++i) {
4326 OS << "\t.objc_category_name_" << DefinedCategoryNames[i] << "=0\n"
4327 << "\t.globl .objc_category_name_" << DefinedCategoryNames[i] << "\n";
4330 CGM.getModule().setModuleInlineAsm(OS.str());
4334 CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
4335 : CGObjCCommonMac(cgm),
4337 ObjCEmptyCacheVar = ObjCEmptyVtableVar = NULL;
4343 ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
4344 : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(0)
4346 CodeGen::CodeGenTypes &Types = CGM.getTypes();
4347 ASTContext &Ctx = CGM.getContext();
4349 ShortTy = Types.ConvertType(Ctx.ShortTy);
4350 IntTy = Types.ConvertType(Ctx.IntTy);
4351 LongTy = Types.ConvertType(Ctx.LongTy);
4352 LongLongTy = Types.ConvertType(Ctx.LongLongTy);
4353 Int8PtrTy = CGM.Int8PtrTy;
4354 Int8PtrPtrTy = CGM.Int8PtrPtrTy;
4356 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
4357 PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy);
4358 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
4360 // I'm not sure I like this. The implicit coordination is a bit
4361 // gross. We should solve this in a reasonable fashion because this
4362 // is a pretty common task (match some runtime data structure with
4363 // an LLVM data structure).
4365 // FIXME: This is leaked.
4366 // FIXME: Merge with rewriter code?
4368 // struct _objc_super {
4372 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
4373 Ctx.getTranslationUnitDecl(),
4374 SourceLocation(), SourceLocation(),
4375 &Ctx.Idents.get("_objc_super"));
4376 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
4377 Ctx.getObjCIdType(), 0, 0, false, false));
4378 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
4379 Ctx.getObjCClassType(), 0, 0, false, false));
4380 RD->completeDefinition();
4382 SuperCTy = Ctx.getTagDeclType(RD);
4383 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
4385 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
4386 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
4390 // char *attributes;
4392 PropertyTy = llvm::StructType::create("struct._prop_t",
4393 Int8PtrTy, Int8PtrTy, NULL);
4395 // struct _prop_list_t {
4396 // uint32_t entsize; // sizeof(struct _prop_t)
4397 // uint32_t count_of_properties;
4398 // struct _prop_t prop_list[count_of_properties];
4401 llvm::StructType::create("struct._prop_list_t", IntTy, IntTy,
4402 llvm::ArrayType::get(PropertyTy, 0), NULL);
4403 // struct _prop_list_t *
4404 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
4406 // struct _objc_method {
4408 // char *method_type;
4411 MethodTy = llvm::StructType::create("struct._objc_method",
4412 SelectorPtrTy, Int8PtrTy, Int8PtrTy,
4415 // struct _objc_cache *
4416 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache");
4417 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
4421 ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
4422 : ObjCCommonTypesHelper(cgm) {
4423 // struct _objc_method_description {
4427 MethodDescriptionTy =
4428 llvm::StructType::create("struct._objc_method_description",
4429 SelectorPtrTy, Int8PtrTy, NULL);
4431 // struct _objc_method_description_list {
4433 // struct _objc_method_description[1];
4435 MethodDescriptionListTy =
4436 llvm::StructType::create("struct._objc_method_description_list",
4438 llvm::ArrayType::get(MethodDescriptionTy, 0),NULL);
4440 // struct _objc_method_description_list *
4441 MethodDescriptionListPtrTy =
4442 llvm::PointerType::getUnqual(MethodDescriptionListTy);
4444 // Protocol description structures
4446 // struct _objc_protocol_extension {
4447 // uint32_t size; // sizeof(struct _objc_protocol_extension)
4448 // struct _objc_method_description_list *optional_instance_methods;
4449 // struct _objc_method_description_list *optional_class_methods;
4450 // struct _objc_property_list *instance_properties;
4451 // const char ** extendedMethodTypes;
4453 ProtocolExtensionTy =
4454 llvm::StructType::create("struct._objc_protocol_extension",
4455 IntTy, MethodDescriptionListPtrTy,
4456 MethodDescriptionListPtrTy, PropertyListPtrTy,
4457 Int8PtrPtrTy, NULL);
4459 // struct _objc_protocol_extension *
4460 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
4462 // Handle recursive construction of Protocol and ProtocolList types
4465 llvm::StructType::create(VMContext, "struct._objc_protocol");
4468 llvm::StructType::create(VMContext, "struct._objc_protocol_list");
4469 ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy),
4471 llvm::ArrayType::get(ProtocolTy, 0),
4474 // struct _objc_protocol {
4475 // struct _objc_protocol_extension *isa;
4476 // char *protocol_name;
4477 // struct _objc_protocol **_objc_protocol_list;
4478 // struct _objc_method_description_list *instance_methods;
4479 // struct _objc_method_description_list *class_methods;
4481 ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy,
4482 llvm::PointerType::getUnqual(ProtocolListTy),
4483 MethodDescriptionListPtrTy,
4484 MethodDescriptionListPtrTy,
4487 // struct _objc_protocol_list *
4488 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
4490 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
4492 // Class description structures
4494 // struct _objc_ivar {
4499 IvarTy = llvm::StructType::create("struct._objc_ivar",
4500 Int8PtrTy, Int8PtrTy, IntTy, NULL);
4502 // struct _objc_ivar_list *
4504 llvm::StructType::create(VMContext, "struct._objc_ivar_list");
4505 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
4507 // struct _objc_method_list *
4509 llvm::StructType::create(VMContext, "struct._objc_method_list");
4510 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
4512 // struct _objc_class_extension *
4514 llvm::StructType::create("struct._objc_class_extension",
4515 IntTy, Int8PtrTy, PropertyListPtrTy, NULL);
4516 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
4518 ClassTy = llvm::StructType::create(VMContext, "struct._objc_class");
4520 // struct _objc_class {
4522 // Class super_class;
4526 // long instance_size;
4527 // struct _objc_ivar_list *ivars;
4528 // struct _objc_method_list *methods;
4529 // struct _objc_cache *cache;
4530 // struct _objc_protocol_list *protocols;
4531 // char *ivar_layout;
4532 // struct _objc_class_ext *ext;
4534 ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy),
4535 llvm::PointerType::getUnqual(ClassTy),
4545 ClassExtensionPtrTy,
4548 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
4550 // struct _objc_category {
4551 // char *category_name;
4552 // char *class_name;
4553 // struct _objc_method_list *instance_method;
4554 // struct _objc_method_list *class_method;
4555 // uint32_t size; // sizeof(struct _objc_category)
4556 // struct _objc_property_list *instance_properties;// category's @property
4559 llvm::StructType::create("struct._objc_category",
4560 Int8PtrTy, Int8PtrTy, MethodListPtrTy,
4561 MethodListPtrTy, ProtocolListPtrTy,
4562 IntTy, PropertyListPtrTy, NULL);
4564 // Global metadata structures
4566 // struct _objc_symtab {
4567 // long sel_ref_cnt;
4569 // short cls_def_cnt;
4570 // short cat_def_cnt;
4571 // char *defs[cls_def_cnt + cat_def_cnt];
4574 llvm::StructType::create("struct._objc_symtab",
4575 LongTy, SelectorPtrTy, ShortTy, ShortTy,
4576 llvm::ArrayType::get(Int8PtrTy, 0), NULL);
4577 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
4579 // struct _objc_module {
4581 // long size; // sizeof(struct _objc_module)
4583 // struct _objc_symtab* symtab;
4586 llvm::StructType::create("struct._objc_module",
4587 LongTy, LongTy, Int8PtrTy, SymtabPtrTy, NULL);
4590 // FIXME: This is the size of the setjmp buffer and should be target
4591 // specific. 18 is what's used on 32-bit X86.
4592 uint64_t SetJmpBufferSize = 18;
4595 llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4);
4598 llvm::StructType::create("struct._objc_exception_data",
4599 llvm::ArrayType::get(CGM.Int32Ty,SetJmpBufferSize),
4604 ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm)
4605 : ObjCCommonTypesHelper(cgm) {
4606 // struct _method_list_t {
4607 // uint32_t entsize; // sizeof(struct _objc_method)
4608 // uint32_t method_count;
4609 // struct _objc_method method_list[method_count];
4612 llvm::StructType::create("struct.__method_list_t", IntTy, IntTy,
4613 llvm::ArrayType::get(MethodTy, 0), NULL);
4614 // struct method_list_t *
4615 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy);
4617 // struct _protocol_t {
4619 // const char * const protocol_name;
4620 // const struct _protocol_list_t * protocol_list; // super protocols
4621 // const struct method_list_t * const instance_methods;
4622 // const struct method_list_t * const class_methods;
4623 // const struct method_list_t *optionalInstanceMethods;
4624 // const struct method_list_t *optionalClassMethods;
4625 // const struct _prop_list_t * properties;
4626 // const uint32_t size; // sizeof(struct _protocol_t)
4627 // const uint32_t flags; // = 0
4628 // const char ** extendedMethodTypes;
4631 // Holder for struct _protocol_list_t *
4632 ProtocolListnfABITy =
4633 llvm::StructType::create(VMContext, "struct._objc_protocol_list");
4636 llvm::StructType::create("struct._protocol_t", ObjectPtrTy, Int8PtrTy,
4637 llvm::PointerType::getUnqual(ProtocolListnfABITy),
4638 MethodListnfABIPtrTy, MethodListnfABIPtrTy,
4639 MethodListnfABIPtrTy, MethodListnfABIPtrTy,
4640 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy,
4643 // struct _protocol_t*
4644 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy);
4646 // struct _protocol_list_t {
4647 // long protocol_count; // Note, this is 32/64 bit
4648 // struct _protocol_t *[protocol_count];
4650 ProtocolListnfABITy->setBody(LongTy,
4651 llvm::ArrayType::get(ProtocolnfABIPtrTy, 0),
4654 // struct _objc_protocol_list*
4655 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy);
4658 // unsigned long int *offset; // pointer to ivar offset location
4661 // uint32_t alignment;
4665 llvm::StructType::create("struct._ivar_t",
4666 llvm::PointerType::getUnqual(LongTy),
4667 Int8PtrTy, Int8PtrTy, IntTy, IntTy, NULL);
4669 // struct _ivar_list_t {
4670 // uint32 entsize; // sizeof(struct _ivar_t)
4672 // struct _iver_t list[count];
4675 llvm::StructType::create("struct._ivar_list_t", IntTy, IntTy,
4676 llvm::ArrayType::get(IvarnfABITy, 0), NULL);
4678 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy);
4680 // struct _class_ro_t {
4681 // uint32_t const flags;
4682 // uint32_t const instanceStart;
4683 // uint32_t const instanceSize;
4684 // uint32_t const reserved; // only when building for 64bit targets
4685 // const uint8_t * const ivarLayout;
4686 // const char *const name;
4687 // const struct _method_list_t * const baseMethods;
4688 // const struct _objc_protocol_list *const baseProtocols;
4689 // const struct _ivar_list_t *const ivars;
4690 // const uint8_t * const weakIvarLayout;
4691 // const struct _prop_list_t * const properties;
4694 // FIXME. Add 'reserved' field in 64bit abi mode!
4695 ClassRonfABITy = llvm::StructType::create("struct._class_ro_t",
4696 IntTy, IntTy, IntTy, Int8PtrTy,
4697 Int8PtrTy, MethodListnfABIPtrTy,
4698 ProtocolListnfABIPtrTy,
4700 Int8PtrTy, PropertyListPtrTy, NULL);
4702 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
4703 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
4704 ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false)
4707 // struct _class_t {
4708 // struct _class_t *isa;
4709 // struct _class_t * const superclass;
4712 // struct class_ro_t *ro;
4715 ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t");
4716 ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy),
4717 llvm::PointerType::getUnqual(ClassnfABITy),
4719 llvm::PointerType::getUnqual(ImpnfABITy),
4720 llvm::PointerType::getUnqual(ClassRonfABITy),
4723 // LLVM for struct _class_t *
4724 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy);
4726 // struct _category_t {
4727 // const char * const name;
4728 // struct _class_t *const cls;
4729 // const struct _method_list_t * const instance_methods;
4730 // const struct _method_list_t * const class_methods;
4731 // const struct _protocol_list_t * const protocols;
4732 // const struct _prop_list_t * const properties;
4734 CategorynfABITy = llvm::StructType::create("struct._category_t",
4735 Int8PtrTy, ClassnfABIPtrTy,
4736 MethodListnfABIPtrTy,
4737 MethodListnfABIPtrTy,
4738 ProtocolListnfABIPtrTy,
4742 // New types for nonfragile abi messaging.
4743 CodeGen::CodeGenTypes &Types = CGM.getTypes();
4744 ASTContext &Ctx = CGM.getContext();
4746 // MessageRefTy - LLVM for:
4747 // struct _message_ref_t {
4752 // First the clang type for struct _message_ref_t
4753 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
4754 Ctx.getTranslationUnitDecl(),
4755 SourceLocation(), SourceLocation(),
4756 &Ctx.Idents.get("_message_ref_t"));
4757 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
4758 Ctx.VoidPtrTy, 0, 0, false, false));
4759 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
4760 Ctx.getObjCSelType(), 0, 0, false, false));
4761 RD->completeDefinition();
4763 MessageRefCTy = Ctx.getTagDeclType(RD);
4764 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
4765 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
4767 // MessageRefPtrTy - LLVM for struct _message_ref_t*
4768 MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy);
4770 // SuperMessageRefTy - LLVM for:
4771 // struct _super_message_ref_t {
4772 // SUPER_IMP messenger;
4776 llvm::StructType::create("struct._super_message_ref_t",
4777 ImpnfABITy, SelectorPtrTy, NULL);
4779 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
4780 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);
4783 // struct objc_typeinfo {
4784 // const void** vtable; // objc_ehtype_vtable + 2
4785 // const char* name; // c++ typeinfo string
4789 llvm::StructType::create("struct._objc_typeinfo",
4790 llvm::PointerType::getUnqual(Int8PtrTy),
4791 Int8PtrTy, ClassnfABIPtrTy, NULL);
4792 EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy);
4795 llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
4796 FinishNonFragileABIModule();
4801 void CGObjCNonFragileABIMac::
4802 AddModuleClassList(ArrayRef<llvm::GlobalValue*> Container,
4803 const char *SymbolName,
4804 const char *SectionName) {
4805 unsigned NumClasses = Container.size();
4810 SmallVector<llvm::Constant*, 8> Symbols(NumClasses);
4811 for (unsigned i=0; i<NumClasses; i++)
4812 Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i],
4813 ObjCTypes.Int8PtrTy);
4814 llvm::Constant *Init =
4815 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
4819 llvm::GlobalVariable *GV =
4820 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
4821 llvm::GlobalValue::InternalLinkage,
4824 GV->setAlignment(CGM.getTargetData().getABITypeAlignment(Init->getType()));
4825 GV->setSection(SectionName);
4826 CGM.AddUsedGlobal(GV);
4829 void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
4830 // nonfragile abi has no module definition.
4832 // Build list of all implemented class addresses in array
4833 // L_OBJC_LABEL_CLASS_$.
4834 AddModuleClassList(DefinedClasses,
4835 "\01L_OBJC_LABEL_CLASS_$",
4836 "__DATA, __objc_classlist, regular, no_dead_strip");
4838 for (unsigned i = 0, e = DefinedClasses.size(); i < e; i++) {
4839 llvm::GlobalValue *IMPLGV = DefinedClasses[i];
4840 if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage)
4842 IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage);
4845 for (unsigned i = 0, e = DefinedMetaClasses.size(); i < e; i++) {
4846 llvm::GlobalValue *IMPLGV = DefinedMetaClasses[i];
4847 if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage)
4849 IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage);
4852 AddModuleClassList(DefinedNonLazyClasses,
4853 "\01L_OBJC_LABEL_NONLAZY_CLASS_$",
4854 "__DATA, __objc_nlclslist, regular, no_dead_strip");
4856 // Build list of all implemented category addresses in array
4857 // L_OBJC_LABEL_CATEGORY_$.
4858 AddModuleClassList(DefinedCategories,
4859 "\01L_OBJC_LABEL_CATEGORY_$",
4860 "__DATA, __objc_catlist, regular, no_dead_strip");
4861 AddModuleClassList(DefinedNonLazyCategories,
4862 "\01L_OBJC_LABEL_NONLAZY_CATEGORY_$",
4863 "__DATA, __objc_nlcatlist, regular, no_dead_strip");
4868 /// isVTableDispatchedSelector - Returns true if SEL is not in the list of
4869 /// VTableDispatchMethods; false otherwise. What this means is that
4870 /// except for the 19 selectors in the list, we generate 32bit-style
4871 /// message dispatch call for all the rest.
4872 bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
4873 // At various points we've experimented with using vtable-based
4874 // dispatch for all methods.
4875 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
4876 case CodeGenOptions::Legacy:
4878 case CodeGenOptions::NonLegacy:
4880 case CodeGenOptions::Mixed:
4884 // If so, see whether this selector is in the white-list of things which must
4885 // use the new dispatch convention. We lazily build a dense set for this.
4886 if (VTableDispatchMethods.empty()) {
4887 VTableDispatchMethods.insert(GetNullarySelector("alloc"));
4888 VTableDispatchMethods.insert(GetNullarySelector("class"));
4889 VTableDispatchMethods.insert(GetNullarySelector("self"));
4890 VTableDispatchMethods.insert(GetNullarySelector("isFlipped"));
4891 VTableDispatchMethods.insert(GetNullarySelector("length"));
4892 VTableDispatchMethods.insert(GetNullarySelector("count"));
4894 // These are vtable-based if GC is disabled.
4895 // Optimistically use vtable dispatch for hybrid compiles.
4896 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
4897 VTableDispatchMethods.insert(GetNullarySelector("retain"));
4898 VTableDispatchMethods.insert(GetNullarySelector("release"));
4899 VTableDispatchMethods.insert(GetNullarySelector("autorelease"));
4902 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone"));
4903 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass"));
4904 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector"));
4905 VTableDispatchMethods.insert(GetUnarySelector("objectForKey"));
4906 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex"));
4907 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString"));
4908 VTableDispatchMethods.insert(GetUnarySelector("isEqual"));
4910 // These are vtable-based if GC is enabled.
4911 // Optimistically use vtable dispatch for hybrid compiles.
4912 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
4913 VTableDispatchMethods.insert(GetNullarySelector("hash"));
4914 VTableDispatchMethods.insert(GetUnarySelector("addObject"));
4916 // "countByEnumeratingWithState:objects:count"
4917 IdentifierInfo *KeyIdents[] = {
4918 &CGM.getContext().Idents.get("countByEnumeratingWithState"),
4919 &CGM.getContext().Idents.get("objects"),
4920 &CGM.getContext().Idents.get("count")
4922 VTableDispatchMethods.insert(
4923 CGM.getContext().Selectors.getSelector(3, KeyIdents));
4927 return VTableDispatchMethods.count(Sel);
4931 enum MetaDataDlags {
4935 OBJC2_CLS_HIDDEN = 0x10,
4936 CLS_EXCEPTION = 0x20,
4938 /// (Obsolete) ARC-specific: this class has a .release_ivars method
4939 CLS_HAS_IVAR_RELEASER = 0x40,
4940 /// class was compiled with -fobjc-arr
4941 CLS_COMPILED_BY_ARC = 0x80 // (1<<7)
4943 /// BuildClassRoTInitializer - generate meta-data for:
4944 /// struct _class_ro_t {
4945 /// uint32_t const flags;
4946 /// uint32_t const instanceStart;
4947 /// uint32_t const instanceSize;
4948 /// uint32_t const reserved; // only when building for 64bit targets
4949 /// const uint8_t * const ivarLayout;
4950 /// const char *const name;
4951 /// const struct _method_list_t * const baseMethods;
4952 /// const struct _protocol_list_t *const baseProtocols;
4953 /// const struct _ivar_list_t *const ivars;
4954 /// const uint8_t * const weakIvarLayout;
4955 /// const struct _prop_list_t * const properties;
4958 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
4960 unsigned InstanceStart,
4961 unsigned InstanceSize,
4962 const ObjCImplementationDecl *ID) {
4963 std::string ClassName = ID->getNameAsString();
4964 llvm::Constant *Values[10]; // 11 for 64bit targets!
4966 if (CGM.getLangOpts().ObjCAutoRefCount)
4967 flags |= CLS_COMPILED_BY_ARC;
4969 Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags);
4970 Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart);
4971 Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize);
4972 // FIXME. For 64bit targets add 0 here.
4973 Values[ 3] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes)
4974 : BuildIvarLayout(ID, true);
4975 Values[ 4] = GetClassName(ID->getIdentifier());
4976 // const struct _method_list_t * const baseMethods;
4977 std::vector<llvm::Constant*> Methods;
4978 std::string MethodListName("\01l_OBJC_$_");
4979 if (flags & CLS_META) {
4980 MethodListName += "CLASS_METHODS_" + ID->getNameAsString();
4981 for (ObjCImplementationDecl::classmeth_iterator
4982 i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
4983 // Class methods should always be defined.
4984 Methods.push_back(GetMethodConstant(*i));
4987 MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString();
4988 for (ObjCImplementationDecl::instmeth_iterator
4989 i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
4990 // Instance methods should always be defined.
4991 Methods.push_back(GetMethodConstant(*i));
4993 for (ObjCImplementationDecl::propimpl_iterator
4994 i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
4995 ObjCPropertyImplDecl *PID = *i;
4997 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
4998 ObjCPropertyDecl *PD = PID->getPropertyDecl();
5000 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
5001 if (llvm::Constant *C = GetMethodConstant(MD))
5002 Methods.push_back(C);
5003 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
5004 if (llvm::Constant *C = GetMethodConstant(MD))
5005 Methods.push_back(C);
5009 Values[ 5] = EmitMethodList(MethodListName,
5010 "__DATA, __objc_const", Methods);
5012 const ObjCInterfaceDecl *OID = ID->getClassInterface();
5013 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");
5014 Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_"
5016 OID->all_referenced_protocol_begin(),
5017 OID->all_referenced_protocol_end());
5019 if (flags & CLS_META)
5020 Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
5022 Values[ 7] = EmitIvarList(ID);
5023 Values[ 8] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes)
5024 : BuildIvarLayout(ID, false);
5025 if (flags & CLS_META)
5026 Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
5028 Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
5029 ID, ID->getClassInterface(), ObjCTypes);
5030 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy,
5032 llvm::GlobalVariable *CLASS_RO_GV =
5033 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassRonfABITy, false,
5034 llvm::GlobalValue::InternalLinkage,
5036 (flags & CLS_META) ?
5037 std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName :
5038 std::string("\01l_OBJC_CLASS_RO_$_")+ClassName);
5039 CLASS_RO_GV->setAlignment(
5040 CGM.getTargetData().getABITypeAlignment(ObjCTypes.ClassRonfABITy));
5041 CLASS_RO_GV->setSection("__DATA, __objc_const");
5046 /// BuildClassMetaData - This routine defines that to-level meta-data
5047 /// for the given ClassName for:
5048 /// struct _class_t {
5049 /// struct _class_t *isa;
5050 /// struct _class_t * const superclass;
5053 /// struct class_ro_t *ro;
5056 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData(
5057 std::string &ClassName,
5058 llvm::Constant *IsAGV,
5059 llvm::Constant *SuperClassGV,
5060 llvm::Constant *ClassRoGV,
5061 bool HiddenVisibility) {
5062 llvm::Constant *Values[] = {
5065 ObjCEmptyCacheVar, // &ObjCEmptyCacheVar
5066 ObjCEmptyVtableVar, // &ObjCEmptyVtableVar
5067 ClassRoGV // &CLASS_RO_GV
5070 Values[1] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy);
5071 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy,
5073 llvm::GlobalVariable *GV = GetClassGlobal(ClassName);
5074 GV->setInitializer(Init);
5075 GV->setSection("__DATA, __objc_data");
5077 CGM.getTargetData().getABITypeAlignment(ObjCTypes.ClassnfABITy));
5078 if (HiddenVisibility)
5079 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5084 CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
5085 return OD->getClassMethod(GetNullarySelector("load")) != 0;
5088 void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
5089 uint32_t &InstanceStart,
5090 uint32_t &InstanceSize) {
5091 const ASTRecordLayout &RL =
5092 CGM.getContext().getASTObjCImplementationLayout(OID);
5094 // InstanceSize is really instance end.
5095 InstanceSize = RL.getDataSize().getQuantity();
5097 // If there are no fields, the start is the same as the end.
5098 if (!RL.getFieldCount())
5099 InstanceStart = InstanceSize;
5101 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
5104 void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
5105 std::string ClassName = ID->getNameAsString();
5106 if (!ObjCEmptyCacheVar) {
5107 ObjCEmptyCacheVar = new llvm::GlobalVariable(
5111 llvm::GlobalValue::ExternalLinkage,
5113 "_objc_empty_cache");
5115 ObjCEmptyVtableVar = new llvm::GlobalVariable(
5117 ObjCTypes.ImpnfABITy,
5119 llvm::GlobalValue::ExternalLinkage,
5121 "_objc_empty_vtable");
5123 assert(ID->getClassInterface() &&
5124 "CGObjCNonFragileABIMac::GenerateClass - class is 0");
5125 // FIXME: Is this correct (that meta class size is never computed)?
5126 uint32_t InstanceStart =
5127 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassnfABITy);
5128 uint32_t InstanceSize = InstanceStart;
5129 uint32_t flags = CLS_META;
5130 std::string ObjCMetaClassName(getMetaclassSymbolPrefix());
5131 std::string ObjCClassName(getClassSymbolPrefix());
5133 llvm::GlobalVariable *SuperClassGV, *IsAGV;
5135 bool classIsHidden =
5136 ID->getClassInterface()->getVisibility() == HiddenVisibility;
5138 flags |= OBJC2_CLS_HIDDEN;
5139 if (ID->hasCXXStructors())
5140 flags |= eClassFlags_ABI2_HasCXXStructors;
5141 if (!ID->getClassInterface()->getSuperClass()) {
5144 SuperClassGV = GetClassGlobal(ObjCClassName + ClassName);
5145 IsAGV = GetClassGlobal(ObjCMetaClassName + ClassName);
5147 // Has a root. Current class is not a root.
5148 const ObjCInterfaceDecl *Root = ID->getClassInterface();
5149 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
5151 IsAGV = GetClassGlobal(ObjCMetaClassName + Root->getNameAsString());
5152 if (Root->isWeakImported())
5153 IsAGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
5154 // work on super class metadata symbol.
5155 std::string SuperClassName =
5157 ID->getClassInterface()->getSuperClass()->getNameAsString();
5158 SuperClassGV = GetClassGlobal(SuperClassName);
5159 if (ID->getClassInterface()->getSuperClass()->isWeakImported())
5160 SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
5162 llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags,
5165 std::string TClassName = ObjCMetaClassName + ClassName;
5166 llvm::GlobalVariable *MetaTClass =
5167 BuildClassMetaData(TClassName, IsAGV, SuperClassGV, CLASS_RO_GV,
5169 DefinedMetaClasses.push_back(MetaTClass);
5171 // Metadata for the class
5174 flags |= OBJC2_CLS_HIDDEN;
5175 if (ID->hasCXXStructors())
5176 flags |= eClassFlags_ABI2_HasCXXStructors;
5178 if (hasObjCExceptionAttribute(CGM.getContext(), ID->getClassInterface()))
5179 flags |= CLS_EXCEPTION;
5181 if (!ID->getClassInterface()->getSuperClass()) {
5185 // Has a root. Current class is not a root.
5186 std::string RootClassName =
5187 ID->getClassInterface()->getSuperClass()->getNameAsString();
5188 SuperClassGV = GetClassGlobal(ObjCClassName + RootClassName);
5189 if (ID->getClassInterface()->getSuperClass()->isWeakImported())
5190 SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
5192 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
5193 CLASS_RO_GV = BuildClassRoTInitializer(flags,
5198 TClassName = ObjCClassName + ClassName;
5199 llvm::GlobalVariable *ClassMD =
5200 BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV,
5202 DefinedClasses.push_back(ClassMD);
5204 // Determine if this class is also "non-lazy".
5205 if (ImplementationIsNonLazy(ID))
5206 DefinedNonLazyClasses.push_back(ClassMD);
5208 // Force the definition of the EHType if necessary.
5209 if (flags & CLS_EXCEPTION)
5210 GetInterfaceEHType(ID->getClassInterface(), true);
5211 // Make sure method definition entries are all clear for next implementation.
5212 MethodDefinitions.clear();
5215 /// GenerateProtocolRef - This routine is called to generate code for
5216 /// a protocol reference expression; as in:
5218 /// @protocol(Proto1);
5220 /// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1
5221 /// which will hold address of the protocol meta-data.
5223 llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CGBuilderTy &Builder,
5224 const ObjCProtocolDecl *PD) {
5226 // This routine is called for @protocol only. So, we must build definition
5227 // of protocol's meta-data (not a reference to it!)
5229 llvm::Constant *Init =
5230 llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD),
5231 ObjCTypes.getExternalProtocolPtrTy());
5233 std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_");
5234 ProtocolName += PD->getName();
5236 llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
5238 return Builder.CreateLoad(PTGV);
5239 PTGV = new llvm::GlobalVariable(
5241 Init->getType(), false,
5242 llvm::GlobalValue::WeakAnyLinkage,
5245 PTGV->setSection("__DATA, __objc_protorefs, coalesced, no_dead_strip");
5246 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5247 CGM.AddUsedGlobal(PTGV);
5248 return Builder.CreateLoad(PTGV);
5251 /// GenerateCategory - Build metadata for a category implementation.
5252 /// struct _category_t {
5253 /// const char * const name;
5254 /// struct _class_t *const cls;
5255 /// const struct _method_list_t * const instance_methods;
5256 /// const struct _method_list_t * const class_methods;
5257 /// const struct _protocol_list_t * const protocols;
5258 /// const struct _prop_list_t * const properties;
5261 void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
5262 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
5263 const char *Prefix = "\01l_OBJC_$_CATEGORY_";
5264 std::string ExtCatName(Prefix + Interface->getNameAsString()+
5265 "_$_" + OCD->getNameAsString());
5266 std::string ExtClassName(getClassSymbolPrefix() +
5267 Interface->getNameAsString());
5269 llvm::Constant *Values[6];
5270 Values[0] = GetClassName(OCD->getIdentifier());
5271 // meta-class entry symbol
5272 llvm::GlobalVariable *ClassGV = GetClassGlobal(ExtClassName);
5273 if (Interface->isWeakImported())
5274 ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
5276 Values[1] = ClassGV;
5277 std::vector<llvm::Constant*> Methods;
5278 std::string MethodListName(Prefix);
5279 MethodListName += "INSTANCE_METHODS_" + Interface->getNameAsString() +
5280 "_$_" + OCD->getNameAsString();
5282 for (ObjCCategoryImplDecl::instmeth_iterator
5283 i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
5284 // Instance methods should always be defined.
5285 Methods.push_back(GetMethodConstant(*i));
5288 Values[2] = EmitMethodList(MethodListName,
5289 "__DATA, __objc_const",
5292 MethodListName = Prefix;
5293 MethodListName += "CLASS_METHODS_" + Interface->getNameAsString() + "_$_" +
5294 OCD->getNameAsString();
5296 for (ObjCCategoryImplDecl::classmeth_iterator
5297 i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
5298 // Class methods should always be defined.
5299 Methods.push_back(GetMethodConstant(*i));
5302 Values[3] = EmitMethodList(MethodListName,
5303 "__DATA, __objc_const",
5305 const ObjCCategoryDecl *Category =
5306 Interface->FindCategoryDeclaration(OCD->getIdentifier());
5308 SmallString<256> ExtName;
5309 llvm::raw_svector_ostream(ExtName) << Interface->getName() << "_$_"
5311 Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_"
5312 + Interface->getName() + "_$_"
5313 + Category->getName(),
5314 Category->protocol_begin(),
5315 Category->protocol_end());
5316 Values[5] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
5317 OCD, Category, ObjCTypes);
5319 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
5320 Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
5323 llvm::Constant *Init =
5324 llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy,
5326 llvm::GlobalVariable *GCATV
5327 = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CategorynfABITy,
5329 llvm::GlobalValue::InternalLinkage,
5332 GCATV->setAlignment(
5333 CGM.getTargetData().getABITypeAlignment(ObjCTypes.CategorynfABITy));
5334 GCATV->setSection("__DATA, __objc_const");
5335 CGM.AddUsedGlobal(GCATV);
5336 DefinedCategories.push_back(GCATV);
5338 // Determine if this category is also "non-lazy".
5339 if (ImplementationIsNonLazy(OCD))
5340 DefinedNonLazyCategories.push_back(GCATV);
5341 // method definition entries must be clear for next implementation.
5342 MethodDefinitions.clear();
5345 /// GetMethodConstant - Return a struct objc_method constant for the
5346 /// given method if it has been defined. The result is null if the
5347 /// method has not been defined. The return value has type MethodPtrTy.
5348 llvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant(
5349 const ObjCMethodDecl *MD) {
5350 llvm::Function *Fn = GetMethodDefinition(MD);
5354 llvm::Constant *Method[] = {
5355 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
5356 ObjCTypes.SelectorPtrTy),
5357 GetMethodVarType(MD),
5358 llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy)
5360 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
5363 /// EmitMethodList - Build meta-data for method declarations
5364 /// struct _method_list_t {
5365 /// uint32_t entsize; // sizeof(struct _objc_method)
5366 /// uint32_t method_count;
5367 /// struct _objc_method method_list[method_count];
5371 CGObjCNonFragileABIMac::EmitMethodList(Twine Name,
5372 const char *Section,
5373 ArrayRef<llvm::Constant*> Methods) {
5374 // Return null for empty list.
5375 if (Methods.empty())
5376 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
5378 llvm::Constant *Values[3];
5379 // sizeof(struct _objc_method)
5380 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.MethodTy);
5381 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
5383 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
5384 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
5386 Values[2] = llvm::ConstantArray::get(AT, Methods);
5387 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
5389 llvm::GlobalVariable *GV =
5390 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5391 llvm::GlobalValue::InternalLinkage, Init, Name);
5392 GV->setAlignment(CGM.getTargetData().getABITypeAlignment(Init->getType()));
5393 GV->setSection(Section);
5394 CGM.AddUsedGlobal(GV);
5395 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy);
5398 /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
5400 llvm::GlobalVariable *
5401 CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
5402 const ObjCIvarDecl *Ivar) {
5403 const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
5404 std::string Name = "OBJC_IVAR_$_" + Container->getNameAsString() +
5405 '.' + Ivar->getNameAsString();
5406 llvm::GlobalVariable *IvarOffsetGV =
5407 CGM.getModule().getGlobalVariable(Name);
5410 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.LongTy,
5412 llvm::GlobalValue::ExternalLinkage,
5415 return IvarOffsetGV;
5419 CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
5420 const ObjCIvarDecl *Ivar,
5421 unsigned long int Offset) {
5422 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
5423 IvarOffsetGV->setInitializer(llvm::ConstantInt::get(ObjCTypes.LongTy,
5425 IvarOffsetGV->setAlignment(
5426 CGM.getTargetData().getABITypeAlignment(ObjCTypes.LongTy));
5428 // FIXME: This matches gcc, but shouldn't the visibility be set on the use as
5429 // well (i.e., in ObjCIvarOffsetVariable).
5430 if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
5431 Ivar->getAccessControl() == ObjCIvarDecl::Package ||
5432 ID->getVisibility() == HiddenVisibility)
5433 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5435 IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
5436 IvarOffsetGV->setSection("__DATA, __objc_ivar");
5437 return IvarOffsetGV;
5440 /// EmitIvarList - Emit the ivar list for the given
5441 /// implementation. The return value has type
5442 /// IvarListnfABIPtrTy.
5443 /// struct _ivar_t {
5444 /// unsigned long int *offset; // pointer to ivar offset location
5447 /// uint32_t alignment;
5450 /// struct _ivar_list_t {
5451 /// uint32 entsize; // sizeof(struct _ivar_t)
5453 /// struct _iver_t list[count];
5457 llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
5458 const ObjCImplementationDecl *ID) {
5460 std::vector<llvm::Constant*> Ivars;
5462 const ObjCInterfaceDecl *OID = ID->getClassInterface();
5463 assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface");
5465 // FIXME. Consolidate this with similar code in GenerateClass.
5467 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
5468 IVD; IVD = IVD->getNextIvar()) {
5469 // Ignore unnamed bit-fields.
5470 if (!IVD->getDeclName())
5472 llvm::Constant *Ivar[5];
5473 Ivar[0] = EmitIvarOffsetVar(ID->getClassInterface(), IVD,
5474 ComputeIvarBaseOffset(CGM, ID, IVD));
5475 Ivar[1] = GetMethodVarName(IVD->getIdentifier());
5476 Ivar[2] = GetMethodVarType(IVD);
5477 llvm::Type *FieldTy =
5478 CGM.getTypes().ConvertTypeForMem(IVD->getType());
5479 unsigned Size = CGM.getTargetData().getTypeAllocSize(FieldTy);
5480 unsigned Align = CGM.getContext().getPreferredTypeAlign(
5481 IVD->getType().getTypePtr()) >> 3;
5482 Align = llvm::Log2_32(Align);
5483 Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align);
5484 // NOTE. Size of a bitfield does not match gcc's, because of the
5485 // way bitfields are treated special in each. But I am told that
5486 // 'size' for bitfield ivars is ignored by the runtime so it does
5487 // not matter. If it matters, there is enough info to get the
5489 Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
5490 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar));
5492 // Return null for empty list.
5494 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
5496 llvm::Constant *Values[3];
5497 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.IvarnfABITy);
5498 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
5499 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
5500 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy,
5502 Values[2] = llvm::ConstantArray::get(AT, Ivars);
5503 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
5504 const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_";
5505 llvm::GlobalVariable *GV =
5506 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5507 llvm::GlobalValue::InternalLinkage,
5509 Prefix + OID->getName());
5511 CGM.getTargetData().getABITypeAlignment(Init->getType()));
5512 GV->setSection("__DATA, __objc_const");
5514 CGM.AddUsedGlobal(GV);
5515 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
5518 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
5519 const ObjCProtocolDecl *PD) {
5520 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
5523 // We use the initializer as a marker of whether this is a forward
5524 // reference or not. At module finalization we add the empty
5525 // contents for protocols which were referenced but never defined.
5527 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, false,
5528 llvm::GlobalValue::ExternalLinkage,
5530 "\01l_OBJC_PROTOCOL_$_" + PD->getName());
5531 Entry->setSection("__DATA,__datacoal_nt,coalesced");
5537 /// GetOrEmitProtocol - Generate the protocol meta-data:
5539 /// struct _protocol_t {
5541 /// const char * const protocol_name;
5542 /// const struct _protocol_list_t * protocol_list; // super protocols
5543 /// const struct method_list_t * const instance_methods;
5544 /// const struct method_list_t * const class_methods;
5545 /// const struct method_list_t *optionalInstanceMethods;
5546 /// const struct method_list_t *optionalClassMethods;
5547 /// const struct _prop_list_t * properties;
5548 /// const uint32_t size; // sizeof(struct _protocol_t)
5549 /// const uint32_t flags; // = 0
5550 /// const char ** extendedMethodTypes;
5555 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
5556 const ObjCProtocolDecl *PD) {
5557 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
5559 // Early exit if a defining object has already been generated.
5560 if (Entry && Entry->hasInitializer())
5563 // Use the protocol definition, if there is one.
5564 if (const ObjCProtocolDecl *Def = PD->getDefinition())
5567 // Construct method lists.
5568 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
5569 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
5570 std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt;
5571 for (ObjCProtocolDecl::instmeth_iterator
5572 i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
5573 ObjCMethodDecl *MD = *i;
5574 llvm::Constant *C = GetMethodDescriptionConstant(MD);
5576 return GetOrEmitProtocolRef(PD);
5578 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
5579 OptInstanceMethods.push_back(C);
5580 OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
5582 InstanceMethods.push_back(C);
5583 MethodTypesExt.push_back(GetMethodVarType(MD, true));
5587 for (ObjCProtocolDecl::classmeth_iterator
5588 i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
5589 ObjCMethodDecl *MD = *i;
5590 llvm::Constant *C = GetMethodDescriptionConstant(MD);
5592 return GetOrEmitProtocolRef(PD);
5594 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
5595 OptClassMethods.push_back(C);
5596 OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
5598 ClassMethods.push_back(C);
5599 MethodTypesExt.push_back(GetMethodVarType(MD, true));
5603 MethodTypesExt.insert(MethodTypesExt.end(),
5604 OptMethodTypesExt.begin(), OptMethodTypesExt.end());
5606 llvm::Constant *Values[11];
5608 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy);
5609 Values[1] = GetClassName(PD->getIdentifier());
5610 Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getName(),
5611 PD->protocol_begin(),
5612 PD->protocol_end());
5614 Values[3] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_"
5616 "__DATA, __objc_const",
5618 Values[4] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_"
5620 "__DATA, __objc_const",
5622 Values[5] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_"
5624 "__DATA, __objc_const",
5625 OptInstanceMethods);
5626 Values[6] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_"
5628 "__DATA, __objc_const",
5630 Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getName(),
5633 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
5634 Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
5635 Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy);
5636 Values[10] = EmitProtocolMethodTypes("\01l_OBJC_$_PROTOCOL_METHOD_TYPES_"
5638 MethodTypesExt, ObjCTypes);
5639 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy,
5643 // Already created, fix the linkage and update the initializer.
5644 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
5645 Entry->setInitializer(Init);
5648 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
5649 false, llvm::GlobalValue::WeakAnyLinkage, Init,
5650 "\01l_OBJC_PROTOCOL_$_" + PD->getName());
5651 Entry->setAlignment(
5652 CGM.getTargetData().getABITypeAlignment(ObjCTypes.ProtocolnfABITy));
5653 Entry->setSection("__DATA,__datacoal_nt,coalesced");
5655 Protocols[PD->getIdentifier()] = Entry;
5657 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
5658 CGM.AddUsedGlobal(Entry);
5660 // Use this protocol meta-data to build protocol list table in section
5661 // __DATA, __objc_protolist
5662 llvm::GlobalVariable *PTGV =
5663 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy,
5664 false, llvm::GlobalValue::WeakAnyLinkage, Entry,
5665 "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getName());
5667 CGM.getTargetData().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
5668 PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip");
5669 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5670 CGM.AddUsedGlobal(PTGV);
5674 /// EmitProtocolList - Generate protocol list meta-data:
5676 /// struct _protocol_list_t {
5677 /// long protocol_count; // Note, this is 32/64 bit
5678 /// struct _protocol_t[protocol_count];
5683 CGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
5684 ObjCProtocolDecl::protocol_iterator begin,
5685 ObjCProtocolDecl::protocol_iterator end) {
5686 llvm::SmallVector<llvm::Constant*, 16> ProtocolRefs;
5688 // Just return null for empty protocol lists
5690 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
5692 // FIXME: We shouldn't need to do this lookup here, should we?
5693 SmallString<256> TmpName;
5694 Name.toVector(TmpName);
5695 llvm::GlobalVariable *GV =
5696 CGM.getModule().getGlobalVariable(TmpName.str(), true);
5698 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
5700 for (; begin != end; ++begin)
5701 ProtocolRefs.push_back(GetProtocolRef(*begin)); // Implemented???
5703 // This list is null terminated.
5704 ProtocolRefs.push_back(llvm::Constant::getNullValue(
5705 ObjCTypes.ProtocolnfABIPtrTy));
5707 llvm::Constant *Values[2];
5709 llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
5711 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolnfABIPtrTy,
5712 ProtocolRefs.size()),
5715 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
5716 GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5717 llvm::GlobalValue::InternalLinkage,
5719 GV->setSection("__DATA, __objc_const");
5721 CGM.getTargetData().getABITypeAlignment(Init->getType()));
5722 CGM.AddUsedGlobal(GV);
5723 return llvm::ConstantExpr::getBitCast(GV,
5724 ObjCTypes.ProtocolListnfABIPtrTy);
5727 /// GetMethodDescriptionConstant - This routine build following meta-data:
5728 /// struct _objc_method {
5730 /// char *method_type;
5735 CGObjCNonFragileABIMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
5736 llvm::Constant *Desc[3];
5738 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
5739 ObjCTypes.SelectorPtrTy);
5740 Desc[1] = GetMethodVarType(MD);
5744 // Protocol methods have no implementation. So, this entry is always NULL.
5745 Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
5746 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc);
5749 /// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference.
5750 /// This code gen. amounts to generating code for:
5752 /// (type *)((char *)base + _OBJC_IVAR_$_.ivar;
5755 LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
5756 CodeGen::CodeGenFunction &CGF,
5758 llvm::Value *BaseValue,
5759 const ObjCIvarDecl *Ivar,
5760 unsigned CVRQualifiers) {
5761 ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCObjectType>()->getInterface();
5762 llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
5763 if (llvm::LoadInst *LI = dyn_cast<llvm::LoadInst>(Offset))
5764 LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
5765 llvm::MDNode::get(VMContext,
5766 ArrayRef<llvm::Value*>()));
5767 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
5771 llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(
5772 CodeGen::CodeGenFunction &CGF,
5773 const ObjCInterfaceDecl *Interface,
5774 const ObjCIvarDecl *Ivar) {
5775 return CGF.Builder.CreateLoad(ObjCIvarOffsetVariable(Interface, Ivar),"ivar");
5778 static void appendSelectorForMessageRefTable(std::string &buffer,
5779 Selector selector) {
5780 if (selector.isUnarySelector()) {
5781 buffer += selector.getNameForSlot(0);
5785 for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) {
5786 buffer += selector.getNameForSlot(i);
5791 /// Emit a "v-table" message send. We emit a weak hidden-visibility
5792 /// struct, initially containing the selector pointer and a pointer to
5793 /// a "fixup" variant of the appropriate objc_msgSend. To call, we
5794 /// load and call the function pointer, passing the address of the
5795 /// struct as the second parameter. The runtime determines whether
5796 /// the selector is currently emitted using vtable dispatch; if so, it
5797 /// substitutes a stub function which simply tail-calls through the
5798 /// appropriate vtable slot, and if not, it substitues a stub function
5799 /// which tail-calls objc_msgSend. Both stubs adjust the selector
5800 /// argument to correctly point to the selector.
5802 CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF,
5803 ReturnValueSlot returnSlot,
5804 QualType resultType,
5809 const CallArgList &formalArgs,
5810 const ObjCMethodDecl *method) {
5811 // Compute the actual arguments.
5814 // First argument: the receiver / super-call structure.
5816 arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy);
5817 args.add(RValue::get(arg0), arg0Type);
5819 // Second argument: a pointer to the message ref structure. Leave
5820 // the actual argument value blank for now.
5821 args.add(RValue::get(0), ObjCTypes.MessageRefCPtrTy);
5823 args.insert(args.end(), formalArgs.begin(), formalArgs.end());
5825 MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
5827 NullReturnState nullReturn;
5829 // Find the function to call and the mangled name for the message
5830 // ref structure. Using a different mangled name wouldn't actually
5831 // be a problem; it would just be a waste.
5833 // The runtime currently never uses vtable dispatch for anything
5834 // except normal, non-super message-sends.
5835 // FIXME: don't use this for that.
5836 llvm::Constant *fn = 0;
5837 std::string messageRefName("\01l_");
5838 if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) {
5840 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
5841 messageRefName += "objc_msgSendSuper2_stret_fixup";
5843 nullReturn.init(CGF, arg0);
5844 fn = ObjCTypes.getMessageSendStretFixupFn();
5845 messageRefName += "objc_msgSend_stret_fixup";
5847 } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) {
5848 fn = ObjCTypes.getMessageSendFpretFixupFn();
5849 messageRefName += "objc_msgSend_fpret_fixup";
5852 fn = ObjCTypes.getMessageSendSuper2FixupFn();
5853 messageRefName += "objc_msgSendSuper2_fixup";
5855 fn = ObjCTypes.getMessageSendFixupFn();
5856 messageRefName += "objc_msgSend_fixup";
5859 assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend");
5860 messageRefName += '_';
5862 // Append the selector name, except use underscores anywhere we
5863 // would have used colons.
5864 appendSelectorForMessageRefTable(messageRefName, selector);
5866 llvm::GlobalVariable *messageRef
5867 = CGM.getModule().getGlobalVariable(messageRefName);
5869 // Build the message ref structure.
5870 llvm::Constant *values[] = { fn, GetMethodVarName(selector) };
5871 llvm::Constant *init = llvm::ConstantStruct::getAnon(values);
5872 messageRef = new llvm::GlobalVariable(CGM.getModule(),
5875 llvm::GlobalValue::WeakAnyLinkage,
5878 messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
5879 messageRef->setAlignment(16);
5880 messageRef->setSection("__DATA, __objc_msgrefs, coalesced");
5883 bool requiresnullCheck = false;
5884 if (CGM.getLangOpts().ObjCAutoRefCount && method)
5885 for (ObjCMethodDecl::param_const_iterator i = method->param_begin(),
5886 e = method->param_end(); i != e; ++i) {
5887 const ParmVarDecl *ParamDecl = (*i);
5888 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
5889 if (!nullReturn.NullBB)
5890 nullReturn.init(CGF, arg0);
5891 requiresnullCheck = true;
5897 CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy);
5899 // Update the message ref argument.
5900 args[1].RV = RValue::get(mref);
5902 // Load the function to call from the message ref table.
5903 llvm::Value *callee = CGF.Builder.CreateStructGEP(mref, 0);
5904 callee = CGF.Builder.CreateLoad(callee, "msgSend_fn");
5906 callee = CGF.Builder.CreateBitCast(callee, MSI.MessengerType);
5908 RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args);
5909 return nullReturn.complete(CGF, result, resultType, formalArgs,
5910 requiresnullCheck ? method : 0);
5913 /// Generate code for a message send expression in the nonfragile abi.
5915 CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
5916 ReturnValueSlot Return,
5917 QualType ResultType,
5919 llvm::Value *Receiver,
5920 const CallArgList &CallArgs,
5921 const ObjCInterfaceDecl *Class,
5922 const ObjCMethodDecl *Method) {
5923 return isVTableDispatchedSelector(Sel)
5924 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
5925 Receiver, CGF.getContext().getObjCIdType(),
5926 false, CallArgs, Method)
5927 : EmitMessageSend(CGF, Return, ResultType,
5928 EmitSelector(CGF.Builder, Sel),
5929 Receiver, CGF.getContext().getObjCIdType(),
5930 false, CallArgs, Method, ObjCTypes);
5933 llvm::GlobalVariable *
5934 CGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name) {
5935 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
5938 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABITy,
5939 false, llvm::GlobalValue::ExternalLinkage,
5946 llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CGBuilderTy &Builder,
5947 IdentifierInfo *II) {
5948 llvm::GlobalVariable *&Entry = ClassReferences[II];
5951 std::string ClassName(getClassSymbolPrefix() + II->getName().str());
5952 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
5954 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
5955 false, llvm::GlobalValue::InternalLinkage,
5957 "\01L_OBJC_CLASSLIST_REFERENCES_$_");
5958 Entry->setAlignment(
5959 CGM.getTargetData().getABITypeAlignment(
5960 ObjCTypes.ClassnfABIPtrTy));
5961 Entry->setSection("__DATA, __objc_classrefs, regular, no_dead_strip");
5962 CGM.AddUsedGlobal(Entry);
5965 return Builder.CreateLoad(Entry);
5968 llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CGBuilderTy &Builder,
5969 const ObjCInterfaceDecl *ID) {
5970 return EmitClassRefFromId(Builder, ID->getIdentifier());
5973 llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
5974 CGBuilderTy &Builder) {
5975 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
5976 return EmitClassRefFromId(Builder, II);
5980 CGObjCNonFragileABIMac::EmitSuperClassRef(CGBuilderTy &Builder,
5981 const ObjCInterfaceDecl *ID) {
5982 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
5985 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
5986 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
5988 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
5989 false, llvm::GlobalValue::InternalLinkage,
5991 "\01L_OBJC_CLASSLIST_SUP_REFS_$_");
5992 Entry->setAlignment(
5993 CGM.getTargetData().getABITypeAlignment(
5994 ObjCTypes.ClassnfABIPtrTy));
5995 Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
5996 CGM.AddUsedGlobal(Entry);
5999 return Builder.CreateLoad(Entry);
6002 /// EmitMetaClassRef - Return a Value * of the address of _class_t
6005 llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CGBuilderTy &Builder,
6006 const ObjCInterfaceDecl *ID) {
6007 llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];
6009 return Builder.CreateLoad(Entry);
6011 std::string MetaClassName(getMetaclassSymbolPrefix() + ID->getNameAsString());
6012 llvm::GlobalVariable *MetaClassGV = GetClassGlobal(MetaClassName);
6014 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, false,
6015 llvm::GlobalValue::InternalLinkage,
6017 "\01L_OBJC_CLASSLIST_SUP_REFS_$_");
6018 Entry->setAlignment(
6019 CGM.getTargetData().getABITypeAlignment(
6020 ObjCTypes.ClassnfABIPtrTy));
6022 Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
6023 CGM.AddUsedGlobal(Entry);
6025 return Builder.CreateLoad(Entry);
6028 /// GetClass - Return a reference to the class for the given interface
6030 llvm::Value *CGObjCNonFragileABIMac::GetClass(CGBuilderTy &Builder,
6031 const ObjCInterfaceDecl *ID) {
6032 if (ID->isWeakImported()) {
6033 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
6034 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
6035 ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
6038 return EmitClassRef(Builder, ID);
6041 /// Generates a message send where the super is the receiver. This is
6042 /// a message send to self with special delivery semantics indicating
6043 /// which class's method should be called.
6045 CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
6046 ReturnValueSlot Return,
6047 QualType ResultType,
6049 const ObjCInterfaceDecl *Class,
6050 bool isCategoryImpl,
6051 llvm::Value *Receiver,
6052 bool IsClassMessage,
6053 const CodeGen::CallArgList &CallArgs,
6054 const ObjCMethodDecl *Method) {
6056 // Create and init a super structure; this is a (receiver, class)
6057 // pair we will pass to objc_msgSendSuper.
6058 llvm::Value *ObjCSuper =
6059 CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super");
6061 llvm::Value *ReceiverAsObject =
6062 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
6063 CGF.Builder.CreateStore(ReceiverAsObject,
6064 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
6066 // If this is a class message the metaclass is passed as the target.
6067 llvm::Value *Target;
6068 if (IsClassMessage) {
6069 if (isCategoryImpl) {
6070 // Message sent to "super' in a class method defined in
6071 // a category implementation.
6072 Target = EmitClassRef(CGF.Builder, Class);
6073 Target = CGF.Builder.CreateStructGEP(Target, 0);
6074 Target = CGF.Builder.CreateLoad(Target);
6076 Target = EmitMetaClassRef(CGF.Builder, Class);
6078 Target = EmitSuperClassRef(CGF.Builder, Class);
6080 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
6082 llvm::Type *ClassTy =
6083 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
6084 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
6085 CGF.Builder.CreateStore(Target,
6086 CGF.Builder.CreateStructGEP(ObjCSuper, 1));
6088 return (isVTableDispatchedSelector(Sel))
6089 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
6090 ObjCSuper, ObjCTypes.SuperPtrCTy,
6091 true, CallArgs, Method)
6092 : EmitMessageSend(CGF, Return, ResultType,
6093 EmitSelector(CGF.Builder, Sel),
6094 ObjCSuper, ObjCTypes.SuperPtrCTy,
6095 true, CallArgs, Method, ObjCTypes);
6098 llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CGBuilderTy &Builder,
6099 Selector Sel, bool lval) {
6100 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
6103 llvm::Constant *Casted =
6104 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
6105 ObjCTypes.SelectorPtrTy);
6107 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.SelectorPtrTy, false,
6108 llvm::GlobalValue::InternalLinkage,
6109 Casted, "\01L_OBJC_SELECTOR_REFERENCES_");
6110 Entry->setSection("__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
6111 CGM.AddUsedGlobal(Entry);
6116 llvm::LoadInst* LI = Builder.CreateLoad(Entry);
6118 LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
6119 llvm::MDNode::get(VMContext,
6120 ArrayRef<llvm::Value*>()));
6123 /// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
6124 /// objc_assign_ivar (id src, id *dst, ptrdiff_t)
6126 void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
6129 llvm::Value *ivarOffset) {
6130 llvm::Type * SrcTy = src->getType();
6131 if (!isa<llvm::PointerType>(SrcTy)) {
6132 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
6133 assert(Size <= 8 && "does not support size > 8");
6134 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6135 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
6136 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6138 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6139 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
6140 CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(),
6141 src, dst, ivarOffset);
6145 /// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
6146 /// objc_assign_strongCast (id src, id *dst)
6148 void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
6149 CodeGen::CodeGenFunction &CGF,
6150 llvm::Value *src, llvm::Value *dst) {
6151 llvm::Type * SrcTy = src->getType();
6152 if (!isa<llvm::PointerType>(SrcTy)) {
6153 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
6154 assert(Size <= 8 && "does not support size > 8");
6155 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6156 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
6157 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6159 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6160 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
6161 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(),
6162 src, dst, "weakassign");
6166 void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
6167 CodeGen::CodeGenFunction &CGF,
6168 llvm::Value *DestPtr,
6169 llvm::Value *SrcPtr,
6170 llvm::Value *Size) {
6171 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
6172 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
6173 CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(),
6174 DestPtr, SrcPtr, Size);
6178 /// EmitObjCWeakRead - Code gen for loading value of a __weak
6179 /// object: objc_read_weak (id *src)
6181 llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
6182 CodeGen::CodeGenFunction &CGF,
6183 llvm::Value *AddrWeakObj) {
6184 llvm::Type* DestTy =
6185 cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
6186 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
6187 llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(),
6188 AddrWeakObj, "weakread");
6189 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
6193 /// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
6194 /// objc_assign_weak (id src, id *dst)
6196 void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
6197 llvm::Value *src, llvm::Value *dst) {
6198 llvm::Type * SrcTy = src->getType();
6199 if (!isa<llvm::PointerType>(SrcTy)) {
6200 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
6201 assert(Size <= 8 && "does not support size > 8");
6202 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6203 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
6204 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6206 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6207 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
6208 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(),
6209 src, dst, "weakassign");
6213 /// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
6214 /// objc_assign_global (id src, id *dst)
6216 void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
6217 llvm::Value *src, llvm::Value *dst,
6219 llvm::Type * SrcTy = src->getType();
6220 if (!isa<llvm::PointerType>(SrcTy)) {
6221 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
6222 assert(Size <= 8 && "does not support size > 8");
6223 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6224 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
6225 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6227 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6228 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
6230 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(),
6231 src, dst, "globalassign");
6233 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(),
6234 src, dst, "threadlocalassign");
6239 CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
6240 const ObjCAtSynchronizedStmt &S) {
6241 EmitAtSynchronizedStmt(CGF, S,
6242 cast<llvm::Function>(ObjCTypes.getSyncEnterFn()),
6243 cast<llvm::Function>(ObjCTypes.getSyncExitFn()));
6247 CGObjCNonFragileABIMac::GetEHType(QualType T) {
6248 // There's a particular fixed type info for 'id'.
6249 if (T->isObjCIdType() ||
6250 T->isObjCQualifiedIdType()) {
6251 llvm::Constant *IDEHType =
6252 CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id");
6255 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy,
6257 llvm::GlobalValue::ExternalLinkage,
6258 0, "OBJC_EHTYPE_id");
6262 // All other types should be Objective-C interface pointer types.
6263 const ObjCObjectPointerType *PT =
6264 T->getAs<ObjCObjectPointerType>();
6265 assert(PT && "Invalid @catch type.");
6266 const ObjCInterfaceType *IT = PT->getInterfaceType();
6267 assert(IT && "Invalid @catch type.");
6268 return GetInterfaceEHType(IT->getDecl(), false);
6271 void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
6272 const ObjCAtTryStmt &S) {
6273 EmitTryCatchStmt(CGF, S,
6274 cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()),
6275 cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()),
6276 cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn()));
6279 /// EmitThrowStmt - Generate code for a throw statement.
6280 void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
6281 const ObjCAtThrowStmt &S) {
6282 if (const Expr *ThrowExpr = S.getThrowExpr()) {
6283 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
6284 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
6285 CGF.EmitCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception)
6286 .setDoesNotReturn();
6288 CGF.EmitCallOrInvoke(ObjCTypes.getExceptionRethrowFn())
6289 .setDoesNotReturn();
6292 CGF.Builder.CreateUnreachable();
6293 CGF.Builder.ClearInsertionPoint();
6297 CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
6298 bool ForDefinition) {
6299 llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
6301 // If we don't need a definition, return the entry if found or check
6302 // if we use an external reference.
6303 if (!ForDefinition) {
6307 // If this type (or a super class) has the __objc_exception__
6308 // attribute, emit an external reference.
6309 if (hasObjCExceptionAttribute(CGM.getContext(), ID))
6311 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
6312 llvm::GlobalValue::ExternalLinkage,
6315 ID->getIdentifier()->getName()));
6318 // Otherwise we need to either make a new entry or fill in the
6320 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition");
6321 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
6322 std::string VTableName = "objc_ehtype_vtable";
6323 llvm::GlobalVariable *VTableGV =
6324 CGM.getModule().getGlobalVariable(VTableName);
6326 VTableGV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy,
6328 llvm::GlobalValue::ExternalLinkage,
6331 llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2);
6333 llvm::Constant *Values[] = {
6334 llvm::ConstantExpr::getGetElementPtr(VTableGV, VTableIdx),
6335 GetClassName(ID->getIdentifier()),
6336 GetClassGlobal(ClassName)
6338 llvm::Constant *Init =
6339 llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values);
6342 Entry->setInitializer(Init);
6344 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
6345 llvm::GlobalValue::WeakAnyLinkage,
6348 ID->getIdentifier()->getName()));
6351 if (CGM.getLangOpts().getVisibilityMode() == HiddenVisibility)
6352 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
6353 Entry->setAlignment(CGM.getTargetData().getABITypeAlignment(
6354 ObjCTypes.EHTypeTy));
6356 if (ForDefinition) {
6357 Entry->setSection("__DATA,__objc_const");
6358 Entry->setLinkage(llvm::GlobalValue::ExternalLinkage);
6360 Entry->setSection("__DATA,__datacoal_nt,coalesced");
6368 CodeGen::CGObjCRuntime *
6369 CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
6370 if (CGM.getLangOpts().ObjCNonFragileABI)
6371 return new CGObjCNonFragileABIMac(CGM);
6372 return new CGObjCMac(CGM);