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