1 //===------- CGObjCMac.cpp - Interface to Apple Objective-C Runtime -------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This provides Objective-C code generation targeting the Apple runtime.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "CGObjCRuntime.h"
15 #include "CGBlocks.h"
16 #include "CGCleanup.h"
17 #include "CGRecordLayout.h"
18 #include "CodeGenFunction.h"
19 #include "CodeGenModule.h"
20 #include "clang/AST/ASTContext.h"
21 #include "clang/AST/Decl.h"
22 #include "clang/AST/DeclObjC.h"
23 #include "clang/AST/RecordLayout.h"
24 #include "clang/AST/StmtObjC.h"
25 #include "clang/Basic/LangOptions.h"
26 #include "clang/CodeGen/CGFunctionInfo.h"
27 #include "clang/Frontend/CodeGenOptions.h"
28 #include "llvm/ADT/DenseSet.h"
29 #include "llvm/ADT/SetVector.h"
30 #include "llvm/ADT/SmallPtrSet.h"
31 #include "llvm/ADT/SmallString.h"
32 #include "llvm/IR/CallSite.h"
33 #include "llvm/IR/DataLayout.h"
34 #include "llvm/IR/InlineAsm.h"
35 #include "llvm/IR/IntrinsicInst.h"
36 #include "llvm/IR/LLVMContext.h"
37 #include "llvm/IR/Module.h"
38 #include "llvm/Support/raw_ostream.h"
39 #include <cstdio>
40
41 using namespace clang;
42 using namespace CodeGen;
43
44 namespace {
45
46 // FIXME: We should find a nicer way to make the labels for metadata, string
47 // concatenation is lame.
48
49 class ObjCCommonTypesHelper {
50 protected:
51 llvm::LLVMContext &VMContext;
52
53 private:
54 // The types of these functions don't really matter because we
55 // should always bitcast before calling them.
56
57 /// id objc_msgSend (id, SEL, ...)
58 ///
59 /// The default messenger, used for sends whose ABI is unchanged from
60 /// the all-integer/pointer case.
getMessageSendFn() const61 llvm::Constant *getMessageSendFn() const {
62 // Add the non-lazy-bind attribute, since objc_msgSend is likely to
63 // be called a lot.
64 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
65 return
66 CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
67 params, true),
68 "objc_msgSend",
69 llvm::AttributeSet::get(CGM.getLLVMContext(),
70 llvm::AttributeSet::FunctionIndex,
71 llvm::Attribute::NonLazyBind));
72 }
73
74 /// void objc_msgSend_stret (id, SEL, ...)
75 ///
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.
getMessageSendStretFn() const79 llvm::Constant *getMessageSendStretFn() const {
80 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
81 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,
82 params, true),
83 "objc_msgSend_stret");
84
85 }
86
87 /// [double | long double] objc_msgSend_fpret(id self, SEL op, ...)
88 ///
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.
getMessageSendFpretFn() const92 llvm::Constant *getMessageSendFpretFn() const {
93 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
94 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.DoubleTy,
95 params, true),
96 "objc_msgSend_fpret");
97
98 }
99
100 /// _Complex long double objc_msgSend_fp2ret(id self, SEL op, ...)
101 ///
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.
getMessageSendFp2retFn() const105 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, nullptr);
110
111 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(resultType,
112 params, true),
113 "objc_msgSend_fp2ret");
114 }
115
116 /// id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
117 ///
118 /// The messenger used for super calls, which have different dispatch
119 /// semantics. The class passed is the superclass of the current
120 /// class.
getMessageSendSuperFn() const121 llvm::Constant *getMessageSendSuperFn() const {
122 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
123 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
124 params, true),
125 "objc_msgSendSuper");
126 }
127
128 /// id objc_msgSendSuper2(struct objc_super *super, SEL op, ...)
129 ///
130 /// A slightly different messenger used for super calls. The class
131 /// passed is the current class.
getMessageSendSuperFn2() const132 llvm::Constant *getMessageSendSuperFn2() const {
133 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
134 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
135 params, true),
136 "objc_msgSendSuper2");
137 }
138
139 /// void objc_msgSendSuper_stret(void *stretAddr, struct objc_super *super,
140 /// SEL op, ...)
141 ///
142 /// The messenger used for super calls which return an aggregate indirectly.
getMessageSendSuperStretFn() const143 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");
148 }
149
150 /// void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super,
151 /// SEL op, ...)
152 ///
153 /// objc_msgSendSuper_stret with the super2 semantics.
getMessageSendSuperStretFn2() const154 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");
159 }
160
getMessageSendSuperFpretFn() const161 llvm::Constant *getMessageSendSuperFpretFn() const {
162 // There is no objc_msgSendSuper_fpret? How can that work?
163 return getMessageSendSuperFn();
164 }
165
getMessageSendSuperFpretFn2() const166 llvm::Constant *getMessageSendSuperFpretFn2() const {
167 // There is no objc_msgSendSuper_fpret? How can that work?
168 return getMessageSendSuperFn2();
169 }
170
171 protected:
172 CodeGen::CodeGenModule &CGM;
173
174 public:
175 llvm::Type *ShortTy, *IntTy, *LongTy, *LongLongTy;
176 llvm::Type *Int8PtrTy, *Int8PtrPtrTy;
177 llvm::Type *IvarOffsetVarTy;
178
179 /// ObjectPtrTy - LLVM type for object handles (typeof(id))
180 llvm::Type *ObjectPtrTy;
181
182 /// PtrObjectPtrTy - LLVM type for id *
183 llvm::Type *PtrObjectPtrTy;
184
185 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
186 llvm::Type *SelectorPtrTy;
187
188 private:
189 /// ProtocolPtrTy - LLVM type for external protocol handles
190 /// (typeof(Protocol))
191 llvm::Type *ExternalProtocolPtrTy;
192
193 public:
getExternalProtocolPtrTy()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);
202 }
203
204 return ExternalProtocolPtrTy;
205 }
206
207 // SuperCTy - clang type for struct objc_super.
208 QualType SuperCTy;
209 // SuperPtrCTy - clang type for struct objc_super *.
210 QualType SuperPtrCTy;
211
212 /// SuperTy - LLVM type for struct objc_super.
213 llvm::StructType *SuperTy;
214 /// SuperPtrTy - LLVM type for struct objc_super *.
215 llvm::Type *SuperPtrTy;
216
217 /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
218 /// in GCC parlance).
219 llvm::StructType *PropertyTy;
220
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::Type *PropertyListPtrTy;
226
227 // MethodTy - LLVM type for struct objc_method.
228 llvm::StructType *MethodTy;
229
230 /// CacheTy - LLVM type for struct objc_cache.
231 llvm::Type *CacheTy;
232 /// CachePtrTy - LLVM type for struct objc_cache *.
233 llvm::Type *CachePtrTy;
234
getGetPropertyFn()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 SmallVector<CanQualType,4> Params;
240 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
241 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
242 Params.push_back(IdType);
243 Params.push_back(SelType);
244 Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
245 Params.push_back(Ctx.BoolTy);
246 llvm::FunctionType *FTy =
247 Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(
248 IdType, false, false, Params, FunctionType::ExtInfo(),
249 RequiredArgs::All));
250 return CGM.CreateRuntimeFunction(FTy, "objc_getProperty");
251 }
252
getSetPropertyFn()253 llvm::Constant *getSetPropertyFn() {
254 CodeGen::CodeGenTypes &Types = CGM.getTypes();
255 ASTContext &Ctx = CGM.getContext();
256 // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool)
257 SmallVector<CanQualType,6> Params;
258 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
259 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
260 Params.push_back(IdType);
261 Params.push_back(SelType);
262 Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
263 Params.push_back(IdType);
264 Params.push_back(Ctx.BoolTy);
265 Params.push_back(Ctx.BoolTy);
266 llvm::FunctionType *FTy =
267 Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(
268 Ctx.VoidTy, false, false, Params, FunctionType::ExtInfo(),
269 RequiredArgs::All));
270 return CGM.CreateRuntimeFunction(FTy, "objc_setProperty");
271 }
272
getOptimizedSetPropertyFn(bool atomic,bool copy)273 llvm::Constant *getOptimizedSetPropertyFn(bool atomic, bool copy) {
274 CodeGen::CodeGenTypes &Types = CGM.getTypes();
275 ASTContext &Ctx = CGM.getContext();
276 // void objc_setProperty_atomic(id self, SEL _cmd,
277 // id newValue, ptrdiff_t offset);
278 // void objc_setProperty_nonatomic(id self, SEL _cmd,
279 // id newValue, ptrdiff_t offset);
280 // void objc_setProperty_atomic_copy(id self, SEL _cmd,
281 // id newValue, ptrdiff_t offset);
282 // void objc_setProperty_nonatomic_copy(id self, SEL _cmd,
283 // id newValue, ptrdiff_t offset);
284
285 SmallVector<CanQualType,4> Params;
286 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
287 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
288 Params.push_back(IdType);
289 Params.push_back(SelType);
290 Params.push_back(IdType);
291 Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
292 llvm::FunctionType *FTy =
293 Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(
294 Ctx.VoidTy, false, false, Params, FunctionType::ExtInfo(),
295 RequiredArgs::All));
296 const char *name;
297 if (atomic && copy)
298 name = "objc_setProperty_atomic_copy";
299 else if (atomic && !copy)
300 name = "objc_setProperty_atomic";
301 else if (!atomic && copy)
302 name = "objc_setProperty_nonatomic_copy";
303 else
304 name = "objc_setProperty_nonatomic";
305
306 return CGM.CreateRuntimeFunction(FTy, name);
307 }
308
getCopyStructFn()309 llvm::Constant *getCopyStructFn() {
310 CodeGen::CodeGenTypes &Types = CGM.getTypes();
311 ASTContext &Ctx = CGM.getContext();
312 // void objc_copyStruct (void *, const void *, size_t, bool, bool)
313 SmallVector<CanQualType,5> Params;
314 Params.push_back(Ctx.VoidPtrTy);
315 Params.push_back(Ctx.VoidPtrTy);
316 Params.push_back(Ctx.LongTy);
317 Params.push_back(Ctx.BoolTy);
318 Params.push_back(Ctx.BoolTy);
319 llvm::FunctionType *FTy =
320 Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(
321 Ctx.VoidTy, false, false, Params, FunctionType::ExtInfo(),
322 RequiredArgs::All));
323 return CGM.CreateRuntimeFunction(FTy, "objc_copyStruct");
324 }
325
326 /// This routine declares and returns address of:
327 /// void objc_copyCppObjectAtomic(
328 /// void *dest, const void *src,
329 /// void (*copyHelper) (void *dest, const void *source));
getCppAtomicObjectFunction()330 llvm::Constant *getCppAtomicObjectFunction() {
331 CodeGen::CodeGenTypes &Types = CGM.getTypes();
332 ASTContext &Ctx = CGM.getContext();
333 /// void objc_copyCppObjectAtomic(void *dest, const void *src, void *helper);
334 SmallVector<CanQualType,3> Params;
335 Params.push_back(Ctx.VoidPtrTy);
336 Params.push_back(Ctx.VoidPtrTy);
337 Params.push_back(Ctx.VoidPtrTy);
338 llvm::FunctionType *FTy =
339 Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, false, false,
340 Params,
341 FunctionType::ExtInfo(),
342 RequiredArgs::All));
343 return CGM.CreateRuntimeFunction(FTy, "objc_copyCppObjectAtomic");
344 }
345
getEnumerationMutationFn()346 llvm::Constant *getEnumerationMutationFn() {
347 CodeGen::CodeGenTypes &Types = CGM.getTypes();
348 ASTContext &Ctx = CGM.getContext();
349 // void objc_enumerationMutation (id)
350 SmallVector<CanQualType,1> Params;
351 Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType()));
352 llvm::FunctionType *FTy =
353 Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(
354 Ctx.VoidTy, false, false, Params, FunctionType::ExtInfo(),
355 RequiredArgs::All));
356 return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
357 }
358
359 /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function.
getGcReadWeakFn()360 llvm::Constant *getGcReadWeakFn() {
361 // id objc_read_weak (id *)
362 llvm::Type *args[] = { ObjectPtrTy->getPointerTo() };
363 llvm::FunctionType *FTy =
364 llvm::FunctionType::get(ObjectPtrTy, args, false);
365 return CGM.CreateRuntimeFunction(FTy, "objc_read_weak");
366 }
367
368 /// GcAssignWeakFn -- LLVM objc_assign_weak function.
getGcAssignWeakFn()369 llvm::Constant *getGcAssignWeakFn() {
370 // id objc_assign_weak (id, id *)
371 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
372 llvm::FunctionType *FTy =
373 llvm::FunctionType::get(ObjectPtrTy, args, false);
374 return CGM.CreateRuntimeFunction(FTy, "objc_assign_weak");
375 }
376
377 /// GcAssignGlobalFn -- LLVM objc_assign_global function.
getGcAssignGlobalFn()378 llvm::Constant *getGcAssignGlobalFn() {
379 // id objc_assign_global(id, id *)
380 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
381 llvm::FunctionType *FTy =
382 llvm::FunctionType::get(ObjectPtrTy, args, false);
383 return CGM.CreateRuntimeFunction(FTy, "objc_assign_global");
384 }
385
386 /// GcAssignThreadLocalFn -- LLVM objc_assign_threadlocal function.
getGcAssignThreadLocalFn()387 llvm::Constant *getGcAssignThreadLocalFn() {
388 // id objc_assign_threadlocal(id src, id * dest)
389 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
390 llvm::FunctionType *FTy =
391 llvm::FunctionType::get(ObjectPtrTy, args, false);
392 return CGM.CreateRuntimeFunction(FTy, "objc_assign_threadlocal");
393 }
394
395 /// GcAssignIvarFn -- LLVM objc_assign_ivar function.
getGcAssignIvarFn()396 llvm::Constant *getGcAssignIvarFn() {
397 // id objc_assign_ivar(id, id *, ptrdiff_t)
398 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo(),
399 CGM.PtrDiffTy };
400 llvm::FunctionType *FTy =
401 llvm::FunctionType::get(ObjectPtrTy, args, false);
402 return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar");
403 }
404
405 /// GcMemmoveCollectableFn -- LLVM objc_memmove_collectable function.
GcMemmoveCollectableFn()406 llvm::Constant *GcMemmoveCollectableFn() {
407 // void *objc_memmove_collectable(void *dst, const void *src, size_t size)
408 llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy };
409 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args, false);
410 return CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable");
411 }
412
413 /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function.
getGcAssignStrongCastFn()414 llvm::Constant *getGcAssignStrongCastFn() {
415 // id objc_assign_strongCast(id, id *)
416 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
417 llvm::FunctionType *FTy =
418 llvm::FunctionType::get(ObjectPtrTy, args, false);
419 return CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast");
420 }
421
422 /// ExceptionThrowFn - LLVM objc_exception_throw function.
getExceptionThrowFn()423 llvm::Constant *getExceptionThrowFn() {
424 // void objc_exception_throw(id)
425 llvm::Type *args[] = { ObjectPtrTy };
426 llvm::FunctionType *FTy =
427 llvm::FunctionType::get(CGM.VoidTy, args, false);
428 return CGM.CreateRuntimeFunction(FTy, "objc_exception_throw");
429 }
430
431 /// ExceptionRethrowFn - LLVM objc_exception_rethrow function.
getExceptionRethrowFn()432 llvm::Constant *getExceptionRethrowFn() {
433 // void objc_exception_rethrow(void)
434 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, false);
435 return CGM.CreateRuntimeFunction(FTy, "objc_exception_rethrow");
436 }
437
438 /// SyncEnterFn - LLVM object_sync_enter function.
getSyncEnterFn()439 llvm::Constant *getSyncEnterFn() {
440 // int objc_sync_enter (id)
441 llvm::Type *args[] = { ObjectPtrTy };
442 llvm::FunctionType *FTy =
443 llvm::FunctionType::get(CGM.IntTy, args, false);
444 return CGM.CreateRuntimeFunction(FTy, "objc_sync_enter");
445 }
446
447 /// SyncExitFn - LLVM object_sync_exit function.
getSyncExitFn()448 llvm::Constant *getSyncExitFn() {
449 // int objc_sync_exit (id)
450 llvm::Type *args[] = { ObjectPtrTy };
451 llvm::FunctionType *FTy =
452 llvm::FunctionType::get(CGM.IntTy, args, false);
453 return CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
454 }
455
getSendFn(bool IsSuper) const456 llvm::Constant *getSendFn(bool IsSuper) const {
457 return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
458 }
459
getSendFn2(bool IsSuper) const460 llvm::Constant *getSendFn2(bool IsSuper) const {
461 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
462 }
463
getSendStretFn(bool IsSuper) const464 llvm::Constant *getSendStretFn(bool IsSuper) const {
465 return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
466 }
467
getSendStretFn2(bool IsSuper) const468 llvm::Constant *getSendStretFn2(bool IsSuper) const {
469 return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
470 }
471
getSendFpretFn(bool IsSuper) const472 llvm::Constant *getSendFpretFn(bool IsSuper) const {
473 return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
474 }
475
getSendFpretFn2(bool IsSuper) const476 llvm::Constant *getSendFpretFn2(bool IsSuper) const {
477 return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
478 }
479
getSendFp2retFn(bool IsSuper) const480 llvm::Constant *getSendFp2retFn(bool IsSuper) const {
481 return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn();
482 }
483
getSendFp2RetFn2(bool IsSuper) const484 llvm::Constant *getSendFp2RetFn2(bool IsSuper) const {
485 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn();
486 }
487
488 ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm);
489 };
490
491 /// ObjCTypesHelper - Helper class that encapsulates lazy
492 /// construction of varies types used during ObjC generation.
493 class ObjCTypesHelper : public ObjCCommonTypesHelper {
494 public:
495 /// SymtabTy - LLVM type for struct objc_symtab.
496 llvm::StructType *SymtabTy;
497 /// SymtabPtrTy - LLVM type for struct objc_symtab *.
498 llvm::Type *SymtabPtrTy;
499 /// ModuleTy - LLVM type for struct objc_module.
500 llvm::StructType *ModuleTy;
501
502 /// ProtocolTy - LLVM type for struct objc_protocol.
503 llvm::StructType *ProtocolTy;
504 /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
505 llvm::Type *ProtocolPtrTy;
506 /// ProtocolExtensionTy - LLVM type for struct
507 /// objc_protocol_extension.
508 llvm::StructType *ProtocolExtensionTy;
509 /// ProtocolExtensionTy - LLVM type for struct
510 /// objc_protocol_extension *.
511 llvm::Type *ProtocolExtensionPtrTy;
512 /// MethodDescriptionTy - LLVM type for struct
513 /// objc_method_description.
514 llvm::StructType *MethodDescriptionTy;
515 /// MethodDescriptionListTy - LLVM type for struct
516 /// objc_method_description_list.
517 llvm::StructType *MethodDescriptionListTy;
518 /// MethodDescriptionListPtrTy - LLVM type for struct
519 /// objc_method_description_list *.
520 llvm::Type *MethodDescriptionListPtrTy;
521 /// ProtocolListTy - LLVM type for struct objc_property_list.
522 llvm::StructType *ProtocolListTy;
523 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
524 llvm::Type *ProtocolListPtrTy;
525 /// CategoryTy - LLVM type for struct objc_category.
526 llvm::StructType *CategoryTy;
527 /// ClassTy - LLVM type for struct objc_class.
528 llvm::StructType *ClassTy;
529 /// ClassPtrTy - LLVM type for struct objc_class *.
530 llvm::Type *ClassPtrTy;
531 /// ClassExtensionTy - LLVM type for struct objc_class_ext.
532 llvm::StructType *ClassExtensionTy;
533 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
534 llvm::Type *ClassExtensionPtrTy;
535 // IvarTy - LLVM type for struct objc_ivar.
536 llvm::StructType *IvarTy;
537 /// IvarListTy - LLVM type for struct objc_ivar_list.
538 llvm::Type *IvarListTy;
539 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
540 llvm::Type *IvarListPtrTy;
541 /// MethodListTy - LLVM type for struct objc_method_list.
542 llvm::Type *MethodListTy;
543 /// MethodListPtrTy - LLVM type for struct objc_method_list *.
544 llvm::Type *MethodListPtrTy;
545
546 /// ExceptionDataTy - LLVM type for struct _objc_exception_data.
547 llvm::Type *ExceptionDataTy;
548
549 /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.
getExceptionTryEnterFn()550 llvm::Constant *getExceptionTryEnterFn() {
551 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
552 return CGM.CreateRuntimeFunction(
553 llvm::FunctionType::get(CGM.VoidTy, params, false),
554 "objc_exception_try_enter");
555 }
556
557 /// ExceptionTryExitFn - LLVM objc_exception_try_exit function.
getExceptionTryExitFn()558 llvm::Constant *getExceptionTryExitFn() {
559 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
560 return CGM.CreateRuntimeFunction(
561 llvm::FunctionType::get(CGM.VoidTy, params, false),
562 "objc_exception_try_exit");
563 }
564
565 /// ExceptionExtractFn - LLVM objc_exception_extract function.
getExceptionExtractFn()566 llvm::Constant *getExceptionExtractFn() {
567 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
568 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
569 params, false),
570 "objc_exception_extract");
571 }
572
573 /// ExceptionMatchFn - LLVM objc_exception_match function.
getExceptionMatchFn()574 llvm::Constant *getExceptionMatchFn() {
575 llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy };
576 return CGM.CreateRuntimeFunction(
577 llvm::FunctionType::get(CGM.Int32Ty, params, false),
578 "objc_exception_match");
579
580 }
581
582 /// SetJmpFn - LLVM _setjmp function.
getSetJmpFn()583 llvm::Constant *getSetJmpFn() {
584 // This is specifically the prototype for x86.
585 llvm::Type *params[] = { CGM.Int32Ty->getPointerTo() };
586 return
587 CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty,
588 params, false),
589 "_setjmp",
590 llvm::AttributeSet::get(CGM.getLLVMContext(),
591 llvm::AttributeSet::FunctionIndex,
592 llvm::Attribute::NonLazyBind));
593 }
594
595 public:
596 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
597 };
598
599 /// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's
600 /// modern abi
601 class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {
602 public:
603
604 // MethodListnfABITy - LLVM for struct _method_list_t
605 llvm::StructType *MethodListnfABITy;
606
607 // MethodListnfABIPtrTy - LLVM for struct _method_list_t*
608 llvm::Type *MethodListnfABIPtrTy;
609
610 // ProtocolnfABITy = LLVM for struct _protocol_t
611 llvm::StructType *ProtocolnfABITy;
612
613 // ProtocolnfABIPtrTy = LLVM for struct _protocol_t*
614 llvm::Type *ProtocolnfABIPtrTy;
615
616 // ProtocolListnfABITy - LLVM for struct _objc_protocol_list
617 llvm::StructType *ProtocolListnfABITy;
618
619 // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list*
620 llvm::Type *ProtocolListnfABIPtrTy;
621
622 // ClassnfABITy - LLVM for struct _class_t
623 llvm::StructType *ClassnfABITy;
624
625 // ClassnfABIPtrTy - LLVM for struct _class_t*
626 llvm::Type *ClassnfABIPtrTy;
627
628 // IvarnfABITy - LLVM for struct _ivar_t
629 llvm::StructType *IvarnfABITy;
630
631 // IvarListnfABITy - LLVM for struct _ivar_list_t
632 llvm::StructType *IvarListnfABITy;
633
634 // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t*
635 llvm::Type *IvarListnfABIPtrTy;
636
637 // ClassRonfABITy - LLVM for struct _class_ro_t
638 llvm::StructType *ClassRonfABITy;
639
640 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
641 llvm::Type *ImpnfABITy;
642
643 // CategorynfABITy - LLVM for struct _category_t
644 llvm::StructType *CategorynfABITy;
645
646 // New types for nonfragile abi messaging.
647
648 // MessageRefTy - LLVM for:
649 // struct _message_ref_t {
650 // IMP messenger;
651 // SEL name;
652 // };
653 llvm::StructType *MessageRefTy;
654 // MessageRefCTy - clang type for struct _message_ref_t
655 QualType MessageRefCTy;
656
657 // MessageRefPtrTy - LLVM for struct _message_ref_t*
658 llvm::Type *MessageRefPtrTy;
659 // MessageRefCPtrTy - clang type for struct _message_ref_t*
660 QualType MessageRefCPtrTy;
661
662 // MessengerTy - Type of the messenger (shown as IMP above)
663 llvm::FunctionType *MessengerTy;
664
665 // SuperMessageRefTy - LLVM for:
666 // struct _super_message_ref_t {
667 // SUPER_IMP messenger;
668 // SEL name;
669 // };
670 llvm::StructType *SuperMessageRefTy;
671
672 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
673 llvm::Type *SuperMessageRefPtrTy;
674
getMessageSendFixupFn()675 llvm::Constant *getMessageSendFixupFn() {
676 // id objc_msgSend_fixup(id, struct message_ref_t*, ...)
677 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
678 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
679 params, true),
680 "objc_msgSend_fixup");
681 }
682
getMessageSendFpretFixupFn()683 llvm::Constant *getMessageSendFpretFixupFn() {
684 // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...)
685 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
686 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
687 params, true),
688 "objc_msgSend_fpret_fixup");
689 }
690
getMessageSendStretFixupFn()691 llvm::Constant *getMessageSendStretFixupFn() {
692 // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...)
693 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
694 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
695 params, true),
696 "objc_msgSend_stret_fixup");
697 }
698
getMessageSendSuper2FixupFn()699 llvm::Constant *getMessageSendSuper2FixupFn() {
700 // id objc_msgSendSuper2_fixup (struct objc_super *,
701 // struct _super_message_ref_t*, ...)
702 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
703 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
704 params, true),
705 "objc_msgSendSuper2_fixup");
706 }
707
getMessageSendSuper2StretFixupFn()708 llvm::Constant *getMessageSendSuper2StretFixupFn() {
709 // id objc_msgSendSuper2_stret_fixup(struct objc_super *,
710 // struct _super_message_ref_t*, ...)
711 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
712 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
713 params, true),
714 "objc_msgSendSuper2_stret_fixup");
715 }
716
getObjCEndCatchFn()717 llvm::Constant *getObjCEndCatchFn() {
718 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy, false),
719 "objc_end_catch");
720
721 }
722
getObjCBeginCatchFn()723 llvm::Constant *getObjCBeginCatchFn() {
724 llvm::Type *params[] = { Int8PtrTy };
725 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy,
726 params, false),
727 "objc_begin_catch");
728 }
729
730 llvm::StructType *EHTypeTy;
731 llvm::Type *EHTypePtrTy;
732
733 ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
734 };
735
736 class CGObjCCommonMac : public CodeGen::CGObjCRuntime {
737 public:
738 // FIXME - accessibility
739 class GC_IVAR {
740 public:
741 unsigned ivar_bytepos;
742 unsigned ivar_size;
GC_IVAR(unsigned bytepos=0,unsigned size=0)743 GC_IVAR(unsigned bytepos = 0, unsigned size = 0)
744 : ivar_bytepos(bytepos), ivar_size(size) {}
745
746 // Allow sorting based on byte pos.
operator <(const GC_IVAR & b) const747 bool operator<(const GC_IVAR &b) const {
748 return ivar_bytepos < b.ivar_bytepos;
749 }
750 };
751
752 class SKIP_SCAN {
753 public:
754 unsigned skip;
755 unsigned scan;
SKIP_SCAN(unsigned _skip=0,unsigned _scan=0)756 SKIP_SCAN(unsigned _skip = 0, unsigned _scan = 0)
757 : skip(_skip), scan(_scan) {}
758 };
759
760 /// opcode for captured block variables layout 'instructions'.
761 /// In the following descriptions, 'I' is the value of the immediate field.
762 /// (field following the opcode).
763 ///
764 enum BLOCK_LAYOUT_OPCODE {
765 /// An operator which affects how the following layout should be
766 /// interpreted.
767 /// I == 0: Halt interpretation and treat everything else as
768 /// a non-pointer. Note that this instruction is equal
769 /// to '\0'.
770 /// I != 0: Currently unused.
771 BLOCK_LAYOUT_OPERATOR = 0,
772
773 /// The next I+1 bytes do not contain a value of object pointer type.
774 /// Note that this can leave the stream unaligned, meaning that
775 /// subsequent word-size instructions do not begin at a multiple of
776 /// the pointer size.
777 BLOCK_LAYOUT_NON_OBJECT_BYTES = 1,
778
779 /// The next I+1 words do not contain a value of object pointer type.
780 /// This is simply an optimized version of BLOCK_LAYOUT_BYTES for
781 /// when the required skip quantity is a multiple of the pointer size.
782 BLOCK_LAYOUT_NON_OBJECT_WORDS = 2,
783
784 /// The next I+1 words are __strong pointers to Objective-C
785 /// objects or blocks.
786 BLOCK_LAYOUT_STRONG = 3,
787
788 /// The next I+1 words are pointers to __block variables.
789 BLOCK_LAYOUT_BYREF = 4,
790
791 /// The next I+1 words are __weak pointers to Objective-C
792 /// objects or blocks.
793 BLOCK_LAYOUT_WEAK = 5,
794
795 /// The next I+1 words are __unsafe_unretained pointers to
796 /// Objective-C objects or blocks.
797 BLOCK_LAYOUT_UNRETAINED = 6
798
799 /// The next I+1 words are block or object pointers with some
800 /// as-yet-unspecified ownership semantics. If we add more
801 /// flavors of ownership semantics, values will be taken from
802 /// this range.
803 ///
804 /// This is included so that older tools can at least continue
805 /// processing the layout past such things.
806 //BLOCK_LAYOUT_OWNERSHIP_UNKNOWN = 7..10,
807
808 /// All other opcodes are reserved. Halt interpretation and
809 /// treat everything else as opaque.
810 };
811
812 class RUN_SKIP {
813 public:
814 enum BLOCK_LAYOUT_OPCODE opcode;
815 CharUnits block_var_bytepos;
816 CharUnits block_var_size;
RUN_SKIP(enum BLOCK_LAYOUT_OPCODE Opcode=BLOCK_LAYOUT_OPERATOR,CharUnits BytePos=CharUnits::Zero (),CharUnits Size=CharUnits::Zero ())817 RUN_SKIP(enum BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR,
818 CharUnits BytePos = CharUnits::Zero(),
819 CharUnits Size = CharUnits::Zero())
820 : opcode(Opcode), block_var_bytepos(BytePos), block_var_size(Size) {}
821
822 // Allow sorting based on byte pos.
operator <(const RUN_SKIP & b) const823 bool operator<(const RUN_SKIP &b) const {
824 return block_var_bytepos < b.block_var_bytepos;
825 }
826 };
827
828 protected:
829 llvm::LLVMContext &VMContext;
830 // FIXME! May not be needing this after all.
831 unsigned ObjCABI;
832
833 // gc ivar layout bitmap calculation helper caches.
834 SmallVector<GC_IVAR, 16> SkipIvars;
835 SmallVector<GC_IVAR, 16> IvarsInfo;
836
837 // arc/mrr layout of captured block literal variables.
838 SmallVector<RUN_SKIP, 16> RunSkipBlockVars;
839
840 /// LazySymbols - Symbols to generate a lazy reference for. See
841 /// DefinedSymbols and FinishModule().
842 llvm::SetVector<IdentifierInfo*> LazySymbols;
843
844 /// DefinedSymbols - External symbols which are defined by this
845 /// module. The symbols in this list and LazySymbols are used to add
846 /// special linker symbols which ensure that Objective-C modules are
847 /// linked properly.
848 llvm::SetVector<IdentifierInfo*> DefinedSymbols;
849
850 /// ClassNames - uniqued class names.
851 llvm::StringMap<llvm::GlobalVariable*> ClassNames;
852
853 /// MethodVarNames - uniqued method variable names.
854 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
855
856 /// DefinedCategoryNames - list of category names in form Class_Category.
857 llvm::SetVector<std::string> DefinedCategoryNames;
858
859 /// MethodVarTypes - uniqued method type signatures. We have to use
860 /// a StringMap here because have no other unique reference.
861 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
862
863 /// MethodDefinitions - map of methods which have been defined in
864 /// this translation unit.
865 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
866
867 /// PropertyNames - uniqued method variable names.
868 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
869
870 /// ClassReferences - uniqued class references.
871 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
872
873 /// SelectorReferences - uniqued selector references.
874 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
875
876 /// Protocols - Protocols for which an objc_protocol structure has
877 /// been emitted. Forward declarations are handled by creating an
878 /// empty structure whose initializer is filled in when/if defined.
879 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
880
881 /// DefinedProtocols - Protocols which have actually been
882 /// defined. We should not need this, see FIXME in GenerateProtocol.
883 llvm::DenseSet<IdentifierInfo*> DefinedProtocols;
884
885 /// DefinedClasses - List of defined classes.
886 SmallVector<llvm::GlobalValue*, 16> DefinedClasses;
887
888 /// ImplementedClasses - List of @implemented classes.
889 SmallVector<const ObjCInterfaceDecl*, 16> ImplementedClasses;
890
891 /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
892 SmallVector<llvm::GlobalValue*, 16> DefinedNonLazyClasses;
893
894 /// DefinedCategories - List of defined categories.
895 SmallVector<llvm::GlobalValue*, 16> DefinedCategories;
896
897 /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
898 SmallVector<llvm::GlobalValue*, 16> DefinedNonLazyCategories;
899
900 /// GetNameForMethod - Return a name for the given method.
901 /// \param[out] NameOut - The return value.
902 void GetNameForMethod(const ObjCMethodDecl *OMD,
903 const ObjCContainerDecl *CD,
904 SmallVectorImpl<char> &NameOut);
905
906 /// GetMethodVarName - Return a unique constant for the given
907 /// selector's name. The return value has type char *.
908 llvm::Constant *GetMethodVarName(Selector Sel);
909 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
910
911 /// GetMethodVarType - Return a unique constant for the given
912 /// method's type encoding string. The return value has type char *.
913
914 // FIXME: This is a horrible name.
915 llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D,
916 bool Extended = false);
917 llvm::Constant *GetMethodVarType(const FieldDecl *D);
918
919 /// GetPropertyName - Return a unique constant for the given
920 /// name. The return value has type char *.
921 llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
922
923 // FIXME: This can be dropped once string functions are unified.
924 llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,
925 const Decl *Container);
926
927 /// GetClassName - Return a unique constant for the given selector's
928 /// runtime name (which may change via use of objc_runtime_name attribute on
929 /// class or protocol definition. The return value has type char *.
930 llvm::Constant *GetClassName(StringRef RuntimeName);
931
932 llvm::Function *GetMethodDefinition(const ObjCMethodDecl *MD);
933
934 /// BuildIvarLayout - Builds ivar layout bitmap for the class
935 /// implementation for the __strong or __weak case.
936 ///
937 llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI,
938 bool ForStrongLayout);
939
940 llvm::Constant *BuildIvarLayoutBitmap(std::string &BitMap);
941
942 void BuildAggrIvarRecordLayout(const RecordType *RT,
943 unsigned int BytePos, bool ForStrongLayout,
944 bool &HasUnion);
945 void BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
946 const llvm::StructLayout *Layout,
947 const RecordDecl *RD,
948 ArrayRef<const FieldDecl*> RecFields,
949 unsigned int BytePos, bool ForStrongLayout,
950 bool &HasUnion);
951
952 Qualifiers::ObjCLifetime getBlockCaptureLifetime(QualType QT, bool ByrefLayout);
953
954 void UpdateRunSkipBlockVars(bool IsByref,
955 Qualifiers::ObjCLifetime LifeTime,
956 CharUnits FieldOffset,
957 CharUnits FieldSize);
958
959 void BuildRCBlockVarRecordLayout(const RecordType *RT,
960 CharUnits BytePos, bool &HasUnion,
961 bool ByrefLayout=false);
962
963 void BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
964 const RecordDecl *RD,
965 ArrayRef<const FieldDecl*> RecFields,
966 CharUnits BytePos, bool &HasUnion,
967 bool ByrefLayout);
968
969 uint64_t InlineLayoutInstruction(SmallVectorImpl<unsigned char> &Layout);
970
971 llvm::Constant *getBitmapBlockLayout(bool ComputeByrefLayout);
972
973
974 /// GetIvarLayoutName - Returns a unique constant for the given
975 /// ivar layout bitmap.
976 llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident,
977 const ObjCCommonTypesHelper &ObjCTypes);
978
979 /// EmitPropertyList - Emit the given property list. The return
980 /// value has type PropertyListPtrTy.
981 llvm::Constant *EmitPropertyList(Twine Name,
982 const Decl *Container,
983 const ObjCContainerDecl *OCD,
984 const ObjCCommonTypesHelper &ObjCTypes);
985
986 /// EmitProtocolMethodTypes - Generate the array of extended method type
987 /// strings. The return value has type Int8PtrPtrTy.
988 llvm::Constant *EmitProtocolMethodTypes(Twine Name,
989 ArrayRef<llvm::Constant*> MethodTypes,
990 const ObjCCommonTypesHelper &ObjCTypes);
991
992 /// PushProtocolProperties - Push protocol's property on the input stack.
993 void PushProtocolProperties(
994 llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet,
995 SmallVectorImpl<llvm::Constant*> &Properties,
996 const Decl *Container,
997 const ObjCProtocolDecl *Proto,
998 const ObjCCommonTypesHelper &ObjCTypes);
999
1000 /// GetProtocolRef - Return a reference to the internal protocol
1001 /// description, creating an empty one if it has not been
1002 /// defined. The return value has type ProtocolPtrTy.
1003 llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD);
1004
1005 /// CreateMetadataVar - Create a global variable with internal
1006 /// linkage for use by the Objective-C runtime.
1007 ///
1008 /// This is a convenience wrapper which not only creates the
1009 /// variable, but also sets the section and alignment and adds the
1010 /// global to the "llvm.used" list.
1011 ///
1012 /// \param Name - The variable name.
1013 /// \param Init - The variable initializer; this is also used to
1014 /// define the type of the variable.
1015 /// \param Section - The section the variable should go into, or empty.
1016 /// \param Align - The alignment for the variable, or 0.
1017 /// \param AddToUsed - Whether the variable should be added to
1018 /// "llvm.used".
1019 llvm::GlobalVariable *CreateMetadataVar(Twine Name, llvm::Constant *Init,
1020 StringRef Section, unsigned Align,
1021 bool AddToUsed);
1022
1023 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
1024 ReturnValueSlot Return,
1025 QualType ResultType,
1026 llvm::Value *Sel,
1027 llvm::Value *Arg0,
1028 QualType Arg0Ty,
1029 bool IsSuper,
1030 const CallArgList &CallArgs,
1031 const ObjCMethodDecl *OMD,
1032 const ObjCCommonTypesHelper &ObjCTypes);
1033
1034 /// EmitImageInfo - Emit the image info marker used to encode some module
1035 /// level information.
1036 void EmitImageInfo();
1037
1038 public:
CGObjCCommonMac(CodeGen::CodeGenModule & cgm)1039 CGObjCCommonMac(CodeGen::CodeGenModule &cgm) :
1040 CGObjCRuntime(cgm), VMContext(cgm.getLLVMContext()) { }
1041
1042 llvm::Constant *GenerateConstantString(const StringLiteral *SL) override;
1043
1044 llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
1045 const ObjCContainerDecl *CD=nullptr) override;
1046
1047 void GenerateProtocol(const ObjCProtocolDecl *PD) override;
1048
1049 /// GetOrEmitProtocol - Get the protocol object for the given
1050 /// declaration, emitting it if necessary. The return value has type
1051 /// ProtocolPtrTy.
1052 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0;
1053
1054 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1055 /// object for the given declaration, emitting it if needed. These
1056 /// forward references will be filled in with empty bodies if no
1057 /// definition is seen. The return value has type ProtocolPtrTy.
1058 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0;
1059 llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
1060 const CGBlockInfo &blockInfo) override;
1061 llvm::Constant *BuildRCBlockLayout(CodeGen::CodeGenModule &CGM,
1062 const CGBlockInfo &blockInfo) override;
1063
1064 llvm::Constant *BuildByrefLayout(CodeGen::CodeGenModule &CGM,
1065 QualType T) override;
1066 };
1067
1068 class CGObjCMac : public CGObjCCommonMac {
1069 private:
1070 ObjCTypesHelper ObjCTypes;
1071
1072 /// EmitModuleInfo - Another marker encoding module level
1073 /// information.
1074 void EmitModuleInfo();
1075
1076 /// EmitModuleSymols - Emit module symbols, the list of defined
1077 /// classes and categories. The result has type SymtabPtrTy.
1078 llvm::Constant *EmitModuleSymbols();
1079
1080 /// FinishModule - Write out global data structures at the end of
1081 /// processing a translation unit.
1082 void FinishModule();
1083
1084 /// EmitClassExtension - Generate the class extension structure used
1085 /// to store the weak ivar layout and properties. The return value
1086 /// has type ClassExtensionPtrTy.
1087 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
1088
1089 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1090 /// for the given class.
1091 llvm::Value *EmitClassRef(CodeGenFunction &CGF,
1092 const ObjCInterfaceDecl *ID);
1093
1094 llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF,
1095 IdentifierInfo *II);
1096
1097 llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) override;
1098
1099 /// EmitSuperClassRef - Emits reference to class's main metadata class.
1100 llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID);
1101
1102 /// EmitIvarList - Emit the ivar list for the given
1103 /// implementation. If ForClass is true the list of class ivars
1104 /// (i.e. metaclass ivars) is emitted, otherwise the list of
1105 /// interface ivars will be emitted. The return value has type
1106 /// IvarListPtrTy.
1107 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
1108 bool ForClass);
1109
1110 /// EmitMetaClass - Emit a forward reference to the class structure
1111 /// for the metaclass of the given interface. The return value has
1112 /// type ClassPtrTy.
1113 llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID);
1114
1115 /// EmitMetaClass - Emit a class structure for the metaclass of the
1116 /// given implementation. The return value has type ClassPtrTy.
1117 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
1118 llvm::Constant *Protocols,
1119 ArrayRef<llvm::Constant*> Methods);
1120
1121 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
1122
1123 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
1124
1125 /// EmitMethodList - Emit the method list for the given
1126 /// implementation. The return value has type MethodListPtrTy.
1127 llvm::Constant *EmitMethodList(Twine Name,
1128 const char *Section,
1129 ArrayRef<llvm::Constant*> Methods);
1130
1131 /// EmitMethodDescList - Emit a method description list for a list of
1132 /// method declarations.
1133 /// - TypeName: The name for the type containing the methods.
1134 /// - IsProtocol: True iff these methods are for a protocol.
1135 /// - ClassMethds: True iff these are class methods.
1136 /// - Required: When true, only "required" methods are
1137 /// listed. Similarly, when false only "optional" methods are
1138 /// listed. For classes this should always be true.
1139 /// - begin, end: The method list to output.
1140 ///
1141 /// The return value has type MethodDescriptionListPtrTy.
1142 llvm::Constant *EmitMethodDescList(Twine Name,
1143 const char *Section,
1144 ArrayRef<llvm::Constant*> Methods);
1145
1146 /// GetOrEmitProtocol - Get the protocol object for the given
1147 /// declaration, emitting it if necessary. The return value has type
1148 /// ProtocolPtrTy.
1149 llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) override;
1150
1151 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1152 /// object for the given declaration, emitting it if needed. These
1153 /// forward references will be filled in with empty bodies if no
1154 /// definition is seen. The return value has type ProtocolPtrTy.
1155 llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) override;
1156
1157 /// EmitProtocolExtension - Generate the protocol extension
1158 /// structure used to store optional instance and class methods, and
1159 /// protocol properties. The return value has type
1160 /// ProtocolExtensionPtrTy.
1161 llvm::Constant *
1162 EmitProtocolExtension(const ObjCProtocolDecl *PD,
1163 ArrayRef<llvm::Constant*> OptInstanceMethods,
1164 ArrayRef<llvm::Constant*> OptClassMethods,
1165 ArrayRef<llvm::Constant*> MethodTypesExt);
1166
1167 /// EmitProtocolList - Generate the list of referenced
1168 /// protocols. The return value has type ProtocolListPtrTy.
1169 llvm::Constant *EmitProtocolList(Twine Name,
1170 ObjCProtocolDecl::protocol_iterator begin,
1171 ObjCProtocolDecl::protocol_iterator end);
1172
1173 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
1174 /// for the given selector.
1175 llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel,
1176 bool lval=false);
1177
1178 public:
1179 CGObjCMac(CodeGen::CodeGenModule &cgm);
1180
1181 llvm::Function *ModuleInitFunction() override;
1182
1183 CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1184 ReturnValueSlot Return,
1185 QualType ResultType,
1186 Selector Sel, llvm::Value *Receiver,
1187 const CallArgList &CallArgs,
1188 const ObjCInterfaceDecl *Class,
1189 const ObjCMethodDecl *Method) override;
1190
1191 CodeGen::RValue
1192 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1193 ReturnValueSlot Return, QualType ResultType,
1194 Selector Sel, const ObjCInterfaceDecl *Class,
1195 bool isCategoryImpl, llvm::Value *Receiver,
1196 bool IsClassMessage, const CallArgList &CallArgs,
1197 const ObjCMethodDecl *Method) override;
1198
1199 llvm::Value *GetClass(CodeGenFunction &CGF,
1200 const ObjCInterfaceDecl *ID) override;
1201
1202 llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel,
1203 bool lval = false) override;
1204
1205 /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1206 /// untyped one.
1207 llvm::Value *GetSelector(CodeGenFunction &CGF,
1208 const ObjCMethodDecl *Method) override;
1209
1210 llvm::Constant *GetEHType(QualType T) override;
1211
1212 void GenerateCategory(const ObjCCategoryImplDecl *CMD) override;
1213
1214 void GenerateClass(const ObjCImplementationDecl *ClassDecl) override;
1215
RegisterAlias(const ObjCCompatibleAliasDecl * OAD)1216 void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) override {}
1217
1218 llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
1219 const ObjCProtocolDecl *PD) override;
1220
1221 llvm::Constant *GetPropertyGetFunction() override;
1222 llvm::Constant *GetPropertySetFunction() override;
1223 llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
1224 bool copy) override;
1225 llvm::Constant *GetGetStructFunction() override;
1226 llvm::Constant *GetSetStructFunction() override;
1227 llvm::Constant *GetCppAtomicObjectGetFunction() override;
1228 llvm::Constant *GetCppAtomicObjectSetFunction() override;
1229 llvm::Constant *EnumerationMutationFunction() override;
1230
1231 void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1232 const ObjCAtTryStmt &S) override;
1233 void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1234 const ObjCAtSynchronizedStmt &S) override;
1235 void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const Stmt &S);
1236 void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S,
1237 bool ClearInsertionPoint=true) override;
1238 llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1239 llvm::Value *AddrWeakObj) override;
1240 void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1241 llvm::Value *src, llvm::Value *dst) override;
1242 void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1243 llvm::Value *src, llvm::Value *dest,
1244 bool threadlocal = false) override;
1245 void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
1246 llvm::Value *src, llvm::Value *dest,
1247 llvm::Value *ivarOffset) override;
1248 void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
1249 llvm::Value *src, llvm::Value *dest) override;
1250 void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1251 llvm::Value *dest, llvm::Value *src,
1252 llvm::Value *size) override;
1253
1254 LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,
1255 llvm::Value *BaseValue, const ObjCIvarDecl *Ivar,
1256 unsigned CVRQualifiers) override;
1257 llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1258 const ObjCInterfaceDecl *Interface,
1259 const ObjCIvarDecl *Ivar) override;
1260
1261 /// GetClassGlobal - Return the global variable for the Objective-C
1262 /// class of the given name.
GetClassGlobal(const std::string & Name,bool Weak=false)1263 llvm::GlobalVariable *GetClassGlobal(const std::string &Name,
1264 bool Weak = false) override {
1265 llvm_unreachable("CGObjCMac::GetClassGlobal");
1266 }
1267 };
1268
1269 class CGObjCNonFragileABIMac : public CGObjCCommonMac {
1270 private:
1271 ObjCNonFragileABITypesHelper ObjCTypes;
1272 llvm::GlobalVariable* ObjCEmptyCacheVar;
1273 llvm::GlobalVariable* ObjCEmptyVtableVar;
1274
1275 /// SuperClassReferences - uniqued super class references.
1276 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
1277
1278 /// MetaClassReferences - uniqued meta class references.
1279 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
1280
1281 /// EHTypeReferences - uniqued class ehtype references.
1282 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
1283
1284 /// VTableDispatchMethods - List of methods for which we generate
1285 /// vtable-based message dispatch.
1286 llvm::DenseSet<Selector> VTableDispatchMethods;
1287
1288 /// DefinedMetaClasses - List of defined meta-classes.
1289 std::vector<llvm::GlobalValue*> DefinedMetaClasses;
1290
1291 /// isVTableDispatchedSelector - Returns true if SEL is a
1292 /// vtable-based selector.
1293 bool isVTableDispatchedSelector(Selector Sel);
1294
1295 /// FinishNonFragileABIModule - Write out global data structures at the end of
1296 /// processing a translation unit.
1297 void FinishNonFragileABIModule();
1298
1299 /// AddModuleClassList - Add the given list of class pointers to the
1300 /// module with the provided symbol and section names.
1301 void AddModuleClassList(ArrayRef<llvm::GlobalValue*> Container,
1302 const char *SymbolName,
1303 const char *SectionName);
1304
1305 llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags,
1306 unsigned InstanceStart,
1307 unsigned InstanceSize,
1308 const ObjCImplementationDecl *ID);
1309 llvm::GlobalVariable * BuildClassMetaData(const std::string &ClassName,
1310 llvm::Constant *IsAGV,
1311 llvm::Constant *SuperClassGV,
1312 llvm::Constant *ClassRoGV,
1313 bool HiddenVisibility,
1314 bool Weak);
1315
1316 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
1317
1318 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
1319
1320 /// EmitMethodList - Emit the method list for the given
1321 /// implementation. The return value has type MethodListnfABITy.
1322 llvm::Constant *EmitMethodList(Twine Name,
1323 const char *Section,
1324 ArrayRef<llvm::Constant*> Methods);
1325 /// EmitIvarList - Emit the ivar list for the given
1326 /// implementation. If ForClass is true the list of class ivars
1327 /// (i.e. metaclass ivars) is emitted, otherwise the list of
1328 /// interface ivars will be emitted. The return value has type
1329 /// IvarListnfABIPtrTy.
1330 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID);
1331
1332 llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
1333 const ObjCIvarDecl *Ivar,
1334 unsigned long int offset);
1335
1336 /// GetOrEmitProtocol - Get the protocol object for the given
1337 /// declaration, emitting it if necessary. The return value has type
1338 /// ProtocolPtrTy.
1339 llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) override;
1340
1341 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1342 /// object for the given declaration, emitting it if needed. These
1343 /// forward references will be filled in with empty bodies if no
1344 /// definition is seen. The return value has type ProtocolPtrTy.
1345 llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) override;
1346
1347 /// EmitProtocolList - Generate the list of referenced
1348 /// protocols. The return value has type ProtocolListPtrTy.
1349 llvm::Constant *EmitProtocolList(Twine Name,
1350 ObjCProtocolDecl::protocol_iterator begin,
1351 ObjCProtocolDecl::protocol_iterator end);
1352
1353 CodeGen::RValue EmitVTableMessageSend(CodeGen::CodeGenFunction &CGF,
1354 ReturnValueSlot Return,
1355 QualType ResultType,
1356 Selector Sel,
1357 llvm::Value *Receiver,
1358 QualType Arg0Ty,
1359 bool IsSuper,
1360 const CallArgList &CallArgs,
1361 const ObjCMethodDecl *Method);
1362
1363 /// GetClassGlobal - Return the global variable for the Objective-C
1364 /// class of the given name.
1365 llvm::GlobalVariable *GetClassGlobal(const std::string &Name,
1366 bool Weak = false) override;
1367
1368 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1369 /// for the given class reference.
1370 llvm::Value *EmitClassRef(CodeGenFunction &CGF,
1371 const ObjCInterfaceDecl *ID);
1372
1373 llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF,
1374 IdentifierInfo *II, bool Weak,
1375 const ObjCInterfaceDecl *ID);
1376
1377 llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) override;
1378
1379 /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1380 /// for the given super class reference.
1381 llvm::Value *EmitSuperClassRef(CodeGenFunction &CGF,
1382 const ObjCInterfaceDecl *ID);
1383
1384 /// EmitMetaClassRef - Return a Value * of the address of _class_t
1385 /// meta-data
1386 llvm::Value *EmitMetaClassRef(CodeGenFunction &CGF,
1387 const ObjCInterfaceDecl *ID, bool Weak);
1388
1389 /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
1390 /// the given ivar.
1391 ///
1392 llvm::GlobalVariable * ObjCIvarOffsetVariable(
1393 const ObjCInterfaceDecl *ID,
1394 const ObjCIvarDecl *Ivar);
1395
1396 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
1397 /// for the given selector.
1398 llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel,
1399 bool lval=false);
1400
1401 /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C
1402 /// interface. The return value has type EHTypePtrTy.
1403 llvm::Constant *GetInterfaceEHType(const ObjCInterfaceDecl *ID,
1404 bool ForDefinition);
1405
getMetaclassSymbolPrefix() const1406 const char *getMetaclassSymbolPrefix() const {
1407 return "OBJC_METACLASS_$_";
1408 }
1409
getClassSymbolPrefix() const1410 const char *getClassSymbolPrefix() const {
1411 return "OBJC_CLASS_$_";
1412 }
1413
1414 void GetClassSizeInfo(const ObjCImplementationDecl *OID,
1415 uint32_t &InstanceStart,
1416 uint32_t &InstanceSize);
1417
1418 // Shamelessly stolen from Analysis/CFRefCount.cpp
GetNullarySelector(const char * name) const1419 Selector GetNullarySelector(const char* name) const {
1420 IdentifierInfo* II = &CGM.getContext().Idents.get(name);
1421 return CGM.getContext().Selectors.getSelector(0, &II);
1422 }
1423
GetUnarySelector(const char * name) const1424 Selector GetUnarySelector(const char* name) const {
1425 IdentifierInfo* II = &CGM.getContext().Idents.get(name);
1426 return CGM.getContext().Selectors.getSelector(1, &II);
1427 }
1428
1429 /// ImplementationIsNonLazy - Check whether the given category or
1430 /// class implementation is "non-lazy".
1431 bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const;
1432
IsIvarOffsetKnownIdempotent(const CodeGen::CodeGenFunction & CGF,const ObjCIvarDecl * IV)1433 bool IsIvarOffsetKnownIdempotent(const CodeGen::CodeGenFunction &CGF,
1434 const ObjCIvarDecl *IV) {
1435 // Annotate the load as an invariant load iff inside an instance method
1436 // and ivar belongs to instance method's class and one of its super class.
1437 // This check is needed because the ivar offset is a lazily
1438 // initialised value that may depend on objc_msgSend to perform a fixup on
1439 // the first message dispatch.
1440 //
1441 // An additional opportunity to mark the load as invariant arises when the
1442 // base of the ivar access is a parameter to an Objective C method.
1443 // However, because the parameters are not available in the current
1444 // interface, we cannot perform this check.
1445 if (const ObjCMethodDecl *MD =
1446 dyn_cast_or_null<ObjCMethodDecl>(CGF.CurFuncDecl))
1447 if (MD->isInstanceMethod())
1448 if (const ObjCInterfaceDecl *ID = MD->getClassInterface())
1449 return IV->getContainingInterface()->isSuperClassOf(ID);
1450 return false;
1451 }
1452
1453 public:
1454 CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
1455 // FIXME. All stubs for now!
1456 llvm::Function *ModuleInitFunction() override;
1457
1458 CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1459 ReturnValueSlot Return,
1460 QualType ResultType, Selector Sel,
1461 llvm::Value *Receiver,
1462 const CallArgList &CallArgs,
1463 const ObjCInterfaceDecl *Class,
1464 const ObjCMethodDecl *Method) override;
1465
1466 CodeGen::RValue
1467 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1468 ReturnValueSlot Return, QualType ResultType,
1469 Selector Sel, const ObjCInterfaceDecl *Class,
1470 bool isCategoryImpl, llvm::Value *Receiver,
1471 bool IsClassMessage, const CallArgList &CallArgs,
1472 const ObjCMethodDecl *Method) override;
1473
1474 llvm::Value *GetClass(CodeGenFunction &CGF,
1475 const ObjCInterfaceDecl *ID) override;
1476
GetSelector(CodeGenFunction & CGF,Selector Sel,bool lvalue=false)1477 llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel,
1478 bool lvalue = false) override
1479 { return EmitSelector(CGF, Sel, lvalue); }
1480
1481 /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1482 /// untyped one.
GetSelector(CodeGenFunction & CGF,const ObjCMethodDecl * Method)1483 llvm::Value *GetSelector(CodeGenFunction &CGF,
1484 const ObjCMethodDecl *Method) override
1485 { return EmitSelector(CGF, Method->getSelector()); }
1486
1487 void GenerateCategory(const ObjCCategoryImplDecl *CMD) override;
1488
1489 void GenerateClass(const ObjCImplementationDecl *ClassDecl) override;
1490
RegisterAlias(const ObjCCompatibleAliasDecl * OAD)1491 void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) override {}
1492
1493 llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
1494 const ObjCProtocolDecl *PD) override;
1495
1496 llvm::Constant *GetEHType(QualType T) override;
1497
GetPropertyGetFunction()1498 llvm::Constant *GetPropertyGetFunction() override {
1499 return ObjCTypes.getGetPropertyFn();
1500 }
GetPropertySetFunction()1501 llvm::Constant *GetPropertySetFunction() override {
1502 return ObjCTypes.getSetPropertyFn();
1503 }
1504
GetOptimizedPropertySetFunction(bool atomic,bool copy)1505 llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
1506 bool copy) override {
1507 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
1508 }
1509
GetSetStructFunction()1510 llvm::Constant *GetSetStructFunction() override {
1511 return ObjCTypes.getCopyStructFn();
1512 }
GetGetStructFunction()1513 llvm::Constant *GetGetStructFunction() override {
1514 return ObjCTypes.getCopyStructFn();
1515 }
GetCppAtomicObjectSetFunction()1516 llvm::Constant *GetCppAtomicObjectSetFunction() override {
1517 return ObjCTypes.getCppAtomicObjectFunction();
1518 }
GetCppAtomicObjectGetFunction()1519 llvm::Constant *GetCppAtomicObjectGetFunction() override {
1520 return ObjCTypes.getCppAtomicObjectFunction();
1521 }
1522
EnumerationMutationFunction()1523 llvm::Constant *EnumerationMutationFunction() override {
1524 return ObjCTypes.getEnumerationMutationFn();
1525 }
1526
1527 void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1528 const ObjCAtTryStmt &S) override;
1529 void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1530 const ObjCAtSynchronizedStmt &S) override;
1531 void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S,
1532 bool ClearInsertionPoint=true) override;
1533 llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1534 llvm::Value *AddrWeakObj) override;
1535 void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1536 llvm::Value *src, llvm::Value *dst) override;
1537 void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1538 llvm::Value *src, llvm::Value *dest,
1539 bool threadlocal = false) override;
1540 void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
1541 llvm::Value *src, llvm::Value *dest,
1542 llvm::Value *ivarOffset) override;
1543 void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
1544 llvm::Value *src, llvm::Value *dest) override;
1545 void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1546 llvm::Value *dest, llvm::Value *src,
1547 llvm::Value *size) override;
1548 LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,
1549 llvm::Value *BaseValue, const ObjCIvarDecl *Ivar,
1550 unsigned CVRQualifiers) override;
1551 llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1552 const ObjCInterfaceDecl *Interface,
1553 const ObjCIvarDecl *Ivar) override;
1554 };
1555
1556 /// A helper class for performing the null-initialization of a return
1557 /// value.
1558 struct NullReturnState {
1559 llvm::BasicBlock *NullBB;
NullReturnState__anon0ea151f90111::NullReturnState1560 NullReturnState() : NullBB(nullptr) {}
1561
1562 /// Perform a null-check of the given receiver.
init__anon0ea151f90111::NullReturnState1563 void init(CodeGenFunction &CGF, llvm::Value *receiver) {
1564 // Make blocks for the null-receiver and call edges.
1565 NullBB = CGF.createBasicBlock("msgSend.null-receiver");
1566 llvm::BasicBlock *callBB = CGF.createBasicBlock("msgSend.call");
1567
1568 // Check for a null receiver and, if there is one, jump to the
1569 // null-receiver block. There's no point in trying to avoid it:
1570 // we're always going to put *something* there, because otherwise
1571 // we shouldn't have done this null-check in the first place.
1572 llvm::Value *isNull = CGF.Builder.CreateIsNull(receiver);
1573 CGF.Builder.CreateCondBr(isNull, NullBB, callBB);
1574
1575 // Otherwise, start performing the call.
1576 CGF.EmitBlock(callBB);
1577 }
1578
1579 /// Complete the null-return operation. It is valid to call this
1580 /// regardless of whether 'init' has been called.
complete__anon0ea151f90111::NullReturnState1581 RValue complete(CodeGenFunction &CGF, RValue result, QualType resultType,
1582 const CallArgList &CallArgs,
1583 const ObjCMethodDecl *Method) {
1584 // If we never had to do a null-check, just use the raw result.
1585 if (!NullBB) return result;
1586
1587 // The continuation block. This will be left null if we don't have an
1588 // IP, which can happen if the method we're calling is marked noreturn.
1589 llvm::BasicBlock *contBB = nullptr;
1590
1591 // Finish the call path.
1592 llvm::BasicBlock *callBB = CGF.Builder.GetInsertBlock();
1593 if (callBB) {
1594 contBB = CGF.createBasicBlock("msgSend.cont");
1595 CGF.Builder.CreateBr(contBB);
1596 }
1597
1598 // Okay, start emitting the null-receiver block.
1599 CGF.EmitBlock(NullBB);
1600
1601 // Release any consumed arguments we've got.
1602 if (Method) {
1603 CallArgList::const_iterator I = CallArgs.begin();
1604 for (ObjCMethodDecl::param_const_iterator i = Method->param_begin(),
1605 e = Method->param_end(); i != e; ++i, ++I) {
1606 const ParmVarDecl *ParamDecl = (*i);
1607 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
1608 RValue RV = I->RV;
1609 assert(RV.isScalar() &&
1610 "NullReturnState::complete - arg not on object");
1611 CGF.EmitARCRelease(RV.getScalarVal(), ARCImpreciseLifetime);
1612 }
1613 }
1614 }
1615
1616 // The phi code below assumes that we haven't needed any control flow yet.
1617 assert(CGF.Builder.GetInsertBlock() == NullBB);
1618
1619 // If we've got a void return, just jump to the continuation block.
1620 if (result.isScalar() && resultType->isVoidType()) {
1621 // No jumps required if the message-send was noreturn.
1622 if (contBB) CGF.EmitBlock(contBB);
1623 return result;
1624 }
1625
1626 // If we've got a scalar return, build a phi.
1627 if (result.isScalar()) {
1628 // Derive the null-initialization value.
1629 llvm::Constant *null = CGF.CGM.EmitNullConstant(resultType);
1630
1631 // If no join is necessary, just flow out.
1632 if (!contBB) return RValue::get(null);
1633
1634 // Otherwise, build a phi.
1635 CGF.EmitBlock(contBB);
1636 llvm::PHINode *phi = CGF.Builder.CreatePHI(null->getType(), 2);
1637 phi->addIncoming(result.getScalarVal(), callBB);
1638 phi->addIncoming(null, NullBB);
1639 return RValue::get(phi);
1640 }
1641
1642 // If we've got an aggregate return, null the buffer out.
1643 // FIXME: maybe we should be doing things differently for all the
1644 // cases where the ABI has us returning (1) non-agg values in
1645 // memory or (2) agg values in registers.
1646 if (result.isAggregate()) {
1647 assert(result.isAggregate() && "null init of non-aggregate result?");
1648 CGF.EmitNullInitialization(result.getAggregateAddr(), resultType);
1649 if (contBB) CGF.EmitBlock(contBB);
1650 return result;
1651 }
1652
1653 // Complex types.
1654 CGF.EmitBlock(contBB);
1655 CodeGenFunction::ComplexPairTy callResult = result.getComplexVal();
1656
1657 // Find the scalar type and its zero value.
1658 llvm::Type *scalarTy = callResult.first->getType();
1659 llvm::Constant *scalarZero = llvm::Constant::getNullValue(scalarTy);
1660
1661 // Build phis for both coordinates.
1662 llvm::PHINode *real = CGF.Builder.CreatePHI(scalarTy, 2);
1663 real->addIncoming(callResult.first, callBB);
1664 real->addIncoming(scalarZero, NullBB);
1665 llvm::PHINode *imag = CGF.Builder.CreatePHI(scalarTy, 2);
1666 imag->addIncoming(callResult.second, callBB);
1667 imag->addIncoming(scalarZero, NullBB);
1668 return RValue::getComplex(real, imag);
1669 }
1670 };
1671
1672 } // end anonymous namespace
1673
1674 /* *** Helper Functions *** */
1675
1676 /// getConstantGEP() - Help routine to construct simple GEPs.
getConstantGEP(llvm::LLVMContext & VMContext,llvm::GlobalVariable * C,unsigned idx0,unsigned idx1)1677 static llvm::Constant *getConstantGEP(llvm::LLVMContext &VMContext,
1678 llvm::GlobalVariable *C, unsigned idx0,
1679 unsigned idx1) {
1680 llvm::Value *Idxs[] = {
1681 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1682 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
1683 };
1684 return llvm::ConstantExpr::getGetElementPtr(C->getValueType(), C, Idxs);
1685 }
1686
1687 /// hasObjCExceptionAttribute - Return true if this class or any super
1688 /// class has the __objc_exception__ attribute.
hasObjCExceptionAttribute(ASTContext & Context,const ObjCInterfaceDecl * OID)1689 static bool hasObjCExceptionAttribute(ASTContext &Context,
1690 const ObjCInterfaceDecl *OID) {
1691 if (OID->hasAttr<ObjCExceptionAttr>())
1692 return true;
1693 if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
1694 return hasObjCExceptionAttribute(Context, Super);
1695 return false;
1696 }
1697
1698 /* *** CGObjCMac Public Interface *** */
1699
CGObjCMac(CodeGen::CodeGenModule & cgm)1700 CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm),
1701 ObjCTypes(cgm) {
1702 ObjCABI = 1;
1703 EmitImageInfo();
1704 }
1705
1706 /// GetClass - Return a reference to the class for the given interface
1707 /// decl.
GetClass(CodeGenFunction & CGF,const ObjCInterfaceDecl * ID)1708 llvm::Value *CGObjCMac::GetClass(CodeGenFunction &CGF,
1709 const ObjCInterfaceDecl *ID) {
1710 return EmitClassRef(CGF, ID);
1711 }
1712
1713 /// GetSelector - Return the pointer to the unique'd string for this selector.
GetSelector(CodeGenFunction & CGF,Selector Sel,bool lval)1714 llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, Selector Sel,
1715 bool lval) {
1716 return EmitSelector(CGF, Sel, lval);
1717 }
GetSelector(CodeGenFunction & CGF,const ObjCMethodDecl * Method)1718 llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, const ObjCMethodDecl
1719 *Method) {
1720 return EmitSelector(CGF, Method->getSelector());
1721 }
1722
GetEHType(QualType T)1723 llvm::Constant *CGObjCMac::GetEHType(QualType T) {
1724 if (T->isObjCIdType() ||
1725 T->isObjCQualifiedIdType()) {
1726 return CGM.GetAddrOfRTTIDescriptor(
1727 CGM.getContext().getObjCIdRedefinitionType(), /*ForEH=*/true);
1728 }
1729 if (T->isObjCClassType() ||
1730 T->isObjCQualifiedClassType()) {
1731 return CGM.GetAddrOfRTTIDescriptor(
1732 CGM.getContext().getObjCClassRedefinitionType(), /*ForEH=*/true);
1733 }
1734 if (T->isObjCObjectPointerType())
1735 return CGM.GetAddrOfRTTIDescriptor(T, /*ForEH=*/true);
1736
1737 llvm_unreachable("asking for catch type for ObjC type in fragile runtime");
1738 }
1739
1740 /// Generate a constant CFString object.
1741 /*
1742 struct __builtin_CFString {
1743 const int *isa; // point to __CFConstantStringClassReference
1744 int flags;
1745 const char *str;
1746 long length;
1747 };
1748 */
1749
1750 /// or Generate a constant NSString object.
1751 /*
1752 struct __builtin_NSString {
1753 const int *isa; // point to __NSConstantStringClassReference
1754 const char *str;
1755 unsigned int length;
1756 };
1757 */
1758
GenerateConstantString(const StringLiteral * SL)1759 llvm::Constant *CGObjCCommonMac::GenerateConstantString(
1760 const StringLiteral *SL) {
1761 return (CGM.getLangOpts().NoConstantCFStrings == 0 ?
1762 CGM.GetAddrOfConstantCFString(SL) :
1763 CGM.GetAddrOfConstantString(SL));
1764 }
1765
1766 enum {
1767 kCFTaggedObjectID_Integer = (1 << 1) + 1
1768 };
1769
1770 /// Generates a message send where the super is the receiver. This is
1771 /// a message send to self with special delivery semantics indicating
1772 /// which class's method should be called.
1773 CodeGen::RValue
GenerateMessageSendSuper(CodeGen::CodeGenFunction & CGF,ReturnValueSlot Return,QualType ResultType,Selector Sel,const ObjCInterfaceDecl * Class,bool isCategoryImpl,llvm::Value * Receiver,bool IsClassMessage,const CodeGen::CallArgList & CallArgs,const ObjCMethodDecl * Method)1774 CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1775 ReturnValueSlot Return,
1776 QualType ResultType,
1777 Selector Sel,
1778 const ObjCInterfaceDecl *Class,
1779 bool isCategoryImpl,
1780 llvm::Value *Receiver,
1781 bool IsClassMessage,
1782 const CodeGen::CallArgList &CallArgs,
1783 const ObjCMethodDecl *Method) {
1784 // Create and init a super structure; this is a (receiver, class)
1785 // pair we will pass to objc_msgSendSuper.
1786 llvm::Value *ObjCSuper =
1787 CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super");
1788 llvm::Value *ReceiverAsObject =
1789 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
1790 CGF.Builder.CreateStore(
1791 ReceiverAsObject,
1792 CGF.Builder.CreateStructGEP(ObjCTypes.SuperTy, ObjCSuper, 0));
1793
1794 // If this is a class message the metaclass is passed as the target.
1795 llvm::Value *Target;
1796 if (IsClassMessage) {
1797 if (isCategoryImpl) {
1798 // Message sent to 'super' in a class method defined in a category
1799 // implementation requires an odd treatment.
1800 // If we are in a class method, we must retrieve the
1801 // _metaclass_ for the current class, pointed at by
1802 // the class's "isa" pointer. The following assumes that
1803 // isa" is the first ivar in a class (which it must be).
1804 Target = EmitClassRef(CGF, Class->getSuperClass());
1805 Target = CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, Target, 0);
1806 Target = CGF.Builder.CreateLoad(Target);
1807 } else {
1808 llvm::Constant *MetaClassPtr = EmitMetaClassRef(Class);
1809 llvm::Value *SuperPtr =
1810 CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, MetaClassPtr, 1);
1811 llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr);
1812 Target = Super;
1813 }
1814 } else if (isCategoryImpl)
1815 Target = EmitClassRef(CGF, Class->getSuperClass());
1816 else {
1817 llvm::Value *ClassPtr = EmitSuperClassRef(Class);
1818 ClassPtr = CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, ClassPtr, 1);
1819 Target = CGF.Builder.CreateLoad(ClassPtr);
1820 }
1821 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
1822 // ObjCTypes types.
1823 llvm::Type *ClassTy =
1824 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
1825 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
1826 CGF.Builder.CreateStore(
1827 Target, CGF.Builder.CreateStructGEP(ObjCTypes.SuperTy, ObjCSuper, 1));
1828 return EmitMessageSend(CGF, Return, ResultType,
1829 EmitSelector(CGF, Sel),
1830 ObjCSuper, ObjCTypes.SuperPtrCTy,
1831 true, CallArgs, Method, ObjCTypes);
1832 }
1833
1834 /// Generate code for a message send expression.
GenerateMessageSend(CodeGen::CodeGenFunction & CGF,ReturnValueSlot Return,QualType ResultType,Selector Sel,llvm::Value * Receiver,const CallArgList & CallArgs,const ObjCInterfaceDecl * Class,const ObjCMethodDecl * Method)1835 CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1836 ReturnValueSlot Return,
1837 QualType ResultType,
1838 Selector Sel,
1839 llvm::Value *Receiver,
1840 const CallArgList &CallArgs,
1841 const ObjCInterfaceDecl *Class,
1842 const ObjCMethodDecl *Method) {
1843 return EmitMessageSend(CGF, Return, ResultType,
1844 EmitSelector(CGF, Sel),
1845 Receiver, CGF.getContext().getObjCIdType(),
1846 false, CallArgs, Method, ObjCTypes);
1847 }
1848
1849 CodeGen::RValue
EmitMessageSend(CodeGen::CodeGenFunction & CGF,ReturnValueSlot Return,QualType ResultType,llvm::Value * Sel,llvm::Value * Arg0,QualType Arg0Ty,bool IsSuper,const CallArgList & CallArgs,const ObjCMethodDecl * Method,const ObjCCommonTypesHelper & ObjCTypes)1850 CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
1851 ReturnValueSlot Return,
1852 QualType ResultType,
1853 llvm::Value *Sel,
1854 llvm::Value *Arg0,
1855 QualType Arg0Ty,
1856 bool IsSuper,
1857 const CallArgList &CallArgs,
1858 const ObjCMethodDecl *Method,
1859 const ObjCCommonTypesHelper &ObjCTypes) {
1860 CallArgList ActualArgs;
1861 if (!IsSuper)
1862 Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy);
1863 ActualArgs.add(RValue::get(Arg0), Arg0Ty);
1864 ActualArgs.add(RValue::get(Sel), CGF.getContext().getObjCSelType());
1865 ActualArgs.addFrom(CallArgs);
1866
1867 // If we're calling a method, use the formal signature.
1868 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
1869
1870 if (Method)
1871 assert(CGM.getContext().getCanonicalType(Method->getReturnType()) ==
1872 CGM.getContext().getCanonicalType(ResultType) &&
1873 "Result type mismatch!");
1874
1875 NullReturnState nullReturn;
1876
1877 llvm::Constant *Fn = nullptr;
1878 if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
1879 if (!IsSuper) nullReturn.init(CGF, Arg0);
1880 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
1881 : ObjCTypes.getSendStretFn(IsSuper);
1882 } else if (CGM.ReturnTypeUsesFPRet(ResultType)) {
1883 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
1884 : ObjCTypes.getSendFpretFn(IsSuper);
1885 } else if (CGM.ReturnTypeUsesFP2Ret(ResultType)) {
1886 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
1887 : ObjCTypes.getSendFp2retFn(IsSuper);
1888 } else {
1889 // arm64 uses objc_msgSend for stret methods and yet null receiver check
1890 // must be made for it.
1891 if (!IsSuper && CGM.ReturnTypeUsesSRet(MSI.CallInfo))
1892 nullReturn.init(CGF, Arg0);
1893 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
1894 : ObjCTypes.getSendFn(IsSuper);
1895 }
1896
1897 bool requiresnullCheck = false;
1898 if (CGM.getLangOpts().ObjCAutoRefCount && Method)
1899 for (const auto *ParamDecl : Method->params()) {
1900 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
1901 if (!nullReturn.NullBB)
1902 nullReturn.init(CGF, Arg0);
1903 requiresnullCheck = true;
1904 break;
1905 }
1906 }
1907
1908 Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType);
1909 RValue rvalue = CGF.EmitCall(MSI.CallInfo, Fn, Return, ActualArgs);
1910 return nullReturn.complete(CGF, rvalue, ResultType, CallArgs,
1911 requiresnullCheck ? Method : nullptr);
1912 }
1913
GetGCAttrTypeForType(ASTContext & Ctx,QualType FQT)1914 static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT) {
1915 if (FQT.isObjCGCStrong())
1916 return Qualifiers::Strong;
1917
1918 if (FQT.isObjCGCWeak() || FQT.getObjCLifetime() == Qualifiers::OCL_Weak)
1919 return Qualifiers::Weak;
1920
1921 // check for __unsafe_unretained
1922 if (FQT.getObjCLifetime() == Qualifiers::OCL_ExplicitNone)
1923 return Qualifiers::GCNone;
1924
1925 if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
1926 return Qualifiers::Strong;
1927
1928 if (const PointerType *PT = FQT->getAs<PointerType>())
1929 return GetGCAttrTypeForType(Ctx, PT->getPointeeType());
1930
1931 return Qualifiers::GCNone;
1932 }
1933
BuildGCBlockLayout(CodeGenModule & CGM,const CGBlockInfo & blockInfo)1934 llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
1935 const CGBlockInfo &blockInfo) {
1936
1937 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
1938 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
1939 !CGM.getLangOpts().ObjCAutoRefCount)
1940 return nullPtr;
1941
1942 bool hasUnion = false;
1943 SkipIvars.clear();
1944 IvarsInfo.clear();
1945 unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(0);
1946 unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
1947
1948 // __isa is the first field in block descriptor and must assume by runtime's
1949 // convention that it is GC'able.
1950 IvarsInfo.push_back(GC_IVAR(0, 1));
1951
1952 const BlockDecl *blockDecl = blockInfo.getBlockDecl();
1953
1954 // Calculate the basic layout of the block structure.
1955 const llvm::StructLayout *layout =
1956 CGM.getDataLayout().getStructLayout(blockInfo.StructureType);
1957
1958 // Ignore the optional 'this' capture: C++ objects are not assumed
1959 // to be GC'ed.
1960
1961 // Walk the captured variables.
1962 for (const auto &CI : blockDecl->captures()) {
1963 const VarDecl *variable = CI.getVariable();
1964 QualType type = variable->getType();
1965
1966 const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
1967
1968 // Ignore constant captures.
1969 if (capture.isConstant()) continue;
1970
1971 uint64_t fieldOffset = layout->getElementOffset(capture.getIndex());
1972
1973 // __block variables are passed by their descriptor address.
1974 if (CI.isByRef()) {
1975 IvarsInfo.push_back(GC_IVAR(fieldOffset, /*size in words*/ 1));
1976 continue;
1977 }
1978
1979 assert(!type->isArrayType() && "array variable should not be caught");
1980 if (const RecordType *record = type->getAs<RecordType>()) {
1981 BuildAggrIvarRecordLayout(record, fieldOffset, true, hasUnion);
1982 continue;
1983 }
1984
1985 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), type);
1986 unsigned fieldSize = CGM.getContext().getTypeSize(type);
1987
1988 if (GCAttr == Qualifiers::Strong)
1989 IvarsInfo.push_back(GC_IVAR(fieldOffset,
1990 fieldSize / WordSizeInBits));
1991 else if (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak)
1992 SkipIvars.push_back(GC_IVAR(fieldOffset,
1993 fieldSize / ByteSizeInBits));
1994 }
1995
1996 if (IvarsInfo.empty())
1997 return nullPtr;
1998
1999 // Sort on byte position; captures might not be allocated in order,
2000 // and unions can do funny things.
2001 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
2002 llvm::array_pod_sort(SkipIvars.begin(), SkipIvars.end());
2003
2004 std::string BitMap;
2005 llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
2006 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
2007 printf("\n block variable layout for block: ");
2008 const unsigned char *s = (const unsigned char*)BitMap.c_str();
2009 for (unsigned i = 0, e = BitMap.size(); i < e; i++)
2010 if (!(s[i] & 0xf0))
2011 printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
2012 else
2013 printf("0x%x%s", s[i], s[i] != 0 ? ", " : "");
2014 printf("\n");
2015 }
2016
2017 return C;
2018 }
2019
2020 /// getBlockCaptureLifetime - This routine returns life time of the captured
2021 /// block variable for the purpose of block layout meta-data generation. FQT is
2022 /// the type of the variable captured in the block.
getBlockCaptureLifetime(QualType FQT,bool ByrefLayout)2023 Qualifiers::ObjCLifetime CGObjCCommonMac::getBlockCaptureLifetime(QualType FQT,
2024 bool ByrefLayout) {
2025 if (CGM.getLangOpts().ObjCAutoRefCount)
2026 return FQT.getObjCLifetime();
2027
2028 // MRR.
2029 if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
2030 return ByrefLayout ? Qualifiers::OCL_ExplicitNone : Qualifiers::OCL_Strong;
2031
2032 return Qualifiers::OCL_None;
2033 }
2034
UpdateRunSkipBlockVars(bool IsByref,Qualifiers::ObjCLifetime LifeTime,CharUnits FieldOffset,CharUnits FieldSize)2035 void CGObjCCommonMac::UpdateRunSkipBlockVars(bool IsByref,
2036 Qualifiers::ObjCLifetime LifeTime,
2037 CharUnits FieldOffset,
2038 CharUnits FieldSize) {
2039 // __block variables are passed by their descriptor address.
2040 if (IsByref)
2041 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset,
2042 FieldSize));
2043 else if (LifeTime == Qualifiers::OCL_Strong)
2044 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset,
2045 FieldSize));
2046 else if (LifeTime == Qualifiers::OCL_Weak)
2047 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset,
2048 FieldSize));
2049 else if (LifeTime == Qualifiers::OCL_ExplicitNone)
2050 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset,
2051 FieldSize));
2052 else
2053 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES,
2054 FieldOffset,
2055 FieldSize));
2056 }
2057
BuildRCRecordLayout(const llvm::StructLayout * RecLayout,const RecordDecl * RD,ArrayRef<const FieldDecl * > RecFields,CharUnits BytePos,bool & HasUnion,bool ByrefLayout)2058 void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
2059 const RecordDecl *RD,
2060 ArrayRef<const FieldDecl*> RecFields,
2061 CharUnits BytePos, bool &HasUnion,
2062 bool ByrefLayout) {
2063 bool IsUnion = (RD && RD->isUnion());
2064 CharUnits MaxUnionSize = CharUnits::Zero();
2065 const FieldDecl *MaxField = nullptr;
2066 const FieldDecl *LastFieldBitfieldOrUnnamed = nullptr;
2067 CharUnits MaxFieldOffset = CharUnits::Zero();
2068 CharUnits LastBitfieldOrUnnamedOffset = CharUnits::Zero();
2069
2070 if (RecFields.empty())
2071 return;
2072 unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
2073
2074 for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
2075 const FieldDecl *Field = RecFields[i];
2076 // Note that 'i' here is actually the field index inside RD of Field,
2077 // although this dependency is hidden.
2078 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2079 CharUnits FieldOffset =
2080 CGM.getContext().toCharUnitsFromBits(RL.getFieldOffset(i));
2081
2082 // Skip over unnamed or bitfields
2083 if (!Field->getIdentifier() || Field->isBitField()) {
2084 LastFieldBitfieldOrUnnamed = Field;
2085 LastBitfieldOrUnnamedOffset = FieldOffset;
2086 continue;
2087 }
2088
2089 LastFieldBitfieldOrUnnamed = nullptr;
2090 QualType FQT = Field->getType();
2091 if (FQT->isRecordType() || FQT->isUnionType()) {
2092 if (FQT->isUnionType())
2093 HasUnion = true;
2094
2095 BuildRCBlockVarRecordLayout(FQT->getAs<RecordType>(),
2096 BytePos + FieldOffset, HasUnion);
2097 continue;
2098 }
2099
2100 if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
2101 const ConstantArrayType *CArray =
2102 dyn_cast_or_null<ConstantArrayType>(Array);
2103 uint64_t ElCount = CArray->getSize().getZExtValue();
2104 assert(CArray && "only array with known element size is supported");
2105 FQT = CArray->getElementType();
2106 while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
2107 const ConstantArrayType *CArray =
2108 dyn_cast_or_null<ConstantArrayType>(Array);
2109 ElCount *= CArray->getSize().getZExtValue();
2110 FQT = CArray->getElementType();
2111 }
2112 if (FQT->isRecordType() && ElCount) {
2113 int OldIndex = RunSkipBlockVars.size() - 1;
2114 const RecordType *RT = FQT->getAs<RecordType>();
2115 BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset,
2116 HasUnion);
2117
2118 // Replicate layout information for each array element. Note that
2119 // one element is already done.
2120 uint64_t ElIx = 1;
2121 for (int FirstIndex = RunSkipBlockVars.size() - 1 ;ElIx < ElCount; ElIx++) {
2122 CharUnits Size = CGM.getContext().getTypeSizeInChars(RT);
2123 for (int i = OldIndex+1; i <= FirstIndex; ++i)
2124 RunSkipBlockVars.push_back(
2125 RUN_SKIP(RunSkipBlockVars[i].opcode,
2126 RunSkipBlockVars[i].block_var_bytepos + Size*ElIx,
2127 RunSkipBlockVars[i].block_var_size));
2128 }
2129 continue;
2130 }
2131 }
2132 CharUnits FieldSize = CGM.getContext().getTypeSizeInChars(Field->getType());
2133 if (IsUnion) {
2134 CharUnits UnionIvarSize = FieldSize;
2135 if (UnionIvarSize > MaxUnionSize) {
2136 MaxUnionSize = UnionIvarSize;
2137 MaxField = Field;
2138 MaxFieldOffset = FieldOffset;
2139 }
2140 } else {
2141 UpdateRunSkipBlockVars(false,
2142 getBlockCaptureLifetime(FQT, ByrefLayout),
2143 BytePos + FieldOffset,
2144 FieldSize);
2145 }
2146 }
2147
2148 if (LastFieldBitfieldOrUnnamed) {
2149 if (LastFieldBitfieldOrUnnamed->isBitField()) {
2150 // Last field was a bitfield. Must update the info.
2151 uint64_t BitFieldSize
2152 = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext());
2153 unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
2154 ((BitFieldSize % ByteSizeInBits) != 0);
2155 CharUnits Size = CharUnits::fromQuantity(UnsSize);
2156 Size += LastBitfieldOrUnnamedOffset;
2157 UpdateRunSkipBlockVars(false,
2158 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType(),
2159 ByrefLayout),
2160 BytePos + LastBitfieldOrUnnamedOffset,
2161 Size);
2162 } else {
2163 assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed");
2164 // Last field was unnamed. Must update skip info.
2165 CharUnits FieldSize
2166 = CGM.getContext().getTypeSizeInChars(LastFieldBitfieldOrUnnamed->getType());
2167 UpdateRunSkipBlockVars(false,
2168 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType(),
2169 ByrefLayout),
2170 BytePos + LastBitfieldOrUnnamedOffset,
2171 FieldSize);
2172 }
2173 }
2174
2175 if (MaxField)
2176 UpdateRunSkipBlockVars(false,
2177 getBlockCaptureLifetime(MaxField->getType(), ByrefLayout),
2178 BytePos + MaxFieldOffset,
2179 MaxUnionSize);
2180 }
2181
BuildRCBlockVarRecordLayout(const RecordType * RT,CharUnits BytePos,bool & HasUnion,bool ByrefLayout)2182 void CGObjCCommonMac::BuildRCBlockVarRecordLayout(const RecordType *RT,
2183 CharUnits BytePos,
2184 bool &HasUnion,
2185 bool ByrefLayout) {
2186 const RecordDecl *RD = RT->getDecl();
2187 SmallVector<const FieldDecl*, 16> Fields(RD->fields());
2188 llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
2189 const llvm::StructLayout *RecLayout =
2190 CGM.getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
2191
2192 BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);
2193 }
2194
2195 /// InlineLayoutInstruction - This routine produce an inline instruction for the
2196 /// block variable layout if it can. If not, it returns 0. Rules are as follow:
2197 /// If ((uintptr_t) layout) < (1 << 12), the layout is inline. In the 64bit world,
2198 /// an inline layout of value 0x0000000000000xyz is interpreted as follows:
2199 /// x captured object pointers of BLOCK_LAYOUT_STRONG. Followed by
2200 /// y captured object of BLOCK_LAYOUT_BYREF. Followed by
2201 /// z captured object of BLOCK_LAYOUT_WEAK. If any of the above is missing, zero
2202 /// replaces it. For example, 0x00000x00 means x BLOCK_LAYOUT_STRONG and no
2203 /// BLOCK_LAYOUT_BYREF and no BLOCK_LAYOUT_WEAK objects are captured.
InlineLayoutInstruction(SmallVectorImpl<unsigned char> & Layout)2204 uint64_t CGObjCCommonMac::InlineLayoutInstruction(
2205 SmallVectorImpl<unsigned char> &Layout) {
2206 uint64_t Result = 0;
2207 if (Layout.size() <= 3) {
2208 unsigned size = Layout.size();
2209 unsigned strong_word_count = 0, byref_word_count=0, weak_word_count=0;
2210 unsigned char inst;
2211 enum BLOCK_LAYOUT_OPCODE opcode ;
2212 switch (size) {
2213 case 3:
2214 inst = Layout[0];
2215 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2216 if (opcode == BLOCK_LAYOUT_STRONG)
2217 strong_word_count = (inst & 0xF)+1;
2218 else
2219 return 0;
2220 inst = Layout[1];
2221 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2222 if (opcode == BLOCK_LAYOUT_BYREF)
2223 byref_word_count = (inst & 0xF)+1;
2224 else
2225 return 0;
2226 inst = Layout[2];
2227 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2228 if (opcode == BLOCK_LAYOUT_WEAK)
2229 weak_word_count = (inst & 0xF)+1;
2230 else
2231 return 0;
2232 break;
2233
2234 case 2:
2235 inst = Layout[0];
2236 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2237 if (opcode == BLOCK_LAYOUT_STRONG) {
2238 strong_word_count = (inst & 0xF)+1;
2239 inst = Layout[1];
2240 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2241 if (opcode == BLOCK_LAYOUT_BYREF)
2242 byref_word_count = (inst & 0xF)+1;
2243 else if (opcode == BLOCK_LAYOUT_WEAK)
2244 weak_word_count = (inst & 0xF)+1;
2245 else
2246 return 0;
2247 }
2248 else if (opcode == BLOCK_LAYOUT_BYREF) {
2249 byref_word_count = (inst & 0xF)+1;
2250 inst = Layout[1];
2251 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2252 if (opcode == BLOCK_LAYOUT_WEAK)
2253 weak_word_count = (inst & 0xF)+1;
2254 else
2255 return 0;
2256 }
2257 else
2258 return 0;
2259 break;
2260
2261 case 1:
2262 inst = Layout[0];
2263 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2264 if (opcode == BLOCK_LAYOUT_STRONG)
2265 strong_word_count = (inst & 0xF)+1;
2266 else if (opcode == BLOCK_LAYOUT_BYREF)
2267 byref_word_count = (inst & 0xF)+1;
2268 else if (opcode == BLOCK_LAYOUT_WEAK)
2269 weak_word_count = (inst & 0xF)+1;
2270 else
2271 return 0;
2272 break;
2273
2274 default:
2275 return 0;
2276 }
2277
2278 // Cannot inline when any of the word counts is 15. Because this is one less
2279 // than the actual work count (so 15 means 16 actual word counts),
2280 // and we can only display 0 thru 15 word counts.
2281 if (strong_word_count == 16 || byref_word_count == 16 || weak_word_count == 16)
2282 return 0;
2283
2284 unsigned count =
2285 (strong_word_count != 0) + (byref_word_count != 0) + (weak_word_count != 0);
2286
2287 if (size == count) {
2288 if (strong_word_count)
2289 Result = strong_word_count;
2290 Result <<= 4;
2291 if (byref_word_count)
2292 Result += byref_word_count;
2293 Result <<= 4;
2294 if (weak_word_count)
2295 Result += weak_word_count;
2296 }
2297 }
2298 return Result;
2299 }
2300
getBitmapBlockLayout(bool ComputeByrefLayout)2301 llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(bool ComputeByrefLayout) {
2302 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
2303 if (RunSkipBlockVars.empty())
2304 return nullPtr;
2305 unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(0);
2306 unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
2307 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2308
2309 // Sort on byte position; captures might not be allocated in order,
2310 // and unions can do funny things.
2311 llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());
2312 SmallVector<unsigned char, 16> Layout;
2313
2314 unsigned size = RunSkipBlockVars.size();
2315 for (unsigned i = 0; i < size; i++) {
2316 enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
2317 CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
2318 CharUnits end_byte_pos = start_byte_pos;
2319 unsigned j = i+1;
2320 while (j < size) {
2321 if (opcode == RunSkipBlockVars[j].opcode) {
2322 end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
2323 i++;
2324 }
2325 else
2326 break;
2327 }
2328 CharUnits size_in_bytes =
2329 end_byte_pos - start_byte_pos + RunSkipBlockVars[j-1].block_var_size;
2330 if (j < size) {
2331 CharUnits gap =
2332 RunSkipBlockVars[j].block_var_bytepos -
2333 RunSkipBlockVars[j-1].block_var_bytepos - RunSkipBlockVars[j-1].block_var_size;
2334 size_in_bytes += gap;
2335 }
2336 CharUnits residue_in_bytes = CharUnits::Zero();
2337 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
2338 residue_in_bytes = size_in_bytes % WordSizeInBytes;
2339 size_in_bytes -= residue_in_bytes;
2340 opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
2341 }
2342
2343 unsigned size_in_words = size_in_bytes.getQuantity() / WordSizeInBytes;
2344 while (size_in_words >= 16) {
2345 // Note that value in imm. is one less that the actual
2346 // value. So, 0xf means 16 words follow!
2347 unsigned char inst = (opcode << 4) | 0xf;
2348 Layout.push_back(inst);
2349 size_in_words -= 16;
2350 }
2351 if (size_in_words > 0) {
2352 // Note that value in imm. is one less that the actual
2353 // value. So, we subtract 1 away!
2354 unsigned char inst = (opcode << 4) | (size_in_words-1);
2355 Layout.push_back(inst);
2356 }
2357 if (residue_in_bytes > CharUnits::Zero()) {
2358 unsigned char inst =
2359 (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) | (residue_in_bytes.getQuantity()-1);
2360 Layout.push_back(inst);
2361 }
2362 }
2363
2364 int e = Layout.size()-1;
2365 while (e >= 0) {
2366 unsigned char inst = Layout[e--];
2367 enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2368 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES || opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
2369 Layout.pop_back();
2370 else
2371 break;
2372 }
2373
2374 uint64_t Result = InlineLayoutInstruction(Layout);
2375 if (Result != 0) {
2376 // Block variable layout instruction has been inlined.
2377 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
2378 if (ComputeByrefLayout)
2379 printf("\n Inline instruction for BYREF variable layout: ");
2380 else
2381 printf("\n Inline instruction for block variable layout: ");
2382 printf("0x0%" PRIx64 "\n", Result);
2383 }
2384 if (WordSizeInBytes == 8) {
2385 const llvm::APInt Instruction(64, Result);
2386 return llvm::Constant::getIntegerValue(CGM.Int64Ty, Instruction);
2387 }
2388 else {
2389 const llvm::APInt Instruction(32, Result);
2390 return llvm::Constant::getIntegerValue(CGM.Int32Ty, Instruction);
2391 }
2392 }
2393
2394 unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
2395 Layout.push_back(inst);
2396 std::string BitMap;
2397 for (unsigned i = 0, e = Layout.size(); i != e; i++)
2398 BitMap += Layout[i];
2399
2400 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
2401 if (ComputeByrefLayout)
2402 printf("\n BYREF variable layout: ");
2403 else
2404 printf("\n block variable layout: ");
2405 for (unsigned i = 0, e = BitMap.size(); i != e; i++) {
2406 unsigned char inst = BitMap[i];
2407 enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2408 unsigned delta = 1;
2409 switch (opcode) {
2410 case BLOCK_LAYOUT_OPERATOR:
2411 printf("BL_OPERATOR:");
2412 delta = 0;
2413 break;
2414 case BLOCK_LAYOUT_NON_OBJECT_BYTES:
2415 printf("BL_NON_OBJECT_BYTES:");
2416 break;
2417 case BLOCK_LAYOUT_NON_OBJECT_WORDS:
2418 printf("BL_NON_OBJECT_WORD:");
2419 break;
2420 case BLOCK_LAYOUT_STRONG:
2421 printf("BL_STRONG:");
2422 break;
2423 case BLOCK_LAYOUT_BYREF:
2424 printf("BL_BYREF:");
2425 break;
2426 case BLOCK_LAYOUT_WEAK:
2427 printf("BL_WEAK:");
2428 break;
2429 case BLOCK_LAYOUT_UNRETAINED:
2430 printf("BL_UNRETAINED:");
2431 break;
2432 }
2433 // Actual value of word count is one more that what is in the imm.
2434 // field of the instruction
2435 printf("%d", (inst & 0xf) + delta);
2436 if (i < e-1)
2437 printf(", ");
2438 else
2439 printf("\n");
2440 }
2441 }
2442
2443 llvm::GlobalVariable *Entry = CreateMetadataVar(
2444 "OBJC_CLASS_NAME_",
2445 llvm::ConstantDataArray::getString(VMContext, BitMap, false),
2446 "__TEXT,__objc_classname,cstring_literals", 1, true);
2447 return getConstantGEP(VMContext, Entry, 0, 0);
2448 }
2449
BuildRCBlockLayout(CodeGenModule & CGM,const CGBlockInfo & blockInfo)2450 llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
2451 const CGBlockInfo &blockInfo) {
2452 assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
2453
2454 RunSkipBlockVars.clear();
2455 bool hasUnion = false;
2456
2457 unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(0);
2458 unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
2459 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2460
2461 const BlockDecl *blockDecl = blockInfo.getBlockDecl();
2462
2463 // Calculate the basic layout of the block structure.
2464 const llvm::StructLayout *layout =
2465 CGM.getDataLayout().getStructLayout(blockInfo.StructureType);
2466
2467 // Ignore the optional 'this' capture: C++ objects are not assumed
2468 // to be GC'ed.
2469 if (blockInfo.BlockHeaderForcedGapSize != CharUnits::Zero())
2470 UpdateRunSkipBlockVars(false, Qualifiers::OCL_None,
2471 blockInfo.BlockHeaderForcedGapOffset,
2472 blockInfo.BlockHeaderForcedGapSize);
2473 // Walk the captured variables.
2474 for (const auto &CI : blockDecl->captures()) {
2475 const VarDecl *variable = CI.getVariable();
2476 QualType type = variable->getType();
2477
2478 const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
2479
2480 // Ignore constant captures.
2481 if (capture.isConstant()) continue;
2482
2483 CharUnits fieldOffset =
2484 CharUnits::fromQuantity(layout->getElementOffset(capture.getIndex()));
2485
2486 assert(!type->isArrayType() && "array variable should not be caught");
2487 if (!CI.isByRef())
2488 if (const RecordType *record = type->getAs<RecordType>()) {
2489 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
2490 continue;
2491 }
2492 CharUnits fieldSize;
2493 if (CI.isByRef())
2494 fieldSize = CharUnits::fromQuantity(WordSizeInBytes);
2495 else
2496 fieldSize = CGM.getContext().getTypeSizeInChars(type);
2497 UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(type, false),
2498 fieldOffset, fieldSize);
2499 }
2500 return getBitmapBlockLayout(false);
2501 }
2502
2503
BuildByrefLayout(CodeGen::CodeGenModule & CGM,QualType T)2504 llvm::Constant *CGObjCCommonMac::BuildByrefLayout(CodeGen::CodeGenModule &CGM,
2505 QualType T) {
2506 assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
2507 assert(!T->isArrayType() && "__block array variable should not be caught");
2508 CharUnits fieldOffset;
2509 RunSkipBlockVars.clear();
2510 bool hasUnion = false;
2511 if (const RecordType *record = T->getAs<RecordType>()) {
2512 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion, true /*ByrefLayout */);
2513 llvm::Constant *Result = getBitmapBlockLayout(true);
2514 return Result;
2515 }
2516 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
2517 return nullPtr;
2518 }
2519
GenerateProtocolRef(CodeGenFunction & CGF,const ObjCProtocolDecl * PD)2520 llvm::Value *CGObjCMac::GenerateProtocolRef(CodeGenFunction &CGF,
2521 const ObjCProtocolDecl *PD) {
2522 // FIXME: I don't understand why gcc generates this, or where it is
2523 // resolved. Investigate. Its also wasteful to look this up over and over.
2524 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
2525
2526 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
2527 ObjCTypes.getExternalProtocolPtrTy());
2528 }
2529
GenerateProtocol(const ObjCProtocolDecl * PD)2530 void CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
2531 // FIXME: We shouldn't need this, the protocol decl should contain enough
2532 // information to tell us whether this was a declaration or a definition.
2533 DefinedProtocols.insert(PD->getIdentifier());
2534
2535 // If we have generated a forward reference to this protocol, emit
2536 // it now. Otherwise do nothing, the protocol objects are lazily
2537 // emitted.
2538 if (Protocols.count(PD->getIdentifier()))
2539 GetOrEmitProtocol(PD);
2540 }
2541
GetProtocolRef(const ObjCProtocolDecl * PD)2542 llvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
2543 if (DefinedProtocols.count(PD->getIdentifier()))
2544 return GetOrEmitProtocol(PD);
2545
2546 return GetOrEmitProtocolRef(PD);
2547 }
2548
2549 /*
2550 // Objective-C 1.0 extensions
2551 struct _objc_protocol {
2552 struct _objc_protocol_extension *isa;
2553 char *protocol_name;
2554 struct _objc_protocol_list *protocol_list;
2555 struct _objc__method_prototype_list *instance_methods;
2556 struct _objc__method_prototype_list *class_methods
2557 };
2558
2559 See EmitProtocolExtension().
2560 */
GetOrEmitProtocol(const ObjCProtocolDecl * PD)2561 llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
2562 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
2563
2564 // Early exit if a defining object has already been generated.
2565 if (Entry && Entry->hasInitializer())
2566 return Entry;
2567
2568 // Use the protocol definition, if there is one.
2569 if (const ObjCProtocolDecl *Def = PD->getDefinition())
2570 PD = Def;
2571
2572 // FIXME: I don't understand why gcc generates this, or where it is
2573 // resolved. Investigate. Its also wasteful to look this up over and over.
2574 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
2575
2576 // Construct method lists.
2577 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
2578 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
2579 std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt;
2580 for (const auto *MD : PD->instance_methods()) {
2581 llvm::Constant *C = GetMethodDescriptionConstant(MD);
2582 if (!C)
2583 return GetOrEmitProtocolRef(PD);
2584
2585 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
2586 OptInstanceMethods.push_back(C);
2587 OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
2588 } else {
2589 InstanceMethods.push_back(C);
2590 MethodTypesExt.push_back(GetMethodVarType(MD, true));
2591 }
2592 }
2593
2594 for (const auto *MD : PD->class_methods()) {
2595 llvm::Constant *C = GetMethodDescriptionConstant(MD);
2596 if (!C)
2597 return GetOrEmitProtocolRef(PD);
2598
2599 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
2600 OptClassMethods.push_back(C);
2601 OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
2602 } else {
2603 ClassMethods.push_back(C);
2604 MethodTypesExt.push_back(GetMethodVarType(MD, true));
2605 }
2606 }
2607
2608 MethodTypesExt.insert(MethodTypesExt.end(),
2609 OptMethodTypesExt.begin(), OptMethodTypesExt.end());
2610
2611 llvm::Constant *Values[] = {
2612 EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods,
2613 MethodTypesExt),
2614 GetClassName(PD->getObjCRuntimeNameAsString()),
2615 EmitProtocolList("OBJC_PROTOCOL_REFS_" + PD->getName(),
2616 PD->protocol_begin(), PD->protocol_end()),
2617 EmitMethodDescList("OBJC_PROTOCOL_INSTANCE_METHODS_" + PD->getName(),
2618 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2619 InstanceMethods),
2620 EmitMethodDescList("OBJC_PROTOCOL_CLASS_METHODS_" + PD->getName(),
2621 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2622 ClassMethods)};
2623 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
2624 Values);
2625
2626 if (Entry) {
2627 // Already created, update the initializer.
2628 assert(Entry->hasPrivateLinkage());
2629 Entry->setInitializer(Init);
2630 } else {
2631 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy,
2632 false, llvm::GlobalValue::PrivateLinkage,
2633 Init, "OBJC_PROTOCOL_" + PD->getName());
2634 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
2635 // FIXME: Is this necessary? Why only for protocol?
2636 Entry->setAlignment(4);
2637
2638 Protocols[PD->getIdentifier()] = Entry;
2639 }
2640 CGM.addCompilerUsedGlobal(Entry);
2641
2642 return Entry;
2643 }
2644
GetOrEmitProtocolRef(const ObjCProtocolDecl * PD)2645 llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
2646 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
2647
2648 if (!Entry) {
2649 // We use the initializer as a marker of whether this is a forward
2650 // reference or not. At module finalization we add the empty
2651 // contents for protocols which were referenced but never defined.
2652 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy,
2653 false, llvm::GlobalValue::PrivateLinkage,
2654 nullptr, "OBJC_PROTOCOL_" + PD->getName());
2655 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
2656 // FIXME: Is this necessary? Why only for protocol?
2657 Entry->setAlignment(4);
2658 }
2659
2660 return Entry;
2661 }
2662
2663 /*
2664 struct _objc_protocol_extension {
2665 uint32_t size;
2666 struct objc_method_description_list *optional_instance_methods;
2667 struct objc_method_description_list *optional_class_methods;
2668 struct objc_property_list *instance_properties;
2669 const char ** extendedMethodTypes;
2670 };
2671 */
2672 llvm::Constant *
EmitProtocolExtension(const ObjCProtocolDecl * PD,ArrayRef<llvm::Constant * > OptInstanceMethods,ArrayRef<llvm::Constant * > OptClassMethods,ArrayRef<llvm::Constant * > MethodTypesExt)2673 CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
2674 ArrayRef<llvm::Constant*> OptInstanceMethods,
2675 ArrayRef<llvm::Constant*> OptClassMethods,
2676 ArrayRef<llvm::Constant*> MethodTypesExt) {
2677 uint64_t Size =
2678 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
2679 llvm::Constant *Values[] = {
2680 llvm::ConstantInt::get(ObjCTypes.IntTy, Size),
2681 EmitMethodDescList("OBJC_PROTOCOL_INSTANCE_METHODS_OPT_" + PD->getName(),
2682 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2683 OptInstanceMethods),
2684 EmitMethodDescList("OBJC_PROTOCOL_CLASS_METHODS_OPT_" + PD->getName(),
2685 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2686 OptClassMethods),
2687 EmitPropertyList("OBJC_$_PROP_PROTO_LIST_" + PD->getName(), nullptr, PD,
2688 ObjCTypes),
2689 EmitProtocolMethodTypes("OBJC_PROTOCOL_METHOD_TYPES_" + PD->getName(),
2690 MethodTypesExt, ObjCTypes)};
2691
2692 // Return null if no extension bits are used.
2693 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
2694 Values[3]->isNullValue() && Values[4]->isNullValue())
2695 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
2696
2697 llvm::Constant *Init =
2698 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
2699
2700 // No special section, but goes in llvm.used
2701 return CreateMetadataVar("\01l_OBJC_PROTOCOLEXT_" + PD->getName(), Init,
2702 StringRef(), 0, true);
2703 }
2704
2705 /*
2706 struct objc_protocol_list {
2707 struct objc_protocol_list *next;
2708 long count;
2709 Protocol *list[];
2710 };
2711 */
2712 llvm::Constant *
EmitProtocolList(Twine Name,ObjCProtocolDecl::protocol_iterator begin,ObjCProtocolDecl::protocol_iterator end)2713 CGObjCMac::EmitProtocolList(Twine Name,
2714 ObjCProtocolDecl::protocol_iterator begin,
2715 ObjCProtocolDecl::protocol_iterator end) {
2716 SmallVector<llvm::Constant *, 16> ProtocolRefs;
2717
2718 for (; begin != end; ++begin)
2719 ProtocolRefs.push_back(GetProtocolRef(*begin));
2720
2721 // Just return null for empty protocol lists
2722 if (ProtocolRefs.empty())
2723 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2724
2725 // This list is null terminated.
2726 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
2727
2728 llvm::Constant *Values[3];
2729 // This field is only used by the runtime.
2730 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2731 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy,
2732 ProtocolRefs.size() - 1);
2733 Values[2] =
2734 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
2735 ProtocolRefs.size()),
2736 ProtocolRefs);
2737
2738 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2739 llvm::GlobalVariable *GV =
2740 CreateMetadataVar(Name, Init, "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2741 4, false);
2742 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
2743 }
2744
2745 void CGObjCCommonMac::
PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo *,16> & PropertySet,SmallVectorImpl<llvm::Constant * > & Properties,const Decl * Container,const ObjCProtocolDecl * Proto,const ObjCCommonTypesHelper & ObjCTypes)2746 PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*,16> &PropertySet,
2747 SmallVectorImpl<llvm::Constant *> &Properties,
2748 const Decl *Container,
2749 const ObjCProtocolDecl *Proto,
2750 const ObjCCommonTypesHelper &ObjCTypes) {
2751 for (const auto *P : Proto->protocols())
2752 PushProtocolProperties(PropertySet, Properties, Container, P, ObjCTypes);
2753 for (const auto *PD : Proto->properties()) {
2754 if (!PropertySet.insert(PD->getIdentifier()).second)
2755 continue;
2756 llvm::Constant *Prop[] = {
2757 GetPropertyName(PD->getIdentifier()),
2758 GetPropertyTypeString(PD, Container)
2759 };
2760 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop));
2761 }
2762 }
2763
2764 /*
2765 struct _objc_property {
2766 const char * const name;
2767 const char * const attributes;
2768 };
2769
2770 struct _objc_property_list {
2771 uint32_t entsize; // sizeof (struct _objc_property)
2772 uint32_t prop_count;
2773 struct _objc_property[prop_count];
2774 };
2775 */
EmitPropertyList(Twine Name,const Decl * Container,const ObjCContainerDecl * OCD,const ObjCCommonTypesHelper & ObjCTypes)2776 llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,
2777 const Decl *Container,
2778 const ObjCContainerDecl *OCD,
2779 const ObjCCommonTypesHelper &ObjCTypes) {
2780 SmallVector<llvm::Constant *, 16> Properties;
2781 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
2782 for (const auto *PD : OCD->properties()) {
2783 PropertySet.insert(PD->getIdentifier());
2784 llvm::Constant *Prop[] = {
2785 GetPropertyName(PD->getIdentifier()),
2786 GetPropertyTypeString(PD, Container)
2787 };
2788 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
2789 Prop));
2790 }
2791 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) {
2792 for (const auto *P : OID->all_referenced_protocols())
2793 PushProtocolProperties(PropertySet, Properties, Container, P, ObjCTypes);
2794 }
2795 else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) {
2796 for (const auto *P : CD->protocols())
2797 PushProtocolProperties(PropertySet, Properties, Container, P, ObjCTypes);
2798 }
2799
2800 // Return null for empty list.
2801 if (Properties.empty())
2802 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
2803
2804 unsigned PropertySize =
2805 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.PropertyTy);
2806 llvm::Constant *Values[3];
2807 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
2808 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
2809 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
2810 Properties.size());
2811 Values[2] = llvm::ConstantArray::get(AT, Properties);
2812 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2813
2814 llvm::GlobalVariable *GV =
2815 CreateMetadataVar(Name, Init,
2816 (ObjCABI == 2) ? "__DATA, __objc_const" :
2817 "__OBJC,__property,regular,no_dead_strip",
2818 (ObjCABI == 2) ? 8 : 4,
2819 true);
2820 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);
2821 }
2822
2823 llvm::Constant *
EmitProtocolMethodTypes(Twine Name,ArrayRef<llvm::Constant * > MethodTypes,const ObjCCommonTypesHelper & ObjCTypes)2824 CGObjCCommonMac::EmitProtocolMethodTypes(Twine Name,
2825 ArrayRef<llvm::Constant*> MethodTypes,
2826 const ObjCCommonTypesHelper &ObjCTypes) {
2827 // Return null for empty list.
2828 if (MethodTypes.empty())
2829 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
2830
2831 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
2832 MethodTypes.size());
2833 llvm::Constant *Init = llvm::ConstantArray::get(AT, MethodTypes);
2834
2835 llvm::GlobalVariable *GV = CreateMetadataVar(
2836 Name, Init, (ObjCABI == 2) ? "__DATA, __objc_const" : StringRef(),
2837 (ObjCABI == 2) ? 8 : 4, true);
2838 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.Int8PtrPtrTy);
2839 }
2840
2841 /*
2842 struct objc_method_description_list {
2843 int count;
2844 struct objc_method_description list[];
2845 };
2846 */
2847 llvm::Constant *
GetMethodDescriptionConstant(const ObjCMethodDecl * MD)2848 CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
2849 llvm::Constant *Desc[] = {
2850 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
2851 ObjCTypes.SelectorPtrTy),
2852 GetMethodVarType(MD)
2853 };
2854 if (!Desc[1])
2855 return nullptr;
2856
2857 return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
2858 Desc);
2859 }
2860
2861 llvm::Constant *
EmitMethodDescList(Twine Name,const char * Section,ArrayRef<llvm::Constant * > Methods)2862 CGObjCMac::EmitMethodDescList(Twine Name, const char *Section,
2863 ArrayRef<llvm::Constant*> Methods) {
2864 // Return null for empty list.
2865 if (Methods.empty())
2866 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
2867
2868 llvm::Constant *Values[2];
2869 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
2870 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
2871 Methods.size());
2872 Values[1] = llvm::ConstantArray::get(AT, Methods);
2873 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2874
2875 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
2876 return llvm::ConstantExpr::getBitCast(GV,
2877 ObjCTypes.MethodDescriptionListPtrTy);
2878 }
2879
2880 /*
2881 struct _objc_category {
2882 char *category_name;
2883 char *class_name;
2884 struct _objc_method_list *instance_methods;
2885 struct _objc_method_list *class_methods;
2886 struct _objc_protocol_list *protocols;
2887 uint32_t size; // <rdar://4585769>
2888 struct _objc_property_list *instance_properties;
2889 };
2890 */
GenerateCategory(const ObjCCategoryImplDecl * OCD)2891 void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
2892 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategoryTy);
2893
2894 // FIXME: This is poor design, the OCD should have a pointer to the category
2895 // decl. Additionally, note that Category can be null for the @implementation
2896 // w/o an @interface case. Sema should just create one for us as it does for
2897 // @implementation so everyone else can live life under a clear blue sky.
2898 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
2899 const ObjCCategoryDecl *Category =
2900 Interface->FindCategoryDeclaration(OCD->getIdentifier());
2901
2902 SmallString<256> ExtName;
2903 llvm::raw_svector_ostream(ExtName) << Interface->getName() << '_'
2904 << OCD->getName();
2905
2906 SmallVector<llvm::Constant *, 16> InstanceMethods, ClassMethods;
2907 for (const auto *I : OCD->instance_methods())
2908 // Instance methods should always be defined.
2909 InstanceMethods.push_back(GetMethodConstant(I));
2910
2911 for (const auto *I : OCD->class_methods())
2912 // Class methods should always be defined.
2913 ClassMethods.push_back(GetMethodConstant(I));
2914
2915 llvm::Constant *Values[7];
2916 Values[0] = GetClassName(OCD->getName());
2917 Values[1] = GetClassName(Interface->getObjCRuntimeNameAsString());
2918 LazySymbols.insert(Interface->getIdentifier());
2919 Values[2] = EmitMethodList("OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(),
2920 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2921 InstanceMethods);
2922 Values[3] = EmitMethodList("OBJC_CATEGORY_CLASS_METHODS_" + ExtName.str(),
2923 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2924 ClassMethods);
2925 if (Category) {
2926 Values[4] =
2927 EmitProtocolList("OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
2928 Category->protocol_begin(), Category->protocol_end());
2929 } else {
2930 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2931 }
2932 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
2933
2934 // If there is no category @interface then there can be no properties.
2935 if (Category) {
2936 Values[6] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
2937 OCD, Category, ObjCTypes);
2938 } else {
2939 Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
2940 }
2941
2942 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
2943 Values);
2944
2945 llvm::GlobalVariable *GV =
2946 CreateMetadataVar("OBJC_CATEGORY_" + ExtName.str(), Init,
2947 "__OBJC,__category,regular,no_dead_strip", 4, true);
2948 DefinedCategories.push_back(GV);
2949 DefinedCategoryNames.insert(ExtName.str());
2950 // method definition entries must be clear for next implementation.
2951 MethodDefinitions.clear();
2952 }
2953
2954 enum FragileClassFlags {
2955 FragileABI_Class_Factory = 0x00001,
2956 FragileABI_Class_Meta = 0x00002,
2957 FragileABI_Class_HasCXXStructors = 0x02000,
2958 FragileABI_Class_Hidden = 0x20000
2959 };
2960
2961 enum NonFragileClassFlags {
2962 /// Is a meta-class.
2963 NonFragileABI_Class_Meta = 0x00001,
2964
2965 /// Is a root class.
2966 NonFragileABI_Class_Root = 0x00002,
2967
2968 /// Has a C++ constructor and destructor.
2969 NonFragileABI_Class_HasCXXStructors = 0x00004,
2970
2971 /// Has hidden visibility.
2972 NonFragileABI_Class_Hidden = 0x00010,
2973
2974 /// Has the exception attribute.
2975 NonFragileABI_Class_Exception = 0x00020,
2976
2977 /// (Obsolete) ARC-specific: this class has a .release_ivars method
2978 NonFragileABI_Class_HasIvarReleaser = 0x00040,
2979
2980 /// Class implementation was compiled under ARC.
2981 NonFragileABI_Class_CompiledByARC = 0x00080,
2982
2983 /// Class has non-trivial destructors, but zero-initialization is okay.
2984 NonFragileABI_Class_HasCXXDestructorOnly = 0x00100
2985 };
2986
2987 /*
2988 struct _objc_class {
2989 Class isa;
2990 Class super_class;
2991 const char *name;
2992 long version;
2993 long info;
2994 long instance_size;
2995 struct _objc_ivar_list *ivars;
2996 struct _objc_method_list *methods;
2997 struct _objc_cache *cache;
2998 struct _objc_protocol_list *protocols;
2999 // Objective-C 1.0 extensions (<rdr://4585769>)
3000 const char *ivar_layout;
3001 struct _objc_class_ext *ext;
3002 };
3003
3004 See EmitClassExtension();
3005 */
GenerateClass(const ObjCImplementationDecl * ID)3006 void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
3007 DefinedSymbols.insert(ID->getIdentifier());
3008
3009 std::string ClassName = ID->getNameAsString();
3010 // FIXME: Gross
3011 ObjCInterfaceDecl *Interface =
3012 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
3013 llvm::Constant *Protocols =
3014 EmitProtocolList("OBJC_CLASS_PROTOCOLS_" + ID->getName(),
3015 Interface->all_referenced_protocol_begin(),
3016 Interface->all_referenced_protocol_end());
3017 unsigned Flags = FragileABI_Class_Factory;
3018 if (ID->hasNonZeroConstructors() || ID->hasDestructors())
3019 Flags |= FragileABI_Class_HasCXXStructors;
3020 unsigned Size =
3021 CGM.getContext().getASTObjCImplementationLayout(ID).getSize().getQuantity();
3022
3023 // FIXME: Set CXX-structors flag.
3024 if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
3025 Flags |= FragileABI_Class_Hidden;
3026
3027 SmallVector<llvm::Constant *, 16> InstanceMethods, ClassMethods;
3028 for (const auto *I : ID->instance_methods())
3029 // Instance methods should always be defined.
3030 InstanceMethods.push_back(GetMethodConstant(I));
3031
3032 for (const auto *I : ID->class_methods())
3033 // Class methods should always be defined.
3034 ClassMethods.push_back(GetMethodConstant(I));
3035
3036 for (const auto *PID : ID->property_impls()) {
3037 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
3038 ObjCPropertyDecl *PD = PID->getPropertyDecl();
3039
3040 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
3041 if (llvm::Constant *C = GetMethodConstant(MD))
3042 InstanceMethods.push_back(C);
3043 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
3044 if (llvm::Constant *C = GetMethodConstant(MD))
3045 InstanceMethods.push_back(C);
3046 }
3047 }
3048
3049 llvm::Constant *Values[12];
3050 Values[ 0] = EmitMetaClass(ID, Protocols, ClassMethods);
3051 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
3052 // Record a reference to the super class.
3053 LazySymbols.insert(Super->getIdentifier());
3054
3055 Values[ 1] =
3056 llvm::ConstantExpr::getBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3057 ObjCTypes.ClassPtrTy);
3058 } else {
3059 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
3060 }
3061 Values[ 2] = GetClassName(ID->getObjCRuntimeNameAsString());
3062 // Version is always 0.
3063 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
3064 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
3065 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
3066 Values[ 6] = EmitIvarList(ID, false);
3067 Values[7] = EmitMethodList("OBJC_INSTANCE_METHODS_" + ID->getName(),
3068 "__OBJC,__inst_meth,regular,no_dead_strip",
3069 InstanceMethods);
3070 // cache is always NULL.
3071 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
3072 Values[ 9] = Protocols;
3073 Values[10] = BuildIvarLayout(ID, true);
3074 Values[11] = EmitClassExtension(ID);
3075 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
3076 Values);
3077 std::string Name("OBJC_CLASS_");
3078 Name += ClassName;
3079 const char *Section = "__OBJC,__class,regular,no_dead_strip";
3080 // Check for a forward reference.
3081 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
3082 if (GV) {
3083 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3084 "Forward metaclass reference has incorrect type.");
3085 GV->setInitializer(Init);
3086 GV->setSection(Section);
3087 GV->setAlignment(4);
3088 CGM.addCompilerUsedGlobal(GV);
3089 } else
3090 GV = CreateMetadataVar(Name, Init, Section, 4, true);
3091 DefinedClasses.push_back(GV);
3092 ImplementedClasses.push_back(Interface);
3093 // method definition entries must be clear for next implementation.
3094 MethodDefinitions.clear();
3095 }
3096
EmitMetaClass(const ObjCImplementationDecl * ID,llvm::Constant * Protocols,ArrayRef<llvm::Constant * > Methods)3097 llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
3098 llvm::Constant *Protocols,
3099 ArrayRef<llvm::Constant*> Methods) {
3100 unsigned Flags = FragileABI_Class_Meta;
3101 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassTy);
3102
3103 if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
3104 Flags |= FragileABI_Class_Hidden;
3105
3106 llvm::Constant *Values[12];
3107 // The isa for the metaclass is the root of the hierarchy.
3108 const ObjCInterfaceDecl *Root = ID->getClassInterface();
3109 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
3110 Root = Super;
3111 Values[ 0] =
3112 llvm::ConstantExpr::getBitCast(GetClassName(Root->getObjCRuntimeNameAsString()),
3113 ObjCTypes.ClassPtrTy);
3114 // The super class for the metaclass is emitted as the name of the
3115 // super class. The runtime fixes this up to point to the
3116 // *metaclass* for the super class.
3117 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
3118 Values[ 1] =
3119 llvm::ConstantExpr::getBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3120 ObjCTypes.ClassPtrTy);
3121 } else {
3122 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
3123 }
3124 Values[ 2] = GetClassName(ID->getObjCRuntimeNameAsString());
3125 // Version is always 0.
3126 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
3127 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
3128 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
3129 Values[ 6] = EmitIvarList(ID, true);
3130 Values[7] =
3131 EmitMethodList("OBJC_CLASS_METHODS_" + ID->getNameAsString(),
3132 "__OBJC,__cls_meth,regular,no_dead_strip", Methods);
3133 // cache is always NULL.
3134 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
3135 Values[ 9] = Protocols;
3136 // ivar_layout for metaclass is always NULL.
3137 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
3138 // The class extension is always unused for metaclasses.
3139 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
3140 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
3141 Values);
3142
3143 std::string Name("OBJC_METACLASS_");
3144 Name += ID->getName();
3145
3146 // Check for a forward reference.
3147 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
3148 if (GV) {
3149 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3150 "Forward metaclass reference has incorrect type.");
3151 GV->setInitializer(Init);
3152 } else {
3153 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
3154 llvm::GlobalValue::PrivateLinkage,
3155 Init, Name);
3156 }
3157 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
3158 GV->setAlignment(4);
3159 CGM.addCompilerUsedGlobal(GV);
3160
3161 return GV;
3162 }
3163
EmitMetaClassRef(const ObjCInterfaceDecl * ID)3164 llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
3165 std::string Name = "OBJC_METACLASS_" + ID->getNameAsString();
3166
3167 // FIXME: Should we look these up somewhere other than the module. Its a bit
3168 // silly since we only generate these while processing an implementation, so
3169 // exactly one pointer would work if know when we entered/exitted an
3170 // implementation block.
3171
3172 // Check for an existing forward reference.
3173 // Previously, metaclass with internal linkage may have been defined.
3174 // pass 'true' as 2nd argument so it is returned.
3175 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
3176 if (!GV)
3177 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
3178 llvm::GlobalValue::PrivateLinkage, nullptr,
3179 Name);
3180
3181 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3182 "Forward metaclass reference has incorrect type.");
3183 return GV;
3184 }
3185
EmitSuperClassRef(const ObjCInterfaceDecl * ID)3186 llvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) {
3187 std::string Name = "OBJC_CLASS_" + ID->getNameAsString();
3188 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
3189
3190 if (!GV)
3191 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
3192 llvm::GlobalValue::PrivateLinkage, nullptr,
3193 Name);
3194
3195 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3196 "Forward class metadata reference has incorrect type.");
3197 return GV;
3198 }
3199
3200 /*
3201 struct objc_class_ext {
3202 uint32_t size;
3203 const char *weak_ivar_layout;
3204 struct _objc_property_list *properties;
3205 };
3206 */
3207 llvm::Constant *
EmitClassExtension(const ObjCImplementationDecl * ID)3208 CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
3209 uint64_t Size =
3210 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
3211
3212 llvm::Constant *Values[3];
3213 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
3214 Values[1] = BuildIvarLayout(ID, false);
3215 Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
3216 ID, ID->getClassInterface(), ObjCTypes);
3217
3218 // Return null if no extension bits are used.
3219 if (Values[1]->isNullValue() && Values[2]->isNullValue())
3220 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
3221
3222 llvm::Constant *Init =
3223 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
3224 return CreateMetadataVar("OBJC_CLASSEXT_" + ID->getName(), Init,
3225 "__OBJC,__class_ext,regular,no_dead_strip", 4, true);
3226 }
3227
3228 /*
3229 struct objc_ivar {
3230 char *ivar_name;
3231 char *ivar_type;
3232 int ivar_offset;
3233 };
3234
3235 struct objc_ivar_list {
3236 int ivar_count;
3237 struct objc_ivar list[count];
3238 };
3239 */
EmitIvarList(const ObjCImplementationDecl * ID,bool ForClass)3240 llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
3241 bool ForClass) {
3242 std::vector<llvm::Constant*> Ivars;
3243
3244 // When emitting the root class GCC emits ivar entries for the
3245 // actual class structure. It is not clear if we need to follow this
3246 // behavior; for now lets try and get away with not doing it. If so,
3247 // the cleanest solution would be to make up an ObjCInterfaceDecl
3248 // for the class.
3249 if (ForClass)
3250 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3251
3252 const ObjCInterfaceDecl *OID = ID->getClassInterface();
3253
3254 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
3255 IVD; IVD = IVD->getNextIvar()) {
3256 // Ignore unnamed bit-fields.
3257 if (!IVD->getDeclName())
3258 continue;
3259 llvm::Constant *Ivar[] = {
3260 GetMethodVarName(IVD->getIdentifier()),
3261 GetMethodVarType(IVD),
3262 llvm::ConstantInt::get(ObjCTypes.IntTy,
3263 ComputeIvarBaseOffset(CGM, OID, IVD))
3264 };
3265 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar));
3266 }
3267
3268 // Return null for empty list.
3269 if (Ivars.empty())
3270 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3271
3272 llvm::Constant *Values[2];
3273 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
3274 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
3275 Ivars.size());
3276 Values[1] = llvm::ConstantArray::get(AT, Ivars);
3277 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
3278
3279 llvm::GlobalVariable *GV;
3280 if (ForClass)
3281 GV =
3282 CreateMetadataVar("OBJC_CLASS_VARIABLES_" + ID->getName(), Init,
3283 "__OBJC,__class_vars,regular,no_dead_strip", 4, true);
3284 else
3285 GV = CreateMetadataVar("OBJC_INSTANCE_VARIABLES_" + ID->getName(), Init,
3286 "__OBJC,__instance_vars,regular,no_dead_strip", 4,
3287 true);
3288 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
3289 }
3290
3291 /*
3292 struct objc_method {
3293 SEL method_name;
3294 char *method_types;
3295 void *method;
3296 };
3297
3298 struct objc_method_list {
3299 struct objc_method_list *obsolete;
3300 int count;
3301 struct objc_method methods_list[count];
3302 };
3303 */
3304
3305 /// GetMethodConstant - Return a struct objc_method constant for the
3306 /// given method if it has been defined. The result is null if the
3307 /// method has not been defined. The return value has type MethodPtrTy.
GetMethodConstant(const ObjCMethodDecl * MD)3308 llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) {
3309 llvm::Function *Fn = GetMethodDefinition(MD);
3310 if (!Fn)
3311 return nullptr;
3312
3313 llvm::Constant *Method[] = {
3314 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
3315 ObjCTypes.SelectorPtrTy),
3316 GetMethodVarType(MD),
3317 llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy)
3318 };
3319 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
3320 }
3321
EmitMethodList(Twine Name,const char * Section,ArrayRef<llvm::Constant * > Methods)3322 llvm::Constant *CGObjCMac::EmitMethodList(Twine Name,
3323 const char *Section,
3324 ArrayRef<llvm::Constant*> Methods) {
3325 // Return null for empty list.
3326 if (Methods.empty())
3327 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
3328
3329 llvm::Constant *Values[3];
3330 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
3331 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
3332 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
3333 Methods.size());
3334 Values[2] = llvm::ConstantArray::get(AT, Methods);
3335 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
3336
3337 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
3338 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy);
3339 }
3340
GenerateMethod(const ObjCMethodDecl * OMD,const ObjCContainerDecl * CD)3341 llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,
3342 const ObjCContainerDecl *CD) {
3343 SmallString<256> Name;
3344 GetNameForMethod(OMD, CD, Name);
3345
3346 CodeGenTypes &Types = CGM.getTypes();
3347 llvm::FunctionType *MethodTy =
3348 Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
3349 llvm::Function *Method =
3350 llvm::Function::Create(MethodTy,
3351 llvm::GlobalValue::InternalLinkage,
3352 Name.str(),
3353 &CGM.getModule());
3354 MethodDefinitions.insert(std::make_pair(OMD, Method));
3355
3356 return Method;
3357 }
3358
CreateMetadataVar(Twine Name,llvm::Constant * Init,StringRef Section,unsigned Align,bool AddToUsed)3359 llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
3360 llvm::Constant *Init,
3361 StringRef Section,
3362 unsigned Align,
3363 bool AddToUsed) {
3364 llvm::Type *Ty = Init->getType();
3365 llvm::GlobalVariable *GV =
3366 new llvm::GlobalVariable(CGM.getModule(), Ty, false,
3367 llvm::GlobalValue::PrivateLinkage, Init, Name);
3368 if (!Section.empty())
3369 GV->setSection(Section);
3370 if (Align)
3371 GV->setAlignment(Align);
3372 if (AddToUsed)
3373 CGM.addCompilerUsedGlobal(GV);
3374 return GV;
3375 }
3376
ModuleInitFunction()3377 llvm::Function *CGObjCMac::ModuleInitFunction() {
3378 // Abuse this interface function as a place to finalize.
3379 FinishModule();
3380 return nullptr;
3381 }
3382
GetPropertyGetFunction()3383 llvm::Constant *CGObjCMac::GetPropertyGetFunction() {
3384 return ObjCTypes.getGetPropertyFn();
3385 }
3386
GetPropertySetFunction()3387 llvm::Constant *CGObjCMac::GetPropertySetFunction() {
3388 return ObjCTypes.getSetPropertyFn();
3389 }
3390
GetOptimizedPropertySetFunction(bool atomic,bool copy)3391 llvm::Constant *CGObjCMac::GetOptimizedPropertySetFunction(bool atomic,
3392 bool copy) {
3393 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
3394 }
3395
GetGetStructFunction()3396 llvm::Constant *CGObjCMac::GetGetStructFunction() {
3397 return ObjCTypes.getCopyStructFn();
3398 }
GetSetStructFunction()3399 llvm::Constant *CGObjCMac::GetSetStructFunction() {
3400 return ObjCTypes.getCopyStructFn();
3401 }
3402
GetCppAtomicObjectGetFunction()3403 llvm::Constant *CGObjCMac::GetCppAtomicObjectGetFunction() {
3404 return ObjCTypes.getCppAtomicObjectFunction();
3405 }
GetCppAtomicObjectSetFunction()3406 llvm::Constant *CGObjCMac::GetCppAtomicObjectSetFunction() {
3407 return ObjCTypes.getCppAtomicObjectFunction();
3408 }
3409
EnumerationMutationFunction()3410 llvm::Constant *CGObjCMac::EnumerationMutationFunction() {
3411 return ObjCTypes.getEnumerationMutationFn();
3412 }
3413
EmitTryStmt(CodeGenFunction & CGF,const ObjCAtTryStmt & S)3414 void CGObjCMac::EmitTryStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S) {
3415 return EmitTryOrSynchronizedStmt(CGF, S);
3416 }
3417
EmitSynchronizedStmt(CodeGenFunction & CGF,const ObjCAtSynchronizedStmt & S)3418 void CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF,
3419 const ObjCAtSynchronizedStmt &S) {
3420 return EmitTryOrSynchronizedStmt(CGF, S);
3421 }
3422
3423 namespace {
3424 struct PerformFragileFinally : EHScopeStack::Cleanup {
3425 const Stmt &S;
3426 llvm::Value *SyncArgSlot;
3427 llvm::Value *CallTryExitVar;
3428 llvm::Value *ExceptionData;
3429 ObjCTypesHelper &ObjCTypes;
PerformFragileFinally__anon0ea151f90311::PerformFragileFinally3430 PerformFragileFinally(const Stmt *S,
3431 llvm::Value *SyncArgSlot,
3432 llvm::Value *CallTryExitVar,
3433 llvm::Value *ExceptionData,
3434 ObjCTypesHelper *ObjCTypes)
3435 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
3436 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
3437
Emit__anon0ea151f90311::PerformFragileFinally3438 void Emit(CodeGenFunction &CGF, Flags flags) override {
3439 // Check whether we need to call objc_exception_try_exit.
3440 // In optimized code, this branch will always be folded.
3441 llvm::BasicBlock *FinallyCallExit =
3442 CGF.createBasicBlock("finally.call_exit");
3443 llvm::BasicBlock *FinallyNoCallExit =
3444 CGF.createBasicBlock("finally.no_call_exit");
3445 CGF.Builder.CreateCondBr(CGF.Builder.CreateLoad(CallTryExitVar),
3446 FinallyCallExit, FinallyNoCallExit);
3447
3448 CGF.EmitBlock(FinallyCallExit);
3449 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryExitFn(),
3450 ExceptionData);
3451
3452 CGF.EmitBlock(FinallyNoCallExit);
3453
3454 if (isa<ObjCAtTryStmt>(S)) {
3455 if (const ObjCAtFinallyStmt* FinallyStmt =
3456 cast<ObjCAtTryStmt>(S).getFinallyStmt()) {
3457 // Don't try to do the @finally if this is an EH cleanup.
3458 if (flags.isForEHCleanup()) return;
3459
3460 // Save the current cleanup destination in case there's
3461 // control flow inside the finally statement.
3462 llvm::Value *CurCleanupDest =
3463 CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot());
3464
3465 CGF.EmitStmt(FinallyStmt->getFinallyBody());
3466
3467 if (CGF.HaveInsertPoint()) {
3468 CGF.Builder.CreateStore(CurCleanupDest,
3469 CGF.getNormalCleanupDestSlot());
3470 } else {
3471 // Currently, the end of the cleanup must always exist.
3472 CGF.EnsureInsertPoint();
3473 }
3474 }
3475 } else {
3476 // Emit objc_sync_exit(expr); as finally's sole statement for
3477 // @synchronized.
3478 llvm::Value *SyncArg = CGF.Builder.CreateLoad(SyncArgSlot);
3479 CGF.EmitNounwindRuntimeCall(ObjCTypes.getSyncExitFn(), SyncArg);
3480 }
3481 }
3482 };
3483
3484 class FragileHazards {
3485 CodeGenFunction &CGF;
3486 SmallVector<llvm::Value*, 20> Locals;
3487 llvm::DenseSet<llvm::BasicBlock*> BlocksBeforeTry;
3488
3489 llvm::InlineAsm *ReadHazard;
3490 llvm::InlineAsm *WriteHazard;
3491
3492 llvm::FunctionType *GetAsmFnType();
3493
3494 void collectLocals();
3495 void emitReadHazard(CGBuilderTy &Builder);
3496
3497 public:
3498 FragileHazards(CodeGenFunction &CGF);
3499
3500 void emitWriteHazard();
3501 void emitHazardsInNewBlocks();
3502 };
3503 }
3504
3505 /// Create the fragile-ABI read and write hazards based on the current
3506 /// state of the function, which is presumed to be immediately prior
3507 /// to a @try block. These hazards are used to maintain correct
3508 /// semantics in the face of optimization and the fragile ABI's
3509 /// cavalier use of setjmp/longjmp.
FragileHazards(CodeGenFunction & CGF)3510 FragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) {
3511 collectLocals();
3512
3513 if (Locals.empty()) return;
3514
3515 // Collect all the blocks in the function.
3516 for (llvm::Function::iterator
3517 I = CGF.CurFn->begin(), E = CGF.CurFn->end(); I != E; ++I)
3518 BlocksBeforeTry.insert(&*I);
3519
3520 llvm::FunctionType *AsmFnTy = GetAsmFnType();
3521
3522 // Create a read hazard for the allocas. This inhibits dead-store
3523 // optimizations and forces the values to memory. This hazard is
3524 // inserted before any 'throwing' calls in the protected scope to
3525 // reflect the possibility that the variables might be read from the
3526 // catch block if the call throws.
3527 {
3528 std::string Constraint;
3529 for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
3530 if (I) Constraint += ',';
3531 Constraint += "*m";
3532 }
3533
3534 ReadHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
3535 }
3536
3537 // Create a write hazard for the allocas. This inhibits folding
3538 // loads across the hazard. This hazard is inserted at the
3539 // beginning of the catch path to reflect the possibility that the
3540 // variables might have been written within the protected scope.
3541 {
3542 std::string Constraint;
3543 for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
3544 if (I) Constraint += ',';
3545 Constraint += "=*m";
3546 }
3547
3548 WriteHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
3549 }
3550 }
3551
3552 /// Emit a write hazard at the current location.
emitWriteHazard()3553 void FragileHazards::emitWriteHazard() {
3554 if (Locals.empty()) return;
3555
3556 CGF.EmitNounwindRuntimeCall(WriteHazard, Locals);
3557 }
3558
emitReadHazard(CGBuilderTy & Builder)3559 void FragileHazards::emitReadHazard(CGBuilderTy &Builder) {
3560 assert(!Locals.empty());
3561 llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
3562 call->setDoesNotThrow();
3563 call->setCallingConv(CGF.getRuntimeCC());
3564 }
3565
3566 /// Emit read hazards in all the protected blocks, i.e. all the blocks
3567 /// which have been inserted since the beginning of the try.
emitHazardsInNewBlocks()3568 void FragileHazards::emitHazardsInNewBlocks() {
3569 if (Locals.empty()) return;
3570
3571 CGBuilderTy Builder(CGF.getLLVMContext());
3572
3573 // Iterate through all blocks, skipping those prior to the try.
3574 for (llvm::Function::iterator
3575 FI = CGF.CurFn->begin(), FE = CGF.CurFn->end(); FI != FE; ++FI) {
3576 llvm::BasicBlock &BB = *FI;
3577 if (BlocksBeforeTry.count(&BB)) continue;
3578
3579 // Walk through all the calls in the block.
3580 for (llvm::BasicBlock::iterator
3581 BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
3582 llvm::Instruction &I = *BI;
3583
3584 // Ignore instructions that aren't non-intrinsic calls.
3585 // These are the only calls that can possibly call longjmp.
3586 if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I)) continue;
3587 if (isa<llvm::IntrinsicInst>(I))
3588 continue;
3589
3590 // Ignore call sites marked nounwind. This may be questionable,
3591 // since 'nounwind' doesn't necessarily mean 'does not call longjmp'.
3592 llvm::CallSite CS(&I);
3593 if (CS.doesNotThrow()) continue;
3594
3595 // Insert a read hazard before the call. This will ensure that
3596 // any writes to the locals are performed before making the
3597 // call. If the call throws, then this is sufficient to
3598 // guarantee correctness as long as it doesn't also write to any
3599 // locals.
3600 Builder.SetInsertPoint(&BB, BI);
3601 emitReadHazard(Builder);
3602 }
3603 }
3604 }
3605
addIfPresent(llvm::DenseSet<llvm::Value * > & S,llvm::Value * V)3606 static void addIfPresent(llvm::DenseSet<llvm::Value*> &S, llvm::Value *V) {
3607 if (V) S.insert(V);
3608 }
3609
collectLocals()3610 void FragileHazards::collectLocals() {
3611 // Compute a set of allocas to ignore.
3612 llvm::DenseSet<llvm::Value*> AllocasToIgnore;
3613 addIfPresent(AllocasToIgnore, CGF.ReturnValue);
3614 addIfPresent(AllocasToIgnore, CGF.NormalCleanupDest);
3615
3616 // Collect all the allocas currently in the function. This is
3617 // probably way too aggressive.
3618 llvm::BasicBlock &Entry = CGF.CurFn->getEntryBlock();
3619 for (llvm::BasicBlock::iterator
3620 I = Entry.begin(), E = Entry.end(); I != E; ++I)
3621 if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
3622 Locals.push_back(&*I);
3623 }
3624
GetAsmFnType()3625 llvm::FunctionType *FragileHazards::GetAsmFnType() {
3626 SmallVector<llvm::Type *, 16> tys(Locals.size());
3627 for (unsigned i = 0, e = Locals.size(); i != e; ++i)
3628 tys[i] = Locals[i]->getType();
3629 return llvm::FunctionType::get(CGF.VoidTy, tys, false);
3630 }
3631
3632 /*
3633
3634 Objective-C setjmp-longjmp (sjlj) Exception Handling
3635 --
3636
3637 A catch buffer is a setjmp buffer plus:
3638 - a pointer to the exception that was caught
3639 - a pointer to the previous exception data buffer
3640 - two pointers of reserved storage
3641 Therefore catch buffers form a stack, with a pointer to the top
3642 of the stack kept in thread-local storage.
3643
3644 objc_exception_try_enter pushes a catch buffer onto the EH stack.
3645 objc_exception_try_exit pops the given catch buffer, which is
3646 required to be the top of the EH stack.
3647 objc_exception_throw pops the top of the EH stack, writes the
3648 thrown exception into the appropriate field, and longjmps
3649 to the setjmp buffer. It crashes the process (with a printf
3650 and an abort()) if there are no catch buffers on the stack.
3651 objc_exception_extract just reads the exception pointer out of the
3652 catch buffer.
3653
3654 There's no reason an implementation couldn't use a light-weight
3655 setjmp here --- something like __builtin_setjmp, but API-compatible
3656 with the heavyweight setjmp. This will be more important if we ever
3657 want to implement correct ObjC/C++ exception interactions for the
3658 fragile ABI.
3659
3660 Note that for this use of setjmp/longjmp to be correct, we may need
3661 to mark some local variables volatile: if a non-volatile local
3662 variable is modified between the setjmp and the longjmp, it has
3663 indeterminate value. For the purposes of LLVM IR, it may be
3664 sufficient to make loads and stores within the @try (to variables
3665 declared outside the @try) volatile. This is necessary for
3666 optimized correctness, but is not currently being done; this is
3667 being tracked as rdar://problem/8160285
3668
3669 The basic framework for a @try-catch-finally is as follows:
3670 {
3671 objc_exception_data d;
3672 id _rethrow = null;
3673 bool _call_try_exit = true;
3674
3675 objc_exception_try_enter(&d);
3676 if (!setjmp(d.jmp_buf)) {
3677 ... try body ...
3678 } else {
3679 // exception path
3680 id _caught = objc_exception_extract(&d);
3681
3682 // enter new try scope for handlers
3683 if (!setjmp(d.jmp_buf)) {
3684 ... match exception and execute catch blocks ...
3685
3686 // fell off end, rethrow.
3687 _rethrow = _caught;
3688 ... jump-through-finally to finally_rethrow ...
3689 } else {
3690 // exception in catch block
3691 _rethrow = objc_exception_extract(&d);
3692 _call_try_exit = false;
3693 ... jump-through-finally to finally_rethrow ...
3694 }
3695 }
3696 ... jump-through-finally to finally_end ...
3697
3698 finally:
3699 if (_call_try_exit)
3700 objc_exception_try_exit(&d);
3701
3702 ... finally block ....
3703 ... dispatch to finally destination ...
3704
3705 finally_rethrow:
3706 objc_exception_throw(_rethrow);
3707
3708 finally_end:
3709 }
3710
3711 This framework differs slightly from the one gcc uses, in that gcc
3712 uses _rethrow to determine if objc_exception_try_exit should be called
3713 and if the object should be rethrown. This breaks in the face of
3714 throwing nil and introduces unnecessary branches.
3715
3716 We specialize this framework for a few particular circumstances:
3717
3718 - If there are no catch blocks, then we avoid emitting the second
3719 exception handling context.
3720
3721 - If there is a catch-all catch block (i.e. @catch(...) or @catch(id
3722 e)) we avoid emitting the code to rethrow an uncaught exception.
3723
3724 - FIXME: If there is no @finally block we can do a few more
3725 simplifications.
3726
3727 Rethrows and Jumps-Through-Finally
3728 --
3729
3730 '@throw;' is supported by pushing the currently-caught exception
3731 onto ObjCEHStack while the @catch blocks are emitted.
3732
3733 Branches through the @finally block are handled with an ordinary
3734 normal cleanup. We do not register an EH cleanup; fragile-ABI ObjC
3735 exceptions are not compatible with C++ exceptions, and this is
3736 hardly the only place where this will go wrong.
3737
3738 @synchronized(expr) { stmt; } is emitted as if it were:
3739 id synch_value = expr;
3740 objc_sync_enter(synch_value);
3741 @try { stmt; } @finally { objc_sync_exit(synch_value); }
3742 */
3743
EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction & CGF,const Stmt & S)3744 void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
3745 const Stmt &S) {
3746 bool isTry = isa<ObjCAtTryStmt>(S);
3747
3748 // A destination for the fall-through edges of the catch handlers to
3749 // jump to.
3750 CodeGenFunction::JumpDest FinallyEnd =
3751 CGF.getJumpDestInCurrentScope("finally.end");
3752
3753 // A destination for the rethrow edge of the catch handlers to jump
3754 // to.
3755 CodeGenFunction::JumpDest FinallyRethrow =
3756 CGF.getJumpDestInCurrentScope("finally.rethrow");
3757
3758 // For @synchronized, call objc_sync_enter(sync.expr). The
3759 // evaluation of the expression must occur before we enter the
3760 // @synchronized. We can't avoid a temp here because we need the
3761 // value to be preserved. If the backend ever does liveness
3762 // correctly after setjmp, this will be unnecessary.
3763 llvm::Value *SyncArgSlot = nullptr;
3764 if (!isTry) {
3765 llvm::Value *SyncArg =
3766 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
3767 SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
3768 CGF.EmitNounwindRuntimeCall(ObjCTypes.getSyncEnterFn(), SyncArg);
3769
3770 SyncArgSlot = CGF.CreateTempAlloca(SyncArg->getType(), "sync.arg");
3771 CGF.Builder.CreateStore(SyncArg, SyncArgSlot);
3772 }
3773
3774 // Allocate memory for the setjmp buffer. This needs to be kept
3775 // live throughout the try and catch blocks.
3776 llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy,
3777 "exceptiondata.ptr");
3778
3779 // Create the fragile hazards. Note that this will not capture any
3780 // of the allocas required for exception processing, but will
3781 // capture the current basic block (which extends all the way to the
3782 // setjmp call) as "before the @try".
3783 FragileHazards Hazards(CGF);
3784
3785 // Create a flag indicating whether the cleanup needs to call
3786 // objc_exception_try_exit. This is true except when
3787 // - no catches match and we're branching through the cleanup
3788 // just to rethrow the exception, or
3789 // - a catch matched and we're falling out of the catch handler.
3790 // The setjmp-safety rule here is that we should always store to this
3791 // variable in a place that dominates the branch through the cleanup
3792 // without passing through any setjmps.
3793 llvm::Value *CallTryExitVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(),
3794 "_call_try_exit");
3795
3796 // A slot containing the exception to rethrow. Only needed when we
3797 // have both a @catch and a @finally.
3798 llvm::Value *PropagatingExnVar = nullptr;
3799
3800 // Push a normal cleanup to leave the try scope.
3801 CGF.EHStack.pushCleanup<PerformFragileFinally>(NormalAndEHCleanup, &S,
3802 SyncArgSlot,
3803 CallTryExitVar,
3804 ExceptionData,
3805 &ObjCTypes);
3806
3807 // Enter a try block:
3808 // - Call objc_exception_try_enter to push ExceptionData on top of
3809 // the EH stack.
3810 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(),
3811 ExceptionData);
3812
3813 // - Call setjmp on the exception data buffer.
3814 llvm::Constant *Zero = llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0);
3815 llvm::Value *GEPIndexes[] = { Zero, Zero, Zero };
3816 llvm::Value *SetJmpBuffer = CGF.Builder.CreateGEP(
3817 ObjCTypes.ExceptionDataTy, ExceptionData, GEPIndexes, "setjmp_buffer");
3818 llvm::CallInst *SetJmpResult = CGF.EmitNounwindRuntimeCall(
3819 ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result");
3820 SetJmpResult->setCanReturnTwice();
3821
3822 // If setjmp returned 0, enter the protected block; otherwise,
3823 // branch to the handler.
3824 llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
3825 llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
3826 llvm::Value *DidCatch =
3827 CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
3828 CGF.Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
3829
3830 // Emit the protected block.
3831 CGF.EmitBlock(TryBlock);
3832 CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
3833 CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
3834 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
3835
3836 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.Builder.saveAndClearIP();
3837
3838 // Emit the exception handler block.
3839 CGF.EmitBlock(TryHandler);
3840
3841 // Don't optimize loads of the in-scope locals across this point.
3842 Hazards.emitWriteHazard();
3843
3844 // For a @synchronized (or a @try with no catches), just branch
3845 // through the cleanup to the rethrow block.
3846 if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
3847 // Tell the cleanup not to re-pop the exit.
3848 CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
3849 CGF.EmitBranchThroughCleanup(FinallyRethrow);
3850
3851 // Otherwise, we have to match against the caught exceptions.
3852 } else {
3853 // Retrieve the exception object. We may emit multiple blocks but
3854 // nothing can cross this so the value is already in SSA form.
3855 llvm::CallInst *Caught =
3856 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(),
3857 ExceptionData, "caught");
3858
3859 // Push the exception to rethrow onto the EH value stack for the
3860 // benefit of any @throws in the handlers.
3861 CGF.ObjCEHValueStack.push_back(Caught);
3862
3863 const ObjCAtTryStmt* AtTryStmt = cast<ObjCAtTryStmt>(&S);
3864
3865 bool HasFinally = (AtTryStmt->getFinallyStmt() != nullptr);
3866
3867 llvm::BasicBlock *CatchBlock = nullptr;
3868 llvm::BasicBlock *CatchHandler = nullptr;
3869 if (HasFinally) {
3870 // Save the currently-propagating exception before
3871 // objc_exception_try_enter clears the exception slot.
3872 PropagatingExnVar = CGF.CreateTempAlloca(Caught->getType(),
3873 "propagating_exception");
3874 CGF.Builder.CreateStore(Caught, PropagatingExnVar);
3875
3876 // Enter a new exception try block (in case a @catch block
3877 // throws an exception).
3878 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(),
3879 ExceptionData);
3880
3881 llvm::CallInst *SetJmpResult =
3882 CGF.EmitNounwindRuntimeCall(ObjCTypes.getSetJmpFn(),
3883 SetJmpBuffer, "setjmp.result");
3884 SetJmpResult->setCanReturnTwice();
3885
3886 llvm::Value *Threw =
3887 CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
3888
3889 CatchBlock = CGF.createBasicBlock("catch");
3890 CatchHandler = CGF.createBasicBlock("catch_for_catch");
3891 CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
3892
3893 CGF.EmitBlock(CatchBlock);
3894 }
3895
3896 CGF.Builder.CreateStore(CGF.Builder.getInt1(HasFinally), CallTryExitVar);
3897
3898 // Handle catch list. As a special case we check if everything is
3899 // matched and avoid generating code for falling off the end if
3900 // so.
3901 bool AllMatched = false;
3902 for (unsigned I = 0, N = AtTryStmt->getNumCatchStmts(); I != N; ++I) {
3903 const ObjCAtCatchStmt *CatchStmt = AtTryStmt->getCatchStmt(I);
3904
3905 const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
3906 const ObjCObjectPointerType *OPT = nullptr;
3907
3908 // catch(...) always matches.
3909 if (!CatchParam) {
3910 AllMatched = true;
3911 } else {
3912 OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>();
3913
3914 // catch(id e) always matches under this ABI, since only
3915 // ObjC exceptions end up here in the first place.
3916 // FIXME: For the time being we also match id<X>; this should
3917 // be rejected by Sema instead.
3918 if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()))
3919 AllMatched = true;
3920 }
3921
3922 // If this is a catch-all, we don't need to test anything.
3923 if (AllMatched) {
3924 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
3925
3926 if (CatchParam) {
3927 CGF.EmitAutoVarDecl(*CatchParam);
3928 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
3929
3930 // These types work out because ConvertType(id) == i8*.
3931 CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(CatchParam));
3932 }
3933
3934 CGF.EmitStmt(CatchStmt->getCatchBody());
3935
3936 // The scope of the catch variable ends right here.
3937 CatchVarCleanups.ForceCleanup();
3938
3939 CGF.EmitBranchThroughCleanup(FinallyEnd);
3940 break;
3941 }
3942
3943 assert(OPT && "Unexpected non-object pointer type in @catch");
3944 const ObjCObjectType *ObjTy = OPT->getObjectType();
3945
3946 // FIXME: @catch (Class c) ?
3947 ObjCInterfaceDecl *IDecl = ObjTy->getInterface();
3948 assert(IDecl && "Catch parameter must have Objective-C type!");
3949
3950 // Check if the @catch block matches the exception object.
3951 llvm::Value *Class = EmitClassRef(CGF, IDecl);
3952
3953 llvm::Value *matchArgs[] = { Class, Caught };
3954 llvm::CallInst *Match =
3955 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionMatchFn(),
3956 matchArgs, "match");
3957
3958 llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("match");
3959 llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch.next");
3960
3961 CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"),
3962 MatchedBlock, NextCatchBlock);
3963
3964 // Emit the @catch block.
3965 CGF.EmitBlock(MatchedBlock);
3966
3967 // Collect any cleanups for the catch variable. The scope lasts until
3968 // the end of the catch body.
3969 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
3970
3971 CGF.EmitAutoVarDecl(*CatchParam);
3972 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
3973
3974 // Initialize the catch variable.
3975 llvm::Value *Tmp =
3976 CGF.Builder.CreateBitCast(Caught,
3977 CGF.ConvertType(CatchParam->getType()));
3978 CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(CatchParam));
3979
3980 CGF.EmitStmt(CatchStmt->getCatchBody());
3981
3982 // We're done with the catch variable.
3983 CatchVarCleanups.ForceCleanup();
3984
3985 CGF.EmitBranchThroughCleanup(FinallyEnd);
3986
3987 CGF.EmitBlock(NextCatchBlock);
3988 }
3989
3990 CGF.ObjCEHValueStack.pop_back();
3991
3992 // If nothing wanted anything to do with the caught exception,
3993 // kill the extract call.
3994 if (Caught->use_empty())
3995 Caught->eraseFromParent();
3996
3997 if (!AllMatched)
3998 CGF.EmitBranchThroughCleanup(FinallyRethrow);
3999
4000 if (HasFinally) {
4001 // Emit the exception handler for the @catch blocks.
4002 CGF.EmitBlock(CatchHandler);
4003
4004 // In theory we might now need a write hazard, but actually it's
4005 // unnecessary because there's no local-accessing code between
4006 // the try's write hazard and here.
4007 //Hazards.emitWriteHazard();
4008
4009 // Extract the new exception and save it to the
4010 // propagating-exception slot.
4011 assert(PropagatingExnVar);
4012 llvm::CallInst *NewCaught =
4013 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(),
4014 ExceptionData, "caught");
4015 CGF.Builder.CreateStore(NewCaught, PropagatingExnVar);
4016
4017 // Don't pop the catch handler; the throw already did.
4018 CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
4019 CGF.EmitBranchThroughCleanup(FinallyRethrow);
4020 }
4021 }
4022
4023 // Insert read hazards as required in the new blocks.
4024 Hazards.emitHazardsInNewBlocks();
4025
4026 // Pop the cleanup.
4027 CGF.Builder.restoreIP(TryFallthroughIP);
4028 if (CGF.HaveInsertPoint())
4029 CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
4030 CGF.PopCleanupBlock();
4031 CGF.EmitBlock(FinallyEnd.getBlock(), true);
4032
4033 // Emit the rethrow block.
4034 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
4035 CGF.EmitBlock(FinallyRethrow.getBlock(), true);
4036 if (CGF.HaveInsertPoint()) {
4037 // If we have a propagating-exception variable, check it.
4038 llvm::Value *PropagatingExn;
4039 if (PropagatingExnVar) {
4040 PropagatingExn = CGF.Builder.CreateLoad(PropagatingExnVar);
4041
4042 // Otherwise, just look in the buffer for the exception to throw.
4043 } else {
4044 llvm::CallInst *Caught =
4045 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(),
4046 ExceptionData);
4047 PropagatingExn = Caught;
4048 }
4049
4050 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionThrowFn(),
4051 PropagatingExn);
4052 CGF.Builder.CreateUnreachable();
4053 }
4054
4055 CGF.Builder.restoreIP(SavedIP);
4056 }
4057
EmitThrowStmt(CodeGen::CodeGenFunction & CGF,const ObjCAtThrowStmt & S,bool ClearInsertionPoint)4058 void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
4059 const ObjCAtThrowStmt &S,
4060 bool ClearInsertionPoint) {
4061 llvm::Value *ExceptionAsObject;
4062
4063 if (const Expr *ThrowExpr = S.getThrowExpr()) {
4064 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
4065 ExceptionAsObject =
4066 CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
4067 } else {
4068 assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
4069 "Unexpected rethrow outside @catch block.");
4070 ExceptionAsObject = CGF.ObjCEHValueStack.back();
4071 }
4072
4073 CGF.EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
4074 ->setDoesNotReturn();
4075 CGF.Builder.CreateUnreachable();
4076
4077 // Clear the insertion point to indicate we are in unreachable code.
4078 if (ClearInsertionPoint)
4079 CGF.Builder.ClearInsertionPoint();
4080 }
4081
4082 /// EmitObjCWeakRead - Code gen for loading value of a __weak
4083 /// object: objc_read_weak (id *src)
4084 ///
EmitObjCWeakRead(CodeGen::CodeGenFunction & CGF,llvm::Value * AddrWeakObj)4085 llvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
4086 llvm::Value *AddrWeakObj) {
4087 llvm::Type* DestTy =
4088 cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
4089 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj,
4090 ObjCTypes.PtrObjectPtrTy);
4091 llvm::Value *read_weak =
4092 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
4093 AddrWeakObj, "weakread");
4094 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
4095 return read_weak;
4096 }
4097
4098 /// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
4099 /// objc_assign_weak (id src, id *dst)
4100 ///
EmitObjCWeakAssign(CodeGen::CodeGenFunction & CGF,llvm::Value * src,llvm::Value * dst)4101 void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
4102 llvm::Value *src, llvm::Value *dst) {
4103 llvm::Type * SrcTy = src->getType();
4104 if (!isa<llvm::PointerType>(SrcTy)) {
4105 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4106 assert(Size <= 8 && "does not support size > 8");
4107 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4108 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4109 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4110 }
4111 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4112 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4113 llvm::Value *args[] = { src, dst };
4114 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
4115 args, "weakassign");
4116 return;
4117 }
4118
4119 /// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
4120 /// objc_assign_global (id src, id *dst)
4121 ///
EmitObjCGlobalAssign(CodeGen::CodeGenFunction & CGF,llvm::Value * src,llvm::Value * dst,bool threadlocal)4122 void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
4123 llvm::Value *src, llvm::Value *dst,
4124 bool threadlocal) {
4125 llvm::Type * SrcTy = src->getType();
4126 if (!isa<llvm::PointerType>(SrcTy)) {
4127 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4128 assert(Size <= 8 && "does not support size > 8");
4129 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4130 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4131 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4132 }
4133 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4134 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4135 llvm::Value *args[] = { src, dst };
4136 if (!threadlocal)
4137 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
4138 args, "globalassign");
4139 else
4140 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
4141 args, "threadlocalassign");
4142 return;
4143 }
4144
4145 /// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
4146 /// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset)
4147 ///
EmitObjCIvarAssign(CodeGen::CodeGenFunction & CGF,llvm::Value * src,llvm::Value * dst,llvm::Value * ivarOffset)4148 void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
4149 llvm::Value *src, llvm::Value *dst,
4150 llvm::Value *ivarOffset) {
4151 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL");
4152 llvm::Type * SrcTy = src->getType();
4153 if (!isa<llvm::PointerType>(SrcTy)) {
4154 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4155 assert(Size <= 8 && "does not support size > 8");
4156 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4157 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4158 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4159 }
4160 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4161 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4162 llvm::Value *args[] = { src, dst, ivarOffset };
4163 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
4164 return;
4165 }
4166
4167 /// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
4168 /// objc_assign_strongCast (id src, id *dst)
4169 ///
EmitObjCStrongCastAssign(CodeGen::CodeGenFunction & CGF,llvm::Value * src,llvm::Value * dst)4170 void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
4171 llvm::Value *src, llvm::Value *dst) {
4172 llvm::Type * SrcTy = src->getType();
4173 if (!isa<llvm::PointerType>(SrcTy)) {
4174 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4175 assert(Size <= 8 && "does not support size > 8");
4176 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4177 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4178 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4179 }
4180 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4181 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4182 llvm::Value *args[] = { src, dst };
4183 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
4184 args, "weakassign");
4185 return;
4186 }
4187
EmitGCMemmoveCollectable(CodeGen::CodeGenFunction & CGF,llvm::Value * DestPtr,llvm::Value * SrcPtr,llvm::Value * size)4188 void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
4189 llvm::Value *DestPtr,
4190 llvm::Value *SrcPtr,
4191 llvm::Value *size) {
4192 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
4193 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
4194 llvm::Value *args[] = { DestPtr, SrcPtr, size };
4195 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
4196 }
4197
4198 /// EmitObjCValueForIvar - Code Gen for ivar reference.
4199 ///
EmitObjCValueForIvar(CodeGen::CodeGenFunction & CGF,QualType ObjectTy,llvm::Value * BaseValue,const ObjCIvarDecl * Ivar,unsigned CVRQualifiers)4200 LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
4201 QualType ObjectTy,
4202 llvm::Value *BaseValue,
4203 const ObjCIvarDecl *Ivar,
4204 unsigned CVRQualifiers) {
4205 const ObjCInterfaceDecl *ID =
4206 ObjectTy->getAs<ObjCObjectType>()->getInterface();
4207 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4208 EmitIvarOffset(CGF, ID, Ivar));
4209 }
4210
EmitIvarOffset(CodeGen::CodeGenFunction & CGF,const ObjCInterfaceDecl * Interface,const ObjCIvarDecl * Ivar)4211 llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
4212 const ObjCInterfaceDecl *Interface,
4213 const ObjCIvarDecl *Ivar) {
4214 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
4215 return llvm::ConstantInt::get(
4216 CGM.getTypes().ConvertType(CGM.getContext().LongTy),
4217 Offset);
4218 }
4219
4220 /* *** Private Interface *** */
4221
4222 /// EmitImageInfo - Emit the image info marker used to encode some module
4223 /// level information.
4224 ///
4225 /// See: <rdr://4810609&4810587&4810587>
4226 /// struct IMAGE_INFO {
4227 /// unsigned version;
4228 /// unsigned flags;
4229 /// };
4230 enum ImageInfoFlags {
4231 eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.
4232 eImageInfo_GarbageCollected = (1 << 1),
4233 eImageInfo_GCOnly = (1 << 2),
4234 eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.
4235
4236 // A flag indicating that the module has no instances of a @synthesize of a
4237 // superclass variable. <rdar://problem/6803242>
4238 eImageInfo_CorrectedSynthesize = (1 << 4), // This flag is no longer set by clang.
4239 eImageInfo_ImageIsSimulated = (1 << 5)
4240 };
4241
EmitImageInfo()4242 void CGObjCCommonMac::EmitImageInfo() {
4243 unsigned version = 0; // Version is unused?
4244 const char *Section = (ObjCABI == 1) ?
4245 "__OBJC, __image_info,regular" :
4246 "__DATA, __objc_imageinfo, regular, no_dead_strip";
4247
4248 // Generate module-level named metadata to convey this information to the
4249 // linker and code-gen.
4250 llvm::Module &Mod = CGM.getModule();
4251
4252 // Add the ObjC ABI version to the module flags.
4253 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version", ObjCABI);
4254 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version",
4255 version);
4256 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section",
4257 llvm::MDString::get(VMContext,Section));
4258
4259 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
4260 // Non-GC overrides those files which specify GC.
4261 Mod.addModuleFlag(llvm::Module::Override,
4262 "Objective-C Garbage Collection", (uint32_t)0);
4263 } else {
4264 // Add the ObjC garbage collection value.
4265 Mod.addModuleFlag(llvm::Module::Error,
4266 "Objective-C Garbage Collection",
4267 eImageInfo_GarbageCollected);
4268
4269 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
4270 // Add the ObjC GC Only value.
4271 Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only",
4272 eImageInfo_GCOnly);
4273
4274 // Require that GC be specified and set to eImageInfo_GarbageCollected.
4275 llvm::Metadata *Ops[2] = {
4276 llvm::MDString::get(VMContext, "Objective-C Garbage Collection"),
4277 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
4278 llvm::Type::getInt32Ty(VMContext), eImageInfo_GarbageCollected))};
4279 Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only",
4280 llvm::MDNode::get(VMContext, Ops));
4281 }
4282 }
4283
4284 // Indicate whether we're compiling this to run on a simulator.
4285 const llvm::Triple &Triple = CGM.getTarget().getTriple();
4286 if (Triple.isiOS() &&
4287 (Triple.getArch() == llvm::Triple::x86 ||
4288 Triple.getArch() == llvm::Triple::x86_64))
4289 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated",
4290 eImageInfo_ImageIsSimulated);
4291 }
4292
4293 // struct objc_module {
4294 // unsigned long version;
4295 // unsigned long size;
4296 // const char *name;
4297 // Symtab symtab;
4298 // };
4299
4300 // FIXME: Get from somewhere
4301 static const int ModuleVersion = 7;
4302
EmitModuleInfo()4303 void CGObjCMac::EmitModuleInfo() {
4304 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy);
4305
4306 llvm::Constant *Values[] = {
4307 llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion),
4308 llvm::ConstantInt::get(ObjCTypes.LongTy, Size),
4309 // This used to be the filename, now it is unused. <rdr://4327263>
4310 GetClassName(StringRef("")),
4311 EmitModuleSymbols()
4312 };
4313 CreateMetadataVar("OBJC_MODULES",
4314 llvm::ConstantStruct::get(ObjCTypes.ModuleTy, Values),
4315 "__OBJC,__module_info,regular,no_dead_strip", 4, true);
4316 }
4317
EmitModuleSymbols()4318 llvm::Constant *CGObjCMac::EmitModuleSymbols() {
4319 unsigned NumClasses = DefinedClasses.size();
4320 unsigned NumCategories = DefinedCategories.size();
4321
4322 // Return null if no symbols were defined.
4323 if (!NumClasses && !NumCategories)
4324 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
4325
4326 llvm::Constant *Values[5];
4327 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
4328 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
4329 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
4330 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
4331
4332 // The runtime expects exactly the list of defined classes followed
4333 // by the list of defined categories, in a single array.
4334 SmallVector<llvm::Constant*, 8> Symbols(NumClasses + NumCategories);
4335 for (unsigned i=0; i<NumClasses; i++) {
4336 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
4337 assert(ID);
4338 if (ObjCImplementationDecl *IMP = ID->getImplementation())
4339 // We are implementing a weak imported interface. Give it external linkage
4340 if (ID->isWeakImported() && !IMP->isWeakImported())
4341 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
4342
4343 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
4344 ObjCTypes.Int8PtrTy);
4345 }
4346 for (unsigned i=0; i<NumCategories; i++)
4347 Symbols[NumClasses + i] =
4348 llvm::ConstantExpr::getBitCast(DefinedCategories[i],
4349 ObjCTypes.Int8PtrTy);
4350
4351 Values[4] =
4352 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
4353 Symbols.size()),
4354 Symbols);
4355
4356 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
4357
4358 llvm::GlobalVariable *GV = CreateMetadataVar(
4359 "OBJC_SYMBOLS", Init, "__OBJC,__symbols,regular,no_dead_strip", 4, true);
4360 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
4361 }
4362
EmitClassRefFromId(CodeGenFunction & CGF,IdentifierInfo * II)4363 llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,
4364 IdentifierInfo *II) {
4365 LazySymbols.insert(II);
4366
4367 llvm::GlobalVariable *&Entry = ClassReferences[II];
4368
4369 if (!Entry) {
4370 llvm::Constant *Casted =
4371 llvm::ConstantExpr::getBitCast(GetClassName(II->getName()),
4372 ObjCTypes.ClassPtrTy);
4373 Entry = CreateMetadataVar(
4374 "OBJC_CLASS_REFERENCES_", Casted,
4375 "__OBJC,__cls_refs,literal_pointers,no_dead_strip", 4, true);
4376 }
4377
4378 return CGF.Builder.CreateLoad(Entry);
4379 }
4380
EmitClassRef(CodeGenFunction & CGF,const ObjCInterfaceDecl * ID)4381 llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF,
4382 const ObjCInterfaceDecl *ID) {
4383 return EmitClassRefFromId(CGF, ID->getIdentifier());
4384 }
4385
EmitNSAutoreleasePoolClassRef(CodeGenFunction & CGF)4386 llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
4387 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
4388 return EmitClassRefFromId(CGF, II);
4389 }
4390
EmitSelector(CodeGenFunction & CGF,Selector Sel,bool lvalue)4391 llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel,
4392 bool lvalue) {
4393 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
4394
4395 if (!Entry) {
4396 llvm::Constant *Casted =
4397 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
4398 ObjCTypes.SelectorPtrTy);
4399 Entry = CreateMetadataVar(
4400 "OBJC_SELECTOR_REFERENCES_", Casted,
4401 "__OBJC,__message_refs,literal_pointers,no_dead_strip", 4, true);
4402 Entry->setExternallyInitialized(true);
4403 }
4404
4405 if (lvalue)
4406 return Entry;
4407 return CGF.Builder.CreateLoad(Entry);
4408 }
4409
GetClassName(StringRef RuntimeName)4410 llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
4411 llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
4412 if (!Entry)
4413 Entry = CreateMetadataVar(
4414 "OBJC_CLASS_NAME_",
4415 llvm::ConstantDataArray::getString(VMContext, RuntimeName),
4416 ((ObjCABI == 2) ? "__TEXT,__objc_classname,cstring_literals"
4417 : "__TEXT,__cstring,cstring_literals"),
4418 1, true);
4419 return getConstantGEP(VMContext, Entry, 0, 0);
4420 }
4421
GetMethodDefinition(const ObjCMethodDecl * MD)4422 llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
4423 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator
4424 I = MethodDefinitions.find(MD);
4425 if (I != MethodDefinitions.end())
4426 return I->second;
4427
4428 return nullptr;
4429 }
4430
4431 /// GetIvarLayoutName - Returns a unique constant for the given
4432 /// ivar layout bitmap.
GetIvarLayoutName(IdentifierInfo * Ident,const ObjCCommonTypesHelper & ObjCTypes)4433 llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
4434 const ObjCCommonTypesHelper &ObjCTypes) {
4435 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
4436 }
4437
BuildAggrIvarRecordLayout(const RecordType * RT,unsigned int BytePos,bool ForStrongLayout,bool & HasUnion)4438 void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT,
4439 unsigned int BytePos,
4440 bool ForStrongLayout,
4441 bool &HasUnion) {
4442 const RecordDecl *RD = RT->getDecl();
4443 // FIXME - Use iterator.
4444 SmallVector<const FieldDecl*, 16> Fields(RD->fields());
4445 llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
4446 const llvm::StructLayout *RecLayout =
4447 CGM.getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
4448
4449 BuildAggrIvarLayout(nullptr, RecLayout, RD, Fields, BytePos, ForStrongLayout,
4450 HasUnion);
4451 }
4452
BuildAggrIvarLayout(const ObjCImplementationDecl * OI,const llvm::StructLayout * Layout,const RecordDecl * RD,ArrayRef<const FieldDecl * > RecFields,unsigned int BytePos,bool ForStrongLayout,bool & HasUnion)4453 void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
4454 const llvm::StructLayout *Layout,
4455 const RecordDecl *RD,
4456 ArrayRef<const FieldDecl*> RecFields,
4457 unsigned int BytePos, bool ForStrongLayout,
4458 bool &HasUnion) {
4459 bool IsUnion = (RD && RD->isUnion());
4460 uint64_t MaxUnionIvarSize = 0;
4461 uint64_t MaxSkippedUnionIvarSize = 0;
4462 const FieldDecl *MaxField = nullptr;
4463 const FieldDecl *MaxSkippedField = nullptr;
4464 const FieldDecl *LastFieldBitfieldOrUnnamed = nullptr;
4465 uint64_t MaxFieldOffset = 0;
4466 uint64_t MaxSkippedFieldOffset = 0;
4467 uint64_t LastBitfieldOrUnnamedOffset = 0;
4468 uint64_t FirstFieldDelta = 0;
4469
4470 if (RecFields.empty())
4471 return;
4472 unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(0);
4473 unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
4474 if (!RD && CGM.getLangOpts().ObjCAutoRefCount) {
4475 const FieldDecl *FirstField = RecFields[0];
4476 FirstFieldDelta =
4477 ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(FirstField));
4478 }
4479
4480 for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
4481 const FieldDecl *Field = RecFields[i];
4482 uint64_t FieldOffset;
4483 if (RD) {
4484 // Note that 'i' here is actually the field index inside RD of Field,
4485 // although this dependency is hidden.
4486 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4487 FieldOffset = (RL.getFieldOffset(i) / ByteSizeInBits) - FirstFieldDelta;
4488 } else
4489 FieldOffset =
4490 ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field)) - FirstFieldDelta;
4491
4492 // Skip over unnamed or bitfields
4493 if (!Field->getIdentifier() || Field->isBitField()) {
4494 LastFieldBitfieldOrUnnamed = Field;
4495 LastBitfieldOrUnnamedOffset = FieldOffset;
4496 continue;
4497 }
4498
4499 LastFieldBitfieldOrUnnamed = nullptr;
4500 QualType FQT = Field->getType();
4501 if (FQT->isRecordType() || FQT->isUnionType()) {
4502 if (FQT->isUnionType())
4503 HasUnion = true;
4504
4505 BuildAggrIvarRecordLayout(FQT->getAs<RecordType>(),
4506 BytePos + FieldOffset,
4507 ForStrongLayout, HasUnion);
4508 continue;
4509 }
4510
4511 if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
4512 const ConstantArrayType *CArray =
4513 dyn_cast_or_null<ConstantArrayType>(Array);
4514 uint64_t ElCount = CArray->getSize().getZExtValue();
4515 assert(CArray && "only array with known element size is supported");
4516 FQT = CArray->getElementType();
4517 while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
4518 const ConstantArrayType *CArray =
4519 dyn_cast_or_null<ConstantArrayType>(Array);
4520 ElCount *= CArray->getSize().getZExtValue();
4521 FQT = CArray->getElementType();
4522 }
4523 if (FQT->isRecordType() && ElCount) {
4524 int OldIndex = IvarsInfo.size() - 1;
4525 int OldSkIndex = SkipIvars.size() -1;
4526
4527 const RecordType *RT = FQT->getAs<RecordType>();
4528 BuildAggrIvarRecordLayout(RT, BytePos + FieldOffset,
4529 ForStrongLayout, HasUnion);
4530
4531 // Replicate layout information for each array element. Note that
4532 // one element is already done.
4533 uint64_t ElIx = 1;
4534 for (int FirstIndex = IvarsInfo.size() - 1,
4535 FirstSkIndex = SkipIvars.size() - 1 ;ElIx < ElCount; ElIx++) {
4536 uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits;
4537 for (int i = OldIndex+1; i <= FirstIndex; ++i)
4538 IvarsInfo.push_back(GC_IVAR(IvarsInfo[i].ivar_bytepos + Size*ElIx,
4539 IvarsInfo[i].ivar_size));
4540 for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i)
4541 SkipIvars.push_back(GC_IVAR(SkipIvars[i].ivar_bytepos + Size*ElIx,
4542 SkipIvars[i].ivar_size));
4543 }
4544 continue;
4545 }
4546 }
4547 // At this point, we are done with Record/Union and array there of.
4548 // For other arrays we are down to its element type.
4549 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT);
4550
4551 unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType());
4552 if ((ForStrongLayout && GCAttr == Qualifiers::Strong)
4553 || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
4554 if (IsUnion) {
4555 uint64_t UnionIvarSize = FieldSize / WordSizeInBits;
4556 if (UnionIvarSize > MaxUnionIvarSize) {
4557 MaxUnionIvarSize = UnionIvarSize;
4558 MaxField = Field;
4559 MaxFieldOffset = FieldOffset;
4560 }
4561 } else {
4562 IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset,
4563 FieldSize / WordSizeInBits));
4564 }
4565 } else if ((ForStrongLayout &&
4566 (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak))
4567 || (!ForStrongLayout && GCAttr != Qualifiers::Weak)) {
4568 if (IsUnion) {
4569 // FIXME: Why the asymmetry? We divide by word size in bits on other
4570 // side.
4571 uint64_t UnionIvarSize = FieldSize / ByteSizeInBits;
4572 if (UnionIvarSize > MaxSkippedUnionIvarSize) {
4573 MaxSkippedUnionIvarSize = UnionIvarSize;
4574 MaxSkippedField = Field;
4575 MaxSkippedFieldOffset = FieldOffset;
4576 }
4577 } else {
4578 // FIXME: Why the asymmetry, we divide by byte size in bits here?
4579 SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset,
4580 FieldSize / ByteSizeInBits));
4581 }
4582 }
4583 }
4584
4585 if (LastFieldBitfieldOrUnnamed) {
4586 if (LastFieldBitfieldOrUnnamed->isBitField()) {
4587 // Last field was a bitfield. Must update skip info.
4588 uint64_t BitFieldSize
4589 = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext());
4590 GC_IVAR skivar;
4591 skivar.ivar_bytepos = BytePos + LastBitfieldOrUnnamedOffset;
4592 skivar.ivar_size = (BitFieldSize / ByteSizeInBits)
4593 + ((BitFieldSize % ByteSizeInBits) != 0);
4594 SkipIvars.push_back(skivar);
4595 } else {
4596 assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed");
4597 // Last field was unnamed. Must update skip info.
4598 unsigned FieldSize
4599 = CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType());
4600 SkipIvars.push_back(GC_IVAR(BytePos + LastBitfieldOrUnnamedOffset,
4601 FieldSize / ByteSizeInBits));
4602 }
4603 }
4604
4605 if (MaxField)
4606 IvarsInfo.push_back(GC_IVAR(BytePos + MaxFieldOffset,
4607 MaxUnionIvarSize));
4608 if (MaxSkippedField)
4609 SkipIvars.push_back(GC_IVAR(BytePos + MaxSkippedFieldOffset,
4610 MaxSkippedUnionIvarSize));
4611 }
4612
4613 /// BuildIvarLayoutBitmap - This routine is the horsework for doing all
4614 /// the computations and returning the layout bitmap (for ivar or blocks) in
4615 /// the given argument BitMap string container. Routine reads
4616 /// two containers, IvarsInfo and SkipIvars which are assumed to be
4617 /// filled already by the caller.
BuildIvarLayoutBitmap(std::string & BitMap)4618 llvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string &BitMap) {
4619 unsigned int WordsToScan, WordsToSkip;
4620 llvm::Type *PtrTy = CGM.Int8PtrTy;
4621
4622 // Build the string of skip/scan nibbles
4623 SmallVector<SKIP_SCAN, 32> SkipScanIvars;
4624 unsigned int WordSize =
4625 CGM.getTypes().getDataLayout().getTypeAllocSize(PtrTy);
4626 if (IvarsInfo[0].ivar_bytepos == 0) {
4627 WordsToSkip = 0;
4628 WordsToScan = IvarsInfo[0].ivar_size;
4629 } else {
4630 WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize;
4631 WordsToScan = IvarsInfo[0].ivar_size;
4632 }
4633 for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++) {
4634 unsigned int TailPrevGCObjC =
4635 IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize;
4636 if (IvarsInfo[i].ivar_bytepos == TailPrevGCObjC) {
4637 // consecutive 'scanned' object pointers.
4638 WordsToScan += IvarsInfo[i].ivar_size;
4639 } else {
4640 // Skip over 'gc'able object pointer which lay over each other.
4641 if (TailPrevGCObjC > IvarsInfo[i].ivar_bytepos)
4642 continue;
4643 // Must skip over 1 or more words. We save current skip/scan values
4644 // and start a new pair.
4645 SKIP_SCAN SkScan;
4646 SkScan.skip = WordsToSkip;
4647 SkScan.scan = WordsToScan;
4648 SkipScanIvars.push_back(SkScan);
4649
4650 // Skip the hole.
4651 SkScan.skip = (IvarsInfo[i].ivar_bytepos - TailPrevGCObjC) / WordSize;
4652 SkScan.scan = 0;
4653 SkipScanIvars.push_back(SkScan);
4654 WordsToSkip = 0;
4655 WordsToScan = IvarsInfo[i].ivar_size;
4656 }
4657 }
4658 if (WordsToScan > 0) {
4659 SKIP_SCAN SkScan;
4660 SkScan.skip = WordsToSkip;
4661 SkScan.scan = WordsToScan;
4662 SkipScanIvars.push_back(SkScan);
4663 }
4664
4665 if (!SkipIvars.empty()) {
4666 unsigned int LastIndex = SkipIvars.size()-1;
4667 int LastByteSkipped =
4668 SkipIvars[LastIndex].ivar_bytepos + SkipIvars[LastIndex].ivar_size;
4669 LastIndex = IvarsInfo.size()-1;
4670 int LastByteScanned =
4671 IvarsInfo[LastIndex].ivar_bytepos +
4672 IvarsInfo[LastIndex].ivar_size * WordSize;
4673 // Compute number of bytes to skip at the tail end of the last ivar scanned.
4674 if (LastByteSkipped > LastByteScanned) {
4675 unsigned int TotalWords = (LastByteSkipped + (WordSize -1)) / WordSize;
4676 SKIP_SCAN SkScan;
4677 SkScan.skip = TotalWords - (LastByteScanned/WordSize);
4678 SkScan.scan = 0;
4679 SkipScanIvars.push_back(SkScan);
4680 }
4681 }
4682 // Mini optimization of nibbles such that an 0xM0 followed by 0x0N is produced
4683 // as 0xMN.
4684 int SkipScan = SkipScanIvars.size()-1;
4685 for (int i = 0; i <= SkipScan; i++) {
4686 if ((i < SkipScan) && SkipScanIvars[i].skip && SkipScanIvars[i].scan == 0
4687 && SkipScanIvars[i+1].skip == 0 && SkipScanIvars[i+1].scan) {
4688 // 0xM0 followed by 0x0N detected.
4689 SkipScanIvars[i].scan = SkipScanIvars[i+1].scan;
4690 for (int j = i+1; j < SkipScan; j++)
4691 SkipScanIvars[j] = SkipScanIvars[j+1];
4692 --SkipScan;
4693 }
4694 }
4695
4696 // Generate the string.
4697 for (int i = 0; i <= SkipScan; i++) {
4698 unsigned char byte;
4699 unsigned int skip_small = SkipScanIvars[i].skip % 0xf;
4700 unsigned int scan_small = SkipScanIvars[i].scan % 0xf;
4701 unsigned int skip_big = SkipScanIvars[i].skip / 0xf;
4702 unsigned int scan_big = SkipScanIvars[i].scan / 0xf;
4703
4704 // first skip big.
4705 for (unsigned int ix = 0; ix < skip_big; ix++)
4706 BitMap += (unsigned char)(0xf0);
4707
4708 // next (skip small, scan)
4709 if (skip_small) {
4710 byte = skip_small << 4;
4711 if (scan_big > 0) {
4712 byte |= 0xf;
4713 --scan_big;
4714 } else if (scan_small) {
4715 byte |= scan_small;
4716 scan_small = 0;
4717 }
4718 BitMap += byte;
4719 }
4720 // next scan big
4721 for (unsigned int ix = 0; ix < scan_big; ix++)
4722 BitMap += (unsigned char)(0x0f);
4723 // last scan small
4724 if (scan_small) {
4725 byte = scan_small;
4726 BitMap += byte;
4727 }
4728 }
4729 // null terminate string.
4730 unsigned char zero = 0;
4731 BitMap += zero;
4732
4733 llvm::GlobalVariable *Entry = CreateMetadataVar(
4734 "OBJC_CLASS_NAME_",
4735 llvm::ConstantDataArray::getString(VMContext, BitMap, false),
4736 ((ObjCABI == 2) ? "__TEXT,__objc_classname,cstring_literals"
4737 : "__TEXT,__cstring,cstring_literals"),
4738 1, true);
4739 return getConstantGEP(VMContext, Entry, 0, 0);
4740 }
4741
4742 /// BuildIvarLayout - Builds ivar layout bitmap for the class
4743 /// implementation for the __strong or __weak case.
4744 /// The layout map displays which words in ivar list must be skipped
4745 /// and which must be scanned by GC (see below). String is built of bytes.
4746 /// Each byte is divided up in two nibbles (4-bit each). Left nibble is count
4747 /// of words to skip and right nibble is count of words to scan. So, each
4748 /// nibble represents up to 15 workds to skip or scan. Skipping the rest is
4749 /// represented by a 0x00 byte which also ends the string.
4750 /// 1. when ForStrongLayout is true, following ivars are scanned:
4751 /// - id, Class
4752 /// - object *
4753 /// - __strong anything
4754 ///
4755 /// 2. When ForStrongLayout is false, following ivars are scanned:
4756 /// - __weak anything
4757 ///
BuildIvarLayout(const ObjCImplementationDecl * OMD,bool ForStrongLayout)4758 llvm::Constant *CGObjCCommonMac::BuildIvarLayout(
4759 const ObjCImplementationDecl *OMD,
4760 bool ForStrongLayout) {
4761 bool hasUnion = false;
4762
4763 llvm::Type *PtrTy = CGM.Int8PtrTy;
4764 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
4765 !CGM.getLangOpts().ObjCAutoRefCount)
4766 return llvm::Constant::getNullValue(PtrTy);
4767
4768 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
4769 SmallVector<const FieldDecl*, 32> RecFields;
4770 if (CGM.getLangOpts().ObjCAutoRefCount) {
4771 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
4772 IVD; IVD = IVD->getNextIvar())
4773 RecFields.push_back(cast<FieldDecl>(IVD));
4774 }
4775 else {
4776 SmallVector<const ObjCIvarDecl*, 32> Ivars;
4777 CGM.getContext().DeepCollectObjCIvars(OI, true, Ivars);
4778
4779 // FIXME: This is not ideal; we shouldn't have to do this copy.
4780 RecFields.append(Ivars.begin(), Ivars.end());
4781 }
4782
4783 if (RecFields.empty())
4784 return llvm::Constant::getNullValue(PtrTy);
4785
4786 SkipIvars.clear();
4787 IvarsInfo.clear();
4788
4789 BuildAggrIvarLayout(OMD, nullptr, nullptr, RecFields, 0, ForStrongLayout,
4790 hasUnion);
4791 if (IvarsInfo.empty())
4792 return llvm::Constant::getNullValue(PtrTy);
4793 // Sort on byte position in case we encounterred a union nested in
4794 // the ivar list.
4795 if (hasUnion && !IvarsInfo.empty())
4796 std::sort(IvarsInfo.begin(), IvarsInfo.end());
4797 if (hasUnion && !SkipIvars.empty())
4798 std::sort(SkipIvars.begin(), SkipIvars.end());
4799
4800 std::string BitMap;
4801 llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
4802
4803 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
4804 printf("\n%s ivar layout for class '%s': ",
4805 ForStrongLayout ? "strong" : "weak",
4806 OMD->getClassInterface()->getName().str().c_str());
4807 const unsigned char *s = (const unsigned char*)BitMap.c_str();
4808 for (unsigned i = 0, e = BitMap.size(); i < e; i++)
4809 if (!(s[i] & 0xf0))
4810 printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
4811 else
4812 printf("0x%x%s", s[i], s[i] != 0 ? ", " : "");
4813 printf("\n");
4814 }
4815 return C;
4816 }
4817
GetMethodVarName(Selector Sel)4818 llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
4819 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
4820
4821 // FIXME: Avoid std::string in "Sel.getAsString()"
4822 if (!Entry)
4823 Entry = CreateMetadataVar(
4824 "OBJC_METH_VAR_NAME_",
4825 llvm::ConstantDataArray::getString(VMContext, Sel.getAsString()),
4826 ((ObjCABI == 2) ? "__TEXT,__objc_methname,cstring_literals"
4827 : "__TEXT,__cstring,cstring_literals"),
4828 1, true);
4829
4830 return getConstantGEP(VMContext, Entry, 0, 0);
4831 }
4832
4833 // FIXME: Merge into a single cstring creation function.
GetMethodVarName(IdentifierInfo * ID)4834 llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
4835 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
4836 }
4837
GetMethodVarType(const FieldDecl * Field)4838 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
4839 std::string TypeStr;
4840 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
4841
4842 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
4843
4844 if (!Entry)
4845 Entry = CreateMetadataVar(
4846 "OBJC_METH_VAR_TYPE_",
4847 llvm::ConstantDataArray::getString(VMContext, TypeStr),
4848 ((ObjCABI == 2) ? "__TEXT,__objc_methtype,cstring_literals"
4849 : "__TEXT,__cstring,cstring_literals"),
4850 1, true);
4851
4852 return getConstantGEP(VMContext, Entry, 0, 0);
4853 }
4854
GetMethodVarType(const ObjCMethodDecl * D,bool Extended)4855 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
4856 bool Extended) {
4857 std::string TypeStr;
4858 if (CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr, Extended))
4859 return nullptr;
4860
4861 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
4862
4863 if (!Entry)
4864 Entry = CreateMetadataVar(
4865 "OBJC_METH_VAR_TYPE_",
4866 llvm::ConstantDataArray::getString(VMContext, TypeStr),
4867 ((ObjCABI == 2) ? "__TEXT,__objc_methtype,cstring_literals"
4868 : "__TEXT,__cstring,cstring_literals"),
4869 1, true);
4870
4871 return getConstantGEP(VMContext, Entry, 0, 0);
4872 }
4873
4874 // FIXME: Merge into a single cstring creation function.
GetPropertyName(IdentifierInfo * Ident)4875 llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
4876 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
4877
4878 if (!Entry)
4879 Entry = CreateMetadataVar(
4880 "OBJC_PROP_NAME_ATTR_",
4881 llvm::ConstantDataArray::getString(VMContext, Ident->getName()),
4882 "__TEXT,__cstring,cstring_literals", 1, true);
4883
4884 return getConstantGEP(VMContext, Entry, 0, 0);
4885 }
4886
4887 // FIXME: Merge into a single cstring creation function.
4888 // FIXME: This Decl should be more precise.
4889 llvm::Constant *
GetPropertyTypeString(const ObjCPropertyDecl * PD,const Decl * Container)4890 CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
4891 const Decl *Container) {
4892 std::string TypeStr;
4893 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
4894 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
4895 }
4896
GetNameForMethod(const ObjCMethodDecl * D,const ObjCContainerDecl * CD,SmallVectorImpl<char> & Name)4897 void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D,
4898 const ObjCContainerDecl *CD,
4899 SmallVectorImpl<char> &Name) {
4900 llvm::raw_svector_ostream OS(Name);
4901 assert (CD && "Missing container decl in GetNameForMethod");
4902 OS << '\01' << (D->isInstanceMethod() ? '-' : '+')
4903 << '[' << CD->getName();
4904 if (const ObjCCategoryImplDecl *CID =
4905 dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
4906 OS << '(' << *CID << ')';
4907 OS << ' ' << D->getSelector().getAsString() << ']';
4908 }
4909
FinishModule()4910 void CGObjCMac::FinishModule() {
4911 EmitModuleInfo();
4912
4913 // Emit the dummy bodies for any protocols which were referenced but
4914 // never defined.
4915 for (llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*>::iterator
4916 I = Protocols.begin(), e = Protocols.end(); I != e; ++I) {
4917 if (I->second->hasInitializer())
4918 continue;
4919
4920 llvm::Constant *Values[5];
4921 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
4922 Values[1] = GetClassName(I->first->getName());
4923 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
4924 Values[3] = Values[4] =
4925 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
4926 I->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
4927 Values));
4928 CGM.addCompilerUsedGlobal(I->second);
4929 }
4930
4931 // Add assembler directives to add lazy undefined symbol references
4932 // for classes which are referenced but not defined. This is
4933 // important for correct linker interaction.
4934 //
4935 // FIXME: It would be nice if we had an LLVM construct for this.
4936 if (!LazySymbols.empty() || !DefinedSymbols.empty()) {
4937 SmallString<256> Asm;
4938 Asm += CGM.getModule().getModuleInlineAsm();
4939 if (!Asm.empty() && Asm.back() != '\n')
4940 Asm += '\n';
4941
4942 llvm::raw_svector_ostream OS(Asm);
4943 for (llvm::SetVector<IdentifierInfo*>::iterator I = DefinedSymbols.begin(),
4944 e = DefinedSymbols.end(); I != e; ++I)
4945 OS << "\t.objc_class_name_" << (*I)->getName() << "=0\n"
4946 << "\t.globl .objc_class_name_" << (*I)->getName() << "\n";
4947 for (llvm::SetVector<IdentifierInfo*>::iterator I = LazySymbols.begin(),
4948 e = LazySymbols.end(); I != e; ++I) {
4949 OS << "\t.lazy_reference .objc_class_name_" << (*I)->getName() << "\n";
4950 }
4951
4952 for (size_t i = 0, e = DefinedCategoryNames.size(); i < e; ++i) {
4953 OS << "\t.objc_category_name_" << DefinedCategoryNames[i] << "=0\n"
4954 << "\t.globl .objc_category_name_" << DefinedCategoryNames[i] << "\n";
4955 }
4956
4957 CGM.getModule().setModuleInlineAsm(OS.str());
4958 }
4959 }
4960
CGObjCNonFragileABIMac(CodeGen::CodeGenModule & cgm)4961 CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
4962 : CGObjCCommonMac(cgm),
4963 ObjCTypes(cgm) {
4964 ObjCEmptyCacheVar = ObjCEmptyVtableVar = nullptr;
4965 ObjCABI = 2;
4966 }
4967
4968 /* *** */
4969
ObjCCommonTypesHelper(CodeGen::CodeGenModule & cgm)4970 ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
4971 : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(nullptr)
4972 {
4973 CodeGen::CodeGenTypes &Types = CGM.getTypes();
4974 ASTContext &Ctx = CGM.getContext();
4975
4976 ShortTy = Types.ConvertType(Ctx.ShortTy);
4977 IntTy = Types.ConvertType(Ctx.IntTy);
4978 LongTy = Types.ConvertType(Ctx.LongTy);
4979 LongLongTy = Types.ConvertType(Ctx.LongLongTy);
4980 Int8PtrTy = CGM.Int8PtrTy;
4981 Int8PtrPtrTy = CGM.Int8PtrPtrTy;
4982
4983 // arm64 targets use "int" ivar offset variables. All others,
4984 // including OS X x86_64 and Windows x86_64, use "long" ivar offsets.
4985 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64)
4986 IvarOffsetVarTy = IntTy;
4987 else
4988 IvarOffsetVarTy = LongTy;
4989
4990 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
4991 PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy);
4992 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
4993
4994 // I'm not sure I like this. The implicit coordination is a bit
4995 // gross. We should solve this in a reasonable fashion because this
4996 // is a pretty common task (match some runtime data structure with
4997 // an LLVM data structure).
4998
4999 // FIXME: This is leaked.
5000 // FIXME: Merge with rewriter code?
5001
5002 // struct _objc_super {
5003 // id self;
5004 // Class cls;
5005 // }
5006 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
5007 Ctx.getTranslationUnitDecl(),
5008 SourceLocation(), SourceLocation(),
5009 &Ctx.Idents.get("_objc_super"));
5010 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5011 nullptr, Ctx.getObjCIdType(), nullptr, nullptr,
5012 false, ICIS_NoInit));
5013 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5014 nullptr, Ctx.getObjCClassType(), nullptr,
5015 nullptr, false, ICIS_NoInit));
5016 RD->completeDefinition();
5017
5018 SuperCTy = Ctx.getTagDeclType(RD);
5019 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
5020
5021 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
5022 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
5023
5024 // struct _prop_t {
5025 // char *name;
5026 // char *attributes;
5027 // }
5028 PropertyTy = llvm::StructType::create("struct._prop_t",
5029 Int8PtrTy, Int8PtrTy, nullptr);
5030
5031 // struct _prop_list_t {
5032 // uint32_t entsize; // sizeof(struct _prop_t)
5033 // uint32_t count_of_properties;
5034 // struct _prop_t prop_list[count_of_properties];
5035 // }
5036 PropertyListTy =
5037 llvm::StructType::create("struct._prop_list_t", IntTy, IntTy,
5038 llvm::ArrayType::get(PropertyTy, 0), nullptr);
5039 // struct _prop_list_t *
5040 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
5041
5042 // struct _objc_method {
5043 // SEL _cmd;
5044 // char *method_type;
5045 // char *_imp;
5046 // }
5047 MethodTy = llvm::StructType::create("struct._objc_method",
5048 SelectorPtrTy, Int8PtrTy, Int8PtrTy,
5049 nullptr);
5050
5051 // struct _objc_cache *
5052 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache");
5053 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
5054
5055 }
5056
ObjCTypesHelper(CodeGen::CodeGenModule & cgm)5057 ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
5058 : ObjCCommonTypesHelper(cgm) {
5059 // struct _objc_method_description {
5060 // SEL name;
5061 // char *types;
5062 // }
5063 MethodDescriptionTy =
5064 llvm::StructType::create("struct._objc_method_description",
5065 SelectorPtrTy, Int8PtrTy, nullptr);
5066
5067 // struct _objc_method_description_list {
5068 // int count;
5069 // struct _objc_method_description[1];
5070 // }
5071 MethodDescriptionListTy = llvm::StructType::create(
5072 "struct._objc_method_description_list", IntTy,
5073 llvm::ArrayType::get(MethodDescriptionTy, 0), nullptr);
5074
5075 // struct _objc_method_description_list *
5076 MethodDescriptionListPtrTy =
5077 llvm::PointerType::getUnqual(MethodDescriptionListTy);
5078
5079 // Protocol description structures
5080
5081 // struct _objc_protocol_extension {
5082 // uint32_t size; // sizeof(struct _objc_protocol_extension)
5083 // struct _objc_method_description_list *optional_instance_methods;
5084 // struct _objc_method_description_list *optional_class_methods;
5085 // struct _objc_property_list *instance_properties;
5086 // const char ** extendedMethodTypes;
5087 // }
5088 ProtocolExtensionTy =
5089 llvm::StructType::create("struct._objc_protocol_extension",
5090 IntTy, MethodDescriptionListPtrTy,
5091 MethodDescriptionListPtrTy, PropertyListPtrTy,
5092 Int8PtrPtrTy, nullptr);
5093
5094 // struct _objc_protocol_extension *
5095 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
5096
5097 // Handle recursive construction of Protocol and ProtocolList types
5098
5099 ProtocolTy =
5100 llvm::StructType::create(VMContext, "struct._objc_protocol");
5101
5102 ProtocolListTy =
5103 llvm::StructType::create(VMContext, "struct._objc_protocol_list");
5104 ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy),
5105 LongTy,
5106 llvm::ArrayType::get(ProtocolTy, 0),
5107 nullptr);
5108
5109 // struct _objc_protocol {
5110 // struct _objc_protocol_extension *isa;
5111 // char *protocol_name;
5112 // struct _objc_protocol **_objc_protocol_list;
5113 // struct _objc_method_description_list *instance_methods;
5114 // struct _objc_method_description_list *class_methods;
5115 // }
5116 ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy,
5117 llvm::PointerType::getUnqual(ProtocolListTy),
5118 MethodDescriptionListPtrTy,
5119 MethodDescriptionListPtrTy,
5120 nullptr);
5121
5122 // struct _objc_protocol_list *
5123 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
5124
5125 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
5126
5127 // Class description structures
5128
5129 // struct _objc_ivar {
5130 // char *ivar_name;
5131 // char *ivar_type;
5132 // int ivar_offset;
5133 // }
5134 IvarTy = llvm::StructType::create("struct._objc_ivar",
5135 Int8PtrTy, Int8PtrTy, IntTy, nullptr);
5136
5137 // struct _objc_ivar_list *
5138 IvarListTy =
5139 llvm::StructType::create(VMContext, "struct._objc_ivar_list");
5140 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
5141
5142 // struct _objc_method_list *
5143 MethodListTy =
5144 llvm::StructType::create(VMContext, "struct._objc_method_list");
5145 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
5146
5147 // struct _objc_class_extension *
5148 ClassExtensionTy =
5149 llvm::StructType::create("struct._objc_class_extension",
5150 IntTy, Int8PtrTy, PropertyListPtrTy, nullptr);
5151 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
5152
5153 ClassTy = llvm::StructType::create(VMContext, "struct._objc_class");
5154
5155 // struct _objc_class {
5156 // Class isa;
5157 // Class super_class;
5158 // char *name;
5159 // long version;
5160 // long info;
5161 // long instance_size;
5162 // struct _objc_ivar_list *ivars;
5163 // struct _objc_method_list *methods;
5164 // struct _objc_cache *cache;
5165 // struct _objc_protocol_list *protocols;
5166 // char *ivar_layout;
5167 // struct _objc_class_ext *ext;
5168 // };
5169 ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy),
5170 llvm::PointerType::getUnqual(ClassTy),
5171 Int8PtrTy,
5172 LongTy,
5173 LongTy,
5174 LongTy,
5175 IvarListPtrTy,
5176 MethodListPtrTy,
5177 CachePtrTy,
5178 ProtocolListPtrTy,
5179 Int8PtrTy,
5180 ClassExtensionPtrTy,
5181 nullptr);
5182
5183 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
5184
5185 // struct _objc_category {
5186 // char *category_name;
5187 // char *class_name;
5188 // struct _objc_method_list *instance_method;
5189 // struct _objc_method_list *class_method;
5190 // uint32_t size; // sizeof(struct _objc_category)
5191 // struct _objc_property_list *instance_properties;// category's @property
5192 // }
5193 CategoryTy =
5194 llvm::StructType::create("struct._objc_category",
5195 Int8PtrTy, Int8PtrTy, MethodListPtrTy,
5196 MethodListPtrTy, ProtocolListPtrTy,
5197 IntTy, PropertyListPtrTy, nullptr);
5198
5199 // Global metadata structures
5200
5201 // struct _objc_symtab {
5202 // long sel_ref_cnt;
5203 // SEL *refs;
5204 // short cls_def_cnt;
5205 // short cat_def_cnt;
5206 // char *defs[cls_def_cnt + cat_def_cnt];
5207 // }
5208 SymtabTy =
5209 llvm::StructType::create("struct._objc_symtab",
5210 LongTy, SelectorPtrTy, ShortTy, ShortTy,
5211 llvm::ArrayType::get(Int8PtrTy, 0), nullptr);
5212 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
5213
5214 // struct _objc_module {
5215 // long version;
5216 // long size; // sizeof(struct _objc_module)
5217 // char *name;
5218 // struct _objc_symtab* symtab;
5219 // }
5220 ModuleTy =
5221 llvm::StructType::create("struct._objc_module",
5222 LongTy, LongTy, Int8PtrTy, SymtabPtrTy, nullptr);
5223
5224
5225 // FIXME: This is the size of the setjmp buffer and should be target
5226 // specific. 18 is what's used on 32-bit X86.
5227 uint64_t SetJmpBufferSize = 18;
5228
5229 // Exceptions
5230 llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4);
5231
5232 ExceptionDataTy =
5233 llvm::StructType::create("struct._objc_exception_data",
5234 llvm::ArrayType::get(CGM.Int32Ty,SetJmpBufferSize),
5235 StackPtrTy, nullptr);
5236
5237 }
5238
ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule & cgm)5239 ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm)
5240 : ObjCCommonTypesHelper(cgm) {
5241 // struct _method_list_t {
5242 // uint32_t entsize; // sizeof(struct _objc_method)
5243 // uint32_t method_count;
5244 // struct _objc_method method_list[method_count];
5245 // }
5246 MethodListnfABITy =
5247 llvm::StructType::create("struct.__method_list_t", IntTy, IntTy,
5248 llvm::ArrayType::get(MethodTy, 0), nullptr);
5249 // struct method_list_t *
5250 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy);
5251
5252 // struct _protocol_t {
5253 // id isa; // NULL
5254 // const char * const protocol_name;
5255 // const struct _protocol_list_t * protocol_list; // super protocols
5256 // const struct method_list_t * const instance_methods;
5257 // const struct method_list_t * const class_methods;
5258 // const struct method_list_t *optionalInstanceMethods;
5259 // const struct method_list_t *optionalClassMethods;
5260 // const struct _prop_list_t * properties;
5261 // const uint32_t size; // sizeof(struct _protocol_t)
5262 // const uint32_t flags; // = 0
5263 // const char ** extendedMethodTypes;
5264 // const char *demangledName;
5265 // }
5266
5267 // Holder for struct _protocol_list_t *
5268 ProtocolListnfABITy =
5269 llvm::StructType::create(VMContext, "struct._objc_protocol_list");
5270
5271 ProtocolnfABITy =
5272 llvm::StructType::create("struct._protocol_t", ObjectPtrTy, Int8PtrTy,
5273 llvm::PointerType::getUnqual(ProtocolListnfABITy),
5274 MethodListnfABIPtrTy, MethodListnfABIPtrTy,
5275 MethodListnfABIPtrTy, MethodListnfABIPtrTy,
5276 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy,
5277 Int8PtrTy,
5278 nullptr);
5279
5280 // struct _protocol_t*
5281 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy);
5282
5283 // struct _protocol_list_t {
5284 // long protocol_count; // Note, this is 32/64 bit
5285 // struct _protocol_t *[protocol_count];
5286 // }
5287 ProtocolListnfABITy->setBody(LongTy,
5288 llvm::ArrayType::get(ProtocolnfABIPtrTy, 0),
5289 nullptr);
5290
5291 // struct _objc_protocol_list*
5292 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy);
5293
5294 // struct _ivar_t {
5295 // unsigned [long] int *offset; // pointer to ivar offset location
5296 // char *name;
5297 // char *type;
5298 // uint32_t alignment;
5299 // uint32_t size;
5300 // }
5301 IvarnfABITy = llvm::StructType::create(
5302 "struct._ivar_t", llvm::PointerType::getUnqual(IvarOffsetVarTy),
5303 Int8PtrTy, Int8PtrTy, IntTy, IntTy, nullptr);
5304
5305 // struct _ivar_list_t {
5306 // uint32 entsize; // sizeof(struct _ivar_t)
5307 // uint32 count;
5308 // struct _iver_t list[count];
5309 // }
5310 IvarListnfABITy =
5311 llvm::StructType::create("struct._ivar_list_t", IntTy, IntTy,
5312 llvm::ArrayType::get(IvarnfABITy, 0), nullptr);
5313
5314 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy);
5315
5316 // struct _class_ro_t {
5317 // uint32_t const flags;
5318 // uint32_t const instanceStart;
5319 // uint32_t const instanceSize;
5320 // uint32_t const reserved; // only when building for 64bit targets
5321 // const uint8_t * const ivarLayout;
5322 // const char *const name;
5323 // const struct _method_list_t * const baseMethods;
5324 // const struct _objc_protocol_list *const baseProtocols;
5325 // const struct _ivar_list_t *const ivars;
5326 // const uint8_t * const weakIvarLayout;
5327 // const struct _prop_list_t * const properties;
5328 // }
5329
5330 // FIXME. Add 'reserved' field in 64bit abi mode!
5331 ClassRonfABITy = llvm::StructType::create("struct._class_ro_t",
5332 IntTy, IntTy, IntTy, Int8PtrTy,
5333 Int8PtrTy, MethodListnfABIPtrTy,
5334 ProtocolListnfABIPtrTy,
5335 IvarListnfABIPtrTy,
5336 Int8PtrTy, PropertyListPtrTy,
5337 nullptr);
5338
5339 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
5340 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
5341 ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false)
5342 ->getPointerTo();
5343
5344 // struct _class_t {
5345 // struct _class_t *isa;
5346 // struct _class_t * const superclass;
5347 // void *cache;
5348 // IMP *vtable;
5349 // struct class_ro_t *ro;
5350 // }
5351
5352 ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t");
5353 ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy),
5354 llvm::PointerType::getUnqual(ClassnfABITy),
5355 CachePtrTy,
5356 llvm::PointerType::getUnqual(ImpnfABITy),
5357 llvm::PointerType::getUnqual(ClassRonfABITy),
5358 nullptr);
5359
5360 // LLVM for struct _class_t *
5361 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy);
5362
5363 // struct _category_t {
5364 // const char * const name;
5365 // struct _class_t *const cls;
5366 // const struct _method_list_t * const instance_methods;
5367 // const struct _method_list_t * const class_methods;
5368 // const struct _protocol_list_t * const protocols;
5369 // const struct _prop_list_t * const properties;
5370 // }
5371 CategorynfABITy = llvm::StructType::create("struct._category_t",
5372 Int8PtrTy, ClassnfABIPtrTy,
5373 MethodListnfABIPtrTy,
5374 MethodListnfABIPtrTy,
5375 ProtocolListnfABIPtrTy,
5376 PropertyListPtrTy,
5377 nullptr);
5378
5379 // New types for nonfragile abi messaging.
5380 CodeGen::CodeGenTypes &Types = CGM.getTypes();
5381 ASTContext &Ctx = CGM.getContext();
5382
5383 // MessageRefTy - LLVM for:
5384 // struct _message_ref_t {
5385 // IMP messenger;
5386 // SEL name;
5387 // };
5388
5389 // First the clang type for struct _message_ref_t
5390 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
5391 Ctx.getTranslationUnitDecl(),
5392 SourceLocation(), SourceLocation(),
5393 &Ctx.Idents.get("_message_ref_t"));
5394 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5395 nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false,
5396 ICIS_NoInit));
5397 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5398 nullptr, Ctx.getObjCSelType(), nullptr, nullptr,
5399 false, ICIS_NoInit));
5400 RD->completeDefinition();
5401
5402 MessageRefCTy = Ctx.getTagDeclType(RD);
5403 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
5404 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
5405
5406 // MessageRefPtrTy - LLVM for struct _message_ref_t*
5407 MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy);
5408
5409 // SuperMessageRefTy - LLVM for:
5410 // struct _super_message_ref_t {
5411 // SUPER_IMP messenger;
5412 // SEL name;
5413 // };
5414 SuperMessageRefTy =
5415 llvm::StructType::create("struct._super_message_ref_t",
5416 ImpnfABITy, SelectorPtrTy, nullptr);
5417
5418 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
5419 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);
5420
5421
5422 // struct objc_typeinfo {
5423 // const void** vtable; // objc_ehtype_vtable + 2
5424 // const char* name; // c++ typeinfo string
5425 // Class cls;
5426 // };
5427 EHTypeTy =
5428 llvm::StructType::create("struct._objc_typeinfo",
5429 llvm::PointerType::getUnqual(Int8PtrTy),
5430 Int8PtrTy, ClassnfABIPtrTy, nullptr);
5431 EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy);
5432 }
5433
ModuleInitFunction()5434 llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
5435 FinishNonFragileABIModule();
5436
5437 return nullptr;
5438 }
5439
5440 void CGObjCNonFragileABIMac::
AddModuleClassList(ArrayRef<llvm::GlobalValue * > Container,const char * SymbolName,const char * SectionName)5441 AddModuleClassList(ArrayRef<llvm::GlobalValue*> Container,
5442 const char *SymbolName,
5443 const char *SectionName) {
5444 unsigned NumClasses = Container.size();
5445
5446 if (!NumClasses)
5447 return;
5448
5449 SmallVector<llvm::Constant*, 8> Symbols(NumClasses);
5450 for (unsigned i=0; i<NumClasses; i++)
5451 Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i],
5452 ObjCTypes.Int8PtrTy);
5453 llvm::Constant *Init =
5454 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
5455 Symbols.size()),
5456 Symbols);
5457
5458 llvm::GlobalVariable *GV =
5459 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5460 llvm::GlobalValue::PrivateLinkage,
5461 Init,
5462 SymbolName);
5463 GV->setAlignment(CGM.getDataLayout().getABITypeAlignment(Init->getType()));
5464 GV->setSection(SectionName);
5465 CGM.addCompilerUsedGlobal(GV);
5466 }
5467
FinishNonFragileABIModule()5468 void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
5469 // nonfragile abi has no module definition.
5470
5471 // Build list of all implemented class addresses in array
5472 // L_OBJC_LABEL_CLASS_$.
5473
5474 for (unsigned i=0, NumClasses=ImplementedClasses.size(); i<NumClasses; i++) {
5475 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
5476 assert(ID);
5477 if (ObjCImplementationDecl *IMP = ID->getImplementation())
5478 // We are implementing a weak imported interface. Give it external linkage
5479 if (ID->isWeakImported() && !IMP->isWeakImported()) {
5480 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
5481 DefinedMetaClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
5482 }
5483 }
5484
5485 AddModuleClassList(DefinedClasses, "OBJC_LABEL_CLASS_$",
5486 "__DATA, __objc_classlist, regular, no_dead_strip");
5487
5488 AddModuleClassList(DefinedNonLazyClasses, "OBJC_LABEL_NONLAZY_CLASS_$",
5489 "__DATA, __objc_nlclslist, regular, no_dead_strip");
5490
5491 // Build list of all implemented category addresses in array
5492 // L_OBJC_LABEL_CATEGORY_$.
5493 AddModuleClassList(DefinedCategories, "OBJC_LABEL_CATEGORY_$",
5494 "__DATA, __objc_catlist, regular, no_dead_strip");
5495 AddModuleClassList(DefinedNonLazyCategories, "OBJC_LABEL_NONLAZY_CATEGORY_$",
5496 "__DATA, __objc_nlcatlist, regular, no_dead_strip");
5497
5498 EmitImageInfo();
5499 }
5500
5501 /// isVTableDispatchedSelector - Returns true if SEL is not in the list of
5502 /// VTableDispatchMethods; false otherwise. What this means is that
5503 /// except for the 19 selectors in the list, we generate 32bit-style
5504 /// message dispatch call for all the rest.
isVTableDispatchedSelector(Selector Sel)5505 bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
5506 // At various points we've experimented with using vtable-based
5507 // dispatch for all methods.
5508 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
5509 case CodeGenOptions::Legacy:
5510 return false;
5511 case CodeGenOptions::NonLegacy:
5512 return true;
5513 case CodeGenOptions::Mixed:
5514 break;
5515 }
5516
5517 // If so, see whether this selector is in the white-list of things which must
5518 // use the new dispatch convention. We lazily build a dense set for this.
5519 if (VTableDispatchMethods.empty()) {
5520 VTableDispatchMethods.insert(GetNullarySelector("alloc"));
5521 VTableDispatchMethods.insert(GetNullarySelector("class"));
5522 VTableDispatchMethods.insert(GetNullarySelector("self"));
5523 VTableDispatchMethods.insert(GetNullarySelector("isFlipped"));
5524 VTableDispatchMethods.insert(GetNullarySelector("length"));
5525 VTableDispatchMethods.insert(GetNullarySelector("count"));
5526
5527 // These are vtable-based if GC is disabled.
5528 // Optimistically use vtable dispatch for hybrid compiles.
5529 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
5530 VTableDispatchMethods.insert(GetNullarySelector("retain"));
5531 VTableDispatchMethods.insert(GetNullarySelector("release"));
5532 VTableDispatchMethods.insert(GetNullarySelector("autorelease"));
5533 }
5534
5535 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone"));
5536 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass"));
5537 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector"));
5538 VTableDispatchMethods.insert(GetUnarySelector("objectForKey"));
5539 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex"));
5540 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString"));
5541 VTableDispatchMethods.insert(GetUnarySelector("isEqual"));
5542
5543 // These are vtable-based if GC is enabled.
5544 // Optimistically use vtable dispatch for hybrid compiles.
5545 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
5546 VTableDispatchMethods.insert(GetNullarySelector("hash"));
5547 VTableDispatchMethods.insert(GetUnarySelector("addObject"));
5548
5549 // "countByEnumeratingWithState:objects:count"
5550 IdentifierInfo *KeyIdents[] = {
5551 &CGM.getContext().Idents.get("countByEnumeratingWithState"),
5552 &CGM.getContext().Idents.get("objects"),
5553 &CGM.getContext().Idents.get("count")
5554 };
5555 VTableDispatchMethods.insert(
5556 CGM.getContext().Selectors.getSelector(3, KeyIdents));
5557 }
5558 }
5559
5560 return VTableDispatchMethods.count(Sel);
5561 }
5562
5563 /// BuildClassRoTInitializer - generate meta-data for:
5564 /// struct _class_ro_t {
5565 /// uint32_t const flags;
5566 /// uint32_t const instanceStart;
5567 /// uint32_t const instanceSize;
5568 /// uint32_t const reserved; // only when building for 64bit targets
5569 /// const uint8_t * const ivarLayout;
5570 /// const char *const name;
5571 /// const struct _method_list_t * const baseMethods;
5572 /// const struct _protocol_list_t *const baseProtocols;
5573 /// const struct _ivar_list_t *const ivars;
5574 /// const uint8_t * const weakIvarLayout;
5575 /// const struct _prop_list_t * const properties;
5576 /// }
5577 ///
BuildClassRoTInitializer(unsigned flags,unsigned InstanceStart,unsigned InstanceSize,const ObjCImplementationDecl * ID)5578 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
5579 unsigned flags,
5580 unsigned InstanceStart,
5581 unsigned InstanceSize,
5582 const ObjCImplementationDecl *ID) {
5583 std::string ClassName = ID->getObjCRuntimeNameAsString();
5584 llvm::Constant *Values[10]; // 11 for 64bit targets!
5585
5586 if (CGM.getLangOpts().ObjCAutoRefCount)
5587 flags |= NonFragileABI_Class_CompiledByARC;
5588
5589 Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags);
5590 Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart);
5591 Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize);
5592 // FIXME. For 64bit targets add 0 here.
5593 Values[ 3] = (flags & NonFragileABI_Class_Meta)
5594 ? GetIvarLayoutName(nullptr, ObjCTypes)
5595 : BuildIvarLayout(ID, true);
5596 Values[ 4] = GetClassName(ID->getObjCRuntimeNameAsString());
5597 // const struct _method_list_t * const baseMethods;
5598 std::vector<llvm::Constant*> Methods;
5599 std::string MethodListName("\01l_OBJC_$_");
5600 if (flags & NonFragileABI_Class_Meta) {
5601 MethodListName += "CLASS_METHODS_";
5602 MethodListName += ID->getObjCRuntimeNameAsString();
5603 for (const auto *I : ID->class_methods())
5604 // Class methods should always be defined.
5605 Methods.push_back(GetMethodConstant(I));
5606 } else {
5607 MethodListName += "INSTANCE_METHODS_";
5608 MethodListName += ID->getObjCRuntimeNameAsString();
5609 for (const auto *I : ID->instance_methods())
5610 // Instance methods should always be defined.
5611 Methods.push_back(GetMethodConstant(I));
5612
5613 for (const auto *PID : ID->property_impls()) {
5614 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
5615 ObjCPropertyDecl *PD = PID->getPropertyDecl();
5616
5617 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
5618 if (llvm::Constant *C = GetMethodConstant(MD))
5619 Methods.push_back(C);
5620 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
5621 if (llvm::Constant *C = GetMethodConstant(MD))
5622 Methods.push_back(C);
5623 }
5624 }
5625 }
5626 Values[ 5] = EmitMethodList(MethodListName,
5627 "__DATA, __objc_const", Methods);
5628
5629 const ObjCInterfaceDecl *OID = ID->getClassInterface();
5630 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");
5631 Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_"
5632 + OID->getObjCRuntimeNameAsString(),
5633 OID->all_referenced_protocol_begin(),
5634 OID->all_referenced_protocol_end());
5635
5636 if (flags & NonFragileABI_Class_Meta) {
5637 Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
5638 Values[ 8] = GetIvarLayoutName(nullptr, ObjCTypes);
5639 Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
5640 } else {
5641 Values[ 7] = EmitIvarList(ID);
5642 Values[ 8] = BuildIvarLayout(ID, false);
5643 Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getObjCRuntimeNameAsString(),
5644 ID, ID->getClassInterface(), ObjCTypes);
5645 }
5646 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy,
5647 Values);
5648 llvm::GlobalVariable *CLASS_RO_GV =
5649 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassRonfABITy, false,
5650 llvm::GlobalValue::PrivateLinkage,
5651 Init,
5652 (flags & NonFragileABI_Class_Meta) ?
5653 std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName :
5654 std::string("\01l_OBJC_CLASS_RO_$_")+ClassName);
5655 CLASS_RO_GV->setAlignment(
5656 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassRonfABITy));
5657 CLASS_RO_GV->setSection("__DATA, __objc_const");
5658 return CLASS_RO_GV;
5659
5660 }
5661
5662 /// BuildClassMetaData - This routine defines that to-level meta-data
5663 /// for the given ClassName for:
5664 /// struct _class_t {
5665 /// struct _class_t *isa;
5666 /// struct _class_t * const superclass;
5667 /// void *cache;
5668 /// IMP *vtable;
5669 /// struct class_ro_t *ro;
5670 /// }
5671 ///
BuildClassMetaData(const std::string & ClassName,llvm::Constant * IsAGV,llvm::Constant * SuperClassGV,llvm::Constant * ClassRoGV,bool HiddenVisibility,bool Weak)5672 llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassMetaData(
5673 const std::string &ClassName, llvm::Constant *IsAGV, llvm::Constant *SuperClassGV,
5674 llvm::Constant *ClassRoGV, bool HiddenVisibility, bool Weak) {
5675 llvm::Constant *Values[] = {
5676 IsAGV,
5677 SuperClassGV,
5678 ObjCEmptyCacheVar, // &ObjCEmptyCacheVar
5679 ObjCEmptyVtableVar, // &ObjCEmptyVtableVar
5680 ClassRoGV // &CLASS_RO_GV
5681 };
5682 if (!Values[1])
5683 Values[1] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy);
5684 if (!Values[3])
5685 Values[3] = llvm::Constant::getNullValue(
5686 llvm::PointerType::getUnqual(ObjCTypes.ImpnfABITy));
5687 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy,
5688 Values);
5689 llvm::GlobalVariable *GV = GetClassGlobal(ClassName, Weak);
5690 GV->setInitializer(Init);
5691 GV->setSection("__DATA, __objc_data");
5692 GV->setAlignment(
5693 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABITy));
5694 if (HiddenVisibility)
5695 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5696 return GV;
5697 }
5698
5699 bool
ImplementationIsNonLazy(const ObjCImplDecl * OD) const5700 CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
5701 return OD->getClassMethod(GetNullarySelector("load")) != nullptr;
5702 }
5703
GetClassSizeInfo(const ObjCImplementationDecl * OID,uint32_t & InstanceStart,uint32_t & InstanceSize)5704 void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
5705 uint32_t &InstanceStart,
5706 uint32_t &InstanceSize) {
5707 const ASTRecordLayout &RL =
5708 CGM.getContext().getASTObjCImplementationLayout(OID);
5709
5710 // InstanceSize is really instance end.
5711 InstanceSize = RL.getDataSize().getQuantity();
5712
5713 // If there are no fields, the start is the same as the end.
5714 if (!RL.getFieldCount())
5715 InstanceStart = InstanceSize;
5716 else
5717 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
5718 }
5719
GenerateClass(const ObjCImplementationDecl * ID)5720 void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
5721 std::string ClassName = ID->getObjCRuntimeNameAsString();
5722 if (!ObjCEmptyCacheVar) {
5723 ObjCEmptyCacheVar = new llvm::GlobalVariable(
5724 CGM.getModule(),
5725 ObjCTypes.CacheTy,
5726 false,
5727 llvm::GlobalValue::ExternalLinkage,
5728 nullptr,
5729 "_objc_empty_cache");
5730
5731 // Make this entry NULL for any iOS device target, any iOS simulator target,
5732 // OS X with deployment target 10.9 or later.
5733 const llvm::Triple &Triple = CGM.getTarget().getTriple();
5734 if (Triple.isiOS() || (Triple.isMacOSX() && !Triple.isMacOSXVersionLT(10, 9)))
5735 // This entry will be null.
5736 ObjCEmptyVtableVar = nullptr;
5737 else
5738 ObjCEmptyVtableVar = new llvm::GlobalVariable(
5739 CGM.getModule(),
5740 ObjCTypes.ImpnfABITy,
5741 false,
5742 llvm::GlobalValue::ExternalLinkage,
5743 nullptr,
5744 "_objc_empty_vtable");
5745 }
5746 assert(ID->getClassInterface() &&
5747 "CGObjCNonFragileABIMac::GenerateClass - class is 0");
5748 // FIXME: Is this correct (that meta class size is never computed)?
5749 uint32_t InstanceStart =
5750 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy);
5751 uint32_t InstanceSize = InstanceStart;
5752 uint32_t flags = NonFragileABI_Class_Meta;
5753 llvm::SmallString<64> ObjCMetaClassName(getMetaclassSymbolPrefix());
5754 llvm::SmallString<64> ObjCClassName(getClassSymbolPrefix());
5755 llvm::SmallString<64> TClassName;
5756
5757 llvm::GlobalVariable *SuperClassGV, *IsAGV;
5758
5759 // Build the flags for the metaclass.
5760 bool classIsHidden =
5761 ID->getClassInterface()->getVisibility() == HiddenVisibility;
5762 if (classIsHidden)
5763 flags |= NonFragileABI_Class_Hidden;
5764
5765 // FIXME: why is this flag set on the metaclass?
5766 // ObjC metaclasses have no fields and don't really get constructed.
5767 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
5768 flags |= NonFragileABI_Class_HasCXXStructors;
5769 if (!ID->hasNonZeroConstructors())
5770 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
5771 }
5772
5773 if (!ID->getClassInterface()->getSuperClass()) {
5774 // class is root
5775 flags |= NonFragileABI_Class_Root;
5776 TClassName = ObjCClassName;
5777 TClassName += ClassName;
5778 SuperClassGV = GetClassGlobal(TClassName.str(),
5779 ID->getClassInterface()->isWeakImported());
5780 TClassName = ObjCMetaClassName;
5781 TClassName += ClassName;
5782 IsAGV = GetClassGlobal(TClassName.str(),
5783 ID->getClassInterface()->isWeakImported());
5784 } else {
5785 // Has a root. Current class is not a root.
5786 const ObjCInterfaceDecl *Root = ID->getClassInterface();
5787 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
5788 Root = Super;
5789 TClassName = ObjCMetaClassName ;
5790 TClassName += Root->getObjCRuntimeNameAsString();
5791 IsAGV = GetClassGlobal(TClassName.str(),
5792 Root->isWeakImported());
5793
5794 // work on super class metadata symbol.
5795 TClassName = ObjCMetaClassName;
5796 TClassName += ID->getClassInterface()->getSuperClass()->getObjCRuntimeNameAsString();
5797 SuperClassGV = GetClassGlobal(
5798 TClassName.str(),
5799 ID->getClassInterface()->getSuperClass()->isWeakImported());
5800 }
5801 llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags,
5802 InstanceStart,
5803 InstanceSize,ID);
5804 TClassName = ObjCMetaClassName;
5805 TClassName += ClassName;
5806 llvm::GlobalVariable *MetaTClass = BuildClassMetaData(
5807 TClassName.str(), IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden,
5808 ID->getClassInterface()->isWeakImported());
5809 DefinedMetaClasses.push_back(MetaTClass);
5810
5811 // Metadata for the class
5812 flags = 0;
5813 if (classIsHidden)
5814 flags |= NonFragileABI_Class_Hidden;
5815
5816 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
5817 flags |= NonFragileABI_Class_HasCXXStructors;
5818
5819 // Set a flag to enable a runtime optimization when a class has
5820 // fields that require destruction but which don't require
5821 // anything except zero-initialization during construction. This
5822 // is most notably true of __strong and __weak types, but you can
5823 // also imagine there being C++ types with non-trivial default
5824 // constructors that merely set all fields to null.
5825 if (!ID->hasNonZeroConstructors())
5826 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
5827 }
5828
5829 if (hasObjCExceptionAttribute(CGM.getContext(), ID->getClassInterface()))
5830 flags |= NonFragileABI_Class_Exception;
5831
5832 if (!ID->getClassInterface()->getSuperClass()) {
5833 flags |= NonFragileABI_Class_Root;
5834 SuperClassGV = nullptr;
5835 } else {
5836 // Has a root. Current class is not a root.
5837 TClassName = ObjCClassName;
5838 TClassName += ID->getClassInterface()->getSuperClass()->getObjCRuntimeNameAsString();
5839 SuperClassGV = GetClassGlobal(
5840 TClassName.str(),
5841 ID->getClassInterface()->getSuperClass()->isWeakImported());
5842 }
5843 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
5844 CLASS_RO_GV = BuildClassRoTInitializer(flags,
5845 InstanceStart,
5846 InstanceSize,
5847 ID);
5848
5849 TClassName = ObjCClassName;
5850 TClassName += ClassName;
5851 llvm::GlobalVariable *ClassMD =
5852 BuildClassMetaData(TClassName.str(), MetaTClass, SuperClassGV, CLASS_RO_GV,
5853 classIsHidden,
5854 ID->getClassInterface()->isWeakImported());
5855 DefinedClasses.push_back(ClassMD);
5856 ImplementedClasses.push_back(ID->getClassInterface());
5857
5858 // Determine if this class is also "non-lazy".
5859 if (ImplementationIsNonLazy(ID))
5860 DefinedNonLazyClasses.push_back(ClassMD);
5861
5862 // Force the definition of the EHType if necessary.
5863 if (flags & NonFragileABI_Class_Exception)
5864 GetInterfaceEHType(ID->getClassInterface(), true);
5865 // Make sure method definition entries are all clear for next implementation.
5866 MethodDefinitions.clear();
5867 }
5868
5869 /// GenerateProtocolRef - This routine is called to generate code for
5870 /// a protocol reference expression; as in:
5871 /// @code
5872 /// @protocol(Proto1);
5873 /// @endcode
5874 /// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1
5875 /// which will hold address of the protocol meta-data.
5876 ///
GenerateProtocolRef(CodeGenFunction & CGF,const ObjCProtocolDecl * PD)5877 llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF,
5878 const ObjCProtocolDecl *PD) {
5879
5880 // This routine is called for @protocol only. So, we must build definition
5881 // of protocol's meta-data (not a reference to it!)
5882 //
5883 llvm::Constant *Init =
5884 llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD),
5885 ObjCTypes.getExternalProtocolPtrTy());
5886
5887 std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_");
5888 ProtocolName += PD->getObjCRuntimeNameAsString();
5889
5890 llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
5891 if (PTGV)
5892 return CGF.Builder.CreateLoad(PTGV);
5893 PTGV = new llvm::GlobalVariable(
5894 CGM.getModule(),
5895 Init->getType(), false,
5896 llvm::GlobalValue::WeakAnyLinkage,
5897 Init,
5898 ProtocolName);
5899 PTGV->setSection("__DATA, __objc_protorefs, coalesced, no_dead_strip");
5900 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5901 CGM.addCompilerUsedGlobal(PTGV);
5902 return CGF.Builder.CreateLoad(PTGV);
5903 }
5904
5905 /// GenerateCategory - Build metadata for a category implementation.
5906 /// struct _category_t {
5907 /// const char * const name;
5908 /// struct _class_t *const cls;
5909 /// const struct _method_list_t * const instance_methods;
5910 /// const struct _method_list_t * const class_methods;
5911 /// const struct _protocol_list_t * const protocols;
5912 /// const struct _prop_list_t * const properties;
5913 /// }
5914 ///
GenerateCategory(const ObjCCategoryImplDecl * OCD)5915 void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
5916 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
5917 const char *Prefix = "\01l_OBJC_$_CATEGORY_";
5918
5919 llvm::SmallString<64> ExtCatName(Prefix);
5920 ExtCatName += Interface->getObjCRuntimeNameAsString();
5921 ExtCatName += "_$_";
5922 ExtCatName += OCD->getNameAsString();
5923
5924 llvm::SmallString<64> ExtClassName(getClassSymbolPrefix());
5925 ExtClassName += Interface->getObjCRuntimeNameAsString();
5926
5927 llvm::Constant *Values[6];
5928 Values[0] = GetClassName(OCD->getIdentifier()->getName());
5929 // meta-class entry symbol
5930 llvm::GlobalVariable *ClassGV =
5931 GetClassGlobal(ExtClassName.str(), Interface->isWeakImported());
5932
5933 Values[1] = ClassGV;
5934 std::vector<llvm::Constant*> Methods;
5935 llvm::SmallString<64> MethodListName(Prefix);
5936
5937 MethodListName += "INSTANCE_METHODS_";
5938 MethodListName += Interface->getObjCRuntimeNameAsString();
5939 MethodListName += "_$_";
5940 MethodListName += OCD->getName();
5941
5942 for (const auto *I : OCD->instance_methods())
5943 // Instance methods should always be defined.
5944 Methods.push_back(GetMethodConstant(I));
5945
5946 Values[2] = EmitMethodList(MethodListName.str(),
5947 "__DATA, __objc_const",
5948 Methods);
5949
5950 MethodListName = Prefix;
5951 MethodListName += "CLASS_METHODS_";
5952 MethodListName += Interface->getObjCRuntimeNameAsString();
5953 MethodListName += "_$_";
5954 MethodListName += OCD->getNameAsString();
5955
5956 Methods.clear();
5957 for (const auto *I : OCD->class_methods())
5958 // Class methods should always be defined.
5959 Methods.push_back(GetMethodConstant(I));
5960
5961 Values[3] = EmitMethodList(MethodListName.str(),
5962 "__DATA, __objc_const",
5963 Methods);
5964 const ObjCCategoryDecl *Category =
5965 Interface->FindCategoryDeclaration(OCD->getIdentifier());
5966 if (Category) {
5967 SmallString<256> ExtName;
5968 llvm::raw_svector_ostream(ExtName) << Interface->getObjCRuntimeNameAsString() << "_$_"
5969 << OCD->getName();
5970 Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_"
5971 + Interface->getObjCRuntimeNameAsString() + "_$_"
5972 + Category->getName(),
5973 Category->protocol_begin(),
5974 Category->protocol_end());
5975 Values[5] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
5976 OCD, Category, ObjCTypes);
5977 } else {
5978 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
5979 Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
5980 }
5981
5982 llvm::Constant *Init =
5983 llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy,
5984 Values);
5985 llvm::GlobalVariable *GCATV
5986 = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CategorynfABITy,
5987 false,
5988 llvm::GlobalValue::PrivateLinkage,
5989 Init,
5990 ExtCatName.str());
5991 GCATV->setAlignment(
5992 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.CategorynfABITy));
5993 GCATV->setSection("__DATA, __objc_const");
5994 CGM.addCompilerUsedGlobal(GCATV);
5995 DefinedCategories.push_back(GCATV);
5996
5997 // Determine if this category is also "non-lazy".
5998 if (ImplementationIsNonLazy(OCD))
5999 DefinedNonLazyCategories.push_back(GCATV);
6000 // method definition entries must be clear for next implementation.
6001 MethodDefinitions.clear();
6002 }
6003
6004 /// GetMethodConstant - Return a struct objc_method constant for the
6005 /// given method if it has been defined. The result is null if the
6006 /// method has not been defined. The return value has type MethodPtrTy.
GetMethodConstant(const ObjCMethodDecl * MD)6007 llvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant(
6008 const ObjCMethodDecl *MD) {
6009 llvm::Function *Fn = GetMethodDefinition(MD);
6010 if (!Fn)
6011 return nullptr;
6012
6013 llvm::Constant *Method[] = {
6014 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
6015 ObjCTypes.SelectorPtrTy),
6016 GetMethodVarType(MD),
6017 llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy)
6018 };
6019 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
6020 }
6021
6022 /// EmitMethodList - Build meta-data for method declarations
6023 /// struct _method_list_t {
6024 /// uint32_t entsize; // sizeof(struct _objc_method)
6025 /// uint32_t method_count;
6026 /// struct _objc_method method_list[method_count];
6027 /// }
6028 ///
6029 llvm::Constant *
EmitMethodList(Twine Name,const char * Section,ArrayRef<llvm::Constant * > Methods)6030 CGObjCNonFragileABIMac::EmitMethodList(Twine Name,
6031 const char *Section,
6032 ArrayRef<llvm::Constant*> Methods) {
6033 // Return null for empty list.
6034 if (Methods.empty())
6035 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
6036
6037 llvm::Constant *Values[3];
6038 // sizeof(struct _objc_method)
6039 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
6040 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6041 // method_count
6042 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
6043 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
6044 Methods.size());
6045 Values[2] = llvm::ConstantArray::get(AT, Methods);
6046 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
6047
6048 llvm::GlobalVariable *GV =
6049 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
6050 llvm::GlobalValue::PrivateLinkage, Init, Name);
6051 GV->setAlignment(CGM.getDataLayout().getABITypeAlignment(Init->getType()));
6052 GV->setSection(Section);
6053 CGM.addCompilerUsedGlobal(GV);
6054 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy);
6055 }
6056
6057 /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
6058 /// the given ivar.
6059 llvm::GlobalVariable *
ObjCIvarOffsetVariable(const ObjCInterfaceDecl * ID,const ObjCIvarDecl * Ivar)6060 CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
6061 const ObjCIvarDecl *Ivar) {
6062
6063 const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
6064 llvm::SmallString<64> Name("OBJC_IVAR_$_");
6065 Name += Container->getObjCRuntimeNameAsString();
6066 Name += ".";
6067 Name += Ivar->getName();
6068 llvm::GlobalVariable *IvarOffsetGV =
6069 CGM.getModule().getGlobalVariable(Name);
6070 if (!IvarOffsetGV)
6071 IvarOffsetGV = new llvm::GlobalVariable(
6072 CGM.getModule(), ObjCTypes.IvarOffsetVarTy, false,
6073 llvm::GlobalValue::ExternalLinkage, nullptr, Name.str());
6074 return IvarOffsetGV;
6075 }
6076
6077 llvm::Constant *
EmitIvarOffsetVar(const ObjCInterfaceDecl * ID,const ObjCIvarDecl * Ivar,unsigned long int Offset)6078 CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
6079 const ObjCIvarDecl *Ivar,
6080 unsigned long int Offset) {
6081 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
6082 IvarOffsetGV->setInitializer(
6083 llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));
6084 IvarOffsetGV->setAlignment(
6085 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.IvarOffsetVarTy));
6086
6087 // FIXME: This matches gcc, but shouldn't the visibility be set on the use as
6088 // well (i.e., in ObjCIvarOffsetVariable).
6089 if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
6090 Ivar->getAccessControl() == ObjCIvarDecl::Package ||
6091 ID->getVisibility() == HiddenVisibility)
6092 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6093 else
6094 IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
6095 IvarOffsetGV->setSection("__DATA, __objc_ivar");
6096 return IvarOffsetGV;
6097 }
6098
6099 /// EmitIvarList - Emit the ivar list for the given
6100 /// implementation. The return value has type
6101 /// IvarListnfABIPtrTy.
6102 /// struct _ivar_t {
6103 /// unsigned [long] int *offset; // pointer to ivar offset location
6104 /// char *name;
6105 /// char *type;
6106 /// uint32_t alignment;
6107 /// uint32_t size;
6108 /// }
6109 /// struct _ivar_list_t {
6110 /// uint32 entsize; // sizeof(struct _ivar_t)
6111 /// uint32 count;
6112 /// struct _iver_t list[count];
6113 /// }
6114 ///
6115
EmitIvarList(const ObjCImplementationDecl * ID)6116 llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
6117 const ObjCImplementationDecl *ID) {
6118
6119 std::vector<llvm::Constant*> Ivars;
6120
6121 const ObjCInterfaceDecl *OID = ID->getClassInterface();
6122 assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface");
6123
6124 // FIXME. Consolidate this with similar code in GenerateClass.
6125
6126 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
6127 IVD; IVD = IVD->getNextIvar()) {
6128 // Ignore unnamed bit-fields.
6129 if (!IVD->getDeclName())
6130 continue;
6131 llvm::Constant *Ivar[5];
6132 Ivar[0] = EmitIvarOffsetVar(ID->getClassInterface(), IVD,
6133 ComputeIvarBaseOffset(CGM, ID, IVD));
6134 Ivar[1] = GetMethodVarName(IVD->getIdentifier());
6135 Ivar[2] = GetMethodVarType(IVD);
6136 llvm::Type *FieldTy =
6137 CGM.getTypes().ConvertTypeForMem(IVD->getType());
6138 unsigned Size = CGM.getDataLayout().getTypeAllocSize(FieldTy);
6139 unsigned Align = CGM.getContext().getPreferredTypeAlign(
6140 IVD->getType().getTypePtr()) >> 3;
6141 Align = llvm::Log2_32(Align);
6142 Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align);
6143 // NOTE. Size of a bitfield does not match gcc's, because of the
6144 // way bitfields are treated special in each. But I am told that
6145 // 'size' for bitfield ivars is ignored by the runtime so it does
6146 // not matter. If it matters, there is enough info to get the
6147 // bitfield right!
6148 Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6149 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar));
6150 }
6151 // Return null for empty list.
6152 if (Ivars.empty())
6153 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
6154
6155 llvm::Constant *Values[3];
6156 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy);
6157 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6158 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
6159 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy,
6160 Ivars.size());
6161 Values[2] = llvm::ConstantArray::get(AT, Ivars);
6162 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
6163 const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_";
6164 llvm::GlobalVariable *GV =
6165 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
6166 llvm::GlobalValue::PrivateLinkage,
6167 Init,
6168 Prefix + OID->getObjCRuntimeNameAsString());
6169 GV->setAlignment(
6170 CGM.getDataLayout().getABITypeAlignment(Init->getType()));
6171 GV->setSection("__DATA, __objc_const");
6172
6173 CGM.addCompilerUsedGlobal(GV);
6174 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
6175 }
6176
GetOrEmitProtocolRef(const ObjCProtocolDecl * PD)6177 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
6178 const ObjCProtocolDecl *PD) {
6179 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
6180
6181 if (!Entry) {
6182 // We use the initializer as a marker of whether this is a forward
6183 // reference or not. At module finalization we add the empty
6184 // contents for protocols which were referenced but never defined.
6185 Entry =
6186 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
6187 false, llvm::GlobalValue::ExternalLinkage,
6188 nullptr,
6189 "\01l_OBJC_PROTOCOL_$_" + PD->getObjCRuntimeNameAsString());
6190 Entry->setSection("__DATA,__datacoal_nt,coalesced");
6191 }
6192
6193 return Entry;
6194 }
6195
6196 /// GetOrEmitProtocol - Generate the protocol meta-data:
6197 /// @code
6198 /// struct _protocol_t {
6199 /// id isa; // NULL
6200 /// const char * const protocol_name;
6201 /// const struct _protocol_list_t * protocol_list; // super protocols
6202 /// const struct method_list_t * const instance_methods;
6203 /// const struct method_list_t * const class_methods;
6204 /// const struct method_list_t *optionalInstanceMethods;
6205 /// const struct method_list_t *optionalClassMethods;
6206 /// const struct _prop_list_t * properties;
6207 /// const uint32_t size; // sizeof(struct _protocol_t)
6208 /// const uint32_t flags; // = 0
6209 /// const char ** extendedMethodTypes;
6210 /// const char *demangledName;
6211 /// }
6212 /// @endcode
6213 ///
6214
GetOrEmitProtocol(const ObjCProtocolDecl * PD)6215 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
6216 const ObjCProtocolDecl *PD) {
6217 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
6218
6219 // Early exit if a defining object has already been generated.
6220 if (Entry && Entry->hasInitializer())
6221 return Entry;
6222
6223 // Use the protocol definition, if there is one.
6224 if (const ObjCProtocolDecl *Def = PD->getDefinition())
6225 PD = Def;
6226
6227 // Construct method lists.
6228 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
6229 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
6230 std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt;
6231 for (const auto *MD : PD->instance_methods()) {
6232 llvm::Constant *C = GetMethodDescriptionConstant(MD);
6233 if (!C)
6234 return GetOrEmitProtocolRef(PD);
6235
6236 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
6237 OptInstanceMethods.push_back(C);
6238 OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
6239 } else {
6240 InstanceMethods.push_back(C);
6241 MethodTypesExt.push_back(GetMethodVarType(MD, true));
6242 }
6243 }
6244
6245 for (const auto *MD : PD->class_methods()) {
6246 llvm::Constant *C = GetMethodDescriptionConstant(MD);
6247 if (!C)
6248 return GetOrEmitProtocolRef(PD);
6249
6250 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
6251 OptClassMethods.push_back(C);
6252 OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
6253 } else {
6254 ClassMethods.push_back(C);
6255 MethodTypesExt.push_back(GetMethodVarType(MD, true));
6256 }
6257 }
6258
6259 MethodTypesExt.insert(MethodTypesExt.end(),
6260 OptMethodTypesExt.begin(), OptMethodTypesExt.end());
6261
6262 llvm::Constant *Values[12];
6263 // isa is NULL
6264 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy);
6265 Values[1] = GetClassName(PD->getObjCRuntimeNameAsString());
6266 Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getObjCRuntimeNameAsString(),
6267 PD->protocol_begin(),
6268 PD->protocol_end());
6269
6270 Values[3] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_"
6271 + PD->getObjCRuntimeNameAsString(),
6272 "__DATA, __objc_const",
6273 InstanceMethods);
6274 Values[4] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_"
6275 + PD->getObjCRuntimeNameAsString(),
6276 "__DATA, __objc_const",
6277 ClassMethods);
6278 Values[5] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_"
6279 + PD->getObjCRuntimeNameAsString(),
6280 "__DATA, __objc_const",
6281 OptInstanceMethods);
6282 Values[6] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_"
6283 + PD->getObjCRuntimeNameAsString(),
6284 "__DATA, __objc_const",
6285 OptClassMethods);
6286 Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getObjCRuntimeNameAsString(),
6287 nullptr, PD, ObjCTypes);
6288 uint32_t Size =
6289 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
6290 Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6291 Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy);
6292 Values[10] = EmitProtocolMethodTypes("\01l_OBJC_$_PROTOCOL_METHOD_TYPES_"
6293 + PD->getObjCRuntimeNameAsString(),
6294 MethodTypesExt, ObjCTypes);
6295 // const char *demangledName;
6296 Values[11] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
6297
6298 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy,
6299 Values);
6300
6301 if (Entry) {
6302 // Already created, fix the linkage and update the initializer.
6303 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
6304 Entry->setInitializer(Init);
6305 } else {
6306 Entry =
6307 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
6308 false, llvm::GlobalValue::WeakAnyLinkage, Init,
6309 "\01l_OBJC_PROTOCOL_$_" + PD->getObjCRuntimeNameAsString());
6310 Entry->setAlignment(
6311 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABITy));
6312 Entry->setSection("__DATA,__datacoal_nt,coalesced");
6313
6314 Protocols[PD->getIdentifier()] = Entry;
6315 }
6316 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
6317 CGM.addCompilerUsedGlobal(Entry);
6318
6319 // Use this protocol meta-data to build protocol list table in section
6320 // __DATA, __objc_protolist
6321 llvm::GlobalVariable *PTGV =
6322 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy,
6323 false, llvm::GlobalValue::WeakAnyLinkage, Entry,
6324 "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getObjCRuntimeNameAsString());
6325 PTGV->setAlignment(
6326 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
6327 PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip");
6328 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6329 CGM.addCompilerUsedGlobal(PTGV);
6330 return Entry;
6331 }
6332
6333 /// EmitProtocolList - Generate protocol list meta-data:
6334 /// @code
6335 /// struct _protocol_list_t {
6336 /// long protocol_count; // Note, this is 32/64 bit
6337 /// struct _protocol_t[protocol_count];
6338 /// }
6339 /// @endcode
6340 ///
6341 llvm::Constant *
EmitProtocolList(Twine Name,ObjCProtocolDecl::protocol_iterator begin,ObjCProtocolDecl::protocol_iterator end)6342 CGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
6343 ObjCProtocolDecl::protocol_iterator begin,
6344 ObjCProtocolDecl::protocol_iterator end) {
6345 SmallVector<llvm::Constant *, 16> ProtocolRefs;
6346
6347 // Just return null for empty protocol lists
6348 if (begin == end)
6349 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
6350
6351 // FIXME: We shouldn't need to do this lookup here, should we?
6352 SmallString<256> TmpName;
6353 Name.toVector(TmpName);
6354 llvm::GlobalVariable *GV =
6355 CGM.getModule().getGlobalVariable(TmpName.str(), true);
6356 if (GV)
6357 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
6358
6359 for (; begin != end; ++begin)
6360 ProtocolRefs.push_back(GetProtocolRef(*begin)); // Implemented???
6361
6362 // This list is null terminated.
6363 ProtocolRefs.push_back(llvm::Constant::getNullValue(
6364 ObjCTypes.ProtocolnfABIPtrTy));
6365
6366 llvm::Constant *Values[2];
6367 Values[0] =
6368 llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
6369 Values[1] =
6370 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolnfABIPtrTy,
6371 ProtocolRefs.size()),
6372 ProtocolRefs);
6373
6374 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
6375 GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
6376 llvm::GlobalValue::PrivateLinkage,
6377 Init, Name);
6378 GV->setSection("__DATA, __objc_const");
6379 GV->setAlignment(
6380 CGM.getDataLayout().getABITypeAlignment(Init->getType()));
6381 CGM.addCompilerUsedGlobal(GV);
6382 return llvm::ConstantExpr::getBitCast(GV,
6383 ObjCTypes.ProtocolListnfABIPtrTy);
6384 }
6385
6386 /// GetMethodDescriptionConstant - This routine build following meta-data:
6387 /// struct _objc_method {
6388 /// SEL _cmd;
6389 /// char *method_type;
6390 /// char *_imp;
6391 /// }
6392
6393 llvm::Constant *
GetMethodDescriptionConstant(const ObjCMethodDecl * MD)6394 CGObjCNonFragileABIMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
6395 llvm::Constant *Desc[3];
6396 Desc[0] =
6397 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
6398 ObjCTypes.SelectorPtrTy);
6399 Desc[1] = GetMethodVarType(MD);
6400 if (!Desc[1])
6401 return nullptr;
6402
6403 // Protocol methods have no implementation. So, this entry is always NULL.
6404 Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
6405 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc);
6406 }
6407
6408 /// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference.
6409 /// This code gen. amounts to generating code for:
6410 /// @code
6411 /// (type *)((char *)base + _OBJC_IVAR_$_.ivar;
6412 /// @encode
6413 ///
EmitObjCValueForIvar(CodeGen::CodeGenFunction & CGF,QualType ObjectTy,llvm::Value * BaseValue,const ObjCIvarDecl * Ivar,unsigned CVRQualifiers)6414 LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
6415 CodeGen::CodeGenFunction &CGF,
6416 QualType ObjectTy,
6417 llvm::Value *BaseValue,
6418 const ObjCIvarDecl *Ivar,
6419 unsigned CVRQualifiers) {
6420 ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCObjectType>()->getInterface();
6421 llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
6422 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
6423 Offset);
6424 }
6425
EmitIvarOffset(CodeGen::CodeGenFunction & CGF,const ObjCInterfaceDecl * Interface,const ObjCIvarDecl * Ivar)6426 llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(
6427 CodeGen::CodeGenFunction &CGF,
6428 const ObjCInterfaceDecl *Interface,
6429 const ObjCIvarDecl *Ivar) {
6430 llvm::Value *IvarOffsetValue = ObjCIvarOffsetVariable(Interface, Ivar);
6431 IvarOffsetValue = CGF.Builder.CreateLoad(IvarOffsetValue, "ivar");
6432 if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
6433 cast<llvm::LoadInst>(IvarOffsetValue)
6434 ->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
6435 llvm::MDNode::get(VMContext, None));
6436
6437 // This could be 32bit int or 64bit integer depending on the architecture.
6438 // Cast it to 64bit integer value, if it is a 32bit integer ivar offset value
6439 // as this is what caller always expectes.
6440 if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
6441 IvarOffsetValue = CGF.Builder.CreateIntCast(
6442 IvarOffsetValue, ObjCTypes.LongTy, true, "ivar.conv");
6443 return IvarOffsetValue;
6444 }
6445
appendSelectorForMessageRefTable(std::string & buffer,Selector selector)6446 static void appendSelectorForMessageRefTable(std::string &buffer,
6447 Selector selector) {
6448 if (selector.isUnarySelector()) {
6449 buffer += selector.getNameForSlot(0);
6450 return;
6451 }
6452
6453 for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) {
6454 buffer += selector.getNameForSlot(i);
6455 buffer += '_';
6456 }
6457 }
6458
6459 /// Emit a "v-table" message send. We emit a weak hidden-visibility
6460 /// struct, initially containing the selector pointer and a pointer to
6461 /// a "fixup" variant of the appropriate objc_msgSend. To call, we
6462 /// load and call the function pointer, passing the address of the
6463 /// struct as the second parameter. The runtime determines whether
6464 /// the selector is currently emitted using vtable dispatch; if so, it
6465 /// substitutes a stub function which simply tail-calls through the
6466 /// appropriate vtable slot, and if not, it substitues a stub function
6467 /// which tail-calls objc_msgSend. Both stubs adjust the selector
6468 /// argument to correctly point to the selector.
6469 RValue
EmitVTableMessageSend(CodeGenFunction & CGF,ReturnValueSlot returnSlot,QualType resultType,Selector selector,llvm::Value * arg0,QualType arg0Type,bool isSuper,const CallArgList & formalArgs,const ObjCMethodDecl * method)6470 CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF,
6471 ReturnValueSlot returnSlot,
6472 QualType resultType,
6473 Selector selector,
6474 llvm::Value *arg0,
6475 QualType arg0Type,
6476 bool isSuper,
6477 const CallArgList &formalArgs,
6478 const ObjCMethodDecl *method) {
6479 // Compute the actual arguments.
6480 CallArgList args;
6481
6482 // First argument: the receiver / super-call structure.
6483 if (!isSuper)
6484 arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy);
6485 args.add(RValue::get(arg0), arg0Type);
6486
6487 // Second argument: a pointer to the message ref structure. Leave
6488 // the actual argument value blank for now.
6489 args.add(RValue::get(nullptr), ObjCTypes.MessageRefCPtrTy);
6490
6491 args.insert(args.end(), formalArgs.begin(), formalArgs.end());
6492
6493 MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
6494
6495 NullReturnState nullReturn;
6496
6497 // Find the function to call and the mangled name for the message
6498 // ref structure. Using a different mangled name wouldn't actually
6499 // be a problem; it would just be a waste.
6500 //
6501 // The runtime currently never uses vtable dispatch for anything
6502 // except normal, non-super message-sends.
6503 // FIXME: don't use this for that.
6504 llvm::Constant *fn = nullptr;
6505 std::string messageRefName("\01l_");
6506 if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
6507 if (isSuper) {
6508 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
6509 messageRefName += "objc_msgSendSuper2_stret_fixup";
6510 } else {
6511 nullReturn.init(CGF, arg0);
6512 fn = ObjCTypes.getMessageSendStretFixupFn();
6513 messageRefName += "objc_msgSend_stret_fixup";
6514 }
6515 } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) {
6516 fn = ObjCTypes.getMessageSendFpretFixupFn();
6517 messageRefName += "objc_msgSend_fpret_fixup";
6518 } else {
6519 if (isSuper) {
6520 fn = ObjCTypes.getMessageSendSuper2FixupFn();
6521 messageRefName += "objc_msgSendSuper2_fixup";
6522 } else {
6523 fn = ObjCTypes.getMessageSendFixupFn();
6524 messageRefName += "objc_msgSend_fixup";
6525 }
6526 }
6527 assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend");
6528 messageRefName += '_';
6529
6530 // Append the selector name, except use underscores anywhere we
6531 // would have used colons.
6532 appendSelectorForMessageRefTable(messageRefName, selector);
6533
6534 llvm::GlobalVariable *messageRef
6535 = CGM.getModule().getGlobalVariable(messageRefName);
6536 if (!messageRef) {
6537 // Build the message ref structure.
6538 llvm::Constant *values[] = { fn, GetMethodVarName(selector) };
6539 llvm::Constant *init = llvm::ConstantStruct::getAnon(values);
6540 messageRef = new llvm::GlobalVariable(CGM.getModule(),
6541 init->getType(),
6542 /*constant*/ false,
6543 llvm::GlobalValue::WeakAnyLinkage,
6544 init,
6545 messageRefName);
6546 messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
6547 messageRef->setAlignment(16);
6548 messageRef->setSection("__DATA, __objc_msgrefs, coalesced");
6549 }
6550
6551 bool requiresnullCheck = false;
6552 if (CGM.getLangOpts().ObjCAutoRefCount && method)
6553 for (const auto *ParamDecl : method->params()) {
6554 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
6555 if (!nullReturn.NullBB)
6556 nullReturn.init(CGF, arg0);
6557 requiresnullCheck = true;
6558 break;
6559 }
6560 }
6561
6562 llvm::Value *mref =
6563 CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy);
6564
6565 // Update the message ref argument.
6566 args[1].RV = RValue::get(mref);
6567
6568 // Load the function to call from the message ref table.
6569 llvm::Value *callee =
6570 CGF.Builder.CreateStructGEP(ObjCTypes.MessageRefTy, mref, 0);
6571 callee = CGF.Builder.CreateLoad(callee, "msgSend_fn");
6572
6573 callee = CGF.Builder.CreateBitCast(callee, MSI.MessengerType);
6574
6575 RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args);
6576 return nullReturn.complete(CGF, result, resultType, formalArgs,
6577 requiresnullCheck ? method : nullptr);
6578 }
6579
6580 /// Generate code for a message send expression in the nonfragile abi.
6581 CodeGen::RValue
GenerateMessageSend(CodeGen::CodeGenFunction & CGF,ReturnValueSlot Return,QualType ResultType,Selector Sel,llvm::Value * Receiver,const CallArgList & CallArgs,const ObjCInterfaceDecl * Class,const ObjCMethodDecl * Method)6582 CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
6583 ReturnValueSlot Return,
6584 QualType ResultType,
6585 Selector Sel,
6586 llvm::Value *Receiver,
6587 const CallArgList &CallArgs,
6588 const ObjCInterfaceDecl *Class,
6589 const ObjCMethodDecl *Method) {
6590 return isVTableDispatchedSelector(Sel)
6591 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
6592 Receiver, CGF.getContext().getObjCIdType(),
6593 false, CallArgs, Method)
6594 : EmitMessageSend(CGF, Return, ResultType,
6595 EmitSelector(CGF, Sel),
6596 Receiver, CGF.getContext().getObjCIdType(),
6597 false, CallArgs, Method, ObjCTypes);
6598 }
6599
6600 llvm::GlobalVariable *
GetClassGlobal(const std::string & Name,bool Weak)6601 CGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name, bool Weak) {
6602 llvm::GlobalValue::LinkageTypes L =
6603 Weak ? llvm::GlobalValue::ExternalWeakLinkage
6604 : llvm::GlobalValue::ExternalLinkage;
6605
6606 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
6607
6608 if (!GV)
6609 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABITy,
6610 false, L, nullptr, Name);
6611
6612 assert(GV->getLinkage() == L);
6613 return GV;
6614 }
6615
EmitClassRefFromId(CodeGenFunction & CGF,IdentifierInfo * II,bool Weak,const ObjCInterfaceDecl * ID)6616 llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CodeGenFunction &CGF,
6617 IdentifierInfo *II,
6618 bool Weak,
6619 const ObjCInterfaceDecl *ID) {
6620 llvm::GlobalVariable *&Entry = ClassReferences[II];
6621
6622 if (!Entry) {
6623 std::string ClassName(
6624 getClassSymbolPrefix() +
6625 (ID ? ID->getObjCRuntimeNameAsString() : II->getName()).str());
6626 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName, Weak);
6627 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
6628 false, llvm::GlobalValue::PrivateLinkage,
6629 ClassGV, "OBJC_CLASSLIST_REFERENCES_$_");
6630 Entry->setAlignment(
6631 CGM.getDataLayout().getABITypeAlignment(
6632 ObjCTypes.ClassnfABIPtrTy));
6633 Entry->setSection("__DATA, __objc_classrefs, regular, no_dead_strip");
6634 CGM.addCompilerUsedGlobal(Entry);
6635 }
6636 return CGF.Builder.CreateLoad(Entry);
6637 }
6638
EmitClassRef(CodeGenFunction & CGF,const ObjCInterfaceDecl * ID)6639 llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF,
6640 const ObjCInterfaceDecl *ID) {
6641 return EmitClassRefFromId(CGF, ID->getIdentifier(), ID->isWeakImported(), ID);
6642 }
6643
EmitNSAutoreleasePoolClassRef(CodeGenFunction & CGF)6644 llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
6645 CodeGenFunction &CGF) {
6646 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
6647 return EmitClassRefFromId(CGF, II, false, 0);
6648 }
6649
6650 llvm::Value *
EmitSuperClassRef(CodeGenFunction & CGF,const ObjCInterfaceDecl * ID)6651 CGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF,
6652 const ObjCInterfaceDecl *ID) {
6653 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
6654
6655 if (!Entry) {
6656 llvm::SmallString<64> ClassName(getClassSymbolPrefix());
6657 ClassName += ID->getObjCRuntimeNameAsString();
6658 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(),
6659 ID->isWeakImported());
6660 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
6661 false, llvm::GlobalValue::PrivateLinkage,
6662 ClassGV, "OBJC_CLASSLIST_SUP_REFS_$_");
6663 Entry->setAlignment(
6664 CGM.getDataLayout().getABITypeAlignment(
6665 ObjCTypes.ClassnfABIPtrTy));
6666 Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
6667 CGM.addCompilerUsedGlobal(Entry);
6668 }
6669 return CGF.Builder.CreateLoad(Entry);
6670 }
6671
6672 /// EmitMetaClassRef - Return a Value * of the address of _class_t
6673 /// meta-data
6674 ///
EmitMetaClassRef(CodeGenFunction & CGF,const ObjCInterfaceDecl * ID,bool Weak)6675 llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CodeGenFunction &CGF,
6676 const ObjCInterfaceDecl *ID,
6677 bool Weak) {
6678 llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];
6679 if (!Entry) {
6680 llvm::SmallString<64> MetaClassName(getMetaclassSymbolPrefix());
6681 MetaClassName += ID->getObjCRuntimeNameAsString();
6682 llvm::GlobalVariable *MetaClassGV =
6683 GetClassGlobal(MetaClassName.str(), Weak);
6684
6685 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
6686 false, llvm::GlobalValue::PrivateLinkage,
6687 MetaClassGV, "OBJC_CLASSLIST_SUP_REFS_$_");
6688 Entry->setAlignment(
6689 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABIPtrTy));
6690
6691 Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
6692 CGM.addCompilerUsedGlobal(Entry);
6693 }
6694
6695 return CGF.Builder.CreateLoad(Entry);
6696 }
6697
6698 /// GetClass - Return a reference to the class for the given interface
6699 /// decl.
GetClass(CodeGenFunction & CGF,const ObjCInterfaceDecl * ID)6700 llvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,
6701 const ObjCInterfaceDecl *ID) {
6702 if (ID->isWeakImported()) {
6703 llvm::SmallString<64> ClassName(getClassSymbolPrefix());
6704 ClassName += ID->getObjCRuntimeNameAsString();
6705 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(), true);
6706 (void)ClassGV;
6707 assert(ClassGV->hasExternalWeakLinkage());
6708 }
6709
6710 return EmitClassRef(CGF, ID);
6711 }
6712
6713 /// Generates a message send where the super is the receiver. This is
6714 /// a message send to self with special delivery semantics indicating
6715 /// which class's method should be called.
6716 CodeGen::RValue
GenerateMessageSendSuper(CodeGen::CodeGenFunction & CGF,ReturnValueSlot Return,QualType ResultType,Selector Sel,const ObjCInterfaceDecl * Class,bool isCategoryImpl,llvm::Value * Receiver,bool IsClassMessage,const CodeGen::CallArgList & CallArgs,const ObjCMethodDecl * Method)6717 CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
6718 ReturnValueSlot Return,
6719 QualType ResultType,
6720 Selector Sel,
6721 const ObjCInterfaceDecl *Class,
6722 bool isCategoryImpl,
6723 llvm::Value *Receiver,
6724 bool IsClassMessage,
6725 const CodeGen::CallArgList &CallArgs,
6726 const ObjCMethodDecl *Method) {
6727 // ...
6728 // Create and init a super structure; this is a (receiver, class)
6729 // pair we will pass to objc_msgSendSuper.
6730 llvm::Value *ObjCSuper =
6731 CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super");
6732
6733 llvm::Value *ReceiverAsObject =
6734 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
6735 CGF.Builder.CreateStore(
6736 ReceiverAsObject,
6737 CGF.Builder.CreateStructGEP(ObjCTypes.SuperTy, ObjCSuper, 0));
6738
6739 // If this is a class message the metaclass is passed as the target.
6740 llvm::Value *Target;
6741 if (IsClassMessage)
6742 Target = EmitMetaClassRef(CGF, Class, Class->isWeakImported());
6743 else
6744 Target = EmitSuperClassRef(CGF, Class);
6745
6746 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
6747 // ObjCTypes types.
6748 llvm::Type *ClassTy =
6749 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
6750 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
6751 CGF.Builder.CreateStore(
6752 Target, CGF.Builder.CreateStructGEP(ObjCTypes.SuperTy, ObjCSuper, 1));
6753
6754 return (isVTableDispatchedSelector(Sel))
6755 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
6756 ObjCSuper, ObjCTypes.SuperPtrCTy,
6757 true, CallArgs, Method)
6758 : EmitMessageSend(CGF, Return, ResultType,
6759 EmitSelector(CGF, Sel),
6760 ObjCSuper, ObjCTypes.SuperPtrCTy,
6761 true, CallArgs, Method, ObjCTypes);
6762 }
6763
EmitSelector(CodeGenFunction & CGF,Selector Sel,bool lval)6764 llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF,
6765 Selector Sel, bool lval) {
6766 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
6767
6768 if (!Entry) {
6769 llvm::Constant *Casted =
6770 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
6771 ObjCTypes.SelectorPtrTy);
6772 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.SelectorPtrTy,
6773 false, llvm::GlobalValue::PrivateLinkage,
6774 Casted, "OBJC_SELECTOR_REFERENCES_");
6775 Entry->setExternallyInitialized(true);
6776 Entry->setSection("__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
6777 CGM.addCompilerUsedGlobal(Entry);
6778 }
6779
6780 if (lval)
6781 return Entry;
6782 llvm::LoadInst* LI = CGF.Builder.CreateLoad(Entry);
6783
6784 LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
6785 llvm::MDNode::get(VMContext, None));
6786 return LI;
6787 }
6788 /// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
6789 /// objc_assign_ivar (id src, id *dst, ptrdiff_t)
6790 ///
EmitObjCIvarAssign(CodeGen::CodeGenFunction & CGF,llvm::Value * src,llvm::Value * dst,llvm::Value * ivarOffset)6791 void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
6792 llvm::Value *src,
6793 llvm::Value *dst,
6794 llvm::Value *ivarOffset) {
6795 llvm::Type * SrcTy = src->getType();
6796 if (!isa<llvm::PointerType>(SrcTy)) {
6797 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
6798 assert(Size <= 8 && "does not support size > 8");
6799 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6800 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
6801 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6802 }
6803 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6804 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
6805 llvm::Value *args[] = { src, dst, ivarOffset };
6806 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
6807 }
6808
6809 /// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
6810 /// objc_assign_strongCast (id src, id *dst)
6811 ///
EmitObjCStrongCastAssign(CodeGen::CodeGenFunction & CGF,llvm::Value * src,llvm::Value * dst)6812 void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
6813 CodeGen::CodeGenFunction &CGF,
6814 llvm::Value *src, llvm::Value *dst) {
6815 llvm::Type * SrcTy = src->getType();
6816 if (!isa<llvm::PointerType>(SrcTy)) {
6817 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
6818 assert(Size <= 8 && "does not support size > 8");
6819 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6820 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
6821 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6822 }
6823 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6824 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
6825 llvm::Value *args[] = { src, dst };
6826 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
6827 args, "weakassign");
6828 }
6829
EmitGCMemmoveCollectable(CodeGen::CodeGenFunction & CGF,llvm::Value * DestPtr,llvm::Value * SrcPtr,llvm::Value * Size)6830 void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
6831 CodeGen::CodeGenFunction &CGF,
6832 llvm::Value *DestPtr,
6833 llvm::Value *SrcPtr,
6834 llvm::Value *Size) {
6835 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
6836 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
6837 llvm::Value *args[] = { DestPtr, SrcPtr, Size };
6838 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
6839 }
6840
6841 /// EmitObjCWeakRead - Code gen for loading value of a __weak
6842 /// object: objc_read_weak (id *src)
6843 ///
EmitObjCWeakRead(CodeGen::CodeGenFunction & CGF,llvm::Value * AddrWeakObj)6844 llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
6845 CodeGen::CodeGenFunction &CGF,
6846 llvm::Value *AddrWeakObj) {
6847 llvm::Type* DestTy =
6848 cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
6849 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
6850 llvm::Value *read_weak =
6851 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
6852 AddrWeakObj, "weakread");
6853 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
6854 return read_weak;
6855 }
6856
6857 /// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
6858 /// objc_assign_weak (id src, id *dst)
6859 ///
EmitObjCWeakAssign(CodeGen::CodeGenFunction & CGF,llvm::Value * src,llvm::Value * dst)6860 void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
6861 llvm::Value *src, llvm::Value *dst) {
6862 llvm::Type * SrcTy = src->getType();
6863 if (!isa<llvm::PointerType>(SrcTy)) {
6864 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
6865 assert(Size <= 8 && "does not support size > 8");
6866 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6867 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
6868 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6869 }
6870 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6871 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
6872 llvm::Value *args[] = { src, dst };
6873 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
6874 args, "weakassign");
6875 }
6876
6877 /// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
6878 /// objc_assign_global (id src, id *dst)
6879 ///
EmitObjCGlobalAssign(CodeGen::CodeGenFunction & CGF,llvm::Value * src,llvm::Value * dst,bool threadlocal)6880 void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
6881 llvm::Value *src, llvm::Value *dst,
6882 bool threadlocal) {
6883 llvm::Type * SrcTy = src->getType();
6884 if (!isa<llvm::PointerType>(SrcTy)) {
6885 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
6886 assert(Size <= 8 && "does not support size > 8");
6887 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6888 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
6889 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6890 }
6891 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6892 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
6893 llvm::Value *args[] = { src, dst };
6894 if (!threadlocal)
6895 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
6896 args, "globalassign");
6897 else
6898 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
6899 args, "threadlocalassign");
6900 }
6901
6902 void
EmitSynchronizedStmt(CodeGen::CodeGenFunction & CGF,const ObjCAtSynchronizedStmt & S)6903 CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
6904 const ObjCAtSynchronizedStmt &S) {
6905 EmitAtSynchronizedStmt(CGF, S,
6906 cast<llvm::Function>(ObjCTypes.getSyncEnterFn()),
6907 cast<llvm::Function>(ObjCTypes.getSyncExitFn()));
6908 }
6909
6910 llvm::Constant *
GetEHType(QualType T)6911 CGObjCNonFragileABIMac::GetEHType(QualType T) {
6912 // There's a particular fixed type info for 'id'.
6913 if (T->isObjCIdType() ||
6914 T->isObjCQualifiedIdType()) {
6915 llvm::Constant *IDEHType =
6916 CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id");
6917 if (!IDEHType)
6918 IDEHType =
6919 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy,
6920 false,
6921 llvm::GlobalValue::ExternalLinkage,
6922 nullptr, "OBJC_EHTYPE_id");
6923 return IDEHType;
6924 }
6925
6926 // All other types should be Objective-C interface pointer types.
6927 const ObjCObjectPointerType *PT =
6928 T->getAs<ObjCObjectPointerType>();
6929 assert(PT && "Invalid @catch type.");
6930 const ObjCInterfaceType *IT = PT->getInterfaceType();
6931 assert(IT && "Invalid @catch type.");
6932 return GetInterfaceEHType(IT->getDecl(), false);
6933 }
6934
EmitTryStmt(CodeGen::CodeGenFunction & CGF,const ObjCAtTryStmt & S)6935 void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
6936 const ObjCAtTryStmt &S) {
6937 EmitTryCatchStmt(CGF, S,
6938 cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()),
6939 cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()),
6940 cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn()));
6941 }
6942
6943 /// EmitThrowStmt - Generate code for a throw statement.
EmitThrowStmt(CodeGen::CodeGenFunction & CGF,const ObjCAtThrowStmt & S,bool ClearInsertionPoint)6944 void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
6945 const ObjCAtThrowStmt &S,
6946 bool ClearInsertionPoint) {
6947 if (const Expr *ThrowExpr = S.getThrowExpr()) {
6948 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
6949 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
6950 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception)
6951 .setDoesNotReturn();
6952 } else {
6953 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn())
6954 .setDoesNotReturn();
6955 }
6956
6957 CGF.Builder.CreateUnreachable();
6958 if (ClearInsertionPoint)
6959 CGF.Builder.ClearInsertionPoint();
6960 }
6961
6962 llvm::Constant *
GetInterfaceEHType(const ObjCInterfaceDecl * ID,bool ForDefinition)6963 CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
6964 bool ForDefinition) {
6965 llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
6966
6967 // If we don't need a definition, return the entry if found or check
6968 // if we use an external reference.
6969 if (!ForDefinition) {
6970 if (Entry)
6971 return Entry;
6972
6973 // If this type (or a super class) has the __objc_exception__
6974 // attribute, emit an external reference.
6975 if (hasObjCExceptionAttribute(CGM.getContext(), ID))
6976 return Entry =
6977 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
6978 llvm::GlobalValue::ExternalLinkage,
6979 nullptr,
6980 ("OBJC_EHTYPE_$_" +
6981 ID->getObjCRuntimeNameAsString()));
6982 }
6983
6984 // Otherwise we need to either make a new entry or fill in the
6985 // initializer.
6986 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition");
6987 llvm::SmallString<64> ClassName(getClassSymbolPrefix());
6988 ClassName += ID->getObjCRuntimeNameAsString();
6989 std::string VTableName = "objc_ehtype_vtable";
6990 llvm::GlobalVariable *VTableGV =
6991 CGM.getModule().getGlobalVariable(VTableName);
6992 if (!VTableGV)
6993 VTableGV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy,
6994 false,
6995 llvm::GlobalValue::ExternalLinkage,
6996 nullptr, VTableName);
6997
6998 llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2);
6999
7000 llvm::Constant *Values[] = {
7001 llvm::ConstantExpr::getGetElementPtr(VTableGV->getValueType(), VTableGV,
7002 VTableIdx),
7003 GetClassName(ID->getObjCRuntimeNameAsString()),
7004 GetClassGlobal(ClassName.str())};
7005 llvm::Constant *Init =
7006 llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values);
7007
7008 llvm::GlobalValue::LinkageTypes L = ForDefinition
7009 ? llvm::GlobalValue::ExternalLinkage
7010 : llvm::GlobalValue::WeakAnyLinkage;
7011 if (Entry) {
7012 Entry->setInitializer(Init);
7013 } else {
7014 llvm::SmallString<64> EHTYPEName("OBJC_EHTYPE_$_");
7015 EHTYPEName += ID->getObjCRuntimeNameAsString();
7016 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
7017 L,
7018 Init,
7019 EHTYPEName.str());
7020 }
7021 assert(Entry->getLinkage() == L);
7022
7023 if (ID->getVisibility() == HiddenVisibility)
7024 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
7025 Entry->setAlignment(CGM.getDataLayout().getABITypeAlignment(
7026 ObjCTypes.EHTypeTy));
7027
7028 if (ForDefinition)
7029 Entry->setSection("__DATA,__objc_const");
7030 else
7031 Entry->setSection("__DATA,__datacoal_nt,coalesced");
7032
7033 return Entry;
7034 }
7035
7036 /* *** */
7037
7038 CodeGen::CGObjCRuntime *
CreateMacObjCRuntime(CodeGen::CodeGenModule & CGM)7039 CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
7040 switch (CGM.getLangOpts().ObjCRuntime.getKind()) {
7041 case ObjCRuntime::FragileMacOSX:
7042 return new CGObjCMac(CGM);
7043
7044 case ObjCRuntime::MacOSX:
7045 case ObjCRuntime::iOS:
7046 return new CGObjCNonFragileABIMac(CGM);
7047
7048 case ObjCRuntime::GNUstep:
7049 case ObjCRuntime::GCC:
7050 case ObjCRuntime::ObjFW:
7051 llvm_unreachable("these runtimes are not Mac runtimes");
7052 }
7053 llvm_unreachable("bad runtime");
7054 }
7055