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