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