Bug Summary

File:clang/lib/CodeGen/CGObjCMac.cpp
Warning:line 2603, column 26
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name CGObjCMac.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -D CLANG_VENDOR="Debian " -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809/build-llvm/tools/clang/lib/CodeGen -I /build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809/clang/lib/CodeGen -I /build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809/clang/include -I /build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809/build-llvm/include -I /build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809/build-llvm/tools/clang/lib/CodeGen -fdebug-prefix-map=/build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fno-common -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2019-12-07-102640-14763-1 -x c++ /build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809/clang/lib/CodeGen/CGObjCMac.cpp

/build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809/clang/lib/CodeGen/CGObjCMac.cpp

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