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