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/DataLayout.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::Attributes::get(CGM.getLLVMContext(),
70 llvm::Attributes::NonLazyBind));
73 /// void objc_msgSend_stret (id, SEL, ...)
75 /// The messenger used when the return value is an aggregate returned
76 /// by indirect reference in the first argument, and therefore the
77 /// self and selector parameters are shifted over by one.
78 llvm::Constant *getMessageSendStretFn() const {
79 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
80 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,
82 "objc_msgSend_stret");
86 /// [double | long double] objc_msgSend_fpret(id self, SEL op, ...)
88 /// The messenger used when the return value is returned on the x87
89 /// floating-point stack; without a special entrypoint, the nil case
90 /// would be unbalanced.
91 llvm::Constant *getMessageSendFpretFn() const {
92 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
93 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.DoubleTy,
95 "objc_msgSend_fpret");
99 /// _Complex long double objc_msgSend_fp2ret(id self, SEL op, ...)
101 /// The messenger used when the return value is returned in two values on the
102 /// x87 floating point stack; without a special entrypoint, the nil case
103 /// would be unbalanced. Only used on 64-bit X86.
104 llvm::Constant *getMessageSendFp2retFn() const {
105 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
106 llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(VMContext);
107 llvm::Type *resultType =
108 llvm::StructType::get(longDoubleType, longDoubleType, NULL);
110 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(resultType,
112 "objc_msgSend_fp2ret");
115 /// id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
117 /// The messenger used for super calls, which have different dispatch
118 /// semantics. The class passed is the superclass of the current
120 llvm::Constant *getMessageSendSuperFn() const {
121 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
122 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
124 "objc_msgSendSuper");
127 /// id objc_msgSendSuper2(struct objc_super *super, SEL op, ...)
129 /// A slightly different messenger used for super calls. The class
130 /// passed is the current class.
131 llvm::Constant *getMessageSendSuperFn2() const {
132 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
133 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
135 "objc_msgSendSuper2");
138 /// void objc_msgSendSuper_stret(void *stretAddr, struct objc_super *super,
141 /// The messenger used for super calls which return an aggregate indirectly.
142 llvm::Constant *getMessageSendSuperStretFn() const {
143 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
144 return CGM.CreateRuntimeFunction(
145 llvm::FunctionType::get(CGM.VoidTy, params, true),
146 "objc_msgSendSuper_stret");
149 /// void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super,
152 /// objc_msgSendSuper_stret with the super2 semantics.
153 llvm::Constant *getMessageSendSuperStretFn2() const {
154 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
155 return CGM.CreateRuntimeFunction(
156 llvm::FunctionType::get(CGM.VoidTy, params, true),
157 "objc_msgSendSuper2_stret");
160 llvm::Constant *getMessageSendSuperFpretFn() const {
161 // There is no objc_msgSendSuper_fpret? How can that work?
162 return getMessageSendSuperFn();
165 llvm::Constant *getMessageSendSuperFpretFn2() const {
166 // There is no objc_msgSendSuper_fpret? How can that work?
167 return getMessageSendSuperFn2();
171 CodeGen::CodeGenModule &CGM;
174 llvm::Type *ShortTy, *IntTy, *LongTy, *LongLongTy;
175 llvm::Type *Int8PtrTy, *Int8PtrPtrTy;
177 /// ObjectPtrTy - LLVM type for object handles (typeof(id))
178 llvm::Type *ObjectPtrTy;
180 /// PtrObjectPtrTy - LLVM type for id *
181 llvm::Type *PtrObjectPtrTy;
183 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
184 llvm::Type *SelectorPtrTy;
187 /// ProtocolPtrTy - LLVM type for external protocol handles
188 /// (typeof(Protocol))
189 llvm::Type *ExternalProtocolPtrTy;
192 llvm::Type *getExternalProtocolPtrTy() {
193 if (!ExternalProtocolPtrTy) {
194 // FIXME: It would be nice to unify this with the opaque type, so that the
195 // IR comes out a bit cleaner.
196 CodeGen::CodeGenTypes &Types = CGM.getTypes();
197 ASTContext &Ctx = CGM.getContext();
198 llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
199 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
202 return ExternalProtocolPtrTy;
205 // SuperCTy - clang type for struct objc_super.
207 // SuperPtrCTy - clang type for struct objc_super *.
208 QualType SuperPtrCTy;
210 /// SuperTy - LLVM type for struct objc_super.
211 llvm::StructType *SuperTy;
212 /// SuperPtrTy - LLVM type for struct objc_super *.
213 llvm::Type *SuperPtrTy;
215 /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
216 /// in GCC parlance).
217 llvm::StructType *PropertyTy;
219 /// PropertyListTy - LLVM type for struct objc_property_list
220 /// (_prop_list_t in GCC parlance).
221 llvm::StructType *PropertyListTy;
222 /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
223 llvm::Type *PropertyListPtrTy;
225 // MethodTy - LLVM type for struct objc_method.
226 llvm::StructType *MethodTy;
228 /// CacheTy - LLVM type for struct objc_cache.
230 /// CachePtrTy - LLVM type for struct objc_cache *.
231 llvm::Type *CachePtrTy;
233 llvm::Constant *getGetPropertyFn() {
234 CodeGen::CodeGenTypes &Types = CGM.getTypes();
235 ASTContext &Ctx = CGM.getContext();
236 // id objc_getProperty (id, SEL, ptrdiff_t, bool)
237 SmallVector<CanQualType,4> Params;
238 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
239 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
240 Params.push_back(IdType);
241 Params.push_back(SelType);
242 Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
243 Params.push_back(Ctx.BoolTy);
244 llvm::FunctionType *FTy =
245 Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(IdType, Params,
246 FunctionType::ExtInfo(),
248 return CGM.CreateRuntimeFunction(FTy, "objc_getProperty");
251 llvm::Constant *getSetPropertyFn() {
252 CodeGen::CodeGenTypes &Types = CGM.getTypes();
253 ASTContext &Ctx = CGM.getContext();
254 // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool)
255 SmallVector<CanQualType,6> Params;
256 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
257 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
258 Params.push_back(IdType);
259 Params.push_back(SelType);
260 Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
261 Params.push_back(IdType);
262 Params.push_back(Ctx.BoolTy);
263 Params.push_back(Ctx.BoolTy);
264 llvm::FunctionType *FTy =
265 Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
266 FunctionType::ExtInfo(),
268 return CGM.CreateRuntimeFunction(FTy, "objc_setProperty");
271 llvm::Constant *getOptimizedSetPropertyFn(bool atomic, bool copy) {
272 CodeGen::CodeGenTypes &Types = CGM.getTypes();
273 ASTContext &Ctx = CGM.getContext();
274 // void objc_setProperty_atomic(id self, SEL _cmd,
275 // id newValue, ptrdiff_t offset);
276 // void objc_setProperty_nonatomic(id self, SEL _cmd,
277 // id newValue, ptrdiff_t offset);
278 // void objc_setProperty_atomic_copy(id self, SEL _cmd,
279 // id newValue, ptrdiff_t offset);
280 // void objc_setProperty_nonatomic_copy(id self, SEL _cmd,
281 // id newValue, ptrdiff_t offset);
283 SmallVector<CanQualType,4> Params;
284 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
285 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
286 Params.push_back(IdType);
287 Params.push_back(SelType);
288 Params.push_back(IdType);
289 Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
290 llvm::FunctionType *FTy =
291 Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
292 FunctionType::ExtInfo(),
296 name = "objc_setProperty_atomic_copy";
297 else if (atomic && !copy)
298 name = "objc_setProperty_atomic";
299 else if (!atomic && copy)
300 name = "objc_setProperty_nonatomic_copy";
302 name = "objc_setProperty_nonatomic";
304 return CGM.CreateRuntimeFunction(FTy, name);
307 llvm::Constant *getCopyStructFn() {
308 CodeGen::CodeGenTypes &Types = CGM.getTypes();
309 ASTContext &Ctx = CGM.getContext();
310 // void objc_copyStruct (void *, const void *, size_t, bool, bool)
311 SmallVector<CanQualType,5> Params;
312 Params.push_back(Ctx.VoidPtrTy);
313 Params.push_back(Ctx.VoidPtrTy);
314 Params.push_back(Ctx.LongTy);
315 Params.push_back(Ctx.BoolTy);
316 Params.push_back(Ctx.BoolTy);
317 llvm::FunctionType *FTy =
318 Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
319 FunctionType::ExtInfo(),
321 return CGM.CreateRuntimeFunction(FTy, "objc_copyStruct");
324 /// This routine declares and returns address of:
325 /// void objc_copyCppObjectAtomic(
326 /// void *dest, const void *src,
327 /// void (*copyHelper) (void *dest, const void *source));
328 llvm::Constant *getCppAtomicObjectFunction() {
329 CodeGen::CodeGenTypes &Types = CGM.getTypes();
330 ASTContext &Ctx = CGM.getContext();
331 /// void objc_copyCppObjectAtomic(void *dest, const void *src, void *helper);
332 SmallVector<CanQualType,3> Params;
333 Params.push_back(Ctx.VoidPtrTy);
334 Params.push_back(Ctx.VoidPtrTy);
335 Params.push_back(Ctx.VoidPtrTy);
336 llvm::FunctionType *FTy =
337 Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
338 FunctionType::ExtInfo(),
340 return CGM.CreateRuntimeFunction(FTy, "objc_copyCppObjectAtomic");
343 llvm::Constant *getEnumerationMutationFn() {
344 CodeGen::CodeGenTypes &Types = CGM.getTypes();
345 ASTContext &Ctx = CGM.getContext();
346 // void objc_enumerationMutation (id)
347 SmallVector<CanQualType,1> Params;
348 Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType()));
349 llvm::FunctionType *FTy =
350 Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
351 FunctionType::ExtInfo(),
353 return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
356 /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function.
357 llvm::Constant *getGcReadWeakFn() {
358 // id objc_read_weak (id *)
359 llvm::Type *args[] = { ObjectPtrTy->getPointerTo() };
360 llvm::FunctionType *FTy =
361 llvm::FunctionType::get(ObjectPtrTy, args, false);
362 return CGM.CreateRuntimeFunction(FTy, "objc_read_weak");
365 /// GcAssignWeakFn -- LLVM objc_assign_weak function.
366 llvm::Constant *getGcAssignWeakFn() {
367 // id objc_assign_weak (id, id *)
368 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
369 llvm::FunctionType *FTy =
370 llvm::FunctionType::get(ObjectPtrTy, args, false);
371 return CGM.CreateRuntimeFunction(FTy, "objc_assign_weak");
374 /// GcAssignGlobalFn -- LLVM objc_assign_global function.
375 llvm::Constant *getGcAssignGlobalFn() {
376 // id objc_assign_global(id, id *)
377 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
378 llvm::FunctionType *FTy =
379 llvm::FunctionType::get(ObjectPtrTy, args, false);
380 return CGM.CreateRuntimeFunction(FTy, "objc_assign_global");
383 /// GcAssignThreadLocalFn -- LLVM objc_assign_threadlocal function.
384 llvm::Constant *getGcAssignThreadLocalFn() {
385 // id objc_assign_threadlocal(id src, id * dest)
386 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
387 llvm::FunctionType *FTy =
388 llvm::FunctionType::get(ObjectPtrTy, args, false);
389 return CGM.CreateRuntimeFunction(FTy, "objc_assign_threadlocal");
392 /// GcAssignIvarFn -- LLVM objc_assign_ivar function.
393 llvm::Constant *getGcAssignIvarFn() {
394 // id objc_assign_ivar(id, id *, ptrdiff_t)
395 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo(),
397 llvm::FunctionType *FTy =
398 llvm::FunctionType::get(ObjectPtrTy, args, false);
399 return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar");
402 /// GcMemmoveCollectableFn -- LLVM objc_memmove_collectable function.
403 llvm::Constant *GcMemmoveCollectableFn() {
404 // void *objc_memmove_collectable(void *dst, const void *src, size_t size)
405 llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy };
406 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args, false);
407 return CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable");
410 /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function.
411 llvm::Constant *getGcAssignStrongCastFn() {
412 // id objc_assign_strongCast(id, id *)
413 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
414 llvm::FunctionType *FTy =
415 llvm::FunctionType::get(ObjectPtrTy, args, false);
416 return CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast");
419 /// ExceptionThrowFn - LLVM objc_exception_throw function.
420 llvm::Constant *getExceptionThrowFn() {
421 // void objc_exception_throw(id)
422 llvm::Type *args[] = { ObjectPtrTy };
423 llvm::FunctionType *FTy =
424 llvm::FunctionType::get(CGM.VoidTy, args, false);
425 return CGM.CreateRuntimeFunction(FTy, "objc_exception_throw");
428 /// ExceptionRethrowFn - LLVM objc_exception_rethrow function.
429 llvm::Constant *getExceptionRethrowFn() {
430 // void objc_exception_rethrow(void)
431 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, false);
432 return CGM.CreateRuntimeFunction(FTy, "objc_exception_rethrow");
435 /// SyncEnterFn - LLVM object_sync_enter function.
436 llvm::Constant *getSyncEnterFn() {
437 // int objc_sync_enter (id)
438 llvm::Type *args[] = { ObjectPtrTy };
439 llvm::FunctionType *FTy =
440 llvm::FunctionType::get(CGM.IntTy, args, false);
441 return CGM.CreateRuntimeFunction(FTy, "objc_sync_enter");
444 /// SyncExitFn - LLVM object_sync_exit function.
445 llvm::Constant *getSyncExitFn() {
446 // int objc_sync_exit (id)
447 llvm::Type *args[] = { ObjectPtrTy };
448 llvm::FunctionType *FTy =
449 llvm::FunctionType::get(CGM.IntTy, args, false);
450 return CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
453 llvm::Constant *getSendFn(bool IsSuper) const {
454 return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
457 llvm::Constant *getSendFn2(bool IsSuper) const {
458 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
461 llvm::Constant *getSendStretFn(bool IsSuper) const {
462 return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
465 llvm::Constant *getSendStretFn2(bool IsSuper) const {
466 return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
469 llvm::Constant *getSendFpretFn(bool IsSuper) const {
470 return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
473 llvm::Constant *getSendFpretFn2(bool IsSuper) const {
474 return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
477 llvm::Constant *getSendFp2retFn(bool IsSuper) const {
478 return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn();
481 llvm::Constant *getSendFp2RetFn2(bool IsSuper) const {
482 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn();
485 ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm);
486 ~ObjCCommonTypesHelper(){}
489 /// ObjCTypesHelper - Helper class that encapsulates lazy
490 /// construction of varies types used during ObjC generation.
491 class ObjCTypesHelper : public ObjCCommonTypesHelper {
493 /// SymtabTy - LLVM type for struct objc_symtab.
494 llvm::StructType *SymtabTy;
495 /// SymtabPtrTy - LLVM type for struct objc_symtab *.
496 llvm::Type *SymtabPtrTy;
497 /// ModuleTy - LLVM type for struct objc_module.
498 llvm::StructType *ModuleTy;
500 /// ProtocolTy - LLVM type for struct objc_protocol.
501 llvm::StructType *ProtocolTy;
502 /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
503 llvm::Type *ProtocolPtrTy;
504 /// ProtocolExtensionTy - LLVM type for struct
505 /// objc_protocol_extension.
506 llvm::StructType *ProtocolExtensionTy;
507 /// ProtocolExtensionTy - LLVM type for struct
508 /// objc_protocol_extension *.
509 llvm::Type *ProtocolExtensionPtrTy;
510 /// MethodDescriptionTy - LLVM type for struct
511 /// objc_method_description.
512 llvm::StructType *MethodDescriptionTy;
513 /// MethodDescriptionListTy - LLVM type for struct
514 /// objc_method_description_list.
515 llvm::StructType *MethodDescriptionListTy;
516 /// MethodDescriptionListPtrTy - LLVM type for struct
517 /// objc_method_description_list *.
518 llvm::Type *MethodDescriptionListPtrTy;
519 /// ProtocolListTy - LLVM type for struct objc_property_list.
520 llvm::StructType *ProtocolListTy;
521 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
522 llvm::Type *ProtocolListPtrTy;
523 /// CategoryTy - LLVM type for struct objc_category.
524 llvm::StructType *CategoryTy;
525 /// ClassTy - LLVM type for struct objc_class.
526 llvm::StructType *ClassTy;
527 /// ClassPtrTy - LLVM type for struct objc_class *.
528 llvm::Type *ClassPtrTy;
529 /// ClassExtensionTy - LLVM type for struct objc_class_ext.
530 llvm::StructType *ClassExtensionTy;
531 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
532 llvm::Type *ClassExtensionPtrTy;
533 // IvarTy - LLVM type for struct objc_ivar.
534 llvm::StructType *IvarTy;
535 /// IvarListTy - LLVM type for struct objc_ivar_list.
536 llvm::Type *IvarListTy;
537 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
538 llvm::Type *IvarListPtrTy;
539 /// MethodListTy - LLVM type for struct objc_method_list.
540 llvm::Type *MethodListTy;
541 /// MethodListPtrTy - LLVM type for struct objc_method_list *.
542 llvm::Type *MethodListPtrTy;
544 /// ExceptionDataTy - LLVM type for struct _objc_exception_data.
545 llvm::Type *ExceptionDataTy;
547 /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.
548 llvm::Constant *getExceptionTryEnterFn() {
549 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
550 return CGM.CreateRuntimeFunction(
551 llvm::FunctionType::get(CGM.VoidTy, params, false),
552 "objc_exception_try_enter");
555 /// ExceptionTryExitFn - LLVM objc_exception_try_exit function.
556 llvm::Constant *getExceptionTryExitFn() {
557 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
558 return CGM.CreateRuntimeFunction(
559 llvm::FunctionType::get(CGM.VoidTy, params, false),
560 "objc_exception_try_exit");
563 /// ExceptionExtractFn - LLVM objc_exception_extract function.
564 llvm::Constant *getExceptionExtractFn() {
565 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
566 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
568 "objc_exception_extract");
571 /// ExceptionMatchFn - LLVM objc_exception_match function.
572 llvm::Constant *getExceptionMatchFn() {
573 llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy };
574 return CGM.CreateRuntimeFunction(
575 llvm::FunctionType::get(CGM.Int32Ty, params, false),
576 "objc_exception_match");
580 /// SetJmpFn - LLVM _setjmp function.
581 llvm::Constant *getSetJmpFn() {
582 // This is specifically the prototype for x86.
583 llvm::Type *params[] = { CGM.Int32Ty->getPointerTo() };
584 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty,
587 llvm::Attributes::get(CGM.getLLVMContext(),
588 llvm::Attributes::NonLazyBind));
592 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
593 ~ObjCTypesHelper() {}
596 /// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's
598 class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {
601 // MethodListnfABITy - LLVM for struct _method_list_t
602 llvm::StructType *MethodListnfABITy;
604 // MethodListnfABIPtrTy - LLVM for struct _method_list_t*
605 llvm::Type *MethodListnfABIPtrTy;
607 // ProtocolnfABITy = LLVM for struct _protocol_t
608 llvm::StructType *ProtocolnfABITy;
610 // ProtocolnfABIPtrTy = LLVM for struct _protocol_t*
611 llvm::Type *ProtocolnfABIPtrTy;
613 // ProtocolListnfABITy - LLVM for struct _objc_protocol_list
614 llvm::StructType *ProtocolListnfABITy;
616 // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list*
617 llvm::Type *ProtocolListnfABIPtrTy;
619 // ClassnfABITy - LLVM for struct _class_t
620 llvm::StructType *ClassnfABITy;
622 // ClassnfABIPtrTy - LLVM for struct _class_t*
623 llvm::Type *ClassnfABIPtrTy;
625 // IvarnfABITy - LLVM for struct _ivar_t
626 llvm::StructType *IvarnfABITy;
628 // IvarListnfABITy - LLVM for struct _ivar_list_t
629 llvm::StructType *IvarListnfABITy;
631 // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t*
632 llvm::Type *IvarListnfABIPtrTy;
634 // ClassRonfABITy - LLVM for struct _class_ro_t
635 llvm::StructType *ClassRonfABITy;
637 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
638 llvm::Type *ImpnfABITy;
640 // CategorynfABITy - LLVM for struct _category_t
641 llvm::StructType *CategorynfABITy;
643 // New types for nonfragile abi messaging.
645 // MessageRefTy - LLVM for:
646 // struct _message_ref_t {
650 llvm::StructType *MessageRefTy;
651 // MessageRefCTy - clang type for struct _message_ref_t
652 QualType MessageRefCTy;
654 // MessageRefPtrTy - LLVM for struct _message_ref_t*
655 llvm::Type *MessageRefPtrTy;
656 // MessageRefCPtrTy - clang type for struct _message_ref_t*
657 QualType MessageRefCPtrTy;
659 // MessengerTy - Type of the messenger (shown as IMP above)
660 llvm::FunctionType *MessengerTy;
662 // SuperMessageRefTy - LLVM for:
663 // struct _super_message_ref_t {
664 // SUPER_IMP messenger;
667 llvm::StructType *SuperMessageRefTy;
669 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
670 llvm::Type *SuperMessageRefPtrTy;
672 llvm::Constant *getMessageSendFixupFn() {
673 // id objc_msgSend_fixup(id, struct message_ref_t*, ...)
674 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
675 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
677 "objc_msgSend_fixup");
680 llvm::Constant *getMessageSendFpretFixupFn() {
681 // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...)
682 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
683 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
685 "objc_msgSend_fpret_fixup");
688 llvm::Constant *getMessageSendStretFixupFn() {
689 // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...)
690 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
691 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
693 "objc_msgSend_stret_fixup");
696 llvm::Constant *getMessageSendSuper2FixupFn() {
697 // id objc_msgSendSuper2_fixup (struct objc_super *,
698 // struct _super_message_ref_t*, ...)
699 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
700 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
702 "objc_msgSendSuper2_fixup");
705 llvm::Constant *getMessageSendSuper2StretFixupFn() {
706 // id objc_msgSendSuper2_stret_fixup(struct objc_super *,
707 // struct _super_message_ref_t*, ...)
708 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
709 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
711 "objc_msgSendSuper2_stret_fixup");
714 llvm::Constant *getObjCEndCatchFn() {
715 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy, false),
720 llvm::Constant *getObjCBeginCatchFn() {
721 llvm::Type *params[] = { Int8PtrTy };
722 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy,
727 llvm::StructType *EHTypeTy;
728 llvm::Type *EHTypePtrTy;
730 ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
731 ~ObjCNonFragileABITypesHelper(){}
734 class CGObjCCommonMac : public CodeGen::CGObjCRuntime {
736 // FIXME - accessibility
739 unsigned ivar_bytepos;
741 GC_IVAR(unsigned bytepos = 0, unsigned size = 0)
742 : ivar_bytepos(bytepos), ivar_size(size) {}
744 // Allow sorting based on byte pos.
745 bool operator<(const GC_IVAR &b) const {
746 return ivar_bytepos < b.ivar_bytepos;
754 SKIP_SCAN(unsigned _skip = 0, unsigned _scan = 0)
755 : skip(_skip), scan(_scan) {}
758 /// opcode for captured block variables layout 'instructions'.
759 /// In the following descriptions, 'I' is the value of the immediate field.
760 /// (field following the opcode).
762 enum BLOCK_LAYOUT_OPCODE {
763 /// An operator which affects how the following layout should be
765 /// I == 0: Halt interpretation and treat everything else as
766 /// a non-pointer. Note that this instruction is equal
768 /// I != 0: Currently unused.
769 BLOCK_LAYOUT_OPERATOR = 0,
771 /// The next I+1 bytes do not contain a value of object pointer type.
772 /// Note that this can leave the stream unaligned, meaning that
773 /// subsequent word-size instructions do not begin at a multiple of
774 /// the pointer size.
775 BLOCK_LAYOUT_NON_OBJECT_BYTES = 1,
777 /// The next I+1 words do not contain a value of object pointer type.
778 /// This is simply an optimized version of BLOCK_LAYOUT_BYTES for
779 /// when the required skip quantity is a multiple of the pointer size.
780 BLOCK_LAYOUT_NON_OBJECT_WORDS = 2,
782 /// The next I+1 words are __strong pointers to Objective-C
783 /// objects or blocks.
784 BLOCK_LAYOUT_STRONG = 3,
786 /// The next I+1 words are pointers to __block variables.
787 BLOCK_LAYOUT_BYREF = 4,
789 /// The next I+1 words are __weak pointers to Objective-C
790 /// objects or blocks.
791 BLOCK_LAYOUT_WEAK = 5,
793 /// The next I+1 words are __unsafe_unretained pointers to
794 /// Objective-C objects or blocks.
795 BLOCK_LAYOUT_UNRETAINED = 6
797 /// The next I+1 words are block or object pointers with some
798 /// as-yet-unspecified ownership semantics. If we add more
799 /// flavors of ownership semantics, values will be taken from
802 /// This is included so that older tools can at least continue
803 /// processing the layout past such things.
804 //BLOCK_LAYOUT_OWNERSHIP_UNKNOWN = 7..10,
806 /// All other opcodes are reserved. Halt interpretation and
807 /// treat everything else as opaque.
812 enum BLOCK_LAYOUT_OPCODE opcode;
813 CharUnits block_var_bytepos;
814 CharUnits block_var_size;
815 RUN_SKIP(enum BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR,
816 CharUnits BytePos = CharUnits::Zero(),
817 CharUnits Size = CharUnits::Zero())
818 : opcode(Opcode), block_var_bytepos(BytePos), block_var_size(Size) {}
820 // Allow sorting based on byte pos.
821 bool operator<(const RUN_SKIP &b) const {
822 return block_var_bytepos < b.block_var_bytepos;
827 llvm::LLVMContext &VMContext;
828 // FIXME! May not be needing this after all.
831 // gc ivar layout bitmap calculation helper caches.
832 SmallVector<GC_IVAR, 16> SkipIvars;
833 SmallVector<GC_IVAR, 16> IvarsInfo;
835 // arc/mrr layout of captured block literal variables.
836 SmallVector<RUN_SKIP, 16> RunSkipBlockVars;
838 /// LazySymbols - Symbols to generate a lazy reference for. See
839 /// DefinedSymbols and FinishModule().
840 llvm::SetVector<IdentifierInfo*> LazySymbols;
842 /// DefinedSymbols - External symbols which are defined by this
843 /// module. The symbols in this list and LazySymbols are used to add
844 /// special linker symbols which ensure that Objective-C modules are
846 llvm::SetVector<IdentifierInfo*> DefinedSymbols;
848 /// ClassNames - uniqued class names.
849 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
851 /// MethodVarNames - uniqued method variable names.
852 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
854 /// DefinedCategoryNames - list of category names in form Class_Category.
855 llvm::SetVector<std::string> DefinedCategoryNames;
857 /// MethodVarTypes - uniqued method type signatures. We have to use
858 /// a StringMap here because have no other unique reference.
859 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
861 /// MethodDefinitions - map of methods which have been defined in
862 /// this translation unit.
863 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
865 /// PropertyNames - uniqued method variable names.
866 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
868 /// ClassReferences - uniqued class references.
869 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
871 /// SelectorReferences - uniqued selector references.
872 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
874 /// Protocols - Protocols for which an objc_protocol structure has
875 /// been emitted. Forward declarations are handled by creating an
876 /// empty structure whose initializer is filled in when/if defined.
877 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
879 /// DefinedProtocols - Protocols which have actually been
880 /// defined. We should not need this, see FIXME in GenerateProtocol.
881 llvm::DenseSet<IdentifierInfo*> DefinedProtocols;
883 /// DefinedClasses - List of defined classes.
884 llvm::SmallVector<llvm::GlobalValue*, 16> DefinedClasses;
886 /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
887 llvm::SmallVector<llvm::GlobalValue*, 16> DefinedNonLazyClasses;
889 /// DefinedCategories - List of defined categories.
890 llvm::SmallVector<llvm::GlobalValue*, 16> DefinedCategories;
892 /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
893 llvm::SmallVector<llvm::GlobalValue*, 16> DefinedNonLazyCategories;
895 /// GetNameForMethod - Return a name for the given method.
896 /// \param[out] NameOut - The return value.
897 void GetNameForMethod(const ObjCMethodDecl *OMD,
898 const ObjCContainerDecl *CD,
899 SmallVectorImpl<char> &NameOut);
901 /// GetMethodVarName - Return a unique constant for the given
902 /// selector's name. The return value has type char *.
903 llvm::Constant *GetMethodVarName(Selector Sel);
904 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
906 /// GetMethodVarType - Return a unique constant for the given
907 /// method's type encoding string. The return value has type char *.
909 // FIXME: This is a horrible name.
910 llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D,
911 bool Extended = false);
912 llvm::Constant *GetMethodVarType(const FieldDecl *D);
914 /// GetPropertyName - Return a unique constant for the given
915 /// name. The return value has type char *.
916 llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
918 // FIXME: This can be dropped once string functions are unified.
919 llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,
920 const Decl *Container);
922 /// GetClassName - Return a unique constant for the given selector's
923 /// name. The return value has type char *.
924 llvm::Constant *GetClassName(IdentifierInfo *Ident);
926 llvm::Function *GetMethodDefinition(const ObjCMethodDecl *MD);
928 /// BuildIvarLayout - Builds ivar layout bitmap for the class
929 /// implementation for the __strong or __weak case.
931 llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI,
932 bool ForStrongLayout);
934 llvm::Constant *BuildIvarLayoutBitmap(std::string &BitMap);
936 void BuildAggrIvarRecordLayout(const RecordType *RT,
937 unsigned int BytePos, bool ForStrongLayout,
939 void BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
940 const llvm::StructLayout *Layout,
941 const RecordDecl *RD,
942 ArrayRef<const FieldDecl*> RecFields,
943 unsigned int BytePos, bool ForStrongLayout,
946 Qualifiers::ObjCLifetime getBlockCaptureLifetime(QualType QT);
948 void UpdateRunSkipBlockVars(bool IsByref,
949 Qualifiers::ObjCLifetime LifeTime,
950 CharUnits FieldOffset,
951 CharUnits FieldSize);
953 void BuildRCBlockVarRecordLayout(const RecordType *RT,
954 CharUnits BytePos, bool &HasUnion);
956 void BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
957 const RecordDecl *RD,
958 ArrayRef<const FieldDecl*> RecFields,
959 CharUnits BytePos, bool &HasUnion);
961 uint64_t InlineLayoutInstruction(SmallVectorImpl<unsigned char> &Layout);
964 /// GetIvarLayoutName - Returns a unique constant for the given
965 /// ivar layout bitmap.
966 llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident,
967 const ObjCCommonTypesHelper &ObjCTypes);
969 /// EmitPropertyList - Emit the given property list. The return
970 /// value has type PropertyListPtrTy.
971 llvm::Constant *EmitPropertyList(Twine Name,
972 const Decl *Container,
973 const ObjCContainerDecl *OCD,
974 const ObjCCommonTypesHelper &ObjCTypes);
976 /// EmitProtocolMethodTypes - Generate the array of extended method type
977 /// strings. The return value has type Int8PtrPtrTy.
978 llvm::Constant *EmitProtocolMethodTypes(Twine Name,
979 ArrayRef<llvm::Constant*> MethodTypes,
980 const ObjCCommonTypesHelper &ObjCTypes);
982 /// PushProtocolProperties - Push protocol's property on the input stack.
983 void PushProtocolProperties(
984 llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet,
985 llvm::SmallVectorImpl<llvm::Constant*> &Properties,
986 const Decl *Container,
987 const ObjCProtocolDecl *PROTO,
988 const ObjCCommonTypesHelper &ObjCTypes);
990 /// GetProtocolRef - Return a reference to the internal protocol
991 /// description, creating an empty one if it has not been
992 /// defined. The return value has type ProtocolPtrTy.
993 llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD);
995 /// CreateMetadataVar - Create a global variable with internal
996 /// linkage for use by the Objective-C runtime.
998 /// This is a convenience wrapper which not only creates the
999 /// variable, but also sets the section and alignment and adds the
1000 /// global to the "llvm.used" list.
1002 /// \param Name - The variable name.
1003 /// \param Init - The variable initializer; this is also used to
1004 /// define the type of the variable.
1005 /// \param Section - The section the variable should go into, or 0.
1006 /// \param Align - The alignment for the variable, or 0.
1007 /// \param AddToUsed - Whether the variable should be added to
1009 llvm::GlobalVariable *CreateMetadataVar(Twine Name,
1010 llvm::Constant *Init,
1011 const char *Section,
1015 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
1016 ReturnValueSlot Return,
1017 QualType ResultType,
1022 const CallArgList &CallArgs,
1023 const ObjCMethodDecl *OMD,
1024 const ObjCCommonTypesHelper &ObjCTypes);
1026 /// EmitImageInfo - Emit the image info marker used to encode some module
1027 /// level information.
1028 void EmitImageInfo();
1031 CGObjCCommonMac(CodeGen::CodeGenModule &cgm) :
1032 CGObjCRuntime(cgm), VMContext(cgm.getLLVMContext()) { }
1034 virtual llvm::Constant *GenerateConstantString(const StringLiteral *SL);
1036 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
1037 const ObjCContainerDecl *CD=0);
1039 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
1041 /// GetOrEmitProtocol - Get the protocol object for the given
1042 /// declaration, emitting it if necessary. The return value has type
1044 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0;
1046 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1047 /// object for the given declaration, emitting it if needed. These
1048 /// forward references will be filled in with empty bodies if no
1049 /// definition is seen. The return value has type ProtocolPtrTy.
1050 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0;
1051 virtual llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
1052 const CGBlockInfo &blockInfo);
1053 virtual llvm::Constant *BuildRCBlockLayout(CodeGen::CodeGenModule &CGM,
1054 const CGBlockInfo &blockInfo);
1058 class CGObjCMac : public CGObjCCommonMac {
1060 ObjCTypesHelper ObjCTypes;
1062 /// EmitModuleInfo - Another marker encoding module level
1064 void EmitModuleInfo();
1066 /// EmitModuleSymols - Emit module symbols, the list of defined
1067 /// classes and categories. The result has type SymtabPtrTy.
1068 llvm::Constant *EmitModuleSymbols();
1070 /// FinishModule - Write out global data structures at the end of
1071 /// processing a translation unit.
1072 void FinishModule();
1074 /// EmitClassExtension - Generate the class extension structure used
1075 /// to store the weak ivar layout and properties. The return value
1076 /// has type ClassExtensionPtrTy.
1077 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
1079 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1080 /// for the given class.
1081 llvm::Value *EmitClassRef(CGBuilderTy &Builder,
1082 const ObjCInterfaceDecl *ID);
1084 llvm::Value *EmitClassRefFromId(CGBuilderTy &Builder,
1085 IdentifierInfo *II);
1087 llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder);
1089 /// EmitSuperClassRef - Emits reference to class's main metadata class.
1090 llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID);
1092 /// EmitIvarList - Emit the ivar list for the given
1093 /// implementation. If ForClass is true the list of class ivars
1094 /// (i.e. metaclass ivars) is emitted, otherwise the list of
1095 /// interface ivars will be emitted. The return value has type
1097 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
1100 /// EmitMetaClass - Emit a forward reference to the class structure
1101 /// for the metaclass of the given interface. The return value has
1102 /// type ClassPtrTy.
1103 llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID);
1105 /// EmitMetaClass - Emit a class structure for the metaclass of the
1106 /// given implementation. The return value has type ClassPtrTy.
1107 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
1108 llvm::Constant *Protocols,
1109 ArrayRef<llvm::Constant*> Methods);
1111 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
1113 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
1115 /// EmitMethodList - Emit the method list for the given
1116 /// implementation. The return value has type MethodListPtrTy.
1117 llvm::Constant *EmitMethodList(Twine Name,
1118 const char *Section,
1119 ArrayRef<llvm::Constant*> Methods);
1121 /// EmitMethodDescList - Emit a method description list for a list of
1122 /// method declarations.
1123 /// - TypeName: The name for the type containing the methods.
1124 /// - IsProtocol: True iff these methods are for a protocol.
1125 /// - ClassMethds: True iff these are class methods.
1126 /// - Required: When true, only "required" methods are
1127 /// listed. Similarly, when false only "optional" methods are
1128 /// listed. For classes this should always be true.
1129 /// - begin, end: The method list to output.
1131 /// The return value has type MethodDescriptionListPtrTy.
1132 llvm::Constant *EmitMethodDescList(Twine Name,
1133 const char *Section,
1134 ArrayRef<llvm::Constant*> Methods);
1136 /// GetOrEmitProtocol - Get the protocol object for the given
1137 /// declaration, emitting it if necessary. The return value has type
1139 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
1141 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1142 /// object for the given declaration, emitting it if needed. These
1143 /// forward references will be filled in with empty bodies if no
1144 /// definition is seen. The return value has type ProtocolPtrTy.
1145 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
1147 /// EmitProtocolExtension - Generate the protocol extension
1148 /// structure used to store optional instance and class methods, and
1149 /// protocol properties. The return value has type
1150 /// ProtocolExtensionPtrTy.
1152 EmitProtocolExtension(const ObjCProtocolDecl *PD,
1153 ArrayRef<llvm::Constant*> OptInstanceMethods,
1154 ArrayRef<llvm::Constant*> OptClassMethods,
1155 ArrayRef<llvm::Constant*> MethodTypesExt);
1157 /// EmitProtocolList - Generate the list of referenced
1158 /// protocols. The return value has type ProtocolListPtrTy.
1159 llvm::Constant *EmitProtocolList(Twine Name,
1160 ObjCProtocolDecl::protocol_iterator begin,
1161 ObjCProtocolDecl::protocol_iterator end);
1163 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
1164 /// for the given selector.
1165 llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel,
1169 CGObjCMac(CodeGen::CodeGenModule &cgm);
1171 virtual llvm::Function *ModuleInitFunction();
1173 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1174 ReturnValueSlot Return,
1175 QualType ResultType,
1177 llvm::Value *Receiver,
1178 const CallArgList &CallArgs,
1179 const ObjCInterfaceDecl *Class,
1180 const ObjCMethodDecl *Method);
1182 virtual CodeGen::RValue
1183 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1184 ReturnValueSlot Return,
1185 QualType ResultType,
1187 const ObjCInterfaceDecl *Class,
1188 bool isCategoryImpl,
1189 llvm::Value *Receiver,
1190 bool IsClassMessage,
1191 const CallArgList &CallArgs,
1192 const ObjCMethodDecl *Method);
1194 virtual llvm::Value *GetClass(CGBuilderTy &Builder,
1195 const ObjCInterfaceDecl *ID);
1197 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel,
1200 /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1202 virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
1203 const ObjCMethodDecl *Method);
1205 virtual llvm::Constant *GetEHType(QualType T);
1207 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
1209 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
1211 virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {}
1213 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
1214 const ObjCProtocolDecl *PD);
1216 virtual llvm::Constant *GetPropertyGetFunction();
1217 virtual llvm::Constant *GetPropertySetFunction();
1218 virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
1220 virtual llvm::Constant *GetGetStructFunction();
1221 virtual llvm::Constant *GetSetStructFunction();
1222 virtual llvm::Constant *GetCppAtomicObjectFunction();
1223 virtual llvm::Constant *EnumerationMutationFunction();
1225 virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1226 const ObjCAtTryStmt &S);
1227 virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1228 const ObjCAtSynchronizedStmt &S);
1229 void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const Stmt &S);
1230 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
1231 const ObjCAtThrowStmt &S);
1232 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1233 llvm::Value *AddrWeakObj);
1234 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1235 llvm::Value *src, llvm::Value *dst);
1236 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1237 llvm::Value *src, llvm::Value *dest,
1238 bool threadlocal = false);
1239 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
1240 llvm::Value *src, llvm::Value *dest,
1241 llvm::Value *ivarOffset);
1242 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
1243 llvm::Value *src, llvm::Value *dest);
1244 virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1245 llvm::Value *dest, llvm::Value *src,
1248 virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
1250 llvm::Value *BaseValue,
1251 const ObjCIvarDecl *Ivar,
1252 unsigned CVRQualifiers);
1253 virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1254 const ObjCInterfaceDecl *Interface,
1255 const ObjCIvarDecl *Ivar);
1257 /// GetClassGlobal - Return the global variable for the Objective-C
1258 /// class of the given name.
1259 virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) {
1260 llvm_unreachable("CGObjCMac::GetClassGlobal");
1264 class CGObjCNonFragileABIMac : public CGObjCCommonMac {
1266 ObjCNonFragileABITypesHelper ObjCTypes;
1267 llvm::GlobalVariable* ObjCEmptyCacheVar;
1268 llvm::GlobalVariable* ObjCEmptyVtableVar;
1270 /// SuperClassReferences - uniqued super class references.
1271 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
1273 /// MetaClassReferences - uniqued meta class references.
1274 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
1276 /// EHTypeReferences - uniqued class ehtype references.
1277 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
1279 /// VTableDispatchMethods - List of methods for which we generate
1280 /// vtable-based message dispatch.
1281 llvm::DenseSet<Selector> VTableDispatchMethods;
1283 /// DefinedMetaClasses - List of defined meta-classes.
1284 std::vector<llvm::GlobalValue*> DefinedMetaClasses;
1286 /// isVTableDispatchedSelector - Returns true if SEL is a
1287 /// vtable-based selector.
1288 bool isVTableDispatchedSelector(Selector Sel);
1290 /// FinishNonFragileABIModule - Write out global data structures at the end of
1291 /// processing a translation unit.
1292 void FinishNonFragileABIModule();
1294 /// AddModuleClassList - Add the given list of class pointers to the
1295 /// module with the provided symbol and section names.
1296 void AddModuleClassList(ArrayRef<llvm::GlobalValue*> Container,
1297 const char *SymbolName,
1298 const char *SectionName);
1300 llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags,
1301 unsigned InstanceStart,
1302 unsigned InstanceSize,
1303 const ObjCImplementationDecl *ID);
1304 llvm::GlobalVariable * BuildClassMetaData(std::string &ClassName,
1305 llvm::Constant *IsAGV,
1306 llvm::Constant *SuperClassGV,
1307 llvm::Constant *ClassRoGV,
1308 bool HiddenVisibility);
1310 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
1312 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
1314 /// EmitMethodList - Emit the method list for the given
1315 /// implementation. The return value has type MethodListnfABITy.
1316 llvm::Constant *EmitMethodList(Twine Name,
1317 const char *Section,
1318 ArrayRef<llvm::Constant*> Methods);
1319 /// EmitIvarList - Emit the ivar list for the given
1320 /// implementation. If ForClass is true the list of class ivars
1321 /// (i.e. metaclass ivars) is emitted, otherwise the list of
1322 /// interface ivars will be emitted. The return value has type
1323 /// IvarListnfABIPtrTy.
1324 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID);
1326 llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
1327 const ObjCIvarDecl *Ivar,
1328 unsigned long int offset);
1330 /// GetOrEmitProtocol - Get the protocol object for the given
1331 /// declaration, emitting it if necessary. The return value has type
1333 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
1335 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1336 /// object for the given declaration, emitting it if needed. These
1337 /// forward references will be filled in with empty bodies if no
1338 /// definition is seen. The return value has type ProtocolPtrTy.
1339 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
1341 /// EmitProtocolList - Generate the list of referenced
1342 /// protocols. The return value has type ProtocolListPtrTy.
1343 llvm::Constant *EmitProtocolList(Twine Name,
1344 ObjCProtocolDecl::protocol_iterator begin,
1345 ObjCProtocolDecl::protocol_iterator end);
1347 CodeGen::RValue EmitVTableMessageSend(CodeGen::CodeGenFunction &CGF,
1348 ReturnValueSlot Return,
1349 QualType ResultType,
1351 llvm::Value *Receiver,
1354 const CallArgList &CallArgs,
1355 const ObjCMethodDecl *Method);
1357 /// GetClassGlobal - Return the global variable for the Objective-C
1358 /// class of the given name.
1359 llvm::GlobalVariable *GetClassGlobal(const std::string &Name);
1361 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1362 /// for the given class reference.
1363 llvm::Value *EmitClassRef(CGBuilderTy &Builder,
1364 const ObjCInterfaceDecl *ID);
1366 llvm::Value *EmitClassRefFromId(CGBuilderTy &Builder,
1367 IdentifierInfo *II);
1369 llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder);
1371 /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1372 /// for the given super class reference.
1373 llvm::Value *EmitSuperClassRef(CGBuilderTy &Builder,
1374 const ObjCInterfaceDecl *ID);
1376 /// EmitMetaClassRef - Return a Value * of the address of _class_t
1378 llvm::Value *EmitMetaClassRef(CGBuilderTy &Builder,
1379 const ObjCInterfaceDecl *ID);
1381 /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
1384 llvm::GlobalVariable * ObjCIvarOffsetVariable(
1385 const ObjCInterfaceDecl *ID,
1386 const ObjCIvarDecl *Ivar);
1388 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
1389 /// for the given selector.
1390 llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel,
1393 /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C
1394 /// interface. The return value has type EHTypePtrTy.
1395 llvm::Constant *GetInterfaceEHType(const ObjCInterfaceDecl *ID,
1396 bool ForDefinition);
1398 const char *getMetaclassSymbolPrefix() const {
1399 return "OBJC_METACLASS_$_";
1402 const char *getClassSymbolPrefix() const {
1403 return "OBJC_CLASS_$_";
1406 void GetClassSizeInfo(const ObjCImplementationDecl *OID,
1407 uint32_t &InstanceStart,
1408 uint32_t &InstanceSize);
1410 // Shamelessly stolen from Analysis/CFRefCount.cpp
1411 Selector GetNullarySelector(const char* name) const {
1412 IdentifierInfo* II = &CGM.getContext().Idents.get(name);
1413 return CGM.getContext().Selectors.getSelector(0, &II);
1416 Selector GetUnarySelector(const char* name) const {
1417 IdentifierInfo* II = &CGM.getContext().Idents.get(name);
1418 return CGM.getContext().Selectors.getSelector(1, &II);
1421 /// ImplementationIsNonLazy - Check whether the given category or
1422 /// class implementation is "non-lazy".
1423 bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const;
1426 CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
1427 // FIXME. All stubs for now!
1428 virtual llvm::Function *ModuleInitFunction();
1430 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1431 ReturnValueSlot Return,
1432 QualType ResultType,
1434 llvm::Value *Receiver,
1435 const CallArgList &CallArgs,
1436 const ObjCInterfaceDecl *Class,
1437 const ObjCMethodDecl *Method);
1439 virtual CodeGen::RValue
1440 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1441 ReturnValueSlot Return,
1442 QualType ResultType,
1444 const ObjCInterfaceDecl *Class,
1445 bool isCategoryImpl,
1446 llvm::Value *Receiver,
1447 bool IsClassMessage,
1448 const CallArgList &CallArgs,
1449 const ObjCMethodDecl *Method);
1451 virtual llvm::Value *GetClass(CGBuilderTy &Builder,
1452 const ObjCInterfaceDecl *ID);
1454 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel,
1455 bool lvalue = false)
1456 { return EmitSelector(Builder, Sel, lvalue); }
1458 /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1460 virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
1461 const ObjCMethodDecl *Method)
1462 { return EmitSelector(Builder, Method->getSelector()); }
1464 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
1466 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
1468 virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {}
1470 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
1471 const ObjCProtocolDecl *PD);
1473 virtual llvm::Constant *GetEHType(QualType T);
1475 virtual llvm::Constant *GetPropertyGetFunction() {
1476 return ObjCTypes.getGetPropertyFn();
1478 virtual llvm::Constant *GetPropertySetFunction() {
1479 return ObjCTypes.getSetPropertyFn();
1482 virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
1484 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
1487 virtual llvm::Constant *GetSetStructFunction() {
1488 return ObjCTypes.getCopyStructFn();
1490 virtual llvm::Constant *GetGetStructFunction() {
1491 return ObjCTypes.getCopyStructFn();
1493 virtual llvm::Constant *GetCppAtomicObjectFunction() {
1494 return ObjCTypes.getCppAtomicObjectFunction();
1497 virtual llvm::Constant *EnumerationMutationFunction() {
1498 return ObjCTypes.getEnumerationMutationFn();
1501 virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1502 const ObjCAtTryStmt &S);
1503 virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1504 const ObjCAtSynchronizedStmt &S);
1505 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
1506 const ObjCAtThrowStmt &S);
1507 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1508 llvm::Value *AddrWeakObj);
1509 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1510 llvm::Value *src, llvm::Value *dst);
1511 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1512 llvm::Value *src, llvm::Value *dest,
1513 bool threadlocal = false);
1514 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
1515 llvm::Value *src, llvm::Value *dest,
1516 llvm::Value *ivarOffset);
1517 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
1518 llvm::Value *src, llvm::Value *dest);
1519 virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1520 llvm::Value *dest, llvm::Value *src,
1522 virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
1524 llvm::Value *BaseValue,
1525 const ObjCIvarDecl *Ivar,
1526 unsigned CVRQualifiers);
1527 virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1528 const ObjCInterfaceDecl *Interface,
1529 const ObjCIvarDecl *Ivar);
1532 /// A helper class for performing the null-initialization of a return
1534 struct NullReturnState {
1535 llvm::BasicBlock *NullBB;
1536 llvm::BasicBlock *callBB;
1537 NullReturnState() : NullBB(0), callBB(0) {}
1539 void init(CodeGenFunction &CGF, llvm::Value *receiver) {
1540 // Make blocks for the null-init and call edges.
1541 NullBB = CGF.createBasicBlock("msgSend.nullinit");
1542 callBB = CGF.createBasicBlock("msgSend.call");
1544 // Check for a null receiver and, if there is one, jump to the
1546 llvm::Value *isNull = CGF.Builder.CreateIsNull(receiver);
1547 CGF.Builder.CreateCondBr(isNull, NullBB, callBB);
1549 // Otherwise, start performing the call.
1550 CGF.EmitBlock(callBB);
1553 RValue complete(CodeGenFunction &CGF, RValue result, QualType resultType,
1554 const CallArgList &CallArgs,
1555 const ObjCMethodDecl *Method) {
1556 if (!NullBB) return result;
1558 llvm::Value *NullInitPtr = 0;
1559 if (result.isScalar() && !resultType->isVoidType()) {
1560 NullInitPtr = CGF.CreateTempAlloca(result.getScalarVal()->getType());
1561 CGF.Builder.CreateStore(result.getScalarVal(), NullInitPtr);
1564 // Finish the call path.
1565 llvm::BasicBlock *contBB = CGF.createBasicBlock("msgSend.cont");
1566 if (CGF.HaveInsertPoint()) CGF.Builder.CreateBr(contBB);
1568 // Emit the null-init block and perform the null-initialization there.
1569 CGF.EmitBlock(NullBB);
1571 // Release consumed arguments along the null-receiver path.
1573 CallArgList::const_iterator I = CallArgs.begin();
1574 for (ObjCMethodDecl::param_const_iterator i = Method->param_begin(),
1575 e = Method->param_end(); i != e; ++i, ++I) {
1576 const ParmVarDecl *ParamDecl = (*i);
1577 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
1579 assert(RV.isScalar() &&
1580 "NullReturnState::complete - arg not on object");
1581 CGF.EmitARCRelease(RV.getScalarVal(), true);
1586 if (result.isScalar()) {
1588 CGF.EmitNullInitialization(NullInitPtr, resultType);
1589 // Jump to the continuation block.
1590 CGF.EmitBlock(contBB);
1591 return NullInitPtr ? RValue::get(CGF.Builder.CreateLoad(NullInitPtr))
1595 if (!resultType->isAnyComplexType()) {
1596 assert(result.isAggregate() && "null init of non-aggregate result?");
1597 CGF.EmitNullInitialization(result.getAggregateAddr(), resultType);
1598 // Jump to the continuation block.
1599 CGF.EmitBlock(contBB);
1604 // FIXME. Now easy to handle any other scalar type whose result is returned
1605 // in memory due to ABI limitations.
1606 CGF.EmitBlock(contBB);
1607 CodeGenFunction::ComplexPairTy CallCV = result.getComplexVal();
1608 llvm::Type *MemberType = CallCV.first->getType();
1609 llvm::Constant *ZeroCV = llvm::Constant::getNullValue(MemberType);
1610 // Create phi instruction for scalar complex value.
1611 llvm::PHINode *PHIReal = CGF.Builder.CreatePHI(MemberType, 2);
1612 PHIReal->addIncoming(ZeroCV, NullBB);
1613 PHIReal->addIncoming(CallCV.first, callBB);
1614 llvm::PHINode *PHIImag = CGF.Builder.CreatePHI(MemberType, 2);
1615 PHIImag->addIncoming(ZeroCV, NullBB);
1616 PHIImag->addIncoming(CallCV.second, callBB);
1617 return RValue::getComplex(PHIReal, PHIImag);
1621 } // end anonymous namespace
1623 /* *** Helper Functions *** */
1625 /// getConstantGEP() - Help routine to construct simple GEPs.
1626 static llvm::Constant *getConstantGEP(llvm::LLVMContext &VMContext,
1630 llvm::Value *Idxs[] = {
1631 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1632 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
1634 return llvm::ConstantExpr::getGetElementPtr(C, Idxs);
1637 /// hasObjCExceptionAttribute - Return true if this class or any super
1638 /// class has the __objc_exception__ attribute.
1639 static bool hasObjCExceptionAttribute(ASTContext &Context,
1640 const ObjCInterfaceDecl *OID) {
1641 if (OID->hasAttr<ObjCExceptionAttr>())
1643 if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
1644 return hasObjCExceptionAttribute(Context, Super);
1648 /* *** CGObjCMac Public Interface *** */
1650 CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm),
1656 /// GetClass - Return a reference to the class for the given interface
1658 llvm::Value *CGObjCMac::GetClass(CGBuilderTy &Builder,
1659 const ObjCInterfaceDecl *ID) {
1660 return EmitClassRef(Builder, ID);
1663 /// GetSelector - Return the pointer to the unique'd string for this selector.
1664 llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, Selector Sel,
1666 return EmitSelector(Builder, Sel, lval);
1668 llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
1670 return EmitSelector(Builder, Method->getSelector());
1673 llvm::Constant *CGObjCMac::GetEHType(QualType T) {
1674 if (T->isObjCIdType() ||
1675 T->isObjCQualifiedIdType()) {
1676 return CGM.GetAddrOfRTTIDescriptor(
1677 CGM.getContext().getObjCIdRedefinitionType(), /*ForEH=*/true);
1679 if (T->isObjCClassType() ||
1680 T->isObjCQualifiedClassType()) {
1681 return CGM.GetAddrOfRTTIDescriptor(
1682 CGM.getContext().getObjCClassRedefinitionType(), /*ForEH=*/true);
1684 if (T->isObjCObjectPointerType())
1685 return CGM.GetAddrOfRTTIDescriptor(T, /*ForEH=*/true);
1687 llvm_unreachable("asking for catch type for ObjC type in fragile runtime");
1690 /// Generate a constant CFString object.
1692 struct __builtin_CFString {
1693 const int *isa; // point to __CFConstantStringClassReference
1700 /// or Generate a constant NSString object.
1702 struct __builtin_NSString {
1703 const int *isa; // point to __NSConstantStringClassReference
1705 unsigned int length;
1709 llvm::Constant *CGObjCCommonMac::GenerateConstantString(
1710 const StringLiteral *SL) {
1711 return (CGM.getLangOpts().NoConstantCFStrings == 0 ?
1712 CGM.GetAddrOfConstantCFString(SL) :
1713 CGM.GetAddrOfConstantString(SL));
1717 kCFTaggedObjectID_Integer = (1 << 1) + 1
1720 /// Generates a message send where the super is the receiver. This is
1721 /// a message send to self with special delivery semantics indicating
1722 /// which class's method should be called.
1724 CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1725 ReturnValueSlot Return,
1726 QualType ResultType,
1728 const ObjCInterfaceDecl *Class,
1729 bool isCategoryImpl,
1730 llvm::Value *Receiver,
1731 bool IsClassMessage,
1732 const CodeGen::CallArgList &CallArgs,
1733 const ObjCMethodDecl *Method) {
1734 // Create and init a super structure; this is a (receiver, class)
1735 // pair we will pass to objc_msgSendSuper.
1736 llvm::Value *ObjCSuper =
1737 CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super");
1738 llvm::Value *ReceiverAsObject =
1739 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
1740 CGF.Builder.CreateStore(ReceiverAsObject,
1741 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
1743 // If this is a class message the metaclass is passed as the target.
1744 llvm::Value *Target;
1745 if (IsClassMessage) {
1746 if (isCategoryImpl) {
1747 // Message sent to 'super' in a class method defined in a category
1748 // implementation requires an odd treatment.
1749 // If we are in a class method, we must retrieve the
1750 // _metaclass_ for the current class, pointed at by
1751 // the class's "isa" pointer. The following assumes that
1752 // isa" is the first ivar in a class (which it must be).
1753 Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
1754 Target = CGF.Builder.CreateStructGEP(Target, 0);
1755 Target = CGF.Builder.CreateLoad(Target);
1757 llvm::Value *MetaClassPtr = EmitMetaClassRef(Class);
1758 llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1);
1759 llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr);
1763 else if (isCategoryImpl)
1764 Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
1766 llvm::Value *ClassPtr = EmitSuperClassRef(Class);
1767 ClassPtr = CGF.Builder.CreateStructGEP(ClassPtr, 1);
1768 Target = CGF.Builder.CreateLoad(ClassPtr);
1770 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
1772 llvm::Type *ClassTy =
1773 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
1774 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
1775 CGF.Builder.CreateStore(Target,
1776 CGF.Builder.CreateStructGEP(ObjCSuper, 1));
1777 return EmitMessageSend(CGF, Return, ResultType,
1778 EmitSelector(CGF.Builder, Sel),
1779 ObjCSuper, ObjCTypes.SuperPtrCTy,
1780 true, CallArgs, Method, ObjCTypes);
1783 /// Generate code for a message send expression.
1784 CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1785 ReturnValueSlot Return,
1786 QualType ResultType,
1788 llvm::Value *Receiver,
1789 const CallArgList &CallArgs,
1790 const ObjCInterfaceDecl *Class,
1791 const ObjCMethodDecl *Method) {
1792 return EmitMessageSend(CGF, Return, ResultType,
1793 EmitSelector(CGF.Builder, Sel),
1794 Receiver, CGF.getContext().getObjCIdType(),
1795 false, CallArgs, Method, ObjCTypes);
1799 CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
1800 ReturnValueSlot Return,
1801 QualType ResultType,
1806 const CallArgList &CallArgs,
1807 const ObjCMethodDecl *Method,
1808 const ObjCCommonTypesHelper &ObjCTypes) {
1809 CallArgList ActualArgs;
1811 Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy);
1812 ActualArgs.add(RValue::get(Arg0), Arg0Ty);
1813 ActualArgs.add(RValue::get(Sel), CGF.getContext().getObjCSelType());
1814 ActualArgs.addFrom(CallArgs);
1816 // If we're calling a method, use the formal signature.
1817 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
1820 assert(CGM.getContext().getCanonicalType(Method->getResultType()) ==
1821 CGM.getContext().getCanonicalType(ResultType) &&
1822 "Result type mismatch!");
1824 NullReturnState nullReturn;
1826 llvm::Constant *Fn = NULL;
1827 if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) {
1828 if (!IsSuper) nullReturn.init(CGF, Arg0);
1829 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
1830 : ObjCTypes.getSendStretFn(IsSuper);
1831 } else if (CGM.ReturnTypeUsesFPRet(ResultType)) {
1832 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
1833 : ObjCTypes.getSendFpretFn(IsSuper);
1834 } else if (CGM.ReturnTypeUsesFP2Ret(ResultType)) {
1835 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
1836 : ObjCTypes.getSendFp2retFn(IsSuper);
1838 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
1839 : ObjCTypes.getSendFn(IsSuper);
1842 bool requiresnullCheck = false;
1843 if (CGM.getLangOpts().ObjCAutoRefCount && Method)
1844 for (ObjCMethodDecl::param_const_iterator i = Method->param_begin(),
1845 e = Method->param_end(); i != e; ++i) {
1846 const ParmVarDecl *ParamDecl = (*i);
1847 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
1848 if (!nullReturn.NullBB)
1849 nullReturn.init(CGF, Arg0);
1850 requiresnullCheck = true;
1855 Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType);
1856 RValue rvalue = CGF.EmitCall(MSI.CallInfo, Fn, Return, ActualArgs);
1857 return nullReturn.complete(CGF, rvalue, ResultType, CallArgs,
1858 requiresnullCheck ? Method : 0);
1861 static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT) {
1862 if (FQT.isObjCGCStrong())
1863 return Qualifiers::Strong;
1865 if (FQT.isObjCGCWeak() || FQT.getObjCLifetime() == Qualifiers::OCL_Weak)
1866 return Qualifiers::Weak;
1868 // check for __unsafe_unretained
1869 if (FQT.getObjCLifetime() == Qualifiers::OCL_ExplicitNone)
1870 return Qualifiers::GCNone;
1872 if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
1873 return Qualifiers::Strong;
1875 if (const PointerType *PT = FQT->getAs<PointerType>())
1876 return GetGCAttrTypeForType(Ctx, PT->getPointeeType());
1878 return Qualifiers::GCNone;
1881 llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
1882 const CGBlockInfo &blockInfo) {
1884 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
1885 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
1886 !CGM.getLangOpts().ObjCAutoRefCount)
1889 bool hasUnion = false;
1892 unsigned WordSizeInBits = CGM.getContext().getTargetInfo().getPointerWidth(0);
1893 unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth();
1895 // __isa is the first field in block descriptor and must assume by runtime's
1896 // convention that it is GC'able.
1897 IvarsInfo.push_back(GC_IVAR(0, 1));
1899 const BlockDecl *blockDecl = blockInfo.getBlockDecl();
1901 // Calculate the basic layout of the block structure.
1902 const llvm::StructLayout *layout =
1903 CGM.getDataLayout().getStructLayout(blockInfo.StructureType);
1905 // Ignore the optional 'this' capture: C++ objects are not assumed
1908 // Walk the captured variables.
1909 for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(),
1910 ce = blockDecl->capture_end(); ci != ce; ++ci) {
1911 const VarDecl *variable = ci->getVariable();
1912 QualType type = variable->getType();
1914 const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
1916 // Ignore constant captures.
1917 if (capture.isConstant()) continue;
1919 uint64_t fieldOffset = layout->getElementOffset(capture.getIndex());
1921 // __block variables are passed by their descriptor address.
1922 if (ci->isByRef()) {
1923 IvarsInfo.push_back(GC_IVAR(fieldOffset, /*size in words*/ 1));
1927 assert(!type->isArrayType() && "array variable should not be caught");
1928 if (const RecordType *record = type->getAs<RecordType>()) {
1929 BuildAggrIvarRecordLayout(record, fieldOffset, true, hasUnion);
1933 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), type);
1934 unsigned fieldSize = CGM.getContext().getTypeSize(type);
1936 if (GCAttr == Qualifiers::Strong)
1937 IvarsInfo.push_back(GC_IVAR(fieldOffset,
1938 fieldSize / WordSizeInBits));
1939 else if (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak)
1940 SkipIvars.push_back(GC_IVAR(fieldOffset,
1941 fieldSize / ByteSizeInBits));
1944 if (IvarsInfo.empty())
1947 // Sort on byte position; captures might not be allocated in order,
1948 // and unions can do funny things.
1949 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
1950 llvm::array_pod_sort(SkipIvars.begin(), SkipIvars.end());
1953 llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
1954 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
1955 printf("\n block variable layout for block: ");
1956 const unsigned char *s = (const unsigned char*)BitMap.c_str();
1957 for (unsigned i = 0, e = BitMap.size(); i < e; i++)
1959 printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
1961 printf("0x%x%s", s[i], s[i] != 0 ? ", " : "");
1968 /// getBlockCaptureLifetime - This routine returns life time of the captured
1969 /// block variable for the purpose of block layout meta-data generation. FQT is
1970 /// the type of the variable captured in the block.
1971 Qualifiers::ObjCLifetime CGObjCCommonMac::getBlockCaptureLifetime(QualType FQT) {
1972 if (CGM.getLangOpts().ObjCAutoRefCount)
1973 return FQT.getObjCLifetime();
1976 if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
1977 return Qualifiers::OCL_ExplicitNone;
1979 return Qualifiers::OCL_None;
1982 void CGObjCCommonMac::UpdateRunSkipBlockVars(bool IsByref,
1983 Qualifiers::ObjCLifetime LifeTime,
1984 CharUnits FieldOffset,
1985 CharUnits FieldSize) {
1986 // __block variables are passed by their descriptor address.
1988 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset,
1990 else if (LifeTime == Qualifiers::OCL_Strong)
1991 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset,
1993 else if (LifeTime == Qualifiers::OCL_Weak)
1994 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset,
1996 else if (LifeTime == Qualifiers::OCL_ExplicitNone)
1997 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset,
2000 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES,
2005 void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
2006 const RecordDecl *RD,
2007 ArrayRef<const FieldDecl*> RecFields,
2008 CharUnits BytePos, bool &HasUnion) {
2009 bool IsUnion = (RD && RD->isUnion());
2010 CharUnits MaxUnionSize = CharUnits::Zero();
2011 const FieldDecl *MaxField = 0;
2012 const FieldDecl *LastFieldBitfieldOrUnnamed = 0;
2013 CharUnits MaxFieldOffset = CharUnits::Zero();
2014 CharUnits LastBitfieldOrUnnamedOffset = CharUnits::Zero();
2016 if (RecFields.empty())
2018 unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth();
2020 for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
2021 const FieldDecl *Field = RecFields[i];
2022 // Note that 'i' here is actually the field index inside RD of Field,
2023 // although this dependency is hidden.
2024 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2025 CharUnits FieldOffset =
2026 CGM.getContext().toCharUnitsFromBits(RL.getFieldOffset(i));
2028 // Skip over unnamed or bitfields
2029 if (!Field->getIdentifier() || Field->isBitField()) {
2030 LastFieldBitfieldOrUnnamed = Field;
2031 LastBitfieldOrUnnamedOffset = FieldOffset;
2035 LastFieldBitfieldOrUnnamed = 0;
2036 QualType FQT = Field->getType();
2037 if (FQT->isRecordType() || FQT->isUnionType()) {
2038 if (FQT->isUnionType())
2041 BuildRCBlockVarRecordLayout(FQT->getAs<RecordType>(),
2042 BytePos + FieldOffset, HasUnion);
2046 if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
2047 const ConstantArrayType *CArray =
2048 dyn_cast_or_null<ConstantArrayType>(Array);
2049 uint64_t ElCount = CArray->getSize().getZExtValue();
2050 assert(CArray && "only array with known element size is supported");
2051 FQT = CArray->getElementType();
2052 while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
2053 const ConstantArrayType *CArray =
2054 dyn_cast_or_null<ConstantArrayType>(Array);
2055 ElCount *= CArray->getSize().getZExtValue();
2056 FQT = CArray->getElementType();
2059 assert(!FQT->isUnionType() &&
2060 "layout for array of unions not supported");
2061 if (FQT->isRecordType() && ElCount) {
2062 int OldIndex = RunSkipBlockVars.size() - 1;
2063 const RecordType *RT = FQT->getAs<RecordType>();
2064 BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset,
2067 // Replicate layout information for each array element. Note that
2068 // one element is already done.
2070 for (int FirstIndex = RunSkipBlockVars.size() - 1 ;ElIx < ElCount; ElIx++) {
2071 CharUnits Size = CGM.getContext().getTypeSizeInChars(RT);
2072 for (int i = OldIndex+1; i <= FirstIndex; ++i)
2073 RunSkipBlockVars.push_back(
2074 RUN_SKIP(RunSkipBlockVars[i].opcode,
2075 RunSkipBlockVars[i].block_var_bytepos + Size*ElIx,
2076 RunSkipBlockVars[i].block_var_size));
2081 CharUnits FieldSize = CGM.getContext().getTypeSizeInChars(Field->getType());
2083 CharUnits UnionIvarSize = FieldSize;
2084 if (UnionIvarSize > MaxUnionSize) {
2085 MaxUnionSize = UnionIvarSize;
2087 MaxFieldOffset = FieldOffset;
2090 UpdateRunSkipBlockVars(false,
2091 getBlockCaptureLifetime(FQT),
2092 BytePos + FieldOffset,
2097 if (LastFieldBitfieldOrUnnamed) {
2098 if (LastFieldBitfieldOrUnnamed->isBitField()) {
2099 // Last field was a bitfield. Must update the info.
2100 uint64_t BitFieldSize
2101 = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext());
2102 unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
2103 ((BitFieldSize % ByteSizeInBits) != 0);
2104 CharUnits Size = CharUnits::fromQuantity(UnsSize);
2105 Size += LastBitfieldOrUnnamedOffset;
2106 UpdateRunSkipBlockVars(false,
2107 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType()),
2108 BytePos + LastBitfieldOrUnnamedOffset,
2111 assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed");
2112 // Last field was unnamed. Must update skip info.
2114 = CGM.getContext().getTypeSizeInChars(LastFieldBitfieldOrUnnamed->getType());
2115 UpdateRunSkipBlockVars(false,
2116 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType()),
2117 BytePos + LastBitfieldOrUnnamedOffset,
2123 UpdateRunSkipBlockVars(false,
2124 getBlockCaptureLifetime(MaxField->getType()),
2125 BytePos + MaxFieldOffset,
2129 void CGObjCCommonMac::BuildRCBlockVarRecordLayout(const RecordType *RT,
2132 const RecordDecl *RD = RT->getDecl();
2133 SmallVector<const FieldDecl*, 16> Fields;
2134 for (RecordDecl::field_iterator i = RD->field_begin(),
2135 e = RD->field_end(); i != e; ++i)
2136 Fields.push_back(*i);
2137 llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
2138 const llvm::StructLayout *RecLayout =
2139 CGM.getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
2141 BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion);
2144 /// InlineLayoutInstruction - This routine produce an inline instruction for the
2145 /// block variable layout if it can. If not, it returns 0. Rules are as follow:
2146 /// If ((uintptr_t) layout) < (1 << 12), the layout is inline. In the 64bit world,
2147 /// an inline layout of value 0x0000000000000xyz is interpreted as follows:
2148 /// x captured object pointers of BLOCK_LAYOUT_STRONG. Followed by
2149 /// y captured object of BLOCK_LAYOUT_BYREF. Followed by
2150 /// z captured object of BLOCK_LAYOUT_WEAK. If any of the above is missing, zero
2151 /// replaces it. For example, 0x00000x00 means x BLOCK_LAYOUT_STRONG and no
2152 /// BLOCK_LAYOUT_BYREF and no BLOCK_LAYOUT_WEAK objects are captured.
2153 uint64_t CGObjCCommonMac::InlineLayoutInstruction(
2154 SmallVectorImpl<unsigned char> &Layout) {
2155 uint64_t Result = 0;
2156 if (Layout.size() <= 3) {
2157 unsigned size = Layout.size();
2158 unsigned strong_word_count = 0, byref_word_count=0, weak_word_count=0;
2160 enum BLOCK_LAYOUT_OPCODE opcode ;
2164 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2165 if (opcode == BLOCK_LAYOUT_STRONG)
2166 strong_word_count = (inst & 0xF)+1;
2170 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2171 if (opcode == BLOCK_LAYOUT_BYREF)
2172 byref_word_count = (inst & 0xF)+1;
2176 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2177 if (opcode == BLOCK_LAYOUT_WEAK)
2178 weak_word_count = (inst & 0xF)+1;
2185 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2186 if (opcode == BLOCK_LAYOUT_STRONG) {
2187 strong_word_count = (inst & 0xF)+1;
2189 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2190 if (opcode == BLOCK_LAYOUT_BYREF)
2191 byref_word_count = (inst & 0xF)+1;
2192 else if (opcode == BLOCK_LAYOUT_WEAK)
2193 weak_word_count = (inst & 0xF)+1;
2197 else if (opcode == BLOCK_LAYOUT_BYREF) {
2198 byref_word_count = (inst & 0xF)+1;
2200 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2201 if (opcode == BLOCK_LAYOUT_WEAK)
2202 weak_word_count = (inst & 0xF)+1;
2212 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2213 if (opcode == BLOCK_LAYOUT_STRONG)
2214 strong_word_count = (inst & 0xF)+1;
2215 else if (opcode == BLOCK_LAYOUT_BYREF)
2216 byref_word_count = (inst & 0xF)+1;
2217 else if (opcode == BLOCK_LAYOUT_WEAK)
2218 weak_word_count = (inst & 0xF)+1;
2227 // Cannot inline when any of the word counts is 15. Because this is one less
2228 // than the actual work count (so 15 means 16 actual word counts),
2229 // and we can only display 0 thru 15 word counts.
2230 if (strong_word_count == 16 || byref_word_count == 16 || weak_word_count == 16)
2234 (strong_word_count != 0) + (byref_word_count != 0) + (weak_word_count != 0);
2236 if (size == count) {
2237 if (strong_word_count)
2238 Result = strong_word_count;
2240 if (byref_word_count)
2241 Result += byref_word_count;
2243 if (weak_word_count)
2244 Result += weak_word_count;
2250 llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
2251 const CGBlockInfo &blockInfo) {
2252 assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
2254 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
2256 RunSkipBlockVars.clear();
2257 bool hasUnion = false;
2259 unsigned WordSizeInBits = CGM.getContext().getTargetInfo().getPointerWidth(0);
2260 unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth();
2261 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2263 const BlockDecl *blockDecl = blockInfo.getBlockDecl();
2265 // Calculate the basic layout of the block structure.
2266 const llvm::StructLayout *layout =
2267 CGM.getDataLayout().getStructLayout(blockInfo.StructureType);
2269 // Ignore the optional 'this' capture: C++ objects are not assumed
2272 // Walk the captured variables.
2273 for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(),
2274 ce = blockDecl->capture_end(); ci != ce; ++ci) {
2275 const VarDecl *variable = ci->getVariable();
2276 QualType type = variable->getType();
2278 const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
2280 // Ignore constant captures.
2281 if (capture.isConstant()) continue;
2283 CharUnits fieldOffset =
2284 CharUnits::fromQuantity(layout->getElementOffset(capture.getIndex()));
2286 assert(!type->isArrayType() && "array variable should not be caught");
2287 if (const RecordType *record = type->getAs<RecordType>()) {
2288 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
2291 CharUnits fieldSize;
2293 fieldSize = CharUnits::fromQuantity(WordSizeInBytes);
2295 fieldSize = CGM.getContext().getTypeSizeInChars(type);
2296 UpdateRunSkipBlockVars(ci->isByRef(), getBlockCaptureLifetime(type),
2297 fieldOffset, fieldSize);
2300 if (RunSkipBlockVars.empty())
2303 // Sort on byte position; captures might not be allocated in order,
2304 // and unions can do funny things.
2305 llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());
2306 SmallVector<unsigned char, 16> Layout;
2308 unsigned size = RunSkipBlockVars.size();
2309 for (unsigned i = 0; i < size; i++) {
2310 enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
2311 CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
2312 CharUnits end_byte_pos = start_byte_pos;
2315 if (opcode == RunSkipBlockVars[j].opcode) {
2316 end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
2322 CharUnits size_in_bytes =
2323 end_byte_pos - start_byte_pos + RunSkipBlockVars[j-1].block_var_size;
2326 RunSkipBlockVars[j].block_var_bytepos -
2327 RunSkipBlockVars[j-1].block_var_bytepos - RunSkipBlockVars[j-1].block_var_size;
2328 size_in_bytes += gap;
2330 CharUnits residue_in_bytes = CharUnits::Zero();
2331 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
2332 residue_in_bytes = size_in_bytes % WordSizeInBytes;
2333 size_in_bytes -= residue_in_bytes;
2334 opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
2337 unsigned size_in_words = size_in_bytes.getQuantity() / WordSizeInBytes;
2338 while (size_in_words >= 16) {
2339 // Note that value in imm. is one less that the actual
2340 // value. So, 0xf means 16 words follow!
2341 unsigned char inst = (opcode << 4) | 0xf;
2342 Layout.push_back(inst);
2343 size_in_words -= 16;
2345 if (size_in_words > 0) {
2346 // Note that value in imm. is one less that the actual
2347 // value. So, we subtract 1 away!
2348 unsigned char inst = (opcode << 4) | (size_in_words-1);
2349 Layout.push_back(inst);
2351 if (residue_in_bytes > CharUnits::Zero()) {
2352 unsigned char inst =
2353 (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) | (residue_in_bytes.getQuantity()-1);
2354 Layout.push_back(inst);
2358 int e = Layout.size()-1;
2360 unsigned char inst = Layout[e--];
2361 enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2362 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES || opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
2368 uint64_t Result = InlineLayoutInstruction(Layout);
2370 // Block variable layout instruction has been inlined.
2371 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
2372 printf("\n Inline instruction for block variable layout: ");
2373 printf("0x0%llx\n", (unsigned long long)Result);
2375 if (WordSizeInBytes == 8) {
2376 const llvm::APInt Instruction(64, Result);
2377 return llvm::Constant::getIntegerValue(CGM.Int64Ty, Instruction);
2380 const llvm::APInt Instruction(32, Result);
2381 return llvm::Constant::getIntegerValue(CGM.Int32Ty, Instruction);
2385 unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
2386 Layout.push_back(inst);
2388 for (unsigned i = 0, e = Layout.size(); i != e; i++)
2389 BitMap += Layout[i];
2391 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
2392 printf("\n block variable layout: ");
2393 for (unsigned i = 0, e = BitMap.size(); i != e; i++) {
2394 unsigned char inst = BitMap[i];
2395 enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2398 case BLOCK_LAYOUT_OPERATOR:
2399 printf("BL_OPERATOR:");
2402 case BLOCK_LAYOUT_NON_OBJECT_BYTES:
2403 printf("BL_NON_OBJECT_BYTES:");
2405 case BLOCK_LAYOUT_NON_OBJECT_WORDS:
2406 printf("BL_NON_OBJECT_WORD:");
2408 case BLOCK_LAYOUT_STRONG:
2409 printf("BL_STRONG:");
2411 case BLOCK_LAYOUT_BYREF:
2412 printf("BL_BYREF:");
2414 case BLOCK_LAYOUT_WEAK:
2417 case BLOCK_LAYOUT_UNRETAINED:
2418 printf("BL_UNRETAINED:");
2421 // Actual value of word count is one more that what is in the imm.
2422 // field of the instruction
2423 printf("%d", (inst & 0xf) + delta);
2431 llvm::GlobalVariable * Entry =
2432 CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
2433 llvm::ConstantDataArray::getString(VMContext, BitMap,false),
2434 "__TEXT,__objc_classname,cstring_literals", 1, true);
2435 return getConstantGEP(VMContext, Entry, 0, 0);
2438 llvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder,
2439 const ObjCProtocolDecl *PD) {
2440 // FIXME: I don't understand why gcc generates this, or where it is
2441 // resolved. Investigate. Its also wasteful to look this up over and over.
2442 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
2444 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
2445 ObjCTypes.getExternalProtocolPtrTy());
2448 void CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
2449 // FIXME: We shouldn't need this, the protocol decl should contain enough
2450 // information to tell us whether this was a declaration or a definition.
2451 DefinedProtocols.insert(PD->getIdentifier());
2453 // If we have generated a forward reference to this protocol, emit
2454 // it now. Otherwise do nothing, the protocol objects are lazily
2456 if (Protocols.count(PD->getIdentifier()))
2457 GetOrEmitProtocol(PD);
2460 llvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
2461 if (DefinedProtocols.count(PD->getIdentifier()))
2462 return GetOrEmitProtocol(PD);
2464 return GetOrEmitProtocolRef(PD);
2468 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
2469 struct _objc_protocol {
2470 struct _objc_protocol_extension *isa;
2471 char *protocol_name;
2472 struct _objc_protocol_list *protocol_list;
2473 struct _objc__method_prototype_list *instance_methods;
2474 struct _objc__method_prototype_list *class_methods
2477 See EmitProtocolExtension().
2479 llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
2480 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
2482 // Early exit if a defining object has already been generated.
2483 if (Entry && Entry->hasInitializer())
2486 // Use the protocol definition, if there is one.
2487 if (const ObjCProtocolDecl *Def = PD->getDefinition())
2490 // FIXME: I don't understand why gcc generates this, or where it is
2491 // resolved. Investigate. Its also wasteful to look this up over and over.
2492 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
2494 // Construct method lists.
2495 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
2496 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
2497 std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt;
2498 for (ObjCProtocolDecl::instmeth_iterator
2499 i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
2500 ObjCMethodDecl *MD = *i;
2501 llvm::Constant *C = GetMethodDescriptionConstant(MD);
2503 return GetOrEmitProtocolRef(PD);
2505 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
2506 OptInstanceMethods.push_back(C);
2507 OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
2509 InstanceMethods.push_back(C);
2510 MethodTypesExt.push_back(GetMethodVarType(MD, true));
2514 for (ObjCProtocolDecl::classmeth_iterator
2515 i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
2516 ObjCMethodDecl *MD = *i;
2517 llvm::Constant *C = GetMethodDescriptionConstant(MD);
2519 return GetOrEmitProtocolRef(PD);
2521 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
2522 OptClassMethods.push_back(C);
2523 OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
2525 ClassMethods.push_back(C);
2526 MethodTypesExt.push_back(GetMethodVarType(MD, true));
2530 MethodTypesExt.insert(MethodTypesExt.end(),
2531 OptMethodTypesExt.begin(), OptMethodTypesExt.end());
2533 llvm::Constant *Values[] = {
2534 EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods,
2536 GetClassName(PD->getIdentifier()),
2537 EmitProtocolList("\01L_OBJC_PROTOCOL_REFS_" + PD->getName(),
2538 PD->protocol_begin(),
2539 PD->protocol_end()),
2540 EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_" + PD->getName(),
2541 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2543 EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_" + PD->getName(),
2544 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2547 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
2551 // Already created, fix the linkage and update the initializer.
2552 Entry->setLinkage(llvm::GlobalValue::InternalLinkage);
2553 Entry->setInitializer(Init);
2556 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,
2557 llvm::GlobalValue::InternalLinkage,
2559 "\01L_OBJC_PROTOCOL_" + PD->getName());
2560 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
2561 // FIXME: Is this necessary? Why only for protocol?
2562 Entry->setAlignment(4);
2564 Protocols[PD->getIdentifier()] = Entry;
2566 CGM.AddUsedGlobal(Entry);
2571 llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
2572 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
2575 // We use the initializer as a marker of whether this is a forward
2576 // reference or not. At module finalization we add the empty
2577 // contents for protocols which were referenced but never defined.
2579 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,
2580 llvm::GlobalValue::ExternalLinkage,
2582 "\01L_OBJC_PROTOCOL_" + PD->getName());
2583 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
2584 // FIXME: Is this necessary? Why only for protocol?
2585 Entry->setAlignment(4);
2592 struct _objc_protocol_extension {
2594 struct objc_method_description_list *optional_instance_methods;
2595 struct objc_method_description_list *optional_class_methods;
2596 struct objc_property_list *instance_properties;
2597 const char ** extendedMethodTypes;
2601 CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
2602 ArrayRef<llvm::Constant*> OptInstanceMethods,
2603 ArrayRef<llvm::Constant*> OptClassMethods,
2604 ArrayRef<llvm::Constant*> MethodTypesExt) {
2606 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
2607 llvm::Constant *Values[] = {
2608 llvm::ConstantInt::get(ObjCTypes.IntTy, Size),
2609 EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_"
2611 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2612 OptInstanceMethods),
2613 EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_" + PD->getName(),
2614 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2616 EmitPropertyList("\01L_OBJC_$_PROP_PROTO_LIST_" + PD->getName(), 0, PD,
2618 EmitProtocolMethodTypes("\01L_OBJC_PROTOCOL_METHOD_TYPES_" + PD->getName(),
2619 MethodTypesExt, ObjCTypes)
2622 // Return null if no extension bits are used.
2623 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
2624 Values[3]->isNullValue() && Values[4]->isNullValue())
2625 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
2627 llvm::Constant *Init =
2628 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
2630 // No special section, but goes in llvm.used
2631 return CreateMetadataVar("\01L_OBJC_PROTOCOLEXT_" + PD->getName(),
2637 struct objc_protocol_list {
2638 struct objc_protocol_list *next;
2644 CGObjCMac::EmitProtocolList(Twine Name,
2645 ObjCProtocolDecl::protocol_iterator begin,
2646 ObjCProtocolDecl::protocol_iterator end) {
2647 llvm::SmallVector<llvm::Constant*, 16> ProtocolRefs;
2649 for (; begin != end; ++begin)
2650 ProtocolRefs.push_back(GetProtocolRef(*begin));
2652 // Just return null for empty protocol lists
2653 if (ProtocolRefs.empty())
2654 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2656 // This list is null terminated.
2657 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
2659 llvm::Constant *Values[3];
2660 // This field is only used by the runtime.
2661 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2662 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy,
2663 ProtocolRefs.size() - 1);
2665 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
2666 ProtocolRefs.size()),
2669 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2670 llvm::GlobalVariable *GV =
2671 CreateMetadataVar(Name, Init, "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2673 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
2676 void CGObjCCommonMac::
2677 PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*,16> &PropertySet,
2678 llvm::SmallVectorImpl<llvm::Constant*> &Properties,
2679 const Decl *Container,
2680 const ObjCProtocolDecl *PROTO,
2681 const ObjCCommonTypesHelper &ObjCTypes) {
2682 for (ObjCProtocolDecl::protocol_iterator P = PROTO->protocol_begin(),
2683 E = PROTO->protocol_end(); P != E; ++P)
2684 PushProtocolProperties(PropertySet, Properties, Container, (*P), ObjCTypes);
2685 for (ObjCContainerDecl::prop_iterator I = PROTO->prop_begin(),
2686 E = PROTO->prop_end(); I != E; ++I) {
2687 const ObjCPropertyDecl *PD = *I;
2688 if (!PropertySet.insert(PD->getIdentifier()))
2690 llvm::Constant *Prop[] = {
2691 GetPropertyName(PD->getIdentifier()),
2692 GetPropertyTypeString(PD, Container)
2694 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop));
2699 struct _objc_property {
2700 const char * const name;
2701 const char * const attributes;
2704 struct _objc_property_list {
2705 uint32_t entsize; // sizeof (struct _objc_property)
2706 uint32_t prop_count;
2707 struct _objc_property[prop_count];
2710 llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,
2711 const Decl *Container,
2712 const ObjCContainerDecl *OCD,
2713 const ObjCCommonTypesHelper &ObjCTypes) {
2714 llvm::SmallVector<llvm::Constant*, 16> Properties;
2715 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
2716 for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(),
2717 E = OCD->prop_end(); I != E; ++I) {
2718 const ObjCPropertyDecl *PD = *I;
2719 PropertySet.insert(PD->getIdentifier());
2720 llvm::Constant *Prop[] = {
2721 GetPropertyName(PD->getIdentifier()),
2722 GetPropertyTypeString(PD, Container)
2724 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
2727 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) {
2728 for (ObjCInterfaceDecl::all_protocol_iterator
2729 P = OID->all_referenced_protocol_begin(),
2730 E = OID->all_referenced_protocol_end(); P != E; ++P)
2731 PushProtocolProperties(PropertySet, Properties, Container, (*P),
2734 else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) {
2735 for (ObjCCategoryDecl::protocol_iterator P = CD->protocol_begin(),
2736 E = CD->protocol_end(); P != E; ++P)
2737 PushProtocolProperties(PropertySet, Properties, Container, (*P),
2741 // Return null for empty list.
2742 if (Properties.empty())
2743 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
2745 unsigned PropertySize =
2746 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.PropertyTy);
2747 llvm::Constant *Values[3];
2748 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
2749 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
2750 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
2752 Values[2] = llvm::ConstantArray::get(AT, Properties);
2753 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2755 llvm::GlobalVariable *GV =
2756 CreateMetadataVar(Name, Init,
2757 (ObjCABI == 2) ? "__DATA, __objc_const" :
2758 "__OBJC,__property,regular,no_dead_strip",
2759 (ObjCABI == 2) ? 8 : 4,
2761 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);
2765 CGObjCCommonMac::EmitProtocolMethodTypes(Twine Name,
2766 ArrayRef<llvm::Constant*> MethodTypes,
2767 const ObjCCommonTypesHelper &ObjCTypes) {
2768 // Return null for empty list.
2769 if (MethodTypes.empty())
2770 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
2772 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
2773 MethodTypes.size());
2774 llvm::Constant *Init = llvm::ConstantArray::get(AT, MethodTypes);
2776 llvm::GlobalVariable *GV =
2777 CreateMetadataVar(Name, Init,
2778 (ObjCABI == 2) ? "__DATA, __objc_const" : 0,
2779 (ObjCABI == 2) ? 8 : 4,
2781 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.Int8PtrPtrTy);
2785 struct objc_method_description_list {
2787 struct objc_method_description list[];
2791 CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
2792 llvm::Constant *Desc[] = {
2793 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
2794 ObjCTypes.SelectorPtrTy),
2795 GetMethodVarType(MD)
2800 return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
2805 CGObjCMac::EmitMethodDescList(Twine Name, const char *Section,
2806 ArrayRef<llvm::Constant*> Methods) {
2807 // Return null for empty list.
2808 if (Methods.empty())
2809 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
2811 llvm::Constant *Values[2];
2812 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
2813 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
2815 Values[1] = llvm::ConstantArray::get(AT, Methods);
2816 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2818 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
2819 return llvm::ConstantExpr::getBitCast(GV,
2820 ObjCTypes.MethodDescriptionListPtrTy);
2824 struct _objc_category {
2825 char *category_name;
2827 struct _objc_method_list *instance_methods;
2828 struct _objc_method_list *class_methods;
2829 struct _objc_protocol_list *protocols;
2830 uint32_t size; // <rdar://4585769>
2831 struct _objc_property_list *instance_properties;
2834 void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
2835 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategoryTy);
2837 // FIXME: This is poor design, the OCD should have a pointer to the category
2838 // decl. Additionally, note that Category can be null for the @implementation
2839 // w/o an @interface case. Sema should just create one for us as it does for
2840 // @implementation so everyone else can live life under a clear blue sky.
2841 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
2842 const ObjCCategoryDecl *Category =
2843 Interface->FindCategoryDeclaration(OCD->getIdentifier());
2845 SmallString<256> ExtName;
2846 llvm::raw_svector_ostream(ExtName) << Interface->getName() << '_'
2849 llvm::SmallVector<llvm::Constant*, 16> InstanceMethods, ClassMethods;
2850 for (ObjCCategoryImplDecl::instmeth_iterator
2851 i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
2852 // Instance methods should always be defined.
2853 InstanceMethods.push_back(GetMethodConstant(*i));
2855 for (ObjCCategoryImplDecl::classmeth_iterator
2856 i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
2857 // Class methods should always be defined.
2858 ClassMethods.push_back(GetMethodConstant(*i));
2861 llvm::Constant *Values[7];
2862 Values[0] = GetClassName(OCD->getIdentifier());
2863 Values[1] = GetClassName(Interface->getIdentifier());
2864 LazySymbols.insert(Interface->getIdentifier());
2866 EmitMethodList("\01L_OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(),
2867 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2870 EmitMethodList("\01L_OBJC_CATEGORY_CLASS_METHODS_" + ExtName.str(),
2871 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2875 EmitProtocolList("\01L_OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
2876 Category->protocol_begin(),
2877 Category->protocol_end());
2879 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2881 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
2883 // If there is no category @interface then there can be no properties.
2885 Values[6] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
2886 OCD, Category, ObjCTypes);
2888 Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
2891 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
2894 llvm::GlobalVariable *GV =
2895 CreateMetadataVar("\01L_OBJC_CATEGORY_" + ExtName.str(), Init,
2896 "__OBJC,__category,regular,no_dead_strip",
2898 DefinedCategories.push_back(GV);
2899 DefinedCategoryNames.insert(ExtName.str());
2900 // method definition entries must be clear for next implementation.
2901 MethodDefinitions.clear();
2904 enum FragileClassFlags {
2905 FragileABI_Class_Factory = 0x00001,
2906 FragileABI_Class_Meta = 0x00002,
2907 FragileABI_Class_HasCXXStructors = 0x02000,
2908 FragileABI_Class_Hidden = 0x20000
2911 enum NonFragileClassFlags {
2912 /// Is a meta-class.
2913 NonFragileABI_Class_Meta = 0x00001,
2915 /// Is a root class.
2916 NonFragileABI_Class_Root = 0x00002,
2918 /// Has a C++ constructor and destructor.
2919 NonFragileABI_Class_HasCXXStructors = 0x00004,
2921 /// Has hidden visibility.
2922 NonFragileABI_Class_Hidden = 0x00010,
2924 /// Has the exception attribute.
2925 NonFragileABI_Class_Exception = 0x00020,
2927 /// (Obsolete) ARC-specific: this class has a .release_ivars method
2928 NonFragileABI_Class_HasIvarReleaser = 0x00040,
2930 /// Class implementation was compiled under ARC.
2931 NonFragileABI_Class_CompiledByARC = 0x00080,
2933 /// Class has non-trivial destructors, but zero-initialization is okay.
2934 NonFragileABI_Class_HasCXXDestructorOnly = 0x00100
2938 struct _objc_class {
2945 struct _objc_ivar_list *ivars;
2946 struct _objc_method_list *methods;
2947 struct _objc_cache *cache;
2948 struct _objc_protocol_list *protocols;
2949 // Objective-C 1.0 extensions (<rdr://4585769>)
2950 const char *ivar_layout;
2951 struct _objc_class_ext *ext;
2954 See EmitClassExtension();
2956 void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
2957 DefinedSymbols.insert(ID->getIdentifier());
2959 std::string ClassName = ID->getNameAsString();
2961 ObjCInterfaceDecl *Interface =
2962 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
2963 llvm::Constant *Protocols =
2964 EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getName(),
2965 Interface->all_referenced_protocol_begin(),
2966 Interface->all_referenced_protocol_end());
2967 unsigned Flags = FragileABI_Class_Factory;
2968 if (ID->hasNonZeroConstructors() || ID->hasDestructors())
2969 Flags |= FragileABI_Class_HasCXXStructors;
2971 CGM.getContext().getASTObjCImplementationLayout(ID).getSize().getQuantity();
2973 // FIXME: Set CXX-structors flag.
2974 if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
2975 Flags |= FragileABI_Class_Hidden;
2977 llvm::SmallVector<llvm::Constant*, 16> InstanceMethods, ClassMethods;
2978 for (ObjCImplementationDecl::instmeth_iterator
2979 i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
2980 // Instance methods should always be defined.
2981 InstanceMethods.push_back(GetMethodConstant(*i));
2983 for (ObjCImplementationDecl::classmeth_iterator
2984 i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
2985 // Class methods should always be defined.
2986 ClassMethods.push_back(GetMethodConstant(*i));
2989 for (ObjCImplementationDecl::propimpl_iterator
2990 i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
2991 ObjCPropertyImplDecl *PID = *i;
2993 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
2994 ObjCPropertyDecl *PD = PID->getPropertyDecl();
2996 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
2997 if (llvm::Constant *C = GetMethodConstant(MD))
2998 InstanceMethods.push_back(C);
2999 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
3000 if (llvm::Constant *C = GetMethodConstant(MD))
3001 InstanceMethods.push_back(C);
3005 llvm::Constant *Values[12];
3006 Values[ 0] = EmitMetaClass(ID, Protocols, ClassMethods);
3007 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
3008 // Record a reference to the super class.
3009 LazySymbols.insert(Super->getIdentifier());
3012 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
3013 ObjCTypes.ClassPtrTy);
3015 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
3017 Values[ 2] = GetClassName(ID->getIdentifier());
3018 // Version is always 0.
3019 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
3020 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
3021 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
3022 Values[ 6] = EmitIvarList(ID, false);
3024 EmitMethodList("\01L_OBJC_INSTANCE_METHODS_" + ID->getName(),
3025 "__OBJC,__inst_meth,regular,no_dead_strip",
3027 // cache is always NULL.
3028 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
3029 Values[ 9] = Protocols;
3030 Values[10] = BuildIvarLayout(ID, true);
3031 Values[11] = EmitClassExtension(ID);
3032 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
3034 std::string Name("\01L_OBJC_CLASS_");
3036 const char *Section = "__OBJC,__class,regular,no_dead_strip";
3037 // Check for a forward reference.
3038 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
3040 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3041 "Forward metaclass reference has incorrect type.");
3042 GV->setLinkage(llvm::GlobalValue::InternalLinkage);
3043 GV->setInitializer(Init);
3044 GV->setSection(Section);
3045 GV->setAlignment(4);
3046 CGM.AddUsedGlobal(GV);
3049 GV = CreateMetadataVar(Name, Init, Section, 4, true);
3050 DefinedClasses.push_back(GV);
3051 // method definition entries must be clear for next implementation.
3052 MethodDefinitions.clear();
3055 llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
3056 llvm::Constant *Protocols,
3057 ArrayRef<llvm::Constant*> Methods) {
3058 unsigned Flags = FragileABI_Class_Meta;
3059 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassTy);
3061 if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
3062 Flags |= FragileABI_Class_Hidden;
3064 llvm::Constant *Values[12];
3065 // The isa for the metaclass is the root of the hierarchy.
3066 const ObjCInterfaceDecl *Root = ID->getClassInterface();
3067 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
3070 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
3071 ObjCTypes.ClassPtrTy);
3072 // The super class for the metaclass is emitted as the name of the
3073 // super class. The runtime fixes this up to point to the
3074 // *metaclass* for the super class.
3075 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
3077 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
3078 ObjCTypes.ClassPtrTy);
3080 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
3082 Values[ 2] = GetClassName(ID->getIdentifier());
3083 // Version is always 0.
3084 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
3085 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
3086 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
3087 Values[ 6] = EmitIvarList(ID, true);
3089 EmitMethodList("\01L_OBJC_CLASS_METHODS_" + ID->getNameAsString(),
3090 "__OBJC,__cls_meth,regular,no_dead_strip",
3092 // cache is always NULL.
3093 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
3094 Values[ 9] = Protocols;
3095 // ivar_layout for metaclass is always NULL.
3096 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
3097 // The class extension is always unused for metaclasses.
3098 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
3099 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
3102 std::string Name("\01L_OBJC_METACLASS_");
3103 Name += ID->getName();
3105 // Check for a forward reference.
3106 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
3108 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3109 "Forward metaclass reference has incorrect type.");
3110 GV->setLinkage(llvm::GlobalValue::InternalLinkage);
3111 GV->setInitializer(Init);
3113 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
3114 llvm::GlobalValue::InternalLinkage,
3117 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
3118 GV->setAlignment(4);
3119 CGM.AddUsedGlobal(GV);
3124 llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
3125 std::string Name = "\01L_OBJC_METACLASS_" + ID->getNameAsString();
3127 // FIXME: Should we look these up somewhere other than the module. Its a bit
3128 // silly since we only generate these while processing an implementation, so
3129 // exactly one pointer would work if know when we entered/exitted an
3130 // implementation block.
3132 // Check for an existing forward reference.
3133 // Previously, metaclass with internal linkage may have been defined.
3134 // pass 'true' as 2nd argument so it is returned.
3135 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name,
3137 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3138 "Forward metaclass reference has incorrect type.");
3141 // Generate as an external reference to keep a consistent
3142 // module. This will be patched up when we emit the metaclass.
3143 return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
3144 llvm::GlobalValue::ExternalLinkage,
3150 llvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) {
3151 std::string Name = "\01L_OBJC_CLASS_" + ID->getNameAsString();
3153 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name,
3155 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3156 "Forward class metadata reference has incorrect type.");
3159 return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
3160 llvm::GlobalValue::ExternalLinkage,
3167 struct objc_class_ext {
3169 const char *weak_ivar_layout;
3170 struct _objc_property_list *properties;
3174 CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
3176 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
3178 llvm::Constant *Values[3];
3179 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
3180 Values[1] = BuildIvarLayout(ID, false);
3181 Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
3182 ID, ID->getClassInterface(), ObjCTypes);
3184 // Return null if no extension bits are used.
3185 if (Values[1]->isNullValue() && Values[2]->isNullValue())
3186 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
3188 llvm::Constant *Init =
3189 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
3190 return CreateMetadataVar("\01L_OBJC_CLASSEXT_" + ID->getName(),
3191 Init, "__OBJC,__class_ext,regular,no_dead_strip",
3202 struct objc_ivar_list {
3204 struct objc_ivar list[count];
3207 llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
3209 std::vector<llvm::Constant*> Ivars;
3211 // When emitting the root class GCC emits ivar entries for the
3212 // actual class structure. It is not clear if we need to follow this
3213 // behavior; for now lets try and get away with not doing it. If so,
3214 // the cleanest solution would be to make up an ObjCInterfaceDecl
3217 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3219 const ObjCInterfaceDecl *OID = ID->getClassInterface();
3221 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
3222 IVD; IVD = IVD->getNextIvar()) {
3223 // Ignore unnamed bit-fields.
3224 if (!IVD->getDeclName())
3226 llvm::Constant *Ivar[] = {
3227 GetMethodVarName(IVD->getIdentifier()),
3228 GetMethodVarType(IVD),
3229 llvm::ConstantInt::get(ObjCTypes.IntTy,
3230 ComputeIvarBaseOffset(CGM, OID, IVD))
3232 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar));
3235 // Return null for empty list.
3237 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3239 llvm::Constant *Values[2];
3240 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
3241 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
3243 Values[1] = llvm::ConstantArray::get(AT, Ivars);
3244 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
3246 llvm::GlobalVariable *GV;
3248 GV = CreateMetadataVar("\01L_OBJC_CLASS_VARIABLES_" + ID->getName(),
3249 Init, "__OBJC,__class_vars,regular,no_dead_strip",
3252 GV = CreateMetadataVar("\01L_OBJC_INSTANCE_VARIABLES_" + ID->getName(),
3253 Init, "__OBJC,__instance_vars,regular,no_dead_strip",
3255 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
3259 struct objc_method {
3265 struct objc_method_list {
3266 struct objc_method_list *obsolete;
3268 struct objc_method methods_list[count];
3272 /// GetMethodConstant - Return a struct objc_method constant for the
3273 /// given method if it has been defined. The result is null if the
3274 /// method has not been defined. The return value has type MethodPtrTy.
3275 llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) {
3276 llvm::Function *Fn = GetMethodDefinition(MD);
3280 llvm::Constant *Method[] = {
3281 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
3282 ObjCTypes.SelectorPtrTy),
3283 GetMethodVarType(MD),
3284 llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy)
3286 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
3289 llvm::Constant *CGObjCMac::EmitMethodList(Twine Name,
3290 const char *Section,
3291 ArrayRef<llvm::Constant*> Methods) {
3292 // Return null for empty list.
3293 if (Methods.empty())
3294 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
3296 llvm::Constant *Values[3];
3297 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
3298 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
3299 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
3301 Values[2] = llvm::ConstantArray::get(AT, Methods);
3302 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
3304 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
3305 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy);
3308 llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,
3309 const ObjCContainerDecl *CD) {
3310 SmallString<256> Name;
3311 GetNameForMethod(OMD, CD, Name);
3313 CodeGenTypes &Types = CGM.getTypes();
3314 llvm::FunctionType *MethodTy =
3315 Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
3316 llvm::Function *Method =
3317 llvm::Function::Create(MethodTy,
3318 llvm::GlobalValue::InternalLinkage,
3321 MethodDefinitions.insert(std::make_pair(OMD, Method));
3326 llvm::GlobalVariable *
3327 CGObjCCommonMac::CreateMetadataVar(Twine Name,
3328 llvm::Constant *Init,
3329 const char *Section,
3332 llvm::Type *Ty = Init->getType();
3333 llvm::GlobalVariable *GV =
3334 new llvm::GlobalVariable(CGM.getModule(), Ty, false,
3335 llvm::GlobalValue::InternalLinkage, Init, Name);
3337 GV->setSection(Section);
3339 GV->setAlignment(Align);
3341 CGM.AddUsedGlobal(GV);
3345 llvm::Function *CGObjCMac::ModuleInitFunction() {
3346 // Abuse this interface function as a place to finalize.
3351 llvm::Constant *CGObjCMac::GetPropertyGetFunction() {
3352 return ObjCTypes.getGetPropertyFn();
3355 llvm::Constant *CGObjCMac::GetPropertySetFunction() {
3356 return ObjCTypes.getSetPropertyFn();
3359 llvm::Constant *CGObjCMac::GetOptimizedPropertySetFunction(bool atomic,
3361 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
3364 llvm::Constant *CGObjCMac::GetGetStructFunction() {
3365 return ObjCTypes.getCopyStructFn();
3367 llvm::Constant *CGObjCMac::GetSetStructFunction() {
3368 return ObjCTypes.getCopyStructFn();
3371 llvm::Constant *CGObjCMac::GetCppAtomicObjectFunction() {
3372 return ObjCTypes.getCppAtomicObjectFunction();
3375 llvm::Constant *CGObjCMac::EnumerationMutationFunction() {
3376 return ObjCTypes.getEnumerationMutationFn();
3379 void CGObjCMac::EmitTryStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S) {
3380 return EmitTryOrSynchronizedStmt(CGF, S);
3383 void CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF,
3384 const ObjCAtSynchronizedStmt &S) {
3385 return EmitTryOrSynchronizedStmt(CGF, S);
3389 struct PerformFragileFinally : EHScopeStack::Cleanup {
3391 llvm::Value *SyncArgSlot;
3392 llvm::Value *CallTryExitVar;
3393 llvm::Value *ExceptionData;
3394 ObjCTypesHelper &ObjCTypes;
3395 PerformFragileFinally(const Stmt *S,
3396 llvm::Value *SyncArgSlot,
3397 llvm::Value *CallTryExitVar,
3398 llvm::Value *ExceptionData,
3399 ObjCTypesHelper *ObjCTypes)
3400 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
3401 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
3403 void Emit(CodeGenFunction &CGF, Flags flags) {
3404 // Check whether we need to call objc_exception_try_exit.
3405 // In optimized code, this branch will always be folded.
3406 llvm::BasicBlock *FinallyCallExit =
3407 CGF.createBasicBlock("finally.call_exit");
3408 llvm::BasicBlock *FinallyNoCallExit =
3409 CGF.createBasicBlock("finally.no_call_exit");
3410 CGF.Builder.CreateCondBr(CGF.Builder.CreateLoad(CallTryExitVar),
3411 FinallyCallExit, FinallyNoCallExit);
3413 CGF.EmitBlock(FinallyCallExit);
3414 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryExitFn(), ExceptionData)
3415 ->setDoesNotThrow();
3417 CGF.EmitBlock(FinallyNoCallExit);
3419 if (isa<ObjCAtTryStmt>(S)) {
3420 if (const ObjCAtFinallyStmt* FinallyStmt =
3421 cast<ObjCAtTryStmt>(S).getFinallyStmt()) {
3422 // Save the current cleanup destination in case there's
3423 // control flow inside the finally statement.
3424 llvm::Value *CurCleanupDest =
3425 CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot());
3427 CGF.EmitStmt(FinallyStmt->getFinallyBody());
3429 if (CGF.HaveInsertPoint()) {
3430 CGF.Builder.CreateStore(CurCleanupDest,
3431 CGF.getNormalCleanupDestSlot());
3433 // Currently, the end of the cleanup must always exist.
3434 CGF.EnsureInsertPoint();
3438 // Emit objc_sync_exit(expr); as finally's sole statement for
3440 llvm::Value *SyncArg = CGF.Builder.CreateLoad(SyncArgSlot);
3441 CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg)
3442 ->setDoesNotThrow();
3447 class FragileHazards {
3448 CodeGenFunction &CGF;
3449 SmallVector<llvm::Value*, 20> Locals;
3450 llvm::DenseSet<llvm::BasicBlock*> BlocksBeforeTry;
3452 llvm::InlineAsm *ReadHazard;
3453 llvm::InlineAsm *WriteHazard;
3455 llvm::FunctionType *GetAsmFnType();
3457 void collectLocals();
3458 void emitReadHazard(CGBuilderTy &Builder);
3461 FragileHazards(CodeGenFunction &CGF);
3463 void emitWriteHazard();
3464 void emitHazardsInNewBlocks();
3468 /// Create the fragile-ABI read and write hazards based on the current
3469 /// state of the function, which is presumed to be immediately prior
3470 /// to a @try block. These hazards are used to maintain correct
3471 /// semantics in the face of optimization and the fragile ABI's
3472 /// cavalier use of setjmp/longjmp.
3473 FragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) {
3476 if (Locals.empty()) return;
3478 // Collect all the blocks in the function.
3479 for (llvm::Function::iterator
3480 I = CGF.CurFn->begin(), E = CGF.CurFn->end(); I != E; ++I)
3481 BlocksBeforeTry.insert(&*I);
3483 llvm::FunctionType *AsmFnTy = GetAsmFnType();
3485 // Create a read hazard for the allocas. This inhibits dead-store
3486 // optimizations and forces the values to memory. This hazard is
3487 // inserted before any 'throwing' calls in the protected scope to
3488 // reflect the possibility that the variables might be read from the
3489 // catch block if the call throws.
3491 std::string Constraint;
3492 for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
3493 if (I) Constraint += ',';
3497 ReadHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
3500 // Create a write hazard for the allocas. This inhibits folding
3501 // loads across the hazard. This hazard is inserted at the
3502 // beginning of the catch path to reflect the possibility that the
3503 // variables might have been written within the protected scope.
3505 std::string Constraint;
3506 for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
3507 if (I) Constraint += ',';
3508 Constraint += "=*m";
3511 WriteHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
3515 /// Emit a write hazard at the current location.
3516 void FragileHazards::emitWriteHazard() {
3517 if (Locals.empty()) return;
3519 CGF.Builder.CreateCall(WriteHazard, Locals)->setDoesNotThrow();
3522 void FragileHazards::emitReadHazard(CGBuilderTy &Builder) {
3523 assert(!Locals.empty());
3524 Builder.CreateCall(ReadHazard, Locals)->setDoesNotThrow();
3527 /// Emit read hazards in all the protected blocks, i.e. all the blocks
3528 /// which have been inserted since the beginning of the try.
3529 void FragileHazards::emitHazardsInNewBlocks() {
3530 if (Locals.empty()) return;
3532 CGBuilderTy Builder(CGF.getLLVMContext());
3534 // Iterate through all blocks, skipping those prior to the try.
3535 for (llvm::Function::iterator
3536 FI = CGF.CurFn->begin(), FE = CGF.CurFn->end(); FI != FE; ++FI) {
3537 llvm::BasicBlock &BB = *FI;
3538 if (BlocksBeforeTry.count(&BB)) continue;
3540 // Walk through all the calls in the block.
3541 for (llvm::BasicBlock::iterator
3542 BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
3543 llvm::Instruction &I = *BI;
3545 // Ignore instructions that aren't non-intrinsic calls.
3546 // These are the only calls that can possibly call longjmp.
3547 if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I)) continue;
3548 if (isa<llvm::IntrinsicInst>(I))
3551 // Ignore call sites marked nounwind. This may be questionable,
3552 // since 'nounwind' doesn't necessarily mean 'does not call longjmp'.
3553 llvm::CallSite CS(&I);
3554 if (CS.doesNotThrow()) continue;
3556 // Insert a read hazard before the call. This will ensure that
3557 // any writes to the locals are performed before making the
3558 // call. If the call throws, then this is sufficient to
3559 // guarantee correctness as long as it doesn't also write to any
3561 Builder.SetInsertPoint(&BB, BI);
3562 emitReadHazard(Builder);
3567 static void addIfPresent(llvm::DenseSet<llvm::Value*> &S, llvm::Value *V) {
3571 void FragileHazards::collectLocals() {
3572 // Compute a set of allocas to ignore.
3573 llvm::DenseSet<llvm::Value*> AllocasToIgnore;
3574 addIfPresent(AllocasToIgnore, CGF.ReturnValue);
3575 addIfPresent(AllocasToIgnore, CGF.NormalCleanupDest);
3577 // Collect all the allocas currently in the function. This is
3578 // probably way too aggressive.
3579 llvm::BasicBlock &Entry = CGF.CurFn->getEntryBlock();
3580 for (llvm::BasicBlock::iterator
3581 I = Entry.begin(), E = Entry.end(); I != E; ++I)
3582 if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
3583 Locals.push_back(&*I);
3586 llvm::FunctionType *FragileHazards::GetAsmFnType() {
3587 SmallVector<llvm::Type *, 16> tys(Locals.size());
3588 for (unsigned i = 0, e = Locals.size(); i != e; ++i)
3589 tys[i] = Locals[i]->getType();
3590 return llvm::FunctionType::get(CGF.VoidTy, tys, false);
3595 Objective-C setjmp-longjmp (sjlj) Exception Handling
3598 A catch buffer is a setjmp buffer plus:
3599 - a pointer to the exception that was caught
3600 - a pointer to the previous exception data buffer
3601 - two pointers of reserved storage
3602 Therefore catch buffers form a stack, with a pointer to the top
3603 of the stack kept in thread-local storage.
3605 objc_exception_try_enter pushes a catch buffer onto the EH stack.
3606 objc_exception_try_exit pops the given catch buffer, which is
3607 required to be the top of the EH stack.
3608 objc_exception_throw pops the top of the EH stack, writes the
3609 thrown exception into the appropriate field, and longjmps
3610 to the setjmp buffer. It crashes the process (with a printf
3611 and an abort()) if there are no catch buffers on the stack.
3612 objc_exception_extract just reads the exception pointer out of the
3615 There's no reason an implementation couldn't use a light-weight
3616 setjmp here --- something like __builtin_setjmp, but API-compatible
3617 with the heavyweight setjmp. This will be more important if we ever
3618 want to implement correct ObjC/C++ exception interactions for the
3621 Note that for this use of setjmp/longjmp to be correct, we may need
3622 to mark some local variables volatile: if a non-volatile local
3623 variable is modified between the setjmp and the longjmp, it has
3624 indeterminate value. For the purposes of LLVM IR, it may be
3625 sufficient to make loads and stores within the @try (to variables
3626 declared outside the @try) volatile. This is necessary for
3627 optimized correctness, but is not currently being done; this is
3628 being tracked as rdar://problem/8160285
3630 The basic framework for a @try-catch-finally is as follows:
3632 objc_exception_data d;
3634 bool _call_try_exit = true;
3636 objc_exception_try_enter(&d);
3637 if (!setjmp(d.jmp_buf)) {
3641 id _caught = objc_exception_extract(&d);
3643 // enter new try scope for handlers
3644 if (!setjmp(d.jmp_buf)) {
3645 ... match exception and execute catch blocks ...
3647 // fell off end, rethrow.
3649 ... jump-through-finally to finally_rethrow ...
3651 // exception in catch block
3652 _rethrow = objc_exception_extract(&d);
3653 _call_try_exit = false;
3654 ... jump-through-finally to finally_rethrow ...
3657 ... jump-through-finally to finally_end ...
3661 objc_exception_try_exit(&d);
3663 ... finally block ....
3664 ... dispatch to finally destination ...
3667 objc_exception_throw(_rethrow);
3672 This framework differs slightly from the one gcc uses, in that gcc
3673 uses _rethrow to determine if objc_exception_try_exit should be called
3674 and if the object should be rethrown. This breaks in the face of
3675 throwing nil and introduces unnecessary branches.
3677 We specialize this framework for a few particular circumstances:
3679 - If there are no catch blocks, then we avoid emitting the second
3680 exception handling context.
3682 - If there is a catch-all catch block (i.e. @catch(...) or @catch(id
3683 e)) we avoid emitting the code to rethrow an uncaught exception.
3685 - FIXME: If there is no @finally block we can do a few more
3688 Rethrows and Jumps-Through-Finally
3691 '@throw;' is supported by pushing the currently-caught exception
3692 onto ObjCEHStack while the @catch blocks are emitted.
3694 Branches through the @finally block are handled with an ordinary
3695 normal cleanup. We do not register an EH cleanup; fragile-ABI ObjC
3696 exceptions are not compatible with C++ exceptions, and this is
3697 hardly the only place where this will go wrong.
3699 @synchronized(expr) { stmt; } is emitted as if it were:
3700 id synch_value = expr;
3701 objc_sync_enter(synch_value);
3702 @try { stmt; } @finally { objc_sync_exit(synch_value); }
3705 void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
3707 bool isTry = isa<ObjCAtTryStmt>(S);
3709 // A destination for the fall-through edges of the catch handlers to
3711 CodeGenFunction::JumpDest FinallyEnd =
3712 CGF.getJumpDestInCurrentScope("finally.end");
3714 // A destination for the rethrow edge of the catch handlers to jump
3716 CodeGenFunction::JumpDest FinallyRethrow =
3717 CGF.getJumpDestInCurrentScope("finally.rethrow");
3719 // For @synchronized, call objc_sync_enter(sync.expr). The
3720 // evaluation of the expression must occur before we enter the
3721 // @synchronized. We can't avoid a temp here because we need the
3722 // value to be preserved. If the backend ever does liveness
3723 // correctly after setjmp, this will be unnecessary.
3724 llvm::Value *SyncArgSlot = 0;
3726 llvm::Value *SyncArg =
3727 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
3728 SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
3729 CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg)
3730 ->setDoesNotThrow();
3732 SyncArgSlot = CGF.CreateTempAlloca(SyncArg->getType(), "sync.arg");
3733 CGF.Builder.CreateStore(SyncArg, SyncArgSlot);
3736 // Allocate memory for the setjmp buffer. This needs to be kept
3737 // live throughout the try and catch blocks.
3738 llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy,
3739 "exceptiondata.ptr");
3741 // Create the fragile hazards. Note that this will not capture any
3742 // of the allocas required for exception processing, but will
3743 // capture the current basic block (which extends all the way to the
3744 // setjmp call) as "before the @try".
3745 FragileHazards Hazards(CGF);
3747 // Create a flag indicating whether the cleanup needs to call
3748 // objc_exception_try_exit. This is true except when
3749 // - no catches match and we're branching through the cleanup
3750 // just to rethrow the exception, or
3751 // - a catch matched and we're falling out of the catch handler.
3752 // The setjmp-safety rule here is that we should always store to this
3753 // variable in a place that dominates the branch through the cleanup
3754 // without passing through any setjmps.
3755 llvm::Value *CallTryExitVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(),
3758 // A slot containing the exception to rethrow. Only needed when we
3759 // have both a @catch and a @finally.
3760 llvm::Value *PropagatingExnVar = 0;
3762 // Push a normal cleanup to leave the try scope.
3763 CGF.EHStack.pushCleanup<PerformFragileFinally>(NormalCleanup, &S,
3769 // Enter a try block:
3770 // - Call objc_exception_try_enter to push ExceptionData on top of
3772 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData)
3773 ->setDoesNotThrow();
3775 // - Call setjmp on the exception data buffer.
3776 llvm::Constant *Zero = llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0);
3777 llvm::Value *GEPIndexes[] = { Zero, Zero, Zero };
3778 llvm::Value *SetJmpBuffer =
3779 CGF.Builder.CreateGEP(ExceptionData, GEPIndexes, "setjmp_buffer");
3780 llvm::CallInst *SetJmpResult =
3781 CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result");
3782 SetJmpResult->setDoesNotThrow();
3783 SetJmpResult->setCanReturnTwice();
3785 // If setjmp returned 0, enter the protected block; otherwise,
3786 // branch to the handler.
3787 llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
3788 llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
3789 llvm::Value *DidCatch =
3790 CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
3791 CGF.Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
3793 // Emit the protected block.
3794 CGF.EmitBlock(TryBlock);
3795 CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
3796 CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
3797 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
3799 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.Builder.saveAndClearIP();
3801 // Emit the exception handler block.
3802 CGF.EmitBlock(TryHandler);
3804 // Don't optimize loads of the in-scope locals across this point.
3805 Hazards.emitWriteHazard();
3807 // For a @synchronized (or a @try with no catches), just branch
3808 // through the cleanup to the rethrow block.
3809 if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
3810 // Tell the cleanup not to re-pop the exit.
3811 CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
3812 CGF.EmitBranchThroughCleanup(FinallyRethrow);
3814 // Otherwise, we have to match against the caught exceptions.
3816 // Retrieve the exception object. We may emit multiple blocks but
3817 // nothing can cross this so the value is already in SSA form.
3818 llvm::CallInst *Caught =
3819 CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
3820 ExceptionData, "caught");
3821 Caught->setDoesNotThrow();
3823 // Push the exception to rethrow onto the EH value stack for the
3824 // benefit of any @throws in the handlers.
3825 CGF.ObjCEHValueStack.push_back(Caught);
3827 const ObjCAtTryStmt* AtTryStmt = cast<ObjCAtTryStmt>(&S);
3829 bool HasFinally = (AtTryStmt->getFinallyStmt() != 0);
3831 llvm::BasicBlock *CatchBlock = 0;
3832 llvm::BasicBlock *CatchHandler = 0;
3834 // Save the currently-propagating exception before
3835 // objc_exception_try_enter clears the exception slot.
3836 PropagatingExnVar = CGF.CreateTempAlloca(Caught->getType(),
3837 "propagating_exception");
3838 CGF.Builder.CreateStore(Caught, PropagatingExnVar);
3840 // Enter a new exception try block (in case a @catch block
3841 // throws an exception).
3842 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData)
3843 ->setDoesNotThrow();
3845 llvm::CallInst *SetJmpResult =
3846 CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer,
3848 SetJmpResult->setDoesNotThrow();
3849 SetJmpResult->setCanReturnTwice();
3851 llvm::Value *Threw =
3852 CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
3854 CatchBlock = CGF.createBasicBlock("catch");
3855 CatchHandler = CGF.createBasicBlock("catch_for_catch");
3856 CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
3858 CGF.EmitBlock(CatchBlock);
3861 CGF.Builder.CreateStore(CGF.Builder.getInt1(HasFinally), CallTryExitVar);
3863 // Handle catch list. As a special case we check if everything is
3864 // matched and avoid generating code for falling off the end if
3866 bool AllMatched = false;
3867 for (unsigned I = 0, N = AtTryStmt->getNumCatchStmts(); I != N; ++I) {
3868 const ObjCAtCatchStmt *CatchStmt = AtTryStmt->getCatchStmt(I);
3870 const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
3871 const ObjCObjectPointerType *OPT = 0;
3873 // catch(...) always matches.
3877 OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>();
3879 // catch(id e) always matches under this ABI, since only
3880 // ObjC exceptions end up here in the first place.
3881 // FIXME: For the time being we also match id<X>; this should
3882 // be rejected by Sema instead.
3883 if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()))
3887 // If this is a catch-all, we don't need to test anything.
3889 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
3892 CGF.EmitAutoVarDecl(*CatchParam);
3893 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
3895 // These types work out because ConvertType(id) == i8*.
3896 CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(CatchParam));
3899 CGF.EmitStmt(CatchStmt->getCatchBody());
3901 // The scope of the catch variable ends right here.
3902 CatchVarCleanups.ForceCleanup();
3904 CGF.EmitBranchThroughCleanup(FinallyEnd);
3908 assert(OPT && "Unexpected non-object pointer type in @catch");
3909 const ObjCObjectType *ObjTy = OPT->getObjectType();
3911 // FIXME: @catch (Class c) ?
3912 ObjCInterfaceDecl *IDecl = ObjTy->getInterface();
3913 assert(IDecl && "Catch parameter must have Objective-C type!");
3915 // Check if the @catch block matches the exception object.
3916 llvm::Value *Class = EmitClassRef(CGF.Builder, IDecl);
3918 llvm::CallInst *Match =
3919 CGF.Builder.CreateCall2(ObjCTypes.getExceptionMatchFn(),
3920 Class, Caught, "match");
3921 Match->setDoesNotThrow();
3923 llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("match");
3924 llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch.next");
3926 CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"),
3927 MatchedBlock, NextCatchBlock);
3929 // Emit the @catch block.
3930 CGF.EmitBlock(MatchedBlock);
3932 // Collect any cleanups for the catch variable. The scope lasts until
3933 // the end of the catch body.
3934 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
3936 CGF.EmitAutoVarDecl(*CatchParam);
3937 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
3939 // Initialize the catch variable.
3941 CGF.Builder.CreateBitCast(Caught,
3942 CGF.ConvertType(CatchParam->getType()));
3943 CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(CatchParam));
3945 CGF.EmitStmt(CatchStmt->getCatchBody());
3947 // We're done with the catch variable.
3948 CatchVarCleanups.ForceCleanup();
3950 CGF.EmitBranchThroughCleanup(FinallyEnd);
3952 CGF.EmitBlock(NextCatchBlock);
3955 CGF.ObjCEHValueStack.pop_back();
3957 // If nothing wanted anything to do with the caught exception,
3958 // kill the extract call.
3959 if (Caught->use_empty())
3960 Caught->eraseFromParent();
3963 CGF.EmitBranchThroughCleanup(FinallyRethrow);
3966 // Emit the exception handler for the @catch blocks.
3967 CGF.EmitBlock(CatchHandler);
3969 // In theory we might now need a write hazard, but actually it's
3970 // unnecessary because there's no local-accessing code between
3971 // the try's write hazard and here.
3972 //Hazards.emitWriteHazard();
3974 // Extract the new exception and save it to the
3975 // propagating-exception slot.
3976 assert(PropagatingExnVar);
3977 llvm::CallInst *NewCaught =
3978 CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
3979 ExceptionData, "caught");
3980 NewCaught->setDoesNotThrow();
3981 CGF.Builder.CreateStore(NewCaught, PropagatingExnVar);
3983 // Don't pop the catch handler; the throw already did.
3984 CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
3985 CGF.EmitBranchThroughCleanup(FinallyRethrow);
3989 // Insert read hazards as required in the new blocks.
3990 Hazards.emitHazardsInNewBlocks();
3993 CGF.Builder.restoreIP(TryFallthroughIP);
3994 if (CGF.HaveInsertPoint())
3995 CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
3996 CGF.PopCleanupBlock();
3997 CGF.EmitBlock(FinallyEnd.getBlock(), true);
3999 // Emit the rethrow block.
4000 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
4001 CGF.EmitBlock(FinallyRethrow.getBlock(), true);
4002 if (CGF.HaveInsertPoint()) {
4003 // If we have a propagating-exception variable, check it.
4004 llvm::Value *PropagatingExn;
4005 if (PropagatingExnVar) {
4006 PropagatingExn = CGF.Builder.CreateLoad(PropagatingExnVar);
4008 // Otherwise, just look in the buffer for the exception to throw.
4010 llvm::CallInst *Caught =
4011 CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
4013 Caught->setDoesNotThrow();
4014 PropagatingExn = Caught;
4017 CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), PropagatingExn)
4018 ->setDoesNotThrow();
4019 CGF.Builder.CreateUnreachable();
4022 CGF.Builder.restoreIP(SavedIP);
4025 void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
4026 const ObjCAtThrowStmt &S) {
4027 llvm::Value *ExceptionAsObject;
4029 if (const Expr *ThrowExpr = S.getThrowExpr()) {
4030 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
4032 CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
4034 assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
4035 "Unexpected rethrow outside @catch block.");
4036 ExceptionAsObject = CGF.ObjCEHValueStack.back();
4039 CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
4040 ->setDoesNotReturn();
4041 CGF.Builder.CreateUnreachable();
4043 // Clear the insertion point to indicate we are in unreachable code.
4044 CGF.Builder.ClearInsertionPoint();
4047 /// EmitObjCWeakRead - Code gen for loading value of a __weak
4048 /// object: objc_read_weak (id *src)
4050 llvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
4051 llvm::Value *AddrWeakObj) {
4052 llvm::Type* DestTy =
4053 cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
4054 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj,
4055 ObjCTypes.PtrObjectPtrTy);
4056 llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(),
4057 AddrWeakObj, "weakread");
4058 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
4062 /// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
4063 /// objc_assign_weak (id src, id *dst)
4065 void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
4066 llvm::Value *src, llvm::Value *dst) {
4067 llvm::Type * SrcTy = src->getType();
4068 if (!isa<llvm::PointerType>(SrcTy)) {
4069 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4070 assert(Size <= 8 && "does not support size > 8");
4071 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4072 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4073 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4075 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4076 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4077 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(),
4078 src, dst, "weakassign");
4082 /// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
4083 /// objc_assign_global (id src, id *dst)
4085 void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
4086 llvm::Value *src, llvm::Value *dst,
4088 llvm::Type * SrcTy = src->getType();
4089 if (!isa<llvm::PointerType>(SrcTy)) {
4090 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4091 assert(Size <= 8 && "does not support size > 8");
4092 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4093 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4094 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4096 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4097 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4099 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(),
4100 src, dst, "globalassign");
4102 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(),
4103 src, dst, "threadlocalassign");
4107 /// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
4108 /// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset)
4110 void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
4111 llvm::Value *src, llvm::Value *dst,
4112 llvm::Value *ivarOffset) {
4113 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL");
4114 llvm::Type * SrcTy = src->getType();
4115 if (!isa<llvm::PointerType>(SrcTy)) {
4116 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4117 assert(Size <= 8 && "does not support size > 8");
4118 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4119 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4120 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4122 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4123 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4124 CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(),
4125 src, dst, ivarOffset);
4129 /// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
4130 /// objc_assign_strongCast (id src, id *dst)
4132 void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
4133 llvm::Value *src, llvm::Value *dst) {
4134 llvm::Type * SrcTy = src->getType();
4135 if (!isa<llvm::PointerType>(SrcTy)) {
4136 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4137 assert(Size <= 8 && "does not support size > 8");
4138 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4139 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4140 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4142 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4143 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4144 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(),
4145 src, dst, "weakassign");
4149 void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
4150 llvm::Value *DestPtr,
4151 llvm::Value *SrcPtr,
4152 llvm::Value *size) {
4153 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
4154 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
4155 CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(),
4156 DestPtr, SrcPtr, size);
4160 /// EmitObjCValueForIvar - Code Gen for ivar reference.
4162 LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
4164 llvm::Value *BaseValue,
4165 const ObjCIvarDecl *Ivar,
4166 unsigned CVRQualifiers) {
4167 const ObjCInterfaceDecl *ID =
4168 ObjectTy->getAs<ObjCObjectType>()->getInterface();
4169 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4170 EmitIvarOffset(CGF, ID, Ivar));
4173 llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
4174 const ObjCInterfaceDecl *Interface,
4175 const ObjCIvarDecl *Ivar) {
4176 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
4177 return llvm::ConstantInt::get(
4178 CGM.getTypes().ConvertType(CGM.getContext().LongTy),
4182 /* *** Private Interface *** */
4184 /// EmitImageInfo - Emit the image info marker used to encode some module
4185 /// level information.
4187 /// See: <rdr://4810609&4810587&4810587>
4188 /// struct IMAGE_INFO {
4189 /// unsigned version;
4192 enum ImageInfoFlags {
4193 eImageInfo_FixAndContinue = (1 << 0),
4194 eImageInfo_GarbageCollected = (1 << 1),
4195 eImageInfo_GCOnly = (1 << 2),
4196 eImageInfo_OptimizedByDyld = (1 << 3), // FIXME: When is this set.
4198 // A flag indicating that the module has no instances of a @synthesize of a
4199 // superclass variable. <rdar://problem/6803242>
4200 eImageInfo_CorrectedSynthesize = (1 << 4),
4201 eImageInfo_ImageIsSimulated = (1 << 5)
4204 void CGObjCCommonMac::EmitImageInfo() {
4205 unsigned version = 0; // Version is unused?
4206 const char *Section = (ObjCABI == 1) ?
4207 "__OBJC, __image_info,regular" :
4208 "__DATA, __objc_imageinfo, regular, no_dead_strip";
4210 // Generate module-level named metadata to convey this information to the
4211 // linker and code-gen.
4212 llvm::Module &Mod = CGM.getModule();
4214 // Add the ObjC ABI version to the module flags.
4215 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version", ObjCABI);
4216 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version",
4218 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section",
4219 llvm::MDString::get(VMContext,Section));
4221 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
4222 // Non-GC overrides those files which specify GC.
4223 Mod.addModuleFlag(llvm::Module::Override,
4224 "Objective-C Garbage Collection", (uint32_t)0);
4226 // Add the ObjC garbage collection value.
4227 Mod.addModuleFlag(llvm::Module::Error,
4228 "Objective-C Garbage Collection",
4229 eImageInfo_GarbageCollected);
4231 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
4232 // Add the ObjC GC Only value.
4233 Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only",
4236 // Require that GC be specified and set to eImageInfo_GarbageCollected.
4237 llvm::Value *Ops[2] = {
4238 llvm::MDString::get(VMContext, "Objective-C Garbage Collection"),
4239 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
4240 eImageInfo_GarbageCollected)
4242 Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only",
4243 llvm::MDNode::get(VMContext, Ops));
4247 // Indicate whether we're compiling this to run on a simulator.
4248 const llvm::Triple &Triple = CGM.getTarget().getTriple();
4249 if (Triple.getOS() == llvm::Triple::IOS &&
4250 (Triple.getArch() == llvm::Triple::x86 ||
4251 Triple.getArch() == llvm::Triple::x86_64))
4252 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated",
4253 eImageInfo_ImageIsSimulated);
4256 // struct objc_module {
4257 // unsigned long version;
4258 // unsigned long size;
4259 // const char *name;
4263 // FIXME: Get from somewhere
4264 static const int ModuleVersion = 7;
4266 void CGObjCMac::EmitModuleInfo() {
4267 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy);
4269 llvm::Constant *Values[] = {
4270 llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion),
4271 llvm::ConstantInt::get(ObjCTypes.LongTy, Size),
4272 // This used to be the filename, now it is unused. <rdr://4327263>
4273 GetClassName(&CGM.getContext().Idents.get("")),
4276 CreateMetadataVar("\01L_OBJC_MODULES",
4277 llvm::ConstantStruct::get(ObjCTypes.ModuleTy, Values),
4278 "__OBJC,__module_info,regular,no_dead_strip",
4282 llvm::Constant *CGObjCMac::EmitModuleSymbols() {
4283 unsigned NumClasses = DefinedClasses.size();
4284 unsigned NumCategories = DefinedCategories.size();
4286 // Return null if no symbols were defined.
4287 if (!NumClasses && !NumCategories)
4288 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
4290 llvm::Constant *Values[5];
4291 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
4292 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
4293 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
4294 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
4296 // The runtime expects exactly the list of defined classes followed
4297 // by the list of defined categories, in a single array.
4298 SmallVector<llvm::Constant*, 8> Symbols(NumClasses + NumCategories);
4299 for (unsigned i=0; i<NumClasses; i++)
4300 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
4301 ObjCTypes.Int8PtrTy);
4302 for (unsigned i=0; i<NumCategories; i++)
4303 Symbols[NumClasses + i] =
4304 llvm::ConstantExpr::getBitCast(DefinedCategories[i],
4305 ObjCTypes.Int8PtrTy);
4308 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
4312 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
4314 llvm::GlobalVariable *GV =
4315 CreateMetadataVar("\01L_OBJC_SYMBOLS", Init,
4316 "__OBJC,__symbols,regular,no_dead_strip",
4318 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
4321 llvm::Value *CGObjCMac::EmitClassRefFromId(CGBuilderTy &Builder,
4322 IdentifierInfo *II) {
4323 LazySymbols.insert(II);
4325 llvm::GlobalVariable *&Entry = ClassReferences[II];
4328 llvm::Constant *Casted =
4329 llvm::ConstantExpr::getBitCast(GetClassName(II),
4330 ObjCTypes.ClassPtrTy);
4332 CreateMetadataVar("\01L_OBJC_CLASS_REFERENCES_", Casted,
4333 "__OBJC,__cls_refs,literal_pointers,no_dead_strip",
4337 return Builder.CreateLoad(Entry);
4340 llvm::Value *CGObjCMac::EmitClassRef(CGBuilderTy &Builder,
4341 const ObjCInterfaceDecl *ID) {
4342 return EmitClassRefFromId(Builder, ID->getIdentifier());
4345 llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder) {
4346 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
4347 return EmitClassRefFromId(Builder, II);
4350 llvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel,
4352 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
4355 llvm::Constant *Casted =
4356 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
4357 ObjCTypes.SelectorPtrTy);
4359 CreateMetadataVar("\01L_OBJC_SELECTOR_REFERENCES_", Casted,
4360 "__OBJC,__message_refs,literal_pointers,no_dead_strip",
4366 return Builder.CreateLoad(Entry);
4369 llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) {
4370 llvm::GlobalVariable *&Entry = ClassNames[Ident];
4373 Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
4374 llvm::ConstantDataArray::getString(VMContext,
4375 Ident->getNameStart()),
4377 "__TEXT,__objc_classname,cstring_literals" :
4378 "__TEXT,__cstring,cstring_literals"),
4381 return getConstantGEP(VMContext, Entry, 0, 0);
4384 llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
4385 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator
4386 I = MethodDefinitions.find(MD);
4387 if (I != MethodDefinitions.end())
4393 /// GetIvarLayoutName - Returns a unique constant for the given
4394 /// ivar layout bitmap.
4395 llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
4396 const ObjCCommonTypesHelper &ObjCTypes) {
4397 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
4400 void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT,
4401 unsigned int BytePos,
4402 bool ForStrongLayout,
4404 const RecordDecl *RD = RT->getDecl();
4405 // FIXME - Use iterator.
4406 SmallVector<const FieldDecl*, 16> Fields;
4407 for (RecordDecl::field_iterator i = RD->field_begin(),
4408 e = RD->field_end(); i != e; ++i)
4409 Fields.push_back(*i);
4410 llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
4411 const llvm::StructLayout *RecLayout =
4412 CGM.getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
4414 BuildAggrIvarLayout(0, RecLayout, RD, Fields, BytePos,
4415 ForStrongLayout, HasUnion);
4418 void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
4419 const llvm::StructLayout *Layout,
4420 const RecordDecl *RD,
4421 ArrayRef<const FieldDecl*> RecFields,
4422 unsigned int BytePos, bool ForStrongLayout,
4424 bool IsUnion = (RD && RD->isUnion());
4425 uint64_t MaxUnionIvarSize = 0;
4426 uint64_t MaxSkippedUnionIvarSize = 0;
4427 const FieldDecl *MaxField = 0;
4428 const FieldDecl *MaxSkippedField = 0;
4429 const FieldDecl *LastFieldBitfieldOrUnnamed = 0;
4430 uint64_t MaxFieldOffset = 0;
4431 uint64_t MaxSkippedFieldOffset = 0;
4432 uint64_t LastBitfieldOrUnnamedOffset = 0;
4433 uint64_t FirstFieldDelta = 0;
4435 if (RecFields.empty())
4437 unsigned WordSizeInBits = CGM.getContext().getTargetInfo().getPointerWidth(0);
4438 unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth();
4439 if (!RD && CGM.getLangOpts().ObjCAutoRefCount) {
4440 const FieldDecl *FirstField = RecFields[0];
4442 ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(FirstField));
4445 for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
4446 const FieldDecl *Field = RecFields[i];
4447 uint64_t FieldOffset;
4449 // Note that 'i' here is actually the field index inside RD of Field,
4450 // although this dependency is hidden.
4451 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4452 FieldOffset = (RL.getFieldOffset(i) / ByteSizeInBits) - FirstFieldDelta;
4455 ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field)) - FirstFieldDelta;
4457 // Skip over unnamed or bitfields
4458 if (!Field->getIdentifier() || Field->isBitField()) {
4459 LastFieldBitfieldOrUnnamed = Field;
4460 LastBitfieldOrUnnamedOffset = FieldOffset;
4464 LastFieldBitfieldOrUnnamed = 0;
4465 QualType FQT = Field->getType();
4466 if (FQT->isRecordType() || FQT->isUnionType()) {
4467 if (FQT->isUnionType())
4470 BuildAggrIvarRecordLayout(FQT->getAs<RecordType>(),
4471 BytePos + FieldOffset,
4472 ForStrongLayout, HasUnion);
4476 if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
4477 const ConstantArrayType *CArray =
4478 dyn_cast_or_null<ConstantArrayType>(Array);
4479 uint64_t ElCount = CArray->getSize().getZExtValue();
4480 assert(CArray && "only array with known element size is supported");
4481 FQT = CArray->getElementType();
4482 while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
4483 const ConstantArrayType *CArray =
4484 dyn_cast_or_null<ConstantArrayType>(Array);
4485 ElCount *= CArray->getSize().getZExtValue();
4486 FQT = CArray->getElementType();
4489 assert(!FQT->isUnionType() &&
4490 "layout for array of unions not supported");
4491 if (FQT->isRecordType() && ElCount) {
4492 int OldIndex = IvarsInfo.size() - 1;
4493 int OldSkIndex = SkipIvars.size() -1;
4495 const RecordType *RT = FQT->getAs<RecordType>();
4496 BuildAggrIvarRecordLayout(RT, BytePos + FieldOffset,
4497 ForStrongLayout, HasUnion);
4499 // Replicate layout information for each array element. Note that
4500 // one element is already done.
4502 for (int FirstIndex = IvarsInfo.size() - 1,
4503 FirstSkIndex = SkipIvars.size() - 1 ;ElIx < ElCount; ElIx++) {
4504 uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits;
4505 for (int i = OldIndex+1; i <= FirstIndex; ++i)
4506 IvarsInfo.push_back(GC_IVAR(IvarsInfo[i].ivar_bytepos + Size*ElIx,
4507 IvarsInfo[i].ivar_size));
4508 for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i)
4509 SkipIvars.push_back(GC_IVAR(SkipIvars[i].ivar_bytepos + Size*ElIx,
4510 SkipIvars[i].ivar_size));
4515 // At this point, we are done with Record/Union and array there of.
4516 // For other arrays we are down to its element type.
4517 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT);
4519 unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType());
4520 if ((ForStrongLayout && GCAttr == Qualifiers::Strong)
4521 || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
4523 uint64_t UnionIvarSize = FieldSize / WordSizeInBits;
4524 if (UnionIvarSize > MaxUnionIvarSize) {
4525 MaxUnionIvarSize = UnionIvarSize;
4527 MaxFieldOffset = FieldOffset;
4530 IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset,
4531 FieldSize / WordSizeInBits));
4533 } else if ((ForStrongLayout &&
4534 (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak))
4535 || (!ForStrongLayout && GCAttr != Qualifiers::Weak)) {
4537 // FIXME: Why the asymmetry? We divide by word size in bits on other
4539 uint64_t UnionIvarSize = FieldSize / ByteSizeInBits;
4540 if (UnionIvarSize > MaxSkippedUnionIvarSize) {
4541 MaxSkippedUnionIvarSize = UnionIvarSize;
4542 MaxSkippedField = Field;
4543 MaxSkippedFieldOffset = FieldOffset;
4546 // FIXME: Why the asymmetry, we divide by byte size in bits here?
4547 SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset,
4548 FieldSize / ByteSizeInBits));
4553 if (LastFieldBitfieldOrUnnamed) {
4554 if (LastFieldBitfieldOrUnnamed->isBitField()) {
4555 // Last field was a bitfield. Must update skip info.
4556 uint64_t BitFieldSize
4557 = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext());
4559 skivar.ivar_bytepos = BytePos + LastBitfieldOrUnnamedOffset;
4560 skivar.ivar_size = (BitFieldSize / ByteSizeInBits)
4561 + ((BitFieldSize % ByteSizeInBits) != 0);
4562 SkipIvars.push_back(skivar);
4564 assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed");
4565 // Last field was unnamed. Must update skip info.
4567 = CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType());
4568 SkipIvars.push_back(GC_IVAR(BytePos + LastBitfieldOrUnnamedOffset,
4569 FieldSize / ByteSizeInBits));
4574 IvarsInfo.push_back(GC_IVAR(BytePos + MaxFieldOffset,
4576 if (MaxSkippedField)
4577 SkipIvars.push_back(GC_IVAR(BytePos + MaxSkippedFieldOffset,
4578 MaxSkippedUnionIvarSize));
4581 /// BuildIvarLayoutBitmap - This routine is the horsework for doing all
4582 /// the computations and returning the layout bitmap (for ivar or blocks) in
4583 /// the given argument BitMap string container. Routine reads
4584 /// two containers, IvarsInfo and SkipIvars which are assumed to be
4585 /// filled already by the caller.
4586 llvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string &BitMap) {
4587 unsigned int WordsToScan, WordsToSkip;
4588 llvm::Type *PtrTy = CGM.Int8PtrTy;
4590 // Build the string of skip/scan nibbles
4591 SmallVector<SKIP_SCAN, 32> SkipScanIvars;
4592 unsigned int WordSize =
4593 CGM.getTypes().getDataLayout().getTypeAllocSize(PtrTy);
4594 if (IvarsInfo[0].ivar_bytepos == 0) {
4596 WordsToScan = IvarsInfo[0].ivar_size;
4598 WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize;
4599 WordsToScan = IvarsInfo[0].ivar_size;
4601 for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++) {
4602 unsigned int TailPrevGCObjC =
4603 IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize;
4604 if (IvarsInfo[i].ivar_bytepos == TailPrevGCObjC) {
4605 // consecutive 'scanned' object pointers.
4606 WordsToScan += IvarsInfo[i].ivar_size;
4608 // Skip over 'gc'able object pointer which lay over each other.
4609 if (TailPrevGCObjC > IvarsInfo[i].ivar_bytepos)
4611 // Must skip over 1 or more words. We save current skip/scan values
4612 // and start a new pair.
4614 SkScan.skip = WordsToSkip;
4615 SkScan.scan = WordsToScan;
4616 SkipScanIvars.push_back(SkScan);
4619 SkScan.skip = (IvarsInfo[i].ivar_bytepos - TailPrevGCObjC) / WordSize;
4621 SkipScanIvars.push_back(SkScan);
4623 WordsToScan = IvarsInfo[i].ivar_size;
4626 if (WordsToScan > 0) {
4628 SkScan.skip = WordsToSkip;
4629 SkScan.scan = WordsToScan;
4630 SkipScanIvars.push_back(SkScan);
4633 if (!SkipIvars.empty()) {
4634 unsigned int LastIndex = SkipIvars.size()-1;
4635 int LastByteSkipped =
4636 SkipIvars[LastIndex].ivar_bytepos + SkipIvars[LastIndex].ivar_size;
4637 LastIndex = IvarsInfo.size()-1;
4638 int LastByteScanned =
4639 IvarsInfo[LastIndex].ivar_bytepos +
4640 IvarsInfo[LastIndex].ivar_size * WordSize;
4641 // Compute number of bytes to skip at the tail end of the last ivar scanned.
4642 if (LastByteSkipped > LastByteScanned) {
4643 unsigned int TotalWords = (LastByteSkipped + (WordSize -1)) / WordSize;
4645 SkScan.skip = TotalWords - (LastByteScanned/WordSize);
4647 SkipScanIvars.push_back(SkScan);
4650 // Mini optimization of nibbles such that an 0xM0 followed by 0x0N is produced
4652 int SkipScan = SkipScanIvars.size()-1;
4653 for (int i = 0; i <= SkipScan; i++) {
4654 if ((i < SkipScan) && SkipScanIvars[i].skip && SkipScanIvars[i].scan == 0
4655 && SkipScanIvars[i+1].skip == 0 && SkipScanIvars[i+1].scan) {
4656 // 0xM0 followed by 0x0N detected.
4657 SkipScanIvars[i].scan = SkipScanIvars[i+1].scan;
4658 for (int j = i+1; j < SkipScan; j++)
4659 SkipScanIvars[j] = SkipScanIvars[j+1];
4664 // Generate the string.
4665 for (int i = 0; i <= SkipScan; i++) {
4667 unsigned int skip_small = SkipScanIvars[i].skip % 0xf;
4668 unsigned int scan_small = SkipScanIvars[i].scan % 0xf;
4669 unsigned int skip_big = SkipScanIvars[i].skip / 0xf;
4670 unsigned int scan_big = SkipScanIvars[i].scan / 0xf;
4673 for (unsigned int ix = 0; ix < skip_big; ix++)
4674 BitMap += (unsigned char)(0xf0);
4676 // next (skip small, scan)
4678 byte = skip_small << 4;
4682 } else if (scan_small) {
4689 for (unsigned int ix = 0; ix < scan_big; ix++)
4690 BitMap += (unsigned char)(0x0f);
4697 // null terminate string.
4698 unsigned char zero = 0;
4701 llvm::GlobalVariable * Entry =
4702 CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
4703 llvm::ConstantDataArray::getString(VMContext, BitMap,false),
4705 "__TEXT,__objc_classname,cstring_literals" :
4706 "__TEXT,__cstring,cstring_literals"),
4708 return getConstantGEP(VMContext, Entry, 0, 0);
4711 /// BuildIvarLayout - Builds ivar layout bitmap for the class
4712 /// implementation for the __strong or __weak case.
4713 /// The layout map displays which words in ivar list must be skipped
4714 /// and which must be scanned by GC (see below). String is built of bytes.
4715 /// Each byte is divided up in two nibbles (4-bit each). Left nibble is count
4716 /// of words to skip and right nibble is count of words to scan. So, each
4717 /// nibble represents up to 15 workds to skip or scan. Skipping the rest is
4718 /// represented by a 0x00 byte which also ends the string.
4719 /// 1. when ForStrongLayout is true, following ivars are scanned:
4722 /// - __strong anything
4724 /// 2. When ForStrongLayout is false, following ivars are scanned:
4725 /// - __weak anything
4727 llvm::Constant *CGObjCCommonMac::BuildIvarLayout(
4728 const ObjCImplementationDecl *OMD,
4729 bool ForStrongLayout) {
4730 bool hasUnion = false;
4732 llvm::Type *PtrTy = CGM.Int8PtrTy;
4733 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
4734 !CGM.getLangOpts().ObjCAutoRefCount)
4735 return llvm::Constant::getNullValue(PtrTy);
4737 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
4738 SmallVector<const FieldDecl*, 32> RecFields;
4739 if (CGM.getLangOpts().ObjCAutoRefCount) {
4740 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
4741 IVD; IVD = IVD->getNextIvar())
4742 RecFields.push_back(cast<FieldDecl>(IVD));
4745 SmallVector<const ObjCIvarDecl*, 32> Ivars;
4746 CGM.getContext().DeepCollectObjCIvars(OI, true, Ivars);
4748 // FIXME: This is not ideal; we shouldn't have to do this copy.
4749 RecFields.append(Ivars.begin(), Ivars.end());
4752 if (RecFields.empty())
4753 return llvm::Constant::getNullValue(PtrTy);
4758 BuildAggrIvarLayout(OMD, 0, 0, RecFields, 0, ForStrongLayout, hasUnion);
4759 if (IvarsInfo.empty())
4760 return llvm::Constant::getNullValue(PtrTy);
4761 // Sort on byte position in case we encounterred a union nested in
4763 if (hasUnion && !IvarsInfo.empty())
4764 std::sort(IvarsInfo.begin(), IvarsInfo.end());
4765 if (hasUnion && !SkipIvars.empty())
4766 std::sort(SkipIvars.begin(), SkipIvars.end());
4769 llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
4771 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
4772 printf("\n%s ivar layout for class '%s': ",
4773 ForStrongLayout ? "strong" : "weak",
4774 OMD->getClassInterface()->getName().data());
4775 const unsigned char *s = (const unsigned char*)BitMap.c_str();
4776 for (unsigned i = 0, e = BitMap.size(); i < e; i++)
4778 printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
4780 printf("0x%x%s", s[i], s[i] != 0 ? ", " : "");
4786 llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
4787 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
4789 // FIXME: Avoid std::string in "Sel.getAsString()"
4791 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_NAME_",
4792 llvm::ConstantDataArray::getString(VMContext, Sel.getAsString()),
4794 "__TEXT,__objc_methname,cstring_literals" :
4795 "__TEXT,__cstring,cstring_literals"),
4798 return getConstantGEP(VMContext, Entry, 0, 0);
4801 // FIXME: Merge into a single cstring creation function.
4802 llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
4803 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
4806 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
4807 std::string TypeStr;
4808 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
4810 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
4813 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_",
4814 llvm::ConstantDataArray::getString(VMContext, TypeStr),
4816 "__TEXT,__objc_methtype,cstring_literals" :
4817 "__TEXT,__cstring,cstring_literals"),
4820 return getConstantGEP(VMContext, Entry, 0, 0);
4823 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
4825 std::string TypeStr;
4826 if (CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr, Extended))
4829 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
4832 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_",
4833 llvm::ConstantDataArray::getString(VMContext, TypeStr),
4835 "__TEXT,__objc_methtype,cstring_literals" :
4836 "__TEXT,__cstring,cstring_literals"),
4839 return getConstantGEP(VMContext, Entry, 0, 0);
4842 // FIXME: Merge into a single cstring creation function.
4843 llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
4844 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
4847 Entry = CreateMetadataVar("\01L_OBJC_PROP_NAME_ATTR_",
4848 llvm::ConstantDataArray::getString(VMContext,
4849 Ident->getNameStart()),
4850 "__TEXT,__cstring,cstring_literals",
4853 return getConstantGEP(VMContext, Entry, 0, 0);
4856 // FIXME: Merge into a single cstring creation function.
4857 // FIXME: This Decl should be more precise.
4859 CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
4860 const Decl *Container) {
4861 std::string TypeStr;
4862 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
4863 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
4866 void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D,
4867 const ObjCContainerDecl *CD,
4868 SmallVectorImpl<char> &Name) {
4869 llvm::raw_svector_ostream OS(Name);
4870 assert (CD && "Missing container decl in GetNameForMethod");
4871 OS << '\01' << (D->isInstanceMethod() ? '-' : '+')
4872 << '[' << CD->getName();
4873 if (const ObjCCategoryImplDecl *CID =
4874 dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
4875 OS << '(' << *CID << ')';
4876 OS << ' ' << D->getSelector().getAsString() << ']';
4879 void CGObjCMac::FinishModule() {
4882 // Emit the dummy bodies for any protocols which were referenced but
4884 for (llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*>::iterator
4885 I = Protocols.begin(), e = Protocols.end(); I != e; ++I) {
4886 if (I->second->hasInitializer())
4889 llvm::Constant *Values[5];
4890 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
4891 Values[1] = GetClassName(I->first);
4892 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
4893 Values[3] = Values[4] =
4894 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
4895 I->second->setLinkage(llvm::GlobalValue::InternalLinkage);
4896 I->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
4898 CGM.AddUsedGlobal(I->second);
4901 // Add assembler directives to add lazy undefined symbol references
4902 // for classes which are referenced but not defined. This is
4903 // important for correct linker interaction.
4905 // FIXME: It would be nice if we had an LLVM construct for this.
4906 if (!LazySymbols.empty() || !DefinedSymbols.empty()) {
4907 SmallString<256> Asm;
4908 Asm += CGM.getModule().getModuleInlineAsm();
4909 if (!Asm.empty() && Asm.back() != '\n')
4912 llvm::raw_svector_ostream OS(Asm);
4913 for (llvm::SetVector<IdentifierInfo*>::iterator I = DefinedSymbols.begin(),
4914 e = DefinedSymbols.end(); I != e; ++I)
4915 OS << "\t.objc_class_name_" << (*I)->getName() << "=0\n"
4916 << "\t.globl .objc_class_name_" << (*I)->getName() << "\n";
4917 for (llvm::SetVector<IdentifierInfo*>::iterator I = LazySymbols.begin(),
4918 e = LazySymbols.end(); I != e; ++I) {
4919 OS << "\t.lazy_reference .objc_class_name_" << (*I)->getName() << "\n";
4922 for (size_t i = 0, e = DefinedCategoryNames.size(); i < e; ++i) {
4923 OS << "\t.objc_category_name_" << DefinedCategoryNames[i] << "=0\n"
4924 << "\t.globl .objc_category_name_" << DefinedCategoryNames[i] << "\n";
4927 CGM.getModule().setModuleInlineAsm(OS.str());
4931 CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
4932 : CGObjCCommonMac(cgm),
4934 ObjCEmptyCacheVar = ObjCEmptyVtableVar = NULL;
4940 ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
4941 : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(0)
4943 CodeGen::CodeGenTypes &Types = CGM.getTypes();
4944 ASTContext &Ctx = CGM.getContext();
4946 ShortTy = Types.ConvertType(Ctx.ShortTy);
4947 IntTy = Types.ConvertType(Ctx.IntTy);
4948 LongTy = Types.ConvertType(Ctx.LongTy);
4949 LongLongTy = Types.ConvertType(Ctx.LongLongTy);
4950 Int8PtrTy = CGM.Int8PtrTy;
4951 Int8PtrPtrTy = CGM.Int8PtrPtrTy;
4953 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
4954 PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy);
4955 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
4957 // I'm not sure I like this. The implicit coordination is a bit
4958 // gross. We should solve this in a reasonable fashion because this
4959 // is a pretty common task (match some runtime data structure with
4960 // an LLVM data structure).
4962 // FIXME: This is leaked.
4963 // FIXME: Merge with rewriter code?
4965 // struct _objc_super {
4969 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
4970 Ctx.getTranslationUnitDecl(),
4971 SourceLocation(), SourceLocation(),
4972 &Ctx.Idents.get("_objc_super"));
4973 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
4974 Ctx.getObjCIdType(), 0, 0, false, ICIS_NoInit));
4975 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
4976 Ctx.getObjCClassType(), 0, 0, false,
4978 RD->completeDefinition();
4980 SuperCTy = Ctx.getTagDeclType(RD);
4981 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
4983 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
4984 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
4988 // char *attributes;
4990 PropertyTy = llvm::StructType::create("struct._prop_t",
4991 Int8PtrTy, Int8PtrTy, NULL);
4993 // struct _prop_list_t {
4994 // uint32_t entsize; // sizeof(struct _prop_t)
4995 // uint32_t count_of_properties;
4996 // struct _prop_t prop_list[count_of_properties];
4999 llvm::StructType::create("struct._prop_list_t", IntTy, IntTy,
5000 llvm::ArrayType::get(PropertyTy, 0), NULL);
5001 // struct _prop_list_t *
5002 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
5004 // struct _objc_method {
5006 // char *method_type;
5009 MethodTy = llvm::StructType::create("struct._objc_method",
5010 SelectorPtrTy, Int8PtrTy, Int8PtrTy,
5013 // struct _objc_cache *
5014 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache");
5015 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
5019 ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
5020 : ObjCCommonTypesHelper(cgm) {
5021 // struct _objc_method_description {
5025 MethodDescriptionTy =
5026 llvm::StructType::create("struct._objc_method_description",
5027 SelectorPtrTy, Int8PtrTy, NULL);
5029 // struct _objc_method_description_list {
5031 // struct _objc_method_description[1];
5033 MethodDescriptionListTy =
5034 llvm::StructType::create("struct._objc_method_description_list",
5036 llvm::ArrayType::get(MethodDescriptionTy, 0),NULL);
5038 // struct _objc_method_description_list *
5039 MethodDescriptionListPtrTy =
5040 llvm::PointerType::getUnqual(MethodDescriptionListTy);
5042 // Protocol description structures
5044 // struct _objc_protocol_extension {
5045 // uint32_t size; // sizeof(struct _objc_protocol_extension)
5046 // struct _objc_method_description_list *optional_instance_methods;
5047 // struct _objc_method_description_list *optional_class_methods;
5048 // struct _objc_property_list *instance_properties;
5049 // const char ** extendedMethodTypes;
5051 ProtocolExtensionTy =
5052 llvm::StructType::create("struct._objc_protocol_extension",
5053 IntTy, MethodDescriptionListPtrTy,
5054 MethodDescriptionListPtrTy, PropertyListPtrTy,
5055 Int8PtrPtrTy, NULL);
5057 // struct _objc_protocol_extension *
5058 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
5060 // Handle recursive construction of Protocol and ProtocolList types
5063 llvm::StructType::create(VMContext, "struct._objc_protocol");
5066 llvm::StructType::create(VMContext, "struct._objc_protocol_list");
5067 ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy),
5069 llvm::ArrayType::get(ProtocolTy, 0),
5072 // struct _objc_protocol {
5073 // struct _objc_protocol_extension *isa;
5074 // char *protocol_name;
5075 // struct _objc_protocol **_objc_protocol_list;
5076 // struct _objc_method_description_list *instance_methods;
5077 // struct _objc_method_description_list *class_methods;
5079 ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy,
5080 llvm::PointerType::getUnqual(ProtocolListTy),
5081 MethodDescriptionListPtrTy,
5082 MethodDescriptionListPtrTy,
5085 // struct _objc_protocol_list *
5086 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
5088 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
5090 // Class description structures
5092 // struct _objc_ivar {
5097 IvarTy = llvm::StructType::create("struct._objc_ivar",
5098 Int8PtrTy, Int8PtrTy, IntTy, NULL);
5100 // struct _objc_ivar_list *
5102 llvm::StructType::create(VMContext, "struct._objc_ivar_list");
5103 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
5105 // struct _objc_method_list *
5107 llvm::StructType::create(VMContext, "struct._objc_method_list");
5108 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
5110 // struct _objc_class_extension *
5112 llvm::StructType::create("struct._objc_class_extension",
5113 IntTy, Int8PtrTy, PropertyListPtrTy, NULL);
5114 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
5116 ClassTy = llvm::StructType::create(VMContext, "struct._objc_class");
5118 // struct _objc_class {
5120 // Class super_class;
5124 // long instance_size;
5125 // struct _objc_ivar_list *ivars;
5126 // struct _objc_method_list *methods;
5127 // struct _objc_cache *cache;
5128 // struct _objc_protocol_list *protocols;
5129 // char *ivar_layout;
5130 // struct _objc_class_ext *ext;
5132 ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy),
5133 llvm::PointerType::getUnqual(ClassTy),
5143 ClassExtensionPtrTy,
5146 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
5148 // struct _objc_category {
5149 // char *category_name;
5150 // char *class_name;
5151 // struct _objc_method_list *instance_method;
5152 // struct _objc_method_list *class_method;
5153 // uint32_t size; // sizeof(struct _objc_category)
5154 // struct _objc_property_list *instance_properties;// category's @property
5157 llvm::StructType::create("struct._objc_category",
5158 Int8PtrTy, Int8PtrTy, MethodListPtrTy,
5159 MethodListPtrTy, ProtocolListPtrTy,
5160 IntTy, PropertyListPtrTy, NULL);
5162 // Global metadata structures
5164 // struct _objc_symtab {
5165 // long sel_ref_cnt;
5167 // short cls_def_cnt;
5168 // short cat_def_cnt;
5169 // char *defs[cls_def_cnt + cat_def_cnt];
5172 llvm::StructType::create("struct._objc_symtab",
5173 LongTy, SelectorPtrTy, ShortTy, ShortTy,
5174 llvm::ArrayType::get(Int8PtrTy, 0), NULL);
5175 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
5177 // struct _objc_module {
5179 // long size; // sizeof(struct _objc_module)
5181 // struct _objc_symtab* symtab;
5184 llvm::StructType::create("struct._objc_module",
5185 LongTy, LongTy, Int8PtrTy, SymtabPtrTy, NULL);
5188 // FIXME: This is the size of the setjmp buffer and should be target
5189 // specific. 18 is what's used on 32-bit X86.
5190 uint64_t SetJmpBufferSize = 18;
5193 llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4);
5196 llvm::StructType::create("struct._objc_exception_data",
5197 llvm::ArrayType::get(CGM.Int32Ty,SetJmpBufferSize),
5202 ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm)
5203 : ObjCCommonTypesHelper(cgm) {
5204 // struct _method_list_t {
5205 // uint32_t entsize; // sizeof(struct _objc_method)
5206 // uint32_t method_count;
5207 // struct _objc_method method_list[method_count];
5210 llvm::StructType::create("struct.__method_list_t", IntTy, IntTy,
5211 llvm::ArrayType::get(MethodTy, 0), NULL);
5212 // struct method_list_t *
5213 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy);
5215 // struct _protocol_t {
5217 // const char * const protocol_name;
5218 // const struct _protocol_list_t * protocol_list; // super protocols
5219 // const struct method_list_t * const instance_methods;
5220 // const struct method_list_t * const class_methods;
5221 // const struct method_list_t *optionalInstanceMethods;
5222 // const struct method_list_t *optionalClassMethods;
5223 // const struct _prop_list_t * properties;
5224 // const uint32_t size; // sizeof(struct _protocol_t)
5225 // const uint32_t flags; // = 0
5226 // const char ** extendedMethodTypes;
5229 // Holder for struct _protocol_list_t *
5230 ProtocolListnfABITy =
5231 llvm::StructType::create(VMContext, "struct._objc_protocol_list");
5234 llvm::StructType::create("struct._protocol_t", ObjectPtrTy, Int8PtrTy,
5235 llvm::PointerType::getUnqual(ProtocolListnfABITy),
5236 MethodListnfABIPtrTy, MethodListnfABIPtrTy,
5237 MethodListnfABIPtrTy, MethodListnfABIPtrTy,
5238 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy,
5241 // struct _protocol_t*
5242 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy);
5244 // struct _protocol_list_t {
5245 // long protocol_count; // Note, this is 32/64 bit
5246 // struct _protocol_t *[protocol_count];
5248 ProtocolListnfABITy->setBody(LongTy,
5249 llvm::ArrayType::get(ProtocolnfABIPtrTy, 0),
5252 // struct _objc_protocol_list*
5253 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy);
5256 // unsigned long int *offset; // pointer to ivar offset location
5259 // uint32_t alignment;
5263 llvm::StructType::create("struct._ivar_t",
5264 llvm::PointerType::getUnqual(LongTy),
5265 Int8PtrTy, Int8PtrTy, IntTy, IntTy, NULL);
5267 // struct _ivar_list_t {
5268 // uint32 entsize; // sizeof(struct _ivar_t)
5270 // struct _iver_t list[count];
5273 llvm::StructType::create("struct._ivar_list_t", IntTy, IntTy,
5274 llvm::ArrayType::get(IvarnfABITy, 0), NULL);
5276 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy);
5278 // struct _class_ro_t {
5279 // uint32_t const flags;
5280 // uint32_t const instanceStart;
5281 // uint32_t const instanceSize;
5282 // uint32_t const reserved; // only when building for 64bit targets
5283 // const uint8_t * const ivarLayout;
5284 // const char *const name;
5285 // const struct _method_list_t * const baseMethods;
5286 // const struct _objc_protocol_list *const baseProtocols;
5287 // const struct _ivar_list_t *const ivars;
5288 // const uint8_t * const weakIvarLayout;
5289 // const struct _prop_list_t * const properties;
5292 // FIXME. Add 'reserved' field in 64bit abi mode!
5293 ClassRonfABITy = llvm::StructType::create("struct._class_ro_t",
5294 IntTy, IntTy, IntTy, Int8PtrTy,
5295 Int8PtrTy, MethodListnfABIPtrTy,
5296 ProtocolListnfABIPtrTy,
5298 Int8PtrTy, PropertyListPtrTy, NULL);
5300 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
5301 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
5302 ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false)
5305 // struct _class_t {
5306 // struct _class_t *isa;
5307 // struct _class_t * const superclass;
5310 // struct class_ro_t *ro;
5313 ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t");
5314 ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy),
5315 llvm::PointerType::getUnqual(ClassnfABITy),
5317 llvm::PointerType::getUnqual(ImpnfABITy),
5318 llvm::PointerType::getUnqual(ClassRonfABITy),
5321 // LLVM for struct _class_t *
5322 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy);
5324 // struct _category_t {
5325 // const char * const name;
5326 // struct _class_t *const cls;
5327 // const struct _method_list_t * const instance_methods;
5328 // const struct _method_list_t * const class_methods;
5329 // const struct _protocol_list_t * const protocols;
5330 // const struct _prop_list_t * const properties;
5332 CategorynfABITy = llvm::StructType::create("struct._category_t",
5333 Int8PtrTy, ClassnfABIPtrTy,
5334 MethodListnfABIPtrTy,
5335 MethodListnfABIPtrTy,
5336 ProtocolListnfABIPtrTy,
5340 // New types for nonfragile abi messaging.
5341 CodeGen::CodeGenTypes &Types = CGM.getTypes();
5342 ASTContext &Ctx = CGM.getContext();
5344 // MessageRefTy - LLVM for:
5345 // struct _message_ref_t {
5350 // First the clang type for struct _message_ref_t
5351 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
5352 Ctx.getTranslationUnitDecl(),
5353 SourceLocation(), SourceLocation(),
5354 &Ctx.Idents.get("_message_ref_t"));
5355 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
5356 Ctx.VoidPtrTy, 0, 0, false, ICIS_NoInit));
5357 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
5358 Ctx.getObjCSelType(), 0, 0, false,
5360 RD->completeDefinition();
5362 MessageRefCTy = Ctx.getTagDeclType(RD);
5363 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
5364 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
5366 // MessageRefPtrTy - LLVM for struct _message_ref_t*
5367 MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy);
5369 // SuperMessageRefTy - LLVM for:
5370 // struct _super_message_ref_t {
5371 // SUPER_IMP messenger;
5375 llvm::StructType::create("struct._super_message_ref_t",
5376 ImpnfABITy, SelectorPtrTy, NULL);
5378 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
5379 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);
5382 // struct objc_typeinfo {
5383 // const void** vtable; // objc_ehtype_vtable + 2
5384 // const char* name; // c++ typeinfo string
5388 llvm::StructType::create("struct._objc_typeinfo",
5389 llvm::PointerType::getUnqual(Int8PtrTy),
5390 Int8PtrTy, ClassnfABIPtrTy, NULL);
5391 EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy);
5394 llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
5395 FinishNonFragileABIModule();
5400 void CGObjCNonFragileABIMac::
5401 AddModuleClassList(ArrayRef<llvm::GlobalValue*> Container,
5402 const char *SymbolName,
5403 const char *SectionName) {
5404 unsigned NumClasses = Container.size();
5409 SmallVector<llvm::Constant*, 8> Symbols(NumClasses);
5410 for (unsigned i=0; i<NumClasses; i++)
5411 Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i],
5412 ObjCTypes.Int8PtrTy);
5413 llvm::Constant *Init =
5414 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
5418 llvm::GlobalVariable *GV =
5419 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5420 llvm::GlobalValue::InternalLinkage,
5423 GV->setAlignment(CGM.getDataLayout().getABITypeAlignment(Init->getType()));
5424 GV->setSection(SectionName);
5425 CGM.AddUsedGlobal(GV);
5428 void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
5429 // nonfragile abi has no module definition.
5431 // Build list of all implemented class addresses in array
5432 // L_OBJC_LABEL_CLASS_$.
5433 AddModuleClassList(DefinedClasses,
5434 "\01L_OBJC_LABEL_CLASS_$",
5435 "__DATA, __objc_classlist, regular, no_dead_strip");
5437 for (unsigned i = 0, e = DefinedClasses.size(); i < e; i++) {
5438 llvm::GlobalValue *IMPLGV = DefinedClasses[i];
5439 if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage)
5441 IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage);
5444 for (unsigned i = 0, e = DefinedMetaClasses.size(); i < e; i++) {
5445 llvm::GlobalValue *IMPLGV = DefinedMetaClasses[i];
5446 if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage)
5448 IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage);
5451 AddModuleClassList(DefinedNonLazyClasses,
5452 "\01L_OBJC_LABEL_NONLAZY_CLASS_$",
5453 "__DATA, __objc_nlclslist, regular, no_dead_strip");
5455 // Build list of all implemented category addresses in array
5456 // L_OBJC_LABEL_CATEGORY_$.
5457 AddModuleClassList(DefinedCategories,
5458 "\01L_OBJC_LABEL_CATEGORY_$",
5459 "__DATA, __objc_catlist, regular, no_dead_strip");
5460 AddModuleClassList(DefinedNonLazyCategories,
5461 "\01L_OBJC_LABEL_NONLAZY_CATEGORY_$",
5462 "__DATA, __objc_nlcatlist, regular, no_dead_strip");
5467 /// isVTableDispatchedSelector - Returns true if SEL is not in the list of
5468 /// VTableDispatchMethods; false otherwise. What this means is that
5469 /// except for the 19 selectors in the list, we generate 32bit-style
5470 /// message dispatch call for all the rest.
5471 bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
5472 // At various points we've experimented with using vtable-based
5473 // dispatch for all methods.
5474 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
5475 case CodeGenOptions::Legacy:
5477 case CodeGenOptions::NonLegacy:
5479 case CodeGenOptions::Mixed:
5483 // If so, see whether this selector is in the white-list of things which must
5484 // use the new dispatch convention. We lazily build a dense set for this.
5485 if (VTableDispatchMethods.empty()) {
5486 VTableDispatchMethods.insert(GetNullarySelector("alloc"));
5487 VTableDispatchMethods.insert(GetNullarySelector("class"));
5488 VTableDispatchMethods.insert(GetNullarySelector("self"));
5489 VTableDispatchMethods.insert(GetNullarySelector("isFlipped"));
5490 VTableDispatchMethods.insert(GetNullarySelector("length"));
5491 VTableDispatchMethods.insert(GetNullarySelector("count"));
5493 // These are vtable-based if GC is disabled.
5494 // Optimistically use vtable dispatch for hybrid compiles.
5495 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
5496 VTableDispatchMethods.insert(GetNullarySelector("retain"));
5497 VTableDispatchMethods.insert(GetNullarySelector("release"));
5498 VTableDispatchMethods.insert(GetNullarySelector("autorelease"));
5501 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone"));
5502 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass"));
5503 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector"));
5504 VTableDispatchMethods.insert(GetUnarySelector("objectForKey"));
5505 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex"));
5506 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString"));
5507 VTableDispatchMethods.insert(GetUnarySelector("isEqual"));
5509 // These are vtable-based if GC is enabled.
5510 // Optimistically use vtable dispatch for hybrid compiles.
5511 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
5512 VTableDispatchMethods.insert(GetNullarySelector("hash"));
5513 VTableDispatchMethods.insert(GetUnarySelector("addObject"));
5515 // "countByEnumeratingWithState:objects:count"
5516 IdentifierInfo *KeyIdents[] = {
5517 &CGM.getContext().Idents.get("countByEnumeratingWithState"),
5518 &CGM.getContext().Idents.get("objects"),
5519 &CGM.getContext().Idents.get("count")
5521 VTableDispatchMethods.insert(
5522 CGM.getContext().Selectors.getSelector(3, KeyIdents));
5526 return VTableDispatchMethods.count(Sel);
5529 /// BuildClassRoTInitializer - generate meta-data for:
5530 /// struct _class_ro_t {
5531 /// uint32_t const flags;
5532 /// uint32_t const instanceStart;
5533 /// uint32_t const instanceSize;
5534 /// uint32_t const reserved; // only when building for 64bit targets
5535 /// const uint8_t * const ivarLayout;
5536 /// const char *const name;
5537 /// const struct _method_list_t * const baseMethods;
5538 /// const struct _protocol_list_t *const baseProtocols;
5539 /// const struct _ivar_list_t *const ivars;
5540 /// const uint8_t * const weakIvarLayout;
5541 /// const struct _prop_list_t * const properties;
5544 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
5546 unsigned InstanceStart,
5547 unsigned InstanceSize,
5548 const ObjCImplementationDecl *ID) {
5549 std::string ClassName = ID->getNameAsString();
5550 llvm::Constant *Values[10]; // 11 for 64bit targets!
5552 if (CGM.getLangOpts().ObjCAutoRefCount)
5553 flags |= NonFragileABI_Class_CompiledByARC;
5555 Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags);
5556 Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart);
5557 Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize);
5558 // FIXME. For 64bit targets add 0 here.
5559 Values[ 3] = (flags & NonFragileABI_Class_Meta)
5560 ? GetIvarLayoutName(0, ObjCTypes)
5561 : BuildIvarLayout(ID, true);
5562 Values[ 4] = GetClassName(ID->getIdentifier());
5563 // const struct _method_list_t * const baseMethods;
5564 std::vector<llvm::Constant*> Methods;
5565 std::string MethodListName("\01l_OBJC_$_");
5566 if (flags & NonFragileABI_Class_Meta) {
5567 MethodListName += "CLASS_METHODS_" + ID->getNameAsString();
5568 for (ObjCImplementationDecl::classmeth_iterator
5569 i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
5570 // Class methods should always be defined.
5571 Methods.push_back(GetMethodConstant(*i));
5574 MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString();
5575 for (ObjCImplementationDecl::instmeth_iterator
5576 i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
5577 // Instance methods should always be defined.
5578 Methods.push_back(GetMethodConstant(*i));
5580 for (ObjCImplementationDecl::propimpl_iterator
5581 i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
5582 ObjCPropertyImplDecl *PID = *i;
5584 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
5585 ObjCPropertyDecl *PD = PID->getPropertyDecl();
5587 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
5588 if (llvm::Constant *C = GetMethodConstant(MD))
5589 Methods.push_back(C);
5590 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
5591 if (llvm::Constant *C = GetMethodConstant(MD))
5592 Methods.push_back(C);
5596 Values[ 5] = EmitMethodList(MethodListName,
5597 "__DATA, __objc_const", Methods);
5599 const ObjCInterfaceDecl *OID = ID->getClassInterface();
5600 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");
5601 Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_"
5603 OID->all_referenced_protocol_begin(),
5604 OID->all_referenced_protocol_end());
5606 if (flags & NonFragileABI_Class_Meta) {
5607 Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
5608 Values[ 8] = GetIvarLayoutName(0, ObjCTypes);
5609 Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
5611 Values[ 7] = EmitIvarList(ID);
5612 Values[ 8] = BuildIvarLayout(ID, false);
5613 Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
5614 ID, ID->getClassInterface(), ObjCTypes);
5616 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy,
5618 llvm::GlobalVariable *CLASS_RO_GV =
5619 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassRonfABITy, false,
5620 llvm::GlobalValue::InternalLinkage,
5622 (flags & NonFragileABI_Class_Meta) ?
5623 std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName :
5624 std::string("\01l_OBJC_CLASS_RO_$_")+ClassName);
5625 CLASS_RO_GV->setAlignment(
5626 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassRonfABITy));
5627 CLASS_RO_GV->setSection("__DATA, __objc_const");
5632 /// BuildClassMetaData - This routine defines that to-level meta-data
5633 /// for the given ClassName for:
5634 /// struct _class_t {
5635 /// struct _class_t *isa;
5636 /// struct _class_t * const superclass;
5639 /// struct class_ro_t *ro;
5642 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData(
5643 std::string &ClassName,
5644 llvm::Constant *IsAGV,
5645 llvm::Constant *SuperClassGV,
5646 llvm::Constant *ClassRoGV,
5647 bool HiddenVisibility) {
5648 llvm::Constant *Values[] = {
5651 ObjCEmptyCacheVar, // &ObjCEmptyCacheVar
5652 ObjCEmptyVtableVar, // &ObjCEmptyVtableVar
5653 ClassRoGV // &CLASS_RO_GV
5656 Values[1] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy);
5657 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy,
5659 llvm::GlobalVariable *GV = GetClassGlobal(ClassName);
5660 GV->setInitializer(Init);
5661 GV->setSection("__DATA, __objc_data");
5663 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABITy));
5664 if (HiddenVisibility)
5665 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5670 CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
5671 return OD->getClassMethod(GetNullarySelector("load")) != 0;
5674 void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
5675 uint32_t &InstanceStart,
5676 uint32_t &InstanceSize) {
5677 const ASTRecordLayout &RL =
5678 CGM.getContext().getASTObjCImplementationLayout(OID);
5680 // InstanceSize is really instance end.
5681 InstanceSize = RL.getDataSize().getQuantity();
5683 // If there are no fields, the start is the same as the end.
5684 if (!RL.getFieldCount())
5685 InstanceStart = InstanceSize;
5687 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
5690 void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
5691 std::string ClassName = ID->getNameAsString();
5692 if (!ObjCEmptyCacheVar) {
5693 ObjCEmptyCacheVar = new llvm::GlobalVariable(
5697 llvm::GlobalValue::ExternalLinkage,
5699 "_objc_empty_cache");
5701 ObjCEmptyVtableVar = new llvm::GlobalVariable(
5703 ObjCTypes.ImpnfABITy,
5705 llvm::GlobalValue::ExternalLinkage,
5707 "_objc_empty_vtable");
5709 assert(ID->getClassInterface() &&
5710 "CGObjCNonFragileABIMac::GenerateClass - class is 0");
5711 // FIXME: Is this correct (that meta class size is never computed)?
5712 uint32_t InstanceStart =
5713 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy);
5714 uint32_t InstanceSize = InstanceStart;
5715 uint32_t flags = NonFragileABI_Class_Meta;
5716 std::string ObjCMetaClassName(getMetaclassSymbolPrefix());
5717 std::string ObjCClassName(getClassSymbolPrefix());
5719 llvm::GlobalVariable *SuperClassGV, *IsAGV;
5721 // Build the flags for the metaclass.
5722 bool classIsHidden =
5723 ID->getClassInterface()->getVisibility() == HiddenVisibility;
5725 flags |= NonFragileABI_Class_Hidden;
5727 // FIXME: why is this flag set on the metaclass?
5728 // ObjC metaclasses have no fields and don't really get constructed.
5729 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
5730 flags |= NonFragileABI_Class_HasCXXStructors;
5731 if (!ID->hasNonZeroConstructors())
5732 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
5735 if (!ID->getClassInterface()->getSuperClass()) {
5737 flags |= NonFragileABI_Class_Root;
5738 SuperClassGV = GetClassGlobal(ObjCClassName + ClassName);
5739 IsAGV = GetClassGlobal(ObjCMetaClassName + ClassName);
5741 // Has a root. Current class is not a root.
5742 const ObjCInterfaceDecl *Root = ID->getClassInterface();
5743 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
5745 IsAGV = GetClassGlobal(ObjCMetaClassName + Root->getNameAsString());
5746 if (Root->isWeakImported())
5747 IsAGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
5748 // work on super class metadata symbol.
5749 std::string SuperClassName =
5751 ID->getClassInterface()->getSuperClass()->getNameAsString();
5752 SuperClassGV = GetClassGlobal(SuperClassName);
5753 if (ID->getClassInterface()->getSuperClass()->isWeakImported())
5754 SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
5756 llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags,
5759 std::string TClassName = ObjCMetaClassName + ClassName;
5760 llvm::GlobalVariable *MetaTClass =
5761 BuildClassMetaData(TClassName, IsAGV, SuperClassGV, CLASS_RO_GV,
5763 DefinedMetaClasses.push_back(MetaTClass);
5765 // Metadata for the class
5768 flags |= NonFragileABI_Class_Hidden;
5770 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
5771 flags |= NonFragileABI_Class_HasCXXStructors;
5773 // Set a flag to enable a runtime optimization when a class has
5774 // fields that require destruction but which don't require
5775 // anything except zero-initialization during construction. This
5776 // is most notably true of __strong and __weak types, but you can
5777 // also imagine there being C++ types with non-trivial default
5778 // constructors that merely set all fields to null.
5779 if (!ID->hasNonZeroConstructors())
5780 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
5783 if (hasObjCExceptionAttribute(CGM.getContext(), ID->getClassInterface()))
5784 flags |= NonFragileABI_Class_Exception;
5786 if (!ID->getClassInterface()->getSuperClass()) {
5787 flags |= NonFragileABI_Class_Root;
5790 // Has a root. Current class is not a root.
5791 std::string RootClassName =
5792 ID->getClassInterface()->getSuperClass()->getNameAsString();
5793 SuperClassGV = GetClassGlobal(ObjCClassName + RootClassName);
5794 if (ID->getClassInterface()->getSuperClass()->isWeakImported())
5795 SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
5797 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
5798 CLASS_RO_GV = BuildClassRoTInitializer(flags,
5803 TClassName = ObjCClassName + ClassName;
5804 llvm::GlobalVariable *ClassMD =
5805 BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV,
5807 DefinedClasses.push_back(ClassMD);
5809 // Determine if this class is also "non-lazy".
5810 if (ImplementationIsNonLazy(ID))
5811 DefinedNonLazyClasses.push_back(ClassMD);
5813 // Force the definition of the EHType if necessary.
5814 if (flags & NonFragileABI_Class_Exception)
5815 GetInterfaceEHType(ID->getClassInterface(), true);
5816 // Make sure method definition entries are all clear for next implementation.
5817 MethodDefinitions.clear();
5820 /// GenerateProtocolRef - This routine is called to generate code for
5821 /// a protocol reference expression; as in:
5823 /// @protocol(Proto1);
5825 /// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1
5826 /// which will hold address of the protocol meta-data.
5828 llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CGBuilderTy &Builder,
5829 const ObjCProtocolDecl *PD) {
5831 // This routine is called for @protocol only. So, we must build definition
5832 // of protocol's meta-data (not a reference to it!)
5834 llvm::Constant *Init =
5835 llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD),
5836 ObjCTypes.getExternalProtocolPtrTy());
5838 std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_");
5839 ProtocolName += PD->getName();
5841 llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
5843 return Builder.CreateLoad(PTGV);
5844 PTGV = new llvm::GlobalVariable(
5846 Init->getType(), false,
5847 llvm::GlobalValue::WeakAnyLinkage,
5850 PTGV->setSection("__DATA, __objc_protorefs, coalesced, no_dead_strip");
5851 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5852 CGM.AddUsedGlobal(PTGV);
5853 return Builder.CreateLoad(PTGV);
5856 /// GenerateCategory - Build metadata for a category implementation.
5857 /// struct _category_t {
5858 /// const char * const name;
5859 /// struct _class_t *const cls;
5860 /// const struct _method_list_t * const instance_methods;
5861 /// const struct _method_list_t * const class_methods;
5862 /// const struct _protocol_list_t * const protocols;
5863 /// const struct _prop_list_t * const properties;
5866 void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
5867 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
5868 const char *Prefix = "\01l_OBJC_$_CATEGORY_";
5869 std::string ExtCatName(Prefix + Interface->getNameAsString()+
5870 "_$_" + OCD->getNameAsString());
5871 std::string ExtClassName(getClassSymbolPrefix() +
5872 Interface->getNameAsString());
5874 llvm::Constant *Values[6];
5875 Values[0] = GetClassName(OCD->getIdentifier());
5876 // meta-class entry symbol
5877 llvm::GlobalVariable *ClassGV = GetClassGlobal(ExtClassName);
5878 if (Interface->isWeakImported())
5879 ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
5881 Values[1] = ClassGV;
5882 std::vector<llvm::Constant*> Methods;
5883 std::string MethodListName(Prefix);
5884 MethodListName += "INSTANCE_METHODS_" + Interface->getNameAsString() +
5885 "_$_" + OCD->getNameAsString();
5887 for (ObjCCategoryImplDecl::instmeth_iterator
5888 i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
5889 // Instance methods should always be defined.
5890 Methods.push_back(GetMethodConstant(*i));
5893 Values[2] = EmitMethodList(MethodListName,
5894 "__DATA, __objc_const",
5897 MethodListName = Prefix;
5898 MethodListName += "CLASS_METHODS_" + Interface->getNameAsString() + "_$_" +
5899 OCD->getNameAsString();
5901 for (ObjCCategoryImplDecl::classmeth_iterator
5902 i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
5903 // Class methods should always be defined.
5904 Methods.push_back(GetMethodConstant(*i));
5907 Values[3] = EmitMethodList(MethodListName,
5908 "__DATA, __objc_const",
5910 const ObjCCategoryDecl *Category =
5911 Interface->FindCategoryDeclaration(OCD->getIdentifier());
5913 SmallString<256> ExtName;
5914 llvm::raw_svector_ostream(ExtName) << Interface->getName() << "_$_"
5916 Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_"
5917 + Interface->getName() + "_$_"
5918 + Category->getName(),
5919 Category->protocol_begin(),
5920 Category->protocol_end());
5921 Values[5] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
5922 OCD, Category, ObjCTypes);
5924 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
5925 Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
5928 llvm::Constant *Init =
5929 llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy,
5931 llvm::GlobalVariable *GCATV
5932 = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CategorynfABITy,
5934 llvm::GlobalValue::InternalLinkage,
5937 GCATV->setAlignment(
5938 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.CategorynfABITy));
5939 GCATV->setSection("__DATA, __objc_const");
5940 CGM.AddUsedGlobal(GCATV);
5941 DefinedCategories.push_back(GCATV);
5943 // Determine if this category is also "non-lazy".
5944 if (ImplementationIsNonLazy(OCD))
5945 DefinedNonLazyCategories.push_back(GCATV);
5946 // method definition entries must be clear for next implementation.
5947 MethodDefinitions.clear();
5950 /// GetMethodConstant - Return a struct objc_method constant for the
5951 /// given method if it has been defined. The result is null if the
5952 /// method has not been defined. The return value has type MethodPtrTy.
5953 llvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant(
5954 const ObjCMethodDecl *MD) {
5955 llvm::Function *Fn = GetMethodDefinition(MD);
5959 llvm::Constant *Method[] = {
5960 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
5961 ObjCTypes.SelectorPtrTy),
5962 GetMethodVarType(MD),
5963 llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy)
5965 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
5968 /// EmitMethodList - Build meta-data for method declarations
5969 /// struct _method_list_t {
5970 /// uint32_t entsize; // sizeof(struct _objc_method)
5971 /// uint32_t method_count;
5972 /// struct _objc_method method_list[method_count];
5976 CGObjCNonFragileABIMac::EmitMethodList(Twine Name,
5977 const char *Section,
5978 ArrayRef<llvm::Constant*> Methods) {
5979 // Return null for empty list.
5980 if (Methods.empty())
5981 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
5983 llvm::Constant *Values[3];
5984 // sizeof(struct _objc_method)
5985 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
5986 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
5988 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
5989 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
5991 Values[2] = llvm::ConstantArray::get(AT, Methods);
5992 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
5994 llvm::GlobalVariable *GV =
5995 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5996 llvm::GlobalValue::InternalLinkage, Init, Name);
5997 GV->setAlignment(CGM.getDataLayout().getABITypeAlignment(Init->getType()));
5998 GV->setSection(Section);
5999 CGM.AddUsedGlobal(GV);
6000 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy);
6003 /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
6005 llvm::GlobalVariable *
6006 CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
6007 const ObjCIvarDecl *Ivar) {
6008 const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
6009 std::string Name = "OBJC_IVAR_$_" + Container->getNameAsString() +
6010 '.' + Ivar->getNameAsString();
6011 llvm::GlobalVariable *IvarOffsetGV =
6012 CGM.getModule().getGlobalVariable(Name);
6015 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.LongTy,
6017 llvm::GlobalValue::ExternalLinkage,
6020 return IvarOffsetGV;
6024 CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
6025 const ObjCIvarDecl *Ivar,
6026 unsigned long int Offset) {
6027 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
6028 IvarOffsetGV->setInitializer(llvm::ConstantInt::get(ObjCTypes.LongTy,
6030 IvarOffsetGV->setAlignment(
6031 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.LongTy));
6033 // FIXME: This matches gcc, but shouldn't the visibility be set on the use as
6034 // well (i.e., in ObjCIvarOffsetVariable).
6035 if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
6036 Ivar->getAccessControl() == ObjCIvarDecl::Package ||
6037 ID->getVisibility() == HiddenVisibility)
6038 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6040 IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
6041 IvarOffsetGV->setSection("__DATA, __objc_ivar");
6042 return IvarOffsetGV;
6045 /// EmitIvarList - Emit the ivar list for the given
6046 /// implementation. The return value has type
6047 /// IvarListnfABIPtrTy.
6048 /// struct _ivar_t {
6049 /// unsigned long int *offset; // pointer to ivar offset location
6052 /// uint32_t alignment;
6055 /// struct _ivar_list_t {
6056 /// uint32 entsize; // sizeof(struct _ivar_t)
6058 /// struct _iver_t list[count];
6062 llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
6063 const ObjCImplementationDecl *ID) {
6065 std::vector<llvm::Constant*> Ivars;
6067 const ObjCInterfaceDecl *OID = ID->getClassInterface();
6068 assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface");
6070 // FIXME. Consolidate this with similar code in GenerateClass.
6072 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
6073 IVD; IVD = IVD->getNextIvar()) {
6074 // Ignore unnamed bit-fields.
6075 if (!IVD->getDeclName())
6077 llvm::Constant *Ivar[5];
6078 Ivar[0] = EmitIvarOffsetVar(ID->getClassInterface(), IVD,
6079 ComputeIvarBaseOffset(CGM, ID, IVD));
6080 Ivar[1] = GetMethodVarName(IVD->getIdentifier());
6081 Ivar[2] = GetMethodVarType(IVD);
6082 llvm::Type *FieldTy =
6083 CGM.getTypes().ConvertTypeForMem(IVD->getType());
6084 unsigned Size = CGM.getDataLayout().getTypeAllocSize(FieldTy);
6085 unsigned Align = CGM.getContext().getPreferredTypeAlign(
6086 IVD->getType().getTypePtr()) >> 3;
6087 Align = llvm::Log2_32(Align);
6088 Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align);
6089 // NOTE. Size of a bitfield does not match gcc's, because of the
6090 // way bitfields are treated special in each. But I am told that
6091 // 'size' for bitfield ivars is ignored by the runtime so it does
6092 // not matter. If it matters, there is enough info to get the
6094 Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6095 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar));
6097 // Return null for empty list.
6099 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
6101 llvm::Constant *Values[3];
6102 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy);
6103 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6104 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
6105 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy,
6107 Values[2] = llvm::ConstantArray::get(AT, Ivars);
6108 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
6109 const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_";
6110 llvm::GlobalVariable *GV =
6111 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
6112 llvm::GlobalValue::InternalLinkage,
6114 Prefix + OID->getName());
6116 CGM.getDataLayout().getABITypeAlignment(Init->getType()));
6117 GV->setSection("__DATA, __objc_const");
6119 CGM.AddUsedGlobal(GV);
6120 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
6123 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
6124 const ObjCProtocolDecl *PD) {
6125 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
6128 // We use the initializer as a marker of whether this is a forward
6129 // reference or not. At module finalization we add the empty
6130 // contents for protocols which were referenced but never defined.
6132 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, false,
6133 llvm::GlobalValue::ExternalLinkage,
6135 "\01l_OBJC_PROTOCOL_$_" + PD->getName());
6136 Entry->setSection("__DATA,__datacoal_nt,coalesced");
6142 /// GetOrEmitProtocol - Generate the protocol meta-data:
6144 /// struct _protocol_t {
6146 /// const char * const protocol_name;
6147 /// const struct _protocol_list_t * protocol_list; // super protocols
6148 /// const struct method_list_t * const instance_methods;
6149 /// const struct method_list_t * const class_methods;
6150 /// const struct method_list_t *optionalInstanceMethods;
6151 /// const struct method_list_t *optionalClassMethods;
6152 /// const struct _prop_list_t * properties;
6153 /// const uint32_t size; // sizeof(struct _protocol_t)
6154 /// const uint32_t flags; // = 0
6155 /// const char ** extendedMethodTypes;
6160 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
6161 const ObjCProtocolDecl *PD) {
6162 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
6164 // Early exit if a defining object has already been generated.
6165 if (Entry && Entry->hasInitializer())
6168 // Use the protocol definition, if there is one.
6169 if (const ObjCProtocolDecl *Def = PD->getDefinition())
6172 // Construct method lists.
6173 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
6174 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
6175 std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt;
6176 for (ObjCProtocolDecl::instmeth_iterator
6177 i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
6178 ObjCMethodDecl *MD = *i;
6179 llvm::Constant *C = GetMethodDescriptionConstant(MD);
6181 return GetOrEmitProtocolRef(PD);
6183 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
6184 OptInstanceMethods.push_back(C);
6185 OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
6187 InstanceMethods.push_back(C);
6188 MethodTypesExt.push_back(GetMethodVarType(MD, true));
6192 for (ObjCProtocolDecl::classmeth_iterator
6193 i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
6194 ObjCMethodDecl *MD = *i;
6195 llvm::Constant *C = GetMethodDescriptionConstant(MD);
6197 return GetOrEmitProtocolRef(PD);
6199 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
6200 OptClassMethods.push_back(C);
6201 OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
6203 ClassMethods.push_back(C);
6204 MethodTypesExt.push_back(GetMethodVarType(MD, true));
6208 MethodTypesExt.insert(MethodTypesExt.end(),
6209 OptMethodTypesExt.begin(), OptMethodTypesExt.end());
6211 llvm::Constant *Values[11];
6213 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy);
6214 Values[1] = GetClassName(PD->getIdentifier());
6215 Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getName(),
6216 PD->protocol_begin(),
6217 PD->protocol_end());
6219 Values[3] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_"
6221 "__DATA, __objc_const",
6223 Values[4] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_"
6225 "__DATA, __objc_const",
6227 Values[5] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_"
6229 "__DATA, __objc_const",
6230 OptInstanceMethods);
6231 Values[6] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_"
6233 "__DATA, __objc_const",
6235 Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getName(),
6238 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
6239 Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6240 Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy);
6241 Values[10] = EmitProtocolMethodTypes("\01l_OBJC_$_PROTOCOL_METHOD_TYPES_"
6243 MethodTypesExt, ObjCTypes);
6244 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy,
6248 // Already created, fix the linkage and update the initializer.
6249 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
6250 Entry->setInitializer(Init);
6253 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
6254 false, llvm::GlobalValue::WeakAnyLinkage, Init,
6255 "\01l_OBJC_PROTOCOL_$_" + PD->getName());
6256 Entry->setAlignment(
6257 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABITy));
6258 Entry->setSection("__DATA,__datacoal_nt,coalesced");
6260 Protocols[PD->getIdentifier()] = Entry;
6262 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
6263 CGM.AddUsedGlobal(Entry);
6265 // Use this protocol meta-data to build protocol list table in section
6266 // __DATA, __objc_protolist
6267 llvm::GlobalVariable *PTGV =
6268 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy,
6269 false, llvm::GlobalValue::WeakAnyLinkage, Entry,
6270 "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getName());
6272 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
6273 PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip");
6274 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6275 CGM.AddUsedGlobal(PTGV);
6279 /// EmitProtocolList - Generate protocol list meta-data:
6281 /// struct _protocol_list_t {
6282 /// long protocol_count; // Note, this is 32/64 bit
6283 /// struct _protocol_t[protocol_count];
6288 CGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
6289 ObjCProtocolDecl::protocol_iterator begin,
6290 ObjCProtocolDecl::protocol_iterator end) {
6291 llvm::SmallVector<llvm::Constant*, 16> ProtocolRefs;
6293 // Just return null for empty protocol lists
6295 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
6297 // FIXME: We shouldn't need to do this lookup here, should we?
6298 SmallString<256> TmpName;
6299 Name.toVector(TmpName);
6300 llvm::GlobalVariable *GV =
6301 CGM.getModule().getGlobalVariable(TmpName.str(), true);
6303 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
6305 for (; begin != end; ++begin)
6306 ProtocolRefs.push_back(GetProtocolRef(*begin)); // Implemented???
6308 // This list is null terminated.
6309 ProtocolRefs.push_back(llvm::Constant::getNullValue(
6310 ObjCTypes.ProtocolnfABIPtrTy));
6312 llvm::Constant *Values[2];
6314 llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
6316 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolnfABIPtrTy,
6317 ProtocolRefs.size()),
6320 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
6321 GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
6322 llvm::GlobalValue::InternalLinkage,
6324 GV->setSection("__DATA, __objc_const");
6326 CGM.getDataLayout().getABITypeAlignment(Init->getType()));
6327 CGM.AddUsedGlobal(GV);
6328 return llvm::ConstantExpr::getBitCast(GV,
6329 ObjCTypes.ProtocolListnfABIPtrTy);
6332 /// GetMethodDescriptionConstant - This routine build following meta-data:
6333 /// struct _objc_method {
6335 /// char *method_type;
6340 CGObjCNonFragileABIMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
6341 llvm::Constant *Desc[3];
6343 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
6344 ObjCTypes.SelectorPtrTy);
6345 Desc[1] = GetMethodVarType(MD);
6349 // Protocol methods have no implementation. So, this entry is always NULL.
6350 Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
6351 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc);
6354 /// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference.
6355 /// This code gen. amounts to generating code for:
6357 /// (type *)((char *)base + _OBJC_IVAR_$_.ivar;
6360 LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
6361 CodeGen::CodeGenFunction &CGF,
6363 llvm::Value *BaseValue,
6364 const ObjCIvarDecl *Ivar,
6365 unsigned CVRQualifiers) {
6366 ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCObjectType>()->getInterface();
6367 llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
6368 if (llvm::LoadInst *LI = dyn_cast<llvm::LoadInst>(Offset))
6369 LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
6370 llvm::MDNode::get(VMContext,
6371 ArrayRef<llvm::Value*>()));
6372 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
6376 llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(
6377 CodeGen::CodeGenFunction &CGF,
6378 const ObjCInterfaceDecl *Interface,
6379 const ObjCIvarDecl *Ivar) {
6380 return CGF.Builder.CreateLoad(ObjCIvarOffsetVariable(Interface, Ivar),"ivar");
6383 static void appendSelectorForMessageRefTable(std::string &buffer,
6384 Selector selector) {
6385 if (selector.isUnarySelector()) {
6386 buffer += selector.getNameForSlot(0);
6390 for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) {
6391 buffer += selector.getNameForSlot(i);
6396 /// Emit a "v-table" message send. We emit a weak hidden-visibility
6397 /// struct, initially containing the selector pointer and a pointer to
6398 /// a "fixup" variant of the appropriate objc_msgSend. To call, we
6399 /// load and call the function pointer, passing the address of the
6400 /// struct as the second parameter. The runtime determines whether
6401 /// the selector is currently emitted using vtable dispatch; if so, it
6402 /// substitutes a stub function which simply tail-calls through the
6403 /// appropriate vtable slot, and if not, it substitues a stub function
6404 /// which tail-calls objc_msgSend. Both stubs adjust the selector
6405 /// argument to correctly point to the selector.
6407 CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF,
6408 ReturnValueSlot returnSlot,
6409 QualType resultType,
6414 const CallArgList &formalArgs,
6415 const ObjCMethodDecl *method) {
6416 // Compute the actual arguments.
6419 // First argument: the receiver / super-call structure.
6421 arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy);
6422 args.add(RValue::get(arg0), arg0Type);
6424 // Second argument: a pointer to the message ref structure. Leave
6425 // the actual argument value blank for now.
6426 args.add(RValue::get(0), ObjCTypes.MessageRefCPtrTy);
6428 args.insert(args.end(), formalArgs.begin(), formalArgs.end());
6430 MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
6432 NullReturnState nullReturn;
6434 // Find the function to call and the mangled name for the message
6435 // ref structure. Using a different mangled name wouldn't actually
6436 // be a problem; it would just be a waste.
6438 // The runtime currently never uses vtable dispatch for anything
6439 // except normal, non-super message-sends.
6440 // FIXME: don't use this for that.
6441 llvm::Constant *fn = 0;
6442 std::string messageRefName("\01l_");
6443 if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) {
6445 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
6446 messageRefName += "objc_msgSendSuper2_stret_fixup";
6448 nullReturn.init(CGF, arg0);
6449 fn = ObjCTypes.getMessageSendStretFixupFn();
6450 messageRefName += "objc_msgSend_stret_fixup";
6452 } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) {
6453 fn = ObjCTypes.getMessageSendFpretFixupFn();
6454 messageRefName += "objc_msgSend_fpret_fixup";
6457 fn = ObjCTypes.getMessageSendSuper2FixupFn();
6458 messageRefName += "objc_msgSendSuper2_fixup";
6460 fn = ObjCTypes.getMessageSendFixupFn();
6461 messageRefName += "objc_msgSend_fixup";
6464 assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend");
6465 messageRefName += '_';
6467 // Append the selector name, except use underscores anywhere we
6468 // would have used colons.
6469 appendSelectorForMessageRefTable(messageRefName, selector);
6471 llvm::GlobalVariable *messageRef
6472 = CGM.getModule().getGlobalVariable(messageRefName);
6474 // Build the message ref structure.
6475 llvm::Constant *values[] = { fn, GetMethodVarName(selector) };
6476 llvm::Constant *init = llvm::ConstantStruct::getAnon(values);
6477 messageRef = new llvm::GlobalVariable(CGM.getModule(),
6480 llvm::GlobalValue::WeakAnyLinkage,
6483 messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
6484 messageRef->setAlignment(16);
6485 messageRef->setSection("__DATA, __objc_msgrefs, coalesced");
6488 bool requiresnullCheck = false;
6489 if (CGM.getLangOpts().ObjCAutoRefCount && method)
6490 for (ObjCMethodDecl::param_const_iterator i = method->param_begin(),
6491 e = method->param_end(); i != e; ++i) {
6492 const ParmVarDecl *ParamDecl = (*i);
6493 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
6494 if (!nullReturn.NullBB)
6495 nullReturn.init(CGF, arg0);
6496 requiresnullCheck = true;
6502 CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy);
6504 // Update the message ref argument.
6505 args[1].RV = RValue::get(mref);
6507 // Load the function to call from the message ref table.
6508 llvm::Value *callee = CGF.Builder.CreateStructGEP(mref, 0);
6509 callee = CGF.Builder.CreateLoad(callee, "msgSend_fn");
6511 callee = CGF.Builder.CreateBitCast(callee, MSI.MessengerType);
6513 RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args);
6514 return nullReturn.complete(CGF, result, resultType, formalArgs,
6515 requiresnullCheck ? method : 0);
6518 /// Generate code for a message send expression in the nonfragile abi.
6520 CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
6521 ReturnValueSlot Return,
6522 QualType ResultType,
6524 llvm::Value *Receiver,
6525 const CallArgList &CallArgs,
6526 const ObjCInterfaceDecl *Class,
6527 const ObjCMethodDecl *Method) {
6528 return isVTableDispatchedSelector(Sel)
6529 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
6530 Receiver, CGF.getContext().getObjCIdType(),
6531 false, CallArgs, Method)
6532 : EmitMessageSend(CGF, Return, ResultType,
6533 EmitSelector(CGF.Builder, Sel),
6534 Receiver, CGF.getContext().getObjCIdType(),
6535 false, CallArgs, Method, ObjCTypes);
6538 llvm::GlobalVariable *
6539 CGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name) {
6540 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
6543 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABITy,
6544 false, llvm::GlobalValue::ExternalLinkage,
6551 llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CGBuilderTy &Builder,
6552 IdentifierInfo *II) {
6553 llvm::GlobalVariable *&Entry = ClassReferences[II];
6556 std::string ClassName(getClassSymbolPrefix() + II->getName().str());
6557 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
6559 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
6560 false, llvm::GlobalValue::InternalLinkage,
6562 "\01L_OBJC_CLASSLIST_REFERENCES_$_");
6563 Entry->setAlignment(
6564 CGM.getDataLayout().getABITypeAlignment(
6565 ObjCTypes.ClassnfABIPtrTy));
6566 Entry->setSection("__DATA, __objc_classrefs, regular, no_dead_strip");
6567 CGM.AddUsedGlobal(Entry);
6570 return Builder.CreateLoad(Entry);
6573 llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CGBuilderTy &Builder,
6574 const ObjCInterfaceDecl *ID) {
6575 return EmitClassRefFromId(Builder, ID->getIdentifier());
6578 llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
6579 CGBuilderTy &Builder) {
6580 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
6581 return EmitClassRefFromId(Builder, II);
6585 CGObjCNonFragileABIMac::EmitSuperClassRef(CGBuilderTy &Builder,
6586 const ObjCInterfaceDecl *ID) {
6587 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
6590 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
6591 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
6593 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
6594 false, llvm::GlobalValue::InternalLinkage,
6596 "\01L_OBJC_CLASSLIST_SUP_REFS_$_");
6597 Entry->setAlignment(
6598 CGM.getDataLayout().getABITypeAlignment(
6599 ObjCTypes.ClassnfABIPtrTy));
6600 Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
6601 CGM.AddUsedGlobal(Entry);
6604 return Builder.CreateLoad(Entry);
6607 /// EmitMetaClassRef - Return a Value * of the address of _class_t
6610 llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CGBuilderTy &Builder,
6611 const ObjCInterfaceDecl *ID) {
6612 llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];
6614 return Builder.CreateLoad(Entry);
6616 std::string MetaClassName(getMetaclassSymbolPrefix() + ID->getNameAsString());
6617 llvm::GlobalVariable *MetaClassGV = GetClassGlobal(MetaClassName);
6619 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, false,
6620 llvm::GlobalValue::InternalLinkage,
6622 "\01L_OBJC_CLASSLIST_SUP_REFS_$_");
6623 Entry->setAlignment(
6624 CGM.getDataLayout().getABITypeAlignment(
6625 ObjCTypes.ClassnfABIPtrTy));
6627 Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
6628 CGM.AddUsedGlobal(Entry);
6630 return Builder.CreateLoad(Entry);
6633 /// GetClass - Return a reference to the class for the given interface
6635 llvm::Value *CGObjCNonFragileABIMac::GetClass(CGBuilderTy &Builder,
6636 const ObjCInterfaceDecl *ID) {
6637 if (ID->isWeakImported()) {
6638 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
6639 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
6640 ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
6643 return EmitClassRef(Builder, ID);
6646 /// Generates a message send where the super is the receiver. This is
6647 /// a message send to self with special delivery semantics indicating
6648 /// which class's method should be called.
6650 CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
6651 ReturnValueSlot Return,
6652 QualType ResultType,
6654 const ObjCInterfaceDecl *Class,
6655 bool isCategoryImpl,
6656 llvm::Value *Receiver,
6657 bool IsClassMessage,
6658 const CodeGen::CallArgList &CallArgs,
6659 const ObjCMethodDecl *Method) {
6661 // Create and init a super structure; this is a (receiver, class)
6662 // pair we will pass to objc_msgSendSuper.
6663 llvm::Value *ObjCSuper =
6664 CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super");
6666 llvm::Value *ReceiverAsObject =
6667 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
6668 CGF.Builder.CreateStore(ReceiverAsObject,
6669 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
6671 // If this is a class message the metaclass is passed as the target.
6672 llvm::Value *Target;
6674 Target = EmitMetaClassRef(CGF.Builder, Class);
6676 Target = EmitSuperClassRef(CGF.Builder, Class);
6678 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
6680 llvm::Type *ClassTy =
6681 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
6682 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
6683 CGF.Builder.CreateStore(Target,
6684 CGF.Builder.CreateStructGEP(ObjCSuper, 1));
6686 return (isVTableDispatchedSelector(Sel))
6687 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
6688 ObjCSuper, ObjCTypes.SuperPtrCTy,
6689 true, CallArgs, Method)
6690 : EmitMessageSend(CGF, Return, ResultType,
6691 EmitSelector(CGF.Builder, Sel),
6692 ObjCSuper, ObjCTypes.SuperPtrCTy,
6693 true, CallArgs, Method, ObjCTypes);
6696 llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CGBuilderTy &Builder,
6697 Selector Sel, bool lval) {
6698 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
6701 llvm::Constant *Casted =
6702 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
6703 ObjCTypes.SelectorPtrTy);
6705 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.SelectorPtrTy, false,
6706 llvm::GlobalValue::InternalLinkage,
6707 Casted, "\01L_OBJC_SELECTOR_REFERENCES_");
6708 Entry->setSection("__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
6709 CGM.AddUsedGlobal(Entry);
6714 llvm::LoadInst* LI = Builder.CreateLoad(Entry);
6716 LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
6717 llvm::MDNode::get(VMContext,
6718 ArrayRef<llvm::Value*>()));
6721 /// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
6722 /// objc_assign_ivar (id src, id *dst, ptrdiff_t)
6724 void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
6727 llvm::Value *ivarOffset) {
6728 llvm::Type * SrcTy = src->getType();
6729 if (!isa<llvm::PointerType>(SrcTy)) {
6730 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
6731 assert(Size <= 8 && "does not support size > 8");
6732 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6733 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
6734 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6736 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6737 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
6738 CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(),
6739 src, dst, ivarOffset);
6743 /// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
6744 /// objc_assign_strongCast (id src, id *dst)
6746 void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
6747 CodeGen::CodeGenFunction &CGF,
6748 llvm::Value *src, llvm::Value *dst) {
6749 llvm::Type * SrcTy = src->getType();
6750 if (!isa<llvm::PointerType>(SrcTy)) {
6751 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
6752 assert(Size <= 8 && "does not support size > 8");
6753 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6754 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
6755 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6757 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6758 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
6759 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(),
6760 src, dst, "weakassign");
6764 void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
6765 CodeGen::CodeGenFunction &CGF,
6766 llvm::Value *DestPtr,
6767 llvm::Value *SrcPtr,
6768 llvm::Value *Size) {
6769 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
6770 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
6771 CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(),
6772 DestPtr, SrcPtr, Size);
6776 /// EmitObjCWeakRead - Code gen for loading value of a __weak
6777 /// object: objc_read_weak (id *src)
6779 llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
6780 CodeGen::CodeGenFunction &CGF,
6781 llvm::Value *AddrWeakObj) {
6782 llvm::Type* DestTy =
6783 cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
6784 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
6785 llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(),
6786 AddrWeakObj, "weakread");
6787 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
6791 /// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
6792 /// objc_assign_weak (id src, id *dst)
6794 void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
6795 llvm::Value *src, llvm::Value *dst) {
6796 llvm::Type * SrcTy = src->getType();
6797 if (!isa<llvm::PointerType>(SrcTy)) {
6798 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
6799 assert(Size <= 8 && "does not support size > 8");
6800 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6801 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
6802 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6804 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6805 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
6806 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(),
6807 src, dst, "weakassign");
6811 /// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
6812 /// objc_assign_global (id src, id *dst)
6814 void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
6815 llvm::Value *src, llvm::Value *dst,
6817 llvm::Type * SrcTy = src->getType();
6818 if (!isa<llvm::PointerType>(SrcTy)) {
6819 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
6820 assert(Size <= 8 && "does not support size > 8");
6821 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6822 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
6823 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6825 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6826 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
6828 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(),
6829 src, dst, "globalassign");
6831 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(),
6832 src, dst, "threadlocalassign");
6837 CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
6838 const ObjCAtSynchronizedStmt &S) {
6839 EmitAtSynchronizedStmt(CGF, S,
6840 cast<llvm::Function>(ObjCTypes.getSyncEnterFn()),
6841 cast<llvm::Function>(ObjCTypes.getSyncExitFn()));
6845 CGObjCNonFragileABIMac::GetEHType(QualType T) {
6846 // There's a particular fixed type info for 'id'.
6847 if (T->isObjCIdType() ||
6848 T->isObjCQualifiedIdType()) {
6849 llvm::Constant *IDEHType =
6850 CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id");
6853 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy,
6855 llvm::GlobalValue::ExternalLinkage,
6856 0, "OBJC_EHTYPE_id");
6860 // All other types should be Objective-C interface pointer types.
6861 const ObjCObjectPointerType *PT =
6862 T->getAs<ObjCObjectPointerType>();
6863 assert(PT && "Invalid @catch type.");
6864 const ObjCInterfaceType *IT = PT->getInterfaceType();
6865 assert(IT && "Invalid @catch type.");
6866 return GetInterfaceEHType(IT->getDecl(), false);
6869 void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
6870 const ObjCAtTryStmt &S) {
6871 EmitTryCatchStmt(CGF, S,
6872 cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()),
6873 cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()),
6874 cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn()));
6877 /// EmitThrowStmt - Generate code for a throw statement.
6878 void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
6879 const ObjCAtThrowStmt &S) {
6880 if (const Expr *ThrowExpr = S.getThrowExpr()) {
6881 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
6882 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
6883 CGF.EmitCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception)
6884 .setDoesNotReturn();
6886 CGF.EmitCallOrInvoke(ObjCTypes.getExceptionRethrowFn())
6887 .setDoesNotReturn();
6890 CGF.Builder.CreateUnreachable();
6891 CGF.Builder.ClearInsertionPoint();
6895 CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
6896 bool ForDefinition) {
6897 llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
6899 // If we don't need a definition, return the entry if found or check
6900 // if we use an external reference.
6901 if (!ForDefinition) {
6905 // If this type (or a super class) has the __objc_exception__
6906 // attribute, emit an external reference.
6907 if (hasObjCExceptionAttribute(CGM.getContext(), ID))
6909 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
6910 llvm::GlobalValue::ExternalLinkage,
6913 ID->getIdentifier()->getName()));
6916 // Otherwise we need to either make a new entry or fill in the
6918 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition");
6919 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
6920 std::string VTableName = "objc_ehtype_vtable";
6921 llvm::GlobalVariable *VTableGV =
6922 CGM.getModule().getGlobalVariable(VTableName);
6924 VTableGV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy,
6926 llvm::GlobalValue::ExternalLinkage,
6929 llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2);
6931 llvm::Constant *Values[] = {
6932 llvm::ConstantExpr::getGetElementPtr(VTableGV, VTableIdx),
6933 GetClassName(ID->getIdentifier()),
6934 GetClassGlobal(ClassName)
6936 llvm::Constant *Init =
6937 llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values);
6940 Entry->setInitializer(Init);
6942 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
6943 llvm::GlobalValue::WeakAnyLinkage,
6946 ID->getIdentifier()->getName()));
6949 if (CGM.getLangOpts().getVisibilityMode() == HiddenVisibility)
6950 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
6951 Entry->setAlignment(CGM.getDataLayout().getABITypeAlignment(
6952 ObjCTypes.EHTypeTy));
6954 if (ForDefinition) {
6955 Entry->setSection("__DATA,__objc_const");
6956 Entry->setLinkage(llvm::GlobalValue::ExternalLinkage);
6958 Entry->setSection("__DATA,__datacoal_nt,coalesced");
6966 CodeGen::CGObjCRuntime *
6967 CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
6968 switch (CGM.getLangOpts().ObjCRuntime.getKind()) {
6969 case ObjCRuntime::FragileMacOSX:
6970 return new CGObjCMac(CGM);
6972 case ObjCRuntime::MacOSX:
6973 case ObjCRuntime::iOS:
6974 return new CGObjCNonFragileABIMac(CGM);
6976 case ObjCRuntime::GNUstep:
6977 case ObjCRuntime::GCC:
6978 case ObjCRuntime::ObjFW:
6979 llvm_unreachable("these runtimes are not Mac runtimes");
6981 llvm_unreachable("bad runtime");