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