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