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