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