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 //===----------------------------------------------------------------------===//
15 #include "CGCleanup.h"
16 #include "CGObjCRuntime.h"
17 #include "CGRecordLayout.h"
18 #include "CodeGenFunction.h"
19 #include "CodeGenModule.h"
20 #include "clang/CodeGen/ConstantInitBuilder.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/CodeGen/CGFunctionInfo.h"
28 #include "clang/Frontend/CodeGenOptions.h"
29 #include "llvm/ADT/CachedHashString.h"
30 #include "llvm/ADT/DenseSet.h"
31 #include "llvm/ADT/SetVector.h"
32 #include "llvm/ADT/SmallPtrSet.h"
33 #include "llvm/ADT/SmallString.h"
34 #include "llvm/IR/CallSite.h"
35 #include "llvm/IR/DataLayout.h"
36 #include "llvm/IR/InlineAsm.h"
37 #include "llvm/IR/IntrinsicInst.h"
38 #include "llvm/IR/LLVMContext.h"
39 #include "llvm/IR/Module.h"
40 #include "llvm/Support/raw_ostream.h"
43 using namespace clang;
44 using namespace CodeGen;
48 // FIXME: We should find a nicer way to make the labels for metadata, string
49 // concatenation is lame.
51 class ObjCCommonTypesHelper {
53 llvm::LLVMContext &VMContext;
56 // The types of these functions don't really matter because we
57 // should always bitcast before calling them.
59 /// id objc_msgSend (id, SEL, ...)
61 /// The default messenger, used for sends whose ABI is unchanged from
62 /// the all-integer/pointer case.
63 llvm::Constant *getMessageSendFn() const {
64 // Add the non-lazy-bind attribute, since objc_msgSend is likely to
66 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
67 return CGM.CreateRuntimeFunction(
68 llvm::FunctionType::get(ObjectPtrTy, params, true), "objc_msgSend",
69 llvm::AttributeList::get(CGM.getLLVMContext(),
70 llvm::AttributeList::FunctionIndex,
71 llvm::Attribute::NonLazyBind));
74 /// void objc_msgSend_stret (id, SEL, ...)
76 /// The messenger used when the return value is an aggregate returned
77 /// by indirect reference in the first argument, and therefore the
78 /// self and selector parameters are shifted over by one.
79 llvm::Constant *getMessageSendStretFn() const {
80 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
81 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,
83 "objc_msgSend_stret");
87 /// [double | long double] objc_msgSend_fpret(id self, SEL op, ...)
89 /// The messenger used when the return value is returned on the x87
90 /// floating-point stack; without a special entrypoint, the nil case
91 /// would be unbalanced.
92 llvm::Constant *getMessageSendFpretFn() const {
93 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
94 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.DoubleTy,
96 "objc_msgSend_fpret");
100 /// _Complex long double objc_msgSend_fp2ret(id self, SEL op, ...)
102 /// The messenger used when the return value is returned in two values on the
103 /// x87 floating point stack; without a special entrypoint, the nil case
104 /// would be unbalanced. Only used on 64-bit X86.
105 llvm::Constant *getMessageSendFp2retFn() const {
106 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
107 llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(VMContext);
108 llvm::Type *resultType =
109 llvm::StructType::get(longDoubleType, longDoubleType);
111 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(resultType,
113 "objc_msgSend_fp2ret");
116 /// id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
118 /// The messenger used for super calls, which have different dispatch
119 /// semantics. The class passed is the superclass of the current
121 llvm::Constant *getMessageSendSuperFn() const {
122 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
123 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
125 "objc_msgSendSuper");
128 /// id objc_msgSendSuper2(struct objc_super *super, SEL op, ...)
130 /// A slightly different messenger used for super calls. The class
131 /// passed is the current class.
132 llvm::Constant *getMessageSendSuperFn2() const {
133 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
134 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
136 "objc_msgSendSuper2");
139 /// void objc_msgSendSuper_stret(void *stretAddr, struct objc_super *super,
142 /// The messenger used for super calls which return an aggregate indirectly.
143 llvm::Constant *getMessageSendSuperStretFn() const {
144 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
145 return CGM.CreateRuntimeFunction(
146 llvm::FunctionType::get(CGM.VoidTy, params, true),
147 "objc_msgSendSuper_stret");
150 /// void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super,
153 /// objc_msgSendSuper_stret with the super2 semantics.
154 llvm::Constant *getMessageSendSuperStretFn2() const {
155 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
156 return CGM.CreateRuntimeFunction(
157 llvm::FunctionType::get(CGM.VoidTy, params, true),
158 "objc_msgSendSuper2_stret");
161 llvm::Constant *getMessageSendSuperFpretFn() const {
162 // There is no objc_msgSendSuper_fpret? How can that work?
163 return getMessageSendSuperFn();
166 llvm::Constant *getMessageSendSuperFpretFn2() const {
167 // There is no objc_msgSendSuper_fpret? How can that work?
168 return getMessageSendSuperFn2();
172 CodeGen::CodeGenModule &CGM;
175 llvm::IntegerType *ShortTy, *IntTy, *LongTy;
176 llvm::PointerType *Int8PtrTy, *Int8PtrPtrTy;
177 llvm::Type *IvarOffsetVarTy;
179 /// ObjectPtrTy - LLVM type for object handles (typeof(id))
180 llvm::PointerType *ObjectPtrTy;
182 /// PtrObjectPtrTy - LLVM type for id *
183 llvm::PointerType *PtrObjectPtrTy;
185 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
186 llvm::PointerType *SelectorPtrTy;
189 /// ProtocolPtrTy - LLVM type for external protocol handles
190 /// (typeof(Protocol))
191 llvm::Type *ExternalProtocolPtrTy;
194 llvm::Type *getExternalProtocolPtrTy() {
195 if (!ExternalProtocolPtrTy) {
196 // FIXME: It would be nice to unify this with the opaque type, so that the
197 // IR comes out a bit cleaner.
198 CodeGen::CodeGenTypes &Types = CGM.getTypes();
199 ASTContext &Ctx = CGM.getContext();
200 llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
201 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
204 return ExternalProtocolPtrTy;
207 // SuperCTy - clang type for struct objc_super.
209 // SuperPtrCTy - clang type for struct objc_super *.
210 QualType SuperPtrCTy;
212 /// SuperTy - LLVM type for struct objc_super.
213 llvm::StructType *SuperTy;
214 /// SuperPtrTy - LLVM type for struct objc_super *.
215 llvm::PointerType *SuperPtrTy;
217 /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
218 /// in GCC parlance).
219 llvm::StructType *PropertyTy;
221 /// PropertyListTy - LLVM type for struct objc_property_list
222 /// (_prop_list_t in GCC parlance).
223 llvm::StructType *PropertyListTy;
224 /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
225 llvm::PointerType *PropertyListPtrTy;
227 // MethodTy - LLVM type for struct objc_method.
228 llvm::StructType *MethodTy;
230 /// CacheTy - LLVM type for struct objc_cache.
232 /// CachePtrTy - LLVM type for struct objc_cache *.
233 llvm::PointerType *CachePtrTy;
235 llvm::Constant *getGetPropertyFn() {
236 CodeGen::CodeGenTypes &Types = CGM.getTypes();
237 ASTContext &Ctx = CGM.getContext();
238 // id objc_getProperty (id, SEL, ptrdiff_t, bool)
239 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
240 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
241 CanQualType Params[] = {
243 Ctx.getPointerDiffType()->getCanonicalTypeUnqualified(), Ctx.BoolTy};
244 llvm::FunctionType *FTy =
245 Types.GetFunctionType(
246 Types.arrangeBuiltinFunctionDeclaration(IdType, Params));
247 return CGM.CreateRuntimeFunction(FTy, "objc_getProperty");
250 llvm::Constant *getSetPropertyFn() {
251 CodeGen::CodeGenTypes &Types = CGM.getTypes();
252 ASTContext &Ctx = CGM.getContext();
253 // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool)
254 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
255 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
256 CanQualType Params[] = {
259 Ctx.getPointerDiffType()->getCanonicalTypeUnqualified(),
263 llvm::FunctionType *FTy =
264 Types.GetFunctionType(
265 Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params));
266 return CGM.CreateRuntimeFunction(FTy, "objc_setProperty");
269 llvm::Constant *getOptimizedSetPropertyFn(bool atomic, bool copy) {
270 CodeGen::CodeGenTypes &Types = CGM.getTypes();
271 ASTContext &Ctx = CGM.getContext();
272 // void objc_setProperty_atomic(id self, SEL _cmd,
273 // id newValue, ptrdiff_t offset);
274 // void objc_setProperty_nonatomic(id self, SEL _cmd,
275 // id newValue, ptrdiff_t offset);
276 // void objc_setProperty_atomic_copy(id self, SEL _cmd,
277 // id newValue, ptrdiff_t offset);
278 // void objc_setProperty_nonatomic_copy(id self, SEL _cmd,
279 // id newValue, ptrdiff_t offset);
281 SmallVector<CanQualType,4> Params;
282 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
283 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
284 Params.push_back(IdType);
285 Params.push_back(SelType);
286 Params.push_back(IdType);
287 Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
288 llvm::FunctionType *FTy =
289 Types.GetFunctionType(
290 Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params));
293 name = "objc_setProperty_atomic_copy";
294 else if (atomic && !copy)
295 name = "objc_setProperty_atomic";
296 else if (!atomic && copy)
297 name = "objc_setProperty_nonatomic_copy";
299 name = "objc_setProperty_nonatomic";
301 return CGM.CreateRuntimeFunction(FTy, name);
304 llvm::Constant *getCopyStructFn() {
305 CodeGen::CodeGenTypes &Types = CGM.getTypes();
306 ASTContext &Ctx = CGM.getContext();
307 // void objc_copyStruct (void *, const void *, size_t, bool, bool)
308 SmallVector<CanQualType,5> Params;
309 Params.push_back(Ctx.VoidPtrTy);
310 Params.push_back(Ctx.VoidPtrTy);
311 Params.push_back(Ctx.getSizeType());
312 Params.push_back(Ctx.BoolTy);
313 Params.push_back(Ctx.BoolTy);
314 llvm::FunctionType *FTy =
315 Types.GetFunctionType(
316 Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params));
317 return CGM.CreateRuntimeFunction(FTy, "objc_copyStruct");
320 /// This routine declares and returns address of:
321 /// void objc_copyCppObjectAtomic(
322 /// void *dest, const void *src,
323 /// void (*copyHelper) (void *dest, const void *source));
324 llvm::Constant *getCppAtomicObjectFunction() {
325 CodeGen::CodeGenTypes &Types = CGM.getTypes();
326 ASTContext &Ctx = CGM.getContext();
327 /// void objc_copyCppObjectAtomic(void *dest, const void *src, void *helper);
328 SmallVector<CanQualType,3> Params;
329 Params.push_back(Ctx.VoidPtrTy);
330 Params.push_back(Ctx.VoidPtrTy);
331 Params.push_back(Ctx.VoidPtrTy);
332 llvm::FunctionType *FTy =
333 Types.GetFunctionType(
334 Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params));
335 return CGM.CreateRuntimeFunction(FTy, "objc_copyCppObjectAtomic");
338 llvm::Constant *getEnumerationMutationFn() {
339 CodeGen::CodeGenTypes &Types = CGM.getTypes();
340 ASTContext &Ctx = CGM.getContext();
341 // void objc_enumerationMutation (id)
342 SmallVector<CanQualType,1> Params;
343 Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType()));
344 llvm::FunctionType *FTy =
345 Types.GetFunctionType(
346 Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params));
347 return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
350 llvm::Constant *getLookUpClassFn() {
351 CodeGen::CodeGenTypes &Types = CGM.getTypes();
352 ASTContext &Ctx = CGM.getContext();
353 // Class objc_lookUpClass (const char *)
354 SmallVector<CanQualType,1> Params;
356 Ctx.getCanonicalType(Ctx.getPointerType(Ctx.CharTy.withConst())));
357 llvm::FunctionType *FTy =
358 Types.GetFunctionType(Types.arrangeBuiltinFunctionDeclaration(
359 Ctx.getCanonicalType(Ctx.getObjCClassType()),
361 return CGM.CreateRuntimeFunction(FTy, "objc_lookUpClass");
364 /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function.
365 llvm::Constant *getGcReadWeakFn() {
366 // id objc_read_weak (id *)
367 llvm::Type *args[] = { ObjectPtrTy->getPointerTo() };
368 llvm::FunctionType *FTy =
369 llvm::FunctionType::get(ObjectPtrTy, args, false);
370 return CGM.CreateRuntimeFunction(FTy, "objc_read_weak");
373 /// GcAssignWeakFn -- LLVM objc_assign_weak function.
374 llvm::Constant *getGcAssignWeakFn() {
375 // id objc_assign_weak (id, id *)
376 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
377 llvm::FunctionType *FTy =
378 llvm::FunctionType::get(ObjectPtrTy, args, false);
379 return CGM.CreateRuntimeFunction(FTy, "objc_assign_weak");
382 /// GcAssignGlobalFn -- LLVM objc_assign_global function.
383 llvm::Constant *getGcAssignGlobalFn() {
384 // id objc_assign_global(id, id *)
385 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
386 llvm::FunctionType *FTy =
387 llvm::FunctionType::get(ObjectPtrTy, args, false);
388 return CGM.CreateRuntimeFunction(FTy, "objc_assign_global");
391 /// GcAssignThreadLocalFn -- LLVM objc_assign_threadlocal function.
392 llvm::Constant *getGcAssignThreadLocalFn() {
393 // id objc_assign_threadlocal(id src, id * dest)
394 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
395 llvm::FunctionType *FTy =
396 llvm::FunctionType::get(ObjectPtrTy, args, false);
397 return CGM.CreateRuntimeFunction(FTy, "objc_assign_threadlocal");
400 /// GcAssignIvarFn -- LLVM objc_assign_ivar function.
401 llvm::Constant *getGcAssignIvarFn() {
402 // id objc_assign_ivar(id, id *, ptrdiff_t)
403 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo(),
405 llvm::FunctionType *FTy =
406 llvm::FunctionType::get(ObjectPtrTy, args, false);
407 return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar");
410 /// GcMemmoveCollectableFn -- LLVM objc_memmove_collectable function.
411 llvm::Constant *GcMemmoveCollectableFn() {
412 // void *objc_memmove_collectable(void *dst, const void *src, size_t size)
413 llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy };
414 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args, false);
415 return CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable");
418 /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function.
419 llvm::Constant *getGcAssignStrongCastFn() {
420 // id objc_assign_strongCast(id, id *)
421 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
422 llvm::FunctionType *FTy =
423 llvm::FunctionType::get(ObjectPtrTy, args, false);
424 return CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast");
427 /// ExceptionThrowFn - LLVM objc_exception_throw function.
428 llvm::Constant *getExceptionThrowFn() {
429 // void objc_exception_throw(id)
430 llvm::Type *args[] = { ObjectPtrTy };
431 llvm::FunctionType *FTy =
432 llvm::FunctionType::get(CGM.VoidTy, args, false);
433 return CGM.CreateRuntimeFunction(FTy, "objc_exception_throw");
436 /// ExceptionRethrowFn - LLVM objc_exception_rethrow function.
437 llvm::Constant *getExceptionRethrowFn() {
438 // void objc_exception_rethrow(void)
439 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, false);
440 return CGM.CreateRuntimeFunction(FTy, "objc_exception_rethrow");
443 /// SyncEnterFn - LLVM object_sync_enter function.
444 llvm::Constant *getSyncEnterFn() {
445 // int objc_sync_enter (id)
446 llvm::Type *args[] = { ObjectPtrTy };
447 llvm::FunctionType *FTy =
448 llvm::FunctionType::get(CGM.IntTy, args, false);
449 return CGM.CreateRuntimeFunction(FTy, "objc_sync_enter");
452 /// SyncExitFn - LLVM object_sync_exit function.
453 llvm::Constant *getSyncExitFn() {
454 // int objc_sync_exit (id)
455 llvm::Type *args[] = { ObjectPtrTy };
456 llvm::FunctionType *FTy =
457 llvm::FunctionType::get(CGM.IntTy, args, false);
458 return CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
461 llvm::Constant *getSendFn(bool IsSuper) const {
462 return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
465 llvm::Constant *getSendFn2(bool IsSuper) const {
466 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
469 llvm::Constant *getSendStretFn(bool IsSuper) const {
470 return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
473 llvm::Constant *getSendStretFn2(bool IsSuper) const {
474 return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
477 llvm::Constant *getSendFpretFn(bool IsSuper) const {
478 return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
481 llvm::Constant *getSendFpretFn2(bool IsSuper) const {
482 return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
485 llvm::Constant *getSendFp2retFn(bool IsSuper) const {
486 return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn();
489 llvm::Constant *getSendFp2RetFn2(bool IsSuper) const {
490 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn();
493 ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm);
496 /// ObjCTypesHelper - Helper class that encapsulates lazy
497 /// construction of varies types used during ObjC generation.
498 class ObjCTypesHelper : public ObjCCommonTypesHelper {
500 /// SymtabTy - LLVM type for struct objc_symtab.
501 llvm::StructType *SymtabTy;
502 /// SymtabPtrTy - LLVM type for struct objc_symtab *.
503 llvm::PointerType *SymtabPtrTy;
504 /// ModuleTy - LLVM type for struct objc_module.
505 llvm::StructType *ModuleTy;
507 /// ProtocolTy - LLVM type for struct objc_protocol.
508 llvm::StructType *ProtocolTy;
509 /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
510 llvm::PointerType *ProtocolPtrTy;
511 /// ProtocolExtensionTy - LLVM type for struct
512 /// objc_protocol_extension.
513 llvm::StructType *ProtocolExtensionTy;
514 /// ProtocolExtensionTy - LLVM type for struct
515 /// objc_protocol_extension *.
516 llvm::PointerType *ProtocolExtensionPtrTy;
517 /// MethodDescriptionTy - LLVM type for struct
518 /// objc_method_description.
519 llvm::StructType *MethodDescriptionTy;
520 /// MethodDescriptionListTy - LLVM type for struct
521 /// objc_method_description_list.
522 llvm::StructType *MethodDescriptionListTy;
523 /// MethodDescriptionListPtrTy - LLVM type for struct
524 /// objc_method_description_list *.
525 llvm::PointerType *MethodDescriptionListPtrTy;
526 /// ProtocolListTy - LLVM type for struct objc_property_list.
527 llvm::StructType *ProtocolListTy;
528 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
529 llvm::PointerType *ProtocolListPtrTy;
530 /// CategoryTy - LLVM type for struct objc_category.
531 llvm::StructType *CategoryTy;
532 /// ClassTy - LLVM type for struct objc_class.
533 llvm::StructType *ClassTy;
534 /// ClassPtrTy - LLVM type for struct objc_class *.
535 llvm::PointerType *ClassPtrTy;
536 /// ClassExtensionTy - LLVM type for struct objc_class_ext.
537 llvm::StructType *ClassExtensionTy;
538 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
539 llvm::PointerType *ClassExtensionPtrTy;
540 // IvarTy - LLVM type for struct objc_ivar.
541 llvm::StructType *IvarTy;
542 /// IvarListTy - LLVM type for struct objc_ivar_list.
543 llvm::StructType *IvarListTy;
544 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
545 llvm::PointerType *IvarListPtrTy;
546 /// MethodListTy - LLVM type for struct objc_method_list.
547 llvm::StructType *MethodListTy;
548 /// MethodListPtrTy - LLVM type for struct objc_method_list *.
549 llvm::PointerType *MethodListPtrTy;
551 /// ExceptionDataTy - LLVM type for struct _objc_exception_data.
552 llvm::StructType *ExceptionDataTy;
554 /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.
555 llvm::Constant *getExceptionTryEnterFn() {
556 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
557 return CGM.CreateRuntimeFunction(
558 llvm::FunctionType::get(CGM.VoidTy, params, false),
559 "objc_exception_try_enter");
562 /// ExceptionTryExitFn - LLVM objc_exception_try_exit function.
563 llvm::Constant *getExceptionTryExitFn() {
564 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
565 return CGM.CreateRuntimeFunction(
566 llvm::FunctionType::get(CGM.VoidTy, params, false),
567 "objc_exception_try_exit");
570 /// ExceptionExtractFn - LLVM objc_exception_extract function.
571 llvm::Constant *getExceptionExtractFn() {
572 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
573 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
575 "objc_exception_extract");
578 /// ExceptionMatchFn - LLVM objc_exception_match function.
579 llvm::Constant *getExceptionMatchFn() {
580 llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy };
581 return CGM.CreateRuntimeFunction(
582 llvm::FunctionType::get(CGM.Int32Ty, params, false),
583 "objc_exception_match");
586 /// SetJmpFn - LLVM _setjmp function.
587 llvm::Constant *getSetJmpFn() {
588 // This is specifically the prototype for x86.
589 llvm::Type *params[] = { CGM.Int32Ty->getPointerTo() };
590 return CGM.CreateRuntimeFunction(
591 llvm::FunctionType::get(CGM.Int32Ty, params, false), "_setjmp",
592 llvm::AttributeList::get(CGM.getLLVMContext(),
593 llvm::AttributeList::FunctionIndex,
594 llvm::Attribute::NonLazyBind));
598 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
601 /// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's
603 class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {
605 // MethodListnfABITy - LLVM for struct _method_list_t
606 llvm::StructType *MethodListnfABITy;
608 // MethodListnfABIPtrTy - LLVM for struct _method_list_t*
609 llvm::PointerType *MethodListnfABIPtrTy;
611 // ProtocolnfABITy = LLVM for struct _protocol_t
612 llvm::StructType *ProtocolnfABITy;
614 // ProtocolnfABIPtrTy = LLVM for struct _protocol_t*
615 llvm::PointerType *ProtocolnfABIPtrTy;
617 // ProtocolListnfABITy - LLVM for struct _objc_protocol_list
618 llvm::StructType *ProtocolListnfABITy;
620 // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list*
621 llvm::PointerType *ProtocolListnfABIPtrTy;
623 // ClassnfABITy - LLVM for struct _class_t
624 llvm::StructType *ClassnfABITy;
626 // ClassnfABIPtrTy - LLVM for struct _class_t*
627 llvm::PointerType *ClassnfABIPtrTy;
629 // IvarnfABITy - LLVM for struct _ivar_t
630 llvm::StructType *IvarnfABITy;
632 // IvarListnfABITy - LLVM for struct _ivar_list_t
633 llvm::StructType *IvarListnfABITy;
635 // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t*
636 llvm::PointerType *IvarListnfABIPtrTy;
638 // ClassRonfABITy - LLVM for struct _class_ro_t
639 llvm::StructType *ClassRonfABITy;
641 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
642 llvm::PointerType *ImpnfABITy;
644 // CategorynfABITy - LLVM for struct _category_t
645 llvm::StructType *CategorynfABITy;
647 // New types for nonfragile abi messaging.
649 // MessageRefTy - LLVM for:
650 // struct _message_ref_t {
654 llvm::StructType *MessageRefTy;
655 // MessageRefCTy - clang type for struct _message_ref_t
656 QualType MessageRefCTy;
658 // MessageRefPtrTy - LLVM for struct _message_ref_t*
659 llvm::Type *MessageRefPtrTy;
660 // MessageRefCPtrTy - clang type for struct _message_ref_t*
661 QualType MessageRefCPtrTy;
663 // SuperMessageRefTy - LLVM for:
664 // struct _super_message_ref_t {
665 // SUPER_IMP messenger;
668 llvm::StructType *SuperMessageRefTy;
670 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
671 llvm::PointerType *SuperMessageRefPtrTy;
673 llvm::Constant *getMessageSendFixupFn() {
674 // id objc_msgSend_fixup(id, struct message_ref_t*, ...)
675 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
676 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
678 "objc_msgSend_fixup");
681 llvm::Constant *getMessageSendFpretFixupFn() {
682 // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...)
683 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
684 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
686 "objc_msgSend_fpret_fixup");
689 llvm::Constant *getMessageSendStretFixupFn() {
690 // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...)
691 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
692 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
694 "objc_msgSend_stret_fixup");
697 llvm::Constant *getMessageSendSuper2FixupFn() {
698 // id objc_msgSendSuper2_fixup (struct objc_super *,
699 // struct _super_message_ref_t*, ...)
700 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
701 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
703 "objc_msgSendSuper2_fixup");
706 llvm::Constant *getMessageSendSuper2StretFixupFn() {
707 // id objc_msgSendSuper2_stret_fixup(struct objc_super *,
708 // struct _super_message_ref_t*, ...)
709 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
710 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
712 "objc_msgSendSuper2_stret_fixup");
715 llvm::Constant *getObjCEndCatchFn() {
716 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy, false),
721 llvm::Constant *getObjCBeginCatchFn() {
722 llvm::Type *params[] = { Int8PtrTy };
723 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy,
728 llvm::StructType *EHTypeTy;
729 llvm::Type *EHTypePtrTy;
731 ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
734 enum class ObjCLabelType {
741 class CGObjCCommonMac : public CodeGen::CGObjCRuntime {
747 SKIP_SCAN(unsigned _skip = 0, unsigned _scan = 0)
748 : skip(_skip), scan(_scan) {}
751 /// opcode for captured block variables layout 'instructions'.
752 /// In the following descriptions, 'I' is the value of the immediate field.
753 /// (field following the opcode).
755 enum BLOCK_LAYOUT_OPCODE {
756 /// An operator which affects how the following layout should be
758 /// I == 0: Halt interpretation and treat everything else as
759 /// a non-pointer. Note that this instruction is equal
761 /// I != 0: Currently unused.
762 BLOCK_LAYOUT_OPERATOR = 0,
764 /// The next I+1 bytes do not contain a value of object pointer type.
765 /// Note that this can leave the stream unaligned, meaning that
766 /// subsequent word-size instructions do not begin at a multiple of
767 /// the pointer size.
768 BLOCK_LAYOUT_NON_OBJECT_BYTES = 1,
770 /// The next I+1 words do not contain a value of object pointer type.
771 /// This is simply an optimized version of BLOCK_LAYOUT_BYTES for
772 /// when the required skip quantity is a multiple of the pointer size.
773 BLOCK_LAYOUT_NON_OBJECT_WORDS = 2,
775 /// The next I+1 words are __strong pointers to Objective-C
776 /// objects or blocks.
777 BLOCK_LAYOUT_STRONG = 3,
779 /// The next I+1 words are pointers to __block variables.
780 BLOCK_LAYOUT_BYREF = 4,
782 /// The next I+1 words are __weak pointers to Objective-C
783 /// objects or blocks.
784 BLOCK_LAYOUT_WEAK = 5,
786 /// The next I+1 words are __unsafe_unretained pointers to
787 /// Objective-C objects or blocks.
788 BLOCK_LAYOUT_UNRETAINED = 6
790 /// The next I+1 words are block or object pointers with some
791 /// as-yet-unspecified ownership semantics. If we add more
792 /// flavors of ownership semantics, values will be taken from
795 /// This is included so that older tools can at least continue
796 /// processing the layout past such things.
797 //BLOCK_LAYOUT_OWNERSHIP_UNKNOWN = 7..10,
799 /// All other opcodes are reserved. Halt interpretation and
800 /// treat everything else as opaque.
805 enum BLOCK_LAYOUT_OPCODE opcode;
806 CharUnits block_var_bytepos;
807 CharUnits block_var_size;
808 RUN_SKIP(enum BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR,
809 CharUnits BytePos = CharUnits::Zero(),
810 CharUnits Size = CharUnits::Zero())
811 : opcode(Opcode), block_var_bytepos(BytePos), block_var_size(Size) {}
813 // Allow sorting based on byte pos.
814 bool operator<(const RUN_SKIP &b) const {
815 return block_var_bytepos < b.block_var_bytepos;
820 llvm::LLVMContext &VMContext;
821 // FIXME! May not be needing this after all.
824 // arc/mrr layout of captured block literal variables.
825 SmallVector<RUN_SKIP, 16> RunSkipBlockVars;
827 /// LazySymbols - Symbols to generate a lazy reference for. See
828 /// DefinedSymbols and FinishModule().
829 llvm::SetVector<IdentifierInfo*> LazySymbols;
831 /// DefinedSymbols - External symbols which are defined by this
832 /// module. The symbols in this list and LazySymbols are used to add
833 /// special linker symbols which ensure that Objective-C modules are
835 llvm::SetVector<IdentifierInfo*> DefinedSymbols;
837 /// ClassNames - uniqued class names.
838 llvm::StringMap<llvm::GlobalVariable*> ClassNames;
840 /// MethodVarNames - uniqued method variable names.
841 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
843 /// DefinedCategoryNames - list of category names in form Class_Category.
844 llvm::SmallSetVector<llvm::CachedHashString, 16> DefinedCategoryNames;
846 /// MethodVarTypes - uniqued method type signatures. We have to use
847 /// a StringMap here because have no other unique reference.
848 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
850 /// MethodDefinitions - map of methods which have been defined in
851 /// this translation unit.
852 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
854 /// PropertyNames - uniqued method variable names.
855 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
857 /// ClassReferences - uniqued class references.
858 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
860 /// SelectorReferences - uniqued selector references.
861 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
863 /// Protocols - Protocols for which an objc_protocol structure has
864 /// been emitted. Forward declarations are handled by creating an
865 /// empty structure whose initializer is filled in when/if defined.
866 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
868 /// DefinedProtocols - Protocols which have actually been
869 /// defined. We should not need this, see FIXME in GenerateProtocol.
870 llvm::DenseSet<IdentifierInfo*> DefinedProtocols;
872 /// DefinedClasses - List of defined classes.
873 SmallVector<llvm::GlobalValue*, 16> DefinedClasses;
875 /// ImplementedClasses - List of @implemented classes.
876 SmallVector<const ObjCInterfaceDecl*, 16> ImplementedClasses;
878 /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
879 SmallVector<llvm::GlobalValue*, 16> DefinedNonLazyClasses;
881 /// DefinedCategories - List of defined categories.
882 SmallVector<llvm::GlobalValue*, 16> DefinedCategories;
884 /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
885 SmallVector<llvm::GlobalValue*, 16> DefinedNonLazyCategories;
887 /// Cached reference to the class for constant strings. This value has type
888 /// int * but is actually an Obj-C class pointer.
889 llvm::WeakTrackingVH ConstantStringClassRef;
891 /// \brief The LLVM type corresponding to NSConstantString.
892 llvm::StructType *NSConstantStringType = nullptr;
894 llvm::StringMap<llvm::GlobalVariable *> NSConstantStringMap;
896 /// GetNameForMethod - Return a name for the given method.
897 /// \param[out] NameOut - The return value.
898 void GetNameForMethod(const ObjCMethodDecl *OMD,
899 const ObjCContainerDecl *CD,
900 SmallVectorImpl<char> &NameOut);
902 /// GetMethodVarName - Return a unique constant for the given
903 /// selector's name. The return value has type char *.
904 llvm::Constant *GetMethodVarName(Selector Sel);
905 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
907 /// GetMethodVarType - Return a unique constant for the given
908 /// method's type encoding string. The return value has type char *.
910 // FIXME: This is a horrible name.
911 llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D,
912 bool Extended = false);
913 llvm::Constant *GetMethodVarType(const FieldDecl *D);
915 /// GetPropertyName - Return a unique constant for the given
916 /// name. The return value has type char *.
917 llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
919 // FIXME: This can be dropped once string functions are unified.
920 llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,
921 const Decl *Container);
923 /// GetClassName - Return a unique constant for the given selector's
924 /// runtime name (which may change via use of objc_runtime_name attribute on
925 /// class or protocol definition. The return value has type char *.
926 llvm::Constant *GetClassName(StringRef RuntimeName);
928 llvm::Function *GetMethodDefinition(const ObjCMethodDecl *MD);
930 /// BuildIvarLayout - Builds ivar layout bitmap for the class
931 /// implementation for the __strong or __weak case.
933 /// \param hasMRCWeakIvars - Whether we are compiling in MRC and there
934 /// are any weak ivars defined directly in the class. Meaningless unless
935 /// building a weak layout. Does not guarantee that the layout will
936 /// actually have any entries, because the ivar might be under-aligned.
937 llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI,
938 CharUnits beginOffset,
940 bool forStrongLayout,
941 bool hasMRCWeakIvars);
943 llvm::Constant *BuildStrongIvarLayout(const ObjCImplementationDecl *OI,
944 CharUnits beginOffset,
945 CharUnits endOffset) {
946 return BuildIvarLayout(OI, beginOffset, endOffset, true, false);
949 llvm::Constant *BuildWeakIvarLayout(const ObjCImplementationDecl *OI,
950 CharUnits beginOffset,
952 bool hasMRCWeakIvars) {
953 return BuildIvarLayout(OI, beginOffset, endOffset, false, hasMRCWeakIvars);
956 Qualifiers::ObjCLifetime getBlockCaptureLifetime(QualType QT, bool ByrefLayout);
958 void UpdateRunSkipBlockVars(bool IsByref,
959 Qualifiers::ObjCLifetime LifeTime,
960 CharUnits FieldOffset,
961 CharUnits FieldSize);
963 void BuildRCBlockVarRecordLayout(const RecordType *RT,
964 CharUnits BytePos, bool &HasUnion,
965 bool ByrefLayout=false);
967 void BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
968 const RecordDecl *RD,
969 ArrayRef<const FieldDecl*> RecFields,
970 CharUnits BytePos, bool &HasUnion,
973 uint64_t InlineLayoutInstruction(SmallVectorImpl<unsigned char> &Layout);
975 llvm::Constant *getBitmapBlockLayout(bool ComputeByrefLayout);
977 /// GetIvarLayoutName - Returns a unique constant for the given
978 /// ivar layout bitmap.
979 llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident,
980 const ObjCCommonTypesHelper &ObjCTypes);
982 /// EmitPropertyList - Emit the given property list. The return
983 /// value has type PropertyListPtrTy.
984 llvm::Constant *EmitPropertyList(Twine Name,
985 const Decl *Container,
986 const ObjCContainerDecl *OCD,
987 const ObjCCommonTypesHelper &ObjCTypes,
988 bool IsClassProperty);
990 /// EmitProtocolMethodTypes - Generate the array of extended method type
991 /// strings. The return value has type Int8PtrPtrTy.
992 llvm::Constant *EmitProtocolMethodTypes(Twine Name,
993 ArrayRef<llvm::Constant*> MethodTypes,
994 const ObjCCommonTypesHelper &ObjCTypes);
996 /// GetProtocolRef - Return a reference to the internal protocol
997 /// description, creating an empty one if it has not been
998 /// defined. The return value has type ProtocolPtrTy.
999 llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD);
1001 /// Return a reference to the given Class using runtime calls rather than
1002 /// by a symbol reference.
1003 llvm::Value *EmitClassRefViaRuntime(CodeGenFunction &CGF,
1004 const ObjCInterfaceDecl *ID,
1005 ObjCCommonTypesHelper &ObjCTypes);
1007 std::string GetSectionName(StringRef Section, StringRef MachOAttributes);
1010 /// CreateMetadataVar - Create a global variable with internal
1011 /// linkage for use by the Objective-C runtime.
1013 /// This is a convenience wrapper which not only creates the
1014 /// variable, but also sets the section and alignment and adds the
1015 /// global to the "llvm.used" list.
1017 /// \param Name - The variable name.
1018 /// \param Init - The variable initializer; this is also used to
1019 /// define the type of the variable.
1020 /// \param Section - The section the variable should go into, or empty.
1021 /// \param Align - The alignment for the variable, or 0.
1022 /// \param AddToUsed - Whether the variable should be added to
1024 llvm::GlobalVariable *CreateMetadataVar(Twine Name,
1025 ConstantStructBuilder &Init,
1026 StringRef Section, CharUnits Align,
1028 llvm::GlobalVariable *CreateMetadataVar(Twine Name,
1029 llvm::Constant *Init,
1030 StringRef Section, CharUnits Align,
1033 llvm::GlobalVariable *CreateCStringLiteral(StringRef Name,
1034 ObjCLabelType LabelType,
1035 bool ForceNonFragileABI = false,
1036 bool NullTerminate = true);
1039 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
1040 ReturnValueSlot Return,
1041 QualType ResultType,
1046 const CallArgList &CallArgs,
1047 const ObjCMethodDecl *OMD,
1048 const ObjCInterfaceDecl *ClassReceiver,
1049 const ObjCCommonTypesHelper &ObjCTypes);
1051 /// EmitImageInfo - Emit the image info marker used to encode some module
1052 /// level information.
1053 void EmitImageInfo();
1056 CGObjCCommonMac(CodeGen::CodeGenModule &cgm) :
1057 CGObjCRuntime(cgm), VMContext(cgm.getLLVMContext()) { }
1059 bool isNonFragileABI() const {
1060 return ObjCABI == 2;
1063 ConstantAddress GenerateConstantString(const StringLiteral *SL) override;
1064 ConstantAddress GenerateConstantNSString(const StringLiteral *SL);
1066 llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
1067 const ObjCContainerDecl *CD=nullptr) override;
1069 void GenerateProtocol(const ObjCProtocolDecl *PD) override;
1071 /// GetOrEmitProtocol - Get the protocol object for the given
1072 /// declaration, emitting it if necessary. The return value has type
1074 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0;
1076 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1077 /// object for the given declaration, emitting it if needed. These
1078 /// forward references will be filled in with empty bodies if no
1079 /// definition is seen. The return value has type ProtocolPtrTy.
1080 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0;
1082 virtual llvm::Constant *getNSConstantStringClassRef() = 0;
1084 llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
1085 const CGBlockInfo &blockInfo) override;
1086 llvm::Constant *BuildRCBlockLayout(CodeGen::CodeGenModule &CGM,
1087 const CGBlockInfo &blockInfo) override;
1089 llvm::Constant *BuildByrefLayout(CodeGen::CodeGenModule &CGM,
1090 QualType T) override;
1095 enum class MethodListType {
1096 CategoryInstanceMethods,
1097 CategoryClassMethods,
1100 ProtocolInstanceMethods,
1101 ProtocolClassMethods,
1102 OptionalProtocolInstanceMethods,
1103 OptionalProtocolClassMethods,
1106 /// A convenience class for splitting the methods of a protocol into
1107 /// the four interesting groups.
1108 class ProtocolMethodLists {
1111 RequiredInstanceMethods,
1112 RequiredClassMethods,
1113 OptionalInstanceMethods,
1114 OptionalClassMethods
1117 NumProtocolMethodLists = 4
1120 static MethodListType getMethodListKind(Kind kind) {
1122 case RequiredInstanceMethods:
1123 return MethodListType::ProtocolInstanceMethods;
1124 case RequiredClassMethods:
1125 return MethodListType::ProtocolClassMethods;
1126 case OptionalInstanceMethods:
1127 return MethodListType::OptionalProtocolInstanceMethods;
1128 case OptionalClassMethods:
1129 return MethodListType::OptionalProtocolClassMethods;
1131 llvm_unreachable("bad kind");
1134 SmallVector<const ObjCMethodDecl *, 4> Methods[NumProtocolMethodLists];
1136 static ProtocolMethodLists get(const ObjCProtocolDecl *PD) {
1137 ProtocolMethodLists result;
1139 for (auto MD : PD->methods()) {
1140 size_t index = (2 * size_t(MD->isOptional()))
1141 + (size_t(MD->isClassMethod()));
1142 result.Methods[index].push_back(MD);
1148 template <class Self>
1149 SmallVector<llvm::Constant*, 8> emitExtendedTypesArray(Self *self) const {
1150 // In both ABIs, the method types list is parallel with the
1151 // concatenation of the methods arrays in the following order:
1154 // optional instance methods
1155 // optional class methods
1156 SmallVector<llvm::Constant*, 8> result;
1158 // Methods is already in the correct order for both ABIs.
1159 for (auto &list : Methods) {
1160 for (auto MD : list) {
1161 result.push_back(self->GetMethodVarType(MD, true));
1168 template <class Self>
1169 llvm::Constant *emitMethodList(Self *self, const ObjCProtocolDecl *PD,
1171 return self->emitMethodList(PD->getObjCRuntimeNameAsString(),
1172 getMethodListKind(kind), Methods[kind]);
1176 } // end anonymous namespace
1178 class CGObjCMac : public CGObjCCommonMac {
1180 friend ProtocolMethodLists;
1182 ObjCTypesHelper ObjCTypes;
1184 /// EmitModuleInfo - Another marker encoding module level
1186 void EmitModuleInfo();
1188 /// EmitModuleSymols - Emit module symbols, the list of defined
1189 /// classes and categories. The result has type SymtabPtrTy.
1190 llvm::Constant *EmitModuleSymbols();
1192 /// FinishModule - Write out global data structures at the end of
1193 /// processing a translation unit.
1194 void FinishModule();
1196 /// EmitClassExtension - Generate the class extension structure used
1197 /// to store the weak ivar layout and properties. The return value
1198 /// has type ClassExtensionPtrTy.
1199 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID,
1200 CharUnits instanceSize,
1201 bool hasMRCWeakIvars,
1204 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1205 /// for the given class.
1206 llvm::Value *EmitClassRef(CodeGenFunction &CGF,
1207 const ObjCInterfaceDecl *ID);
1209 llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF,
1210 IdentifierInfo *II);
1212 llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) override;
1214 /// EmitSuperClassRef - Emits reference to class's main metadata class.
1215 llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID);
1217 /// EmitIvarList - Emit the ivar list for the given
1218 /// implementation. If ForClass is true the list of class ivars
1219 /// (i.e. metaclass ivars) is emitted, otherwise the list of
1220 /// interface ivars will be emitted. The return value has type
1222 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
1225 /// EmitMetaClass - Emit a forward reference to the class structure
1226 /// for the metaclass of the given interface. The return value has
1227 /// type ClassPtrTy.
1228 llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID);
1230 /// EmitMetaClass - Emit a class structure for the metaclass of the
1231 /// given implementation. The return value has type ClassPtrTy.
1232 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
1233 llvm::Constant *Protocols,
1234 ArrayRef<const ObjCMethodDecl *> Methods);
1236 void emitMethodConstant(ConstantArrayBuilder &builder,
1237 const ObjCMethodDecl *MD);
1239 void emitMethodDescriptionConstant(ConstantArrayBuilder &builder,
1240 const ObjCMethodDecl *MD);
1242 /// EmitMethodList - Emit the method list for the given
1243 /// implementation. The return value has type MethodListPtrTy.
1244 llvm::Constant *emitMethodList(Twine Name, MethodListType MLT,
1245 ArrayRef<const ObjCMethodDecl *> Methods);
1247 /// GetOrEmitProtocol - Get the protocol object for the given
1248 /// declaration, emitting it if necessary. The return value has type
1250 llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) override;
1252 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1253 /// object for the given declaration, emitting it if needed. These
1254 /// forward references will be filled in with empty bodies if no
1255 /// definition is seen. The return value has type ProtocolPtrTy.
1256 llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) override;
1258 /// EmitProtocolExtension - Generate the protocol extension
1259 /// structure used to store optional instance and class methods, and
1260 /// protocol properties. The return value has type
1261 /// ProtocolExtensionPtrTy.
1263 EmitProtocolExtension(const ObjCProtocolDecl *PD,
1264 const ProtocolMethodLists &methodLists);
1266 /// EmitProtocolList - Generate the list of referenced
1267 /// protocols. The return value has type ProtocolListPtrTy.
1268 llvm::Constant *EmitProtocolList(Twine Name,
1269 ObjCProtocolDecl::protocol_iterator begin,
1270 ObjCProtocolDecl::protocol_iterator end);
1272 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
1273 /// for the given selector.
1274 llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel);
1275 Address EmitSelectorAddr(CodeGenFunction &CGF, Selector Sel);
1278 CGObjCMac(CodeGen::CodeGenModule &cgm);
1280 llvm::Constant *getNSConstantStringClassRef() override;
1282 llvm::Function *ModuleInitFunction() override;
1284 CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1285 ReturnValueSlot Return,
1286 QualType ResultType,
1287 Selector Sel, llvm::Value *Receiver,
1288 const CallArgList &CallArgs,
1289 const ObjCInterfaceDecl *Class,
1290 const ObjCMethodDecl *Method) override;
1293 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1294 ReturnValueSlot Return, QualType ResultType,
1295 Selector Sel, const ObjCInterfaceDecl *Class,
1296 bool isCategoryImpl, llvm::Value *Receiver,
1297 bool IsClassMessage, const CallArgList &CallArgs,
1298 const ObjCMethodDecl *Method) override;
1300 llvm::Value *GetClass(CodeGenFunction &CGF,
1301 const ObjCInterfaceDecl *ID) override;
1303 llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel) override;
1304 Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) override;
1306 /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1308 llvm::Value *GetSelector(CodeGenFunction &CGF,
1309 const ObjCMethodDecl *Method) override;
1311 llvm::Constant *GetEHType(QualType T) override;
1313 void GenerateCategory(const ObjCCategoryImplDecl *CMD) override;
1315 void GenerateClass(const ObjCImplementationDecl *ClassDecl) override;
1317 void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) override {}
1319 llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
1320 const ObjCProtocolDecl *PD) override;
1322 llvm::Constant *GetPropertyGetFunction() override;
1323 llvm::Constant *GetPropertySetFunction() override;
1324 llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
1325 bool copy) override;
1326 llvm::Constant *GetGetStructFunction() override;
1327 llvm::Constant *GetSetStructFunction() override;
1328 llvm::Constant *GetCppAtomicObjectGetFunction() override;
1329 llvm::Constant *GetCppAtomicObjectSetFunction() override;
1330 llvm::Constant *EnumerationMutationFunction() override;
1332 void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1333 const ObjCAtTryStmt &S) override;
1334 void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1335 const ObjCAtSynchronizedStmt &S) override;
1336 void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const Stmt &S);
1337 void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S,
1338 bool ClearInsertionPoint=true) override;
1339 llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1340 Address AddrWeakObj) override;
1341 void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1342 llvm::Value *src, Address dst) override;
1343 void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1344 llvm::Value *src, Address dest,
1345 bool threadlocal = false) override;
1346 void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
1347 llvm::Value *src, Address dest,
1348 llvm::Value *ivarOffset) override;
1349 void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
1350 llvm::Value *src, Address dest) override;
1351 void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1352 Address dest, Address src,
1353 llvm::Value *size) override;
1355 LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,
1356 llvm::Value *BaseValue, const ObjCIvarDecl *Ivar,
1357 unsigned CVRQualifiers) override;
1358 llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1359 const ObjCInterfaceDecl *Interface,
1360 const ObjCIvarDecl *Ivar) override;
1363 class CGObjCNonFragileABIMac : public CGObjCCommonMac {
1365 friend ProtocolMethodLists;
1366 ObjCNonFragileABITypesHelper ObjCTypes;
1367 llvm::GlobalVariable* ObjCEmptyCacheVar;
1368 llvm::Constant* ObjCEmptyVtableVar;
1370 /// SuperClassReferences - uniqued super class references.
1371 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
1373 /// MetaClassReferences - uniqued meta class references.
1374 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
1376 /// EHTypeReferences - uniqued class ehtype references.
1377 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
1379 /// VTableDispatchMethods - List of methods for which we generate
1380 /// vtable-based message dispatch.
1381 llvm::DenseSet<Selector> VTableDispatchMethods;
1383 /// DefinedMetaClasses - List of defined meta-classes.
1384 std::vector<llvm::GlobalValue*> DefinedMetaClasses;
1386 /// isVTableDispatchedSelector - Returns true if SEL is a
1387 /// vtable-based selector.
1388 bool isVTableDispatchedSelector(Selector Sel);
1390 /// FinishNonFragileABIModule - Write out global data structures at the end of
1391 /// processing a translation unit.
1392 void FinishNonFragileABIModule();
1394 /// AddModuleClassList - Add the given list of class pointers to the
1395 /// module with the provided symbol and section names.
1396 void AddModuleClassList(ArrayRef<llvm::GlobalValue *> Container,
1397 StringRef SymbolName, StringRef SectionName);
1399 llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags,
1400 unsigned InstanceStart,
1401 unsigned InstanceSize,
1402 const ObjCImplementationDecl *ID);
1403 llvm::GlobalVariable *BuildClassObject(const ObjCInterfaceDecl *CI,
1405 llvm::Constant *IsAGV,
1406 llvm::Constant *SuperClassGV,
1407 llvm::Constant *ClassRoGV,
1408 bool HiddenVisibility);
1410 void emitMethodConstant(ConstantArrayBuilder &builder,
1411 const ObjCMethodDecl *MD,
1414 /// Emit the method list for the given implementation. The return value
1415 /// has type MethodListnfABITy.
1416 llvm::Constant *emitMethodList(Twine Name, MethodListType MLT,
1417 ArrayRef<const ObjCMethodDecl *> Methods);
1419 /// EmitIvarList - Emit the ivar list for the given
1420 /// implementation. If ForClass is true the list of class ivars
1421 /// (i.e. metaclass ivars) is emitted, otherwise the list of
1422 /// interface ivars will be emitted. The return value has type
1423 /// IvarListnfABIPtrTy.
1424 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID);
1426 llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
1427 const ObjCIvarDecl *Ivar,
1428 unsigned long int offset);
1430 /// GetOrEmitProtocol - Get the protocol object for the given
1431 /// declaration, emitting it if necessary. The return value has type
1433 llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) override;
1435 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1436 /// object for the given declaration, emitting it if needed. These
1437 /// forward references will be filled in with empty bodies if no
1438 /// definition is seen. The return value has type ProtocolPtrTy.
1439 llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) override;
1441 /// EmitProtocolList - Generate the list of referenced
1442 /// protocols. The return value has type ProtocolListPtrTy.
1443 llvm::Constant *EmitProtocolList(Twine Name,
1444 ObjCProtocolDecl::protocol_iterator begin,
1445 ObjCProtocolDecl::protocol_iterator end);
1447 CodeGen::RValue EmitVTableMessageSend(CodeGen::CodeGenFunction &CGF,
1448 ReturnValueSlot Return,
1449 QualType ResultType,
1451 llvm::Value *Receiver,
1454 const CallArgList &CallArgs,
1455 const ObjCMethodDecl *Method);
1457 /// GetClassGlobal - Return the global variable for the Objective-C
1458 /// class of the given name.
1459 llvm::Constant *GetClassGlobal(StringRef Name,
1460 ForDefinition_t IsForDefinition,
1461 bool Weak = false, bool DLLImport = false);
1462 llvm::Constant *GetClassGlobal(const ObjCInterfaceDecl *ID,
1464 ForDefinition_t isForDefinition);
1466 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1467 /// for the given class reference.
1468 llvm::Value *EmitClassRef(CodeGenFunction &CGF,
1469 const ObjCInterfaceDecl *ID);
1471 llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF,
1473 const ObjCInterfaceDecl *ID);
1475 llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) override;
1477 /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1478 /// for the given super class reference.
1479 llvm::Value *EmitSuperClassRef(CodeGenFunction &CGF,
1480 const ObjCInterfaceDecl *ID);
1482 /// EmitMetaClassRef - Return a Value * of the address of _class_t
1484 llvm::Value *EmitMetaClassRef(CodeGenFunction &CGF,
1485 const ObjCInterfaceDecl *ID, bool Weak);
1487 /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
1490 llvm::GlobalVariable * ObjCIvarOffsetVariable(
1491 const ObjCInterfaceDecl *ID,
1492 const ObjCIvarDecl *Ivar);
1494 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
1495 /// for the given selector.
1496 llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel);
1497 Address EmitSelectorAddr(CodeGenFunction &CGF, Selector Sel);
1499 /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C
1500 /// interface. The return value has type EHTypePtrTy.
1501 llvm::Constant *GetInterfaceEHType(const ObjCInterfaceDecl *ID,
1502 ForDefinition_t IsForDefinition);
1504 StringRef getMetaclassSymbolPrefix() const { return "OBJC_METACLASS_$_"; }
1506 StringRef getClassSymbolPrefix() const { return "OBJC_CLASS_$_"; }
1508 void GetClassSizeInfo(const ObjCImplementationDecl *OID,
1509 uint32_t &InstanceStart,
1510 uint32_t &InstanceSize);
1512 // Shamelessly stolen from Analysis/CFRefCount.cpp
1513 Selector GetNullarySelector(const char* name) const {
1514 IdentifierInfo* II = &CGM.getContext().Idents.get(name);
1515 return CGM.getContext().Selectors.getSelector(0, &II);
1518 Selector GetUnarySelector(const char* name) const {
1519 IdentifierInfo* II = &CGM.getContext().Idents.get(name);
1520 return CGM.getContext().Selectors.getSelector(1, &II);
1523 /// ImplementationIsNonLazy - Check whether the given category or
1524 /// class implementation is "non-lazy".
1525 bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const;
1527 bool IsIvarOffsetKnownIdempotent(const CodeGen::CodeGenFunction &CGF,
1528 const ObjCIvarDecl *IV) {
1529 // Annotate the load as an invariant load iff inside an instance method
1530 // and ivar belongs to instance method's class and one of its super class.
1531 // This check is needed because the ivar offset is a lazily
1532 // initialised value that may depend on objc_msgSend to perform a fixup on
1533 // the first message dispatch.
1535 // An additional opportunity to mark the load as invariant arises when the
1536 // base of the ivar access is a parameter to an Objective C method.
1537 // However, because the parameters are not available in the current
1538 // interface, we cannot perform this check.
1539 if (const ObjCMethodDecl *MD =
1540 dyn_cast_or_null<ObjCMethodDecl>(CGF.CurFuncDecl))
1541 if (MD->isInstanceMethod())
1542 if (const ObjCInterfaceDecl *ID = MD->getClassInterface())
1543 return IV->getContainingInterface()->isSuperClassOf(ID);
1548 CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
1550 llvm::Constant *getNSConstantStringClassRef() override;
1552 llvm::Function *ModuleInitFunction() override;
1554 CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1555 ReturnValueSlot Return,
1556 QualType ResultType, Selector Sel,
1557 llvm::Value *Receiver,
1558 const CallArgList &CallArgs,
1559 const ObjCInterfaceDecl *Class,
1560 const ObjCMethodDecl *Method) override;
1563 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1564 ReturnValueSlot Return, QualType ResultType,
1565 Selector Sel, const ObjCInterfaceDecl *Class,
1566 bool isCategoryImpl, llvm::Value *Receiver,
1567 bool IsClassMessage, const CallArgList &CallArgs,
1568 const ObjCMethodDecl *Method) override;
1570 llvm::Value *GetClass(CodeGenFunction &CGF,
1571 const ObjCInterfaceDecl *ID) override;
1573 llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel) override
1574 { return EmitSelector(CGF, Sel); }
1575 Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) override
1576 { return EmitSelectorAddr(CGF, Sel); }
1578 /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1580 llvm::Value *GetSelector(CodeGenFunction &CGF,
1581 const ObjCMethodDecl *Method) override
1582 { return EmitSelector(CGF, Method->getSelector()); }
1584 void GenerateCategory(const ObjCCategoryImplDecl *CMD) override;
1586 void GenerateClass(const ObjCImplementationDecl *ClassDecl) override;
1588 void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) override {}
1590 llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
1591 const ObjCProtocolDecl *PD) override;
1593 llvm::Constant *GetEHType(QualType T) override;
1595 llvm::Constant *GetPropertyGetFunction() override {
1596 return ObjCTypes.getGetPropertyFn();
1598 llvm::Constant *GetPropertySetFunction() override {
1599 return ObjCTypes.getSetPropertyFn();
1602 llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
1603 bool copy) override {
1604 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
1607 llvm::Constant *GetSetStructFunction() override {
1608 return ObjCTypes.getCopyStructFn();
1611 llvm::Constant *GetGetStructFunction() override {
1612 return ObjCTypes.getCopyStructFn();
1615 llvm::Constant *GetCppAtomicObjectSetFunction() override {
1616 return ObjCTypes.getCppAtomicObjectFunction();
1619 llvm::Constant *GetCppAtomicObjectGetFunction() override {
1620 return ObjCTypes.getCppAtomicObjectFunction();
1623 llvm::Constant *EnumerationMutationFunction() override {
1624 return ObjCTypes.getEnumerationMutationFn();
1627 void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1628 const ObjCAtTryStmt &S) override;
1629 void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1630 const ObjCAtSynchronizedStmt &S) override;
1631 void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S,
1632 bool ClearInsertionPoint=true) override;
1633 llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1634 Address AddrWeakObj) override;
1635 void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1636 llvm::Value *src, Address edst) override;
1637 void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1638 llvm::Value *src, Address dest,
1639 bool threadlocal = false) override;
1640 void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
1641 llvm::Value *src, Address dest,
1642 llvm::Value *ivarOffset) override;
1643 void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
1644 llvm::Value *src, Address dest) override;
1645 void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1646 Address dest, Address src,
1647 llvm::Value *size) override;
1648 LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,
1649 llvm::Value *BaseValue, const ObjCIvarDecl *Ivar,
1650 unsigned CVRQualifiers) override;
1651 llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1652 const ObjCInterfaceDecl *Interface,
1653 const ObjCIvarDecl *Ivar) override;
1656 /// A helper class for performing the null-initialization of a return
1658 struct NullReturnState {
1659 llvm::BasicBlock *NullBB;
1660 NullReturnState() : NullBB(nullptr) {}
1662 /// Perform a null-check of the given receiver.
1663 void init(CodeGenFunction &CGF, llvm::Value *receiver) {
1664 // Make blocks for the null-receiver and call edges.
1665 NullBB = CGF.createBasicBlock("msgSend.null-receiver");
1666 llvm::BasicBlock *callBB = CGF.createBasicBlock("msgSend.call");
1668 // Check for a null receiver and, if there is one, jump to the
1669 // null-receiver block. There's no point in trying to avoid it:
1670 // we're always going to put *something* there, because otherwise
1671 // we shouldn't have done this null-check in the first place.
1672 llvm::Value *isNull = CGF.Builder.CreateIsNull(receiver);
1673 CGF.Builder.CreateCondBr(isNull, NullBB, callBB);
1675 // Otherwise, start performing the call.
1676 CGF.EmitBlock(callBB);
1679 /// Complete the null-return operation. It is valid to call this
1680 /// regardless of whether 'init' has been called.
1681 RValue complete(CodeGenFunction &CGF, RValue result, QualType resultType,
1682 const CallArgList &CallArgs,
1683 const ObjCMethodDecl *Method) {
1684 // If we never had to do a null-check, just use the raw result.
1685 if (!NullBB) return result;
1687 // The continuation block. This will be left null if we don't have an
1688 // IP, which can happen if the method we're calling is marked noreturn.
1689 llvm::BasicBlock *contBB = nullptr;
1691 // Finish the call path.
1692 llvm::BasicBlock *callBB = CGF.Builder.GetInsertBlock();
1694 contBB = CGF.createBasicBlock("msgSend.cont");
1695 CGF.Builder.CreateBr(contBB);
1698 // Okay, start emitting the null-receiver block.
1699 CGF.EmitBlock(NullBB);
1701 // Release any consumed arguments we've got.
1703 CallArgList::const_iterator I = CallArgs.begin();
1704 for (ObjCMethodDecl::param_const_iterator i = Method->param_begin(),
1705 e = Method->param_end(); i != e; ++i, ++I) {
1706 const ParmVarDecl *ParamDecl = (*i);
1707 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
1709 assert(RV.isScalar() &&
1710 "NullReturnState::complete - arg not on object");
1711 CGF.EmitARCRelease(RV.getScalarVal(), ARCImpreciseLifetime);
1716 // The phi code below assumes that we haven't needed any control flow yet.
1717 assert(CGF.Builder.GetInsertBlock() == NullBB);
1719 // If we've got a void return, just jump to the continuation block.
1720 if (result.isScalar() && resultType->isVoidType()) {
1721 // No jumps required if the message-send was noreturn.
1722 if (contBB) CGF.EmitBlock(contBB);
1726 // If we've got a scalar return, build a phi.
1727 if (result.isScalar()) {
1728 // Derive the null-initialization value.
1729 llvm::Constant *null = CGF.CGM.EmitNullConstant(resultType);
1731 // If no join is necessary, just flow out.
1732 if (!contBB) return RValue::get(null);
1734 // Otherwise, build a phi.
1735 CGF.EmitBlock(contBB);
1736 llvm::PHINode *phi = CGF.Builder.CreatePHI(null->getType(), 2);
1737 phi->addIncoming(result.getScalarVal(), callBB);
1738 phi->addIncoming(null, NullBB);
1739 return RValue::get(phi);
1742 // If we've got an aggregate return, null the buffer out.
1743 // FIXME: maybe we should be doing things differently for all the
1744 // cases where the ABI has us returning (1) non-agg values in
1745 // memory or (2) agg values in registers.
1746 if (result.isAggregate()) {
1747 assert(result.isAggregate() && "null init of non-aggregate result?");
1748 CGF.EmitNullInitialization(result.getAggregateAddress(), resultType);
1749 if (contBB) CGF.EmitBlock(contBB);
1754 CGF.EmitBlock(contBB);
1755 CodeGenFunction::ComplexPairTy callResult = result.getComplexVal();
1757 // Find the scalar type and its zero value.
1758 llvm::Type *scalarTy = callResult.first->getType();
1759 llvm::Constant *scalarZero = llvm::Constant::getNullValue(scalarTy);
1761 // Build phis for both coordinates.
1762 llvm::PHINode *real = CGF.Builder.CreatePHI(scalarTy, 2);
1763 real->addIncoming(callResult.first, callBB);
1764 real->addIncoming(scalarZero, NullBB);
1765 llvm::PHINode *imag = CGF.Builder.CreatePHI(scalarTy, 2);
1766 imag->addIncoming(callResult.second, callBB);
1767 imag->addIncoming(scalarZero, NullBB);
1768 return RValue::getComplex(real, imag);
1772 } // end anonymous namespace
1774 /* *** Helper Functions *** */
1776 /// getConstantGEP() - Help routine to construct simple GEPs.
1777 static llvm::Constant *getConstantGEP(llvm::LLVMContext &VMContext,
1778 llvm::GlobalVariable *C, unsigned idx0,
1780 llvm::Value *Idxs[] = {
1781 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1782 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
1784 return llvm::ConstantExpr::getGetElementPtr(C->getValueType(), C, Idxs);
1787 /// hasObjCExceptionAttribute - Return true if this class or any super
1788 /// class has the __objc_exception__ attribute.
1789 static bool hasObjCExceptionAttribute(ASTContext &Context,
1790 const ObjCInterfaceDecl *OID) {
1791 if (OID->hasAttr<ObjCExceptionAttr>())
1793 if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
1794 return hasObjCExceptionAttribute(Context, Super);
1798 /* *** CGObjCMac Public Interface *** */
1800 CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm),
1806 /// GetClass - Return a reference to the class for the given interface
1808 llvm::Value *CGObjCMac::GetClass(CodeGenFunction &CGF,
1809 const ObjCInterfaceDecl *ID) {
1810 return EmitClassRef(CGF, ID);
1813 /// GetSelector - Return the pointer to the unique'd string for this selector.
1814 llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, Selector Sel) {
1815 return EmitSelector(CGF, Sel);
1817 Address CGObjCMac::GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) {
1818 return EmitSelectorAddr(CGF, Sel);
1820 llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, const ObjCMethodDecl
1822 return EmitSelector(CGF, Method->getSelector());
1825 llvm::Constant *CGObjCMac::GetEHType(QualType T) {
1826 if (T->isObjCIdType() ||
1827 T->isObjCQualifiedIdType()) {
1828 return CGM.GetAddrOfRTTIDescriptor(
1829 CGM.getContext().getObjCIdRedefinitionType(), /*ForEH=*/true);
1831 if (T->isObjCClassType() ||
1832 T->isObjCQualifiedClassType()) {
1833 return CGM.GetAddrOfRTTIDescriptor(
1834 CGM.getContext().getObjCClassRedefinitionType(), /*ForEH=*/true);
1836 if (T->isObjCObjectPointerType())
1837 return CGM.GetAddrOfRTTIDescriptor(T, /*ForEH=*/true);
1839 llvm_unreachable("asking for catch type for ObjC type in fragile runtime");
1842 /// Generate a constant CFString object.
1844 struct __builtin_CFString {
1845 const int *isa; // point to __CFConstantStringClassReference
1852 /// or Generate a constant NSString object.
1854 struct __builtin_NSString {
1855 const int *isa; // point to __NSConstantStringClassReference
1857 unsigned int length;
1862 CGObjCCommonMac::GenerateConstantString(const StringLiteral *SL) {
1863 return (!CGM.getLangOpts().NoConstantCFStrings
1864 ? CGM.GetAddrOfConstantCFString(SL)
1865 : GenerateConstantNSString(SL));
1868 static llvm::StringMapEntry<llvm::GlobalVariable *> &
1869 GetConstantStringEntry(llvm::StringMap<llvm::GlobalVariable *> &Map,
1870 const StringLiteral *Literal, unsigned &StringLength) {
1871 StringRef String = Literal->getString();
1872 StringLength = String.size();
1873 return *Map.insert(std::make_pair(String, nullptr)).first;
1876 llvm::Constant *CGObjCMac::getNSConstantStringClassRef() {
1877 if (llvm::Value *V = ConstantStringClassRef)
1878 return cast<llvm::Constant>(V);
1880 auto &StringClass = CGM.getLangOpts().ObjCConstantStringClass;
1882 StringClass.empty() ? "_NSConstantStringClassReference"
1883 : "_" + StringClass + "ClassReference";
1885 llvm::Type *PTy = llvm::ArrayType::get(CGM.IntTy, 0);
1886 auto GV = CGM.CreateRuntimeVariable(PTy, str);
1887 auto V = llvm::ConstantExpr::getBitCast(GV, CGM.IntTy->getPointerTo());
1888 ConstantStringClassRef = V;
1892 llvm::Constant *CGObjCNonFragileABIMac::getNSConstantStringClassRef() {
1893 if (llvm::Value *V = ConstantStringClassRef)
1894 return cast<llvm::Constant>(V);
1896 auto &StringClass = CGM.getLangOpts().ObjCConstantStringClass;
1898 StringClass.empty() ? "OBJC_CLASS_$_NSConstantString"
1899 : "OBJC_CLASS_$_" + StringClass;
1900 auto GV = GetClassGlobal(str, NotForDefinition);
1902 // Make sure the result is of the correct type.
1903 auto V = llvm::ConstantExpr::getBitCast(GV, CGM.IntTy->getPointerTo());
1905 ConstantStringClassRef = V;
1910 CGObjCCommonMac::GenerateConstantNSString(const StringLiteral *Literal) {
1911 unsigned StringLength = 0;
1912 llvm::StringMapEntry<llvm::GlobalVariable *> &Entry =
1913 GetConstantStringEntry(NSConstantStringMap, Literal, StringLength);
1915 if (auto *C = Entry.second)
1916 return ConstantAddress(C, CharUnits::fromQuantity(C->getAlignment()));
1918 // If we don't already have it, get _NSConstantStringClassReference.
1919 llvm::Constant *Class = getNSConstantStringClassRef();
1921 // If we don't already have it, construct the type for a constant NSString.
1922 if (!NSConstantStringType) {
1923 NSConstantStringType =
1924 llvm::StructType::create({
1925 CGM.Int32Ty->getPointerTo(),
1928 }, "struct.__builtin_NSString");
1931 ConstantInitBuilder Builder(CGM);
1932 auto Fields = Builder.beginStruct(NSConstantStringType);
1939 llvm::ConstantDataArray::getString(VMContext, Entry.first());
1941 llvm::GlobalValue::LinkageTypes Linkage = llvm::GlobalValue::PrivateLinkage;
1942 bool isConstant = !CGM.getLangOpts().WritableStrings;
1944 auto *GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), isConstant,
1945 Linkage, C, ".str");
1946 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1947 // Don't enforce the target's minimum global alignment, since the only use
1948 // of the string is via this class initializer.
1949 GV->setAlignment(1);
1950 Fields.addBitCast(GV, CGM.Int8PtrTy);
1953 Fields.addInt(CGM.IntTy, StringLength);
1956 CharUnits Alignment = CGM.getPointerAlign();
1957 GV = Fields.finishAndCreateGlobal("_unnamed_nsstring_", Alignment,
1959 llvm::GlobalVariable::PrivateLinkage);
1960 const char *NSStringSection = "__OBJC,__cstring_object,regular,no_dead_strip";
1961 const char *NSStringNonFragileABISection =
1962 "__DATA,__objc_stringobj,regular,no_dead_strip";
1963 // FIXME. Fix section.
1964 GV->setSection(CGM.getLangOpts().ObjCRuntime.isNonFragile()
1965 ? NSStringNonFragileABISection
1969 return ConstantAddress(GV, Alignment);
1973 kCFTaggedObjectID_Integer = (1 << 1) + 1
1976 /// Generates a message send where the super is the receiver. This is
1977 /// a message send to self with special delivery semantics indicating
1978 /// which class's method should be called.
1980 CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1981 ReturnValueSlot Return,
1982 QualType ResultType,
1984 const ObjCInterfaceDecl *Class,
1985 bool isCategoryImpl,
1986 llvm::Value *Receiver,
1987 bool IsClassMessage,
1988 const CodeGen::CallArgList &CallArgs,
1989 const ObjCMethodDecl *Method) {
1990 // Create and init a super structure; this is a (receiver, class)
1991 // pair we will pass to objc_msgSendSuper.
1993 CGF.CreateTempAlloca(ObjCTypes.SuperTy, CGF.getPointerAlign(),
1995 llvm::Value *ReceiverAsObject =
1996 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
1997 CGF.Builder.CreateStore(
1999 CGF.Builder.CreateStructGEP(ObjCSuper, 0, CharUnits::Zero()));
2001 // If this is a class message the metaclass is passed as the target.
2002 llvm::Value *Target;
2003 if (IsClassMessage) {
2004 if (isCategoryImpl) {
2005 // Message sent to 'super' in a class method defined in a category
2006 // implementation requires an odd treatment.
2007 // If we are in a class method, we must retrieve the
2008 // _metaclass_ for the current class, pointed at by
2009 // the class's "isa" pointer. The following assumes that
2010 // isa" is the first ivar in a class (which it must be).
2011 Target = EmitClassRef(CGF, Class->getSuperClass());
2012 Target = CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, Target, 0);
2013 Target = CGF.Builder.CreateAlignedLoad(Target, CGF.getPointerAlign());
2015 llvm::Constant *MetaClassPtr = EmitMetaClassRef(Class);
2016 llvm::Value *SuperPtr =
2017 CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, MetaClassPtr, 1);
2018 llvm::Value *Super =
2019 CGF.Builder.CreateAlignedLoad(SuperPtr, CGF.getPointerAlign());
2022 } else if (isCategoryImpl)
2023 Target = EmitClassRef(CGF, Class->getSuperClass());
2025 llvm::Value *ClassPtr = EmitSuperClassRef(Class);
2026 ClassPtr = CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, ClassPtr, 1);
2027 Target = CGF.Builder.CreateAlignedLoad(ClassPtr, CGF.getPointerAlign());
2029 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
2031 llvm::Type *ClassTy =
2032 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
2033 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
2034 CGF.Builder.CreateStore(Target,
2035 CGF.Builder.CreateStructGEP(ObjCSuper, 1, CGF.getPointerSize()));
2036 return EmitMessageSend(CGF, Return, ResultType,
2037 EmitSelector(CGF, Sel),
2038 ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy,
2039 true, CallArgs, Method, Class, ObjCTypes);
2042 /// Generate code for a message send expression.
2043 CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
2044 ReturnValueSlot Return,
2045 QualType ResultType,
2047 llvm::Value *Receiver,
2048 const CallArgList &CallArgs,
2049 const ObjCInterfaceDecl *Class,
2050 const ObjCMethodDecl *Method) {
2051 return EmitMessageSend(CGF, Return, ResultType,
2052 EmitSelector(CGF, Sel),
2053 Receiver, CGF.getContext().getObjCIdType(),
2054 false, CallArgs, Method, Class, ObjCTypes);
2057 static bool isWeakLinkedClass(const ObjCInterfaceDecl *ID) {
2059 if (ID->isWeakImported())
2061 } while ((ID = ID->getSuperClass()));
2067 CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
2068 ReturnValueSlot Return,
2069 QualType ResultType,
2074 const CallArgList &CallArgs,
2075 const ObjCMethodDecl *Method,
2076 const ObjCInterfaceDecl *ClassReceiver,
2077 const ObjCCommonTypesHelper &ObjCTypes) {
2078 CallArgList ActualArgs;
2080 Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy);
2081 ActualArgs.add(RValue::get(Arg0), Arg0Ty);
2082 ActualArgs.add(RValue::get(Sel), CGF.getContext().getObjCSelType());
2083 ActualArgs.addFrom(CallArgs);
2085 // If we're calling a method, use the formal signature.
2086 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2089 assert(CGM.getContext().getCanonicalType(Method->getReturnType()) ==
2090 CGM.getContext().getCanonicalType(ResultType) &&
2091 "Result type mismatch!");
2093 bool ReceiverCanBeNull = true;
2095 // Super dispatch assumes that self is non-null; even the messenger
2096 // doesn't have a null check internally.
2098 ReceiverCanBeNull = false;
2100 // If this is a direct dispatch of a class method, check whether the class,
2101 // or anything in its hierarchy, was weak-linked.
2102 } else if (ClassReceiver && Method && Method->isClassMethod()) {
2103 ReceiverCanBeNull = isWeakLinkedClass(ClassReceiver);
2105 // If we're emitting a method, and self is const (meaning just ARC, for now),
2106 // and the receiver is a load of self, then self is a valid object.
2107 } else if (auto CurMethod =
2108 dyn_cast_or_null<ObjCMethodDecl>(CGF.CurCodeDecl)) {
2109 auto Self = CurMethod->getSelfDecl();
2110 if (Self->getType().isConstQualified()) {
2111 if (auto LI = dyn_cast<llvm::LoadInst>(Arg0->stripPointerCasts())) {
2112 llvm::Value *SelfAddr = CGF.GetAddrOfLocalVar(Self).getPointer();
2113 if (SelfAddr == LI->getPointerOperand()) {
2114 ReceiverCanBeNull = false;
2120 NullReturnState nullReturn;
2122 llvm::Constant *Fn = nullptr;
2123 if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
2124 if (ReceiverCanBeNull) nullReturn.init(CGF, Arg0);
2125 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
2126 : ObjCTypes.getSendStretFn(IsSuper);
2127 } else if (CGM.ReturnTypeUsesFPRet(ResultType)) {
2128 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
2129 : ObjCTypes.getSendFpretFn(IsSuper);
2130 } else if (CGM.ReturnTypeUsesFP2Ret(ResultType)) {
2131 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
2132 : ObjCTypes.getSendFp2retFn(IsSuper);
2134 // arm64 uses objc_msgSend for stret methods and yet null receiver check
2135 // must be made for it.
2136 if (ReceiverCanBeNull && CGM.ReturnTypeUsesSRet(MSI.CallInfo))
2137 nullReturn.init(CGF, Arg0);
2138 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
2139 : ObjCTypes.getSendFn(IsSuper);
2142 // Emit a null-check if there's a consumed argument other than the receiver.
2143 bool RequiresNullCheck = false;
2144 if (ReceiverCanBeNull && CGM.getLangOpts().ObjCAutoRefCount && Method) {
2145 for (const auto *ParamDecl : Method->parameters()) {
2146 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
2147 if (!nullReturn.NullBB)
2148 nullReturn.init(CGF, Arg0);
2149 RequiresNullCheck = true;
2155 llvm::Instruction *CallSite;
2156 Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType);
2157 CGCallee Callee = CGCallee::forDirect(Fn);
2158 RValue rvalue = CGF.EmitCall(MSI.CallInfo, Callee, Return, ActualArgs,
2161 // Mark the call as noreturn if the method is marked noreturn and the
2162 // receiver cannot be null.
2163 if (Method && Method->hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {
2164 llvm::CallSite(CallSite).setDoesNotReturn();
2167 return nullReturn.complete(CGF, rvalue, ResultType, CallArgs,
2168 RequiresNullCheck ? Method : nullptr);
2171 static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT,
2172 bool pointee = false) {
2173 // Note that GC qualification applies recursively to C pointer types
2174 // that aren't otherwise decorated. This is weird, but it's probably
2175 // an intentional workaround to the unreliable placement of GC qualifiers.
2176 if (FQT.isObjCGCStrong())
2177 return Qualifiers::Strong;
2179 if (FQT.isObjCGCWeak())
2180 return Qualifiers::Weak;
2182 if (auto ownership = FQT.getObjCLifetime()) {
2183 // Ownership does not apply recursively to C pointer types.
2184 if (pointee) return Qualifiers::GCNone;
2185 switch (ownership) {
2186 case Qualifiers::OCL_Weak: return Qualifiers::Weak;
2187 case Qualifiers::OCL_Strong: return Qualifiers::Strong;
2188 case Qualifiers::OCL_ExplicitNone: return Qualifiers::GCNone;
2189 case Qualifiers::OCL_Autoreleasing: llvm_unreachable("autoreleasing ivar?");
2190 case Qualifiers::OCL_None: llvm_unreachable("known nonzero");
2192 llvm_unreachable("bad objc ownership");
2195 // Treat unqualified retainable pointers as strong.
2196 if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
2197 return Qualifiers::Strong;
2199 // Walk into C pointer types, but only in GC.
2200 if (Ctx.getLangOpts().getGC() != LangOptions::NonGC) {
2201 if (const PointerType *PT = FQT->getAs<PointerType>())
2202 return GetGCAttrTypeForType(Ctx, PT->getPointeeType(), /*pointee*/ true);
2205 return Qualifiers::GCNone;
2211 uint64_t SizeInWords;
2212 IvarInfo(CharUnits offset, uint64_t sizeInWords)
2213 : Offset(offset), SizeInWords(sizeInWords) {}
2215 // Allow sorting based on byte pos.
2216 bool operator<(const IvarInfo &other) const {
2217 return Offset < other.Offset;
2221 /// A helper class for building GC layout strings.
2222 class IvarLayoutBuilder {
2225 /// The start of the layout. Offsets will be relative to this value,
2226 /// and entries less than this value will be silently discarded.
2227 CharUnits InstanceBegin;
2229 /// The end of the layout. Offsets will never exceed this value.
2230 CharUnits InstanceEnd;
2232 /// Whether we're generating the strong layout or the weak layout.
2233 bool ForStrongLayout;
2235 /// Whether the offsets in IvarsInfo might be out-of-order.
2236 bool IsDisordered = false;
2238 llvm::SmallVector<IvarInfo, 8> IvarsInfo;
2241 IvarLayoutBuilder(CodeGenModule &CGM, CharUnits instanceBegin,
2242 CharUnits instanceEnd, bool forStrongLayout)
2243 : CGM(CGM), InstanceBegin(instanceBegin), InstanceEnd(instanceEnd),
2244 ForStrongLayout(forStrongLayout) {
2247 void visitRecord(const RecordType *RT, CharUnits offset);
2249 template <class Iterator, class GetOffsetFn>
2250 void visitAggregate(Iterator begin, Iterator end,
2251 CharUnits aggrOffset,
2252 const GetOffsetFn &getOffset);
2254 void visitField(const FieldDecl *field, CharUnits offset);
2256 /// Add the layout of a block implementation.
2257 void visitBlock(const CGBlockInfo &blockInfo);
2259 /// Is there any information for an interesting bitmap?
2260 bool hasBitmapData() const { return !IvarsInfo.empty(); }
2262 llvm::Constant *buildBitmap(CGObjCCommonMac &CGObjC,
2263 llvm::SmallVectorImpl<unsigned char> &buffer);
2265 static void dump(ArrayRef<unsigned char> buffer) {
2266 const unsigned char *s = buffer.data();
2267 for (unsigned i = 0, e = buffer.size(); i < e; i++)
2269 printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
2271 printf("0x%x%s", s[i], s[i] != 0 ? ", " : "");
2275 } // end anonymous namespace
2277 llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
2278 const CGBlockInfo &blockInfo) {
2280 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
2281 if (CGM.getLangOpts().getGC() == LangOptions::NonGC)
2284 IvarLayoutBuilder builder(CGM, CharUnits::Zero(), blockInfo.BlockSize,
2285 /*for strong layout*/ true);
2287 builder.visitBlock(blockInfo);
2289 if (!builder.hasBitmapData())
2292 llvm::SmallVector<unsigned char, 32> buffer;
2293 llvm::Constant *C = builder.buildBitmap(*this, buffer);
2294 if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
2295 printf("\n block variable layout for block: ");
2296 builder.dump(buffer);
2302 void IvarLayoutBuilder::visitBlock(const CGBlockInfo &blockInfo) {
2303 // __isa is the first field in block descriptor and must assume by runtime's
2304 // convention that it is GC'able.
2305 IvarsInfo.push_back(IvarInfo(CharUnits::Zero(), 1));
2307 const BlockDecl *blockDecl = blockInfo.getBlockDecl();
2309 // Ignore the optional 'this' capture: C++ objects are not assumed
2312 CharUnits lastFieldOffset;
2314 // Walk the captured variables.
2315 for (const auto &CI : blockDecl->captures()) {
2316 const VarDecl *variable = CI.getVariable();
2317 QualType type = variable->getType();
2319 const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
2321 // Ignore constant captures.
2322 if (capture.isConstant()) continue;
2324 CharUnits fieldOffset = capture.getOffset();
2326 // Block fields are not necessarily ordered; if we detect that we're
2327 // adding them out-of-order, make sure we sort later.
2328 if (fieldOffset < lastFieldOffset)
2329 IsDisordered = true;
2330 lastFieldOffset = fieldOffset;
2332 // __block variables are passed by their descriptor address.
2334 IvarsInfo.push_back(IvarInfo(fieldOffset, /*size in words*/ 1));
2338 assert(!type->isArrayType() && "array variable should not be caught");
2339 if (const RecordType *record = type->getAs<RecordType>()) {
2340 visitRecord(record, fieldOffset);
2344 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), type);
2346 if (GCAttr == Qualifiers::Strong) {
2347 assert(CGM.getContext().getTypeSize(type)
2348 == CGM.getTarget().getPointerWidth(0));
2349 IvarsInfo.push_back(IvarInfo(fieldOffset, /*size in words*/ 1));
2354 /// getBlockCaptureLifetime - This routine returns life time of the captured
2355 /// block variable for the purpose of block layout meta-data generation. FQT is
2356 /// the type of the variable captured in the block.
2357 Qualifiers::ObjCLifetime CGObjCCommonMac::getBlockCaptureLifetime(QualType FQT,
2359 // If it has an ownership qualifier, we're done.
2360 if (auto lifetime = FQT.getObjCLifetime())
2363 // If it doesn't, and this is ARC, it has no ownership.
2364 if (CGM.getLangOpts().ObjCAutoRefCount)
2365 return Qualifiers::OCL_None;
2367 // In MRC, retainable pointers are owned by non-__block variables.
2368 if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
2369 return ByrefLayout ? Qualifiers::OCL_ExplicitNone : Qualifiers::OCL_Strong;
2371 return Qualifiers::OCL_None;
2374 void CGObjCCommonMac::UpdateRunSkipBlockVars(bool IsByref,
2375 Qualifiers::ObjCLifetime LifeTime,
2376 CharUnits FieldOffset,
2377 CharUnits FieldSize) {
2378 // __block variables are passed by their descriptor address.
2380 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset,
2382 else if (LifeTime == Qualifiers::OCL_Strong)
2383 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset,
2385 else if (LifeTime == Qualifiers::OCL_Weak)
2386 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset,
2388 else if (LifeTime == Qualifiers::OCL_ExplicitNone)
2389 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset,
2392 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES,
2397 void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
2398 const RecordDecl *RD,
2399 ArrayRef<const FieldDecl*> RecFields,
2400 CharUnits BytePos, bool &HasUnion,
2402 bool IsUnion = (RD && RD->isUnion());
2403 CharUnits MaxUnionSize = CharUnits::Zero();
2404 const FieldDecl *MaxField = nullptr;
2405 const FieldDecl *LastFieldBitfieldOrUnnamed = nullptr;
2406 CharUnits MaxFieldOffset = CharUnits::Zero();
2407 CharUnits LastBitfieldOrUnnamedOffset = CharUnits::Zero();
2409 if (RecFields.empty())
2411 unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
2413 for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
2414 const FieldDecl *Field = RecFields[i];
2415 // Note that 'i' here is actually the field index inside RD of Field,
2416 // although this dependency is hidden.
2417 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2418 CharUnits FieldOffset =
2419 CGM.getContext().toCharUnitsFromBits(RL.getFieldOffset(i));
2421 // Skip over unnamed or bitfields
2422 if (!Field->getIdentifier() || Field->isBitField()) {
2423 LastFieldBitfieldOrUnnamed = Field;
2424 LastBitfieldOrUnnamedOffset = FieldOffset;
2428 LastFieldBitfieldOrUnnamed = nullptr;
2429 QualType FQT = Field->getType();
2430 if (FQT->isRecordType() || FQT->isUnionType()) {
2431 if (FQT->isUnionType())
2434 BuildRCBlockVarRecordLayout(FQT->getAs<RecordType>(),
2435 BytePos + FieldOffset, HasUnion);
2439 if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
2440 const ConstantArrayType *CArray =
2441 dyn_cast_or_null<ConstantArrayType>(Array);
2442 uint64_t ElCount = CArray->getSize().getZExtValue();
2443 assert(CArray && "only array with known element size is supported");
2444 FQT = CArray->getElementType();
2445 while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
2446 const ConstantArrayType *CArray =
2447 dyn_cast_or_null<ConstantArrayType>(Array);
2448 ElCount *= CArray->getSize().getZExtValue();
2449 FQT = CArray->getElementType();
2451 if (FQT->isRecordType() && ElCount) {
2452 int OldIndex = RunSkipBlockVars.size() - 1;
2453 const RecordType *RT = FQT->getAs<RecordType>();
2454 BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset,
2457 // Replicate layout information for each array element. Note that
2458 // one element is already done.
2460 for (int FirstIndex = RunSkipBlockVars.size() - 1 ;ElIx < ElCount; ElIx++) {
2461 CharUnits Size = CGM.getContext().getTypeSizeInChars(RT);
2462 for (int i = OldIndex+1; i <= FirstIndex; ++i)
2463 RunSkipBlockVars.push_back(
2464 RUN_SKIP(RunSkipBlockVars[i].opcode,
2465 RunSkipBlockVars[i].block_var_bytepos + Size*ElIx,
2466 RunSkipBlockVars[i].block_var_size));
2471 CharUnits FieldSize = CGM.getContext().getTypeSizeInChars(Field->getType());
2473 CharUnits UnionIvarSize = FieldSize;
2474 if (UnionIvarSize > MaxUnionSize) {
2475 MaxUnionSize = UnionIvarSize;
2477 MaxFieldOffset = FieldOffset;
2480 UpdateRunSkipBlockVars(false,
2481 getBlockCaptureLifetime(FQT, ByrefLayout),
2482 BytePos + FieldOffset,
2487 if (LastFieldBitfieldOrUnnamed) {
2488 if (LastFieldBitfieldOrUnnamed->isBitField()) {
2489 // Last field was a bitfield. Must update the info.
2490 uint64_t BitFieldSize
2491 = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext());
2492 unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
2493 ((BitFieldSize % ByteSizeInBits) != 0);
2494 CharUnits Size = CharUnits::fromQuantity(UnsSize);
2495 Size += LastBitfieldOrUnnamedOffset;
2496 UpdateRunSkipBlockVars(false,
2497 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType(),
2499 BytePos + LastBitfieldOrUnnamedOffset,
2502 assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed");
2503 // Last field was unnamed. Must update skip info.
2505 = CGM.getContext().getTypeSizeInChars(LastFieldBitfieldOrUnnamed->getType());
2506 UpdateRunSkipBlockVars(false,
2507 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType(),
2509 BytePos + LastBitfieldOrUnnamedOffset,
2515 UpdateRunSkipBlockVars(false,
2516 getBlockCaptureLifetime(MaxField->getType(), ByrefLayout),
2517 BytePos + MaxFieldOffset,
2521 void CGObjCCommonMac::BuildRCBlockVarRecordLayout(const RecordType *RT,
2525 const RecordDecl *RD = RT->getDecl();
2526 SmallVector<const FieldDecl*, 16> Fields(RD->fields());
2527 llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
2528 const llvm::StructLayout *RecLayout =
2529 CGM.getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
2531 BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);
2534 /// InlineLayoutInstruction - This routine produce an inline instruction for the
2535 /// block variable layout if it can. If not, it returns 0. Rules are as follow:
2536 /// If ((uintptr_t) layout) < (1 << 12), the layout is inline. In the 64bit world,
2537 /// an inline layout of value 0x0000000000000xyz is interpreted as follows:
2538 /// x captured object pointers of BLOCK_LAYOUT_STRONG. Followed by
2539 /// y captured object of BLOCK_LAYOUT_BYREF. Followed by
2540 /// z captured object of BLOCK_LAYOUT_WEAK. If any of the above is missing, zero
2541 /// replaces it. For example, 0x00000x00 means x BLOCK_LAYOUT_STRONG and no
2542 /// BLOCK_LAYOUT_BYREF and no BLOCK_LAYOUT_WEAK objects are captured.
2543 uint64_t CGObjCCommonMac::InlineLayoutInstruction(
2544 SmallVectorImpl<unsigned char> &Layout) {
2545 uint64_t Result = 0;
2546 if (Layout.size() <= 3) {
2547 unsigned size = Layout.size();
2548 unsigned strong_word_count = 0, byref_word_count=0, weak_word_count=0;
2550 enum BLOCK_LAYOUT_OPCODE opcode ;
2554 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2555 if (opcode == BLOCK_LAYOUT_STRONG)
2556 strong_word_count = (inst & 0xF)+1;
2560 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2561 if (opcode == BLOCK_LAYOUT_BYREF)
2562 byref_word_count = (inst & 0xF)+1;
2566 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2567 if (opcode == BLOCK_LAYOUT_WEAK)
2568 weak_word_count = (inst & 0xF)+1;
2575 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2576 if (opcode == BLOCK_LAYOUT_STRONG) {
2577 strong_word_count = (inst & 0xF)+1;
2579 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2580 if (opcode == BLOCK_LAYOUT_BYREF)
2581 byref_word_count = (inst & 0xF)+1;
2582 else if (opcode == BLOCK_LAYOUT_WEAK)
2583 weak_word_count = (inst & 0xF)+1;
2587 else if (opcode == BLOCK_LAYOUT_BYREF) {
2588 byref_word_count = (inst & 0xF)+1;
2590 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2591 if (opcode == BLOCK_LAYOUT_WEAK)
2592 weak_word_count = (inst & 0xF)+1;
2602 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2603 if (opcode == BLOCK_LAYOUT_STRONG)
2604 strong_word_count = (inst & 0xF)+1;
2605 else if (opcode == BLOCK_LAYOUT_BYREF)
2606 byref_word_count = (inst & 0xF)+1;
2607 else if (opcode == BLOCK_LAYOUT_WEAK)
2608 weak_word_count = (inst & 0xF)+1;
2617 // Cannot inline when any of the word counts is 15. Because this is one less
2618 // than the actual work count (so 15 means 16 actual word counts),
2619 // and we can only display 0 thru 15 word counts.
2620 if (strong_word_count == 16 || byref_word_count == 16 || weak_word_count == 16)
2624 (strong_word_count != 0) + (byref_word_count != 0) + (weak_word_count != 0);
2626 if (size == count) {
2627 if (strong_word_count)
2628 Result = strong_word_count;
2630 if (byref_word_count)
2631 Result += byref_word_count;
2633 if (weak_word_count)
2634 Result += weak_word_count;
2640 llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(bool ComputeByrefLayout) {
2641 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
2642 if (RunSkipBlockVars.empty())
2644 unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(0);
2645 unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
2646 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2648 // Sort on byte position; captures might not be allocated in order,
2649 // and unions can do funny things.
2650 llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());
2651 SmallVector<unsigned char, 16> Layout;
2653 unsigned size = RunSkipBlockVars.size();
2654 for (unsigned i = 0; i < size; i++) {
2655 enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
2656 CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
2657 CharUnits end_byte_pos = start_byte_pos;
2660 if (opcode == RunSkipBlockVars[j].opcode) {
2661 end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
2667 CharUnits size_in_bytes =
2668 end_byte_pos - start_byte_pos + RunSkipBlockVars[j-1].block_var_size;
2671 RunSkipBlockVars[j].block_var_bytepos -
2672 RunSkipBlockVars[j-1].block_var_bytepos - RunSkipBlockVars[j-1].block_var_size;
2673 size_in_bytes += gap;
2675 CharUnits residue_in_bytes = CharUnits::Zero();
2676 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
2677 residue_in_bytes = size_in_bytes % WordSizeInBytes;
2678 size_in_bytes -= residue_in_bytes;
2679 opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
2682 unsigned size_in_words = size_in_bytes.getQuantity() / WordSizeInBytes;
2683 while (size_in_words >= 16) {
2684 // Note that value in imm. is one less that the actual
2685 // value. So, 0xf means 16 words follow!
2686 unsigned char inst = (opcode << 4) | 0xf;
2687 Layout.push_back(inst);
2688 size_in_words -= 16;
2690 if (size_in_words > 0) {
2691 // Note that value in imm. is one less that the actual
2692 // value. So, we subtract 1 away!
2693 unsigned char inst = (opcode << 4) | (size_in_words-1);
2694 Layout.push_back(inst);
2696 if (residue_in_bytes > CharUnits::Zero()) {
2697 unsigned char inst =
2698 (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) | (residue_in_bytes.getQuantity()-1);
2699 Layout.push_back(inst);
2703 while (!Layout.empty()) {
2704 unsigned char inst = Layout.back();
2705 enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2706 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES || opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
2712 uint64_t Result = InlineLayoutInstruction(Layout);
2714 // Block variable layout instruction has been inlined.
2715 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
2716 if (ComputeByrefLayout)
2717 printf("\n Inline BYREF variable layout: ");
2719 printf("\n Inline block variable layout: ");
2720 printf("0x0%" PRIx64 "", Result);
2721 if (auto numStrong = (Result & 0xF00) >> 8)
2722 printf(", BL_STRONG:%d", (int) numStrong);
2723 if (auto numByref = (Result & 0x0F0) >> 4)
2724 printf(", BL_BYREF:%d", (int) numByref);
2725 if (auto numWeak = (Result & 0x00F) >> 0)
2726 printf(", BL_WEAK:%d", (int) numWeak);
2727 printf(", BL_OPERATOR:0\n");
2729 return llvm::ConstantInt::get(CGM.IntPtrTy, Result);
2732 unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
2733 Layout.push_back(inst);
2735 for (unsigned i = 0, e = Layout.size(); i != e; i++)
2736 BitMap += Layout[i];
2738 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
2739 if (ComputeByrefLayout)
2740 printf("\n Byref variable layout: ");
2742 printf("\n Block variable layout: ");
2743 for (unsigned i = 0, e = BitMap.size(); i != e; i++) {
2744 unsigned char inst = BitMap[i];
2745 enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2748 case BLOCK_LAYOUT_OPERATOR:
2749 printf("BL_OPERATOR:");
2752 case BLOCK_LAYOUT_NON_OBJECT_BYTES:
2753 printf("BL_NON_OBJECT_BYTES:");
2755 case BLOCK_LAYOUT_NON_OBJECT_WORDS:
2756 printf("BL_NON_OBJECT_WORD:");
2758 case BLOCK_LAYOUT_STRONG:
2759 printf("BL_STRONG:");
2761 case BLOCK_LAYOUT_BYREF:
2762 printf("BL_BYREF:");
2764 case BLOCK_LAYOUT_WEAK:
2767 case BLOCK_LAYOUT_UNRETAINED:
2768 printf("BL_UNRETAINED:");
2771 // Actual value of word count is one more that what is in the imm.
2772 // field of the instruction
2773 printf("%d", (inst & 0xf) + delta);
2781 auto *Entry = CreateCStringLiteral(BitMap, ObjCLabelType::ClassName,
2782 /*ForceNonFragileABI=*/true,
2783 /*NullTerminate=*/false);
2784 return getConstantGEP(VMContext, Entry, 0, 0);
2787 llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
2788 const CGBlockInfo &blockInfo) {
2789 assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
2791 RunSkipBlockVars.clear();
2792 bool hasUnion = false;
2794 unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(0);
2795 unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
2796 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2798 const BlockDecl *blockDecl = blockInfo.getBlockDecl();
2800 // Calculate the basic layout of the block structure.
2801 const llvm::StructLayout *layout =
2802 CGM.getDataLayout().getStructLayout(blockInfo.StructureType);
2804 // Ignore the optional 'this' capture: C++ objects are not assumed
2806 if (blockInfo.BlockHeaderForcedGapSize != CharUnits::Zero())
2807 UpdateRunSkipBlockVars(false, Qualifiers::OCL_None,
2808 blockInfo.BlockHeaderForcedGapOffset,
2809 blockInfo.BlockHeaderForcedGapSize);
2810 // Walk the captured variables.
2811 for (const auto &CI : blockDecl->captures()) {
2812 const VarDecl *variable = CI.getVariable();
2813 QualType type = variable->getType();
2815 const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
2817 // Ignore constant captures.
2818 if (capture.isConstant()) continue;
2820 CharUnits fieldOffset =
2821 CharUnits::fromQuantity(layout->getElementOffset(capture.getIndex()));
2823 assert(!type->isArrayType() && "array variable should not be caught");
2825 if (const RecordType *record = type->getAs<RecordType>()) {
2826 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
2829 CharUnits fieldSize;
2831 fieldSize = CharUnits::fromQuantity(WordSizeInBytes);
2833 fieldSize = CGM.getContext().getTypeSizeInChars(type);
2834 UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(type, false),
2835 fieldOffset, fieldSize);
2837 return getBitmapBlockLayout(false);
2840 llvm::Constant *CGObjCCommonMac::BuildByrefLayout(CodeGen::CodeGenModule &CGM,
2842 assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
2843 assert(!T->isArrayType() && "__block array variable should not be caught");
2844 CharUnits fieldOffset;
2845 RunSkipBlockVars.clear();
2846 bool hasUnion = false;
2847 if (const RecordType *record = T->getAs<RecordType>()) {
2848 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion, true /*ByrefLayout */);
2849 llvm::Constant *Result = getBitmapBlockLayout(true);
2850 if (isa<llvm::ConstantInt>(Result))
2851 Result = llvm::ConstantExpr::getIntToPtr(Result, CGM.Int8PtrTy);
2854 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
2858 llvm::Value *CGObjCMac::GenerateProtocolRef(CodeGenFunction &CGF,
2859 const ObjCProtocolDecl *PD) {
2860 // FIXME: I don't understand why gcc generates this, or where it is
2861 // resolved. Investigate. Its also wasteful to look this up over and over.
2862 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
2864 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
2865 ObjCTypes.getExternalProtocolPtrTy());
2868 void CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
2869 // FIXME: We shouldn't need this, the protocol decl should contain enough
2870 // information to tell us whether this was a declaration or a definition.
2871 DefinedProtocols.insert(PD->getIdentifier());
2873 // If we have generated a forward reference to this protocol, emit
2874 // it now. Otherwise do nothing, the protocol objects are lazily
2876 if (Protocols.count(PD->getIdentifier()))
2877 GetOrEmitProtocol(PD);
2880 llvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
2881 if (DefinedProtocols.count(PD->getIdentifier()))
2882 return GetOrEmitProtocol(PD);
2884 return GetOrEmitProtocolRef(PD);
2887 llvm::Value *CGObjCCommonMac::EmitClassRefViaRuntime(
2888 CodeGenFunction &CGF,
2889 const ObjCInterfaceDecl *ID,
2890 ObjCCommonTypesHelper &ObjCTypes) {
2891 llvm::Constant *lookUpClassFn = ObjCTypes.getLookUpClassFn();
2893 llvm::Value *className =
2894 CGF.CGM.GetAddrOfConstantCString(ID->getObjCRuntimeNameAsString())
2896 ASTContext &ctx = CGF.CGM.getContext();
2898 CGF.Builder.CreateBitCast(className,
2900 ctx.getPointerType(ctx.CharTy.withConst())));
2901 llvm::CallInst *call = CGF.Builder.CreateCall(lookUpClassFn, className);
2902 call->setDoesNotThrow();
2907 // Objective-C 1.0 extensions
2908 struct _objc_protocol {
2909 struct _objc_protocol_extension *isa;
2910 char *protocol_name;
2911 struct _objc_protocol_list *protocol_list;
2912 struct _objc__method_prototype_list *instance_methods;
2913 struct _objc__method_prototype_list *class_methods
2916 See EmitProtocolExtension().
2918 llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
2919 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
2921 // Early exit if a defining object has already been generated.
2922 if (Entry && Entry->hasInitializer())
2925 // Use the protocol definition, if there is one.
2926 if (const ObjCProtocolDecl *Def = PD->getDefinition())
2929 // FIXME: I don't understand why gcc generates this, or where it is
2930 // resolved. Investigate. Its also wasteful to look this up over and over.
2931 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
2933 // Construct method lists.
2934 auto methodLists = ProtocolMethodLists::get(PD);
2936 ConstantInitBuilder builder(CGM);
2937 auto values = builder.beginStruct(ObjCTypes.ProtocolTy);
2938 values.add(EmitProtocolExtension(PD, methodLists));
2939 values.add(GetClassName(PD->getObjCRuntimeNameAsString()));
2940 values.add(EmitProtocolList("OBJC_PROTOCOL_REFS_" + PD->getName(),
2941 PD->protocol_begin(), PD->protocol_end()));
2942 values.add(methodLists.emitMethodList(this, PD,
2943 ProtocolMethodLists::RequiredInstanceMethods));
2944 values.add(methodLists.emitMethodList(this, PD,
2945 ProtocolMethodLists::RequiredClassMethods));
2948 // Already created, update the initializer.
2949 assert(Entry->hasPrivateLinkage());
2950 values.finishAndSetAsInitializer(Entry);
2952 Entry = values.finishAndCreateGlobal("OBJC_PROTOCOL_" + PD->getName(),
2953 CGM.getPointerAlign(),
2955 llvm::GlobalValue::PrivateLinkage);
2956 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
2958 Protocols[PD->getIdentifier()] = Entry;
2960 CGM.addCompilerUsedGlobal(Entry);
2965 llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
2966 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
2969 // We use the initializer as a marker of whether this is a forward
2970 // reference or not. At module finalization we add the empty
2971 // contents for protocols which were referenced but never defined.
2972 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy,
2973 false, llvm::GlobalValue::PrivateLinkage,
2974 nullptr, "OBJC_PROTOCOL_" + PD->getName());
2975 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
2976 // FIXME: Is this necessary? Why only for protocol?
2977 Entry->setAlignment(4);
2984 struct _objc_protocol_extension {
2986 struct objc_method_description_list *optional_instance_methods;
2987 struct objc_method_description_list *optional_class_methods;
2988 struct objc_property_list *instance_properties;
2989 const char ** extendedMethodTypes;
2990 struct objc_property_list *class_properties;
2994 CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
2995 const ProtocolMethodLists &methodLists) {
2996 auto optInstanceMethods =
2997 methodLists.emitMethodList(this, PD,
2998 ProtocolMethodLists::OptionalInstanceMethods);
2999 auto optClassMethods =
3000 methodLists.emitMethodList(this, PD,
3001 ProtocolMethodLists::OptionalClassMethods);
3003 auto extendedMethodTypes =
3004 EmitProtocolMethodTypes("OBJC_PROTOCOL_METHOD_TYPES_" + PD->getName(),
3005 methodLists.emitExtendedTypesArray(this),
3008 auto instanceProperties =
3009 EmitPropertyList("OBJC_$_PROP_PROTO_LIST_" + PD->getName(), nullptr, PD,
3011 auto classProperties =
3012 EmitPropertyList("OBJC_$_CLASS_PROP_PROTO_LIST_" + PD->getName(), nullptr,
3013 PD, ObjCTypes, true);
3015 // Return null if no extension bits are used.
3016 if (optInstanceMethods->isNullValue() &&
3017 optClassMethods->isNullValue() &&
3018 extendedMethodTypes->isNullValue() &&
3019 instanceProperties->isNullValue() &&
3020 classProperties->isNullValue()) {
3021 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
3025 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
3027 ConstantInitBuilder builder(CGM);
3028 auto values = builder.beginStruct(ObjCTypes.ProtocolExtensionTy);
3029 values.addInt(ObjCTypes.IntTy, size);
3030 values.add(optInstanceMethods);
3031 values.add(optClassMethods);
3032 values.add(instanceProperties);
3033 values.add(extendedMethodTypes);
3034 values.add(classProperties);
3036 // No special section, but goes in llvm.used
3037 return CreateMetadataVar("\01l_OBJC_PROTOCOLEXT_" + PD->getName(), values,
3038 StringRef(), CGM.getPointerAlign(), true);
3042 struct objc_protocol_list {
3043 struct objc_protocol_list *next;
3049 CGObjCMac::EmitProtocolList(Twine name,
3050 ObjCProtocolDecl::protocol_iterator begin,
3051 ObjCProtocolDecl::protocol_iterator end) {
3052 // Just return null for empty protocol lists
3054 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
3056 ConstantInitBuilder builder(CGM);
3057 auto values = builder.beginStruct();
3059 // This field is only used by the runtime.
3060 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3062 // Reserve a slot for the count.
3063 auto countSlot = values.addPlaceholder();
3065 auto refsArray = values.beginArray(ObjCTypes.ProtocolPtrTy);
3066 for (; begin != end; ++begin) {
3067 refsArray.add(GetProtocolRef(*begin));
3069 auto count = refsArray.size();
3071 // This list is null terminated.
3072 refsArray.addNullPointer(ObjCTypes.ProtocolPtrTy);
3074 refsArray.finishAndAddTo(values);
3075 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
3078 if (CGM.getTriple().isOSBinFormatMachO())
3079 section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";
3081 llvm::GlobalVariable *GV =
3082 CreateMetadataVar(name, values, section, CGM.getPointerAlign(), false);
3083 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
3087 PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*,16> &PropertySet,
3088 SmallVectorImpl<const ObjCPropertyDecl *> &Properties,
3089 const ObjCProtocolDecl *Proto,
3090 bool IsClassProperty) {
3091 for (const auto *P : Proto->protocols())
3092 PushProtocolProperties(PropertySet, Properties, P, IsClassProperty);
3094 for (const auto *PD : Proto->properties()) {
3095 if (IsClassProperty != PD->isClassProperty())
3097 if (!PropertySet.insert(PD->getIdentifier()).second)
3099 Properties.push_back(PD);
3104 struct _objc_property {
3105 const char * const name;
3106 const char * const attributes;
3109 struct _objc_property_list {
3110 uint32_t entsize; // sizeof (struct _objc_property)
3111 uint32_t prop_count;
3112 struct _objc_property[prop_count];
3115 llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,
3116 const Decl *Container,
3117 const ObjCContainerDecl *OCD,
3118 const ObjCCommonTypesHelper &ObjCTypes,
3119 bool IsClassProperty) {
3120 if (IsClassProperty) {
3121 // Make this entry NULL for OS X with deployment target < 10.11, for iOS
3122 // with deployment target < 9.0.
3123 const llvm::Triple &Triple = CGM.getTarget().getTriple();
3124 if ((Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 11)) ||
3125 (Triple.isiOS() && Triple.isOSVersionLT(9)))
3126 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3129 SmallVector<const ObjCPropertyDecl *, 16> Properties;
3130 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
3132 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
3133 for (const ObjCCategoryDecl *ClassExt : OID->known_extensions())
3134 for (auto *PD : ClassExt->properties()) {
3135 if (IsClassProperty != PD->isClassProperty())
3137 PropertySet.insert(PD->getIdentifier());
3138 Properties.push_back(PD);
3141 for (const auto *PD : OCD->properties()) {
3142 if (IsClassProperty != PD->isClassProperty())
3144 // Don't emit duplicate metadata for properties that were already in a
3146 if (!PropertySet.insert(PD->getIdentifier()).second)
3148 Properties.push_back(PD);
3151 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) {
3152 for (const auto *P : OID->all_referenced_protocols())
3153 PushProtocolProperties(PropertySet, Properties, P, IsClassProperty);
3155 else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) {
3156 for (const auto *P : CD->protocols())
3157 PushProtocolProperties(PropertySet, Properties, P, IsClassProperty);
3160 // Return null for empty list.
3161 if (Properties.empty())
3162 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3164 unsigned propertySize =
3165 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.PropertyTy);
3167 ConstantInitBuilder builder(CGM);
3168 auto values = builder.beginStruct();
3169 values.addInt(ObjCTypes.IntTy, propertySize);
3170 values.addInt(ObjCTypes.IntTy, Properties.size());
3171 auto propertiesArray = values.beginArray(ObjCTypes.PropertyTy);
3172 for (auto PD : Properties) {
3173 auto property = propertiesArray.beginStruct(ObjCTypes.PropertyTy);
3174 property.add(GetPropertyName(PD->getIdentifier()));
3175 property.add(GetPropertyTypeString(PD, Container));
3176 property.finishAndAddTo(propertiesArray);
3178 propertiesArray.finishAndAddTo(values);
3181 if (CGM.getTriple().isOSBinFormatMachO())
3182 Section = (ObjCABI == 2) ? "__DATA, __objc_const"
3183 : "__OBJC,__property,regular,no_dead_strip";
3185 llvm::GlobalVariable *GV =
3186 CreateMetadataVar(Name, values, Section, CGM.getPointerAlign(), true);
3187 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);
3191 CGObjCCommonMac::EmitProtocolMethodTypes(Twine Name,
3192 ArrayRef<llvm::Constant*> MethodTypes,
3193 const ObjCCommonTypesHelper &ObjCTypes) {
3194 // Return null for empty list.
3195 if (MethodTypes.empty())
3196 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
3198 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
3199 MethodTypes.size());
3200 llvm::Constant *Init = llvm::ConstantArray::get(AT, MethodTypes);
3203 if (CGM.getTriple().isOSBinFormatMachO() && ObjCABI == 2)
3204 Section = "__DATA, __objc_const";
3206 llvm::GlobalVariable *GV =
3207 CreateMetadataVar(Name, Init, Section, CGM.getPointerAlign(), true);
3208 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.Int8PtrPtrTy);
3212 struct _objc_category {
3213 char *category_name;
3215 struct _objc_method_list *instance_methods;
3216 struct _objc_method_list *class_methods;
3217 struct _objc_protocol_list *protocols;
3218 uint32_t size; // <rdar://4585769>
3219 struct _objc_property_list *instance_properties;
3220 struct _objc_property_list *class_properties;
3223 void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
3224 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategoryTy);
3226 // FIXME: This is poor design, the OCD should have a pointer to the category
3227 // decl. Additionally, note that Category can be null for the @implementation
3228 // w/o an @interface case. Sema should just create one for us as it does for
3229 // @implementation so everyone else can live life under a clear blue sky.
3230 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
3231 const ObjCCategoryDecl *Category =
3232 Interface->FindCategoryDeclaration(OCD->getIdentifier());
3234 SmallString<256> ExtName;
3235 llvm::raw_svector_ostream(ExtName) << Interface->getName() << '_'
3238 ConstantInitBuilder Builder(CGM);
3239 auto Values = Builder.beginStruct(ObjCTypes.CategoryTy);
3246 SmallVector<const ObjCMethodDecl *, 16> Methods[NumMethodLists];
3247 for (const auto *MD : OCD->methods()) {
3248 Methods[unsigned(MD->isClassMethod())].push_back(MD);
3251 Values.add(GetClassName(OCD->getName()));
3252 Values.add(GetClassName(Interface->getObjCRuntimeNameAsString()));
3253 LazySymbols.insert(Interface->getIdentifier());
3255 Values.add(emitMethodList(ExtName, MethodListType::CategoryInstanceMethods,
3256 Methods[InstanceMethods]));
3257 Values.add(emitMethodList(ExtName, MethodListType::CategoryClassMethods,
3258 Methods[ClassMethods]));
3261 EmitProtocolList("OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
3262 Category->protocol_begin(), Category->protocol_end()));
3264 Values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3266 Values.addInt(ObjCTypes.IntTy, Size);
3268 // If there is no category @interface then there can be no properties.
3270 Values.add(EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
3271 OCD, Category, ObjCTypes, false));
3272 Values.add(EmitPropertyList("\01l_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
3273 OCD, Category, ObjCTypes, true));
3275 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
3276 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
3279 llvm::GlobalVariable *GV =
3280 CreateMetadataVar("OBJC_CATEGORY_" + ExtName.str(), Values,
3281 "__OBJC,__category,regular,no_dead_strip",
3282 CGM.getPointerAlign(), true);
3283 DefinedCategories.push_back(GV);
3284 DefinedCategoryNames.insert(llvm::CachedHashString(ExtName));
3285 // method definition entries must be clear for next implementation.
3286 MethodDefinitions.clear();
3289 enum FragileClassFlags {
3290 /// Apparently: is not a meta-class.
3291 FragileABI_Class_Factory = 0x00001,
3293 /// Is a meta-class.
3294 FragileABI_Class_Meta = 0x00002,
3296 /// Has a non-trivial constructor or destructor.
3297 FragileABI_Class_HasCXXStructors = 0x02000,
3299 /// Has hidden visibility.
3300 FragileABI_Class_Hidden = 0x20000,
3302 /// Class implementation was compiled under ARC.
3303 FragileABI_Class_CompiledByARC = 0x04000000,
3305 /// Class implementation was compiled under MRC and has MRC weak ivars.
3306 /// Exclusive with CompiledByARC.
3307 FragileABI_Class_HasMRCWeakIvars = 0x08000000,
3310 enum NonFragileClassFlags {
3311 /// Is a meta-class.
3312 NonFragileABI_Class_Meta = 0x00001,
3314 /// Is a root class.
3315 NonFragileABI_Class_Root = 0x00002,
3317 /// Has a non-trivial constructor or destructor.
3318 NonFragileABI_Class_HasCXXStructors = 0x00004,
3320 /// Has hidden visibility.
3321 NonFragileABI_Class_Hidden = 0x00010,
3323 /// Has the exception attribute.
3324 NonFragileABI_Class_Exception = 0x00020,
3326 /// (Obsolete) ARC-specific: this class has a .release_ivars method
3327 NonFragileABI_Class_HasIvarReleaser = 0x00040,
3329 /// Class implementation was compiled under ARC.
3330 NonFragileABI_Class_CompiledByARC = 0x00080,
3332 /// Class has non-trivial destructors, but zero-initialization is okay.
3333 NonFragileABI_Class_HasCXXDestructorOnly = 0x00100,
3335 /// Class implementation was compiled under MRC and has MRC weak ivars.
3336 /// Exclusive with CompiledByARC.
3337 NonFragileABI_Class_HasMRCWeakIvars = 0x00200,
3340 static bool hasWeakMember(QualType type) {
3341 if (type.getObjCLifetime() == Qualifiers::OCL_Weak) {
3345 if (auto recType = type->getAs<RecordType>()) {
3346 for (auto field : recType->getDecl()->fields()) {
3347 if (hasWeakMember(field->getType()))
3355 /// For compatibility, we only want to set the "HasMRCWeakIvars" flag
3356 /// (and actually fill in a layout string) if we really do have any
3358 static bool hasMRCWeakIvars(CodeGenModule &CGM,
3359 const ObjCImplementationDecl *ID) {
3360 if (!CGM.getLangOpts().ObjCWeak) return false;
3361 assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
3363 for (const ObjCIvarDecl *ivar =
3364 ID->getClassInterface()->all_declared_ivar_begin();
3365 ivar; ivar = ivar->getNextIvar()) {
3366 if (hasWeakMember(ivar->getType()))
3374 struct _objc_class {
3381 struct _objc_ivar_list *ivars;
3382 struct _objc_method_list *methods;
3383 struct _objc_cache *cache;
3384 struct _objc_protocol_list *protocols;
3385 // Objective-C 1.0 extensions (<rdr://4585769>)
3386 const char *ivar_layout;
3387 struct _objc_class_ext *ext;
3390 See EmitClassExtension();
3392 void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
3393 DefinedSymbols.insert(ID->getIdentifier());
3395 std::string ClassName = ID->getNameAsString();
3397 ObjCInterfaceDecl *Interface =
3398 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
3399 llvm::Constant *Protocols =
3400 EmitProtocolList("OBJC_CLASS_PROTOCOLS_" + ID->getName(),
3401 Interface->all_referenced_protocol_begin(),
3402 Interface->all_referenced_protocol_end());
3403 unsigned Flags = FragileABI_Class_Factory;
3404 if (ID->hasNonZeroConstructors() || ID->hasDestructors())
3405 Flags |= FragileABI_Class_HasCXXStructors;
3407 bool hasMRCWeak = false;
3409 if (CGM.getLangOpts().ObjCAutoRefCount)
3410 Flags |= FragileABI_Class_CompiledByARC;
3411 else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
3412 Flags |= FragileABI_Class_HasMRCWeakIvars;
3415 CGM.getContext().getASTObjCImplementationLayout(ID).getSize();
3417 // FIXME: Set CXX-structors flag.
3418 if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
3419 Flags |= FragileABI_Class_Hidden;
3426 SmallVector<const ObjCMethodDecl *, 16> Methods[NumMethodLists];
3427 for (const auto *MD : ID->methods()) {
3428 Methods[unsigned(MD->isClassMethod())].push_back(MD);
3431 for (const auto *PID : ID->property_impls()) {
3432 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
3433 ObjCPropertyDecl *PD = PID->getPropertyDecl();
3435 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
3436 if (GetMethodDefinition(MD))
3437 Methods[InstanceMethods].push_back(MD);
3438 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
3439 if (GetMethodDefinition(MD))
3440 Methods[InstanceMethods].push_back(MD);
3444 ConstantInitBuilder builder(CGM);
3445 auto values = builder.beginStruct(ObjCTypes.ClassTy);
3446 values.add(EmitMetaClass(ID, Protocols, Methods[ClassMethods]));
3447 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
3448 // Record a reference to the super class.
3449 LazySymbols.insert(Super->getIdentifier());
3451 values.addBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3452 ObjCTypes.ClassPtrTy);
3454 values.addNullPointer(ObjCTypes.ClassPtrTy);
3456 values.add(GetClassName(ID->getObjCRuntimeNameAsString()));
3457 // Version is always 0.
3458 values.addInt(ObjCTypes.LongTy, 0);
3459 values.addInt(ObjCTypes.LongTy, Flags);
3460 values.addInt(ObjCTypes.LongTy, Size.getQuantity());
3461 values.add(EmitIvarList(ID, false));
3462 values.add(emitMethodList(ID->getName(), MethodListType::InstanceMethods,
3463 Methods[InstanceMethods]));
3464 // cache is always NULL.
3465 values.addNullPointer(ObjCTypes.CachePtrTy);
3466 values.add(Protocols);
3467 values.add(BuildStrongIvarLayout(ID, CharUnits::Zero(), Size));
3468 values.add(EmitClassExtension(ID, Size, hasMRCWeak,
3469 /*isMetaclass*/ false));
3471 std::string Name("OBJC_CLASS_");
3473 const char *Section = "__OBJC,__class,regular,no_dead_strip";
3474 // Check for a forward reference.
3475 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
3477 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3478 "Forward metaclass reference has incorrect type.");
3479 values.finishAndSetAsInitializer(GV);
3480 GV->setSection(Section);
3481 GV->setAlignment(CGM.getPointerAlign().getQuantity());
3482 CGM.addCompilerUsedGlobal(GV);
3484 GV = CreateMetadataVar(Name, values, Section, CGM.getPointerAlign(), true);
3485 DefinedClasses.push_back(GV);
3486 ImplementedClasses.push_back(Interface);
3487 // method definition entries must be clear for next implementation.
3488 MethodDefinitions.clear();
3491 llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
3492 llvm::Constant *Protocols,
3493 ArrayRef<const ObjCMethodDecl*> Methods) {
3494 unsigned Flags = FragileABI_Class_Meta;
3495 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassTy);
3497 if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
3498 Flags |= FragileABI_Class_Hidden;
3500 ConstantInitBuilder builder(CGM);
3501 auto values = builder.beginStruct(ObjCTypes.ClassTy);
3502 // The isa for the metaclass is the root of the hierarchy.
3503 const ObjCInterfaceDecl *Root = ID->getClassInterface();
3504 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
3506 values.addBitCast(GetClassName(Root->getObjCRuntimeNameAsString()),
3507 ObjCTypes.ClassPtrTy);
3508 // The super class for the metaclass is emitted as the name of the
3509 // super class. The runtime fixes this up to point to the
3510 // *metaclass* for the super class.
3511 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
3512 values.addBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3513 ObjCTypes.ClassPtrTy);
3515 values.addNullPointer(ObjCTypes.ClassPtrTy);
3517 values.add(GetClassName(ID->getObjCRuntimeNameAsString()));
3518 // Version is always 0.
3519 values.addInt(ObjCTypes.LongTy, 0);
3520 values.addInt(ObjCTypes.LongTy, Flags);
3521 values.addInt(ObjCTypes.LongTy, Size);
3522 values.add(EmitIvarList(ID, true));
3523 values.add(emitMethodList(ID->getName(), MethodListType::ClassMethods,
3525 // cache is always NULL.
3526 values.addNullPointer(ObjCTypes.CachePtrTy);
3527 values.add(Protocols);
3528 // ivar_layout for metaclass is always NULL.
3529 values.addNullPointer(ObjCTypes.Int8PtrTy);
3530 // The class extension is used to store class properties for metaclasses.
3531 values.add(EmitClassExtension(ID, CharUnits::Zero(), false/*hasMRCWeak*/,
3532 /*isMetaclass*/true));
3534 std::string Name("OBJC_METACLASS_");
3535 Name += ID->getName();
3537 // Check for a forward reference.
3538 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
3540 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3541 "Forward metaclass reference has incorrect type.");
3542 values.finishAndSetAsInitializer(GV);
3544 GV = values.finishAndCreateGlobal(Name, CGM.getPointerAlign(),
3546 llvm::GlobalValue::PrivateLinkage);
3548 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
3549 CGM.addCompilerUsedGlobal(GV);
3554 llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
3555 std::string Name = "OBJC_METACLASS_" + ID->getNameAsString();
3557 // FIXME: Should we look these up somewhere other than the module. Its a bit
3558 // silly since we only generate these while processing an implementation, so
3559 // exactly one pointer would work if know when we entered/exitted an
3560 // implementation block.
3562 // Check for an existing forward reference.
3563 // Previously, metaclass with internal linkage may have been defined.
3564 // pass 'true' as 2nd argument so it is returned.
3565 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
3567 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
3568 llvm::GlobalValue::PrivateLinkage, nullptr,
3571 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3572 "Forward metaclass reference has incorrect type.");
3576 llvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) {
3577 std::string Name = "OBJC_CLASS_" + ID->getNameAsString();
3578 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
3581 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
3582 llvm::GlobalValue::PrivateLinkage, nullptr,
3585 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3586 "Forward class metadata reference has incorrect type.");
3591 Emit a "class extension", which in this specific context means extra
3592 data that doesn't fit in the normal fragile-ABI class structure, and
3593 has nothing to do with the language concept of a class extension.
3595 struct objc_class_ext {
3597 const char *weak_ivar_layout;
3598 struct _objc_property_list *properties;
3602 CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID,
3603 CharUnits InstanceSize, bool hasMRCWeakIvars,
3605 // Weak ivar layout.
3606 llvm::Constant *layout;
3608 layout = llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
3610 layout = BuildWeakIvarLayout(ID, CharUnits::Zero(), InstanceSize,
3615 llvm::Constant *propertyList =
3616 EmitPropertyList((isMetaclass ? Twine("\01l_OBJC_$_CLASS_PROP_LIST_")
3617 : Twine("\01l_OBJC_$_PROP_LIST_"))
3619 ID, ID->getClassInterface(), ObjCTypes, isMetaclass);
3621 // Return null if no extension bits are used.
3622 if (layout->isNullValue() && propertyList->isNullValue()) {
3623 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
3627 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
3629 ConstantInitBuilder builder(CGM);
3630 auto values = builder.beginStruct(ObjCTypes.ClassExtensionTy);
3631 values.addInt(ObjCTypes.IntTy, size);
3633 values.add(propertyList);
3635 return CreateMetadataVar("OBJC_CLASSEXT_" + ID->getName(), values,
3636 "__OBJC,__class_ext,regular,no_dead_strip",
3637 CGM.getPointerAlign(), true);
3647 struct objc_ivar_list {
3649 struct objc_ivar list[count];
3652 llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
3654 // When emitting the root class GCC emits ivar entries for the
3655 // actual class structure. It is not clear if we need to follow this
3656 // behavior; for now lets try and get away with not doing it. If so,
3657 // the cleanest solution would be to make up an ObjCInterfaceDecl
3660 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3662 const ObjCInterfaceDecl *OID = ID->getClassInterface();
3664 ConstantInitBuilder builder(CGM);
3665 auto ivarList = builder.beginStruct();
3666 auto countSlot = ivarList.addPlaceholder();
3667 auto ivars = ivarList.beginArray(ObjCTypes.IvarTy);
3669 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
3670 IVD; IVD = IVD->getNextIvar()) {
3671 // Ignore unnamed bit-fields.
3672 if (!IVD->getDeclName())
3675 auto ivar = ivars.beginStruct(ObjCTypes.IvarTy);
3676 ivar.add(GetMethodVarName(IVD->getIdentifier()));
3677 ivar.add(GetMethodVarType(IVD));
3678 ivar.addInt(ObjCTypes.IntTy, ComputeIvarBaseOffset(CGM, OID, IVD));
3679 ivar.finishAndAddTo(ivars);
3682 // Return null for empty list.
3683 auto count = ivars.size();
3687 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3690 ivars.finishAndAddTo(ivarList);
3691 ivarList.fillPlaceholderWithInt(countSlot, ObjCTypes.IntTy, count);
3693 llvm::GlobalVariable *GV;
3696 CreateMetadataVar("OBJC_CLASS_VARIABLES_" + ID->getName(), ivarList,
3697 "__OBJC,__class_vars,regular,no_dead_strip",
3698 CGM.getPointerAlign(), true);
3700 GV = CreateMetadataVar("OBJC_INSTANCE_VARIABLES_" + ID->getName(), ivarList,
3701 "__OBJC,__instance_vars,regular,no_dead_strip",
3702 CGM.getPointerAlign(), true);
3703 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
3706 /// Build a struct objc_method_description constant for the given method.
3708 /// struct objc_method_description {
3709 /// SEL method_name;
3710 /// char *method_types;
3712 void CGObjCMac::emitMethodDescriptionConstant(ConstantArrayBuilder &builder,
3713 const ObjCMethodDecl *MD) {
3714 auto description = builder.beginStruct(ObjCTypes.MethodDescriptionTy);
3715 description.addBitCast(GetMethodVarName(MD->getSelector()),
3716 ObjCTypes.SelectorPtrTy);
3717 description.add(GetMethodVarType(MD));
3718 description.finishAndAddTo(builder);
3721 /// Build a struct objc_method constant for the given method.
3723 /// struct objc_method {
3724 /// SEL method_name;
3725 /// char *method_types;
3728 void CGObjCMac::emitMethodConstant(ConstantArrayBuilder &builder,
3729 const ObjCMethodDecl *MD) {
3730 llvm::Function *fn = GetMethodDefinition(MD);
3731 assert(fn && "no definition registered for method");
3733 auto method = builder.beginStruct(ObjCTypes.MethodTy);
3734 method.addBitCast(GetMethodVarName(MD->getSelector()),
3735 ObjCTypes.SelectorPtrTy);
3736 method.add(GetMethodVarType(MD));
3737 method.addBitCast(fn, ObjCTypes.Int8PtrTy);
3738 method.finishAndAddTo(builder);
3741 /// Build a struct objc_method_list or struct objc_method_description_list,
3744 /// struct objc_method_list {
3745 /// struct objc_method_list *obsolete;
3747 /// struct objc_method methods_list[count];
3750 /// struct objc_method_description_list {
3752 /// struct objc_method_description list[count];
3754 llvm::Constant *CGObjCMac::emitMethodList(Twine name, MethodListType MLT,
3755 ArrayRef<const ObjCMethodDecl *> methods) {
3758 bool forProtocol = false;
3760 case MethodListType::CategoryInstanceMethods:
3761 prefix = "OBJC_CATEGORY_INSTANCE_METHODS_";
3762 section = "__OBJC,__cat_inst_meth,regular,no_dead_strip";
3763 forProtocol = false;
3765 case MethodListType::CategoryClassMethods:
3766 prefix = "OBJC_CATEGORY_CLASS_METHODS_";
3767 section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";
3768 forProtocol = false;
3770 case MethodListType::InstanceMethods:
3771 prefix = "OBJC_INSTANCE_METHODS_";
3772 section = "__OBJC,__inst_meth,regular,no_dead_strip";
3773 forProtocol = false;
3775 case MethodListType::ClassMethods:
3776 prefix = "OBJC_CLASS_METHODS_";
3777 section = "__OBJC,__cls_meth,regular,no_dead_strip";
3778 forProtocol = false;
3780 case MethodListType::ProtocolInstanceMethods:
3781 prefix = "OBJC_PROTOCOL_INSTANCE_METHODS_";
3782 section = "__OBJC,__cat_inst_meth,regular,no_dead_strip";
3785 case MethodListType::ProtocolClassMethods:
3786 prefix = "OBJC_PROTOCOL_CLASS_METHODS_";
3787 section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";
3790 case MethodListType::OptionalProtocolInstanceMethods:
3791 prefix = "OBJC_PROTOCOL_INSTANCE_METHODS_OPT_";
3792 section = "__OBJC,__cat_inst_meth,regular,no_dead_strip";
3795 case MethodListType::OptionalProtocolClassMethods:
3796 prefix = "OBJC_PROTOCOL_CLASS_METHODS_OPT_";
3797 section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";
3802 // Return null for empty list.
3803 if (methods.empty())
3804 return llvm::Constant::getNullValue(forProtocol
3805 ? ObjCTypes.MethodDescriptionListPtrTy
3806 : ObjCTypes.MethodListPtrTy);
3808 // For protocols, this is an objc_method_description_list, which has
3809 // a slightly different structure.
3811 ConstantInitBuilder builder(CGM);
3812 auto values = builder.beginStruct();
3813 values.addInt(ObjCTypes.IntTy, methods.size());
3814 auto methodArray = values.beginArray(ObjCTypes.MethodDescriptionTy);
3815 for (auto MD : methods) {
3816 emitMethodDescriptionConstant(methodArray, MD);
3818 methodArray.finishAndAddTo(values);
3820 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
3821 CGM.getPointerAlign(), true);
3822 return llvm::ConstantExpr::getBitCast(GV,
3823 ObjCTypes.MethodDescriptionListPtrTy);
3826 // Otherwise, it's an objc_method_list.
3827 ConstantInitBuilder builder(CGM);
3828 auto values = builder.beginStruct();
3829 values.addNullPointer(ObjCTypes.Int8PtrTy);
3830 values.addInt(ObjCTypes.IntTy, methods.size());
3831 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
3832 for (auto MD : methods) {
3833 emitMethodConstant(methodArray, MD);
3835 methodArray.finishAndAddTo(values);
3837 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
3838 CGM.getPointerAlign(), true);
3839 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy);
3842 llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,
3843 const ObjCContainerDecl *CD) {
3844 SmallString<256> Name;
3845 GetNameForMethod(OMD, CD, Name);
3847 CodeGenTypes &Types = CGM.getTypes();
3848 llvm::FunctionType *MethodTy =
3849 Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
3850 llvm::Function *Method =
3851 llvm::Function::Create(MethodTy,
3852 llvm::GlobalValue::InternalLinkage,
3855 MethodDefinitions.insert(std::make_pair(OMD, Method));
3860 llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
3861 ConstantStructBuilder &Init,
3865 llvm::GlobalVariable *GV =
3866 Init.finishAndCreateGlobal(Name, Align, /*constant*/ false,
3867 llvm::GlobalValue::PrivateLinkage);
3868 if (!Section.empty())
3869 GV->setSection(Section);
3871 CGM.addCompilerUsedGlobal(GV);
3875 llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
3876 llvm::Constant *Init,
3880 llvm::Type *Ty = Init->getType();
3881 llvm::GlobalVariable *GV =
3882 new llvm::GlobalVariable(CGM.getModule(), Ty, false,
3883 llvm::GlobalValue::PrivateLinkage, Init, Name);
3884 if (!Section.empty())
3885 GV->setSection(Section);
3886 GV->setAlignment(Align.getQuantity());
3888 CGM.addCompilerUsedGlobal(GV);
3892 llvm::GlobalVariable *
3893 CGObjCCommonMac::CreateCStringLiteral(StringRef Name, ObjCLabelType Type,
3894 bool ForceNonFragileABI,
3895 bool NullTerminate) {
3898 case ObjCLabelType::ClassName: Label = "OBJC_CLASS_NAME_"; break;
3899 case ObjCLabelType::MethodVarName: Label = "OBJC_METH_VAR_NAME_"; break;
3900 case ObjCLabelType::MethodVarType: Label = "OBJC_METH_VAR_TYPE_"; break;
3901 case ObjCLabelType::PropertyName: Label = "OBJC_PROP_NAME_ATTR_"; break;
3904 bool NonFragile = ForceNonFragileABI || isNonFragileABI();
3908 case ObjCLabelType::ClassName:
3909 Section = NonFragile ? "__TEXT,__objc_classname,cstring_literals"
3910 : "__TEXT,__cstring,cstring_literals";
3912 case ObjCLabelType::MethodVarName:
3913 Section = NonFragile ? "__TEXT,__objc_methname,cstring_literals"
3914 : "__TEXT,__cstring,cstring_literals";
3916 case ObjCLabelType::MethodVarType:
3917 Section = NonFragile ? "__TEXT,__objc_methtype,cstring_literals"
3918 : "__TEXT,__cstring,cstring_literals";
3920 case ObjCLabelType::PropertyName:
3921 Section = "__TEXT,__cstring,cstring_literals";
3925 llvm::Constant *Value =
3926 llvm::ConstantDataArray::getString(VMContext, Name, NullTerminate);
3927 llvm::GlobalVariable *GV =
3928 new llvm::GlobalVariable(CGM.getModule(), Value->getType(),
3929 /*isConstant=*/true,
3930 llvm::GlobalValue::PrivateLinkage, Value, Label);
3931 if (CGM.getTriple().isOSBinFormatMachO())
3932 GV->setSection(Section);
3933 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
3934 GV->setAlignment(CharUnits::One().getQuantity());
3935 CGM.addCompilerUsedGlobal(GV);
3940 llvm::Function *CGObjCMac::ModuleInitFunction() {
3941 // Abuse this interface function as a place to finalize.
3946 llvm::Constant *CGObjCMac::GetPropertyGetFunction() {
3947 return ObjCTypes.getGetPropertyFn();
3950 llvm::Constant *CGObjCMac::GetPropertySetFunction() {
3951 return ObjCTypes.getSetPropertyFn();
3954 llvm::Constant *CGObjCMac::GetOptimizedPropertySetFunction(bool atomic,
3956 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
3959 llvm::Constant *CGObjCMac::GetGetStructFunction() {
3960 return ObjCTypes.getCopyStructFn();
3963 llvm::Constant *CGObjCMac::GetSetStructFunction() {
3964 return ObjCTypes.getCopyStructFn();
3967 llvm::Constant *CGObjCMac::GetCppAtomicObjectGetFunction() {
3968 return ObjCTypes.getCppAtomicObjectFunction();
3971 llvm::Constant *CGObjCMac::GetCppAtomicObjectSetFunction() {
3972 return ObjCTypes.getCppAtomicObjectFunction();
3975 llvm::Constant *CGObjCMac::EnumerationMutationFunction() {
3976 return ObjCTypes.getEnumerationMutationFn();
3979 void CGObjCMac::EmitTryStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S) {
3980 return EmitTryOrSynchronizedStmt(CGF, S);
3983 void CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF,
3984 const ObjCAtSynchronizedStmt &S) {
3985 return EmitTryOrSynchronizedStmt(CGF, S);
3989 struct PerformFragileFinally final : EHScopeStack::Cleanup {
3991 Address SyncArgSlot;
3992 Address CallTryExitVar;
3993 Address ExceptionData;
3994 ObjCTypesHelper &ObjCTypes;
3995 PerformFragileFinally(const Stmt *S,
3996 Address SyncArgSlot,
3997 Address CallTryExitVar,
3998 Address ExceptionData,
3999 ObjCTypesHelper *ObjCTypes)
4000 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
4001 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
4003 void Emit(CodeGenFunction &CGF, Flags flags) override {
4004 // Check whether we need to call objc_exception_try_exit.
4005 // In optimized code, this branch will always be folded.
4006 llvm::BasicBlock *FinallyCallExit =
4007 CGF.createBasicBlock("finally.call_exit");
4008 llvm::BasicBlock *FinallyNoCallExit =
4009 CGF.createBasicBlock("finally.no_call_exit");
4010 CGF.Builder.CreateCondBr(CGF.Builder.CreateLoad(CallTryExitVar),
4011 FinallyCallExit, FinallyNoCallExit);
4013 CGF.EmitBlock(FinallyCallExit);
4014 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryExitFn(),
4015 ExceptionData.getPointer());
4017 CGF.EmitBlock(FinallyNoCallExit);
4019 if (isa<ObjCAtTryStmt>(S)) {
4020 if (const ObjCAtFinallyStmt* FinallyStmt =
4021 cast<ObjCAtTryStmt>(S).getFinallyStmt()) {
4022 // Don't try to do the @finally if this is an EH cleanup.
4023 if (flags.isForEHCleanup()) return;
4025 // Save the current cleanup destination in case there's
4026 // control flow inside the finally statement.
4027 llvm::Value *CurCleanupDest =
4028 CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot());
4030 CGF.EmitStmt(FinallyStmt->getFinallyBody());
4032 if (CGF.HaveInsertPoint()) {
4033 CGF.Builder.CreateStore(CurCleanupDest,
4034 CGF.getNormalCleanupDestSlot());
4036 // Currently, the end of the cleanup must always exist.
4037 CGF.EnsureInsertPoint();
4041 // Emit objc_sync_exit(expr); as finally's sole statement for
4043 llvm::Value *SyncArg = CGF.Builder.CreateLoad(SyncArgSlot);
4044 CGF.EmitNounwindRuntimeCall(ObjCTypes.getSyncExitFn(), SyncArg);
4049 class FragileHazards {
4050 CodeGenFunction &CGF;
4051 SmallVector<llvm::Value*, 20> Locals;
4052 llvm::DenseSet<llvm::BasicBlock*> BlocksBeforeTry;
4054 llvm::InlineAsm *ReadHazard;
4055 llvm::InlineAsm *WriteHazard;
4057 llvm::FunctionType *GetAsmFnType();
4059 void collectLocals();
4060 void emitReadHazard(CGBuilderTy &Builder);
4063 FragileHazards(CodeGenFunction &CGF);
4065 void emitWriteHazard();
4066 void emitHazardsInNewBlocks();
4068 } // end anonymous namespace
4070 /// Create the fragile-ABI read and write hazards based on the current
4071 /// state of the function, which is presumed to be immediately prior
4072 /// to a @try block. These hazards are used to maintain correct
4073 /// semantics in the face of optimization and the fragile ABI's
4074 /// cavalier use of setjmp/longjmp.
4075 FragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) {
4078 if (Locals.empty()) return;
4080 // Collect all the blocks in the function.
4081 for (llvm::Function::iterator
4082 I = CGF.CurFn->begin(), E = CGF.CurFn->end(); I != E; ++I)
4083 BlocksBeforeTry.insert(&*I);
4085 llvm::FunctionType *AsmFnTy = GetAsmFnType();
4087 // Create a read hazard for the allocas. This inhibits dead-store
4088 // optimizations and forces the values to memory. This hazard is
4089 // inserted before any 'throwing' calls in the protected scope to
4090 // reflect the possibility that the variables might be read from the
4091 // catch block if the call throws.
4093 std::string Constraint;
4094 for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
4095 if (I) Constraint += ',';
4099 ReadHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
4102 // Create a write hazard for the allocas. This inhibits folding
4103 // loads across the hazard. This hazard is inserted at the
4104 // beginning of the catch path to reflect the possibility that the
4105 // variables might have been written within the protected scope.
4107 std::string Constraint;
4108 for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
4109 if (I) Constraint += ',';
4110 Constraint += "=*m";
4113 WriteHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
4117 /// Emit a write hazard at the current location.
4118 void FragileHazards::emitWriteHazard() {
4119 if (Locals.empty()) return;
4121 CGF.EmitNounwindRuntimeCall(WriteHazard, Locals);
4124 void FragileHazards::emitReadHazard(CGBuilderTy &Builder) {
4125 assert(!Locals.empty());
4126 llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
4127 call->setDoesNotThrow();
4128 call->setCallingConv(CGF.getRuntimeCC());
4131 /// Emit read hazards in all the protected blocks, i.e. all the blocks
4132 /// which have been inserted since the beginning of the try.
4133 void FragileHazards::emitHazardsInNewBlocks() {
4134 if (Locals.empty()) return;
4136 CGBuilderTy Builder(CGF, CGF.getLLVMContext());
4138 // Iterate through all blocks, skipping those prior to the try.
4139 for (llvm::Function::iterator
4140 FI = CGF.CurFn->begin(), FE = CGF.CurFn->end(); FI != FE; ++FI) {
4141 llvm::BasicBlock &BB = *FI;
4142 if (BlocksBeforeTry.count(&BB)) continue;
4144 // Walk through all the calls in the block.
4145 for (llvm::BasicBlock::iterator
4146 BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
4147 llvm::Instruction &I = *BI;
4149 // Ignore instructions that aren't non-intrinsic calls.
4150 // These are the only calls that can possibly call longjmp.
4151 if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I)) continue;
4152 if (isa<llvm::IntrinsicInst>(I))
4155 // Ignore call sites marked nounwind. This may be questionable,
4156 // since 'nounwind' doesn't necessarily mean 'does not call longjmp'.
4157 llvm::CallSite CS(&I);
4158 if (CS.doesNotThrow()) continue;
4160 // Insert a read hazard before the call. This will ensure that
4161 // any writes to the locals are performed before making the
4162 // call. If the call throws, then this is sufficient to
4163 // guarantee correctness as long as it doesn't also write to any
4165 Builder.SetInsertPoint(&BB, BI);
4166 emitReadHazard(Builder);
4171 static void addIfPresent(llvm::DenseSet<llvm::Value*> &S, llvm::Value *V) {
4175 static void addIfPresent(llvm::DenseSet<llvm::Value*> &S, Address V) {
4176 if (V.isValid()) S.insert(V.getPointer());
4179 void FragileHazards::collectLocals() {
4180 // Compute a set of allocas to ignore.
4181 llvm::DenseSet<llvm::Value*> AllocasToIgnore;
4182 addIfPresent(AllocasToIgnore, CGF.ReturnValue);
4183 addIfPresent(AllocasToIgnore, CGF.NormalCleanupDest);
4185 // Collect all the allocas currently in the function. This is
4186 // probably way too aggressive.
4187 llvm::BasicBlock &Entry = CGF.CurFn->getEntryBlock();
4188 for (llvm::BasicBlock::iterator
4189 I = Entry.begin(), E = Entry.end(); I != E; ++I)
4190 if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
4191 Locals.push_back(&*I);
4194 llvm::FunctionType *FragileHazards::GetAsmFnType() {
4195 SmallVector<llvm::Type *, 16> tys(Locals.size());
4196 for (unsigned i = 0, e = Locals.size(); i != e; ++i)
4197 tys[i] = Locals[i]->getType();
4198 return llvm::FunctionType::get(CGF.VoidTy, tys, false);
4203 Objective-C setjmp-longjmp (sjlj) Exception Handling
4206 A catch buffer is a setjmp buffer plus:
4207 - a pointer to the exception that was caught
4208 - a pointer to the previous exception data buffer
4209 - two pointers of reserved storage
4210 Therefore catch buffers form a stack, with a pointer to the top
4211 of the stack kept in thread-local storage.
4213 objc_exception_try_enter pushes a catch buffer onto the EH stack.
4214 objc_exception_try_exit pops the given catch buffer, which is
4215 required to be the top of the EH stack.
4216 objc_exception_throw pops the top of the EH stack, writes the
4217 thrown exception into the appropriate field, and longjmps
4218 to the setjmp buffer. It crashes the process (with a printf
4219 and an abort()) if there are no catch buffers on the stack.
4220 objc_exception_extract just reads the exception pointer out of the
4223 There's no reason an implementation couldn't use a light-weight
4224 setjmp here --- something like __builtin_setjmp, but API-compatible
4225 with the heavyweight setjmp. This will be more important if we ever
4226 want to implement correct ObjC/C++ exception interactions for the
4229 Note that for this use of setjmp/longjmp to be correct, we may need
4230 to mark some local variables volatile: if a non-volatile local
4231 variable is modified between the setjmp and the longjmp, it has
4232 indeterminate value. For the purposes of LLVM IR, it may be
4233 sufficient to make loads and stores within the @try (to variables
4234 declared outside the @try) volatile. This is necessary for
4235 optimized correctness, but is not currently being done; this is
4236 being tracked as rdar://problem/8160285
4238 The basic framework for a @try-catch-finally is as follows:
4240 objc_exception_data d;
4242 bool _call_try_exit = true;
4244 objc_exception_try_enter(&d);
4245 if (!setjmp(d.jmp_buf)) {
4249 id _caught = objc_exception_extract(&d);
4251 // enter new try scope for handlers
4252 if (!setjmp(d.jmp_buf)) {
4253 ... match exception and execute catch blocks ...
4255 // fell off end, rethrow.
4257 ... jump-through-finally to finally_rethrow ...
4259 // exception in catch block
4260 _rethrow = objc_exception_extract(&d);
4261 _call_try_exit = false;
4262 ... jump-through-finally to finally_rethrow ...
4265 ... jump-through-finally to finally_end ...
4269 objc_exception_try_exit(&d);
4271 ... finally block ....
4272 ... dispatch to finally destination ...
4275 objc_exception_throw(_rethrow);
4280 This framework differs slightly from the one gcc uses, in that gcc
4281 uses _rethrow to determine if objc_exception_try_exit should be called
4282 and if the object should be rethrown. This breaks in the face of
4283 throwing nil and introduces unnecessary branches.
4285 We specialize this framework for a few particular circumstances:
4287 - If there are no catch blocks, then we avoid emitting the second
4288 exception handling context.
4290 - If there is a catch-all catch block (i.e. @catch(...) or @catch(id
4291 e)) we avoid emitting the code to rethrow an uncaught exception.
4293 - FIXME: If there is no @finally block we can do a few more
4296 Rethrows and Jumps-Through-Finally
4299 '@throw;' is supported by pushing the currently-caught exception
4300 onto ObjCEHStack while the @catch blocks are emitted.
4302 Branches through the @finally block are handled with an ordinary
4303 normal cleanup. We do not register an EH cleanup; fragile-ABI ObjC
4304 exceptions are not compatible with C++ exceptions, and this is
4305 hardly the only place where this will go wrong.
4307 @synchronized(expr) { stmt; } is emitted as if it were:
4308 id synch_value = expr;
4309 objc_sync_enter(synch_value);
4310 @try { stmt; } @finally { objc_sync_exit(synch_value); }
4313 void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
4315 bool isTry = isa<ObjCAtTryStmt>(S);
4317 // A destination for the fall-through edges of the catch handlers to
4319 CodeGenFunction::JumpDest FinallyEnd =
4320 CGF.getJumpDestInCurrentScope("finally.end");
4322 // A destination for the rethrow edge of the catch handlers to jump
4324 CodeGenFunction::JumpDest FinallyRethrow =
4325 CGF.getJumpDestInCurrentScope("finally.rethrow");
4327 // For @synchronized, call objc_sync_enter(sync.expr). The
4328 // evaluation of the expression must occur before we enter the
4329 // @synchronized. We can't avoid a temp here because we need the
4330 // value to be preserved. If the backend ever does liveness
4331 // correctly after setjmp, this will be unnecessary.
4332 Address SyncArgSlot = Address::invalid();
4334 llvm::Value *SyncArg =
4335 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
4336 SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
4337 CGF.EmitNounwindRuntimeCall(ObjCTypes.getSyncEnterFn(), SyncArg);
4339 SyncArgSlot = CGF.CreateTempAlloca(SyncArg->getType(),
4340 CGF.getPointerAlign(), "sync.arg");
4341 CGF.Builder.CreateStore(SyncArg, SyncArgSlot);
4344 // Allocate memory for the setjmp buffer. This needs to be kept
4345 // live throughout the try and catch blocks.
4346 Address ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy,
4347 CGF.getPointerAlign(),
4348 "exceptiondata.ptr");
4350 // Create the fragile hazards. Note that this will not capture any
4351 // of the allocas required for exception processing, but will
4352 // capture the current basic block (which extends all the way to the
4353 // setjmp call) as "before the @try".
4354 FragileHazards Hazards(CGF);
4356 // Create a flag indicating whether the cleanup needs to call
4357 // objc_exception_try_exit. This is true except when
4358 // - no catches match and we're branching through the cleanup
4359 // just to rethrow the exception, or
4360 // - a catch matched and we're falling out of the catch handler.
4361 // The setjmp-safety rule here is that we should always store to this
4362 // variable in a place that dominates the branch through the cleanup
4363 // without passing through any setjmps.
4364 Address CallTryExitVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(),
4368 // A slot containing the exception to rethrow. Only needed when we
4369 // have both a @catch and a @finally.
4370 Address PropagatingExnVar = Address::invalid();
4372 // Push a normal cleanup to leave the try scope.
4373 CGF.EHStack.pushCleanup<PerformFragileFinally>(NormalAndEHCleanup, &S,
4379 // Enter a try block:
4380 // - Call objc_exception_try_enter to push ExceptionData on top of
4382 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(),
4383 ExceptionData.getPointer());
4385 // - Call setjmp on the exception data buffer.
4386 llvm::Constant *Zero = llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0);
4387 llvm::Value *GEPIndexes[] = { Zero, Zero, Zero };
4388 llvm::Value *SetJmpBuffer = CGF.Builder.CreateGEP(
4389 ObjCTypes.ExceptionDataTy, ExceptionData.getPointer(), GEPIndexes,
4391 llvm::CallInst *SetJmpResult = CGF.EmitNounwindRuntimeCall(
4392 ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result");
4393 SetJmpResult->setCanReturnTwice();
4395 // If setjmp returned 0, enter the protected block; otherwise,
4396 // branch to the handler.
4397 llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
4398 llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
4399 llvm::Value *DidCatch =
4400 CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
4401 CGF.Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
4403 // Emit the protected block.
4404 CGF.EmitBlock(TryBlock);
4405 CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
4406 CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
4407 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
4409 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.Builder.saveAndClearIP();
4411 // Emit the exception handler block.
4412 CGF.EmitBlock(TryHandler);
4414 // Don't optimize loads of the in-scope locals across this point.
4415 Hazards.emitWriteHazard();
4417 // For a @synchronized (or a @try with no catches), just branch
4418 // through the cleanup to the rethrow block.
4419 if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
4420 // Tell the cleanup not to re-pop the exit.
4421 CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
4422 CGF.EmitBranchThroughCleanup(FinallyRethrow);
4424 // Otherwise, we have to match against the caught exceptions.
4426 // Retrieve the exception object. We may emit multiple blocks but
4427 // nothing can cross this so the value is already in SSA form.
4428 llvm::CallInst *Caught =
4429 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(),
4430 ExceptionData.getPointer(), "caught");
4432 // Push the exception to rethrow onto the EH value stack for the
4433 // benefit of any @throws in the handlers.
4434 CGF.ObjCEHValueStack.push_back(Caught);
4436 const ObjCAtTryStmt* AtTryStmt = cast<ObjCAtTryStmt>(&S);
4438 bool HasFinally = (AtTryStmt->getFinallyStmt() != nullptr);
4440 llvm::BasicBlock *CatchBlock = nullptr;
4441 llvm::BasicBlock *CatchHandler = nullptr;
4443 // Save the currently-propagating exception before
4444 // objc_exception_try_enter clears the exception slot.
4445 PropagatingExnVar = CGF.CreateTempAlloca(Caught->getType(),
4446 CGF.getPointerAlign(),
4447 "propagating_exception");
4448 CGF.Builder.CreateStore(Caught, PropagatingExnVar);
4450 // Enter a new exception try block (in case a @catch block
4451 // throws an exception).
4452 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(),
4453 ExceptionData.getPointer());
4455 llvm::CallInst *SetJmpResult =
4456 CGF.EmitNounwindRuntimeCall(ObjCTypes.getSetJmpFn(),
4457 SetJmpBuffer, "setjmp.result");
4458 SetJmpResult->setCanReturnTwice();
4460 llvm::Value *Threw =
4461 CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
4463 CatchBlock = CGF.createBasicBlock("catch");
4464 CatchHandler = CGF.createBasicBlock("catch_for_catch");
4465 CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
4467 CGF.EmitBlock(CatchBlock);
4470 CGF.Builder.CreateStore(CGF.Builder.getInt1(HasFinally), CallTryExitVar);
4472 // Handle catch list. As a special case we check if everything is
4473 // matched and avoid generating code for falling off the end if
4475 bool AllMatched = false;
4476 for (unsigned I = 0, N = AtTryStmt->getNumCatchStmts(); I != N; ++I) {
4477 const ObjCAtCatchStmt *CatchStmt = AtTryStmt->getCatchStmt(I);
4479 const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
4480 const ObjCObjectPointerType *OPT = nullptr;
4482 // catch(...) always matches.
4486 OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>();
4488 // catch(id e) always matches under this ABI, since only
4489 // ObjC exceptions end up here in the first place.
4490 // FIXME: For the time being we also match id<X>; this should
4491 // be rejected by Sema instead.
4492 if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()))
4496 // If this is a catch-all, we don't need to test anything.
4498 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
4501 CGF.EmitAutoVarDecl(*CatchParam);
4502 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
4504 // These types work out because ConvertType(id) == i8*.
4505 EmitInitOfCatchParam(CGF, Caught, CatchParam);
4508 CGF.EmitStmt(CatchStmt->getCatchBody());
4510 // The scope of the catch variable ends right here.
4511 CatchVarCleanups.ForceCleanup();
4513 CGF.EmitBranchThroughCleanup(FinallyEnd);
4517 assert(OPT && "Unexpected non-object pointer type in @catch");
4518 const ObjCObjectType *ObjTy = OPT->getObjectType();
4520 // FIXME: @catch (Class c) ?
4521 ObjCInterfaceDecl *IDecl = ObjTy->getInterface();
4522 assert(IDecl && "Catch parameter must have Objective-C type!");
4524 // Check if the @catch block matches the exception object.
4525 llvm::Value *Class = EmitClassRef(CGF, IDecl);
4527 llvm::Value *matchArgs[] = { Class, Caught };
4528 llvm::CallInst *Match =
4529 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionMatchFn(),
4530 matchArgs, "match");
4532 llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("match");
4533 llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch.next");
4535 CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"),
4536 MatchedBlock, NextCatchBlock);
4538 // Emit the @catch block.
4539 CGF.EmitBlock(MatchedBlock);
4541 // Collect any cleanups for the catch variable. The scope lasts until
4542 // the end of the catch body.
4543 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
4545 CGF.EmitAutoVarDecl(*CatchParam);
4546 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
4548 // Initialize the catch variable.
4550 CGF.Builder.CreateBitCast(Caught,
4551 CGF.ConvertType(CatchParam->getType()));
4552 EmitInitOfCatchParam(CGF, Tmp, CatchParam);
4554 CGF.EmitStmt(CatchStmt->getCatchBody());
4556 // We're done with the catch variable.
4557 CatchVarCleanups.ForceCleanup();
4559 CGF.EmitBranchThroughCleanup(FinallyEnd);
4561 CGF.EmitBlock(NextCatchBlock);
4564 CGF.ObjCEHValueStack.pop_back();
4566 // If nothing wanted anything to do with the caught exception,
4567 // kill the extract call.
4568 if (Caught->use_empty())
4569 Caught->eraseFromParent();
4572 CGF.EmitBranchThroughCleanup(FinallyRethrow);
4575 // Emit the exception handler for the @catch blocks.
4576 CGF.EmitBlock(CatchHandler);
4578 // In theory we might now need a write hazard, but actually it's
4579 // unnecessary because there's no local-accessing code between
4580 // the try's write hazard and here.
4581 //Hazards.emitWriteHazard();
4583 // Extract the new exception and save it to the
4584 // propagating-exception slot.
4585 assert(PropagatingExnVar.isValid());
4586 llvm::CallInst *NewCaught =
4587 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(),
4588 ExceptionData.getPointer(), "caught");
4589 CGF.Builder.CreateStore(NewCaught, PropagatingExnVar);
4591 // Don't pop the catch handler; the throw already did.
4592 CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
4593 CGF.EmitBranchThroughCleanup(FinallyRethrow);
4597 // Insert read hazards as required in the new blocks.
4598 Hazards.emitHazardsInNewBlocks();
4601 CGF.Builder.restoreIP(TryFallthroughIP);
4602 if (CGF.HaveInsertPoint())
4603 CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
4604 CGF.PopCleanupBlock();
4605 CGF.EmitBlock(FinallyEnd.getBlock(), true);
4607 // Emit the rethrow block.
4608 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
4609 CGF.EmitBlock(FinallyRethrow.getBlock(), true);
4610 if (CGF.HaveInsertPoint()) {
4611 // If we have a propagating-exception variable, check it.
4612 llvm::Value *PropagatingExn;
4613 if (PropagatingExnVar.isValid()) {
4614 PropagatingExn = CGF.Builder.CreateLoad(PropagatingExnVar);
4616 // Otherwise, just look in the buffer for the exception to throw.
4618 llvm::CallInst *Caught =
4619 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(),
4620 ExceptionData.getPointer());
4621 PropagatingExn = Caught;
4624 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionThrowFn(),
4626 CGF.Builder.CreateUnreachable();
4629 CGF.Builder.restoreIP(SavedIP);
4632 void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
4633 const ObjCAtThrowStmt &S,
4634 bool ClearInsertionPoint) {
4635 llvm::Value *ExceptionAsObject;
4637 if (const Expr *ThrowExpr = S.getThrowExpr()) {
4638 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
4640 CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
4642 assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
4643 "Unexpected rethrow outside @catch block.");
4644 ExceptionAsObject = CGF.ObjCEHValueStack.back();
4647 CGF.EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
4648 ->setDoesNotReturn();
4649 CGF.Builder.CreateUnreachable();
4651 // Clear the insertion point to indicate we are in unreachable code.
4652 if (ClearInsertionPoint)
4653 CGF.Builder.ClearInsertionPoint();
4656 /// EmitObjCWeakRead - Code gen for loading value of a __weak
4657 /// object: objc_read_weak (id *src)
4659 llvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
4660 Address AddrWeakObj) {
4661 llvm::Type* DestTy = AddrWeakObj.getElementType();
4662 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj,
4663 ObjCTypes.PtrObjectPtrTy);
4664 llvm::Value *read_weak =
4665 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
4666 AddrWeakObj.getPointer(), "weakread");
4667 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
4671 /// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
4672 /// objc_assign_weak (id src, id *dst)
4674 void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
4675 llvm::Value *src, Address dst) {
4676 llvm::Type * SrcTy = src->getType();
4677 if (!isa<llvm::PointerType>(SrcTy)) {
4678 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4679 assert(Size <= 8 && "does not support size > 8");
4680 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
4681 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
4682 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4684 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4685 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4686 llvm::Value *args[] = { src, dst.getPointer() };
4687 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
4688 args, "weakassign");
4691 /// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
4692 /// objc_assign_global (id src, id *dst)
4694 void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
4695 llvm::Value *src, Address dst,
4697 llvm::Type * SrcTy = src->getType();
4698 if (!isa<llvm::PointerType>(SrcTy)) {
4699 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4700 assert(Size <= 8 && "does not support size > 8");
4701 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
4702 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
4703 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4705 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4706 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4707 llvm::Value *args[] = { src, dst.getPointer() };
4709 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
4710 args, "globalassign");
4712 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
4713 args, "threadlocalassign");
4716 /// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
4717 /// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset)
4719 void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
4720 llvm::Value *src, Address dst,
4721 llvm::Value *ivarOffset) {
4722 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL");
4723 llvm::Type * SrcTy = src->getType();
4724 if (!isa<llvm::PointerType>(SrcTy)) {
4725 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4726 assert(Size <= 8 && "does not support size > 8");
4727 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
4728 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
4729 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4731 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4732 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4733 llvm::Value *args[] = { src, dst.getPointer(), ivarOffset };
4734 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
4737 /// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
4738 /// objc_assign_strongCast (id src, id *dst)
4740 void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
4741 llvm::Value *src, Address dst) {
4742 llvm::Type * SrcTy = src->getType();
4743 if (!isa<llvm::PointerType>(SrcTy)) {
4744 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4745 assert(Size <= 8 && "does not support size > 8");
4746 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
4747 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
4748 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4750 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4751 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4752 llvm::Value *args[] = { src, dst.getPointer() };
4753 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
4754 args, "strongassign");
4757 void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
4760 llvm::Value *size) {
4761 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
4762 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
4763 llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), size };
4764 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
4767 /// EmitObjCValueForIvar - Code Gen for ivar reference.
4769 LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
4771 llvm::Value *BaseValue,
4772 const ObjCIvarDecl *Ivar,
4773 unsigned CVRQualifiers) {
4774 const ObjCInterfaceDecl *ID =
4775 ObjectTy->getAs<ObjCObjectType>()->getInterface();
4776 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4777 EmitIvarOffset(CGF, ID, Ivar));
4780 llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
4781 const ObjCInterfaceDecl *Interface,
4782 const ObjCIvarDecl *Ivar) {
4783 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
4784 return llvm::ConstantInt::get(
4785 CGM.getTypes().ConvertType(CGM.getContext().LongTy),
4789 /* *** Private Interface *** */
4791 std::string CGObjCCommonMac::GetSectionName(StringRef Section,
4792 StringRef MachOAttributes) {
4793 switch (CGM.getTriple().getObjectFormat()) {
4795 llvm_unreachable("unexpected object file format");
4796 case llvm::Triple::MachO: {
4797 if (MachOAttributes.empty())
4798 return ("__DATA," + Section).str();
4799 return ("__DATA," + Section + "," + MachOAttributes).str();
4801 case llvm::Triple::ELF:
4802 assert(Section.substr(0, 2) == "__" &&
4803 "expected the name to begin with __");
4804 return Section.substr(2).str();
4805 case llvm::Triple::COFF:
4806 assert(Section.substr(0, 2) == "__" &&
4807 "expected the name to begin with __");
4808 return ("." + Section.substr(2) + "$B").str();
4812 /// EmitImageInfo - Emit the image info marker used to encode some module
4813 /// level information.
4815 /// See: <rdr://4810609&4810587&4810587>
4816 /// struct IMAGE_INFO {
4817 /// unsigned version;
4820 enum ImageInfoFlags {
4821 eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.
4822 eImageInfo_GarbageCollected = (1 << 1),
4823 eImageInfo_GCOnly = (1 << 2),
4824 eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.
4826 // A flag indicating that the module has no instances of a @synthesize of a
4827 // superclass variable. <rdar://problem/6803242>
4828 eImageInfo_CorrectedSynthesize = (1 << 4), // This flag is no longer set by clang.
4829 eImageInfo_ImageIsSimulated = (1 << 5),
4830 eImageInfo_ClassProperties = (1 << 6)
4833 void CGObjCCommonMac::EmitImageInfo() {
4834 unsigned version = 0; // Version is unused?
4835 std::string Section =
4837 ? "__OBJC,__image_info,regular"
4838 : GetSectionName("__objc_imageinfo", "regular,no_dead_strip");
4840 // Generate module-level named metadata to convey this information to the
4841 // linker and code-gen.
4842 llvm::Module &Mod = CGM.getModule();
4844 // Add the ObjC ABI version to the module flags.
4845 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version", ObjCABI);
4846 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version",
4848 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section",
4849 llvm::MDString::get(VMContext, Section));
4851 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
4852 // Non-GC overrides those files which specify GC.
4853 Mod.addModuleFlag(llvm::Module::Override,
4854 "Objective-C Garbage Collection", (uint32_t)0);
4856 // Add the ObjC garbage collection value.
4857 Mod.addModuleFlag(llvm::Module::Error,
4858 "Objective-C Garbage Collection",
4859 eImageInfo_GarbageCollected);
4861 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
4862 // Add the ObjC GC Only value.
4863 Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only",
4866 // Require that GC be specified and set to eImageInfo_GarbageCollected.
4867 llvm::Metadata *Ops[2] = {
4868 llvm::MDString::get(VMContext, "Objective-C Garbage Collection"),
4869 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
4870 llvm::Type::getInt32Ty(VMContext), eImageInfo_GarbageCollected))};
4871 Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only",
4872 llvm::MDNode::get(VMContext, Ops));
4876 // Indicate whether we're compiling this to run on a simulator.
4877 const llvm::Triple &Triple = CGM.getTarget().getTriple();
4878 if ((Triple.isiOS() || Triple.isWatchOS()) &&
4879 (Triple.getArch() == llvm::Triple::x86 ||
4880 Triple.getArch() == llvm::Triple::x86_64))
4881 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated",
4882 eImageInfo_ImageIsSimulated);
4884 // Indicate whether we are generating class properties.
4885 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Class Properties",
4886 eImageInfo_ClassProperties);
4889 // struct objc_module {
4890 // unsigned long version;
4891 // unsigned long size;
4892 // const char *name;
4896 // FIXME: Get from somewhere
4897 static const int ModuleVersion = 7;
4899 void CGObjCMac::EmitModuleInfo() {
4900 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy);
4902 ConstantInitBuilder builder(CGM);
4903 auto values = builder.beginStruct(ObjCTypes.ModuleTy);
4904 values.addInt(ObjCTypes.LongTy, ModuleVersion);
4905 values.addInt(ObjCTypes.LongTy, Size);
4906 // This used to be the filename, now it is unused. <rdr://4327263>
4907 values.add(GetClassName(StringRef("")));
4908 values.add(EmitModuleSymbols());
4909 CreateMetadataVar("OBJC_MODULES", values,
4910 "__OBJC,__module_info,regular,no_dead_strip",
4911 CGM.getPointerAlign(), true);
4914 llvm::Constant *CGObjCMac::EmitModuleSymbols() {
4915 unsigned NumClasses = DefinedClasses.size();
4916 unsigned NumCategories = DefinedCategories.size();
4918 // Return null if no symbols were defined.
4919 if (!NumClasses && !NumCategories)
4920 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
4922 ConstantInitBuilder builder(CGM);
4923 auto values = builder.beginStruct();
4924 values.addInt(ObjCTypes.LongTy, 0);
4925 values.addNullPointer(ObjCTypes.SelectorPtrTy);
4926 values.addInt(ObjCTypes.ShortTy, NumClasses);
4927 values.addInt(ObjCTypes.ShortTy, NumCategories);
4929 // The runtime expects exactly the list of defined classes followed
4930 // by the list of defined categories, in a single array.
4931 auto array = values.beginArray(ObjCTypes.Int8PtrTy);
4932 for (unsigned i=0; i<NumClasses; i++) {
4933 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
4935 if (ObjCImplementationDecl *IMP = ID->getImplementation())
4936 // We are implementing a weak imported interface. Give it external linkage
4937 if (ID->isWeakImported() && !IMP->isWeakImported())
4938 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
4940 array.addBitCast(DefinedClasses[i], ObjCTypes.Int8PtrTy);
4942 for (unsigned i=0; i<NumCategories; i++)
4943 array.addBitCast(DefinedCategories[i], ObjCTypes.Int8PtrTy);
4945 array.finishAndAddTo(values);
4947 llvm::GlobalVariable *GV = CreateMetadataVar(
4948 "OBJC_SYMBOLS", values, "__OBJC,__symbols,regular,no_dead_strip",
4949 CGM.getPointerAlign(), true);
4950 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
4953 llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,
4954 IdentifierInfo *II) {
4955 LazySymbols.insert(II);
4957 llvm::GlobalVariable *&Entry = ClassReferences[II];
4960 llvm::Constant *Casted =
4961 llvm::ConstantExpr::getBitCast(GetClassName(II->getName()),
4962 ObjCTypes.ClassPtrTy);
4963 Entry = CreateMetadataVar(
4964 "OBJC_CLASS_REFERENCES_", Casted,
4965 "__OBJC,__cls_refs,literal_pointers,no_dead_strip",
4966 CGM.getPointerAlign(), true);
4969 return CGF.Builder.CreateAlignedLoad(Entry, CGF.getPointerAlign());
4972 llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF,
4973 const ObjCInterfaceDecl *ID) {
4974 // If the class has the objc_runtime_visible attribute, we need to
4975 // use the Objective-C runtime to get the class.
4976 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
4977 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
4979 return EmitClassRefFromId(CGF, ID->getIdentifier());
4982 llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
4983 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
4984 return EmitClassRefFromId(CGF, II);
4987 llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) {
4988 return CGF.Builder.CreateLoad(EmitSelectorAddr(CGF, Sel));
4991 Address CGObjCMac::EmitSelectorAddr(CodeGenFunction &CGF, Selector Sel) {
4992 CharUnits Align = CGF.getPointerAlign();
4994 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
4996 llvm::Constant *Casted =
4997 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
4998 ObjCTypes.SelectorPtrTy);
4999 Entry = CreateMetadataVar(
5000 "OBJC_SELECTOR_REFERENCES_", Casted,
5001 "__OBJC,__message_refs,literal_pointers,no_dead_strip", Align, true);
5002 Entry->setExternallyInitialized(true);
5005 return Address(Entry, Align);
5008 llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
5009 llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
5011 Entry = CreateCStringLiteral(RuntimeName, ObjCLabelType::ClassName);
5012 return getConstantGEP(VMContext, Entry, 0, 0);
5015 llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
5016 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator
5017 I = MethodDefinitions.find(MD);
5018 if (I != MethodDefinitions.end())
5024 /// GetIvarLayoutName - Returns a unique constant for the given
5025 /// ivar layout bitmap.
5026 llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
5027 const ObjCCommonTypesHelper &ObjCTypes) {
5028 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
5031 void IvarLayoutBuilder::visitRecord(const RecordType *RT,
5033 const RecordDecl *RD = RT->getDecl();
5035 // If this is a union, remember that we had one, because it might mess
5036 // up the ordering of layout entries.
5038 IsDisordered = true;
5040 const ASTRecordLayout *recLayout = nullptr;
5041 visitAggregate(RD->field_begin(), RD->field_end(), offset,
5042 [&](const FieldDecl *field) -> CharUnits {
5044 recLayout = &CGM.getContext().getASTRecordLayout(RD);
5045 auto offsetInBits = recLayout->getFieldOffset(field->getFieldIndex());
5046 return CGM.getContext().toCharUnitsFromBits(offsetInBits);
5050 template <class Iterator, class GetOffsetFn>
5051 void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,
5052 CharUnits aggregateOffset,
5053 const GetOffsetFn &getOffset) {
5054 for (; begin != end; ++begin) {
5055 auto field = *begin;
5057 // Skip over bitfields.
5058 if (field->isBitField()) {
5062 // Compute the offset of the field within the aggregate.
5063 CharUnits fieldOffset = aggregateOffset + getOffset(field);
5065 visitField(field, fieldOffset);
5069 /// Collect layout information for the given fields into IvarsInfo.
5070 void IvarLayoutBuilder::visitField(const FieldDecl *field,
5071 CharUnits fieldOffset) {
5072 QualType fieldType = field->getType();
5074 // Drill down into arrays.
5075 uint64_t numElts = 1;
5076 while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) {
5077 numElts *= arrayType->getSize().getZExtValue();
5078 fieldType = arrayType->getElementType();
5081 assert(!fieldType->isArrayType() && "ivar of non-constant array type?");
5083 // If we ended up with a zero-sized array, we've done what we can do within
5084 // the limits of this layout encoding.
5085 if (numElts == 0) return;
5087 // Recurse if the base element type is a record type.
5088 if (auto recType = fieldType->getAs<RecordType>()) {
5089 size_t oldEnd = IvarsInfo.size();
5091 visitRecord(recType, fieldOffset);
5093 // If we have an array, replicate the first entry's layout information.
5094 auto numEltEntries = IvarsInfo.size() - oldEnd;
5095 if (numElts != 1 && numEltEntries != 0) {
5096 CharUnits eltSize = CGM.getContext().getTypeSizeInChars(recType);
5097 for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) {
5098 // Copy the last numEltEntries onto the end of the array, adjusting
5099 // each for the element size.
5100 for (size_t i = 0; i != numEltEntries; ++i) {
5101 auto firstEntry = IvarsInfo[oldEnd + i];
5102 IvarsInfo.push_back(IvarInfo(firstEntry.Offset + eltIndex * eltSize,
5103 firstEntry.SizeInWords));
5111 // Classify the element type.
5112 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), fieldType);
5114 // If it matches what we're looking for, add an entry.
5115 if ((ForStrongLayout && GCAttr == Qualifiers::Strong)
5116 || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
5117 assert(CGM.getContext().getTypeSizeInChars(fieldType)
5118 == CGM.getPointerSize());
5119 IvarsInfo.push_back(IvarInfo(fieldOffset, numElts));
5123 /// buildBitmap - This routine does the horsework of taking the offsets of
5124 /// strong/weak references and creating a bitmap. The bitmap is also
5125 /// returned in the given buffer, suitable for being passed to \c dump().
5126 llvm::Constant *IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
5127 llvm::SmallVectorImpl<unsigned char> &buffer) {
5128 // The bitmap is a series of skip/scan instructions, aligned to word
5129 // boundaries. The skip is performed first.
5130 const unsigned char MaxNibble = 0xF;
5131 const unsigned char SkipMask = 0xF0, SkipShift = 4;
5132 const unsigned char ScanMask = 0x0F, ScanShift = 0;
5134 assert(!IvarsInfo.empty() && "generating bitmap for no data");
5136 // Sort the ivar info on byte position in case we encounterred a
5137 // union nested in the ivar list.
5139 // This isn't a stable sort, but our algorithm should handle it fine.
5140 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
5142 assert(std::is_sorted(IvarsInfo.begin(), IvarsInfo.end()));
5144 assert(IvarsInfo.back().Offset < InstanceEnd);
5146 assert(buffer.empty());
5148 // Skip the next N words.
5149 auto skip = [&](unsigned numWords) {
5150 assert(numWords > 0);
5152 // Try to merge into the previous byte. Since scans happen second, we
5153 // can't do this if it includes a scan.
5154 if (!buffer.empty() && !(buffer.back() & ScanMask)) {
5155 unsigned lastSkip = buffer.back() >> SkipShift;
5156 if (lastSkip < MaxNibble) {
5157 unsigned claimed = std::min(MaxNibble - lastSkip, numWords);
5158 numWords -= claimed;
5159 lastSkip += claimed;
5160 buffer.back() = (lastSkip << SkipShift);
5164 while (numWords >= MaxNibble) {
5165 buffer.push_back(MaxNibble << SkipShift);
5166 numWords -= MaxNibble;
5169 buffer.push_back(numWords << SkipShift);
5173 // Scan the next N words.
5174 auto scan = [&](unsigned numWords) {
5175 assert(numWords > 0);
5177 // Try to merge into the previous byte. Since scans happen second, we can
5178 // do this even if it includes a skip.
5179 if (!buffer.empty()) {
5180 unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift;
5181 if (lastScan < MaxNibble) {
5182 unsigned claimed = std::min(MaxNibble - lastScan, numWords);
5183 numWords -= claimed;
5184 lastScan += claimed;
5185 buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift);
5189 while (numWords >= MaxNibble) {
5190 buffer.push_back(MaxNibble << ScanShift);
5191 numWords -= MaxNibble;
5194 buffer.push_back(numWords << ScanShift);
5198 // One past the end of the last scan.
5199 unsigned endOfLastScanInWords = 0;
5200 const CharUnits WordSize = CGM.getPointerSize();
5202 // Consider all the scan requests.
5203 for (auto &request : IvarsInfo) {
5204 CharUnits beginOfScan = request.Offset - InstanceBegin;
5206 // Ignore scan requests that don't start at an even multiple of the
5207 // word size. We can't encode them.
5208 if ((beginOfScan % WordSize) != 0) continue;
5210 // Ignore scan requests that start before the instance start.
5211 // This assumes that scans never span that boundary. The boundary
5212 // isn't the true start of the ivars, because in the fragile-ARC case
5213 // it's rounded up to word alignment, but the test above should leave
5214 // us ignoring that possibility.
5215 if (beginOfScan.isNegative()) {
5216 assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin);
5220 unsigned beginOfScanInWords = beginOfScan / WordSize;
5221 unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords;
5223 // If the scan starts some number of words after the last one ended,
5225 if (beginOfScanInWords > endOfLastScanInWords) {
5226 skip(beginOfScanInWords - endOfLastScanInWords);
5228 // Otherwise, start scanning where the last left off.
5230 beginOfScanInWords = endOfLastScanInWords;
5232 // If that leaves us with nothing to scan, ignore this request.
5233 if (beginOfScanInWords >= endOfScanInWords) continue;
5236 // Scan to the end of the request.
5237 assert(beginOfScanInWords < endOfScanInWords);
5238 scan(endOfScanInWords - beginOfScanInWords);
5239 endOfLastScanInWords = endOfScanInWords;
5243 return llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
5245 // For GC layouts, emit a skip to the end of the allocation so that we
5246 // have precise information about the entire thing. This isn't useful
5247 // or necessary for the ARC-style layout strings.
5248 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
5249 unsigned lastOffsetInWords =
5250 (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize;
5251 if (lastOffsetInWords > endOfLastScanInWords) {
5252 skip(lastOffsetInWords - endOfLastScanInWords);
5256 // Null terminate the string.
5257 buffer.push_back(0);
5259 auto *Entry = CGObjC.CreateCStringLiteral(
5260 reinterpret_cast<char *>(buffer.data()), ObjCLabelType::ClassName);
5261 return getConstantGEP(CGM.getLLVMContext(), Entry, 0, 0);
5264 /// BuildIvarLayout - Builds ivar layout bitmap for the class
5265 /// implementation for the __strong or __weak case.
5266 /// The layout map displays which words in ivar list must be skipped
5267 /// and which must be scanned by GC (see below). String is built of bytes.
5268 /// Each byte is divided up in two nibbles (4-bit each). Left nibble is count
5269 /// of words to skip and right nibble is count of words to scan. So, each
5270 /// nibble represents up to 15 workds to skip or scan. Skipping the rest is
5271 /// represented by a 0x00 byte which also ends the string.
5272 /// 1. when ForStrongLayout is true, following ivars are scanned:
5275 /// - __strong anything
5277 /// 2. When ForStrongLayout is false, following ivars are scanned:
5278 /// - __weak anything
5281 CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
5282 CharUnits beginOffset, CharUnits endOffset,
5283 bool ForStrongLayout, bool HasMRCWeakIvars) {
5284 // If this is MRC, and we're either building a strong layout or there
5285 // are no weak ivars, bail out early.
5286 llvm::Type *PtrTy = CGM.Int8PtrTy;
5287 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
5288 !CGM.getLangOpts().ObjCAutoRefCount &&
5289 (ForStrongLayout || !HasMRCWeakIvars))
5290 return llvm::Constant::getNullValue(PtrTy);
5292 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
5293 SmallVector<const ObjCIvarDecl*, 32> ivars;
5295 // GC layout strings include the complete object layout, possibly
5296 // inaccurately in the non-fragile ABI; the runtime knows how to fix this
5299 // ARC layout strings only include the class's ivars. In non-fragile
5300 // runtimes, that means starting at InstanceStart, rounded up to word
5301 // alignment. In fragile runtimes, there's no InstanceStart, so it means
5302 // starting at the offset of the first ivar, rounded up to word alignment.
5304 // MRC weak layout strings follow the ARC style.
5305 CharUnits baseOffset;
5306 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
5307 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
5308 IVD; IVD = IVD->getNextIvar())
5309 ivars.push_back(IVD);
5311 if (isNonFragileABI()) {
5312 baseOffset = beginOffset; // InstanceStart
5313 } else if (!ivars.empty()) {
5315 CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivars[0]));
5317 baseOffset = CharUnits::Zero();
5320 baseOffset = baseOffset.alignTo(CGM.getPointerAlign());
5323 CGM.getContext().DeepCollectObjCIvars(OI, true, ivars);
5325 baseOffset = CharUnits::Zero();
5329 return llvm::Constant::getNullValue(PtrTy);
5331 IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout);
5333 builder.visitAggregate(ivars.begin(), ivars.end(), CharUnits::Zero(),
5334 [&](const ObjCIvarDecl *ivar) -> CharUnits {
5335 return CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivar));
5338 if (!builder.hasBitmapData())
5339 return llvm::Constant::getNullValue(PtrTy);
5341 llvm::SmallVector<unsigned char, 4> buffer;
5342 llvm::Constant *C = builder.buildBitmap(*this, buffer);
5344 if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
5345 printf("\n%s ivar layout for class '%s': ",
5346 ForStrongLayout ? "strong" : "weak",
5347 OMD->getClassInterface()->getName().str().c_str());
5348 builder.dump(buffer);
5353 llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
5354 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
5355 // FIXME: Avoid std::string in "Sel.getAsString()"
5357 Entry = CreateCStringLiteral(Sel.getAsString(), ObjCLabelType::MethodVarName);
5358 return getConstantGEP(VMContext, Entry, 0, 0);
5361 // FIXME: Merge into a single cstring creation function.
5362 llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
5363 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
5366 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
5367 std::string TypeStr;
5368 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
5370 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
5372 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
5373 return getConstantGEP(VMContext, Entry, 0, 0);
5376 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
5378 std::string TypeStr =
5379 CGM.getContext().getObjCEncodingForMethodDecl(D, Extended);
5381 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
5383 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
5384 return getConstantGEP(VMContext, Entry, 0, 0);
5387 // FIXME: Merge into a single cstring creation function.
5388 llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
5389 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
5391 Entry = CreateCStringLiteral(Ident->getName(), ObjCLabelType::PropertyName);
5392 return getConstantGEP(VMContext, Entry, 0, 0);
5395 // FIXME: Merge into a single cstring creation function.
5396 // FIXME: This Decl should be more precise.
5398 CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
5399 const Decl *Container) {
5400 std::string TypeStr =
5401 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container);
5402 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
5405 void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D,
5406 const ObjCContainerDecl *CD,
5407 SmallVectorImpl<char> &Name) {
5408 llvm::raw_svector_ostream OS(Name);
5409 assert (CD && "Missing container decl in GetNameForMethod");
5410 OS << '\01' << (D->isInstanceMethod() ? '-' : '+')
5411 << '[' << CD->getName();
5412 if (const ObjCCategoryImplDecl *CID =
5413 dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
5414 OS << '(' << *CID << ')';
5415 OS << ' ' << D->getSelector().getAsString() << ']';
5418 void CGObjCMac::FinishModule() {
5421 // Emit the dummy bodies for any protocols which were referenced but
5423 for (auto &entry : Protocols) {
5424 llvm::GlobalVariable *global = entry.second;
5425 if (global->hasInitializer())
5428 ConstantInitBuilder builder(CGM);
5429 auto values = builder.beginStruct(ObjCTypes.ProtocolTy);
5430 values.addNullPointer(ObjCTypes.ProtocolExtensionPtrTy);
5431 values.add(GetClassName(entry.first->getName()));
5432 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
5433 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);
5434 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);
5435 values.finishAndSetAsInitializer(global);
5436 CGM.addCompilerUsedGlobal(global);
5439 // Add assembler directives to add lazy undefined symbol references
5440 // for classes which are referenced but not defined. This is
5441 // important for correct linker interaction.
5443 // FIXME: It would be nice if we had an LLVM construct for this.
5444 if ((!LazySymbols.empty() || !DefinedSymbols.empty()) &&
5445 CGM.getTriple().isOSBinFormatMachO()) {
5446 SmallString<256> Asm;
5447 Asm += CGM.getModule().getModuleInlineAsm();
5448 if (!Asm.empty() && Asm.back() != '\n')
5451 llvm::raw_svector_ostream OS(Asm);
5452 for (const auto *Sym : DefinedSymbols)
5453 OS << "\t.objc_class_name_" << Sym->getName() << "=0\n"
5454 << "\t.globl .objc_class_name_" << Sym->getName() << "\n";
5455 for (const auto *Sym : LazySymbols)
5456 OS << "\t.lazy_reference .objc_class_name_" << Sym->getName() << "\n";
5457 for (const auto &Category : DefinedCategoryNames)
5458 OS << "\t.objc_category_name_" << Category << "=0\n"
5459 << "\t.globl .objc_category_name_" << Category << "\n";
5461 CGM.getModule().setModuleInlineAsm(OS.str());
5465 CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
5466 : CGObjCCommonMac(cgm), ObjCTypes(cgm), ObjCEmptyCacheVar(nullptr),
5467 ObjCEmptyVtableVar(nullptr) {
5473 ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
5474 : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(nullptr)
5476 CodeGen::CodeGenTypes &Types = CGM.getTypes();
5477 ASTContext &Ctx = CGM.getContext();
5479 ShortTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.ShortTy));
5481 LongTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.LongTy));
5482 Int8PtrTy = CGM.Int8PtrTy;
5483 Int8PtrPtrTy = CGM.Int8PtrPtrTy;
5485 // arm64 targets use "int" ivar offset variables. All others,
5486 // including OS X x86_64 and Windows x86_64, use "long" ivar offsets.
5487 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64)
5488 IvarOffsetVarTy = IntTy;
5490 IvarOffsetVarTy = LongTy;
5493 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCIdType()));
5495 llvm::PointerType::getUnqual(ObjectPtrTy);
5497 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCSelType()));
5499 // I'm not sure I like this. The implicit coordination is a bit
5500 // gross. We should solve this in a reasonable fashion because this
5501 // is a pretty common task (match some runtime data structure with
5502 // an LLVM data structure).
5504 // FIXME: This is leaked.
5505 // FIXME: Merge with rewriter code?
5507 // struct _objc_super {
5511 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
5512 Ctx.getTranslationUnitDecl(),
5513 SourceLocation(), SourceLocation(),
5514 &Ctx.Idents.get("_objc_super"));
5515 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5516 nullptr, Ctx.getObjCIdType(), nullptr, nullptr,
5517 false, ICIS_NoInit));
5518 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5519 nullptr, Ctx.getObjCClassType(), nullptr,
5520 nullptr, false, ICIS_NoInit));
5521 RD->completeDefinition();
5523 SuperCTy = Ctx.getTagDeclType(RD);
5524 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
5526 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
5527 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
5531 // char *attributes;
5533 PropertyTy = llvm::StructType::create("struct._prop_t", Int8PtrTy, Int8PtrTy);
5535 // struct _prop_list_t {
5536 // uint32_t entsize; // sizeof(struct _prop_t)
5537 // uint32_t count_of_properties;
5538 // struct _prop_t prop_list[count_of_properties];
5540 PropertyListTy = llvm::StructType::create(
5541 "struct._prop_list_t", IntTy, IntTy, llvm::ArrayType::get(PropertyTy, 0));
5542 // struct _prop_list_t *
5543 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
5545 // struct _objc_method {
5547 // char *method_type;
5550 MethodTy = llvm::StructType::create("struct._objc_method", SelectorPtrTy,
5551 Int8PtrTy, Int8PtrTy);
5553 // struct _objc_cache *
5554 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache");
5555 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
5558 ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
5559 : ObjCCommonTypesHelper(cgm) {
5560 // struct _objc_method_description {
5564 MethodDescriptionTy = llvm::StructType::create(
5565 "struct._objc_method_description", SelectorPtrTy, Int8PtrTy);
5567 // struct _objc_method_description_list {
5569 // struct _objc_method_description[1];
5571 MethodDescriptionListTy =
5572 llvm::StructType::create("struct._objc_method_description_list", IntTy,
5573 llvm::ArrayType::get(MethodDescriptionTy, 0));
5575 // struct _objc_method_description_list *
5576 MethodDescriptionListPtrTy =
5577 llvm::PointerType::getUnqual(MethodDescriptionListTy);
5579 // Protocol description structures
5581 // struct _objc_protocol_extension {
5582 // uint32_t size; // sizeof(struct _objc_protocol_extension)
5583 // struct _objc_method_description_list *optional_instance_methods;
5584 // struct _objc_method_description_list *optional_class_methods;
5585 // struct _objc_property_list *instance_properties;
5586 // const char ** extendedMethodTypes;
5587 // struct _objc_property_list *class_properties;
5589 ProtocolExtensionTy = llvm::StructType::create(
5590 "struct._objc_protocol_extension", IntTy, MethodDescriptionListPtrTy,
5591 MethodDescriptionListPtrTy, PropertyListPtrTy, Int8PtrPtrTy,
5594 // struct _objc_protocol_extension *
5595 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
5597 // Handle recursive construction of Protocol and ProtocolList types
5600 llvm::StructType::create(VMContext, "struct._objc_protocol");
5603 llvm::StructType::create(VMContext, "struct._objc_protocol_list");
5604 ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy), LongTy,
5605 llvm::ArrayType::get(ProtocolTy, 0));
5607 // struct _objc_protocol {
5608 // struct _objc_protocol_extension *isa;
5609 // char *protocol_name;
5610 // struct _objc_protocol **_objc_protocol_list;
5611 // struct _objc_method_description_list *instance_methods;
5612 // struct _objc_method_description_list *class_methods;
5614 ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy,
5615 llvm::PointerType::getUnqual(ProtocolListTy),
5616 MethodDescriptionListPtrTy, MethodDescriptionListPtrTy);
5618 // struct _objc_protocol_list *
5619 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
5621 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
5623 // Class description structures
5625 // struct _objc_ivar {
5630 IvarTy = llvm::StructType::create("struct._objc_ivar", Int8PtrTy, Int8PtrTy,
5633 // struct _objc_ivar_list *
5635 llvm::StructType::create(VMContext, "struct._objc_ivar_list");
5636 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
5638 // struct _objc_method_list *
5640 llvm::StructType::create(VMContext, "struct._objc_method_list");
5641 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
5643 // struct _objc_class_extension *
5644 ClassExtensionTy = llvm::StructType::create(
5645 "struct._objc_class_extension", IntTy, Int8PtrTy, PropertyListPtrTy);
5646 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
5648 ClassTy = llvm::StructType::create(VMContext, "struct._objc_class");
5650 // struct _objc_class {
5652 // Class super_class;
5656 // long instance_size;
5657 // struct _objc_ivar_list *ivars;
5658 // struct _objc_method_list *methods;
5659 // struct _objc_cache *cache;
5660 // struct _objc_protocol_list *protocols;
5661 // char *ivar_layout;
5662 // struct _objc_class_ext *ext;
5664 ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy),
5665 llvm::PointerType::getUnqual(ClassTy), Int8PtrTy, LongTy,
5666 LongTy, LongTy, IvarListPtrTy, MethodListPtrTy, CachePtrTy,
5667 ProtocolListPtrTy, Int8PtrTy, ClassExtensionPtrTy);
5669 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
5671 // struct _objc_category {
5672 // char *category_name;
5673 // char *class_name;
5674 // struct _objc_method_list *instance_method;
5675 // struct _objc_method_list *class_method;
5676 // struct _objc_protocol_list *protocols;
5677 // uint32_t size; // sizeof(struct _objc_category)
5678 // struct _objc_property_list *instance_properties;// category's @property
5679 // struct _objc_property_list *class_properties;
5681 CategoryTy = llvm::StructType::create(
5682 "struct._objc_category", Int8PtrTy, Int8PtrTy, MethodListPtrTy,
5683 MethodListPtrTy, ProtocolListPtrTy, IntTy, PropertyListPtrTy,
5686 // Global metadata structures
5688 // struct _objc_symtab {
5689 // long sel_ref_cnt;
5691 // short cls_def_cnt;
5692 // short cat_def_cnt;
5693 // char *defs[cls_def_cnt + cat_def_cnt];
5695 SymtabTy = llvm::StructType::create("struct._objc_symtab", LongTy,
5696 SelectorPtrTy, ShortTy, ShortTy,
5697 llvm::ArrayType::get(Int8PtrTy, 0));
5698 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
5700 // struct _objc_module {
5702 // long size; // sizeof(struct _objc_module)
5704 // struct _objc_symtab* symtab;
5706 ModuleTy = llvm::StructType::create("struct._objc_module", LongTy, LongTy,
5707 Int8PtrTy, SymtabPtrTy);
5709 // FIXME: This is the size of the setjmp buffer and should be target
5710 // specific. 18 is what's used on 32-bit X86.
5711 uint64_t SetJmpBufferSize = 18;
5714 llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4);
5716 ExceptionDataTy = llvm::StructType::create(
5717 "struct._objc_exception_data",
5718 llvm::ArrayType::get(CGM.Int32Ty, SetJmpBufferSize), StackPtrTy);
5721 ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm)
5722 : ObjCCommonTypesHelper(cgm) {
5723 // struct _method_list_t {
5724 // uint32_t entsize; // sizeof(struct _objc_method)
5725 // uint32_t method_count;
5726 // struct _objc_method method_list[method_count];
5729 llvm::StructType::create("struct.__method_list_t", IntTy, IntTy,
5730 llvm::ArrayType::get(MethodTy, 0));
5731 // struct method_list_t *
5732 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy);
5734 // struct _protocol_t {
5736 // const char * const protocol_name;
5737 // const struct _protocol_list_t * protocol_list; // super protocols
5738 // const struct method_list_t * const instance_methods;
5739 // const struct method_list_t * const class_methods;
5740 // const struct method_list_t *optionalInstanceMethods;
5741 // const struct method_list_t *optionalClassMethods;
5742 // const struct _prop_list_t * properties;
5743 // const uint32_t size; // sizeof(struct _protocol_t)
5744 // const uint32_t flags; // = 0
5745 // const char ** extendedMethodTypes;
5746 // const char *demangledName;
5747 // const struct _prop_list_t * class_properties;
5750 // Holder for struct _protocol_list_t *
5751 ProtocolListnfABITy =
5752 llvm::StructType::create(VMContext, "struct._objc_protocol_list");
5754 ProtocolnfABITy = llvm::StructType::create(
5755 "struct._protocol_t", ObjectPtrTy, Int8PtrTy,
5756 llvm::PointerType::getUnqual(ProtocolListnfABITy), MethodListnfABIPtrTy,
5757 MethodListnfABIPtrTy, MethodListnfABIPtrTy, MethodListnfABIPtrTy,
5758 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy, Int8PtrTy,
5761 // struct _protocol_t*
5762 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy);
5764 // struct _protocol_list_t {
5765 // long protocol_count; // Note, this is 32/64 bit
5766 // struct _protocol_t *[protocol_count];
5768 ProtocolListnfABITy->setBody(LongTy,
5769 llvm::ArrayType::get(ProtocolnfABIPtrTy, 0));
5771 // struct _objc_protocol_list*
5772 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy);
5775 // unsigned [long] int *offset; // pointer to ivar offset location
5778 // uint32_t alignment;
5781 IvarnfABITy = llvm::StructType::create(
5782 "struct._ivar_t", llvm::PointerType::getUnqual(IvarOffsetVarTy),
5783 Int8PtrTy, Int8PtrTy, IntTy, IntTy);
5785 // struct _ivar_list_t {
5786 // uint32 entsize; // sizeof(struct _ivar_t)
5788 // struct _iver_t list[count];
5791 llvm::StructType::create("struct._ivar_list_t", IntTy, IntTy,
5792 llvm::ArrayType::get(IvarnfABITy, 0));
5794 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy);
5796 // struct _class_ro_t {
5797 // uint32_t const flags;
5798 // uint32_t const instanceStart;
5799 // uint32_t const instanceSize;
5800 // uint32_t const reserved; // only when building for 64bit targets
5801 // const uint8_t * const ivarLayout;
5802 // const char *const name;
5803 // const struct _method_list_t * const baseMethods;
5804 // const struct _objc_protocol_list *const baseProtocols;
5805 // const struct _ivar_list_t *const ivars;
5806 // const uint8_t * const weakIvarLayout;
5807 // const struct _prop_list_t * const properties;
5810 // FIXME. Add 'reserved' field in 64bit abi mode!
5811 ClassRonfABITy = llvm::StructType::create(
5812 "struct._class_ro_t", IntTy, IntTy, IntTy, Int8PtrTy, Int8PtrTy,
5813 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, IvarListnfABIPtrTy,
5814 Int8PtrTy, PropertyListPtrTy);
5816 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
5817 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
5818 ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false)
5821 // struct _class_t {
5822 // struct _class_t *isa;
5823 // struct _class_t * const superclass;
5826 // struct class_ro_t *ro;
5829 ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t");
5830 ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy),
5831 llvm::PointerType::getUnqual(ClassnfABITy), CachePtrTy,
5832 llvm::PointerType::getUnqual(ImpnfABITy),
5833 llvm::PointerType::getUnqual(ClassRonfABITy));
5835 // LLVM for struct _class_t *
5836 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy);
5838 // struct _category_t {
5839 // const char * const name;
5840 // struct _class_t *const cls;
5841 // const struct _method_list_t * const instance_methods;
5842 // const struct _method_list_t * const class_methods;
5843 // const struct _protocol_list_t * const protocols;
5844 // const struct _prop_list_t * const properties;
5845 // const struct _prop_list_t * const class_properties;
5846 // const uint32_t size;
5848 CategorynfABITy = llvm::StructType::create(
5849 "struct._category_t", Int8PtrTy, ClassnfABIPtrTy, MethodListnfABIPtrTy,
5850 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, PropertyListPtrTy,
5851 PropertyListPtrTy, IntTy);
5853 // New types for nonfragile abi messaging.
5854 CodeGen::CodeGenTypes &Types = CGM.getTypes();
5855 ASTContext &Ctx = CGM.getContext();
5857 // MessageRefTy - LLVM for:
5858 // struct _message_ref_t {
5863 // First the clang type for struct _message_ref_t
5864 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
5865 Ctx.getTranslationUnitDecl(),
5866 SourceLocation(), SourceLocation(),
5867 &Ctx.Idents.get("_message_ref_t"));
5868 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5869 nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false,
5871 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5872 nullptr, Ctx.getObjCSelType(), nullptr, nullptr,
5873 false, ICIS_NoInit));
5874 RD->completeDefinition();
5876 MessageRefCTy = Ctx.getTagDeclType(RD);
5877 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
5878 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
5880 // MessageRefPtrTy - LLVM for struct _message_ref_t*
5881 MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy);
5883 // SuperMessageRefTy - LLVM for:
5884 // struct _super_message_ref_t {
5885 // SUPER_IMP messenger;
5888 SuperMessageRefTy = llvm::StructType::create("struct._super_message_ref_t",
5889 ImpnfABITy, SelectorPtrTy);
5891 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
5892 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);
5895 // struct objc_typeinfo {
5896 // const void** vtable; // objc_ehtype_vtable + 2
5897 // const char* name; // c++ typeinfo string
5900 EHTypeTy = llvm::StructType::create("struct._objc_typeinfo",
5901 llvm::PointerType::getUnqual(Int8PtrTy),
5902 Int8PtrTy, ClassnfABIPtrTy);
5903 EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy);
5906 llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
5907 FinishNonFragileABIModule();
5912 void CGObjCNonFragileABIMac::AddModuleClassList(
5913 ArrayRef<llvm::GlobalValue *> Container, StringRef SymbolName,
5914 StringRef SectionName) {
5915 unsigned NumClasses = Container.size();
5920 SmallVector<llvm::Constant*, 8> Symbols(NumClasses);
5921 for (unsigned i=0; i<NumClasses; i++)
5922 Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i],
5923 ObjCTypes.Int8PtrTy);
5924 llvm::Constant *Init =
5925 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
5929 llvm::GlobalVariable *GV =
5930 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5931 llvm::GlobalValue::PrivateLinkage,
5934 GV->setAlignment(CGM.getDataLayout().getABITypeAlignment(Init->getType()));
5935 GV->setSection(SectionName);
5936 CGM.addCompilerUsedGlobal(GV);
5939 void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
5940 // nonfragile abi has no module definition.
5942 // Build list of all implemented class addresses in array
5943 // L_OBJC_LABEL_CLASS_$.
5945 for (unsigned i=0, NumClasses=ImplementedClasses.size(); i<NumClasses; i++) {
5946 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
5948 if (ObjCImplementationDecl *IMP = ID->getImplementation())
5949 // We are implementing a weak imported interface. Give it external linkage
5950 if (ID->isWeakImported() && !IMP->isWeakImported()) {
5951 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
5952 DefinedMetaClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
5956 AddModuleClassList(DefinedClasses, "OBJC_LABEL_CLASS_$",
5957 GetSectionName("__objc_classlist",
5958 "regular,no_dead_strip"));
5960 AddModuleClassList(DefinedNonLazyClasses, "OBJC_LABEL_NONLAZY_CLASS_$",
5961 GetSectionName("__objc_nlclslist",
5962 "regular,no_dead_strip"));
5964 // Build list of all implemented category addresses in array
5965 // L_OBJC_LABEL_CATEGORY_$.
5966 AddModuleClassList(DefinedCategories, "OBJC_LABEL_CATEGORY_$",
5967 GetSectionName("__objc_catlist",
5968 "regular,no_dead_strip"));
5969 AddModuleClassList(DefinedNonLazyCategories, "OBJC_LABEL_NONLAZY_CATEGORY_$",
5970 GetSectionName("__objc_nlcatlist",
5971 "regular,no_dead_strip"));
5976 /// isVTableDispatchedSelector - Returns true if SEL is not in the list of
5977 /// VTableDispatchMethods; false otherwise. What this means is that
5978 /// except for the 19 selectors in the list, we generate 32bit-style
5979 /// message dispatch call for all the rest.
5980 bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
5981 // At various points we've experimented with using vtable-based
5982 // dispatch for all methods.
5983 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
5984 case CodeGenOptions::Legacy:
5986 case CodeGenOptions::NonLegacy:
5988 case CodeGenOptions::Mixed:
5992 // If so, see whether this selector is in the white-list of things which must
5993 // use the new dispatch convention. We lazily build a dense set for this.
5994 if (VTableDispatchMethods.empty()) {
5995 VTableDispatchMethods.insert(GetNullarySelector("alloc"));
5996 VTableDispatchMethods.insert(GetNullarySelector("class"));
5997 VTableDispatchMethods.insert(GetNullarySelector("self"));
5998 VTableDispatchMethods.insert(GetNullarySelector("isFlipped"));
5999 VTableDispatchMethods.insert(GetNullarySelector("length"));
6000 VTableDispatchMethods.insert(GetNullarySelector("count"));
6002 // These are vtable-based if GC is disabled.
6003 // Optimistically use vtable dispatch for hybrid compiles.
6004 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
6005 VTableDispatchMethods.insert(GetNullarySelector("retain"));
6006 VTableDispatchMethods.insert(GetNullarySelector("release"));
6007 VTableDispatchMethods.insert(GetNullarySelector("autorelease"));
6010 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone"));
6011 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass"));
6012 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector"));
6013 VTableDispatchMethods.insert(GetUnarySelector("objectForKey"));
6014 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex"));
6015 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString"));
6016 VTableDispatchMethods.insert(GetUnarySelector("isEqual"));
6018 // These are vtable-based if GC is enabled.
6019 // Optimistically use vtable dispatch for hybrid compiles.
6020 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
6021 VTableDispatchMethods.insert(GetNullarySelector("hash"));
6022 VTableDispatchMethods.insert(GetUnarySelector("addObject"));
6024 // "countByEnumeratingWithState:objects:count"
6025 IdentifierInfo *KeyIdents[] = {
6026 &CGM.getContext().Idents.get("countByEnumeratingWithState"),
6027 &CGM.getContext().Idents.get("objects"),
6028 &CGM.getContext().Idents.get("count")
6030 VTableDispatchMethods.insert(
6031 CGM.getContext().Selectors.getSelector(3, KeyIdents));
6035 return VTableDispatchMethods.count(Sel);
6038 /// BuildClassRoTInitializer - generate meta-data for:
6039 /// struct _class_ro_t {
6040 /// uint32_t const flags;
6041 /// uint32_t const instanceStart;
6042 /// uint32_t const instanceSize;
6043 /// uint32_t const reserved; // only when building for 64bit targets
6044 /// const uint8_t * const ivarLayout;
6045 /// const char *const name;
6046 /// const struct _method_list_t * const baseMethods;
6047 /// const struct _protocol_list_t *const baseProtocols;
6048 /// const struct _ivar_list_t *const ivars;
6049 /// const uint8_t * const weakIvarLayout;
6050 /// const struct _prop_list_t * const properties;
6053 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
6055 unsigned InstanceStart,
6056 unsigned InstanceSize,
6057 const ObjCImplementationDecl *ID) {
6058 std::string ClassName = ID->getObjCRuntimeNameAsString();
6060 CharUnits beginInstance = CharUnits::fromQuantity(InstanceStart);
6061 CharUnits endInstance = CharUnits::fromQuantity(InstanceSize);
6063 bool hasMRCWeak = false;
6064 if (CGM.getLangOpts().ObjCAutoRefCount)
6065 flags |= NonFragileABI_Class_CompiledByARC;
6066 else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
6067 flags |= NonFragileABI_Class_HasMRCWeakIvars;
6069 ConstantInitBuilder builder(CGM);
6070 auto values = builder.beginStruct(ObjCTypes.ClassRonfABITy);
6072 values.addInt(ObjCTypes.IntTy, flags);
6073 values.addInt(ObjCTypes.IntTy, InstanceStart);
6074 values.addInt(ObjCTypes.IntTy, InstanceSize);
6075 values.add((flags & NonFragileABI_Class_Meta)
6076 ? GetIvarLayoutName(nullptr, ObjCTypes)
6077 : BuildStrongIvarLayout(ID, beginInstance, endInstance));
6078 values.add(GetClassName(ID->getObjCRuntimeNameAsString()));
6080 // const struct _method_list_t * const baseMethods;
6081 SmallVector<const ObjCMethodDecl*, 16> methods;
6082 if (flags & NonFragileABI_Class_Meta) {
6083 for (const auto *MD : ID->class_methods())
6084 methods.push_back(MD);
6086 for (const auto *MD : ID->instance_methods())
6087 methods.push_back(MD);
6089 for (const auto *PID : ID->property_impls()) {
6090 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
6091 ObjCPropertyDecl *PD = PID->getPropertyDecl();
6093 if (auto MD = PD->getGetterMethodDecl())
6094 if (GetMethodDefinition(MD))
6095 methods.push_back(MD);
6096 if (auto MD = PD->getSetterMethodDecl())
6097 if (GetMethodDefinition(MD))
6098 methods.push_back(MD);
6103 values.add(emitMethodList(ID->getObjCRuntimeNameAsString(),
6104 (flags & NonFragileABI_Class_Meta)
6105 ? MethodListType::ClassMethods
6106 : MethodListType::InstanceMethods,
6109 const ObjCInterfaceDecl *OID = ID->getClassInterface();
6110 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");
6111 values.add(EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_"
6112 + OID->getObjCRuntimeNameAsString(),
6113 OID->all_referenced_protocol_begin(),
6114 OID->all_referenced_protocol_end()));
6116 if (flags & NonFragileABI_Class_Meta) {
6117 values.addNullPointer(ObjCTypes.IvarListnfABIPtrTy);
6118 values.add(GetIvarLayoutName(nullptr, ObjCTypes));
6119 values.add(EmitPropertyList(
6120 "\01l_OBJC_$_CLASS_PROP_LIST_" + ID->getObjCRuntimeNameAsString(),
6121 ID, ID->getClassInterface(), ObjCTypes, true));
6123 values.add(EmitIvarList(ID));
6124 values.add(BuildWeakIvarLayout(ID, beginInstance, endInstance, hasMRCWeak));
6125 values.add(EmitPropertyList(
6126 "\01l_OBJC_$_PROP_LIST_" + ID->getObjCRuntimeNameAsString(),
6127 ID, ID->getClassInterface(), ObjCTypes, false));
6130 llvm::SmallString<64> roLabel;
6131 llvm::raw_svector_ostream(roLabel)
6132 << ((flags & NonFragileABI_Class_Meta) ? "\01l_OBJC_METACLASS_RO_$_"
6133 : "\01l_OBJC_CLASS_RO_$_")
6136 llvm::GlobalVariable *CLASS_RO_GV =
6137 values.finishAndCreateGlobal(roLabel, CGM.getPointerAlign(),
6139 llvm::GlobalValue::PrivateLinkage);
6140 if (CGM.getTriple().isOSBinFormatMachO())
6141 CLASS_RO_GV->setSection("__DATA, __objc_const");
6145 /// Build the metaclass object for a class.
6147 /// struct _class_t {
6148 /// struct _class_t *isa;
6149 /// struct _class_t * const superclass;
6152 /// struct class_ro_t *ro;
6155 llvm::GlobalVariable *
6156 CGObjCNonFragileABIMac::BuildClassObject(const ObjCInterfaceDecl *CI,
6158 llvm::Constant *IsAGV,
6159 llvm::Constant *SuperClassGV,
6160 llvm::Constant *ClassRoGV,
6161 bool HiddenVisibility) {
6162 ConstantInitBuilder builder(CGM);
6163 auto values = builder.beginStruct(ObjCTypes.ClassnfABITy);
6166 values.add(SuperClassGV);
6168 values.addNullPointer(ObjCTypes.ClassnfABIPtrTy);
6170 values.add(ObjCEmptyCacheVar);
6171 values.add(ObjCEmptyVtableVar);
6172 values.add(ClassRoGV);
6174 llvm::GlobalVariable *GV =
6175 cast<llvm::GlobalVariable>(GetClassGlobal(CI, isMetaclass, ForDefinition));
6176 values.finishAndSetAsInitializer(GV);
6178 if (CGM.getTriple().isOSBinFormatMachO())
6179 GV->setSection("__DATA, __objc_data");
6181 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABITy));
6182 if (!CGM.getTriple().isOSBinFormatCOFF())
6183 if (HiddenVisibility)
6184 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6189 CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
6190 return OD->getClassMethod(GetNullarySelector("load")) != nullptr;
6193 void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
6194 uint32_t &InstanceStart,
6195 uint32_t &InstanceSize) {
6196 const ASTRecordLayout &RL =
6197 CGM.getContext().getASTObjCImplementationLayout(OID);
6199 // InstanceSize is really instance end.
6200 InstanceSize = RL.getDataSize().getQuantity();
6202 // If there are no fields, the start is the same as the end.
6203 if (!RL.getFieldCount())
6204 InstanceStart = InstanceSize;
6206 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
6209 static llvm::GlobalValue::DLLStorageClassTypes getStorage(CodeGenModule &CGM,
6211 IdentifierInfo &II = CGM.getContext().Idents.get(Name);
6212 TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl();
6213 DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);
6215 const VarDecl *VD = nullptr;
6216 for (const auto &Result : DC->lookup(&II))
6217 if ((VD = dyn_cast<VarDecl>(Result)))
6221 return llvm::GlobalValue::DLLImportStorageClass;
6222 if (VD->hasAttr<DLLExportAttr>())
6223 return llvm::GlobalValue::DLLExportStorageClass;
6224 if (VD->hasAttr<DLLImportAttr>())
6225 return llvm::GlobalValue::DLLImportStorageClass;
6226 return llvm::GlobalValue::DefaultStorageClass;
6229 void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
6230 if (!ObjCEmptyCacheVar) {
6232 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CacheTy, false,
6233 llvm::GlobalValue::ExternalLinkage, nullptr,
6234 "_objc_empty_cache");
6235 if (CGM.getTriple().isOSBinFormatCOFF())
6236 ObjCEmptyCacheVar->setDLLStorageClass(getStorage(CGM, "_objc_empty_cache"));
6238 // Only OS X with deployment version <10.9 use the empty vtable symbol
6239 const llvm::Triple &Triple = CGM.getTarget().getTriple();
6240 if (Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 9))
6241 ObjCEmptyVtableVar =
6242 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ImpnfABITy, false,
6243 llvm::GlobalValue::ExternalLinkage, nullptr,
6244 "_objc_empty_vtable");
6246 ObjCEmptyVtableVar =
6247 llvm::ConstantPointerNull::get(ObjCTypes.ImpnfABITy->getPointerTo());
6250 // FIXME: Is this correct (that meta class size is never computed)?
6251 uint32_t InstanceStart =
6252 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy);
6253 uint32_t InstanceSize = InstanceStart;
6254 uint32_t flags = NonFragileABI_Class_Meta;
6256 llvm::Constant *SuperClassGV, *IsAGV;
6258 const auto *CI = ID->getClassInterface();
6259 assert(CI && "CGObjCNonFragileABIMac::GenerateClass - class is 0");
6261 // Build the flags for the metaclass.
6262 bool classIsHidden = (CGM.getTriple().isOSBinFormatCOFF())
6263 ? !CI->hasAttr<DLLExportAttr>()
6264 : CI->getVisibility() == HiddenVisibility;
6266 flags |= NonFragileABI_Class_Hidden;
6268 // FIXME: why is this flag set on the metaclass?
6269 // ObjC metaclasses have no fields and don't really get constructed.
6270 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
6271 flags |= NonFragileABI_Class_HasCXXStructors;
6272 if (!ID->hasNonZeroConstructors())
6273 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
6276 if (!CI->getSuperClass()) {
6278 flags |= NonFragileABI_Class_Root;
6280 SuperClassGV = GetClassGlobal(CI, /*metaclass*/ false, NotForDefinition);
6281 IsAGV = GetClassGlobal(CI, /*metaclass*/ true, NotForDefinition);
6283 // Has a root. Current class is not a root.
6284 const ObjCInterfaceDecl *Root = ID->getClassInterface();
6285 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
6288 const auto *Super = CI->getSuperClass();
6289 IsAGV = GetClassGlobal(Root, /*metaclass*/ true, NotForDefinition);
6290 SuperClassGV = GetClassGlobal(Super, /*metaclass*/ true, NotForDefinition);
6293 llvm::GlobalVariable *CLASS_RO_GV =
6294 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
6296 llvm::GlobalVariable *MetaTClass =
6297 BuildClassObject(CI, /*metaclass*/ true,
6298 IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden);
6299 if (CGM.getTriple().isOSBinFormatCOFF())
6300 if (CI->hasAttr<DLLExportAttr>())
6301 MetaTClass->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
6302 DefinedMetaClasses.push_back(MetaTClass);
6304 // Metadata for the class
6307 flags |= NonFragileABI_Class_Hidden;
6309 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
6310 flags |= NonFragileABI_Class_HasCXXStructors;
6312 // Set a flag to enable a runtime optimization when a class has
6313 // fields that require destruction but which don't require
6314 // anything except zero-initialization during construction. This
6315 // is most notably true of __strong and __weak types, but you can
6316 // also imagine there being C++ types with non-trivial default
6317 // constructors that merely set all fields to null.
6318 if (!ID->hasNonZeroConstructors())
6319 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
6322 if (hasObjCExceptionAttribute(CGM.getContext(), CI))
6323 flags |= NonFragileABI_Class_Exception;
6325 if (!CI->getSuperClass()) {
6326 flags |= NonFragileABI_Class_Root;
6327 SuperClassGV = nullptr;
6329 // Has a root. Current class is not a root.
6330 const auto *Super = CI->getSuperClass();
6331 SuperClassGV = GetClassGlobal(Super, /*metaclass*/ false, NotForDefinition);
6334 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
6336 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
6338 llvm::GlobalVariable *ClassMD =
6339 BuildClassObject(CI, /*metaclass*/ false,
6340 MetaTClass, SuperClassGV, CLASS_RO_GV, classIsHidden);
6341 if (CGM.getTriple().isOSBinFormatCOFF())
6342 if (CI->hasAttr<DLLExportAttr>())
6343 ClassMD->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
6344 DefinedClasses.push_back(ClassMD);
6345 ImplementedClasses.push_back(CI);
6347 // Determine if this class is also "non-lazy".
6348 if (ImplementationIsNonLazy(ID))
6349 DefinedNonLazyClasses.push_back(ClassMD);
6351 // Force the definition of the EHType if necessary.
6352 if (flags & NonFragileABI_Class_Exception)
6353 (void) GetInterfaceEHType(CI, ForDefinition);
6354 // Make sure method definition entries are all clear for next implementation.
6355 MethodDefinitions.clear();
6358 /// GenerateProtocolRef - This routine is called to generate code for
6359 /// a protocol reference expression; as in:
6361 /// @protocol(Proto1);
6363 /// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1
6364 /// which will hold address of the protocol meta-data.
6366 llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF,
6367 const ObjCProtocolDecl *PD) {
6369 // This routine is called for @protocol only. So, we must build definition
6370 // of protocol's meta-data (not a reference to it!)
6372 llvm::Constant *Init =
6373 llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD),
6374 ObjCTypes.getExternalProtocolPtrTy());
6376 std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_");
6377 ProtocolName += PD->getObjCRuntimeNameAsString();
6379 CharUnits Align = CGF.getPointerAlign();
6381 llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
6383 return CGF.Builder.CreateAlignedLoad(PTGV, Align);
6384 PTGV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
6385 llvm::GlobalValue::WeakAnyLinkage, Init,
6387 PTGV->setSection(GetSectionName("__objc_protorefs",
6388 "coalesced,no_dead_strip"));
6389 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6390 PTGV->setAlignment(Align.getQuantity());
6391 if (!CGM.getTriple().isOSBinFormatMachO())
6392 PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolName));
6393 CGM.addCompilerUsedGlobal(PTGV);
6394 return CGF.Builder.CreateAlignedLoad(PTGV, Align);
6397 /// GenerateCategory - Build metadata for a category implementation.
6398 /// struct _category_t {
6399 /// const char * const name;
6400 /// struct _class_t *const cls;
6401 /// const struct _method_list_t * const instance_methods;
6402 /// const struct _method_list_t * const class_methods;
6403 /// const struct _protocol_list_t * const protocols;
6404 /// const struct _prop_list_t * const properties;
6405 /// const struct _prop_list_t * const class_properties;
6406 /// const uint32_t size;
6409 void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
6410 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
6411 const char *Prefix = "\01l_OBJC_$_CATEGORY_";
6413 llvm::SmallString<64> ExtCatName(Prefix);
6414 ExtCatName += Interface->getObjCRuntimeNameAsString();
6415 ExtCatName += "_$_";
6416 ExtCatName += OCD->getNameAsString();
6418 ConstantInitBuilder builder(CGM);
6419 auto values = builder.beginStruct(ObjCTypes.CategorynfABITy);
6420 values.add(GetClassName(OCD->getIdentifier()->getName()));
6421 // meta-class entry symbol
6422 values.add(GetClassGlobal(Interface, /*metaclass*/ false, NotForDefinition));
6423 std::string listName =
6424 (Interface->getObjCRuntimeNameAsString() + "_$_" + OCD->getName()).str();
6426 SmallVector<const ObjCMethodDecl *, 16> instanceMethods;
6427 SmallVector<const ObjCMethodDecl *, 8> classMethods;
6428 for (const auto *MD : OCD->methods()) {
6429 if (MD->isInstanceMethod()) {
6430 instanceMethods.push_back(MD);
6432 classMethods.push_back(MD);
6436 values.add(emitMethodList(listName, MethodListType::CategoryInstanceMethods,
6438 values.add(emitMethodList(listName, MethodListType::CategoryClassMethods,
6441 const ObjCCategoryDecl *Category =
6442 Interface->FindCategoryDeclaration(OCD->getIdentifier());
6444 SmallString<256> ExtName;
6445 llvm::raw_svector_ostream(ExtName) << Interface->getObjCRuntimeNameAsString() << "_$_"
6447 values.add(EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_"
6448 + Interface->getObjCRuntimeNameAsString() + "_$_"
6449 + Category->getName(),
6450 Category->protocol_begin(),
6451 Category->protocol_end()));
6452 values.add(EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
6453 OCD, Category, ObjCTypes, false));
6454 values.add(EmitPropertyList("\01l_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
6455 OCD, Category, ObjCTypes, true));
6457 values.addNullPointer(ObjCTypes.ProtocolListnfABIPtrTy);
6458 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
6459 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
6462 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategorynfABITy);
6463 values.addInt(ObjCTypes.IntTy, Size);
6465 llvm::GlobalVariable *GCATV =
6466 values.finishAndCreateGlobal(ExtCatName.str(), CGM.getPointerAlign(),
6468 llvm::GlobalValue::PrivateLinkage);
6469 if (CGM.getTriple().isOSBinFormatMachO())
6470 GCATV->setSection("__DATA, __objc_const");
6471 CGM.addCompilerUsedGlobal(GCATV);
6472 DefinedCategories.push_back(GCATV);
6474 // Determine if this category is also "non-lazy".
6475 if (ImplementationIsNonLazy(OCD))
6476 DefinedNonLazyCategories.push_back(GCATV);
6477 // method definition entries must be clear for next implementation.
6478 MethodDefinitions.clear();
6481 /// emitMethodConstant - Return a struct objc_method constant. If
6482 /// forProtocol is true, the implementation will be null; otherwise,
6483 /// the method must have a definition registered with the runtime.
6485 /// struct _objc_method {
6487 /// char *method_type;
6490 void CGObjCNonFragileABIMac::emitMethodConstant(ConstantArrayBuilder &builder,
6491 const ObjCMethodDecl *MD,
6493 auto method = builder.beginStruct(ObjCTypes.MethodTy);
6494 method.addBitCast(GetMethodVarName(MD->getSelector()),
6495 ObjCTypes.SelectorPtrTy);
6496 method.add(GetMethodVarType(MD));
6499 // Protocol methods have no implementation. So, this entry is always NULL.
6500 method.addNullPointer(ObjCTypes.Int8PtrTy);
6502 llvm::Function *fn = GetMethodDefinition(MD);
6503 assert(fn && "no definition for method?");
6504 method.addBitCast(fn, ObjCTypes.Int8PtrTy);
6507 method.finishAndAddTo(builder);
6510 /// Build meta-data for method declarations.
6512 /// struct _method_list_t {
6513 /// uint32_t entsize; // sizeof(struct _objc_method)
6514 /// uint32_t method_count;
6515 /// struct _objc_method method_list[method_count];
6519 CGObjCNonFragileABIMac::emitMethodList(Twine name, MethodListType kind,
6520 ArrayRef<const ObjCMethodDecl *> methods) {
6521 // Return null for empty list.
6522 if (methods.empty())
6523 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
6528 case MethodListType::CategoryInstanceMethods:
6529 prefix = "\01l_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6530 forProtocol = false;
6532 case MethodListType::CategoryClassMethods:
6533 prefix = "\01l_OBJC_$_CATEGORY_CLASS_METHODS_";
6534 forProtocol = false;
6536 case MethodListType::InstanceMethods:
6537 prefix = "\01l_OBJC_$_INSTANCE_METHODS_";
6538 forProtocol = false;
6540 case MethodListType::ClassMethods:
6541 prefix = "\01l_OBJC_$_CLASS_METHODS_";
6542 forProtocol = false;
6545 case MethodListType::ProtocolInstanceMethods:
6546 prefix = "\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_";
6549 case MethodListType::ProtocolClassMethods:
6550 prefix = "\01l_OBJC_$_PROTOCOL_CLASS_METHODS_";
6553 case MethodListType::OptionalProtocolInstanceMethods:
6554 prefix = "\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_";
6557 case MethodListType::OptionalProtocolClassMethods:
6558 prefix = "\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_";
6563 ConstantInitBuilder builder(CGM);
6564 auto values = builder.beginStruct();
6566 // sizeof(struct _objc_method)
6567 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
6568 values.addInt(ObjCTypes.IntTy, Size);
6570 values.addInt(ObjCTypes.IntTy, methods.size());
6571 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
6572 for (auto MD : methods) {
6573 emitMethodConstant(methodArray, MD, forProtocol);
6575 methodArray.finishAndAddTo(values);
6577 auto *GV = values.finishAndCreateGlobal(prefix + name, CGM.getPointerAlign(),
6579 llvm::GlobalValue::PrivateLinkage);
6580 if (CGM.getTriple().isOSBinFormatMachO())
6581 GV->setSection("__DATA, __objc_const");
6582 CGM.addCompilerUsedGlobal(GV);
6583 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy);
6586 /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
6588 llvm::GlobalVariable *
6589 CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
6590 const ObjCIvarDecl *Ivar) {
6591 const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
6592 llvm::SmallString<64> Name("OBJC_IVAR_$_");
6593 Name += Container->getObjCRuntimeNameAsString();
6595 Name += Ivar->getName();
6596 llvm::GlobalVariable *IvarOffsetGV = CGM.getModule().getGlobalVariable(Name);
6597 if (!IvarOffsetGV) {
6599 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.IvarOffsetVarTy,
6600 false, llvm::GlobalValue::ExternalLinkage,
6601 nullptr, Name.str());
6602 if (CGM.getTriple().isOSBinFormatCOFF()) {
6603 bool IsPrivateOrPackage =
6604 Ivar->getAccessControl() == ObjCIvarDecl::Private ||
6605 Ivar->getAccessControl() == ObjCIvarDecl::Package;
6607 if (ID->hasAttr<DLLExportAttr>() && !IsPrivateOrPackage)
6608 IvarOffsetGV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
6609 else if (ID->hasAttr<DLLImportAttr>())
6610 IvarOffsetGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
6613 return IvarOffsetGV;
6617 CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
6618 const ObjCIvarDecl *Ivar,
6619 unsigned long int Offset) {
6620 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
6621 IvarOffsetGV->setInitializer(
6622 llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));
6623 IvarOffsetGV->setAlignment(
6624 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.IvarOffsetVarTy));
6626 if (!CGM.getTriple().isOSBinFormatCOFF()) {
6627 // FIXME: This matches gcc, but shouldn't the visibility be set on the use
6628 // as well (i.e., in ObjCIvarOffsetVariable).
6629 if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
6630 Ivar->getAccessControl() == ObjCIvarDecl::Package ||
6631 ID->getVisibility() == HiddenVisibility)
6632 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6634 IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
6637 if (CGM.getTriple().isOSBinFormatMachO())
6638 IvarOffsetGV->setSection("__DATA, __objc_ivar");
6639 return IvarOffsetGV;
6642 /// EmitIvarList - Emit the ivar list for the given
6643 /// implementation. The return value has type
6644 /// IvarListnfABIPtrTy.
6645 /// struct _ivar_t {
6646 /// unsigned [long] int *offset; // pointer to ivar offset location
6649 /// uint32_t alignment;
6652 /// struct _ivar_list_t {
6653 /// uint32 entsize; // sizeof(struct _ivar_t)
6655 /// struct _iver_t list[count];
6659 llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
6660 const ObjCImplementationDecl *ID) {
6662 ConstantInitBuilder builder(CGM);
6663 auto ivarList = builder.beginStruct();
6664 ivarList.addInt(ObjCTypes.IntTy,
6665 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy));
6666 auto ivarCountSlot = ivarList.addPlaceholder();
6667 auto ivars = ivarList.beginArray(ObjCTypes.IvarnfABITy);
6669 const ObjCInterfaceDecl *OID = ID->getClassInterface();
6670 assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface");
6672 // FIXME. Consolidate this with similar code in GenerateClass.
6674 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
6675 IVD; IVD = IVD->getNextIvar()) {
6676 // Ignore unnamed bit-fields.
6677 if (!IVD->getDeclName())
6680 auto ivar = ivars.beginStruct(ObjCTypes.IvarnfABITy);
6681 ivar.add(EmitIvarOffsetVar(ID->getClassInterface(), IVD,
6682 ComputeIvarBaseOffset(CGM, ID, IVD)));
6683 ivar.add(GetMethodVarName(IVD->getIdentifier()));
6684 ivar.add(GetMethodVarType(IVD));
6685 llvm::Type *FieldTy =
6686 CGM.getTypes().ConvertTypeForMem(IVD->getType());
6687 unsigned Size = CGM.getDataLayout().getTypeAllocSize(FieldTy);
6688 unsigned Align = CGM.getContext().getPreferredTypeAlign(
6689 IVD->getType().getTypePtr()) >> 3;
6690 Align = llvm::Log2_32(Align);
6691 ivar.addInt(ObjCTypes.IntTy, Align);
6692 // NOTE. Size of a bitfield does not match gcc's, because of the
6693 // way bitfields are treated special in each. But I am told that
6694 // 'size' for bitfield ivars is ignored by the runtime so it does
6695 // not matter. If it matters, there is enough info to get the
6697 ivar.addInt(ObjCTypes.IntTy, Size);
6698 ivar.finishAndAddTo(ivars);
6700 // Return null for empty list.
6701 if (ivars.empty()) {
6704 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
6707 auto ivarCount = ivars.size();
6708 ivars.finishAndAddTo(ivarList);
6709 ivarList.fillPlaceholderWithInt(ivarCountSlot, ObjCTypes.IntTy, ivarCount);
6711 const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_";
6712 llvm::GlobalVariable *GV =
6713 ivarList.finishAndCreateGlobal(Prefix + OID->getObjCRuntimeNameAsString(),
6714 CGM.getPointerAlign(), /*constant*/ false,
6715 llvm::GlobalValue::PrivateLinkage);
6716 if (CGM.getTriple().isOSBinFormatMachO())
6717 GV->setSection("__DATA, __objc_const");
6718 CGM.addCompilerUsedGlobal(GV);
6719 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
6722 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
6723 const ObjCProtocolDecl *PD) {
6724 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
6727 // We use the initializer as a marker of whether this is a forward
6728 // reference or not. At module finalization we add the empty
6729 // contents for protocols which were referenced but never defined.
6730 llvm::SmallString<64> Protocol;
6731 llvm::raw_svector_ostream(Protocol) << "\01l_OBJC_PROTOCOL_$_"
6732 << PD->getObjCRuntimeNameAsString();
6734 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
6735 false, llvm::GlobalValue::ExternalLinkage,
6737 if (!CGM.getTriple().isOSBinFormatMachO())
6738 Entry->setComdat(CGM.getModule().getOrInsertComdat(Protocol));
6744 /// GetOrEmitProtocol - Generate the protocol meta-data:
6746 /// struct _protocol_t {
6748 /// const char * const protocol_name;
6749 /// const struct _protocol_list_t * protocol_list; // super protocols
6750 /// const struct method_list_t * const instance_methods;
6751 /// const struct method_list_t * const class_methods;
6752 /// const struct method_list_t *optionalInstanceMethods;
6753 /// const struct method_list_t *optionalClassMethods;
6754 /// const struct _prop_list_t * properties;
6755 /// const uint32_t size; // sizeof(struct _protocol_t)
6756 /// const uint32_t flags; // = 0
6757 /// const char ** extendedMethodTypes;
6758 /// const char *demangledName;
6759 /// const struct _prop_list_t * class_properties;
6764 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
6765 const ObjCProtocolDecl *PD) {
6766 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
6768 // Early exit if a defining object has already been generated.
6769 if (Entry && Entry->hasInitializer())
6772 // Use the protocol definition, if there is one.
6773 if (const ObjCProtocolDecl *Def = PD->getDefinition())
6776 auto methodLists = ProtocolMethodLists::get(PD);
6778 ConstantInitBuilder builder(CGM);
6779 auto values = builder.beginStruct(ObjCTypes.ProtocolnfABITy);
6782 values.addNullPointer(ObjCTypes.ObjectPtrTy);
6783 values.add(GetClassName(PD->getObjCRuntimeNameAsString()));
6784 values.add(EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_"
6785 + PD->getObjCRuntimeNameAsString(),
6786 PD->protocol_begin(),
6787 PD->protocol_end()));
6788 values.add(methodLists.emitMethodList(this, PD,
6789 ProtocolMethodLists::RequiredInstanceMethods));
6790 values.add(methodLists.emitMethodList(this, PD,
6791 ProtocolMethodLists::RequiredClassMethods));
6792 values.add(methodLists.emitMethodList(this, PD,
6793 ProtocolMethodLists::OptionalInstanceMethods));
6794 values.add(methodLists.emitMethodList(this, PD,
6795 ProtocolMethodLists::OptionalClassMethods));
6796 values.add(EmitPropertyList(
6797 "\01l_OBJC_$_PROP_LIST_" + PD->getObjCRuntimeNameAsString(),
6798 nullptr, PD, ObjCTypes, false));
6800 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
6801 values.addInt(ObjCTypes.IntTy, Size);
6802 values.addInt(ObjCTypes.IntTy, 0);
6803 values.add(EmitProtocolMethodTypes("\01l_OBJC_$_PROTOCOL_METHOD_TYPES_"
6804 + PD->getObjCRuntimeNameAsString(),
6805 methodLists.emitExtendedTypesArray(this),
6808 // const char *demangledName;
6809 values.addNullPointer(ObjCTypes.Int8PtrTy);
6811 values.add(EmitPropertyList(
6812 "\01l_OBJC_$_CLASS_PROP_LIST_" + PD->getObjCRuntimeNameAsString(),
6813 nullptr, PD, ObjCTypes, true));
6816 // Already created, fix the linkage and update the initializer.
6817 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
6818 values.finishAndSetAsInitializer(Entry);
6820 llvm::SmallString<64> symbolName;
6821 llvm::raw_svector_ostream(symbolName)
6822 << "\01l_OBJC_PROTOCOL_$_" << PD->getObjCRuntimeNameAsString();
6824 Entry = values.finishAndCreateGlobal(symbolName, CGM.getPointerAlign(),
6826 llvm::GlobalValue::WeakAnyLinkage);
6827 if (!CGM.getTriple().isOSBinFormatMachO())
6828 Entry->setComdat(CGM.getModule().getOrInsertComdat(symbolName));
6830 Protocols[PD->getIdentifier()] = Entry;
6832 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
6833 CGM.addCompilerUsedGlobal(Entry);
6835 // Use this protocol meta-data to build protocol list table in section
6836 // __DATA, __objc_protolist
6837 llvm::SmallString<64> ProtocolRef;
6838 llvm::raw_svector_ostream(ProtocolRef) << "\01l_OBJC_LABEL_PROTOCOL_$_"
6839 << PD->getObjCRuntimeNameAsString();
6841 llvm::GlobalVariable *PTGV =
6842 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy,
6843 false, llvm::GlobalValue::WeakAnyLinkage, Entry,
6845 if (!CGM.getTriple().isOSBinFormatMachO())
6846 PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolRef));
6848 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
6849 PTGV->setSection(GetSectionName("__objc_protolist",
6850 "coalesced,no_dead_strip"));
6851 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6852 CGM.addCompilerUsedGlobal(PTGV);
6856 /// EmitProtocolList - Generate protocol list meta-data:
6858 /// struct _protocol_list_t {
6859 /// long protocol_count; // Note, this is 32/64 bit
6860 /// struct _protocol_t[protocol_count];
6865 CGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
6866 ObjCProtocolDecl::protocol_iterator begin,
6867 ObjCProtocolDecl::protocol_iterator end) {
6868 SmallVector<llvm::Constant *, 16> ProtocolRefs;
6870 // Just return null for empty protocol lists
6872 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
6874 // FIXME: We shouldn't need to do this lookup here, should we?
6875 SmallString<256> TmpName;
6876 Name.toVector(TmpName);
6877 llvm::GlobalVariable *GV =
6878 CGM.getModule().getGlobalVariable(TmpName.str(), true);
6880 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
6882 ConstantInitBuilder builder(CGM);
6883 auto values = builder.beginStruct();
6884 auto countSlot = values.addPlaceholder();
6886 // A null-terminated array of protocols.
6887 auto array = values.beginArray(ObjCTypes.ProtocolnfABIPtrTy);
6888 for (; begin != end; ++begin)
6889 array.add(GetProtocolRef(*begin)); // Implemented???
6890 auto count = array.size();
6891 array.addNullPointer(ObjCTypes.ProtocolnfABIPtrTy);
6893 array.finishAndAddTo(values);
6894 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
6896 GV = values.finishAndCreateGlobal(Name, CGM.getPointerAlign(),
6898 llvm::GlobalValue::PrivateLinkage);
6899 if (CGM.getTriple().isOSBinFormatMachO())
6900 GV->setSection("__DATA, __objc_const");
6901 CGM.addCompilerUsedGlobal(GV);
6902 return llvm::ConstantExpr::getBitCast(GV,
6903 ObjCTypes.ProtocolListnfABIPtrTy);
6906 /// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference.
6907 /// This code gen. amounts to generating code for:
6909 /// (type *)((char *)base + _OBJC_IVAR_$_.ivar;
6912 LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
6913 CodeGen::CodeGenFunction &CGF,
6915 llvm::Value *BaseValue,
6916 const ObjCIvarDecl *Ivar,
6917 unsigned CVRQualifiers) {
6918 ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCObjectType>()->getInterface();
6919 llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
6920 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
6924 llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(
6925 CodeGen::CodeGenFunction &CGF,
6926 const ObjCInterfaceDecl *Interface,
6927 const ObjCIvarDecl *Ivar) {
6928 llvm::Value *IvarOffsetValue = ObjCIvarOffsetVariable(Interface, Ivar);
6929 IvarOffsetValue = CGF.Builder.CreateAlignedLoad(IvarOffsetValue,
6930 CGF.getSizeAlign(), "ivar");
6931 if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
6932 cast<llvm::LoadInst>(IvarOffsetValue)
6933 ->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
6934 llvm::MDNode::get(VMContext, None));
6936 // This could be 32bit int or 64bit integer depending on the architecture.
6937 // Cast it to 64bit integer value, if it is a 32bit integer ivar offset value
6938 // as this is what caller always expectes.
6939 if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
6940 IvarOffsetValue = CGF.Builder.CreateIntCast(
6941 IvarOffsetValue, ObjCTypes.LongTy, true, "ivar.conv");
6942 return IvarOffsetValue;
6945 static void appendSelectorForMessageRefTable(std::string &buffer,
6946 Selector selector) {
6947 if (selector.isUnarySelector()) {
6948 buffer += selector.getNameForSlot(0);
6952 for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) {
6953 buffer += selector.getNameForSlot(i);
6958 /// Emit a "vtable" message send. We emit a weak hidden-visibility
6959 /// struct, initially containing the selector pointer and a pointer to
6960 /// a "fixup" variant of the appropriate objc_msgSend. To call, we
6961 /// load and call the function pointer, passing the address of the
6962 /// struct as the second parameter. The runtime determines whether
6963 /// the selector is currently emitted using vtable dispatch; if so, it
6964 /// substitutes a stub function which simply tail-calls through the
6965 /// appropriate vtable slot, and if not, it substitues a stub function
6966 /// which tail-calls objc_msgSend. Both stubs adjust the selector
6967 /// argument to correctly point to the selector.
6969 CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF,
6970 ReturnValueSlot returnSlot,
6971 QualType resultType,
6976 const CallArgList &formalArgs,
6977 const ObjCMethodDecl *method) {
6978 // Compute the actual arguments.
6981 // First argument: the receiver / super-call structure.
6983 arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy);
6984 args.add(RValue::get(arg0), arg0Type);
6986 // Second argument: a pointer to the message ref structure. Leave
6987 // the actual argument value blank for now.
6988 args.add(RValue::get(nullptr), ObjCTypes.MessageRefCPtrTy);
6990 args.insert(args.end(), formalArgs.begin(), formalArgs.end());
6992 MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
6994 NullReturnState nullReturn;
6996 // Find the function to call and the mangled name for the message
6997 // ref structure. Using a different mangled name wouldn't actually
6998 // be a problem; it would just be a waste.
7000 // The runtime currently never uses vtable dispatch for anything
7001 // except normal, non-super message-sends.
7002 // FIXME: don't use this for that.
7003 llvm::Constant *fn = nullptr;
7004 std::string messageRefName("\01l_");
7005 if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
7007 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
7008 messageRefName += "objc_msgSendSuper2_stret_fixup";
7010 nullReturn.init(CGF, arg0);
7011 fn = ObjCTypes.getMessageSendStretFixupFn();
7012 messageRefName += "objc_msgSend_stret_fixup";
7014 } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) {
7015 fn = ObjCTypes.getMessageSendFpretFixupFn();
7016 messageRefName += "objc_msgSend_fpret_fixup";
7019 fn = ObjCTypes.getMessageSendSuper2FixupFn();
7020 messageRefName += "objc_msgSendSuper2_fixup";
7022 fn = ObjCTypes.getMessageSendFixupFn();
7023 messageRefName += "objc_msgSend_fixup";
7026 assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend");
7027 messageRefName += '_';
7029 // Append the selector name, except use underscores anywhere we
7030 // would have used colons.
7031 appendSelectorForMessageRefTable(messageRefName, selector);
7033 llvm::GlobalVariable *messageRef
7034 = CGM.getModule().getGlobalVariable(messageRefName);
7036 // Build the message ref structure.
7037 ConstantInitBuilder builder(CGM);
7038 auto values = builder.beginStruct();
7040 values.add(GetMethodVarName(selector));
7041 messageRef = values.finishAndCreateGlobal(messageRefName,
7042 CharUnits::fromQuantity(16),
7044 llvm::GlobalValue::WeakAnyLinkage);
7045 messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
7046 messageRef->setSection(GetSectionName("__objc_msgrefs", "coalesced"));
7049 bool requiresnullCheck = false;
7050 if (CGM.getLangOpts().ObjCAutoRefCount && method)
7051 for (const auto *ParamDecl : method->parameters()) {
7052 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
7053 if (!nullReturn.NullBB)
7054 nullReturn.init(CGF, arg0);
7055 requiresnullCheck = true;
7061 Address(CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy),
7062 CGF.getPointerAlign());
7064 // Update the message ref argument.
7065 args[1].RV = RValue::get(mref.getPointer());
7067 // Load the function to call from the message ref table.
7068 Address calleeAddr =
7069 CGF.Builder.CreateStructGEP(mref, 0, CharUnits::Zero());
7070 llvm::Value *calleePtr = CGF.Builder.CreateLoad(calleeAddr, "msgSend_fn");
7072 calleePtr = CGF.Builder.CreateBitCast(calleePtr, MSI.MessengerType);
7073 CGCallee callee(CGCalleeInfo(), calleePtr);
7075 RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args);
7076 return nullReturn.complete(CGF, result, resultType, formalArgs,
7077 requiresnullCheck ? method : nullptr);
7080 /// Generate code for a message send expression in the nonfragile abi.
7082 CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
7083 ReturnValueSlot Return,
7084 QualType ResultType,
7086 llvm::Value *Receiver,
7087 const CallArgList &CallArgs,
7088 const ObjCInterfaceDecl *Class,
7089 const ObjCMethodDecl *Method) {
7090 return isVTableDispatchedSelector(Sel)
7091 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
7092 Receiver, CGF.getContext().getObjCIdType(),
7093 false, CallArgs, Method)
7094 : EmitMessageSend(CGF, Return, ResultType,
7095 EmitSelector(CGF, Sel),
7096 Receiver, CGF.getContext().getObjCIdType(),
7097 false, CallArgs, Method, Class, ObjCTypes);
7101 CGObjCNonFragileABIMac::GetClassGlobal(const ObjCInterfaceDecl *ID,
7103 ForDefinition_t isForDefinition) {
7105 (metaclass ? getMetaclassSymbolPrefix() : getClassSymbolPrefix());
7106 return GetClassGlobal((prefix + ID->getObjCRuntimeNameAsString()).str(),
7108 ID->isWeakImported(),
7110 && CGM.getTriple().isOSBinFormatCOFF()
7111 && ID->hasAttr<DLLImportAttr>());
7115 CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name,
7116 ForDefinition_t IsForDefinition,
7117 bool Weak, bool DLLImport) {
7118 llvm::GlobalValue::LinkageTypes L =
7119 Weak ? llvm::GlobalValue::ExternalWeakLinkage
7120 : llvm::GlobalValue::ExternalLinkage;
7124 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
7126 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABITy,
7127 false, L, nullptr, Name);
7130 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
7133 assert(GV->getLinkage() == L);
7138 CGObjCNonFragileABIMac::EmitClassRefFromId(CodeGenFunction &CGF,
7140 const ObjCInterfaceDecl *ID) {
7141 CharUnits Align = CGF.getPointerAlign();
7142 llvm::GlobalVariable *&Entry = ClassReferences[II];
7145 llvm::Constant *ClassGV;
7147 ClassGV = GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);
7149 ClassGV = GetClassGlobal((getClassSymbolPrefix() + II->getName()).str(),
7153 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
7154 false, llvm::GlobalValue::PrivateLinkage,
7155 ClassGV, "OBJC_CLASSLIST_REFERENCES_$_");
7156 Entry->setAlignment(Align.getQuantity());
7157 Entry->setSection(GetSectionName("__objc_classrefs",
7158 "regular,no_dead_strip"));
7159 CGM.addCompilerUsedGlobal(Entry);
7161 return CGF.Builder.CreateAlignedLoad(Entry, Align);
7164 llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF,
7165 const ObjCInterfaceDecl *ID) {
7166 // If the class has the objc_runtime_visible attribute, we need to
7167 // use the Objective-C runtime to get the class.
7168 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
7169 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
7171 return EmitClassRefFromId(CGF, ID->getIdentifier(), ID);
7174 llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
7175 CodeGenFunction &CGF) {
7176 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
7177 return EmitClassRefFromId(CGF, II, nullptr);
7181 CGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF,
7182 const ObjCInterfaceDecl *ID) {
7183 CharUnits Align = CGF.getPointerAlign();
7184 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
7187 auto ClassGV = GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);
7188 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
7189 false, llvm::GlobalValue::PrivateLinkage,
7190 ClassGV, "OBJC_CLASSLIST_SUP_REFS_$_");
7191 Entry->setAlignment(Align.getQuantity());
7192 Entry->setSection(GetSectionName("__objc_superrefs",
7193 "regular,no_dead_strip"));
7194 CGM.addCompilerUsedGlobal(Entry);
7196 return CGF.Builder.CreateAlignedLoad(Entry, Align);
7199 /// EmitMetaClassRef - Return a Value * of the address of _class_t
7202 llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CodeGenFunction &CGF,
7203 const ObjCInterfaceDecl *ID,
7205 CharUnits Align = CGF.getPointerAlign();
7206 llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];
7208 auto MetaClassGV = GetClassGlobal(ID, /*metaclass*/ true, NotForDefinition);
7210 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
7211 false, llvm::GlobalValue::PrivateLinkage,
7212 MetaClassGV, "OBJC_CLASSLIST_SUP_REFS_$_");
7213 Entry->setAlignment(Align.getQuantity());
7215 Entry->setSection(GetSectionName("__objc_superrefs",
7216 "regular,no_dead_strip"));
7217 CGM.addCompilerUsedGlobal(Entry);
7220 return CGF.Builder.CreateAlignedLoad(Entry, Align);
7223 /// GetClass - Return a reference to the class for the given interface
7225 llvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,
7226 const ObjCInterfaceDecl *ID) {
7227 if (ID->isWeakImported()) {
7228 auto ClassGV = GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);
7230 assert(!isa<llvm::GlobalVariable>(ClassGV) ||
7231 cast<llvm::GlobalVariable>(ClassGV)->hasExternalWeakLinkage());
7234 return EmitClassRef(CGF, ID);
7237 /// Generates a message send where the super is the receiver. This is
7238 /// a message send to self with special delivery semantics indicating
7239 /// which class's method should be called.
7241 CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
7242 ReturnValueSlot Return,
7243 QualType ResultType,
7245 const ObjCInterfaceDecl *Class,
7246 bool isCategoryImpl,
7247 llvm::Value *Receiver,
7248 bool IsClassMessage,
7249 const CodeGen::CallArgList &CallArgs,
7250 const ObjCMethodDecl *Method) {
7252 // Create and init a super structure; this is a (receiver, class)
7253 // pair we will pass to objc_msgSendSuper.
7255 CGF.CreateTempAlloca(ObjCTypes.SuperTy, CGF.getPointerAlign(),
7258 llvm::Value *ReceiverAsObject =
7259 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
7260 CGF.Builder.CreateStore(
7262 CGF.Builder.CreateStructGEP(ObjCSuper, 0, CharUnits::Zero()));
7264 // If this is a class message the metaclass is passed as the target.
7265 llvm::Value *Target;
7267 Target = EmitMetaClassRef(CGF, Class, Class->isWeakImported());
7269 Target = EmitSuperClassRef(CGF, Class);
7271 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
7273 llvm::Type *ClassTy =
7274 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
7275 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
7276 CGF.Builder.CreateStore(
7277 Target, CGF.Builder.CreateStructGEP(ObjCSuper, 1, CGF.getPointerSize()));
7279 return (isVTableDispatchedSelector(Sel))
7280 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
7281 ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy,
7282 true, CallArgs, Method)
7283 : EmitMessageSend(CGF, Return, ResultType,
7284 EmitSelector(CGF, Sel),
7285 ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy,
7286 true, CallArgs, Method, Class, ObjCTypes);
7289 llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF,
7291 Address Addr = EmitSelectorAddr(CGF, Sel);
7293 llvm::LoadInst* LI = CGF.Builder.CreateLoad(Addr);
7294 LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
7295 llvm::MDNode::get(VMContext, None));
7299 Address CGObjCNonFragileABIMac::EmitSelectorAddr(CodeGenFunction &CGF,
7301 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
7303 CharUnits Align = CGF.getPointerAlign();
7305 llvm::Constant *Casted =
7306 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
7307 ObjCTypes.SelectorPtrTy);
7308 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.SelectorPtrTy,
7309 false, llvm::GlobalValue::PrivateLinkage,
7310 Casted, "OBJC_SELECTOR_REFERENCES_");
7311 Entry->setExternallyInitialized(true);
7312 Entry->setSection(GetSectionName("__objc_selrefs",
7313 "literal_pointers,no_dead_strip"));
7314 Entry->setAlignment(Align.getQuantity());
7315 CGM.addCompilerUsedGlobal(Entry);
7318 return Address(Entry, Align);
7321 /// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
7322 /// objc_assign_ivar (id src, id *dst, ptrdiff_t)
7324 void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
7327 llvm::Value *ivarOffset) {
7328 llvm::Type * SrcTy = src->getType();
7329 if (!isa<llvm::PointerType>(SrcTy)) {
7330 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7331 assert(Size <= 8 && "does not support size > 8");
7332 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7333 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7334 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7336 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7337 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
7338 llvm::Value *args[] = { src, dst.getPointer(), ivarOffset };
7339 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
7342 /// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
7343 /// objc_assign_strongCast (id src, id *dst)
7345 void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
7346 CodeGen::CodeGenFunction &CGF,
7347 llvm::Value *src, Address dst) {
7348 llvm::Type * SrcTy = src->getType();
7349 if (!isa<llvm::PointerType>(SrcTy)) {
7350 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7351 assert(Size <= 8 && "does not support size > 8");
7352 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7353 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7354 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7356 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7357 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
7358 llvm::Value *args[] = { src, dst.getPointer() };
7359 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
7360 args, "weakassign");
7363 void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
7364 CodeGen::CodeGenFunction &CGF,
7367 llvm::Value *Size) {
7368 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
7369 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
7370 llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), Size };
7371 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
7374 /// EmitObjCWeakRead - Code gen for loading value of a __weak
7375 /// object: objc_read_weak (id *src)
7377 llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
7378 CodeGen::CodeGenFunction &CGF,
7379 Address AddrWeakObj) {
7380 llvm::Type *DestTy = AddrWeakObj.getElementType();
7381 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
7382 llvm::Value *read_weak =
7383 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
7384 AddrWeakObj.getPointer(), "weakread");
7385 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
7389 /// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
7390 /// objc_assign_weak (id src, id *dst)
7392 void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
7393 llvm::Value *src, Address dst) {
7394 llvm::Type * SrcTy = src->getType();
7395 if (!isa<llvm::PointerType>(SrcTy)) {
7396 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7397 assert(Size <= 8 && "does not support size > 8");
7398 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7399 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7400 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7402 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7403 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
7404 llvm::Value *args[] = { src, dst.getPointer() };
7405 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
7406 args, "weakassign");
7409 /// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
7410 /// objc_assign_global (id src, id *dst)
7412 void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
7413 llvm::Value *src, Address dst,
7415 llvm::Type * SrcTy = src->getType();
7416 if (!isa<llvm::PointerType>(SrcTy)) {
7417 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7418 assert(Size <= 8 && "does not support size > 8");
7419 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7420 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7421 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7423 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7424 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
7425 llvm::Value *args[] = { src, dst.getPointer() };
7427 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
7428 args, "globalassign");
7430 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
7431 args, "threadlocalassign");
7435 CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
7436 const ObjCAtSynchronizedStmt &S) {
7437 EmitAtSynchronizedStmt(CGF, S,
7438 cast<llvm::Function>(ObjCTypes.getSyncEnterFn()),
7439 cast<llvm::Function>(ObjCTypes.getSyncExitFn()));
7443 CGObjCNonFragileABIMac::GetEHType(QualType T) {
7444 // There's a particular fixed type info for 'id'.
7445 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) {
7446 auto *IDEHType = CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id");
7449 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
7450 llvm::GlobalValue::ExternalLinkage, nullptr,
7452 if (CGM.getTriple().isOSBinFormatCOFF())
7453 IDEHType->setDLLStorageClass(getStorage(CGM, "OBJC_EHTYPE_id"));
7458 // All other types should be Objective-C interface pointer types.
7459 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
7460 assert(PT && "Invalid @catch type.");
7462 const ObjCInterfaceType *IT = PT->getInterfaceType();
7463 assert(IT && "Invalid @catch type.");
7465 return GetInterfaceEHType(IT->getDecl(), NotForDefinition);
7468 void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
7469 const ObjCAtTryStmt &S) {
7470 EmitTryCatchStmt(CGF, S,
7471 cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()),
7472 cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()),
7473 cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn()));
7476 /// EmitThrowStmt - Generate code for a throw statement.
7477 void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
7478 const ObjCAtThrowStmt &S,
7479 bool ClearInsertionPoint) {
7480 if (const Expr *ThrowExpr = S.getThrowExpr()) {
7481 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
7482 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
7483 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception)
7484 .setDoesNotReturn();
7486 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn())
7487 .setDoesNotReturn();
7490 CGF.Builder.CreateUnreachable();
7491 if (ClearInsertionPoint)
7492 CGF.Builder.ClearInsertionPoint();
7496 CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
7497 ForDefinition_t IsForDefinition) {
7498 llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
7499 StringRef ClassName = ID->getObjCRuntimeNameAsString();
7501 // If we don't need a definition, return the entry if found or check
7502 // if we use an external reference.
7503 if (!IsForDefinition) {
7507 // If this type (or a super class) has the __objc_exception__
7508 // attribute, emit an external reference.
7509 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) {
7510 std::string EHTypeName = ("OBJC_EHTYPE_$_" + ClassName).str();
7511 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy,
7512 false, llvm::GlobalValue::ExternalLinkage,
7513 nullptr, EHTypeName);
7514 if (CGM.getTriple().isOSBinFormatCOFF()) {
7515 if (ID->hasAttr<DLLExportAttr>())
7516 Entry->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
7517 else if (ID->hasAttr<DLLImportAttr>())
7518 Entry->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
7524 // Otherwise we need to either make a new entry or fill in the initializer.
7525 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition");
7527 std::string VTableName = "objc_ehtype_vtable";
7528 auto *VTableGV = CGM.getModule().getGlobalVariable(VTableName);
7531 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy, false,
7532 llvm::GlobalValue::ExternalLinkage, nullptr,
7534 if (CGM.getTriple().isOSBinFormatCOFF())
7535 VTableGV->setDLLStorageClass(getStorage(CGM, VTableName));
7538 llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2);
7539 ConstantInitBuilder builder(CGM);
7540 auto values = builder.beginStruct(ObjCTypes.EHTypeTy);
7541 values.add(llvm::ConstantExpr::getGetElementPtr(VTableGV->getValueType(),
7542 VTableGV, VTableIdx));
7543 values.add(GetClassName(ClassName));
7544 values.add(GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition));
7546 llvm::GlobalValue::LinkageTypes L = IsForDefinition
7547 ? llvm::GlobalValue::ExternalLinkage
7548 : llvm::GlobalValue::WeakAnyLinkage;
7550 values.finishAndSetAsInitializer(Entry);
7551 Entry->setAlignment(CGM.getPointerAlign().getQuantity());
7553 Entry = values.finishAndCreateGlobal("OBJC_EHTYPE_$_" + ClassName,
7554 CGM.getPointerAlign(),
7557 if (CGM.getTriple().isOSBinFormatCOFF())
7558 if (hasObjCExceptionAttribute(CGM.getContext(), ID))
7559 if (ID->hasAttr<DLLExportAttr>())
7560 Entry->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
7562 assert(Entry->getLinkage() == L);
7564 if (!CGM.getTriple().isOSBinFormatCOFF())
7565 if (ID->getVisibility() == HiddenVisibility)
7566 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
7568 if (IsForDefinition)
7569 if (CGM.getTriple().isOSBinFormatMachO())
7570 Entry->setSection("__DATA,__objc_const");
7577 CodeGen::CGObjCRuntime *
7578 CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
7579 switch (CGM.getLangOpts().ObjCRuntime.getKind()) {
7580 case ObjCRuntime::FragileMacOSX:
7581 return new CGObjCMac(CGM);
7583 case ObjCRuntime::MacOSX:
7584 case ObjCRuntime::iOS:
7585 case ObjCRuntime::WatchOS:
7586 return new CGObjCNonFragileABIMac(CGM);
7588 case ObjCRuntime::GNUstep:
7589 case ObjCRuntime::GCC:
7590 case ObjCRuntime::ObjFW:
7591 llvm_unreachable("these runtimes are not Mac runtimes");
7593 llvm_unreachable("bad runtime");