1c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar//===------- CGObjCMac.cpp - Interface to Apple Objective-C Runtime -------===//
2c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar//
3c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar//                     The LLVM Compiler Infrastructure
4c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar//
5c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar// This file is distributed under the University of Illinois Open Source
6c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar// License. See LICENSE.TXT for details.
7c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar//
8c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar//===----------------------------------------------------------------------===//
9c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar//
10fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner// This provides Objective-C code generation targeting the Apple runtime.
11c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar//
12c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar//===----------------------------------------------------------------------===//
13c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
14c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar#include "CGObjCRuntime.h"
15f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar
16198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar#include "CGRecordLayout.h"
17f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar#include "CodeGenModule.h"
18b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar#include "CodeGenFunction.h"
19d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall#include "CGBlocks.h"
2036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall#include "CGCleanup.h"
21bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar#include "clang/AST/ASTContext.h"
22e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar#include "clang/AST/Decl.h"
236efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar#include "clang/AST/DeclObjC.h"
2419cc4abea06a9b49e0e16a50d335c064cd723572Anders Carlsson#include "clang/AST/RecordLayout.h"
2516f0049415ec596504891259e2a83e19871c0d52Chris Lattner#include "clang/AST/StmtObjC.h"
26f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar#include "clang/Basic/LangOptions.h"
2706057cef0bcd7804e80f3ce2bbe352178396c715Chandler Carruth#include "clang/Frontend/CodeGenOptions.h"
28f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar
2987bb5822bfa4baea23a3d9273df266777f3ab796John McCall#include "llvm/InlineAsm.h"
3087bb5822bfa4baea23a3d9273df266777f3ab796John McCall#include "llvm/IntrinsicInst.h"
3169243825cb5c91ec7207256aa57ae327cfaf8cb2Owen Anderson#include "llvm/LLVMContext.h"
32bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar#include "llvm/Module.h"
330c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar#include "llvm/ADT/DenseSet.h"
34330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar#include "llvm/ADT/SetVector.h"
35330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar#include "llvm/ADT/SmallString.h"
36191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian#include "llvm/ADT/SmallPtrSet.h"
378e3f86193995c47ee0d229e4336c3382410f09f5John McCall#include "llvm/Support/CallSite.h"
38330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar#include "llvm/Support/raw_ostream.h"
394e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar#include "llvm/Target/TargetData.h"
40f42e4a6e089e8413247400fe58ad299193371f9cTorok Edwin#include <cstdio>
41c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
42c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbarusing namespace clang;
4346f45b9bec4a265ad8400a538e5ec3a5683617f1Daniel Dunbarusing namespace CodeGen;
44c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
459777687562c338601c2f17906e65e1c1a0aad96fDaniel Dunbar
46c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbarnamespace {
47bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar
486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbartypedef std::vector<llvm::Constant*> ConstantVector;
49ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar
506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar// FIXME: We should find a nicer way to make the labels for metadata, string
516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar// concatenation is lame.
526efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
53ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianclass ObjCCommonTypesHelper {
54a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Andersonprotected:
55a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson  llvm::LLVMContext &VMContext;
566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
57d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanianprivate:
580774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  // The types of these functions don't really matter because we
590774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  // should always bitcast before calling them.
600774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall
610774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// id objc_msgSend (id, SEL, ...)
620774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  ///
630774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// The default messenger, used for sends whose ABI is unchanged from
640774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// the all-integer/pointer case.
65d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getMessageSendFn() const {
66f85e193739c953358c865005855253af4f68a497John McCall    // Add the non-lazy-bind attribute, since objc_msgSend is likely to
67f85e193739c953358c865005855253af4f68a497John McCall    // be called a lot.
689cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
690774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
700774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                             params, true),
71f85e193739c953358c865005855253af4f68a497John McCall                                     "objc_msgSend",
72f85e193739c953358c865005855253af4f68a497John McCall                                     llvm::Attribute::NonLazyBind);
73d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  }
746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
750774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// void objc_msgSend_stret (id, SEL, ...)
760774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  ///
770774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// The messenger used when the return value is an aggregate returned
780774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// by indirect reference in the first argument, and therefore the
790774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// self and selector parameters are shifted over by one.
80d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getMessageSendStretFn() const {
819cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
820774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,
830774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                             params, true),
840774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                     "objc_msgSend_stret");
856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
86d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  }
876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
880774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// [double | long double] objc_msgSend_fpret(id self, SEL op, ...)
890774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  ///
900774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// The messenger used when the return value is returned on the x87
910774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// floating-point stack; without a special entrypoint, the nil case
920774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// would be unbalanced.
93d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getMessageSendFpretFn() const {
949cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
950774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(
960032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson                                             llvm::Type::getDoubleTy(VMContext),
970774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                        params, true),
980774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                     "objc_msgSend_fpret");
996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
100d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  }
1016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1020774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
1030774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  ///
1040774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// The messenger used for super calls, which have different dispatch
1050774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// semantics.  The class passed is the superclass of the current
1060774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// class.
107d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getMessageSendSuperFn() const {
1089cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
10996e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
1100774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                             params, true),
1110774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                     "objc_msgSendSuper");
112d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  }
1136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1140774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// id objc_msgSendSuper2(struct objc_super *super, SEL op, ...)
1150774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  ///
1160774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// A slightly different messenger used for super calls.  The class
1170774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// passed is the current class.
118d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getMessageSendSuperFn2() const {
1199cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
12096e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
1210774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                             params, true),
1220774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                     "objc_msgSendSuper2");
123d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  }
1246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1250774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// void objc_msgSendSuper_stret(void *stretAddr, struct objc_super *super,
1260774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  ///                              SEL op, ...)
1270774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  ///
1280774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// The messenger used for super calls which return an aggregate indirectly.
129d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getMessageSendSuperStretFn() const {
1309cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
131a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    return CGM.CreateRuntimeFunction(
1320774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(CGM.VoidTy, params, true),
1336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      "objc_msgSendSuper_stret");
134d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  }
1356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1360774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super,
1370774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  ///                               SEL op, ...)
1380774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  ///
1390774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// objc_msgSendSuper_stret with the super2 semantics.
140d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getMessageSendSuperStretFn2() const {
1419cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
142a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    return CGM.CreateRuntimeFunction(
1430774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(CGM.VoidTy, params, true),
1446bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      "objc_msgSendSuper2_stret");
145d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  }
1466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
147d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getMessageSendSuperFpretFn() const {
148d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    // There is no objc_msgSendSuper_fpret? How can that work?
149d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    return getMessageSendSuperFn();
150d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  }
1516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
152d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getMessageSendSuperFpretFn2() const {
153d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    // There is no objc_msgSendSuper_fpret? How can that work?
154d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    return getMessageSendSuperFn2();
155d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  }
1566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
157ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianprotected:
158ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  CodeGen::CodeGenModule &CGM;
1596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
160bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbarpublic:
1619cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ShortTy, *IntTy, *LongTy, *LongLongTy;
1629cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *Int8PtrTy;
1636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1642bedbf8549bb33293c6a53e5da6cbd8de290d014Daniel Dunbar  /// ObjectPtrTy - LLVM type for object handles (typeof(id))
1659cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ObjectPtrTy;
1666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1676d657c4809d9128be88705d32768de007b988212Fariborz Jahanian  /// PtrObjectPtrTy - LLVM type for id *
1689cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *PtrObjectPtrTy;
1696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1704e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
1719cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *SelectorPtrTy;
1726efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// ProtocolPtrTy - LLVM type for external protocol handles
1736efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// (typeof(Protocol))
1749cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ExternalProtocolPtrTy;
1756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
17619cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar  // SuperCTy - clang type for struct objc_super.
17719cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar  QualType SuperCTy;
17819cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar  // SuperPtrCTy - clang type for struct objc_super *.
17919cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar  QualType SuperPtrCTy;
1806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
181e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar  /// SuperTy - LLVM type for struct objc_super.
1829cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *SuperTy;
18314c80b7ed64e0eddfbe81adf5113d5be5f9964bfDaniel Dunbar  /// SuperPtrTy - LLVM type for struct objc_super *.
1849cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *SuperPtrTy;
1856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
18630bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
18730bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  /// in GCC parlance).
1889cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *PropertyTy;
1896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
19030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  /// PropertyListTy - LLVM type for struct objc_property_list
19130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  /// (_prop_list_t in GCC parlance).
1929cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *PropertyListTy;
19330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
1949cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *PropertyListPtrTy;
1956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
19630bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // MethodTy - LLVM type for struct objc_method.
1979cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *MethodTy;
1986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
199d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  /// CacheTy - LLVM type for struct objc_cache.
2009cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *CacheTy;
201d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  /// CachePtrTy - LLVM type for struct objc_cache *.
2029cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *CachePtrTy;
2039d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian
20472db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  llvm::Constant *getGetPropertyFn() {
20572db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    CodeGen::CodeGenTypes &Types = CGM.getTypes();
20672db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    ASTContext &Ctx = CGM.getContext();
20772db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    // id objc_getProperty (id, SEL, ptrdiff_t, bool)
2085f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<CanQualType,4> Params;
209ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
210ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
21172db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    Params.push_back(IdType);
21272db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    Params.push_back(SelType);
213ab5824e97666ca7a91ed3013524cee18420866f1David Chisnall    Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
21472db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    Params.push_back(Ctx.BoolTy);
2152acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *FTy =
21604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall      Types.GetFunctionType(Types.getFunctionInfo(IdType, Params,
217264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola                                                  FunctionType::ExtInfo()),
218264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola                            false);
21972db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    return CGM.CreateRuntimeFunction(FTy, "objc_getProperty");
22072db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  }
2216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
22272db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  llvm::Constant *getSetPropertyFn() {
22372db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    CodeGen::CodeGenTypes &Types = CGM.getTypes();
22472db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    ASTContext &Ctx = CGM.getContext();
22572db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool)
2265f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<CanQualType,6> Params;
227ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
228ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
22972db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    Params.push_back(IdType);
23072db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    Params.push_back(SelType);
231ab5824e97666ca7a91ed3013524cee18420866f1David Chisnall    Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
23272db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    Params.push_back(IdType);
23372db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    Params.push_back(Ctx.BoolTy);
23472db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    Params.push_back(Ctx.BoolTy);
2352acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *FTy =
23604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall      Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
237264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola                                                  FunctionType::ExtInfo()),
238264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola                            false);
23972db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    return CGM.CreateRuntimeFunction(FTy, "objc_setProperty");
24072db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  }
2416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
2426cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian
2436cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian  llvm::Constant *getCopyStructFn() {
2446cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian    CodeGen::CodeGenTypes &Types = CGM.getTypes();
2456cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian    ASTContext &Ctx = CGM.getContext();
2466cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian    // void objc_copyStruct (void *, const void *, size_t, bool, bool)
2475f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<CanQualType,5> Params;
2486cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian    Params.push_back(Ctx.VoidPtrTy);
2496cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian    Params.push_back(Ctx.VoidPtrTy);
2506cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian    Params.push_back(Ctx.LongTy);
2516cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian    Params.push_back(Ctx.BoolTy);
2526cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian    Params.push_back(Ctx.BoolTy);
2532acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *FTy =
2546cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian      Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
2556cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian                                                  FunctionType::ExtInfo()),
2566cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian                            false);
2576cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian    return CGM.CreateRuntimeFunction(FTy, "objc_copyStruct");
2586cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian  }
2596cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian
26072db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  llvm::Constant *getEnumerationMutationFn() {
261c1ab900fa5e9b8a09b042992eeca29f413b1d595Daniel Dunbar    CodeGen::CodeGenTypes &Types = CGM.getTypes();
262c1ab900fa5e9b8a09b042992eeca29f413b1d595Daniel Dunbar    ASTContext &Ctx = CGM.getContext();
26372db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    // void objc_enumerationMutation (id)
2645f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<CanQualType,1> Params;
265ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType()));
2662acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *FTy =
26704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall      Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
268264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola                                                  FunctionType::ExtInfo()),
269264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola                            false);
27072db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
27172db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  }
2726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
273db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian  /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function.
27472db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  llvm::Constant *getGcReadWeakFn() {
27572db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    // id objc_read_weak (id *)
2769cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *args[] = { ObjectPtrTy->getPointerTo() };
2776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    llvm::FunctionType *FTy =
2780774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(ObjectPtrTy, args, false);
27972db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    return CGM.CreateRuntimeFunction(FTy, "objc_read_weak");
2806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  }
2816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
282db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian  /// GcAssignWeakFn -- LLVM objc_assign_weak function.
28396508e1fea58347b6401ca9a4728c0b268174603Chris Lattner  llvm::Constant *getGcAssignWeakFn() {
28496508e1fea58347b6401ca9a4728c0b268174603Chris Lattner    // id objc_assign_weak (id, id *)
2859cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
28696508e1fea58347b6401ca9a4728c0b268174603Chris Lattner    llvm::FunctionType *FTy =
2870774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(ObjectPtrTy, args, false);
28896508e1fea58347b6401ca9a4728c0b268174603Chris Lattner    return CGM.CreateRuntimeFunction(FTy, "objc_assign_weak");
28996508e1fea58347b6401ca9a4728c0b268174603Chris Lattner  }
2906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
291db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian  /// GcAssignGlobalFn -- LLVM objc_assign_global function.
292bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  llvm::Constant *getGcAssignGlobalFn() {
293bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner    // id objc_assign_global(id, id *)
2949cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
295a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    llvm::FunctionType *FTy =
2960774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(ObjectPtrTy, args, false);
297bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner    return CGM.CreateRuntimeFunction(FTy, "objc_assign_global");
298bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  }
2996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
300021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian  /// GcAssignThreadLocalFn -- LLVM objc_assign_threadlocal function.
301021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian  llvm::Constant *getGcAssignThreadLocalFn() {
302021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian    // id objc_assign_threadlocal(id src, id * dest)
3039cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
304021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian    llvm::FunctionType *FTy =
3050774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(ObjectPtrTy, args, false);
306021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian    return CGM.CreateRuntimeFunction(FTy, "objc_assign_threadlocal");
307021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian  }
308021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian
309db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian  /// GcAssignIvarFn -- LLVM objc_assign_ivar function.
310bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  llvm::Constant *getGcAssignIvarFn() {
3116c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian    // id objc_assign_ivar(id, id *, ptrdiff_t)
3129cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo(),
3139cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                           CGM.PtrDiffTy };
314a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    llvm::FunctionType *FTy =
3150774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(ObjectPtrTy, args, false);
316bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner    return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar");
317bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  }
3186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
319082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  /// GcMemmoveCollectableFn -- LLVM objc_memmove_collectable function.
320082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  llvm::Constant *GcMemmoveCollectableFn() {
321082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian    // void *objc_memmove_collectable(void *dst, const void *src, size_t size)
3229cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy };
3230774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall    llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args, false);
324082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian    return CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable");
325082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  }
3266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
327db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian  /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function.
328bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  llvm::Constant *getGcAssignStrongCastFn() {
329021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian    // id objc_assign_strongCast(id, id *)
3309cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
331a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    llvm::FunctionType *FTy =
3320774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(ObjectPtrTy, args, false);
333bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner    return CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast");
334bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  }
335f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson
336f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson  /// ExceptionThrowFn - LLVM objc_exception_throw function.
337bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  llvm::Constant *getExceptionThrowFn() {
338bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner    // void objc_exception_throw(id)
3399cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *args[] = { ObjectPtrTy };
340bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner    llvm::FunctionType *FTy =
3410774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(CGM.VoidTy, args, false);
342bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner    return CGM.CreateRuntimeFunction(FTy, "objc_exception_throw");
343bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  }
3446bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
34569677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian  /// ExceptionRethrowFn - LLVM objc_exception_rethrow function.
34669677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian  llvm::Constant *getExceptionRethrowFn() {
34769677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian    // void objc_exception_rethrow(void)
3480774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall    llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, false);
34969677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian    return CGM.CreateRuntimeFunction(FTy, "objc_exception_rethrow");
35069677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian  }
35169677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian
3521c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar  /// SyncEnterFn - LLVM object_sync_enter function.
353b02e53b5a859f12ad1e3f90a22b6fb711901a172Chris Lattner  llvm::Constant *getSyncEnterFn() {
354b02e53b5a859f12ad1e3f90a22b6fb711901a172Chris Lattner    // void objc_sync_enter (id)
3559cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *args[] = { ObjectPtrTy };
356b02e53b5a859f12ad1e3f90a22b6fb711901a172Chris Lattner    llvm::FunctionType *FTy =
3570774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(CGM.VoidTy, args, false);
358b02e53b5a859f12ad1e3f90a22b6fb711901a172Chris Lattner    return CGM.CreateRuntimeFunction(FTy, "objc_sync_enter");
359b02e53b5a859f12ad1e3f90a22b6fb711901a172Chris Lattner  }
3606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3611c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar  /// SyncExitFn - LLVM object_sync_exit function.
362bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  llvm::Constant *getSyncExitFn() {
363bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner    // void objc_sync_exit (id)
3649cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *args[] = { ObjectPtrTy };
365bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner    llvm::FunctionType *FTy =
3660774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(CGM.VoidTy, args, false);
367bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner    return CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
368bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  }
3696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
370d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getSendFn(bool IsSuper) const {
371d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
3724176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner  }
3736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
374d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getSendFn2(bool IsSuper) const {
375d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
3764176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner  }
3776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
378d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getSendStretFn(bool IsSuper) const {
379d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
3804176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner  }
3816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
382d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getSendStretFn2(bool IsSuper) const {
383d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
3844176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner  }
3856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
386d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getSendFpretFn(bool IsSuper) const {
387d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
3884176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner  }
3896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
390d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getSendFpretFn2(bool IsSuper) const {
391d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
3924176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner  }
3936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
394d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm);
395d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  ~ObjCCommonTypesHelper(){}
396d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian};
397ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian
398d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian/// ObjCTypesHelper - Helper class that encapsulates lazy
399d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian/// construction of varies types used during ObjC generation.
400d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanianclass ObjCTypesHelper : public ObjCCommonTypesHelper {
401ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianpublic:
4024e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  /// SymtabTy - LLVM type for struct objc_symtab.
4039cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *SymtabTy;
40427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// SymtabPtrTy - LLVM type for struct objc_symtab *.
4059cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *SymtabPtrTy;
4064e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  /// ModuleTy - LLVM type for struct objc_module.
4079cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *ModuleTy;
408259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar
4096efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// ProtocolTy - LLVM type for struct objc_protocol.
4109cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *ProtocolTy;
4116efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
4129cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ProtocolPtrTy;
4136efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// ProtocolExtensionTy - LLVM type for struct
4146efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// objc_protocol_extension.
4159cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *ProtocolExtensionTy;
4166efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// ProtocolExtensionTy - LLVM type for struct
4176efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// objc_protocol_extension *.
4189cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ProtocolExtensionPtrTy;
4196efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// MethodDescriptionTy - LLVM type for struct
4206efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// objc_method_description.
4219cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *MethodDescriptionTy;
4226efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// MethodDescriptionListTy - LLVM type for struct
4236efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// objc_method_description_list.
4249cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *MethodDescriptionListTy;
4256efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// MethodDescriptionListPtrTy - LLVM type for struct
4266efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// objc_method_description_list *.
4279cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *MethodDescriptionListPtrTy;
4286efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// ProtocolListTy - LLVM type for struct objc_property_list.
4299cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *ProtocolListTy;
4306efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
4319cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ProtocolListPtrTy;
43286e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  /// CategoryTy - LLVM type for struct objc_category.
4339cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *CategoryTy;
43427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// ClassTy - LLVM type for struct objc_class.
4359cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *ClassTy;
43627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// ClassPtrTy - LLVM type for struct objc_class *.
4379cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ClassPtrTy;
43827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// ClassExtensionTy - LLVM type for struct objc_class_ext.
4399cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *ClassExtensionTy;
44027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
4419cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ClassExtensionPtrTy;
44227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // IvarTy - LLVM type for struct objc_ivar.
4439cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *IvarTy;
44427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// IvarListTy - LLVM type for struct objc_ivar_list.
4459cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *IvarListTy;
44627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
4479cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *IvarListPtrTy;
44827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// MethodListTy - LLVM type for struct objc_method_list.
4499cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *MethodListTy;
45027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// MethodListPtrTy - LLVM type for struct objc_method_list *.
4519cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *MethodListPtrTy;
4526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
453124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson  /// ExceptionDataTy - LLVM type for struct _objc_exception_data.
4549cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ExceptionDataTy;
4559d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian
456124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson  /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.
45734b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner  llvm::Constant *getExceptionTryEnterFn() {
4589cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
459a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    return CGM.CreateRuntimeFunction(
4600774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(CGM.VoidTy, params, false),
4616bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      "objc_exception_try_enter");
46234b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner  }
463124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson
464124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson  /// ExceptionTryExitFn - LLVM objc_exception_try_exit function.
46534b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner  llvm::Constant *getExceptionTryExitFn() {
4669cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
467a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    return CGM.CreateRuntimeFunction(
4680774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(CGM.VoidTy, params, false),
4696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      "objc_exception_try_exit");
47034b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner  }
471124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson
472124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson  /// ExceptionExtractFn - LLVM objc_exception_extract function.
47334b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner  llvm::Constant *getExceptionExtractFn() {
4749cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
47596e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
4760774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                             params, false),
47734b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner                                     "objc_exception_extract");
47834b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner  }
4796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
480124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson  /// ExceptionMatchFn - LLVM objc_exception_match function.
48134b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner  llvm::Constant *getExceptionMatchFn() {
4829cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy };
4836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    return CGM.CreateRuntimeFunction(
4840774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(CGM.Int32Ty, params, false),
4856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      "objc_exception_match");
4866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
48734b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner  }
4886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
489124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson  /// SetJmpFn - LLVM _setjmp function.
49034b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner  llvm::Constant *getSetJmpFn() {
4910774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall    // This is specifically the prototype for x86.
4929cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { CGM.Int32Ty->getPointerTo() };
4930774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty,
4940774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                             params, false),
4950774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                     "_setjmp");
49634b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner  }
4976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
498bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbarpublic:
499bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar  ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
500ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  ~ObjCTypesHelper() {}
501bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar};
502bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar
50330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian/// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's
504ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian/// modern abi
50530bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanianclass ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {
50683a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanianpublic:
5076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
508d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // MethodListnfABITy - LLVM for struct _method_list_t
5099cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *MethodListnfABITy;
5106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
511d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // MethodListnfABIPtrTy - LLVM for struct _method_list_t*
5129cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *MethodListnfABIPtrTy;
5136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
514d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // ProtocolnfABITy = LLVM for struct _protocol_t
5159cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *ProtocolnfABITy;
5166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
517948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar  // ProtocolnfABIPtrTy = LLVM for struct _protocol_t*
5189cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ProtocolnfABIPtrTy;
519948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar
520d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // ProtocolListnfABITy - LLVM for struct _objc_protocol_list
5219cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *ProtocolListnfABITy;
5226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
523d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list*
5249cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ProtocolListnfABIPtrTy;
5256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
526d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // ClassnfABITy - LLVM for struct _class_t
5279cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *ClassnfABITy;
5286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
529aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  // ClassnfABIPtrTy - LLVM for struct _class_t*
5309cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ClassnfABIPtrTy;
5316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
532d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // IvarnfABITy - LLVM for struct _ivar_t
5339cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *IvarnfABITy;
5346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
535d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // IvarListnfABITy - LLVM for struct _ivar_list_t
5369cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *IvarListnfABITy;
5376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
538d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t*
5399cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *IvarListnfABIPtrTy;
5406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
541d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // ClassRonfABITy - LLVM for struct _class_ro_t
5429cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *ClassRonfABITy;
5436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
544d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
5459cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ImpnfABITy;
5466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
547d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // CategorynfABITy - LLVM for struct _category_t
5489cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *CategorynfABITy;
5496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5502e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // New types for nonfragile abi messaging.
5516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5522e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // MessageRefTy - LLVM for:
5532e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // struct _message_ref_t {
5542e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  //   IMP messenger;
5552e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  //   SEL name;
5562e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // };
5579cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *MessageRefTy;
55883a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  // MessageRefCTy - clang type for struct _message_ref_t
55983a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  QualType MessageRefCTy;
5606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5612e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // MessageRefPtrTy - LLVM for struct _message_ref_t*
5629cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *MessageRefPtrTy;
56383a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  // MessageRefCPtrTy - clang type for struct _message_ref_t*
56483a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  QualType MessageRefCPtrTy;
5656bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
566ef163782d227f064df5988d46487609324a0169eFariborz Jahanian  // MessengerTy - Type of the messenger (shown as IMP above)
5679cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::FunctionType *MessengerTy;
5686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5692e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // SuperMessageRefTy - LLVM for:
5702e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // struct _super_message_ref_t {
5712e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  //   SUPER_IMP messenger;
5722e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  //   SEL name;
5732e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // };
5749cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *SuperMessageRefTy;
5756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5762e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
5779cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *SuperMessageRefPtrTy;
5788ecbaf25c1373be6fb5a9d332b08b6be16d9fd4eDaniel Dunbar
5791c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner  llvm::Constant *getMessageSendFixupFn() {
5801c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner    // id objc_msgSend_fixup(id, struct message_ref_t*, ...)
5819cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
58296e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
5830774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                             params, true),
5841c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner                                     "objc_msgSend_fixup");
5851c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner  }
5866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5871c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner  llvm::Constant *getMessageSendFpretFixupFn() {
5881c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner    // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...)
5899cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
59096e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
5910774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                             params, true),
5921c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner                                     "objc_msgSend_fpret_fixup");
5931c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner  }
5946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5951c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner  llvm::Constant *getMessageSendStretFixupFn() {
5961c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner    // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...)
5979cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
59896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
5990774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                             params, true),
6001c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner                                     "objc_msgSend_stret_fixup");
6011c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner  }
6026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
6031c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner  llvm::Constant *getMessageSendSuper2FixupFn() {
6046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    // id objc_msgSendSuper2_fixup (struct objc_super *,
6051c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner    //                              struct _super_message_ref_t*, ...)
6069cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
60796e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    return  CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
6080774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                              params, true),
6091c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner                                      "objc_msgSendSuper2_fixup");
6101c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner  }
6116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
6121c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner  llvm::Constant *getMessageSendSuper2StretFixupFn() {
6136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    // id objc_msgSendSuper2_stret_fixup(struct objc_super *,
6141c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner    //                                   struct _super_message_ref_t*, ...)
6159cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
61696e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    return  CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
6170774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                              params, true),
6181c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner                                      "objc_msgSendSuper2_stret_fixup");
6191c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner  }
6206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
6218a56911956aa875922a5faa3787c6829e7f7011fChris Lattner  llvm::Constant *getObjCEndCatchFn() {
6220774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy, false),
6238a56911956aa875922a5faa3787c6829e7f7011fChris Lattner                                     "objc_end_catch");
6246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
6258a56911956aa875922a5faa3787c6829e7f7011fChris Lattner  }
6266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
6278a56911956aa875922a5faa3787c6829e7f7011fChris Lattner  llvm::Constant *getObjCBeginCatchFn() {
6289cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { Int8PtrTy };
62996e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy,
6300774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                             params, false),
6318a56911956aa875922a5faa3787c6829e7f7011fChris Lattner                                     "objc_begin_catch");
6328a56911956aa875922a5faa3787c6829e7f7011fChris Lattner  }
633e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar
6349cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *EHTypeTy;
6359cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *EHTypePtrTy;
6369d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian
63730bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
63830bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  ~ObjCNonFragileABITypesHelper(){}
639ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian};
6406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
641ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianclass CGObjCCommonMac : public CodeGen::CGObjCRuntime {
6429397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanianpublic:
6439397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  // FIXME - accessibility
644a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian  class GC_IVAR {
645820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian  public:
6468b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar    unsigned ivar_bytepos;
6478b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar    unsigned ivar_size;
6488b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar    GC_IVAR(unsigned bytepos = 0, unsigned size = 0)
6496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      : ivar_bytepos(bytepos), ivar_size(size) {}
6500941b49af3b7204ddb69ed21f07c966b8d949cf4Daniel Dunbar
6510941b49af3b7204ddb69ed21f07c966b8d949cf4Daniel Dunbar    // Allow sorting based on byte pos.
6520941b49af3b7204ddb69ed21f07c966b8d949cf4Daniel Dunbar    bool operator<(const GC_IVAR &b) const {
6530941b49af3b7204ddb69ed21f07c966b8d949cf4Daniel Dunbar      return ivar_bytepos < b.ivar_bytepos;
6540941b49af3b7204ddb69ed21f07c966b8d949cf4Daniel Dunbar    }
655a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian  };
6566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
6579397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  class SKIP_SCAN {
6588b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar  public:
6598b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar    unsigned skip;
6608b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar    unsigned scan;
6616bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    SKIP_SCAN(unsigned _skip = 0, unsigned _scan = 0)
6628b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar      : skip(_skip), scan(_scan) {}
6639397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  };
6646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
665ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianprotected:
666ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  CodeGen::CodeGenModule &CGM;
66769243825cb5c91ec7207256aa57ae327cfaf8cb2Owen Anderson  llvm::LLVMContext &VMContext;
668ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  // FIXME! May not be needing this after all.
669bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar  unsigned ObjCABI;
6706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
6719397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  // gc ivar layout bitmap calculation helper caches.
6725f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<GC_IVAR, 16> SkipIvars;
6735f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<GC_IVAR, 16> IvarsInfo;
6746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
675242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  /// LazySymbols - Symbols to generate a lazy reference for. See
676242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  /// DefinedSymbols and FinishModule().
677330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar  llvm::SetVector<IdentifierInfo*> LazySymbols;
6786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
679242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  /// DefinedSymbols - External symbols which are defined by this
680242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  /// module. The symbols in this list and LazySymbols are used to add
681242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  /// special linker symbols which ensure that Objective-C modules are
682242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  /// linked properly.
683330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar  llvm::SetVector<IdentifierInfo*> DefinedSymbols;
6846bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
6854e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  /// ClassNames - uniqued class names.
6866efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
6876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
688259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar  /// MethodVarNames - uniqued method variable names.
689259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar  llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
6906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
691b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian  /// DefinedCategoryNames - list of category names in form Class_Category.
692b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian  llvm::SetVector<std::string> DefinedCategoryNames;
693b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian
6946efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// MethodVarTypes - uniqued method type signatures. We have to use
6956efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// a StringMap here because have no other unique reference.
6966efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
6976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
698c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar  /// MethodDefinitions - map of methods which have been defined in
699c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar  /// this translation unit.
700c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar  llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
7016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
702c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar  /// PropertyNames - uniqued method variable names.
703c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
7046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
70527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// ClassReferences - uniqued class references.
70627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
7076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
708259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar  /// SelectorReferences - uniqued selector references.
709259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar  llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
7106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
7116efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// Protocols - Protocols for which an objc_protocol structure has
7126efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// been emitted. Forward declarations are handled by creating an
7136efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// empty structure whose initializer is filled in when/if defined.
7146efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
7156bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
7160c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  /// DefinedProtocols - Protocols which have actually been
7170c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  /// defined. We should not need this, see FIXME in GenerateProtocol.
7180c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  llvm::DenseSet<IdentifierInfo*> DefinedProtocols;
7196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
72027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// DefinedClasses - List of defined classes.
72127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  std::vector<llvm::GlobalValue*> DefinedClasses;
72274d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar
72374d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar  /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
72474d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar  std::vector<llvm::GlobalValue*> DefinedNonLazyClasses;
7256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
72627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// DefinedCategories - List of defined categories.
72727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  std::vector<llvm::GlobalValue*> DefinedCategories;
7286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
72974d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar  /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
73074d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar  std::vector<llvm::GlobalValue*> DefinedNonLazyCategories;
7316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
73256210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  /// GetNameForMethod - Return a name for the given method.
73356210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  /// \param[out] NameOut - The return value.
73456210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  void GetNameForMethod(const ObjCMethodDecl *OMD,
73556210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian                        const ObjCContainerDecl *CD,
7365f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                        SmallVectorImpl<char> &NameOut);
7376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
73856210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  /// GetMethodVarName - Return a unique constant for the given
73956210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  /// selector's name. The return value has type char *.
74056210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  llvm::Constant *GetMethodVarName(Selector Sel);
74156210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
7426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
74356210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  /// GetMethodVarType - Return a unique constant for the given
74456210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  /// selector's name. The return value has type char *.
7456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
74656210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  // FIXME: This is a horrible name.
74756210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D);
7483e5f0d88d7eda79b7a679188d1e6da54cec72f5dDaniel Dunbar  llvm::Constant *GetMethodVarType(const FieldDecl *D);
7496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
75056210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  /// GetPropertyName - Return a unique constant for the given
75156210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  /// name. The return value has type char *.
75256210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
7536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
75456210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  // FIXME: This can be dropped once string functions are unified.
75556210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,
75656210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian                                        const Decl *Container);
7576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
758058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  /// GetClassName - Return a unique constant for the given selector's
759058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  /// name. The return value has type char *.
760058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  llvm::Constant *GetClassName(IdentifierInfo *Ident);
7616bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
7629d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis  llvm::Function *GetMethodDefinition(const ObjCMethodDecl *MD);
7639d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis
764d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian  /// BuildIvarLayout - Builds ivar layout bitmap for the class
765d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian  /// implementation for the __strong or __weak case.
766d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian  ///
767c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian  llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI,
768c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian                                  bool ForStrongLayout);
76993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
770b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian  llvm::Constant *BuildIvarLayoutBitmap(std::string &BitMap);
7716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
772d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar  void BuildAggrIvarRecordLayout(const RecordType *RT,
7736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                 unsigned int BytePos, bool ForStrongLayout,
7746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                 bool &HasUnion);
7755a5a803df8a8e3e567278fdfd8a6c1aff8dc6b82Daniel Dunbar  void BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
776c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian                           const llvm::StructLayout *Layout,
777a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian                           const RecordDecl *RD,
778db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose                           const SmallVectorImpl<const FieldDecl*> &RecFields,
779d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian                           unsigned int BytePos, bool ForStrongLayout,
78081adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian                           bool &HasUnion);
781c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian
782d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian  /// GetIvarLayoutName - Returns a unique constant for the given
783d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian  /// ivar layout bitmap.
784d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian  llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident,
785d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian                                    const ObjCCommonTypesHelper &ObjCTypes);
7866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
7875de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian  /// EmitPropertyList - Emit the given property list. The return
7885de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian  /// value has type PropertyListPtrTy.
7895f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  llvm::Constant *EmitPropertyList(Twine Name,
7906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                   const Decl *Container,
7915de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian                                   const ObjCContainerDecl *OCD,
7925de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian                                   const ObjCCommonTypesHelper &ObjCTypes);
7936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
794191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian  /// PushProtocolProperties - Push protocol's property on the input stack.
795191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian  void PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet,
796191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian                              std::vector<llvm::Constant*> &Properties,
797191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian                                   const Decl *Container,
798191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian                                   const ObjCProtocolDecl *PROTO,
799191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian                                   const ObjCCommonTypesHelper &ObjCTypes);
800191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian
801da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// GetProtocolRef - Return a reference to the internal protocol
802da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// description, creating an empty one if it has not been
803da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// defined. The return value has type ProtocolPtrTy.
804da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD);
805b21f07e056b6c9918bf938f19ca561c60f778695Fariborz Jahanian
806fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar  /// CreateMetadataVar - Create a global variable with internal
807fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar  /// linkage for use by the Objective-C runtime.
808fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar  ///
809fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar  /// This is a convenience wrapper which not only creates the
810fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar  /// variable, but also sets the section and alignment and adds the
811ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  /// global to the "llvm.used" list.
81235bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar  ///
81335bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar  /// \param Name - The variable name.
81435bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar  /// \param Init - The variable initializer; this is also used to
81535bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar  /// define the type of the variable.
81635bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar  /// \param Section - The section the variable should go into, or 0.
81735bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar  /// \param Align - The alignment for the variable, or 0.
81835bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar  /// \param AddToUsed - Whether the variable should be added to
819c15830694f2bd01080e6c39a88c5b8ff2288af18Daniel Dunbar  /// "llvm.used".
8205f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  llvm::GlobalVariable *CreateMetadataVar(Twine Name,
821fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar                                          llvm::Constant *Init,
822fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar                                          const char *Section,
82335bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar                                          unsigned Align,
82435bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar                                          bool AddToUsed);
825fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar
826944c84313da15477eb18d90babb0890d10d98082John McCall  CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
827944c84313da15477eb18d90babb0890d10d98082John McCall                                  ReturnValueSlot Return,
828944c84313da15477eb18d90babb0890d10d98082John McCall                                  QualType ResultType,
829944c84313da15477eb18d90babb0890d10d98082John McCall                                  llvm::Value *Sel,
830944c84313da15477eb18d90babb0890d10d98082John McCall                                  llvm::Value *Arg0,
831944c84313da15477eb18d90babb0890d10d98082John McCall                                  QualType Arg0Ty,
832944c84313da15477eb18d90babb0890d10d98082John McCall                                  bool IsSuper,
833944c84313da15477eb18d90babb0890d10d98082John McCall                                  const CallArgList &CallArgs,
834944c84313da15477eb18d90babb0890d10d98082John McCall                                  const ObjCMethodDecl *OMD,
835944c84313da15477eb18d90babb0890d10d98082John McCall                                  const ObjCCommonTypesHelper &ObjCTypes);
8363e5f0d88d7eda79b7a679188d1e6da54cec72f5dDaniel Dunbar
837fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar  /// EmitImageInfo - Emit the image info marker used to encode some module
838fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar  /// level information.
839fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar  void EmitImageInfo();
840fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar
841ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianpublic:
84269243825cb5c91ec7207256aa57ae327cfaf8cb2Owen Anderson  CGObjCCommonMac(CodeGen::CodeGenModule &cgm) :
8431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    CGM(cgm), VMContext(cgm.getLLVMContext()) { }
8446bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
8450d13f6fdbdd6f06e2449b8834dda53334abd399aDavid Chisnall  virtual llvm::Constant *GenerateConstantString(const StringLiteral *SL);
8466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
847493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
848493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian                                         const ObjCContainerDecl *CD=0);
8496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
850da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
8516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
852da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// GetOrEmitProtocol - Get the protocol object for the given
853da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// declaration, emitting it if necessary. The return value has type
854da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// ProtocolPtrTy.
855da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0;
8566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
857da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// GetOrEmitProtocolRef - Get a forward reference to the protocol
858da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// object for the given declaration, emitting it if needed. These
859da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// forward references will be filled in with empty bodies if no
860da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// definition is seen. The return value has type ProtocolPtrTy.
861da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0;
8626b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  virtual llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
8636b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall                                             const CGBlockInfo &blockInfo);
86489ecd41e0a6bfb3b0913dbe41c3c666340b308c7Fariborz Jahanian
865ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian};
8666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
867ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianclass CGObjCMac : public CGObjCCommonMac {
868ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianprivate:
869ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  ObjCTypesHelper ObjCTypes;
870f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar
8714e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  /// EmitModuleInfo - Another marker encoding module level
8726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  /// information.
8734e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  void EmitModuleInfo();
8744e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
87527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// EmitModuleSymols - Emit module symbols, the list of defined
87627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// classes and categories. The result has type SymtabPtrTy.
8774e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  llvm::Constant *EmitModuleSymbols();
8784e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
879f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar  /// FinishModule - Write out global data structures at the end of
880f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar  /// processing a translation unit.
881f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar  void FinishModule();
8826efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
88327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// EmitClassExtension - Generate the class extension structure used
88427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// to store the weak ivar layout and properties. The return value
88527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// has type ClassExtensionPtrTy.
88627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
88727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
88827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
88927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// for the given class.
8906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Value *EmitClassRef(CGBuilderTy &Builder,
89127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                            const ObjCInterfaceDecl *ID);
892b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian
893f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *EmitClassRefFromId(CGBuilderTy &Builder,
894f85e193739c953358c865005855253af4f68a497John McCall                                  IdentifierInfo *II);
895f85e193739c953358c865005855253af4f68a497John McCall
896f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder);
897f85e193739c953358c865005855253af4f68a497John McCall
898b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  /// EmitSuperClassRef - Emits reference to class's main metadata class.
899b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID);
90027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
90127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// EmitIvarList - Emit the ivar list for the given
90227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// implementation. If ForClass is true the list of class ivars
90327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// (i.e. metaclass ivars) is emitted, otherwise the list of
90427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// interface ivars will be emitted. The return value has type
90527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// IvarListPtrTy.
90627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
90746b86c610ede6d9abdec254f39663db86c9c88e0Fariborz Jahanian                               bool ForClass);
9086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
909f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  /// EmitMetaClass - Emit a forward reference to the class structure
910f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  /// for the metaclass of the given interface. The return value has
911f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  /// type ClassPtrTy.
912f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID);
913f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar
91427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// EmitMetaClass - Emit a class structure for the metaclass of the
915f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  /// given implementation. The return value has type ClassPtrTy.
91627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
91727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                                llvm::Constant *Protocols,
918ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                                const ConstantVector &Methods);
9196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
920ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
9216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
922ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
92327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
92427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// EmitMethodList - Emit the method list for the given
925af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  /// implementation. The return value has type MethodListPtrTy.
9265f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  llvm::Constant *EmitMethodList(Twine Name,
92786e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar                                 const char *Section,
928ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                                 const ConstantVector &Methods);
92927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
93027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// EmitMethodDescList - Emit a method description list for a list of
9316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  /// method declarations.
9326efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  ///  - TypeName: The name for the type containing the methods.
9336efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  ///  - IsProtocol: True iff these methods are for a protocol.
9346efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  ///  - ClassMethds: True iff these are class methods.
9356efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  ///  - Required: When true, only "required" methods are
9366efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  ///    listed. Similarly, when false only "optional" methods are
9376efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  ///    listed. For classes this should always be true.
9386efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  ///  - begin, end: The method list to output.
9396efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  ///
9406efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// The return value has type MethodDescriptionListPtrTy.
9415f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  llvm::Constant *EmitMethodDescList(Twine Name,
942ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                                     const char *Section,
943ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                                     const ConstantVector &Methods);
9446efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
9450c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  /// GetOrEmitProtocol - Get the protocol object for the given
9460c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  /// declaration, emitting it if necessary. The return value has type
9470c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  /// ProtocolPtrTy.
948da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
9490c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar
9500c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  /// GetOrEmitProtocolRef - Get a forward reference to the protocol
9510c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  /// object for the given declaration, emitting it if needed. These
9520c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  /// forward references will be filled in with empty bodies if no
9530c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  /// definition is seen. The return value has type ProtocolPtrTy.
954da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
9550c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar
9566efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// EmitProtocolExtension - Generate the protocol extension
9576efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// structure used to store optional instance and class methods, and
9586efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// protocol properties. The return value has type
9596efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// ProtocolExtensionPtrTy.
960ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  llvm::Constant *
961ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  EmitProtocolExtension(const ObjCProtocolDecl *PD,
962ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                        const ConstantVector &OptInstanceMethods,
963ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                        const ConstantVector &OptClassMethods);
9646efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
9656efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// EmitProtocolList - Generate the list of referenced
9666efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// protocols. The return value has type ProtocolListPtrTy.
9675f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  llvm::Constant *EmitProtocolList(Twine Name,
968dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar                                   ObjCProtocolDecl::protocol_iterator begin,
969dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar                                   ObjCProtocolDecl::protocol_iterator end);
9706efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
97127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
97227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// for the given selector.
97303b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian  llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel,
97403b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian                            bool lval=false);
9756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
9766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarpublic:
977c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar  CGObjCMac(CodeGen::CodeGenModule &cgm);
978c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
979aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual llvm::Function *ModuleInitFunction();
9806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
9818f2926b73ed635afecd020da787af6a837601a2bDaniel Dunbar  virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
982ef072fd2f3347cfd857d6eb787b245b950771430John McCall                                              ReturnValueSlot Return,
9837f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                                              QualType ResultType,
9847f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                                              Selector Sel,
985f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar                                              llvm::Value *Receiver,
986df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian                                              const CallArgList &CallArgs,
987c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall                                              const ObjCInterfaceDecl *Class,
988df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian                                              const ObjCMethodDecl *Method);
9898f2926b73ed635afecd020da787af6a837601a2bDaniel Dunbar
9906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  virtual CodeGen::RValue
9918f2926b73ed635afecd020da787af6a837601a2bDaniel Dunbar  GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
992ef072fd2f3347cfd857d6eb787b245b950771430John McCall                           ReturnValueSlot Return,
9937f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                           QualType ResultType,
9947f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                           Selector Sel,
995f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar                           const ObjCInterfaceDecl *Class,
9967ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian                           bool isCategoryImpl,
997f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar                           llvm::Value *Receiver,
99819cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar                           bool IsClassMessage,
999d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                           const CallArgList &CallArgs,
1000d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                           const ObjCMethodDecl *Method);
10016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
100245d196b8387dcefc4df26cda114fa34c6528e928Daniel Dunbar  virtual llvm::Value *GetClass(CGBuilderTy &Builder,
100327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                                const ObjCInterfaceDecl *ID);
1004c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
100503b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian  virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel,
100603b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian                                   bool lval = false);
1007df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian
1008df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian  /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1009df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian  /// untyped one.
1010df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian  virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
1011df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian                                   const ObjCMethodDecl *Method);
1012df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian
1013cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian  virtual llvm::Constant *GetEHType(QualType T);
10145a180397870944548aaadeaebf58e415885b9489John McCall
10157ded7f4983dc4a20561db7a8d02c6b2435030961Daniel Dunbar  virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
10167ded7f4983dc4a20561db7a8d02c6b2435030961Daniel Dunbar
10177ded7f4983dc4a20561db7a8d02c6b2435030961Daniel Dunbar  virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
1018c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
101945d196b8387dcefc4df26cda114fa34c6528e928Daniel Dunbar  virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
1020af2f62ce32e462f256855cd24b06dec4755d2827Daniel Dunbar                                           const ObjCProtocolDecl *PD);
10216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
102274391b48b4791cded373683a3baf67314f358d50Chris Lattner  virtual llvm::Constant *GetPropertyGetFunction();
102374391b48b4791cded373683a3baf67314f358d50Chris Lattner  virtual llvm::Constant *GetPropertySetFunction();
10248fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall  virtual llvm::Constant *GetGetStructFunction();
10258fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall  virtual llvm::Constant *GetSetStructFunction();
102674391b48b4791cded373683a3baf67314f358d50Chris Lattner  virtual llvm::Constant *EnumerationMutationFunction();
10276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1028f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1029f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                           const ObjCAtTryStmt &S);
1030f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1031f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                                    const ObjCAtSynchronizedStmt &S);
1032f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const Stmt &S);
103364d5d6c5903157c521af496479d06dc26032d718Anders Carlsson  virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
103464d5d6c5903157c521af496479d06dc26032d718Anders Carlsson                             const ObjCAtThrowStmt &S);
10353e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian  virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
10366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                         llvm::Value *AddrWeakObj);
10373e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian  virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
10386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                  llvm::Value *src, llvm::Value *dst);
103958626500527695865683d1d65053743de8770b60Fariborz Jahanian  virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1040021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                                    llvm::Value *src, llvm::Value *dest,
1041021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                                    bool threadlocal = false);
10427eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian  virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
10436c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian                                  llvm::Value *src, llvm::Value *dest,
10446c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian                                  llvm::Value *ivarOffset);
104558626500527695865683d1d65053743de8770b60Fariborz Jahanian  virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
104658626500527695865683d1d65053743de8770b60Fariborz Jahanian                                        llvm::Value *src, llvm::Value *dest);
1047082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1048082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian                                        llvm::Value *dest, llvm::Value *src,
104955bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian                                        llvm::Value *size);
10506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1051598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian  virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
1052598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                      QualType ObjectTy,
1053598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                      llvm::Value *BaseValue,
1054598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                      const ObjCIvarDecl *Ivar,
1055598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                      unsigned CVRQualifiers);
1056f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian  virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
10572a03192a02dbf4fdff438d1e658356bde871aba4Daniel Dunbar                                      const ObjCInterfaceDecl *Interface,
1058f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian                                      const ObjCIvarDecl *Ivar);
10596f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian
10606f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian  /// GetClassGlobal - Return the global variable for the Objective-C
10616f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian  /// class of the given name.
10626f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian  virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) {
1063b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie    llvm_unreachable("CGObjCMac::GetClassGlobal");
10646f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian  }
1065c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar};
10666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
106730bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanianclass CGObjCNonFragileABIMac : public CGObjCCommonMac {
1068ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianprivate:
106930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  ObjCNonFragileABITypesHelper ObjCTypes;
1070aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  llvm::GlobalVariable* ObjCEmptyCacheVar;
1071aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  llvm::GlobalVariable* ObjCEmptyVtableVar;
10726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
10731139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar  /// SuperClassReferences - uniqued super class references.
10741139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
10756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
10767a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  /// MetaClassReferences - uniqued meta class references.
10777a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
1078e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar
1079e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  /// EHTypeReferences - uniqued class ehtype references.
1080e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
10816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1082944c84313da15477eb18d90babb0890d10d98082John McCall  /// VTableDispatchMethods - List of methods for which we generate
1083944c84313da15477eb18d90babb0890d10d98082John McCall  /// vtable-based message dispatch.
1084944c84313da15477eb18d90babb0890d10d98082John McCall  llvm::DenseSet<Selector> VTableDispatchMethods;
10856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1086a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian  /// DefinedMetaClasses - List of defined meta-classes.
1087a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian  std::vector<llvm::GlobalValue*> DefinedMetaClasses;
1088a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian
1089944c84313da15477eb18d90babb0890d10d98082John McCall  /// isVTableDispatchedSelector - Returns true if SEL is a
1090944c84313da15477eb18d90babb0890d10d98082John McCall  /// vtable-based selector.
1091944c84313da15477eb18d90babb0890d10d98082John McCall  bool isVTableDispatchedSelector(Selector Sel);
10926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1093aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  /// FinishNonFragileABIModule - Write out global data structures at the end of
1094aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  /// processing a translation unit.
1095aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  void FinishNonFragileABIModule();
10968158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar
1097463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar  /// AddModuleClassList - Add the given list of class pointers to the
1098463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar  /// module with the provided symbol and section names.
1099463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar  void AddModuleClassList(const std::vector<llvm::GlobalValue*> &Container,
1100463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar                          const char *SymbolName,
1101463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar                          const char *SectionName);
1102463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar
11036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags,
11046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                              unsigned InstanceStart,
11056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                              unsigned InstanceSize,
11066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                              const ObjCImplementationDecl *ID);
110784394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian  llvm::GlobalVariable * BuildClassMetaData(std::string &ClassName,
11086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                            llvm::Constant *IsAGV,
110984394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian                                            llvm::Constant *SuperClassGV,
1110cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian                                            llvm::Constant *ClassRoGV,
1111cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian                                            bool HiddenVisibility);
11126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1113493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
11146bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
11153819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian  llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
11166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1117493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  /// EmitMethodList - Emit the method list for the given
1118493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  /// implementation. The return value has type MethodListnfABITy.
11195f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  llvm::Constant *EmitMethodList(Twine Name,
1120493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian                                 const char *Section,
112198abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian                                 const ConstantVector &Methods);
112298abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  /// EmitIvarList - Emit the ivar list for the given
112398abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  /// implementation. If ForClass is true the list of class ivars
112498abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  /// (i.e. metaclass ivars) is emitted, otherwise the list of
112598abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  /// interface ivars will be emitted. The return value has type
112698abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  /// IvarListnfABIPtrTy.
112798abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID);
11286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1129ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian  llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
11302fa5a27f38b2c4abc26e86895fdcef3ec84af39dFariborz Jahanian                                    const ObjCIvarDecl *Ivar,
11311bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian                                    unsigned long int offset);
11326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1133da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// GetOrEmitProtocol - Get the protocol object for the given
1134da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// declaration, emitting it if necessary. The return value has type
1135da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// ProtocolPtrTy.
1136da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
11376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1138da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1139da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// object for the given declaration, emitting it if needed. These
1140da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// forward references will be filled in with empty bodies if no
1141da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// definition is seen. The return value has type ProtocolPtrTy.
1142da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
11436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1144da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// EmitProtocolList - Generate the list of referenced
1145da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// protocols. The return value has type ProtocolListPtrTy.
11465f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  llvm::Constant *EmitProtocolList(Twine Name,
1147da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                                   ObjCProtocolDecl::protocol_iterator begin,
11484655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian                                   ObjCProtocolDecl::protocol_iterator end);
11496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1150944c84313da15477eb18d90babb0890d10d98082John McCall  CodeGen::RValue EmitVTableMessageSend(CodeGen::CodeGenFunction &CGF,
1151944c84313da15477eb18d90babb0890d10d98082John McCall                                        ReturnValueSlot Return,
1152944c84313da15477eb18d90babb0890d10d98082John McCall                                        QualType ResultType,
1153944c84313da15477eb18d90babb0890d10d98082John McCall                                        Selector Sel,
1154944c84313da15477eb18d90babb0890d10d98082John McCall                                        llvm::Value *Receiver,
1155944c84313da15477eb18d90babb0890d10d98082John McCall                                        QualType Arg0Ty,
1156944c84313da15477eb18d90babb0890d10d98082John McCall                                        bool IsSuper,
1157944c84313da15477eb18d90babb0890d10d98082John McCall                                        const CallArgList &CallArgs,
1158944c84313da15477eb18d90babb0890d10d98082John McCall                                        const ObjCMethodDecl *Method);
11596f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian
11605a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar  /// GetClassGlobal - Return the global variable for the Objective-C
11615a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar  /// class of the given name.
11620f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz Jahanian  llvm::GlobalVariable *GetClassGlobal(const std::string &Name);
11636f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian
11640e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian  /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
11651139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar  /// for the given class reference.
11666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Value *EmitClassRef(CGBuilderTy &Builder,
11671139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar                            const ObjCInterfaceDecl *ID);
1168f85e193739c953358c865005855253af4f68a497John McCall
1169f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *EmitClassRefFromId(CGBuilderTy &Builder,
1170f85e193739c953358c865005855253af4f68a497John McCall                                  IdentifierInfo *II);
1171f85e193739c953358c865005855253af4f68a497John McCall
1172f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder);
11736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
11741139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar  /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
11751139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar  /// for the given super class reference.
11766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Value *EmitSuperClassRef(CGBuilderTy &Builder,
11776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                 const ObjCInterfaceDecl *ID);
11786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
11797a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  /// EmitMetaClassRef - Return a Value * of the address of _class_t
11807a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  /// meta-data
11816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Value *EmitMetaClassRef(CGBuilderTy &Builder,
11827a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian                                const ObjCInterfaceDecl *ID);
11837a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian
1184ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian  /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
1185ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian  /// the given ivar.
1186ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian  ///
11875e88beaa0a86b162dfb9f53891adfdfbe925cc64Daniel Dunbar  llvm::GlobalVariable * ObjCIvarOffsetVariable(
11886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    const ObjCInterfaceDecl *ID,
11896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    const ObjCIvarDecl *Ivar);
11906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
119126cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian  /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
119226cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian  /// for the given selector.
119303b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian  llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel,
119403b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian                            bool lval=false);
1195e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar
11968158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C
1197e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  /// interface. The return value has type EHTypePtrTy.
11985a180397870944548aaadeaebf58e415885b9489John McCall  llvm::Constant *GetInterfaceEHType(const ObjCInterfaceDecl *ID,
11998158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar                                  bool ForDefinition);
12006ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar
12016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const char *getMetaclassSymbolPrefix() const {
12026ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar    return "OBJC_METACLASS_$_";
12036ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar  }
12046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
12056ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar  const char *getClassSymbolPrefix() const {
12066ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar    return "OBJC_CLASS_$_";
12076ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar  }
12086ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar
12099f89f2bc111339ee7fa0df3c2f18e39493b460c4Daniel Dunbar  void GetClassSizeInfo(const ObjCImplementationDecl *OID,
1210b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar                        uint32_t &InstanceStart,
1211b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar                        uint32_t &InstanceSize);
12126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
12134523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian  // Shamelessly stolen from Analysis/CFRefCount.cpp
121474d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar  Selector GetNullarySelector(const char* name) const {
12154523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian    IdentifierInfo* II = &CGM.getContext().Idents.get(name);
12164523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian    return CGM.getContext().Selectors.getSelector(0, &II);
12174523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian  }
12186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
121974d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar  Selector GetUnarySelector(const char* name) const {
12204523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian    IdentifierInfo* II = &CGM.getContext().Idents.get(name);
12214523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian    return CGM.getContext().Selectors.getSelector(1, &II);
12224523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian  }
1223b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar
122474d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar  /// ImplementationIsNonLazy - Check whether the given category or
122574d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar  /// class implementation is "non-lazy".
1226ecfbdcbaf71609ab99cdebbf2d704173070dbaf3Fariborz Jahanian  bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const;
122774d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar
1228ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianpublic:
122930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
1230aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  // FIXME. All stubs for now!
1231aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual llvm::Function *ModuleInitFunction();
12326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1233aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1234ef072fd2f3347cfd857d6eb787b245b950771430John McCall                                              ReturnValueSlot Return,
1235aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian                                              QualType ResultType,
1236aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian                                              Selector Sel,
1237aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian                                              llvm::Value *Receiver,
1238df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian                                              const CallArgList &CallArgs,
1239c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall                                              const ObjCInterfaceDecl *Class,
1240df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian                                              const ObjCMethodDecl *Method);
12416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
12426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  virtual CodeGen::RValue
1243aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1244ef072fd2f3347cfd857d6eb787b245b950771430John McCall                           ReturnValueSlot Return,
1245aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian                           QualType ResultType,
1246aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian                           Selector Sel,
1247aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian                           const ObjCInterfaceDecl *Class,
12487ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian                           bool isCategoryImpl,
1249aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian                           llvm::Value *Receiver,
1250aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian                           bool IsClassMessage,
1251d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                           const CallArgList &CallArgs,
1252d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                           const ObjCMethodDecl *Method);
12536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1254aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual llvm::Value *GetClass(CGBuilderTy &Builder,
12550e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian                                const ObjCInterfaceDecl *ID);
12566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
125703b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian  virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel,
125803b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian                                   bool lvalue = false)
125903b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian    { return EmitSelector(Builder, Sel, lvalue); }
1260df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian
1261df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian  /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1262df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian  /// untyped one.
1263df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian  virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
1264df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian                                   const ObjCMethodDecl *Method)
1265df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian    { return EmitSelector(Builder, Method->getSelector()); }
12666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1267eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian  virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
12686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1269aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
1270aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
12718cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian                                           const ObjCProtocolDecl *PD);
12726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1273cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian  virtual llvm::Constant *GetEHType(QualType T);
12745a180397870944548aaadeaebf58e415885b9489John McCall
12756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  virtual llvm::Constant *GetPropertyGetFunction() {
127672db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    return ObjCTypes.getGetPropertyFn();
1277f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian  }
12786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  virtual llvm::Constant *GetPropertySetFunction() {
12796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    return ObjCTypes.getSetPropertyFn();
1280f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian  }
12816cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian
12828fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall  virtual llvm::Constant *GetSetStructFunction() {
12838fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall    return ObjCTypes.getCopyStructFn();
12848fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall  }
12858fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall  virtual llvm::Constant *GetGetStructFunction() {
12866cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian    return ObjCTypes.getCopyStructFn();
12876cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian  }
12886cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian
128974391b48b4791cded373683a3baf67314f358d50Chris Lattner  virtual llvm::Constant *EnumerationMutationFunction() {
129072db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    return ObjCTypes.getEnumerationMutationFn();
129128ed0847480b76ce76a7e605156608b1cea80e53Daniel Dunbar  }
12926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1293f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1294f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                           const ObjCAtTryStmt &S);
1295f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1296f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                                    const ObjCAtSynchronizedStmt &S);
1297aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
1298f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson                             const ObjCAtThrowStmt &S);
1299aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
13006948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian                                         llvm::Value *AddrWeakObj);
1301aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
13026948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian                                  llvm::Value *src, llvm::Value *dst);
1303aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1304021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                                    llvm::Value *src, llvm::Value *dest,
1305021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                                    bool threadlocal = false);
1306aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
13076c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian                                  llvm::Value *src, llvm::Value *dest,
13086c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian                                  llvm::Value *ivarOffset);
1309aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
13106948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian                                        llvm::Value *src, llvm::Value *dest);
1311082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1312082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian                                        llvm::Value *dest, llvm::Value *src,
131355bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian                                        llvm::Value *size);
1314598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian  virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
1315598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                      QualType ObjectTy,
1316598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                      llvm::Value *BaseValue,
1317598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                      const ObjCIvarDecl *Ivar,
1318598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                      unsigned CVRQualifiers);
1319f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian  virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
13202a03192a02dbf4fdff438d1e658356bde871aba4Daniel Dunbar                                      const ObjCInterfaceDecl *Interface,
1321f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian                                      const ObjCIvarDecl *Ivar);
1322ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian};
13236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1324cba681af356e24ec4335bcf2b6bb6515072ace99John McCall/// A helper class for performing the null-initialization of a return
1325cba681af356e24ec4335bcf2b6bb6515072ace99John McCall/// value.
1326cba681af356e24ec4335bcf2b6bb6515072ace99John McCallstruct NullReturnState {
1327cba681af356e24ec4335bcf2b6bb6515072ace99John McCall  llvm::BasicBlock *NullBB;
1328cba681af356e24ec4335bcf2b6bb6515072ace99John McCall
1329cba681af356e24ec4335bcf2b6bb6515072ace99John McCall  NullReturnState() : NullBB(0) {}
1330cba681af356e24ec4335bcf2b6bb6515072ace99John McCall
1331cba681af356e24ec4335bcf2b6bb6515072ace99John McCall  void init(CodeGenFunction &CGF, llvm::Value *receiver) {
1332cba681af356e24ec4335bcf2b6bb6515072ace99John McCall    // Make blocks for the null-init and call edges.
1333cba681af356e24ec4335bcf2b6bb6515072ace99John McCall    NullBB = CGF.createBasicBlock("msgSend.nullinit");
1334cba681af356e24ec4335bcf2b6bb6515072ace99John McCall    llvm::BasicBlock *callBB = CGF.createBasicBlock("msgSend.call");
1335cba681af356e24ec4335bcf2b6bb6515072ace99John McCall
1336cba681af356e24ec4335bcf2b6bb6515072ace99John McCall    // Check for a null receiver and, if there is one, jump to the
1337cba681af356e24ec4335bcf2b6bb6515072ace99John McCall    // null-init test.
1338cba681af356e24ec4335bcf2b6bb6515072ace99John McCall    llvm::Value *isNull = CGF.Builder.CreateIsNull(receiver);
1339cba681af356e24ec4335bcf2b6bb6515072ace99John McCall    CGF.Builder.CreateCondBr(isNull, NullBB, callBB);
1340cba681af356e24ec4335bcf2b6bb6515072ace99John McCall
1341cba681af356e24ec4335bcf2b6bb6515072ace99John McCall    // Otherwise, start performing the call.
1342cba681af356e24ec4335bcf2b6bb6515072ace99John McCall    CGF.EmitBlock(callBB);
1343cba681af356e24ec4335bcf2b6bb6515072ace99John McCall  }
1344cba681af356e24ec4335bcf2b6bb6515072ace99John McCall
1345cba681af356e24ec4335bcf2b6bb6515072ace99John McCall  RValue complete(CodeGenFunction &CGF, RValue result, QualType resultType) {
1346cba681af356e24ec4335bcf2b6bb6515072ace99John McCall    if (!NullBB) return result;
1347cba681af356e24ec4335bcf2b6bb6515072ace99John McCall
1348cba681af356e24ec4335bcf2b6bb6515072ace99John McCall    // Finish the call path.
1349cba681af356e24ec4335bcf2b6bb6515072ace99John McCall    llvm::BasicBlock *contBB = CGF.createBasicBlock("msgSend.cont");
1350cba681af356e24ec4335bcf2b6bb6515072ace99John McCall    if (CGF.HaveInsertPoint()) CGF.Builder.CreateBr(contBB);
1351cba681af356e24ec4335bcf2b6bb6515072ace99John McCall
1352cba681af356e24ec4335bcf2b6bb6515072ace99John McCall    // Emit the null-init block and perform the null-initialization there.
1353cba681af356e24ec4335bcf2b6bb6515072ace99John McCall    CGF.EmitBlock(NullBB);
1354cba681af356e24ec4335bcf2b6bb6515072ace99John McCall    assert(result.isAggregate() && "null init of non-aggregate result?");
1355cba681af356e24ec4335bcf2b6bb6515072ace99John McCall    CGF.EmitNullInitialization(result.getAggregateAddr(), resultType);
1356cba681af356e24ec4335bcf2b6bb6515072ace99John McCall
1357cba681af356e24ec4335bcf2b6bb6515072ace99John McCall    // Jump to the continuation block.
1358cba681af356e24ec4335bcf2b6bb6515072ace99John McCall    CGF.EmitBlock(contBB);
1359cba681af356e24ec4335bcf2b6bb6515072ace99John McCall
1360cba681af356e24ec4335bcf2b6bb6515072ace99John McCall    return result;
1361cba681af356e24ec4335bcf2b6bb6515072ace99John McCall  }
1362cba681af356e24ec4335bcf2b6bb6515072ace99John McCall};
1363cba681af356e24ec4335bcf2b6bb6515072ace99John McCall
1364c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} // end anonymous namespace
1365bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar
1366bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar/* *** Helper Functions *** */
1367bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar
1368bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar/// getConstantGEP() - Help routine to construct simple GEPs.
1369a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Andersonstatic llvm::Constant *getConstantGEP(llvm::LLVMContext &VMContext,
13706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                      llvm::Constant *C,
1371bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar                                      unsigned idx0,
1372bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar                                      unsigned idx1) {
1373bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar  llvm::Value *Idxs[] = {
13740032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
13750032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
1376bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar  };
1377a5c04344fa70d6eec34344760c1fe511e16f2d76Jay Foad  return llvm::ConstantExpr::getGetElementPtr(C, Idxs);
1378bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar}
1379bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar
13808158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar/// hasObjCExceptionAttribute - Return true if this class or any super
13818158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar/// class has the __objc_exception__ attribute.
13826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstatic bool hasObjCExceptionAttribute(ASTContext &Context,
138368584ed35ad819a1668e3f527ba7f5dd4ae6a333Douglas Gregor                                      const ObjCInterfaceDecl *OID) {
138440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  if (OID->hasAttr<ObjCExceptionAttr>())
13858158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar    return true;
13868158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
138768584ed35ad819a1668e3f527ba7f5dd4ae6a333Douglas Gregor    return hasObjCExceptionAttribute(Context, Super);
13888158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  return false;
13898158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar}
13908158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar
1391bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar/* *** CGObjCMac Public Interface *** */
13926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1393ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz JahanianCGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm),
13941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                                    ObjCTypes(cgm) {
1395ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  ObjCABI = 1;
13966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  EmitImageInfo();
1397c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
1398c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
1399ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar/// GetClass - Return a reference to the class for the given interface
1400ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar/// decl.
140145d196b8387dcefc4df26cda114fa34c6528e928Daniel Dunbarllvm::Value *CGObjCMac::GetClass(CGBuilderTy &Builder,
140227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                                 const ObjCInterfaceDecl *ID) {
140327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  return EmitClassRef(Builder, ID);
1404c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
1405c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
1406c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar/// GetSelector - Return the pointer to the unique'd string for this selector.
140703b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanianllvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, Selector Sel,
140803b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian                                    bool lval) {
140903b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian  return EmitSelector(Builder, Sel, lval);
1410c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
1411df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanianllvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
14126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                    *Method) {
1413df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian  return EmitSelector(Builder, Method->getSelector());
1414df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian}
1415c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
1416cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanianllvm::Constant *CGObjCMac::GetEHType(QualType T) {
14179d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian  if (T->isObjCIdType() ||
14189d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian      T->isObjCQualifiedIdType()) {
14199d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian    return CGM.GetAddrOfRTTIDescriptor(
142001a4cf11777bb34c35f5d251a9e95eb736d0842bDouglas Gregor              CGM.getContext().getObjCIdRedefinitionType(), /*ForEH=*/true);
14219d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian  }
1422cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian  if (T->isObjCClassType() ||
1423cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian      T->isObjCQualifiedClassType()) {
1424cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian    return CGM.GetAddrOfRTTIDescriptor(
142501a4cf11777bb34c35f5d251a9e95eb736d0842bDouglas Gregor             CGM.getContext().getObjCClassRedefinitionType(), /*ForEH=*/true);
1426cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian  }
1427cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian  if (T->isObjCObjectPointerType())
1428cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian    return CGM.GetAddrOfRTTIDescriptor(T,  /*ForEH=*/true);
1429cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian
14305a180397870944548aaadeaebf58e415885b9489John McCall  llvm_unreachable("asking for catch type for ObjC type in fragile runtime");
14315a180397870944548aaadeaebf58e415885b9489John McCall  return 0;
14325a180397870944548aaadeaebf58e415885b9489John McCall}
14335a180397870944548aaadeaebf58e415885b9489John McCall
1434bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar/// Generate a constant CFString object.
14356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar/*
14366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct __builtin_CFString {
14376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const int *isa; // point to __CFConstantStringClassReference
14386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  int flags;
14396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const char *str;
14406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  long length;
14416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  };
1442bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar*/
1443bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar
144433e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian/// or Generate a constant NSString object.
144533e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian/*
144633e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian   struct __builtin_NSString {
144733e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian     const int *isa; // point to __NSConstantStringClassReference
144833e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian     const char *str;
144933e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian     unsigned int length;
145033e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian   };
145133e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian*/
145233e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian
1453aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GenerateConstantString(
14540d13f6fdbdd6f06e2449b8834dda53334abd399aDavid Chisnall  const StringLiteral *SL) {
145533e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian  return (CGM.getLangOptions().NoConstantCFStrings == 0 ?
145633e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian          CGM.GetAddrOfConstantCFString(SL) :
14574c73307c74764ba99e1379677fe92af72f676531Fariborz Jahanian          CGM.GetAddrOfConstantString(SL));
1458c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
1459c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
1460c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar/// Generates a message send where the super is the receiver.  This is
1461c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar/// a message send to self with special delivery semantics indicating
1462c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar/// which class's method should be called.
14638f2926b73ed635afecd020da787af6a837601a2bDaniel DunbarCodeGen::RValue
14648f2926b73ed635afecd020da787af6a837601a2bDaniel DunbarCGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1465ef072fd2f3347cfd857d6eb787b245b950771430John McCall                                    ReturnValueSlot Return,
14667f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                                    QualType ResultType,
14677f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                                    Selector Sel,
1468f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar                                    const ObjCInterfaceDecl *Class,
14697ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian                                    bool isCategoryImpl,
1470f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar                                    llvm::Value *Receiver,
147119cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar                                    bool IsClassMessage,
1472d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                                    const CodeGen::CallArgList &CallArgs,
1473d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                                    const ObjCMethodDecl *Method) {
1474e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar  // Create and init a super structure; this is a (receiver, class)
1475e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar  // pair we will pass to objc_msgSendSuper.
14766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Value *ObjCSuper =
1477604da292483bc94a6a3e4700cd426d4fa7f1a4a8John McCall    CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super");
14786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Value *ReceiverAsObject =
1479e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar    CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
14806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  CGF.Builder.CreateStore(ReceiverAsObject,
1481e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar                          CGF.Builder.CreateStructGEP(ObjCSuper, 0));
1482e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar
1483f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  // If this is a class message the metaclass is passed as the target.
1484f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  llvm::Value *Target;
1485f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  if (IsClassMessage) {
14867ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian    if (isCategoryImpl) {
14877ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      // Message sent to 'super' in a class method defined in a category
14887ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      // implementation requires an odd treatment.
14897ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      // If we are in a class method, we must retrieve the
14907ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      // _metaclass_ for the current class, pointed at by
14917ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      // the class's "isa" pointer.  The following assumes that
14927ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      // isa" is the first ivar in a class (which it must be).
14937ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
14947ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      Target = CGF.Builder.CreateStructGEP(Target, 0);
14957ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      Target = CGF.Builder.CreateLoad(Target);
1496b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump    } else {
14977ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      llvm::Value *MetaClassPtr = EmitMetaClassRef(Class);
14987ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1);
14997ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr);
15007ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      Target = Super;
15016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    }
1502182f2681e75565c9ec3099c90bbc4fcc7782140cFariborz Jahanian  }
1503182f2681e75565c9ec3099c90bbc4fcc7782140cFariborz Jahanian  else if (isCategoryImpl)
1504182f2681e75565c9ec3099c90bbc4fcc7782140cFariborz Jahanian    Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
1505182f2681e75565c9ec3099c90bbc4fcc7782140cFariborz Jahanian  else {
1506b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    llvm::Value *ClassPtr = EmitSuperClassRef(Class);
1507b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    ClassPtr = CGF.Builder.CreateStructGEP(ClassPtr, 1);
1508b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    Target = CGF.Builder.CreateLoad(ClassPtr);
1509f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  }
1510f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
1511f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // ObjCTypes types.
15122acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *ClassTy =
151319cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar    CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
15140c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  Target = CGF.Builder.CreateBitCast(Target, ClassTy);
15156bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  CGF.Builder.CreateStore(Target,
1516f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar                          CGF.Builder.CreateStructGEP(ObjCSuper, 1));
1517944c84313da15477eb18d90babb0890d10d98082John McCall  return EmitMessageSend(CGF, Return, ResultType,
1518944c84313da15477eb18d90babb0890d10d98082John McCall                         EmitSelector(CGF.Builder, Sel),
1519944c84313da15477eb18d90babb0890d10d98082John McCall                         ObjCSuper, ObjCTypes.SuperPtrCTy,
1520944c84313da15477eb18d90babb0890d10d98082John McCall                         true, CallArgs, Method, ObjCTypes);
1521c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
15226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
15236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar/// Generate code for a message send expression.
15248f2926b73ed635afecd020da787af6a837601a2bDaniel DunbarCodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1525ef072fd2f3347cfd857d6eb787b245b950771430John McCall                                               ReturnValueSlot Return,
15267f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                                               QualType ResultType,
15277f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                                               Selector Sel,
1528f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar                                               llvm::Value *Receiver,
1529df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian                                               const CallArgList &CallArgs,
1530c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall                                               const ObjCInterfaceDecl *Class,
1531df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian                                               const ObjCMethodDecl *Method) {
1532944c84313da15477eb18d90babb0890d10d98082John McCall  return EmitMessageSend(CGF, Return, ResultType,
1533944c84313da15477eb18d90babb0890d10d98082John McCall                         EmitSelector(CGF.Builder, Sel),
1534944c84313da15477eb18d90babb0890d10d98082John McCall                         Receiver, CGF.getContext().getObjCIdType(),
1535944c84313da15477eb18d90babb0890d10d98082John McCall                         false, CallArgs, Method, ObjCTypes);
153614c80b7ed64e0eddfbe81adf5113d5be5f9964bfDaniel Dunbar}
153714c80b7ed64e0eddfbe81adf5113d5be5f9964bfDaniel Dunbar
1538d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel DunbarCodeGen::RValue
1539944c84313da15477eb18d90babb0890d10d98082John McCallCGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
1540944c84313da15477eb18d90babb0890d10d98082John McCall                                 ReturnValueSlot Return,
1541944c84313da15477eb18d90babb0890d10d98082John McCall                                 QualType ResultType,
1542944c84313da15477eb18d90babb0890d10d98082John McCall                                 llvm::Value *Sel,
1543944c84313da15477eb18d90babb0890d10d98082John McCall                                 llvm::Value *Arg0,
1544944c84313da15477eb18d90babb0890d10d98082John McCall                                 QualType Arg0Ty,
1545944c84313da15477eb18d90babb0890d10d98082John McCall                                 bool IsSuper,
1546944c84313da15477eb18d90babb0890d10d98082John McCall                                 const CallArgList &CallArgs,
1547944c84313da15477eb18d90babb0890d10d98082John McCall                                 const ObjCMethodDecl *Method,
1548944c84313da15477eb18d90babb0890d10d98082John McCall                                 const ObjCCommonTypesHelper &ObjCTypes) {
154919cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar  CallArgList ActualArgs;
1550d019d96e1ea39cec32f1320b1f9f772aae28247eFariborz Jahanian  if (!IsSuper)
1551578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer    Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy);
155204c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  ActualArgs.add(RValue::get(Arg0), Arg0Ty);
155304c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  ActualArgs.add(RValue::get(Sel), CGF.getContext().getObjCSelType());
1554f85e193739c953358c865005855253af4f68a497John McCall  ActualArgs.addFrom(CallArgs);
15556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1556541b63b1a9db77e4a8670e9823711c2c12e58afbDaniel Dunbar  CodeGenTypes &Types = CGM.getTypes();
155704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs,
1558264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola                                                       FunctionType::ExtInfo());
15592acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::FunctionType *FTy =
15606793966aa221764f579cc8436bd641e1ec339c6dDaniel Dunbar    Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false);
15616bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
15627e70fb217dcdf96faf34df3e197c3831c86f8089Anders Carlsson  if (Method)
15637e70fb217dcdf96faf34df3e197c3831c86f8089Anders Carlsson    assert(CGM.getContext().getCanonicalType(Method->getResultType()) ==
15647e70fb217dcdf96faf34df3e197c3831c86f8089Anders Carlsson           CGM.getContext().getCanonicalType(ResultType) &&
15657e70fb217dcdf96faf34df3e197c3831c86f8089Anders Carlsson           "Result type mismatch!");
15667e70fb217dcdf96faf34df3e197c3831c86f8089Anders Carlsson
1567cba681af356e24ec4335bcf2b6bb6515072ace99John McCall  NullReturnState nullReturn;
1568cba681af356e24ec4335bcf2b6bb6515072ace99John McCall
1569d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *Fn = NULL;
1570dacf9dda17346c628fdd8c5df53c681738db0dc5Daniel Dunbar  if (CGM.ReturnTypeUsesSRet(FnInfo)) {
1571cba681af356e24ec4335bcf2b6bb6515072ace99John McCall    if (!IsSuper) nullReturn.init(CGF, Arg0);
1572d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    Fn = (ObjCABI == 2) ?  ObjCTypes.getSendStretFn2(IsSuper)
15736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      : ObjCTypes.getSendStretFn(IsSuper);
1574dacf9dda17346c628fdd8c5df53c681738db0dc5Daniel Dunbar  } else if (CGM.ReturnTypeUsesFPRet(ResultType)) {
1575dacf9dda17346c628fdd8c5df53c681738db0dc5Daniel Dunbar    Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
1576dacf9dda17346c628fdd8c5df53c681738db0dc5Daniel Dunbar      : ObjCTypes.getSendFpretFn(IsSuper);
15775669e57b4a74d26e9e2fb70d778141d0d849388bDaniel Dunbar  } else {
1578d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
15796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      : ObjCTypes.getSendFn(IsSuper);
15805669e57b4a74d26e9e2fb70d778141d0d849388bDaniel Dunbar  }
1581dacf9dda17346c628fdd8c5df53c681738db0dc5Daniel Dunbar  Fn = llvm::ConstantExpr::getBitCast(Fn, llvm::PointerType::getUnqual(FTy));
1582cba681af356e24ec4335bcf2b6bb6515072ace99John McCall  RValue rvalue = CGF.EmitCall(FnInfo, Fn, Return, ActualArgs);
1583cba681af356e24ec4335bcf2b6bb6515072ace99John McCall  return nullReturn.complete(CGF, rvalue, ResultType);
1584c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
1585c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
158693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanianstatic Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT) {
158793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  if (FQT.isObjCGCStrong())
158893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    return Qualifiers::Strong;
158993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
1590f85e193739c953358c865005855253af4f68a497John McCall  if (FQT.isObjCGCWeak() || FQT.getObjCLifetime() == Qualifiers::OCL_Weak)
159193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    return Qualifiers::Weak;
159293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
159393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
159493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    return Qualifiers::Strong;
159593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
159693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  if (const PointerType *PT = FQT->getAs<PointerType>())
159793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    return GetGCAttrTypeForType(Ctx, PT->getPointeeType());
159893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
159993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  return Qualifiers::GCNone;
160093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian}
160193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
16026b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallllvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
16036b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall                                                const CGBlockInfo &blockInfo) {
16046b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  llvm::Constant *nullPtr =
160544034db24bf59a53aa7699f4bbf59b939710bb3cFariborz Jahanian    llvm::Constant::getNullValue(llvm::Type::getInt8PtrTy(VMContext));
16066b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
1607e289d81369914678db386f6aa86faf8f178e245dDouglas Gregor  if (CGM.getLangOptions().getGC() == LangOptions::NonGC &&
1608f85e193739c953358c865005855253af4f68a497John McCall      !CGM.getLangOptions().ObjCAutoRefCount)
16096b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    return nullPtr;
16106b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
1611a1f024c1a5c49f87ee1d0767afc0437c4e4dbecfFariborz Jahanian  bool hasUnion = false;
161293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  SkipIvars.clear();
161393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  IvarsInfo.clear();
1614bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  unsigned WordSizeInBits = CGM.getContext().getTargetInfo().getPointerWidth(0);
1615bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth();
161693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
161781979822cbf6347116d06dac0e5b06c451bcff05Fariborz Jahanian  // __isa is the first field in block descriptor and must assume by runtime's
161881979822cbf6347116d06dac0e5b06c451bcff05Fariborz Jahanian  // convention that it is GC'able.
161981979822cbf6347116d06dac0e5b06c451bcff05Fariborz Jahanian  IvarsInfo.push_back(GC_IVAR(0, 1));
16206b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
16216b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  const BlockDecl *blockDecl = blockInfo.getBlockDecl();
16226b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
16236b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  // Calculate the basic layout of the block structure.
16246b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  const llvm::StructLayout *layout =
16256b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    CGM.getTargetData().getStructLayout(blockInfo.StructureType);
16266b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
16276b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  // Ignore the optional 'this' capture: C++ objects are not assumed
16286b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  // to be GC'ed.
16296b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
16306b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  // Walk the captured variables.
16316b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(),
16326b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall         ce = blockDecl->capture_end(); ci != ce; ++ci) {
16336b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    const VarDecl *variable = ci->getVariable();
16346b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    QualType type = variable->getType();
16356b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
16366b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
16376b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
16386b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    // Ignore constant captures.
16396b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    if (capture.isConstant()) continue;
16406b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
16416b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    uint64_t fieldOffset = layout->getElementOffset(capture.getIndex());
16426b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
16436b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    // __block variables are passed by their descriptor address.
16446b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    if (ci->isByRef()) {
16456b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall      IvarsInfo.push_back(GC_IVAR(fieldOffset, /*size in words*/ 1));
1646c5904b40c3d76b612fb09c6d2717f646a0af6670Fariborz Jahanian      continue;
16476b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    }
16486b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
16496b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    assert(!type->isArrayType() && "array variable should not be caught");
16506b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    if (const RecordType *record = type->getAs<RecordType>()) {
16516b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall      BuildAggrIvarRecordLayout(record, fieldOffset, true, hasUnion);
1652e1a48984f91cd8a65932f69be25f8330737e9842Fariborz Jahanian      continue;
1653e1a48984f91cd8a65932f69be25f8330737e9842Fariborz Jahanian    }
1654a1f024c1a5c49f87ee1d0767afc0437c4e4dbecfFariborz Jahanian
16556b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), type);
16566b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    unsigned fieldSize = CGM.getContext().getTypeSize(type);
16576b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
16586b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    if (GCAttr == Qualifiers::Strong)
16596b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall      IvarsInfo.push_back(GC_IVAR(fieldOffset,
16606b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall                                  fieldSize / WordSizeInBits));
166193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    else if (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak)
16626b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall      SkipIvars.push_back(GC_IVAR(fieldOffset,
16636b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall                                  fieldSize / ByteSizeInBits));
166493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  }
166593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
166693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  if (IvarsInfo.empty())
16676b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    return nullPtr;
16686b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
16696b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  // Sort on byte position; captures might not be allocated in order,
16706b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  // and unions can do funny things.
16716b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
16726b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  llvm::array_pod_sort(SkipIvars.begin(), SkipIvars.end());
167393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
167493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  std::string BitMap;
1675b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian  llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
167693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  if (CGM.getLangOptions().ObjCGCBitmapPrint) {
167793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    printf("\n block variable layout for block: ");
167893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    const unsigned char *s = (unsigned char*)BitMap.c_str();
167993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    for (unsigned i = 0; i < BitMap.size(); i++)
168093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian      if (!(s[i] & 0xf0))
168193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian        printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
168293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian      else
168393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian        printf("0x%x%s",  s[i], s[i] != 0 ? ", " : "");
168493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    printf("\n");
168593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  }
168693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
168793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  return C;
168889ecd41e0a6bfb3b0913dbe41c3c666340b308c7Fariborz Jahanian}
168989ecd41e0a6bfb3b0913dbe41c3c666340b308c7Fariborz Jahanian
16906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder,
1691af2f62ce32e462f256855cd24b06dec4755d2827Daniel Dunbar                                            const ObjCProtocolDecl *PD) {
1692c67876d6886219983881e1304a761b113ae1aec0Daniel Dunbar  // FIXME: I don't understand why gcc generates this, or where it is
1693f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // resolved. Investigate. Its also wasteful to look this up over and over.
1694c67876d6886219983881e1304a761b113ae1aec0Daniel Dunbar  LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
1695c67876d6886219983881e1304a761b113ae1aec0Daniel Dunbar
16963c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson  return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
16976efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar                                        ObjCTypes.ExternalProtocolPtrTy);
16986efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar}
16996efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
1700da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanianvoid CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
1701f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // FIXME: We shouldn't need this, the protocol decl should contain enough
1702f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // information to tell us whether this was a declaration or a definition.
17030c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  DefinedProtocols.insert(PD->getIdentifier());
17040c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar
17050c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  // If we have generated a forward reference to this protocol, emit
17060c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  // it now. Otherwise do nothing, the protocol objects are lazily
17070c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  // emitted.
17086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  if (Protocols.count(PD->getIdentifier()))
17090c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar    GetOrEmitProtocol(PD);
17100c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar}
17110c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar
1712da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
17130c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  if (DefinedProtocols.count(PD->getIdentifier()))
17140c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar    return GetOrEmitProtocol(PD);
1715f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor
17160c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  return GetOrEmitProtocolRef(PD);
17170c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar}
17180c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar
17196efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar/*
17206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar// APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
17216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstruct _objc_protocol {
17226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstruct _objc_protocol_extension *isa;
17236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarchar *protocol_name;
17246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstruct _objc_protocol_list *protocol_list;
17256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstruct _objc__method_prototype_list *instance_methods;
17266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstruct _objc__method_prototype_list *class_methods
17276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar};
17286efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
17296bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarSee EmitProtocolExtension().
17306efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar*/
17310c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbarllvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
17320c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
17330c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar
17340c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  // Early exit if a defining object has already been generated.
17350c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  if (Entry && Entry->hasInitializer())
17360c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar    return Entry;
17370c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar
1738242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  // FIXME: I don't understand why gcc generates this, or where it is
1739f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // resolved. Investigate. Its also wasteful to look this up over and over.
1740242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
1741242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar
1742ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  // Construct method lists.
1743ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
1744ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
17456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCProtocolDecl::instmeth_iterator
174617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
1747ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar    ObjCMethodDecl *MD = *i;
1748ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar    llvm::Constant *C = GetMethodDescriptionConstant(MD);
1749f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor    if (!C)
1750f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor      return GetOrEmitProtocolRef(PD);
1751f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor
1752ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
1753ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar      OptInstanceMethods.push_back(C);
1754ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar    } else {
1755ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar      InstanceMethods.push_back(C);
17566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    }
1757ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  }
1758ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar
17596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCProtocolDecl::classmeth_iterator
176017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
1761ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar    ObjCMethodDecl *MD = *i;
1762ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar    llvm::Constant *C = GetMethodDescriptionConstant(MD);
1763f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor    if (!C)
1764f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor      return GetOrEmitProtocolRef(PD);
1765f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor
1766ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
1767ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar      OptClassMethods.push_back(C);
1768ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar    } else {
1769ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar      ClassMethods.push_back(C);
17706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    }
1771ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  }
1772ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar
17731d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  llvm::Constant *Values[] = {
17741d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods),
17751d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    GetClassName(PD->getIdentifier()),
17769c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    EmitProtocolList("\01L_OBJC_PROTOCOL_REFS_" + PD->getName(),
1777dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar                     PD->protocol_begin(),
17781d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer                     PD->protocol_end()),
17799c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_" + PD->getName(),
1780ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                       "__OBJC,__cat_inst_meth,regular,no_dead_strip",
17811d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer                       InstanceMethods),
17829c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_" + PD->getName(),
1783ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                       "__OBJC,__cat_cls_meth,regular,no_dead_strip",
17841d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer                       ClassMethods)
17851d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  };
178608e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
17876efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar                                                   Values);
17886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
17896efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  if (Entry) {
17900c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar    // Already created, fix the linkage and update the initializer.
17910c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar    Entry->setLinkage(llvm::GlobalValue::InternalLinkage);
17926efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar    Entry->setInitializer(Init);
17936efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  } else {
17946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry =
17951c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,
17966efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar                               llvm::GlobalValue::InternalLinkage,
17976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                               Init,
17989c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                               "\01L_OBJC_PROTOCOL_" + PD->getName());
17996efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar    Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
18006efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar    // FIXME: Is this necessary? Why only for protocol?
18016efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar    Entry->setAlignment(4);
18026efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  }
1803ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  CGM.AddUsedGlobal(Entry);
18040c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar
18050c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  return Entry;
18066efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar}
18076efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
18080c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbarllvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
18096efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
18106efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
18116efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  if (!Entry) {
18120c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar    // We use the initializer as a marker of whether this is a forward
18130c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar    // reference or not. At module finalization we add the empty
18140c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar    // contents for protocols which were referenced but never defined.
18156bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry =
18161c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,
18170c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar                               llvm::GlobalValue::ExternalLinkage,
18180c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar                               0,
18199c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                               "\01L_OBJC_PROTOCOL_" + PD->getName());
18206efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar    Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
18216efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar    // FIXME: Is this necessary? Why only for protocol?
18226efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar    Entry->setAlignment(4);
18236efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  }
18246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
18256efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  return Entry;
18266efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar}
18276efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
18286efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar/*
18296efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  struct _objc_protocol_extension {
18306bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  uint32_t size;
18316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct objc_method_description_list *optional_instance_methods;
18326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct objc_method_description_list *optional_class_methods;
18336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct objc_property_list *instance_properties;
18346efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  };
18356efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar*/
1836ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbarllvm::Constant *
1837ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel DunbarCGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
1838ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                                 const ConstantVector &OptInstanceMethods,
1839ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                                 const ConstantVector &OptClassMethods) {
18406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  uint64_t Size =
18419408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
18421d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  llvm::Constant *Values[] = {
18431d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    llvm::ConstantInt::get(ObjCTypes.IntTy, Size),
18446bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_"
18459c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                       + PD->getName(),
1846ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                       "__OBJC,__cat_inst_meth,regular,no_dead_strip",
18471d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer                       OptInstanceMethods),
18489c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_" + PD->getName(),
1849ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                       "__OBJC,__cat_cls_meth,regular,no_dead_strip",
18501d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer                       OptClassMethods),
18511d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    EmitPropertyList("\01L_OBJC_$_PROP_PROTO_LIST_" + PD->getName(), 0, PD,
18521d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer                     ObjCTypes)
18531d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  };
18546efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
185527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // Return null if no extension bits are used.
18566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
18576efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar      Values[3]->isNullValue())
1858c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
18596efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
18606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Constant *Init =
186108e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson    llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
18626efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
186363c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar  // No special section, but goes in llvm.used
18649c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar  return CreateMetadataVar("\01L_OBJC_PROTOCOLEXT_" + PD->getName(),
18656bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                           Init,
186663c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar                           0, 0, true);
18676efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar}
18686efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
18696efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar/*
18706efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  struct objc_protocol_list {
18716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct objc_protocol_list *next;
18726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  long count;
18736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Protocol *list[];
18746efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  };
18756efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar*/
1876dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbarllvm::Constant *
18775f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerCGObjCMac::EmitProtocolList(Twine Name,
1878dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar                            ObjCProtocolDecl::protocol_iterator begin,
1879dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar                            ObjCProtocolDecl::protocol_iterator end) {
18806efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  std::vector<llvm::Constant*> ProtocolRefs;
18816efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
1882dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar  for (; begin != end; ++begin)
1883dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar    ProtocolRefs.push_back(GetProtocolRef(*begin));
18846efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
18856efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  // Just return null for empty protocol lists
18866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  if (ProtocolRefs.empty())
1887c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
18886efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
188927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // This list is null terminated.
1890c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
18916efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
1892c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[3];
189327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // This field is only used by the runtime.
1894c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
18954a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy,
18966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                     ProtocolRefs.size() - 1);
18976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[2] =
18986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
18996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                  ProtocolRefs.size()),
19006efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar                             ProtocolRefs);
19016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1902c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
19036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::GlobalVariable *GV =
190463c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar    CreateMetadataVar(Name, Init, "__OBJC,__cat_cls_meth,regular,no_dead_strip",
190558a29128005f6e54c7d3aa39797d86ada8d40006Daniel Dunbar                      4, false);
19063c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
1907c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
1908c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
1909191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanianvoid CGObjCCommonMac::PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet,
1910191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian                                   std::vector<llvm::Constant*> &Properties,
1911191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian                                   const Decl *Container,
1912191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian                                   const ObjCProtocolDecl *PROTO,
1913191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian                                   const ObjCCommonTypesHelper &ObjCTypes) {
1914191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian  for (ObjCProtocolDecl::protocol_iterator P = PROTO->protocol_begin(),
1915191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian         E = PROTO->protocol_end(); P != E; ++P)
1916191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian    PushProtocolProperties(PropertySet, Properties, Container, (*P), ObjCTypes);
1917191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian  for (ObjCContainerDecl::prop_iterator I = PROTO->prop_begin(),
1918191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian       E = PROTO->prop_end(); I != E; ++I) {
1919191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian    const ObjCPropertyDecl *PD = *I;
1920191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian    if (!PropertySet.insert(PD->getIdentifier()))
1921191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian      continue;
19221d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    llvm::Constant *Prop[] = {
19231d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer      GetPropertyName(PD->getIdentifier()),
19241d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer      GetPropertyTypeString(PD, Container)
19251d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    };
1926191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian    Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop));
1927191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian  }
1928191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian}
1929191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian
19306efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar/*
1931c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar  struct _objc_property {
19326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const char * const name;
19336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const char * const attributes;
1934c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar  };
1935c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar
1936c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar  struct _objc_property_list {
19376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  uint32_t entsize; // sizeof (struct _objc_property)
19386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  uint32_t prop_count;
19396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct _objc_property[prop_count];
1940c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar  };
1941c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar*/
19425f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerllvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,
19436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                       const Decl *Container,
19446bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                       const ObjCContainerDecl *OCD,
19456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                       const ObjCCommonTypesHelper &ObjCTypes) {
19461d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  std::vector<llvm::Constant*> Properties;
1947191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian  llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
19486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(),
19496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar         E = OCD->prop_end(); I != E; ++I) {
195093983f8fa120330bf212bfde7e65da2709fb3be8Steve Naroff    const ObjCPropertyDecl *PD = *I;
1951191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian    PropertySet.insert(PD->getIdentifier());
19521d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    llvm::Constant *Prop[] = {
19531d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer      GetPropertyName(PD->getIdentifier()),
19541d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer      GetPropertyTypeString(PD, Container)
19551d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    };
195608e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson    Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
1957c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar                                                   Prop));
1958c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar  }
19596afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian  if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) {
196053b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek    for (ObjCInterfaceDecl::all_protocol_iterator
196153b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek         P = OID->all_referenced_protocol_begin(),
196253b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek         E = OID->all_referenced_protocol_end(); P != E; ++P)
19636afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian      PushProtocolProperties(PropertySet, Properties, Container, (*P),
19646afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian                             ObjCTypes);
19656afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian  }
19666afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian  else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) {
19676afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian    for (ObjCCategoryDecl::protocol_iterator P = CD->protocol_begin(),
19686afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian         E = CD->protocol_end(); P != E; ++P)
19696afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian      PushProtocolProperties(PropertySet, Properties, Container, (*P),
19706afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian                             ObjCTypes);
19716afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian  }
1972c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar
1973c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar  // Return null for empty list.
1974c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar  if (Properties.empty())
1975c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
1976c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar
19776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  unsigned PropertySize =
19789408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    CGM.getTargetData().getTypeAllocSize(ObjCTypes.PropertyTy);
1979c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[3];
19804a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
19814a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
19826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
1983c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar                                             Properties.size());
19847db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson  Values[2] = llvm::ConstantArray::get(AT, Properties);
1985c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
1986c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar
19876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::GlobalVariable *GV =
19886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    CreateMetadataVar(Name, Init,
19896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                      (ObjCABI == 2) ? "__DATA, __objc_const" :
19900bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar                      "__OBJC,__property,regular,no_dead_strip",
19916bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                      (ObjCABI == 2) ? 8 : 4,
19920bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar                      true);
19933c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);
1994c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar}
1995c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar
1996c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar/*
19976efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  struct objc_method_description_list {
19986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  int count;
19996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct objc_method_description list[];
20006efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  };
20016efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar*/
2002ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbarllvm::Constant *
2003ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel DunbarCGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
20041d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  llvm::Constant *Desc[] = {
20056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
20061d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer                                   ObjCTypes.SelectorPtrTy),
20071d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    GetMethodVarType(MD)
20081d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  };
2009f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor  if (!Desc[1])
2010f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor    return 0;
2011f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor
201208e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson  return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
2013ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                                   Desc);
2014ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar}
20156efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
20165f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerllvm::Constant *CGObjCMac::EmitMethodDescList(Twine Name,
2017ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                                              const char *Section,
2018ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                                              const ConstantVector &Methods) {
20196efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  // Return null for empty list.
20206efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  if (Methods.empty())
2021c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
20226efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
2023c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[2];
20244a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
20256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
20266efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar                                             Methods.size());
20277db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson  Values[1] = llvm::ConstantArray::get(AT, Methods);
2028c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
20296efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
20300bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar  llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
20316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  return llvm::ConstantExpr::getBitCast(GV,
20326efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar                                        ObjCTypes.MethodDescriptionListPtrTy);
2033c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
2034c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
203586e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar/*
203686e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  struct _objc_category {
20376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  char *category_name;
20386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  char *class_name;
20396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct _objc_method_list *instance_methods;
20406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct _objc_method_list *class_methods;
20416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct _objc_protocol_list *protocols;
20426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  uint32_t size; // <rdar://4585769>
20436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct _objc_property_list *instance_properties;
204486e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  };
20456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar*/
20467ded7f4983dc4a20561db7a8d02c6b2435030961Daniel Dunbarvoid CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
20479408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands  unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.CategoryTy);
204886e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar
2049f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // FIXME: This is poor design, the OCD should have a pointer to the category
2050f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // decl. Additionally, note that Category can be null for the @implementation
2051f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // w/o an @interface case. Sema should just create one for us as it does for
2052f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // @implementation so everyone else can live life under a clear blue sky.
205386e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
20546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const ObjCCategoryDecl *Category =
205586e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar    Interface->FindCategoryDeclaration(OCD->getIdentifier());
20569c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar
20579c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar  llvm::SmallString<256> ExtName;
20589c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar  llvm::raw_svector_ostream(ExtName) << Interface->getName() << '_'
20599c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                     << OCD->getName();
206086e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar
2061c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar  std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
20626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCCategoryImplDecl::instmeth_iterator
206317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
2064c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar    // Instance methods should always be defined.
2065c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar    InstanceMethods.push_back(GetMethodConstant(*i));
2066c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar  }
20676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCCategoryImplDecl::classmeth_iterator
206817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
2069c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar    // Class methods should always be defined.
2070c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar    ClassMethods.push_back(GetMethodConstant(*i));
2071c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar  }
2072c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar
2073c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[7];
207486e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  Values[0] = GetClassName(OCD->getIdentifier());
207586e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  Values[1] = GetClassName(Interface->getIdentifier());
2076679cd7fcbd341fa3747e598f537601db421b1002Fariborz Jahanian  LazySymbols.insert(Interface->getIdentifier());
20776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[2] =
20789c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    EmitMethodList("\01L_OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(),
2079c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar                   "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2080c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar                   InstanceMethods);
20816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[3] =
20829c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    EmitMethodList("\01L_OBJC_CATEGORY_CLASS_METHODS_" + ExtName.str(),
20830bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar                   "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2084c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar                   ClassMethods);
2085ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  if (Category) {
20866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Values[4] =
20879c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar      EmitProtocolList("\01L_OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
2088ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                       Category->protocol_begin(),
2089ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                       Category->protocol_end());
2090ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  } else {
2091c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2092ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  }
20934a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
209486e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar
209586e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar  // If there is no category @interface then there can be no properties.
209686e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar  if (Category) {
20979c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    Values[6] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
20985de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian                                 OCD, Category, ObjCTypes);
209986e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar  } else {
2100c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
210186e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar  }
21026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
210308e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
210486e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar                                                   Values);
210586e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar
21066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::GlobalVariable *GV =
21079c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    CreateMetadataVar("\01L_OBJC_CATEGORY_" + ExtName.str(), Init,
210863c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar                      "__OBJC,__category,regular,no_dead_strip",
210958a29128005f6e54c7d3aa39797d86ada8d40006Daniel Dunbar                      4, true);
211086e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  DefinedCategories.push_back(GV);
2111b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian  DefinedCategoryNames.insert(ExtName.str());
211264089cece350472c04b420c497ae391443353325Fariborz Jahanian  // method definition entries must be clear for next implementation.
211364089cece350472c04b420c497ae391443353325Fariborz Jahanian  MethodDefinitions.clear();
2114c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
2115c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
211627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar// FIXME: Get from somewhere?
211727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbarenum ClassFlags {
211827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  eClassFlags_Factory              = 0x00001,
211927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  eClassFlags_Meta                 = 0x00002,
212027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // <rdr://5142207>
212127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  eClassFlags_HasCXXStructors      = 0x02000,
212227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  eClassFlags_Hidden               = 0x20000,
212327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  eClassFlags_ABI2_Hidden          = 0x00010,
212427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  eClassFlags_ABI2_HasCXXStructors = 0x00004   // <rdr://4923634>
212527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar};
212627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
212727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar/*
212827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  struct _objc_class {
21296bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Class isa;
21306bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Class super_class;
21316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const char *name;
21326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  long version;
21336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  long info;
21346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  long instance_size;
21356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct _objc_ivar_list *ivars;
21366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct _objc_method_list *methods;
21376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct _objc_cache *cache;
21386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct _objc_protocol_list *protocols;
21396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  // Objective-C 1.0 extensions (<rdr://4585769>)
21406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const char *ivar_layout;
21416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct _objc_class_ext *ext;
214227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  };
214327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
214427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  See EmitClassExtension();
21456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar*/
214627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbarvoid CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
2147242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  DefinedSymbols.insert(ID->getIdentifier());
2148242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar
21498ec03f58c33c33a917f54bb7f2cd61b6d7ffe0caChris Lattner  std::string ClassName = ID->getNameAsString();
215027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // FIXME: Gross
21516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  ObjCInterfaceDecl *Interface =
215227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar    const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
21536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Constant *Protocols =
21549c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getName(),
215553b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek                     Interface->all_referenced_protocol_begin(),
215653b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek                     Interface->all_referenced_protocol_end());
215727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  unsigned Flags = eClassFlags_Factory;
2158f85e193739c953358c865005855253af4f68a497John McCall  if (ID->hasCXXStructors())
2159109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    Flags |= eClassFlags_HasCXXStructors;
21606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  unsigned Size =
21615f022d82696c84e4d127c558871d68ac6273274eKen Dyck    CGM.getContext().getASTObjCImplementationLayout(ID).getSize().getQuantity();
216227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
216327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // FIXME: Set CXX-structors flag.
21641fb0caaa7bef765b85972274e3b434af2572c141John McCall  if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
216527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar    Flags |= eClassFlags_Hidden;
216627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
2167c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar  std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
21686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCImplementationDecl::instmeth_iterator
216917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
2170c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar    // Instance methods should always be defined.
2171c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar    InstanceMethods.push_back(GetMethodConstant(*i));
2172c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar  }
21736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCImplementationDecl::classmeth_iterator
217417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
2175c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar    // Class methods should always be defined.
2176c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar    ClassMethods.push_back(GetMethodConstant(*i));
2177c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar  }
2178c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar
21796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCImplementationDecl::propimpl_iterator
218017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
2181c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar    ObjCPropertyImplDecl *PID = *i;
2182c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar
2183c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar    if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
2184c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar      ObjCPropertyDecl *PD = PID->getPropertyDecl();
2185c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar
2186c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar      if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
2187c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar        if (llvm::Constant *C = GetMethodConstant(MD))
2188c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar          InstanceMethods.push_back(C);
2189c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar      if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
2190c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar        if (llvm::Constant *C = GetMethodConstant(MD))
2191c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar          InstanceMethods.push_back(C);
2192c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar    }
2193c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar  }
2194c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar
2195c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[12];
21965384b0990ea6995121fd4bad0855e96d41dcad18Daniel Dunbar  Values[ 0] = EmitMetaClass(ID, Protocols, ClassMethods);
219727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
2198242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar    // Record a reference to the super class.
2199242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar    LazySymbols.insert(Super->getIdentifier());
2200242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar
22016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Values[ 1] =
22023c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson      llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
220327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                                     ObjCTypes.ClassPtrTy);
220427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  } else {
2205c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
220627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  }
220727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  Values[ 2] = GetClassName(ID->getIdentifier());
220827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // Version is always 0.
22094a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
22104a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
22114a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
221246b86c610ede6d9abdec254f39663db86c9c88e0Fariborz Jahanian  Values[ 6] = EmitIvarList(ID, false);
22136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[ 7] =
22149c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    EmitMethodList("\01L_OBJC_INSTANCE_METHODS_" + ID->getName(),
2215c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar                   "__OBJC,__inst_meth,regular,no_dead_strip",
2216c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar                   InstanceMethods);
221727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // cache is always NULL.
2218c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
221927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  Values[ 9] = Protocols;
22206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[10] = BuildIvarLayout(ID, true);
222127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  Values[11] = EmitClassExtension(ID);
222208e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
222327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                                                   Values);
2224b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  std::string Name("\01L_OBJC_CLASS_");
2225b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  Name += ClassName;
2226b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  const char *Section = "__OBJC,__class,regular,no_dead_strip";
2227b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  // Check for a forward reference.
2228b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
2229b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  if (GV) {
2230b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2231b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian           "Forward metaclass reference has incorrect type.");
2232b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    GV->setLinkage(llvm::GlobalValue::InternalLinkage);
2233b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    GV->setInitializer(Init);
2234b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    GV->setSection(Section);
2235b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    GV->setAlignment(4);
2236b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    CGM.AddUsedGlobal(GV);
2237b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  }
2238b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  else
2239b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    GV = CreateMetadataVar(Name, Init, Section, 4, true);
224027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  DefinedClasses.push_back(GV);
224164089cece350472c04b420c497ae391443353325Fariborz Jahanian  // method definition entries must be clear for next implementation.
224264089cece350472c04b420c497ae391443353325Fariborz Jahanian  MethodDefinitions.clear();
224327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar}
224427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
224527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbarllvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
224627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                                         llvm::Constant *Protocols,
2247ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                                         const ConstantVector &Methods) {
224827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  unsigned Flags = eClassFlags_Meta;
22499408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands  unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassTy);
225027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
22511fb0caaa7bef765b85972274e3b434af2572c141John McCall  if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
225227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar    Flags |= eClassFlags_Hidden;
22536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
2254c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[12];
225527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // The isa for the metaclass is the root of the hierarchy.
225627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  const ObjCInterfaceDecl *Root = ID->getClassInterface();
225727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
225827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar    Root = Super;
22596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[ 0] =
22603c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson    llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
226127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                                   ObjCTypes.ClassPtrTy);
226286e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  // The super class for the metaclass is emitted as the name of the
226386e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  // super class. The runtime fixes this up to point to the
226486e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  // *metaclass* for the super class.
226527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
22666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Values[ 1] =
22673c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson      llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
226827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                                     ObjCTypes.ClassPtrTy);
226927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  } else {
2270c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
227127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  }
227227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  Values[ 2] = GetClassName(ID->getIdentifier());
227327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // Version is always 0.
22744a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
22754a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
22764a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
227746b86c610ede6d9abdec254f39663db86c9c88e0Fariborz Jahanian  Values[ 6] = EmitIvarList(ID, true);
22786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[ 7] =
2279d9d22dd9c94618490dbffb0e2caf222530ca39d3Chris Lattner    EmitMethodList("\01L_OBJC_CLASS_METHODS_" + ID->getNameAsString(),
22800bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar                   "__OBJC,__cls_meth,regular,no_dead_strip",
2281c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar                   Methods);
228227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // cache is always NULL.
2283c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
228427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  Values[ 9] = Protocols;
228527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // ivar_layout for metaclass is always NULL.
2286c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
228727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // The class extension is always unused for metaclasses.
2288c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
228908e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
229027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                                                   Values);
229127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
2292f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  std::string Name("\01L_OBJC_METACLASS_");
22938ec03f58c33c33a917f54bb7f2cd61b6d7ffe0caChris Lattner  Name += ID->getNameAsCString();
2294f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar
2295f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  // Check for a forward reference.
2296f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
2297f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  if (GV) {
2298f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar    assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2299f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar           "Forward metaclass reference has incorrect type.");
2300f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar    GV->setLinkage(llvm::GlobalValue::InternalLinkage);
2301f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar    GV->setInitializer(Init);
2302f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  } else {
23031c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson    GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
2304f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar                                  llvm::GlobalValue::InternalLinkage,
23051c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                                  Init, Name);
2306f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  }
230727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
230858a29128005f6e54c7d3aa39797d86ada8d40006Daniel Dunbar  GV->setAlignment(4);
2309ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  CGM.AddUsedGlobal(GV);
231027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
231127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  return GV;
231227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar}
231327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
23146bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
2315d9d22dd9c94618490dbffb0e2caf222530ca39d3Chris Lattner  std::string Name = "\01L_OBJC_METACLASS_" + ID->getNameAsString();
2316f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar
2317f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // FIXME: Should we look these up somewhere other than the module. Its a bit
2318f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // silly since we only generate these while processing an implementation, so
2319f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // exactly one pointer would work if know when we entered/exitted an
2320f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // implementation block.
2321f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar
2322f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  // Check for an existing forward reference.
2323b0d27943e133f099a39abc26a49d1130b5a8f5afFariborz Jahanian  // Previously, metaclass with internal linkage may have been defined.
2324b0d27943e133f099a39abc26a49d1130b5a8f5afFariborz Jahanian  // pass 'true' as 2nd argument so it is returned.
23256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name,
23266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                                   true)) {
2327f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar    assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2328f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar           "Forward metaclass reference has incorrect type.");
2329f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar    return GV;
2330f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  } else {
2331f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar    // Generate as an external reference to keep a consistent
2332f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar    // module. This will be patched up when we emit the metaclass.
23331c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson    return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
2334f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar                                    llvm::GlobalValue::ExternalLinkage,
2335b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian                                    0,
2336b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian                                    Name);
2337b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  }
2338b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian}
2339b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian
2340b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanianllvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) {
2341b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  std::string Name = "\01L_OBJC_CLASS_" + ID->getNameAsString();
2342b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian
2343b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name,
2344b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian                                                                   true)) {
2345b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2346b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian           "Forward class metadata reference has incorrect type.");
2347b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    return GV;
2348b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  } else {
2349b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
2350b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian                                    llvm::GlobalValue::ExternalLinkage,
2351f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar                                    0,
23521c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                                    Name);
2353f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  }
2354f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar}
2355f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar
235627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar/*
235727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  struct objc_class_ext {
23586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  uint32_t size;
23596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const char *weak_ivar_layout;
23606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct _objc_property_list *properties;
236127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  };
236227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar*/
236327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbarllvm::Constant *
236427f9d77b61b377b21ccda536122f2be6fa715751Daniel DunbarCGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
23656bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  uint64_t Size =
23669408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
236727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
2368c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[3];
23694a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
2370c71303de3e295d19c3617b6738da009f6e679337Fariborz Jahanian  Values[1] = BuildIvarLayout(ID, false);
23719c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar  Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
23725de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian                               ID, ID->getClassInterface(), ObjCTypes);
237327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
237427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // Return null if no extension bits are used.
237527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  if (Values[1]->isNullValue() && Values[2]->isNullValue())
2376c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
237727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
23786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Constant *Init =
237908e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson    llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
23809c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar  return CreateMetadataVar("\01L_OBJC_CLASSEXT_" + ID->getName(),
23816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                           Init, "__OBJC,__class_ext,regular,no_dead_strip",
23820bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar                           4, true);
238327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar}
238427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
238527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar/*
238627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  struct objc_ivar {
23876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  char *ivar_name;
23886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  char *ivar_type;
23896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  int ivar_offset;
239027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  };
239127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
239227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  struct objc_ivar_list {
23936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  int ivar_count;
23946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct objc_ivar list[count];
239527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  };
23966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar*/
239727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbarllvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
239846b86c610ede6d9abdec254f39663db86c9c88e0Fariborz Jahanian                                        bool ForClass) {
23991d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  std::vector<llvm::Constant*> Ivars;
240027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
240127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // When emitting the root class GCC emits ivar entries for the
240227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // actual class structure. It is not clear if we need to follow this
240327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // behavior; for now lets try and get away with not doing it. If so,
240427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // the cleanest solution would be to make up an ObjCInterfaceDecl
240527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // for the class.
240627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  if (ForClass)
2407c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
24086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
2409db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  const ObjCInterfaceDecl *OID = ID->getClassInterface();
24106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
2411db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
2412bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian       IVD; IVD = IVD->getNextIvar()) {
24138e6ac1d80055fa37b9b84029c7e751624ba7f84cFariborz Jahanian    // Ignore unnamed bit-fields.
24148e6ac1d80055fa37b9b84029c7e751624ba7f84cFariborz Jahanian    if (!IVD->getDeclName())
24156bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      continue;
24161d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    llvm::Constant *Ivar[] = {
24171d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer      GetMethodVarName(IVD->getIdentifier()),
24181d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer      GetMethodVarType(IVD),
24191d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer      llvm::ConstantInt::get(ObjCTypes.IntTy,
24201d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer                             ComputeIvarBaseOffset(CGM, OID, IVD))
24211d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    };
242208e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson    Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar));
242327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  }
242427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
242527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // Return null for empty list.
242627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  if (Ivars.empty())
2427c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
242827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
2429c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[2];
24304a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
243196e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
243227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                                             Ivars.size());
24337db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson  Values[1] = llvm::ConstantArray::get(AT, Ivars);
2434c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
243527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
243663c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar  llvm::GlobalVariable *GV;
243763c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar  if (ForClass)
24389c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    GV = CreateMetadataVar("\01L_OBJC_CLASS_VARIABLES_" + ID->getName(),
24396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                           Init, "__OBJC,__class_vars,regular,no_dead_strip",
244058a29128005f6e54c7d3aa39797d86ada8d40006Daniel Dunbar                           4, true);
244163c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar  else
24429c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    GV = CreateMetadataVar("\01L_OBJC_INSTANCE_VARIABLES_" + ID->getName(),
244363c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar                           Init, "__OBJC,__instance_vars,regular,no_dead_strip",
24440bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar                           4, true);
24453c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
244627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar}
244727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
244827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar/*
244927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  struct objc_method {
24506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  SEL method_name;
24516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  char *method_types;
24526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  void *method;
245327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  };
24546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
245527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  struct objc_method_list {
24566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct objc_method_list *obsolete;
24576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  int count;
24586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct objc_method methods_list[count];
245927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  };
246027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar*/
246127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
2462c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar/// GetMethodConstant - Return a struct objc_method constant for the
2463c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar/// given method if it has been defined. The result is null if the
2464c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar/// method has not been defined. The return value has type MethodPtrTy.
2465ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbarllvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) {
24669d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis  llvm::Function *Fn = GetMethodDefinition(MD);
2467c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar  if (!Fn)
2468c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar    return 0;
24696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
24701d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  llvm::Constant *Method[] = {
24713c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson    llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
24721d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer                                   ObjCTypes.SelectorPtrTy),
24731d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    GetMethodVarType(MD),
24741d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy)
24751d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  };
247608e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson  return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
2477c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar}
247827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
24795f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerllvm::Constant *CGObjCMac::EmitMethodList(Twine Name,
2480c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar                                          const char *Section,
2481ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                                          const ConstantVector &Methods) {
248227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // Return null for empty list.
248327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  if (Methods.empty())
2484c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
248527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
2486c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[3];
2487c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
24884a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
248996e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
249027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                                             Methods.size());
24917db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson  Values[2] = llvm::ConstantArray::get(AT, Methods);
2492c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
249327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
24940bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar  llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
2495c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy);
2496b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar}
2497b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar
2498493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanianllvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,
24996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                const ObjCContainerDecl *CD) {
2500c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar  llvm::SmallString<256> Name;
2501679a502d462ef819e6175b58e255ca3f3391e7cfFariborz Jahanian  GetNameForMethod(OMD, CD, Name);
2502b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar
2503541b63b1a9db77e4a8670e9823711c2c12e58afbDaniel Dunbar  CodeGenTypes &Types = CGM.getTypes();
25042acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::FunctionType *MethodTy =
2505541b63b1a9db77e4a8670e9823711c2c12e58afbDaniel Dunbar    Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic());
25066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Function *Method =
250745c25ba11cbf8c9a461def5b03f6ee9481e06769Daniel Dunbar    llvm::Function::Create(MethodTy,
2508b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar                           llvm::GlobalValue::InternalLinkage,
2509c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar                           Name.str(),
2510b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar                           &CGM.getModule());
2511c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar  MethodDefinitions.insert(std::make_pair(OMD, Method));
2512b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar
2513b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  return Method;
2514c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
2515c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
2516fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbarllvm::GlobalVariable *
25175f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerCGObjCCommonMac::CreateMetadataVar(Twine Name,
2518fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar                                   llvm::Constant *Init,
2519fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar                                   const char *Section,
252035bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar                                   unsigned Align,
252135bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar                                   bool AddToUsed) {
25222acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *Ty = Init->getType();
25236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::GlobalVariable *GV =
25241c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson    new llvm::GlobalVariable(CGM.getModule(), Ty, false,
2525ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner                             llvm::GlobalValue::InternalLinkage, Init, Name);
2526fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar  if (Section)
2527fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar    GV->setSection(Section);
252835bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar  if (Align)
252935bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar    GV->setAlignment(Align);
253035bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar  if (AddToUsed)
2531ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner    CGM.AddUsedGlobal(GV);
2532fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar  return GV;
2533fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar}
2534fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar
25356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Function *CGObjCMac::ModuleInitFunction() {
2536f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar  // Abuse this interface function as a place to finalize.
2537f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar  FinishModule();
2538c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar  return NULL;
2539c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
2540c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
254174391b48b4791cded373683a3baf67314f358d50Chris Lattnerllvm::Constant *CGObjCMac::GetPropertyGetFunction() {
254272db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  return ObjCTypes.getGetPropertyFn();
254349f6602707887eea1a558a1dffe0213102f887f2Daniel Dunbar}
254449f6602707887eea1a558a1dffe0213102f887f2Daniel Dunbar
254574391b48b4791cded373683a3baf67314f358d50Chris Lattnerllvm::Constant *CGObjCMac::GetPropertySetFunction() {
254672db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  return ObjCTypes.getSetPropertyFn();
254749f6602707887eea1a558a1dffe0213102f887f2Daniel Dunbar}
254849f6602707887eea1a558a1dffe0213102f887f2Daniel Dunbar
25498fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnallllvm::Constant *CGObjCMac::GetGetStructFunction() {
25508fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall  return ObjCTypes.getCopyStructFn();
25518fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall}
25528fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnallllvm::Constant *CGObjCMac::GetSetStructFunction() {
25536cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian  return ObjCTypes.getCopyStructFn();
25546cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian}
25556cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian
255674391b48b4791cded373683a3baf67314f358d50Chris Lattnerllvm::Constant *CGObjCMac::EnumerationMutationFunction() {
255772db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  return ObjCTypes.getEnumerationMutationFn();
25582abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson}
25592abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
2560f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid CGObjCMac::EmitTryStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S) {
2561f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return EmitTryOrSynchronizedStmt(CGF, S);
2562f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
2563f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
2564f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF,
2565f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                                     const ObjCAtSynchronizedStmt &S) {
2566f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return EmitTryOrSynchronizedStmt(CGF, S);
2567f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
2568f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
2569cc5052999cd064584492ba15a808b6e1cee6d931John McCallnamespace {
25701f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall  struct PerformFragileFinally : EHScopeStack::Cleanup {
2571cc5052999cd064584492ba15a808b6e1cee6d931John McCall    const Stmt &S;
25720b2517299415ab1c28b9cb87d536ccea84317a10John McCall    llvm::Value *SyncArgSlot;
2573cc5052999cd064584492ba15a808b6e1cee6d931John McCall    llvm::Value *CallTryExitVar;
2574cc5052999cd064584492ba15a808b6e1cee6d931John McCall    llvm::Value *ExceptionData;
2575cc5052999cd064584492ba15a808b6e1cee6d931John McCall    ObjCTypesHelper &ObjCTypes;
2576cc5052999cd064584492ba15a808b6e1cee6d931John McCall    PerformFragileFinally(const Stmt *S,
25770b2517299415ab1c28b9cb87d536ccea84317a10John McCall                          llvm::Value *SyncArgSlot,
2578cc5052999cd064584492ba15a808b6e1cee6d931John McCall                          llvm::Value *CallTryExitVar,
2579cc5052999cd064584492ba15a808b6e1cee6d931John McCall                          llvm::Value *ExceptionData,
2580cc5052999cd064584492ba15a808b6e1cee6d931John McCall                          ObjCTypesHelper *ObjCTypes)
25810b2517299415ab1c28b9cb87d536ccea84317a10John McCall      : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
2582cc5052999cd064584492ba15a808b6e1cee6d931John McCall        ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
2583cc5052999cd064584492ba15a808b6e1cee6d931John McCall
2584ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
2585cc5052999cd064584492ba15a808b6e1cee6d931John McCall      // Check whether we need to call objc_exception_try_exit.
2586cc5052999cd064584492ba15a808b6e1cee6d931John McCall      // In optimized code, this branch will always be folded.
2587cc5052999cd064584492ba15a808b6e1cee6d931John McCall      llvm::BasicBlock *FinallyCallExit =
2588cc5052999cd064584492ba15a808b6e1cee6d931John McCall        CGF.createBasicBlock("finally.call_exit");
2589cc5052999cd064584492ba15a808b6e1cee6d931John McCall      llvm::BasicBlock *FinallyNoCallExit =
2590cc5052999cd064584492ba15a808b6e1cee6d931John McCall        CGF.createBasicBlock("finally.no_call_exit");
2591cc5052999cd064584492ba15a808b6e1cee6d931John McCall      CGF.Builder.CreateCondBr(CGF.Builder.CreateLoad(CallTryExitVar),
2592cc5052999cd064584492ba15a808b6e1cee6d931John McCall                               FinallyCallExit, FinallyNoCallExit);
2593cc5052999cd064584492ba15a808b6e1cee6d931John McCall
2594cc5052999cd064584492ba15a808b6e1cee6d931John McCall      CGF.EmitBlock(FinallyCallExit);
2595cc5052999cd064584492ba15a808b6e1cee6d931John McCall      CGF.Builder.CreateCall(ObjCTypes.getExceptionTryExitFn(), ExceptionData)
2596cc5052999cd064584492ba15a808b6e1cee6d931John McCall        ->setDoesNotThrow();
2597cc5052999cd064584492ba15a808b6e1cee6d931John McCall
2598cc5052999cd064584492ba15a808b6e1cee6d931John McCall      CGF.EmitBlock(FinallyNoCallExit);
2599cc5052999cd064584492ba15a808b6e1cee6d931John McCall
2600cc5052999cd064584492ba15a808b6e1cee6d931John McCall      if (isa<ObjCAtTryStmt>(S)) {
2601cc5052999cd064584492ba15a808b6e1cee6d931John McCall        if (const ObjCAtFinallyStmt* FinallyStmt =
2602d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall              cast<ObjCAtTryStmt>(S).getFinallyStmt()) {
2603d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall          // Save the current cleanup destination in case there's
2604d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall          // control flow inside the finally statement.
2605d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall          llvm::Value *CurCleanupDest =
2606d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall            CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot());
2607d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall
2608cc5052999cd064584492ba15a808b6e1cee6d931John McCall          CGF.EmitStmt(FinallyStmt->getFinallyBody());
2609cc5052999cd064584492ba15a808b6e1cee6d931John McCall
2610d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall          if (CGF.HaveInsertPoint()) {
2611d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall            CGF.Builder.CreateStore(CurCleanupDest,
2612d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall                                    CGF.getNormalCleanupDestSlot());
2613d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall          } else {
2614d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall            // Currently, the end of the cleanup must always exist.
2615d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall            CGF.EnsureInsertPoint();
2616d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall          }
2617d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall        }
2618cc5052999cd064584492ba15a808b6e1cee6d931John McCall      } else {
2619cc5052999cd064584492ba15a808b6e1cee6d931John McCall        // Emit objc_sync_exit(expr); as finally's sole statement for
2620cc5052999cd064584492ba15a808b6e1cee6d931John McCall        // @synchronized.
26210b2517299415ab1c28b9cb87d536ccea84317a10John McCall        llvm::Value *SyncArg = CGF.Builder.CreateLoad(SyncArgSlot);
2622cc5052999cd064584492ba15a808b6e1cee6d931John McCall        CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg)
2623cc5052999cd064584492ba15a808b6e1cee6d931John McCall          ->setDoesNotThrow();
2624cc5052999cd064584492ba15a808b6e1cee6d931John McCall      }
2625cc5052999cd064584492ba15a808b6e1cee6d931John McCall    }
2626cc5052999cd064584492ba15a808b6e1cee6d931John McCall  };
262787bb5822bfa4baea23a3d9273df266777f3ab796John McCall
262887bb5822bfa4baea23a3d9273df266777f3ab796John McCall  class FragileHazards {
262987bb5822bfa4baea23a3d9273df266777f3ab796John McCall    CodeGenFunction &CGF;
26305f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<llvm::Value*, 20> Locals;
263187bb5822bfa4baea23a3d9273df266777f3ab796John McCall    llvm::DenseSet<llvm::BasicBlock*> BlocksBeforeTry;
263287bb5822bfa4baea23a3d9273df266777f3ab796John McCall
263387bb5822bfa4baea23a3d9273df266777f3ab796John McCall    llvm::InlineAsm *ReadHazard;
263487bb5822bfa4baea23a3d9273df266777f3ab796John McCall    llvm::InlineAsm *WriteHazard;
263587bb5822bfa4baea23a3d9273df266777f3ab796John McCall
263687bb5822bfa4baea23a3d9273df266777f3ab796John McCall    llvm::FunctionType *GetAsmFnType();
263787bb5822bfa4baea23a3d9273df266777f3ab796John McCall
263887bb5822bfa4baea23a3d9273df266777f3ab796John McCall    void collectLocals();
263987bb5822bfa4baea23a3d9273df266777f3ab796John McCall    void emitReadHazard(CGBuilderTy &Builder);
264087bb5822bfa4baea23a3d9273df266777f3ab796John McCall
264187bb5822bfa4baea23a3d9273df266777f3ab796John McCall  public:
264287bb5822bfa4baea23a3d9273df266777f3ab796John McCall    FragileHazards(CodeGenFunction &CGF);
26430b2517299415ab1c28b9cb87d536ccea84317a10John McCall
264487bb5822bfa4baea23a3d9273df266777f3ab796John McCall    void emitWriteHazard();
26450b2517299415ab1c28b9cb87d536ccea84317a10John McCall    void emitHazardsInNewBlocks();
264687bb5822bfa4baea23a3d9273df266777f3ab796John McCall  };
264787bb5822bfa4baea23a3d9273df266777f3ab796John McCall}
264887bb5822bfa4baea23a3d9273df266777f3ab796John McCall
264987bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// Create the fragile-ABI read and write hazards based on the current
265087bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// state of the function, which is presumed to be immediately prior
265187bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// to a @try block.  These hazards are used to maintain correct
265287bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// semantics in the face of optimization and the fragile ABI's
265387bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// cavalier use of setjmp/longjmp.
265487bb5822bfa4baea23a3d9273df266777f3ab796John McCallFragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) {
265587bb5822bfa4baea23a3d9273df266777f3ab796John McCall  collectLocals();
265687bb5822bfa4baea23a3d9273df266777f3ab796John McCall
265787bb5822bfa4baea23a3d9273df266777f3ab796John McCall  if (Locals.empty()) return;
265887bb5822bfa4baea23a3d9273df266777f3ab796John McCall
265987bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // Collect all the blocks in the function.
266087bb5822bfa4baea23a3d9273df266777f3ab796John McCall  for (llvm::Function::iterator
266187bb5822bfa4baea23a3d9273df266777f3ab796John McCall         I = CGF.CurFn->begin(), E = CGF.CurFn->end(); I != E; ++I)
266287bb5822bfa4baea23a3d9273df266777f3ab796John McCall    BlocksBeforeTry.insert(&*I);
266387bb5822bfa4baea23a3d9273df266777f3ab796John McCall
266487bb5822bfa4baea23a3d9273df266777f3ab796John McCall  llvm::FunctionType *AsmFnTy = GetAsmFnType();
266587bb5822bfa4baea23a3d9273df266777f3ab796John McCall
266687bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // Create a read hazard for the allocas.  This inhibits dead-store
266787bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // optimizations and forces the values to memory.  This hazard is
266887bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // inserted before any 'throwing' calls in the protected scope to
266987bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // reflect the possibility that the variables might be read from the
267087bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // catch block if the call throws.
267187bb5822bfa4baea23a3d9273df266777f3ab796John McCall  {
267287bb5822bfa4baea23a3d9273df266777f3ab796John McCall    std::string Constraint;
267387bb5822bfa4baea23a3d9273df266777f3ab796John McCall    for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
267487bb5822bfa4baea23a3d9273df266777f3ab796John McCall      if (I) Constraint += ',';
267587bb5822bfa4baea23a3d9273df266777f3ab796John McCall      Constraint += "*m";
267687bb5822bfa4baea23a3d9273df266777f3ab796John McCall    }
267787bb5822bfa4baea23a3d9273df266777f3ab796John McCall
267887bb5822bfa4baea23a3d9273df266777f3ab796John McCall    ReadHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
267987bb5822bfa4baea23a3d9273df266777f3ab796John McCall  }
268087bb5822bfa4baea23a3d9273df266777f3ab796John McCall
268187bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // Create a write hazard for the allocas.  This inhibits folding
268287bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // loads across the hazard.  This hazard is inserted at the
268387bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // beginning of the catch path to reflect the possibility that the
268487bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // variables might have been written within the protected scope.
268587bb5822bfa4baea23a3d9273df266777f3ab796John McCall  {
268687bb5822bfa4baea23a3d9273df266777f3ab796John McCall    std::string Constraint;
268787bb5822bfa4baea23a3d9273df266777f3ab796John McCall    for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
268887bb5822bfa4baea23a3d9273df266777f3ab796John McCall      if (I) Constraint += ',';
268987bb5822bfa4baea23a3d9273df266777f3ab796John McCall      Constraint += "=*m";
269087bb5822bfa4baea23a3d9273df266777f3ab796John McCall    }
269187bb5822bfa4baea23a3d9273df266777f3ab796John McCall
269287bb5822bfa4baea23a3d9273df266777f3ab796John McCall    WriteHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
269387bb5822bfa4baea23a3d9273df266777f3ab796John McCall  }
269487bb5822bfa4baea23a3d9273df266777f3ab796John McCall}
269587bb5822bfa4baea23a3d9273df266777f3ab796John McCall
269687bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// Emit a write hazard at the current location.
269787bb5822bfa4baea23a3d9273df266777f3ab796John McCallvoid FragileHazards::emitWriteHazard() {
269887bb5822bfa4baea23a3d9273df266777f3ab796John McCall  if (Locals.empty()) return;
269987bb5822bfa4baea23a3d9273df266777f3ab796John McCall
27004c7d9f1507d0f102bd4133bba63348636facd469Jay Foad  CGF.Builder.CreateCall(WriteHazard, Locals)->setDoesNotThrow();
270187bb5822bfa4baea23a3d9273df266777f3ab796John McCall}
270287bb5822bfa4baea23a3d9273df266777f3ab796John McCall
270387bb5822bfa4baea23a3d9273df266777f3ab796John McCallvoid FragileHazards::emitReadHazard(CGBuilderTy &Builder) {
270487bb5822bfa4baea23a3d9273df266777f3ab796John McCall  assert(!Locals.empty());
27054c7d9f1507d0f102bd4133bba63348636facd469Jay Foad  Builder.CreateCall(ReadHazard, Locals)->setDoesNotThrow();
270687bb5822bfa4baea23a3d9273df266777f3ab796John McCall}
270787bb5822bfa4baea23a3d9273df266777f3ab796John McCall
270887bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// Emit read hazards in all the protected blocks, i.e. all the blocks
270987bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// which have been inserted since the beginning of the try.
27100b2517299415ab1c28b9cb87d536ccea84317a10John McCallvoid FragileHazards::emitHazardsInNewBlocks() {
271187bb5822bfa4baea23a3d9273df266777f3ab796John McCall  if (Locals.empty()) return;
271287bb5822bfa4baea23a3d9273df266777f3ab796John McCall
271387bb5822bfa4baea23a3d9273df266777f3ab796John McCall  CGBuilderTy Builder(CGF.getLLVMContext());
271487bb5822bfa4baea23a3d9273df266777f3ab796John McCall
271587bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // Iterate through all blocks, skipping those prior to the try.
271687bb5822bfa4baea23a3d9273df266777f3ab796John McCall  for (llvm::Function::iterator
271787bb5822bfa4baea23a3d9273df266777f3ab796John McCall         FI = CGF.CurFn->begin(), FE = CGF.CurFn->end(); FI != FE; ++FI) {
271887bb5822bfa4baea23a3d9273df266777f3ab796John McCall    llvm::BasicBlock &BB = *FI;
271987bb5822bfa4baea23a3d9273df266777f3ab796John McCall    if (BlocksBeforeTry.count(&BB)) continue;
272087bb5822bfa4baea23a3d9273df266777f3ab796John McCall
272187bb5822bfa4baea23a3d9273df266777f3ab796John McCall    // Walk through all the calls in the block.
272287bb5822bfa4baea23a3d9273df266777f3ab796John McCall    for (llvm::BasicBlock::iterator
272387bb5822bfa4baea23a3d9273df266777f3ab796John McCall           BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
272487bb5822bfa4baea23a3d9273df266777f3ab796John McCall      llvm::Instruction &I = *BI;
272587bb5822bfa4baea23a3d9273df266777f3ab796John McCall
272687bb5822bfa4baea23a3d9273df266777f3ab796John McCall      // Ignore instructions that aren't non-intrinsic calls.
272787bb5822bfa4baea23a3d9273df266777f3ab796John McCall      // These are the only calls that can possibly call longjmp.
272887bb5822bfa4baea23a3d9273df266777f3ab796John McCall      if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I)) continue;
272987bb5822bfa4baea23a3d9273df266777f3ab796John McCall      if (isa<llvm::IntrinsicInst>(I))
273087bb5822bfa4baea23a3d9273df266777f3ab796John McCall        continue;
273187bb5822bfa4baea23a3d9273df266777f3ab796John McCall
273287bb5822bfa4baea23a3d9273df266777f3ab796John McCall      // Ignore call sites marked nounwind.  This may be questionable,
273387bb5822bfa4baea23a3d9273df266777f3ab796John McCall      // since 'nounwind' doesn't necessarily mean 'does not call longjmp'.
273487bb5822bfa4baea23a3d9273df266777f3ab796John McCall      llvm::CallSite CS(&I);
273587bb5822bfa4baea23a3d9273df266777f3ab796John McCall      if (CS.doesNotThrow()) continue;
273687bb5822bfa4baea23a3d9273df266777f3ab796John McCall
27370b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // Insert a read hazard before the call.  This will ensure that
27380b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // any writes to the locals are performed before making the
27390b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // call.  If the call throws, then this is sufficient to
27400b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // guarantee correctness as long as it doesn't also write to any
27410b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // locals.
274287bb5822bfa4baea23a3d9273df266777f3ab796John McCall      Builder.SetInsertPoint(&BB, BI);
274387bb5822bfa4baea23a3d9273df266777f3ab796John McCall      emitReadHazard(Builder);
274487bb5822bfa4baea23a3d9273df266777f3ab796John McCall    }
274587bb5822bfa4baea23a3d9273df266777f3ab796John McCall  }
274687bb5822bfa4baea23a3d9273df266777f3ab796John McCall}
274787bb5822bfa4baea23a3d9273df266777f3ab796John McCall
274887bb5822bfa4baea23a3d9273df266777f3ab796John McCallstatic void addIfPresent(llvm::DenseSet<llvm::Value*> &S, llvm::Value *V) {
274987bb5822bfa4baea23a3d9273df266777f3ab796John McCall  if (V) S.insert(V);
275087bb5822bfa4baea23a3d9273df266777f3ab796John McCall}
275187bb5822bfa4baea23a3d9273df266777f3ab796John McCall
275287bb5822bfa4baea23a3d9273df266777f3ab796John McCallvoid FragileHazards::collectLocals() {
275387bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // Compute a set of allocas to ignore.
275487bb5822bfa4baea23a3d9273df266777f3ab796John McCall  llvm::DenseSet<llvm::Value*> AllocasToIgnore;
275587bb5822bfa4baea23a3d9273df266777f3ab796John McCall  addIfPresent(AllocasToIgnore, CGF.ReturnValue);
275687bb5822bfa4baea23a3d9273df266777f3ab796John McCall  addIfPresent(AllocasToIgnore, CGF.NormalCleanupDest);
275787bb5822bfa4baea23a3d9273df266777f3ab796John McCall
275887bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // Collect all the allocas currently in the function.  This is
275987bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // probably way too aggressive.
276087bb5822bfa4baea23a3d9273df266777f3ab796John McCall  llvm::BasicBlock &Entry = CGF.CurFn->getEntryBlock();
276187bb5822bfa4baea23a3d9273df266777f3ab796John McCall  for (llvm::BasicBlock::iterator
276287bb5822bfa4baea23a3d9273df266777f3ab796John McCall         I = Entry.begin(), E = Entry.end(); I != E; ++I)
276387bb5822bfa4baea23a3d9273df266777f3ab796John McCall    if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
276487bb5822bfa4baea23a3d9273df266777f3ab796John McCall      Locals.push_back(&*I);
276587bb5822bfa4baea23a3d9273df266777f3ab796John McCall}
276687bb5822bfa4baea23a3d9273df266777f3ab796John McCall
276787bb5822bfa4baea23a3d9273df266777f3ab796John McCallllvm::FunctionType *FragileHazards::GetAsmFnType() {
27685f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<llvm::Type *, 16> tys(Locals.size());
27690774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  for (unsigned i = 0, e = Locals.size(); i != e; ++i)
27700774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall    tys[i] = Locals[i]->getType();
27710774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  return llvm::FunctionType::get(CGF.VoidTy, tys, false);
2772cc5052999cd064584492ba15a808b6e1cee6d931John McCall}
2773cc5052999cd064584492ba15a808b6e1cee6d931John McCall
27746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar/*
277518ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar
27766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Objective-C setjmp-longjmp (sjlj) Exception Handling
27776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  --
277818ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar
2779f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  A catch buffer is a setjmp buffer plus:
2780f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    - a pointer to the exception that was caught
2781f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    - a pointer to the previous exception data buffer
2782f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    - two pointers of reserved storage
2783f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Therefore catch buffers form a stack, with a pointer to the top
2784f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  of the stack kept in thread-local storage.
2785f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
2786f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  objc_exception_try_enter pushes a catch buffer onto the EH stack.
2787f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  objc_exception_try_exit pops the given catch buffer, which is
2788f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    required to be the top of the EH stack.
2789f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  objc_exception_throw pops the top of the EH stack, writes the
2790f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    thrown exception into the appropriate field, and longjmps
2791f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    to the setjmp buffer.  It crashes the process (with a printf
2792f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    and an abort()) if there are no catch buffers on the stack.
2793f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  objc_exception_extract just reads the exception pointer out of the
2794f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    catch buffer.
2795f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
2796f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  There's no reason an implementation couldn't use a light-weight
2797f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  setjmp here --- something like __builtin_setjmp, but API-compatible
2798f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  with the heavyweight setjmp.  This will be more important if we ever
2799f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  want to implement correct ObjC/C++ exception interactions for the
2800f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  fragile ABI.
2801f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
2802f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Note that for this use of setjmp/longjmp to be correct, we may need
2803f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  to mark some local variables volatile: if a non-volatile local
2804f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  variable is modified between the setjmp and the longjmp, it has
2805f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  indeterminate value.  For the purposes of LLVM IR, it may be
2806f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  sufficient to make loads and stores within the @try (to variables
2807f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  declared outside the @try) volatile.  This is necessary for
2808f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  optimized correctness, but is not currently being done; this is
2809f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  being tracked as rdar://problem/8160285
2810f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
28116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  The basic framework for a @try-catch-finally is as follows:
28126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  {
281318ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar  objc_exception_data d;
281418ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar  id _rethrow = null;
2815190d00e1396214c77539c7095756b9ea38160463Anders Carlsson  bool _call_try_exit = true;
28166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
281718ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar  objc_exception_try_enter(&d);
281818ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar  if (!setjmp(d.jmp_buf)) {
28196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  ... try body ...
282018ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar  } else {
28216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  // exception path
28226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  id _caught = objc_exception_extract(&d);
28236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
28246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  // enter new try scope for handlers
28256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  if (!setjmp(d.jmp_buf)) {
28266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  ... match exception and execute catch blocks ...
28276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
28286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  // fell off end, rethrow.
28296bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  _rethrow = _caught;
28306bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  ... jump-through-finally to finally_rethrow ...
28316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  } else {
28326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  // exception in catch block
28336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  _rethrow = objc_exception_extract(&d);
28346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  _call_try_exit = false;
28356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  ... jump-through-finally to finally_rethrow ...
28366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  }
283718ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar  }
2838898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar  ... jump-through-finally to finally_end ...
283918ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar
28406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  finally:
2841190d00e1396214c77539c7095756b9ea38160463Anders Carlsson  if (_call_try_exit)
28426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  objc_exception_try_exit(&d);
2843190d00e1396214c77539c7095756b9ea38160463Anders Carlsson
284418ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar  ... finally block ....
2845898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar  ... dispatch to finally destination ...
2846898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar
28476bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  finally_rethrow:
2848898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar  objc_exception_throw(_rethrow);
2849898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar
28506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  finally_end:
28516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  }
28526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
28536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  This framework differs slightly from the one gcc uses, in that gcc
28546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  uses _rethrow to determine if objc_exception_try_exit should be called
28556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  and if the object should be rethrown. This breaks in the face of
28566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  throwing nil and introduces unnecessary branches.
28576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
28586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  We specialize this framework for a few particular circumstances:
28596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
28606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  - If there are no catch blocks, then we avoid emitting the second
28616bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  exception handling context.
28626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
28636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  - If there is a catch-all catch block (i.e. @catch(...) or @catch(id
28646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  e)) we avoid emitting the code to rethrow an uncaught exception.
286518ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar
28666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  - FIXME: If there is no @finally block we can do a few more
28676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  simplifications.
28686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
28696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Rethrows and Jumps-Through-Finally
28706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  --
28716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
2872f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  '@throw;' is supported by pushing the currently-caught exception
2873f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  onto ObjCEHStack while the @catch blocks are emitted.
2874f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
2875f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Branches through the @finally block are handled with an ordinary
2876f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  normal cleanup.  We do not register an EH cleanup; fragile-ABI ObjC
2877f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  exceptions are not compatible with C++ exceptions, and this is
2878f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  hardly the only place where this will go wrong.
2879f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
2880f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  @synchronized(expr) { stmt; } is emitted as if it were:
2881f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    id synch_value = expr;
2882f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    objc_sync_enter(synch_value);
2883f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    @try { stmt; } @finally { objc_sync_exit(synch_value); }
288418ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar*/
288518ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar
2886bd71be4683c195260d5245118b1e13e6b2e20504Fariborz Jahanianvoid CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
2887bd71be4683c195260d5245118b1e13e6b2e20504Fariborz Jahanian                                          const Stmt &S) {
2888bd71be4683c195260d5245118b1e13e6b2e20504Fariborz Jahanian  bool isTry = isa<ObjCAtTryStmt>(S);
2889f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
2890f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // A destination for the fall-through edges of the catch handlers to
2891f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // jump to.
2892f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CodeGenFunction::JumpDest FinallyEnd =
2893f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.getJumpDestInCurrentScope("finally.end");
2894f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
2895f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // A destination for the rethrow edge of the catch handlers to jump
2896f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // to.
2897f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CodeGenFunction::JumpDest FinallyRethrow =
2898f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.getJumpDestInCurrentScope("finally.rethrow");
28996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
29001c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar  // For @synchronized, call objc_sync_enter(sync.expr). The
29011c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar  // evaluation of the expression must occur before we enter the
29020b2517299415ab1c28b9cb87d536ccea84317a10John McCall  // @synchronized.  We can't avoid a temp here because we need the
29030b2517299415ab1c28b9cb87d536ccea84317a10John McCall  // value to be preserved.  If the backend ever does liveness
29040b2517299415ab1c28b9cb87d536ccea84317a10John McCall  // correctly after setjmp, this will be unnecessary.
29050b2517299415ab1c28b9cb87d536ccea84317a10John McCall  llvm::Value *SyncArgSlot = 0;
29061c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar  if (!isTry) {
29070b2517299415ab1c28b9cb87d536ccea84317a10John McCall    llvm::Value *SyncArg =
29081c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar      CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
29091c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar    SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
2910f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg)
2911f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      ->setDoesNotThrow();
29120b2517299415ab1c28b9cb87d536ccea84317a10John McCall
29130b2517299415ab1c28b9cb87d536ccea84317a10John McCall    SyncArgSlot = CGF.CreateTempAlloca(SyncArg->getType(), "sync.arg");
29140b2517299415ab1c28b9cb87d536ccea84317a10John McCall    CGF.Builder.CreateStore(SyncArg, SyncArgSlot);
29151c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar  }
2916898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar
29170b2517299415ab1c28b9cb87d536ccea84317a10John McCall  // Allocate memory for the setjmp buffer.  This needs to be kept
29180b2517299415ab1c28b9cb87d536ccea84317a10John McCall  // live throughout the try and catch blocks.
29190b2517299415ab1c28b9cb87d536ccea84317a10John McCall  llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy,
29200b2517299415ab1c28b9cb87d536ccea84317a10John McCall                                                    "exceptiondata.ptr");
29210b2517299415ab1c28b9cb87d536ccea84317a10John McCall
292287bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // Create the fragile hazards.  Note that this will not capture any
292387bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // of the allocas required for exception processing, but will
292487bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // capture the current basic block (which extends all the way to the
292587bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // setjmp call) as "before the @try".
292687bb5822bfa4baea23a3d9273df266777f3ab796John McCall  FragileHazards Hazards(CGF);
292787bb5822bfa4baea23a3d9273df266777f3ab796John McCall
2928f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Create a flag indicating whether the cleanup needs to call
2929f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // objc_exception_try_exit.  This is true except when
2930f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   - no catches match and we're branching through the cleanup
2931f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //     just to rethrow the exception, or
2932f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   - a catch matched and we're falling out of the catch handler.
29330b2517299415ab1c28b9cb87d536ccea84317a10John McCall  // The setjmp-safety rule here is that we should always store to this
29340b2517299415ab1c28b9cb87d536ccea84317a10John McCall  // variable in a place that dominates the branch through the cleanup
29350b2517299415ab1c28b9cb87d536ccea84317a10John McCall  // without passing through any setjmps.
2936f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::Value *CallTryExitVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(),
2937190d00e1396214c77539c7095756b9ea38160463Anders Carlsson                                                     "_call_try_exit");
2938f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
29399e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall  // A slot containing the exception to rethrow.  Only needed when we
29409e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall  // have both a @catch and a @finally.
29419e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall  llvm::Value *PropagatingExnVar = 0;
29429e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall
2943f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Push a normal cleanup to leave the try scope.
29441f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall  CGF.EHStack.pushCleanup<PerformFragileFinally>(NormalCleanup, &S,
29450b2517299415ab1c28b9cb87d536ccea84317a10John McCall                                                 SyncArgSlot,
29461f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall                                                 CallTryExitVar,
29471f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall                                                 ExceptionData,
29481f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall                                                 &ObjCTypes);
29496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
2950f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Enter a try block:
2951f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //  - Call objc_exception_try_enter to push ExceptionData on top of
2952f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //    the EH stack.
2953f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData)
2954f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      ->setDoesNotThrow();
2955898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar
2956f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //  - Call setjmp on the exception data buffer.
2957f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::Constant *Zero = llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0);
2958f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::Value *GEPIndexes[] = { Zero, Zero, Zero };
2959f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::Value *SetJmpBuffer =
29600f6ac7cf7bc6a02c1a5c19d2c90ec0d1dd7786e7Jay Foad    CGF.Builder.CreateGEP(ExceptionData, GEPIndexes, "setjmp_buffer");
2961f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::CallInst *SetJmpResult =
2962f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result");
2963f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  SetJmpResult->setDoesNotThrow();
2964f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
2965f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // If setjmp returned 0, enter the protected block; otherwise,
2966f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // branch to the handler.
296755e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar  llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
296855e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar  llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
2969f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::Value *DidCatch =
2970d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall    CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
2971d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall  CGF.Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
297280f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson
2973f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Emit the protected block.
297480f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson  CGF.EmitBlock(TryBlock);
29750b2517299415ab1c28b9cb87d536ccea84317a10John McCall  CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
29766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
2977f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                     : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
29780b2517299415ab1c28b9cb87d536ccea84317a10John McCall
29790b2517299415ab1c28b9cb87d536ccea84317a10John McCall  CGBuilderTy::InsertPoint TryFallthroughIP = CGF.Builder.saveAndClearIP();
29806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
2981f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Emit the exception handler block.
2982e4b5ee06153777c6899d20797dce1d4d236eb4bcDaniel Dunbar  CGF.EmitBlock(TryHandler);
298355e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar
298487bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // Don't optimize loads of the in-scope locals across this point.
298587bb5822bfa4baea23a3d9273df266777f3ab796John McCall  Hazards.emitWriteHazard();
298687bb5822bfa4baea23a3d9273df266777f3ab796John McCall
2987f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // For a @synchronized (or a @try with no catches), just branch
2988f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // through the cleanup to the rethrow block.
2989f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
2990f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Tell the cleanup not to re-pop the exit.
29910b2517299415ab1c28b9cb87d536ccea84317a10John McCall    CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
2992f3a79a96eecff0fba4de8e29831a5ec0eaf90385Anders Carlsson    CGF.EmitBranchThroughCleanup(FinallyRethrow);
2993f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
2994f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Otherwise, we have to match against the caught exceptions.
2995f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  } else {
29960b2517299415ab1c28b9cb87d536ccea84317a10John McCall    // Retrieve the exception object.  We may emit multiple blocks but
29970b2517299415ab1c28b9cb87d536ccea84317a10John McCall    // nothing can cross this so the value is already in SSA form.
29980b2517299415ab1c28b9cb87d536ccea84317a10John McCall    llvm::CallInst *Caught =
29990b2517299415ab1c28b9cb87d536ccea84317a10John McCall      CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
30000b2517299415ab1c28b9cb87d536ccea84317a10John McCall                             ExceptionData, "caught");
30010b2517299415ab1c28b9cb87d536ccea84317a10John McCall    Caught->setDoesNotThrow();
30020b2517299415ab1c28b9cb87d536ccea84317a10John McCall
3003f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Push the exception to rethrow onto the EH value stack for the
3004f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // benefit of any @throws in the handlers.
3005f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.ObjCEHValueStack.push_back(Caught);
3006f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
30078f5e3dd32e443768d9dbbad7191e123e6733750cDouglas Gregor    const ObjCAtTryStmt* AtTryStmt = cast<ObjCAtTryStmt>(&S);
3008f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
30090b2517299415ab1c28b9cb87d536ccea84317a10John McCall    bool HasFinally = (AtTryStmt->getFinallyStmt() != 0);
30100b2517299415ab1c28b9cb87d536ccea84317a10John McCall
30110b2517299415ab1c28b9cb87d536ccea84317a10John McCall    llvm::BasicBlock *CatchBlock = 0;
30120b2517299415ab1c28b9cb87d536ccea84317a10John McCall    llvm::BasicBlock *CatchHandler = 0;
30130b2517299415ab1c28b9cb87d536ccea84317a10John McCall    if (HasFinally) {
30149e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      // Save the currently-propagating exception before
30159e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      // objc_exception_try_enter clears the exception slot.
30169e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      PropagatingExnVar = CGF.CreateTempAlloca(Caught->getType(),
30179e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall                                               "propagating_exception");
30189e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      CGF.Builder.CreateStore(Caught, PropagatingExnVar);
30199e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall
30200b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // Enter a new exception try block (in case a @catch block
30210b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // throws an exception).
30220b2517299415ab1c28b9cb87d536ccea84317a10John McCall      CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData)
30230b2517299415ab1c28b9cb87d536ccea84317a10John McCall        ->setDoesNotThrow();
30240b2517299415ab1c28b9cb87d536ccea84317a10John McCall
30250b2517299415ab1c28b9cb87d536ccea84317a10John McCall      llvm::CallInst *SetJmpResult =
30260b2517299415ab1c28b9cb87d536ccea84317a10John McCall        CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer,
30270b2517299415ab1c28b9cb87d536ccea84317a10John McCall                               "setjmp.result");
30280b2517299415ab1c28b9cb87d536ccea84317a10John McCall      SetJmpResult->setDoesNotThrow();
30290b2517299415ab1c28b9cb87d536ccea84317a10John McCall
30300b2517299415ab1c28b9cb87d536ccea84317a10John McCall      llvm::Value *Threw =
30310b2517299415ab1c28b9cb87d536ccea84317a10John McCall        CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
30326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
30330b2517299415ab1c28b9cb87d536ccea84317a10John McCall      CatchBlock = CGF.createBasicBlock("catch");
30340b2517299415ab1c28b9cb87d536ccea84317a10John McCall      CatchHandler = CGF.createBasicBlock("catch_for_catch");
30350b2517299415ab1c28b9cb87d536ccea84317a10John McCall      CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
303680f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson
30370b2517299415ab1c28b9cb87d536ccea84317a10John McCall      CGF.EmitBlock(CatchBlock);
30380b2517299415ab1c28b9cb87d536ccea84317a10John McCall    }
30396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
30400b2517299415ab1c28b9cb87d536ccea84317a10John McCall    CGF.Builder.CreateStore(CGF.Builder.getInt1(HasFinally), CallTryExitVar);
30416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
304255e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar    // Handle catch list. As a special case we check if everything is
304355e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar    // matched and avoid generating code for falling off the end if
304455e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar    // so.
304555e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar    bool AllMatched = false;
30468f5e3dd32e443768d9dbbad7191e123e6733750cDouglas Gregor    for (unsigned I = 0, N = AtTryStmt->getNumCatchStmts(); I != N; ++I) {
30478f5e3dd32e443768d9dbbad7191e123e6733750cDouglas Gregor      const ObjCAtCatchStmt *CatchStmt = AtTryStmt->getCatchStmt(I);
304880f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson
3049c00d8e18ad3d903acfeb5d05163ce90713066a3fDouglas Gregor      const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
305014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      const ObjCObjectPointerType *OPT = 0;
3051129271a42975f8b9d42adc707be9883db91c8a5dDaniel Dunbar
305280f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson      // catch(...) always matches.
305355e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar      if (!CatchParam) {
305455e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar        AllMatched = true;
305555e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar      } else {
3056183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall        OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>();
30576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3058f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        // catch(id e) always matches under this ABI, since only
3059f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        // ObjC exceptions end up here in the first place.
306097f61d14c89c26b9ae8e8f1faa8e8fcc6ec00b77Daniel Dunbar        // FIXME: For the time being we also match id<X>; this should
306197f61d14c89c26b9ae8e8f1faa8e8fcc6ec00b77Daniel Dunbar        // be rejected by Sema instead.
3062818e96f5a42b2a9adea4ac0050340469b49d70efEli Friedman        if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()))
306355e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar          AllMatched = true;
306480f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson      }
30656bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3066f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // If this is a catch-all, we don't need to test anything.
30676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      if (AllMatched) {
3068f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
3069f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3070dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson        if (CatchParam) {
3071b6bbcc9995186799a60ce17d0c1acff31601653aJohn McCall          CGF.EmitAutoVarDecl(*CatchParam);
3072a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar          assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
3073f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3074f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall          // These types work out because ConvertType(id) == i8*.
30757ba138abd329e591a8f6d5001f60dd7082f71b3bSteve Naroff          CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(CatchParam));
3076dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson        }
30776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3078dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson        CGF.EmitStmt(CatchStmt->getCatchBody());
3079f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3080f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        // The scope of the catch variable ends right here.
3081f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        CatchVarCleanups.ForceCleanup();
3082f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3083f3a79a96eecff0fba4de8e29831a5ec0eaf90385Anders Carlsson        CGF.EmitBranchThroughCleanup(FinallyEnd);
308480f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson        break;
308580f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson      }
30866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
308714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      assert(OPT && "Unexpected non-object pointer type in @catch");
3088506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall      const ObjCObjectType *ObjTy = OPT->getObjectType();
3089f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3090f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // FIXME: @catch (Class c) ?
3091506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall      ObjCInterfaceDecl *IDecl = ObjTy->getInterface();
3092506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall      assert(IDecl && "Catch parameter must have Objective-C type!");
309380f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson
309480f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson      // Check if the @catch block matches the exception object.
3095506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall      llvm::Value *Class = EmitClassRef(CGF.Builder, IDecl);
30966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3097f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      llvm::CallInst *Match =
309834b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner        CGF.Builder.CreateCall2(ObjCTypes.getExceptionMatchFn(),
309934b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner                                Class, Caught, "match");
3100f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      Match->setDoesNotThrow();
31016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3102f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("match");
3103f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch.next");
31046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
31056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"),
3106e4b5ee06153777c6899d20797dce1d4d236eb4bcDaniel Dunbar                               MatchedBlock, NextCatchBlock);
31076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
310880f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson      // Emit the @catch block.
310980f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson      CGF.EmitBlock(MatchedBlock);
3110f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3111f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // Collect any cleanups for the catch variable.  The scope lasts until
3112f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // the end of the catch body.
31130b2517299415ab1c28b9cb87d536ccea84317a10John McCall      CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
3114f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3115b6bbcc9995186799a60ce17d0c1acff31601653aJohn McCall      CGF.EmitAutoVarDecl(*CatchParam);
3116a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar      assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
311718ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar
3118f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // Initialize the catch variable.
31196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      llvm::Value *Tmp =
31206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar        CGF.Builder.CreateBitCast(Caught,
3121578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer                                  CGF.ConvertType(CatchParam->getType()));
31227ba138abd329e591a8f6d5001f60dd7082f71b3bSteve Naroff      CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(CatchParam));
31236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3124dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson      CGF.EmitStmt(CatchStmt->getCatchBody());
3125f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3126f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // We're done with the catch variable.
3127f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      CatchVarCleanups.ForceCleanup();
3128f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3129f3a79a96eecff0fba4de8e29831a5ec0eaf90385Anders Carlsson      CGF.EmitBranchThroughCleanup(FinallyEnd);
31306bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
313180f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson      CGF.EmitBlock(NextCatchBlock);
313280f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson    }
313380f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson
3134f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.ObjCEHValueStack.pop_back();
3135f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
31360b2517299415ab1c28b9cb87d536ccea84317a10John McCall    // If nothing wanted anything to do with the caught exception,
31370b2517299415ab1c28b9cb87d536ccea84317a10John McCall    // kill the extract call.
31380b2517299415ab1c28b9cb87d536ccea84317a10John McCall    if (Caught->use_empty())
31390b2517299415ab1c28b9cb87d536ccea84317a10John McCall      Caught->eraseFromParent();
31400b2517299415ab1c28b9cb87d536ccea84317a10John McCall
31410b2517299415ab1c28b9cb87d536ccea84317a10John McCall    if (!AllMatched)
3142f3a79a96eecff0fba4de8e29831a5ec0eaf90385Anders Carlsson      CGF.EmitBranchThroughCleanup(FinallyRethrow);
31436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
31440b2517299415ab1c28b9cb87d536ccea84317a10John McCall    if (HasFinally) {
31450b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // Emit the exception handler for the @catch blocks.
31460b2517299415ab1c28b9cb87d536ccea84317a10John McCall      CGF.EmitBlock(CatchHandler);
3147f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
31480b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // In theory we might now need a write hazard, but actually it's
31490b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // unnecessary because there's no local-accessing code between
31500b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // the try's write hazard and here.
31510b2517299415ab1c28b9cb87d536ccea84317a10John McCall      //Hazards.emitWriteHazard();
3152f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
31539e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      // Extract the new exception and save it to the
31549e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      // propagating-exception slot.
31559e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      assert(PropagatingExnVar);
31569e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      llvm::CallInst *NewCaught =
31579e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall        CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
31589e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall                               ExceptionData, "caught");
31599e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      NewCaught->setDoesNotThrow();
31609e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      CGF.Builder.CreateStore(NewCaught, PropagatingExnVar);
31619e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall
31620b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // Don't pop the catch handler; the throw already did.
31630b2517299415ab1c28b9cb87d536ccea84317a10John McCall      CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
31640b2517299415ab1c28b9cb87d536ccea84317a10John McCall      CGF.EmitBranchThroughCleanup(FinallyRethrow);
31650b2517299415ab1c28b9cb87d536ccea84317a10John McCall    }
316680f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson  }
31676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
316887bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // Insert read hazards as required in the new blocks.
31690b2517299415ab1c28b9cb87d536ccea84317a10John McCall  Hazards.emitHazardsInNewBlocks();
317087bb5822bfa4baea23a3d9273df266777f3ab796John McCall
3171f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Pop the cleanup.
31720b2517299415ab1c28b9cb87d536ccea84317a10John McCall  CGF.Builder.restoreIP(TryFallthroughIP);
31730b2517299415ab1c28b9cb87d536ccea84317a10John McCall  if (CGF.HaveInsertPoint())
31740b2517299415ab1c28b9cb87d536ccea84317a10John McCall    CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
3175f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGF.PopCleanupBlock();
31760b2517299415ab1c28b9cb87d536ccea84317a10John McCall  CGF.EmitBlock(FinallyEnd.getBlock(), true);
31776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3178f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Emit the rethrow block.
317987bb5822bfa4baea23a3d9273df266777f3ab796John McCall  CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
3180ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall  CGF.EmitBlock(FinallyRethrow.getBlock(), true);
3181f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (CGF.HaveInsertPoint()) {
31829e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall    // If we have a propagating-exception variable, check it.
31839e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall    llvm::Value *PropagatingExn;
31849e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall    if (PropagatingExnVar) {
31859e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      PropagatingExn = CGF.Builder.CreateLoad(PropagatingExnVar);
31869e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall
31879e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall    // Otherwise, just look in the buffer for the exception to throw.
31889e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall    } else {
31899e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      llvm::CallInst *Caught =
31909e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall        CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
31919e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall                               ExceptionData);
31929e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      Caught->setDoesNotThrow();
31939e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      PropagatingExn = Caught;
31949e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall    }
31950b2517299415ab1c28b9cb87d536ccea84317a10John McCall
31969e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall    CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), PropagatingExn)
3197f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      ->setDoesNotThrow();
3198f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.Builder.CreateUnreachable();
3199f2878e5dffd20bf0a97fb0b30a376f2d60963593Fariborz Jahanian  }
320080f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson
320187bb5822bfa4baea23a3d9273df266777f3ab796John McCall  CGF.Builder.restoreIP(SavedIP);
320264d5d6c5903157c521af496479d06dc26032d718Anders Carlsson}
320364d5d6c5903157c521af496479d06dc26032d718Anders Carlsson
320464d5d6c5903157c521af496479d06dc26032d718Anders Carlssonvoid CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
3205898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar                              const ObjCAtThrowStmt &S) {
32062b1e311009cf682b7b5adb8ba97a0816f727bfb7Anders Carlsson  llvm::Value *ExceptionAsObject;
32076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
32082b1e311009cf682b7b5adb8ba97a0816f727bfb7Anders Carlsson  if (const Expr *ThrowExpr = S.getThrowExpr()) {
32092b014d6c0c6b8ac94b416ac37dfc7931f20777a7John McCall    llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
32106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    ExceptionAsObject =
3211578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer      CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
32122b1e311009cf682b7b5adb8ba97a0816f727bfb7Anders Carlsson  } else {
32136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
321418ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar           "Unexpected rethrow outside @catch block.");
3215273558fbd891a0872e620e0d3d109b92c1160d72Anders Carlsson    ExceptionAsObject = CGF.ObjCEHValueStack.back();
32162b1e311009cf682b7b5adb8ba97a0816f727bfb7Anders Carlsson  }
32176bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3218f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
3219f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    ->setDoesNotReturn();
322080f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson  CGF.Builder.CreateUnreachable();
3221a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar
3222a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar  // Clear the insertion point to indicate we are in unreachable code.
3223a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar  CGF.Builder.ClearInsertionPoint();
322464d5d6c5903157c521af496479d06dc26032d718Anders Carlsson}
322564d5d6c5903157c521af496479d06dc26032d718Anders Carlsson
32263e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian/// EmitObjCWeakRead - Code gen for loading value of a __weak
32276dc2317b59cb1180a59f6c283d96b7a5dfeb5307Fariborz Jahanian/// object: objc_read_weak (id *src)
32286dc2317b59cb1180a59f6c283d96b7a5dfeb5307Fariborz Jahanian///
32293e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanianllvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
32301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                          llvm::Value *AddrWeakObj) {
32312acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type* DestTy =
32326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
32336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj,
32346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                          ObjCTypes.PtrObjectPtrTy);
323572db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(),
32363e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian                                                  AddrWeakObj, "weakread");
32378339b35ca05dd040a9a0ecfc92e7b49d80c5a96bEli Friedman  read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
32386dc2317b59cb1180a59f6c283d96b7a5dfeb5307Fariborz Jahanian  return read_weak;
32396dc2317b59cb1180a59f6c283d96b7a5dfeb5307Fariborz Jahanian}
32406dc2317b59cb1180a59f6c283d96b7a5dfeb5307Fariborz Jahanian
32413e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian/// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
32423e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian/// objc_assign_weak (id src, id *dst)
32433e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian///
32443e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanianvoid CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
32451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                   llvm::Value *src, llvm::Value *dst) {
32462acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type * SrcTy = src->getType();
32470a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian  if (!isa<llvm::PointerType>(SrcTy)) {
32489408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
32490a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    assert(Size <= 8 && "does not support size > 8");
32500a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
32516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
32523b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
32533b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian  }
3254dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
3255dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
325696508e1fea58347b6401ca9a4728c0b268174603Chris Lattner  CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(),
32573e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian                          src, dst, "weakassign");
32583e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian  return;
32593e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian}
32603e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian
326158626500527695865683d1d65053743de8770b60Fariborz Jahanian/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
326258626500527695865683d1d65053743de8770b60Fariborz Jahanian/// objc_assign_global (id src, id *dst)
326358626500527695865683d1d65053743de8770b60Fariborz Jahanian///
326458626500527695865683d1d65053743de8770b60Fariborz Jahanianvoid CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
3265021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                                     llvm::Value *src, llvm::Value *dst,
3266021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                                     bool threadlocal) {
32672acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type * SrcTy = src->getType();
32680a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian  if (!isa<llvm::PointerType>(SrcTy)) {
32699408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
32700a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    assert(Size <= 8 && "does not support size > 8");
32710a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
32726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
32733b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
32743b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian  }
3275dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
3276dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
3277021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian  if (!threadlocal)
3278021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian    CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(),
3279021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                            src, dst, "globalassign");
3280021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian  else
3281021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian    CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(),
3282021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                            src, dst, "threadlocalassign");
328358626500527695865683d1d65053743de8770b60Fariborz Jahanian  return;
328458626500527695865683d1d65053743de8770b60Fariborz Jahanian}
328558626500527695865683d1d65053743de8770b60Fariborz Jahanian
32867eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian/// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
32876c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian/// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset)
32887eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian///
32897eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanianvoid CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
32906c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian                                   llvm::Value *src, llvm::Value *dst,
32916c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian                                   llvm::Value *ivarOffset) {
32926c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian  assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL");
32932acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type * SrcTy = src->getType();
32940a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian  if (!isa<llvm::PointerType>(SrcTy)) {
32959408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
32960a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    assert(Size <= 8 && "does not support size > 8");
32970a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
32986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
32993b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
33003b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian  }
33017eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
33027eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
33036c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian  CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(),
33046c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian                          src, dst, ivarOffset);
33057eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian  return;
33067eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian}
33077eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian
330858626500527695865683d1d65053743de8770b60Fariborz Jahanian/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
330958626500527695865683d1d65053743de8770b60Fariborz Jahanian/// objc_assign_strongCast (id src, id *dst)
331058626500527695865683d1d65053743de8770b60Fariborz Jahanian///
331158626500527695865683d1d65053743de8770b60Fariborz Jahanianvoid CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
33121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                         llvm::Value *src, llvm::Value *dst) {
33132acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type * SrcTy = src->getType();
33140a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian  if (!isa<llvm::PointerType>(SrcTy)) {
33159408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
33160a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    assert(Size <= 8 && "does not support size > 8");
33170a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
33186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
33193b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
33203b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian  }
3321dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
3322dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
3323bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(),
332458626500527695865683d1d65053743de8770b60Fariborz Jahanian                          src, dst, "weakassign");
332558626500527695865683d1d65053743de8770b60Fariborz Jahanian  return;
332658626500527695865683d1d65053743de8770b60Fariborz Jahanian}
332758626500527695865683d1d65053743de8770b60Fariborz Jahanian
3328082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanianvoid CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
33296bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                         llvm::Value *DestPtr,
33306bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                         llvm::Value *SrcPtr,
333155bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian                                         llvm::Value *size) {
3332082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
3333082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
3334082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(),
333555bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian                          DestPtr, SrcPtr, size);
3336082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  return;
3337082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian}
3338082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian
33390bb20361a321593887f067515dd04cf109f4c74aFariborz Jahanian/// EmitObjCValueForIvar - Code Gen for ivar reference.
33400bb20361a321593887f067515dd04cf109f4c74aFariborz Jahanian///
3341598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz JahanianLValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
3342598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                       QualType ObjectTy,
3343598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                       llvm::Value *BaseValue,
3344598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                       const ObjCIvarDecl *Ivar,
3345598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                       unsigned CVRQualifiers) {
3346c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  const ObjCInterfaceDecl *ID =
3347c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall    ObjectTy->getAs<ObjCObjectType>()->getInterface();
33489777687562c338601c2f17906e65e1c1a0aad96fDaniel Dunbar  return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
33499777687562c338601c2f17906e65e1c1a0aad96fDaniel Dunbar                                  EmitIvarOffset(CGF, ID, Ivar));
33500bb20361a321593887f067515dd04cf109f4c74aFariborz Jahanian}
33510bb20361a321593887f067515dd04cf109f4c74aFariborz Jahanian
3352f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanianllvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
33532a03192a02dbf4fdff438d1e658356bde871aba4Daniel Dunbar                                       const ObjCInterfaceDecl *Interface,
3354f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian                                       const ObjCIvarDecl *Ivar) {
33559777687562c338601c2f17906e65e1c1a0aad96fDaniel Dunbar  uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
33564a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  return llvm::ConstantInt::get(
33576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    CGM.getTypes().ConvertType(CGM.getContext().LongTy),
33586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Offset);
3359f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian}
3360f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian
3361f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/* *** Private Interface *** */
3362f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar
3363f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// EmitImageInfo - Emit the image info marker used to encode some module
3364f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// level information.
3365f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar///
3366f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// See: <rdr://4810609&4810587&4810587>
3367f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// struct IMAGE_INFO {
3368f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar///   unsigned version;
3369f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar///   unsigned flags;
3370f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// };
3371f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbarenum ImageInfoFlags {
3372fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar  eImageInfo_FixAndContinue      = (1 << 0),
33736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  eImageInfo_GarbageCollected    = (1 << 1),
33746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  eImageInfo_GCOnly              = (1 << 2),
3375c7c6dc0c7ad547f03778502a63a18c3277dd93b5Daniel Dunbar  eImageInfo_OptimizedByDyld     = (1 << 3), // FIXME: When is this set.
3376c7c6dc0c7ad547f03778502a63a18c3277dd93b5Daniel Dunbar
3377fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar  // A flag indicating that the module has no instances of a @synthesize of a
3378fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar  // superclass variable. <rdar://problem/6803242>
3379c7c6dc0c7ad547f03778502a63a18c3277dd93b5Daniel Dunbar  eImageInfo_CorrectedSynthesize = (1 << 4)
3380f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar};
3381f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar
3382fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbarvoid CGObjCCommonMac::EmitImageInfo() {
3383f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar  unsigned version = 0; // Version is unused?
3384f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar  unsigned flags = 0;
3385f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar
3386f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar  // FIXME: Fix and continue?
3387e289d81369914678db386f6aa86faf8f178e245dDouglas Gregor  if (CGM.getLangOptions().getGC() != LangOptions::NonGC)
3388f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar    flags |= eImageInfo_GarbageCollected;
3389e289d81369914678db386f6aa86faf8f178e245dDouglas Gregor  if (CGM.getLangOptions().getGC() == LangOptions::GCOnly)
3390f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar    flags |= eImageInfo_GCOnly;
33916bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3392c7c6dc0c7ad547f03778502a63a18c3277dd93b5Daniel Dunbar  // We never allow @synthesize of a superclass property.
3393c7c6dc0c7ad547f03778502a63a18c3277dd93b5Daniel Dunbar  flags |= eImageInfo_CorrectedSynthesize;
3394f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar
33952acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *Int32Ty = llvm::Type::getInt32Ty(VMContext);
339677b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner
3397f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar  // Emitted as int[2];
3398f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar  llvm::Constant *values[2] = {
339977b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner    llvm::ConstantInt::get(Int32Ty, version),
340077b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner    llvm::ConstantInt::get(Int32Ty, flags)
3401f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar  };
340277b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner  llvm::ArrayType *AT = llvm::ArrayType::get(Int32Ty, 2);
3403f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar
340463c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar  const char *Section;
340563c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar  if (ObjCABI == 1)
340663c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar    Section = "__OBJC, __image_info,regular";
340763c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar  else
340863c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar    Section = "__DATA, __objc_imageinfo, regular, no_dead_strip";
34096bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::GlobalVariable *GV =
341063c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar    CreateMetadataVar("\01L_OBJC_IMAGE_INFO",
341197357602a289749d59520ac4ac31149f8d32e12eJay Foad                      llvm::ConstantArray::get(AT, values),
341263c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar                      Section,
341363c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar                      0,
341463c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar                      true);
341563c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar  GV->setConstant(true);
3416f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar}
3417f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar
34184e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
34194e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar// struct objc_module {
34204e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar//   unsigned long version;
34214e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar//   unsigned long size;
34224e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar//   const char *name;
34234e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar//   Symtab symtab;
34244e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar// };
34254e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
34264e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar// FIXME: Get from somewhere
34274e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbarstatic const int ModuleVersion = 7;
34284e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
34294e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbarvoid CGObjCMac::EmitModuleInfo() {
34309408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands  uint64_t Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ModuleTy);
34316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
34321d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  llvm::Constant *Values[] = {
34331d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion),
34341d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    llvm::ConstantInt::get(ObjCTypes.LongTy, Size),
34351d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    // This used to be the filename, now it is unused. <rdr://4327263>
34361d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    GetClassName(&CGM.getContext().Idents.get("")),
34371d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    EmitModuleSymbols()
34381d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  };
34396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  CreateMetadataVar("\01L_OBJC_MODULES",
344008e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson                    llvm::ConstantStruct::get(ObjCTypes.ModuleTy, Values),
344163c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar                    "__OBJC,__module_info,regular,no_dead_strip",
344258a29128005f6e54c7d3aa39797d86ada8d40006Daniel Dunbar                    4, true);
34434e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar}
34444e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
34454e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbarllvm::Constant *CGObjCMac::EmitModuleSymbols() {
344627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  unsigned NumClasses = DefinedClasses.size();
344727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  unsigned NumCategories = DefinedCategories.size();
344827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
3449242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  // Return null if no symbols were defined.
3450242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  if (!NumClasses && !NumCategories)
3451c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
3452242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar
3453c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[5];
34544a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
3455c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
34564a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
34574a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
345827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
345986e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  // The runtime expects exactly the list of defined classes followed
346086e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  // by the list of defined categories, in a single array.
346127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories);
346286e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  for (unsigned i=0; i<NumClasses; i++)
34633c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson    Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
346486e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar                                                ObjCTypes.Int8PtrTy);
346586e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  for (unsigned i=0; i<NumCategories; i++)
34666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Symbols[NumClasses + i] =
34673c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson      llvm::ConstantExpr::getBitCast(DefinedCategories[i],
346886e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar                                     ObjCTypes.Int8PtrTy);
346986e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar
34706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[4] =
347196e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
347227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                                                  NumClasses + NumCategories),
347327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                             Symbols);
347427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
3475c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
347627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
34774e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  llvm::GlobalVariable *GV =
347863c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar    CreateMetadataVar("\01L_OBJC_SYMBOLS", Init,
347963c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar                      "__OBJC,__symbols,regular,no_dead_strip",
34800bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar                      4, true);
34813c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
348227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar}
348327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
3484f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCMac::EmitClassRefFromId(CGBuilderTy &Builder,
3485f85e193739c953358c865005855253af4f68a497John McCall                                     IdentifierInfo *II) {
3486f85e193739c953358c865005855253af4f68a497John McCall  LazySymbols.insert(II);
3487f85e193739c953358c865005855253af4f68a497John McCall
3488f85e193739c953358c865005855253af4f68a497John McCall  llvm::GlobalVariable *&Entry = ClassReferences[II];
3489f85e193739c953358c865005855253af4f68a497John McCall
349027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  if (!Entry) {
34916bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    llvm::Constant *Casted =
3492f85e193739c953358c865005855253af4f68a497John McCall    llvm::ConstantExpr::getBitCast(GetClassName(II),
3493f85e193739c953358c865005855253af4f68a497John McCall                                   ObjCTypes.ClassPtrTy);
34946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry =
3495f85e193739c953358c865005855253af4f68a497John McCall    CreateMetadataVar("\01L_OBJC_CLASS_REFERENCES_", Casted,
3496f85e193739c953358c865005855253af4f68a497John McCall                      "__OBJC,__cls_refs,literal_pointers,no_dead_strip",
3497f85e193739c953358c865005855253af4f68a497John McCall                      4, true);
349827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  }
3499f85e193739c953358c865005855253af4f68a497John McCall
3500578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer  return Builder.CreateLoad(Entry);
35014e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar}
35024e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
3503f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCMac::EmitClassRef(CGBuilderTy &Builder,
3504f85e193739c953358c865005855253af4f68a497John McCall                                     const ObjCInterfaceDecl *ID) {
3505f85e193739c953358c865005855253af4f68a497John McCall  return EmitClassRefFromId(Builder, ID->getIdentifier());
3506f85e193739c953358c865005855253af4f68a497John McCall}
3507f85e193739c953358c865005855253af4f68a497John McCall
3508f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder) {
3509f85e193739c953358c865005855253af4f68a497John McCall  IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
3510f85e193739c953358c865005855253af4f68a497John McCall  return EmitClassRefFromId(Builder, II);
3511f85e193739c953358c865005855253af4f68a497John McCall}
3512f85e193739c953358c865005855253af4f68a497John McCall
351303b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanianllvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel,
351403b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian                                     bool lvalue) {
3515259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar  llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
35166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3517259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar  if (!Entry) {
35186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    llvm::Constant *Casted =
35193c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson      llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
3520259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar                                     ObjCTypes.SelectorPtrTy);
35216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry =
352263c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar      CreateMetadataVar("\01L_OBJC_SELECTOR_REFERENCES_", Casted,
352363c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar                        "__OBJC,__message_refs,literal_pointers,no_dead_strip",
35240bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar                        4, true);
3525259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar  }
3526259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar
352703b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian  if (lvalue)
352803b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian    return Entry;
3529578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer  return Builder.CreateLoad(Entry);
3530259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar}
3531259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar
3532058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) {
35336efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  llvm::GlobalVariable *&Entry = ClassNames[Ident];
35344e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
353563c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar  if (!Entry)
35366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
35379c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                          llvm::ConstantArray::get(VMContext,
35389c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                                   Ident->getNameStart()),
3539af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                              ((ObjCABI == 2) ?
3540af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                               "__TEXT,__objc_classname,cstring_literals" :
3541af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                               "__TEXT,__cstring,cstring_literals"),
3542b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar                              1, true);
35434e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
3544a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson  return getConstantGEP(VMContext, Entry, 0, 0);
35454e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar}
35464e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
35479d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidisllvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
35489d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis  llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator
35499d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis      I = MethodDefinitions.find(MD);
35509d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis  if (I != MethodDefinitions.end())
35519d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis    return I->second;
35529d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis
35539d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis  return NULL;
35549d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis}
35559d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis
3556d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian/// GetIvarLayoutName - Returns a unique constant for the given
3557d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian/// ivar layout bitmap.
3558d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
35596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                       const ObjCCommonTypesHelper &ObjCTypes) {
3560c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
3561d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian}
3562d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian
3563d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbarvoid CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT,
35646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                unsigned int BytePos,
3565d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar                                                bool ForStrongLayout,
3566d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar                                                bool &HasUnion) {
3567d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar  const RecordDecl *RD = RT->getDecl();
3568d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar  // FIXME - Use iterator.
3569db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  SmallVector<const FieldDecl*, 16> Fields(RD->field_begin(), RD->field_end());
35702acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
35716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const llvm::StructLayout *RecLayout =
3572d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar    CGM.getTargetData().getStructLayout(cast<llvm::StructType>(Ty));
35736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3574d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar  BuildAggrIvarLayout(0, RecLayout, RD, Fields, BytePos,
3575d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar                      ForStrongLayout, HasUnion);
3576d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar}
3577d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar
35785a5a803df8a8e3e567278fdfd8a6c1aff8dc6b82Daniel Dunbarvoid CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
35796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             const llvm::StructLayout *Layout,
35806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             const RecordDecl *RD,
3581db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose                             const SmallVectorImpl<const FieldDecl*> &RecFields,
35826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             unsigned int BytePos, bool ForStrongLayout,
35836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             bool &HasUnion) {
3584820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian  bool IsUnion = (RD && RD->isUnion());
3585820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian  uint64_t MaxUnionIvarSize = 0;
3586820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian  uint64_t MaxSkippedUnionIvarSize = 0;
3587db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  const FieldDecl *MaxField = 0;
3588db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  const FieldDecl *MaxSkippedField = 0;
3589db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  const FieldDecl *LastFieldBitfieldOrUnnamed = 0;
3590900c1980de73d17cdc11b108cde7f9b68be1e5bdDaniel Dunbar  uint64_t MaxFieldOffset = 0;
3591900c1980de73d17cdc11b108cde7f9b68be1e5bdDaniel Dunbar  uint64_t MaxSkippedFieldOffset = 0;
35920dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis  uint64_t LastBitfieldOrUnnamedOffset = 0;
3593f85e193739c953358c865005855253af4f68a497John McCall  uint64_t FirstFieldDelta = 0;
35946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3595a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian  if (RecFields.empty())
3596a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian    return;
3597bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  unsigned WordSizeInBits = CGM.getContext().getTargetInfo().getPointerWidth(0);
3598bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth();
3599f85e193739c953358c865005855253af4f68a497John McCall  if (!RD && CGM.getLangOptions().ObjCAutoRefCount) {
3600db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose    const FieldDecl *FirstField = RecFields[0];
3601f85e193739c953358c865005855253af4f68a497John McCall    FirstFieldDelta =
3602f85e193739c953358c865005855253af4f68a497John McCall      ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(FirstField));
3603f85e193739c953358c865005855253af4f68a497John McCall  }
3604f85e193739c953358c865005855253af4f68a497John McCall
3605f1690858344968358131f8d5690d9ee458883000Chris Lattner  for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
3606db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose    const FieldDecl *Field = RecFields[i];
3607e05cc98e97ec910829beccd0d890a002ce5ab909Daniel Dunbar    uint64_t FieldOffset;
3608fc514abac21dbd801e2b665a1a24075c5ff62f44Anders Carlsson    if (RD) {
3609f8f8ebafafa6f4469a44de7a64194f52be1b8f53Daniel Dunbar      // Note that 'i' here is actually the field index inside RD of Field,
3610f8f8ebafafa6f4469a44de7a64194f52be1b8f53Daniel Dunbar      // although this dependency is hidden.
3611f8f8ebafafa6f4469a44de7a64194f52be1b8f53Daniel Dunbar      const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
3612f85e193739c953358c865005855253af4f68a497John McCall      FieldOffset = (RL.getFieldOffset(i) / ByteSizeInBits) - FirstFieldDelta;
3613fc514abac21dbd801e2b665a1a24075c5ff62f44Anders Carlsson    } else
3614f85e193739c953358c865005855253af4f68a497John McCall      FieldOffset =
3615f85e193739c953358c865005855253af4f68a497John McCall        ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field)) - FirstFieldDelta;
361625d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar
3617a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian    // Skip over unnamed or bitfields
36187fb162785f42d74d419db3d0d37ba698bca780a1Fariborz Jahanian    if (!Field->getIdentifier() || Field->isBitField()) {
36190dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis      LastFieldBitfieldOrUnnamed = Field;
36200dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis      LastBitfieldOrUnnamedOffset = FieldOffset;
3621a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian      continue;
36227fb162785f42d74d419db3d0d37ba698bca780a1Fariborz Jahanian    }
362325d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar
36240dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis    LastFieldBitfieldOrUnnamed = 0;
3625a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian    QualType FQT = Field->getType();
3626667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian    if (FQT->isRecordType() || FQT->isUnionType()) {
3627a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian      if (FQT->isUnionType())
3628a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian        HasUnion = true;
3629820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian
36306bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      BuildAggrIvarRecordLayout(FQT->getAs<RecordType>(),
363125d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar                                BytePos + FieldOffset,
3632d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar                                ForStrongLayout, HasUnion);
3633a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian      continue;
3634a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian    }
36356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3636f1690858344968358131f8d5690d9ee458883000Chris Lattner    if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
36376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      const ConstantArrayType *CArray =
36385e563dd38d6ec9f367cfd4b55d3efaf88a97cc09Daniel Dunbar        dyn_cast_or_null<ConstantArrayType>(Array);
36397fb162785f42d74d419db3d0d37ba698bca780a1Fariborz Jahanian      uint64_t ElCount = CArray->getSize().getZExtValue();
36405e563dd38d6ec9f367cfd4b55d3efaf88a97cc09Daniel Dunbar      assert(CArray && "only array with known element size is supported");
3641820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian      FQT = CArray->getElementType();
3642667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian      while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
3643667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian        const ConstantArrayType *CArray =
36445e563dd38d6ec9f367cfd4b55d3efaf88a97cc09Daniel Dunbar          dyn_cast_or_null<ConstantArrayType>(Array);
36457fb162785f42d74d419db3d0d37ba698bca780a1Fariborz Jahanian        ElCount *= CArray->getSize().getZExtValue();
3646667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian        FQT = CArray->getElementType();
3647667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian      }
36486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
36496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      assert(!FQT->isUnionType() &&
3650820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian             "layout for array of unions not supported");
3651f96bdf409fc9e5570e35aaf8a9167265e63d58d8Fariborz Jahanian      if (FQT->isRecordType() && ElCount) {
365281adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian        int OldIndex = IvarsInfo.size() - 1;
365381adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian        int OldSkIndex = SkipIvars.size() -1;
36546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
36556217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        const RecordType *RT = FQT->getAs<RecordType>();
365625d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar        BuildAggrIvarRecordLayout(RT, BytePos + FieldOffset,
3657d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar                                  ForStrongLayout, HasUnion);
36586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3659820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian        // Replicate layout information for each array element. Note that
3660820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian        // one element is already done.
3661820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian        uint64_t ElIx = 1;
36626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar        for (int FirstIndex = IvarsInfo.size() - 1,
36636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar               FirstSkIndex = SkipIvars.size() - 1 ;ElIx < ElCount; ElIx++) {
3664c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian          uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits;
36658b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar          for (int i = OldIndex+1; i <= FirstIndex; ++i)
36668b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar            IvarsInfo.push_back(GC_IVAR(IvarsInfo[i].ivar_bytepos + Size*ElIx,
36678b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar                                        IvarsInfo[i].ivar_size));
36688b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar          for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i)
36698b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar            SkipIvars.push_back(GC_IVAR(SkipIvars[i].ivar_bytepos + Size*ElIx,
36708b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar                                        SkipIvars[i].ivar_size));
3671820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian        }
3672820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian        continue;
3673820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian      }
3674a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian    }
3675820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian    // At this point, we are done with Record/Union and array there of.
3676820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian    // For other arrays we are down to its element type.
36770953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT);
36785e563dd38d6ec9f367cfd4b55d3efaf88a97cc09Daniel Dunbar
36798b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar    unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType());
36800953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    if ((ForStrongLayout && GCAttr == Qualifiers::Strong)
36810953e767ff7817f97b3ab20896b229891eeff45bJohn McCall        || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
3682487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar      if (IsUnion) {
36838b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar        uint64_t UnionIvarSize = FieldSize / WordSizeInBits;
3684487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar        if (UnionIvarSize > MaxUnionIvarSize) {
3685820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian          MaxUnionIvarSize = UnionIvarSize;
3686820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian          MaxField = Field;
3687900c1980de73d17cdc11b108cde7f9b68be1e5bdDaniel Dunbar          MaxFieldOffset = FieldOffset;
3688820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian        }
3689487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar      } else {
369025d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar        IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset,
36918b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar                                    FieldSize / WordSizeInBits));
3692820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian      }
36936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    } else if ((ForStrongLayout &&
36940953e767ff7817f97b3ab20896b229891eeff45bJohn McCall                (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak))
36950953e767ff7817f97b3ab20896b229891eeff45bJohn McCall               || (!ForStrongLayout && GCAttr != Qualifiers::Weak)) {
3696487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar      if (IsUnion) {
3697f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump        // FIXME: Why the asymmetry? We divide by word size in bits on other
3698f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump        // side.
36998b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar        uint64_t UnionIvarSize = FieldSize;
3700487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar        if (UnionIvarSize > MaxSkippedUnionIvarSize) {
3701820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian          MaxSkippedUnionIvarSize = UnionIvarSize;
3702820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian          MaxSkippedField = Field;
3703900c1980de73d17cdc11b108cde7f9b68be1e5bdDaniel Dunbar          MaxSkippedFieldOffset = FieldOffset;
3704820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian        }
3705487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar      } else {
37068b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar        // FIXME: Why the asymmetry, we divide by byte size in bits here?
370725d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar        SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset,
37088b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar                                    FieldSize / ByteSizeInBits));
3709820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian      }
3710820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian    }
3711820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian  }
3712d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar
37130dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis  if (LastFieldBitfieldOrUnnamed) {
37140dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis    if (LastFieldBitfieldOrUnnamed->isBitField()) {
37150dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis      // Last field was a bitfield. Must update skip info.
3716a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith      uint64_t BitFieldSize
3717a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith          = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext());
37180dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis      GC_IVAR skivar;
37190dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis      skivar.ivar_bytepos = BytePos + LastBitfieldOrUnnamedOffset;
37200dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis      skivar.ivar_size = (BitFieldSize / ByteSizeInBits)
37210dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis        + ((BitFieldSize % ByteSizeInBits) != 0);
37220dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis      SkipIvars.push_back(skivar);
37230dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis    } else {
37240dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis      assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed");
37250dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis      // Last field was unnamed. Must update skip info.
37260dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis      unsigned FieldSize
37270dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis          = CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType());
37280dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis      SkipIvars.push_back(GC_IVAR(BytePos + LastBitfieldOrUnnamedOffset,
37290dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis                                  FieldSize / ByteSizeInBits));
37300dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis    }
37317fb162785f42d74d419db3d0d37ba698bca780a1Fariborz Jahanian  }
37326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
37338b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar  if (MaxField)
37346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    IvarsInfo.push_back(GC_IVAR(BytePos + MaxFieldOffset,
37358b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar                                MaxUnionIvarSize));
37368b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar  if (MaxSkippedField)
3737900c1980de73d17cdc11b108cde7f9b68be1e5bdDaniel Dunbar    SkipIvars.push_back(GC_IVAR(BytePos + MaxSkippedFieldOffset,
37388b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar                                MaxSkippedUnionIvarSize));
3739d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian}
3740d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian
3741b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian/// BuildIvarLayoutBitmap - This routine is the horsework for doing all
3742b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian/// the computations and returning the layout bitmap (for ivar or blocks) in
3743b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian/// the given argument BitMap string container. Routine reads
3744b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian/// two containers, IvarsInfo and SkipIvars which are assumed to be
3745b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian/// filled already by the caller.
3746b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanianllvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string& BitMap) {
37479397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  unsigned int WordsToScan, WordsToSkip;
37482acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext);
374993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
37509397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  // Build the string of skip/scan nibbles
37515f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<SKIP_SCAN, 32> SkipScanIvars;
37526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  unsigned int WordSize =
375393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  CGM.getTypes().getTargetData().getTypeAllocSize(PtrTy);
37549397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  if (IvarsInfo[0].ivar_bytepos == 0) {
37559397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    WordsToSkip = 0;
37569397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    WordsToScan = IvarsInfo[0].ivar_size;
375731682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar  } else {
37589397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize;
37599397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    WordsToScan = IvarsInfo[0].ivar_size;
37609397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  }
376131682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar  for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++) {
37626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    unsigned int TailPrevGCObjC =
376393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize;
376431682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar    if (IvarsInfo[i].ivar_bytepos == TailPrevGCObjC) {
37659397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      // consecutive 'scanned' object pointers.
37669397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      WordsToScan += IvarsInfo[i].ivar_size;
376731682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar    } else {
37689397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      // Skip over 'gc'able object pointer which lay over each other.
37699397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      if (TailPrevGCObjC > IvarsInfo[i].ivar_bytepos)
37709397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian        continue;
37719397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      // Must skip over 1 or more words. We save current skip/scan values
37729397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      //  and start a new pair.
3773c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian      SKIP_SCAN SkScan;
3774c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian      SkScan.skip = WordsToSkip;
3775c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian      SkScan.scan = WordsToScan;
377681adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian      SkipScanIvars.push_back(SkScan);
377793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
37789397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      // Skip the hole.
3779c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian      SkScan.skip = (IvarsInfo[i].ivar_bytepos - TailPrevGCObjC) / WordSize;
3780c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian      SkScan.scan = 0;
378181adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian      SkipScanIvars.push_back(SkScan);
37829397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      WordsToSkip = 0;
37839397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      WordsToScan = IvarsInfo[i].ivar_size;
37849397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    }
37859397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  }
378631682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar  if (WordsToScan > 0) {
3787c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian    SKIP_SCAN SkScan;
3788c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian    SkScan.skip = WordsToSkip;
3789c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian    SkScan.scan = WordsToScan;
379081adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian    SkipScanIvars.push_back(SkScan);
37919397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  }
379293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
379331682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar  if (!SkipIvars.empty()) {
379481adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian    unsigned int LastIndex = SkipIvars.size()-1;
37956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    int LastByteSkipped =
379693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    SkipIvars[LastIndex].ivar_bytepos + SkipIvars[LastIndex].ivar_size;
379781adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian    LastIndex = IvarsInfo.size()-1;
37986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    int LastByteScanned =
379993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    IvarsInfo[LastIndex].ivar_bytepos +
380093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    IvarsInfo[LastIndex].ivar_size * WordSize;
38019397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    // Compute number of bytes to skip at the tail end of the last ivar scanned.
380254d76db0aa7107597cac0b80d8e138a37e6d1de9Benjamin Kramer    if (LastByteSkipped > LastByteScanned) {
38039397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      unsigned int TotalWords = (LastByteSkipped + (WordSize -1)) / WordSize;
3804c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian      SKIP_SCAN SkScan;
3805c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian      SkScan.skip = TotalWords - (LastByteScanned/WordSize);
3806c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian      SkScan.scan = 0;
380781adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian      SkipScanIvars.push_back(SkScan);
38089397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    }
38099397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  }
38109397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  // Mini optimization of nibbles such that an 0xM0 followed by 0x0N is produced
38119397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  // as 0xMN.
381281adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian  int SkipScan = SkipScanIvars.size()-1;
381331682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar  for (int i = 0; i <= SkipScan; i++) {
38149397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    if ((i < SkipScan) && SkipScanIvars[i].skip && SkipScanIvars[i].scan == 0
38159397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian        && SkipScanIvars[i+1].skip == 0 && SkipScanIvars[i+1].scan) {
38169397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      // 0xM0 followed by 0x0N detected.
38179397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      SkipScanIvars[i].scan = SkipScanIvars[i+1].scan;
38189397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      for (int j = i+1; j < SkipScan; j++)
38199397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian        SkipScanIvars[j] = SkipScanIvars[j+1];
38209397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      --SkipScan;
38219397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    }
38229397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  }
382393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
38249397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  // Generate the string.
382531682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar  for (int i = 0; i <= SkipScan; i++) {
38269397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    unsigned char byte;
38279397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    unsigned int skip_small = SkipScanIvars[i].skip % 0xf;
38289397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    unsigned int scan_small = SkipScanIvars[i].scan % 0xf;
38299397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    unsigned int skip_big  = SkipScanIvars[i].skip / 0xf;
38309397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    unsigned int scan_big  = SkipScanIvars[i].scan / 0xf;
383193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
38329397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    // first skip big.
38339397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    for (unsigned int ix = 0; ix < skip_big; ix++)
38349397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      BitMap += (unsigned char)(0xf0);
383593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
38369397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    // next (skip small, scan)
383731682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar    if (skip_small) {
38389397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      byte = skip_small << 4;
383931682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar      if (scan_big > 0) {
38409397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian        byte |= 0xf;
38419397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian        --scan_big;
384231682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar      } else if (scan_small) {
38439397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian        byte |= scan_small;
38449397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian        scan_small = 0;
38459397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      }
38469397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      BitMap += byte;
38479397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    }
38489397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    // next scan big
38499397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    for (unsigned int ix = 0; ix < scan_big; ix++)
38509397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      BitMap += (unsigned char)(0x0f);
38519397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    // last scan small
385231682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar    if (scan_small) {
38539397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      byte = scan_small;
38549397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      BitMap += byte;
38559397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    }
38569397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  }
38579397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  // null terminate string.
3858667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian  unsigned char zero = 0;
3859667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian  BitMap += zero;
386093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
386193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  llvm::GlobalVariable * Entry =
386293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
386393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian                    llvm::ConstantArray::get(VMContext, BitMap.c_str()),
3864af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                    ((ObjCABI == 2) ?
3865af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                     "__TEXT,__objc_classname,cstring_literals" :
3866af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                     "__TEXT,__cstring,cstring_literals"),
386793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian                    1, true);
386893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  return getConstantGEP(VMContext, Entry, 0, 0);
386993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian}
38706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
387193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// BuildIvarLayout - Builds ivar layout bitmap for the class
387293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// implementation for the __strong or __weak case.
387393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// The layout map displays which words in ivar list must be skipped
387493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// and which must be scanned by GC (see below). String is built of bytes.
387593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// Each byte is divided up in two nibbles (4-bit each). Left nibble is count
387693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// of words to skip and right nibble is count of words to scan. So, each
387793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// nibble represents up to 15 workds to skip or scan. Skipping the rest is
387893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// represented by a 0x00 byte which also ends the string.
387993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// 1. when ForStrongLayout is true, following ivars are scanned:
388093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// - id, Class
388193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// - object *
388293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// - __strong anything
388393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian///
388493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// 2. When ForStrongLayout is false, following ivars are scanned:
388593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// - __weak anything
388693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian///
388793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanianllvm::Constant *CGObjCCommonMac::BuildIvarLayout(
388893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  const ObjCImplementationDecl *OMD,
388993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  bool ForStrongLayout) {
389093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  bool hasUnion = false;
389193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
38922acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext);
3893e289d81369914678db386f6aa86faf8f178e245dDouglas Gregor  if (CGM.getLangOptions().getGC() == LangOptions::NonGC &&
3894f85e193739c953358c865005855253af4f68a497John McCall      !CGM.getLangOptions().ObjCAutoRefCount)
389593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    return llvm::Constant::getNullValue(PtrTy);
389693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
3897db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  const ObjCInterfaceDecl *OI = OMD->getClassInterface();
3898db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  SmallVector<const FieldDecl*, 32> RecFields;
3899bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian  if (CGM.getLangOptions().ObjCAutoRefCount) {
3900db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose    for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
3901bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian         IVD; IVD = IVD->getNextIvar())
3902bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian      RecFields.push_back(cast<FieldDecl>(IVD));
3903bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian  }
3904bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian  else {
3905db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose    SmallVector<const ObjCIvarDecl*, 32> Ivars;
3906f85e193739c953358c865005855253af4f68a497John McCall    CGM.getContext().DeepCollectObjCIvars(OI, true, Ivars);
390793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
3908db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose    // FIXME: This is not ideal; we shouldn't have to do this copy.
3909db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose    RecFields.append(Ivars.begin(), Ivars.end());
3910bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian  }
391193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
391293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  if (RecFields.empty())
391393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    return llvm::Constant::getNullValue(PtrTy);
391493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
391593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  SkipIvars.clear();
391693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  IvarsInfo.clear();
391793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
391893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  BuildAggrIvarLayout(OMD, 0, 0, RecFields, 0, ForStrongLayout, hasUnion);
391993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  if (IvarsInfo.empty())
392093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    return llvm::Constant::getNullValue(PtrTy);
3921b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian  // Sort on byte position in case we encounterred a union nested in
3922b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian  // the ivar list.
3923b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian  if (hasUnion && !IvarsInfo.empty())
3924b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian    std::sort(IvarsInfo.begin(), IvarsInfo.end());
3925b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian  if (hasUnion && !SkipIvars.empty())
3926b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian    std::sort(SkipIvars.begin(), SkipIvars.end());
3927b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian
392893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  std::string BitMap;
3929b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian  llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
393093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
393193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian   if (CGM.getLangOptions().ObjCGCBitmapPrint) {
39326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    printf("\n%s ivar layout for class '%s': ",
39333d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian           ForStrongLayout ? "strong" : "weak",
39344087f27e5416c799bcb6be072f905be752acb61cDaniel Dunbar           OMD->getClassInterface()->getName().data());
39353d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian    const unsigned char *s = (unsigned char*)BitMap.c_str();
39363d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian    for (unsigned i = 0; i < BitMap.size(); i++)
39373d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian      if (!(s[i] & 0xf0))
39383d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian        printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
39393d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian      else
39403d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian        printf("0x%x%s",  s[i], s[i] != 0 ? ", " : "");
39413d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian    printf("\n");
39423d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian  }
394393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  return C;
3944d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian}
3945d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian
394656210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
3947259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar  llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
3948259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar
394963c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar  // FIXME: Avoid std::string copying.
395063c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar  if (!Entry)
39516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_NAME_",
39520032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson                        llvm::ConstantArray::get(VMContext, Sel.getAsString()),
3953af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                              ((ObjCABI == 2) ?
3954af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                               "__TEXT,__objc_methname,cstring_literals" :
3955af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                               "__TEXT,__cstring,cstring_literals"),
3956b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar                              1, true);
3957259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar
3958a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson  return getConstantGEP(VMContext, Entry, 0, 0);
39596efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar}
39606efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
396127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar// FIXME: Merge into a single cstring creation function.
396256210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
396327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
396427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar}
396527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
39663e5f0d88d7eda79b7a679188d1e6da54cec72f5dDaniel Dunbarllvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
39677794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel  std::string TypeStr;
39687794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel  CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
39697794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel
39707794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel  llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
39716efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
397263c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar  if (!Entry)
397363c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar    Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_",
39740032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson                              llvm::ConstantArray::get(VMContext, TypeStr),
3975af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                              ((ObjCABI == 2) ?
3976af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                               "__TEXT,__objc_methtype,cstring_literals" :
3977af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                               "__TEXT,__cstring,cstring_literals"),
3978b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar                              1, true);
39796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3980a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson  return getConstantGEP(VMContext, Entry, 0, 0);
3981259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar}
3982259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar
398356210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D) {
398427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  std::string TypeStr;
3985f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor  if (CGM.getContext().getObjCEncodingForMethodDecl(
3986f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor                                                const_cast<ObjCMethodDecl*>(D),
3987f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor                                                    TypeStr))
3988f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor    return 0;
39897794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel
39907794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel  llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
39917794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel
3992b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar  if (!Entry)
3993b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar    Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_",
39940032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson                              llvm::ConstantArray::get(VMContext, TypeStr),
3995af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                              ((ObjCABI == 2) ?
3996af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                               "__TEXT,__objc_methtype,cstring_literals" :
3997af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                               "__TEXT,__cstring,cstring_literals"),
3998b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar                              1, true);
39997794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel
4000a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson  return getConstantGEP(VMContext, Entry, 0, 0);
400127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar}
400227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
4003c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar// FIXME: Merge into a single cstring creation function.
400456210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
4005c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar  llvm::GlobalVariable *&Entry = PropertyNames[Ident];
40066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
400763c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar  if (!Entry)
40086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry = CreateMetadataVar("\01L_OBJC_PROP_NAME_ATTR_",
40099c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                          llvm::ConstantArray::get(VMContext,
40109c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                                   Ident->getNameStart()),
401163c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar                              "__TEXT,__cstring,cstring_literals",
4012b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar                              1, true);
4013c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar
4014a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson  return getConstantGEP(VMContext, Entry, 0, 0);
4015c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar}
4016c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar
4017c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar// FIXME: Merge into a single cstring creation function.
4018c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar// FIXME: This Decl should be more precise.
401963c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbarllvm::Constant *
40206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarCGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
40216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                       const Decl *Container) {
4022c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar  std::string TypeStr;
4023c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar  CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
4024c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar  return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
4025c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar}
4026c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar
40276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarvoid CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D,
402856210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian                                       const ObjCContainerDecl *CD,
40295f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                       SmallVectorImpl<char> &Name) {
4030c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar  llvm::raw_svector_ostream OS(Name);
4031679a502d462ef819e6175b58e255ca3f3391e7cfFariborz Jahanian  assert (CD && "Missing container decl in GetNameForMethod");
4032c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar  OS << '\01' << (D->isInstanceMethod() ? '-' : '+')
4033c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar     << '[' << CD->getName();
40346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  if (const ObjCCategoryImplDecl *CID =
4035c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar      dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
4036900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer    OS << '(' << CID << ')';
4037c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar  OS << ' ' << D->getSelector().getAsString() << ']';
4038b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar}
4039b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar
4040f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbarvoid CGObjCMac::FinishModule() {
40414e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  EmitModuleInfo();
40424e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
40430c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  // Emit the dummy bodies for any protocols which were referenced but
40440c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  // never defined.
40456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*>::iterator
4046ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner         I = Protocols.begin(), e = Protocols.end(); I != e; ++I) {
4047ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner    if (I->second->hasInitializer())
40480c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar      continue;
40494e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
40501d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    llvm::Constant *Values[5];
4051c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
4052ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner    Values[1] = GetClassName(I->first);
4053c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
40540c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar    Values[3] = Values[4] =
4055c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson      llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
4056ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner    I->second->setLinkage(llvm::GlobalValue::InternalLinkage);
405708e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson    I->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
40580c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar                                                        Values));
4059ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner    CGM.AddUsedGlobal(I->second);
40600c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  }
40610c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar
4062242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  // Add assembler directives to add lazy undefined symbol references
4063242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  // for classes which are referenced but not defined. This is
4064242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  // important for correct linker interaction.
4065330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar  //
4066330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar  // FIXME: It would be nice if we had an LLVM construct for this.
4067330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar  if (!LazySymbols.empty() || !DefinedSymbols.empty()) {
4068330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar    llvm::SmallString<256> Asm;
4069330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar    Asm += CGM.getModule().getModuleInlineAsm();
4070330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar    if (!Asm.empty() && Asm.back() != '\n')
4071330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar      Asm += '\n';
4072330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar
4073330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar    llvm::raw_svector_ostream OS(Asm);
4074330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar    for (llvm::SetVector<IdentifierInfo*>::iterator I = DefinedSymbols.begin(),
4075330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar           e = DefinedSymbols.end(); I != e; ++I)
407601eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      OS << "\t.objc_class_name_" << (*I)->getName() << "=0\n"
407701eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar         << "\t.globl .objc_class_name_" << (*I)->getName() << "\n";
4078afd5eda46e8e98e13e6cb0c937e39835eef5a296Chris Lattner    for (llvm::SetVector<IdentifierInfo*>::iterator I = LazySymbols.begin(),
4079b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian         e = LazySymbols.end(); I != e; ++I) {
4080afd5eda46e8e98e13e6cb0c937e39835eef5a296Chris Lattner      OS << "\t.lazy_reference .objc_class_name_" << (*I)->getName() << "\n";
4081b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian    }
4082b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian
4083b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian    for (size_t i = 0; i < DefinedCategoryNames.size(); ++i) {
4084b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian      OS << "\t.objc_category_name_" << DefinedCategoryNames[i] << "=0\n"
4085b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian         << "\t.globl .objc_category_name_" << DefinedCategoryNames[i] << "\n";
4086b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian    }
4087afd5eda46e8e98e13e6cb0c937e39835eef5a296Chris Lattner
4088330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar    CGM.getModule().setModuleInlineAsm(OS.str());
4089242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  }
4090f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar}
4091f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar
40926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarCGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
4093ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  : CGObjCCommonMac(cgm),
40941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    ObjCTypes(cgm) {
4095aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  ObjCEmptyCacheVar = ObjCEmptyVtableVar = NULL;
4096ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  ObjCABI = 2;
4097ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian}
4098ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian
4099f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/* *** */
4100f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar
4101ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz JahanianObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
41021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : VMContext(cgm.getLLVMContext()), CGM(cgm) {
41034e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  CodeGen::CodeGenTypes &Types = CGM.getTypes();
41044e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  ASTContext &Ctx = CGM.getContext();
41056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
410627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  ShortTy = Types.ConvertType(Ctx.ShortTy);
41076efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  IntTy = Types.ConvertType(Ctx.IntTy);
41084e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  LongTy = Types.ConvertType(Ctx.LongTy);
41090a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian  LongLongTy = Types.ConvertType(Ctx.LongLongTy);
41103c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer  Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
41116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
41124e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
411396e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy);
41144e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
41156bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4116f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // FIXME: It would be nice to unify this with the opaque type, so that the IR
4117f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // comes out a bit cleaner.
41182acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
411996e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
41206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4121ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  // I'm not sure I like this. The implicit coordination is a bit
4122ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  // gross. We should solve this in a reasonable fashion because this
4123ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  // is a pretty common task (match some runtime data structure with
4124ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  // an LLVM data structure).
41256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4126ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  // FIXME: This is leaked.
4127ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  // FIXME: Merge with rewriter code?
41286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4129ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  // struct _objc_super {
4130ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  //   id self;
4131ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  //   Class cls;
4132ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  // }
4133465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara  RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
4134daa3ac503e93315ed3546463c13de4856bb80ef7Daniel Dunbar                                      Ctx.getTranslationUnitDecl(),
4135ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                      SourceLocation(), SourceLocation(),
41366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                      &Ctx.Idents.get("_objc_super"));
4137ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
41387a614d8380297fcd2bc23986241905d97222948cRichard Smith                                Ctx.getObjCIdType(), 0, 0, false, false));
4139ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
41407a614d8380297fcd2bc23986241905d97222948cRichard Smith                                Ctx.getObjCClassType(), 0, 0, false, false));
4141838db383b69b9fb55f55c8e9546477df198a4faaDouglas Gregor  RD->completeDefinition();
41426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4143ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  SuperCTy = Ctx.getTagDeclType(RD);
4144ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  SuperPtrCTy = Ctx.getPointerType(SuperCTy);
41456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4146ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
41476bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
41486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
414930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // struct _prop_t {
415030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   char *name;
41516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  //   char *attributes;
415230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // }
4153c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner  PropertyTy = llvm::StructType::create("struct._prop_t",
4154c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                        Int8PtrTy, Int8PtrTy, NULL);
41556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
415630bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // struct _prop_list_t {
4157d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   uint32_t entsize;      // sizeof(struct _prop_t)
415830bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   uint32_t count_of_properties;
4159d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   struct _prop_t prop_list[count_of_properties];
416030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // }
41619cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  PropertyListTy =
4162c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._prop_list_t", IntTy, IntTy,
4163c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             llvm::ArrayType::get(PropertyTy, 0), NULL);
416430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // struct _prop_list_t *
416596e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
41666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
416730bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // struct _objc_method {
416830bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   SEL _cmd;
416930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   char *method_type;
417030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   char *_imp;
417130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // }
4172c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner  MethodTy = llvm::StructType::create("struct._objc_method",
4173c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                      SelectorPtrTy, Int8PtrTy, Int8PtrTy,
4174c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                      NULL);
41756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4176d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // struct _objc_cache *
4177c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner  CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache");
417896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
41799d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian
4180ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian}
41814e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
41826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
41831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : ObjCCommonTypesHelper(cgm) {
418410a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_method_description {
418510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   SEL name;
418610a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   char *types;
418710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // }
41886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  MethodDescriptionTy =
4189c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._objc_method_description",
4190c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             SelectorPtrTy, Int8PtrTy, NULL);
41916efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
419210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_method_description_list {
419310a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   int count;
419410a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_method_description[1];
419510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // }
41966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  MethodDescriptionListTy =
4197c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._objc_method_description_list",
4198c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             IntTy,
4199c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             llvm::ArrayType::get(MethodDescriptionTy, 0),NULL);
42006bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
420110a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_method_description_list *
42026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  MethodDescriptionListPtrTy =
420396e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    llvm::PointerType::getUnqual(MethodDescriptionListTy);
42046efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
42056efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  // Protocol description structures
42066efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
420710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_protocol_extension {
420810a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   uint32_t size;  // sizeof(struct _objc_protocol_extension)
420910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_method_description_list *optional_instance_methods;
421010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_method_description_list *optional_class_methods;
421110a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_property_list *instance_properties;
421210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // }
42136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  ProtocolExtensionTy =
4214c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._objc_protocol_extension",
4215c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             IntTy, MethodDescriptionListPtrTy,
4216c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             MethodDescriptionListPtrTy, PropertyListPtrTy,
4217c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             NULL);
42186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
421910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_protocol_extension *
422096e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
42216efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
42220c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  // Handle recursive construction of Protocol and ProtocolList types
42236efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
42249cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  ProtocolTy =
4225c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create(VMContext, "struct._objc_protocol");
42266efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
42279cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  ProtocolListTy =
4228c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create(VMContext, "struct._objc_protocol_list");
42299cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy),
4230ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian                          LongTy,
42319cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                          llvm::ArrayType::get(ProtocolTy, 0),
4232ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian                          NULL);
42336efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
423410a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_protocol {
423510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_protocol_extension *isa;
423610a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   char *protocol_name;
423710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_protocol **_objc_protocol_list;
423810a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_method_description_list *instance_methods;
423910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_method_description_list *class_methods;
424010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // }
42419cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy,
42429cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                      llvm::PointerType::getUnqual(ProtocolListTy),
42439cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                      MethodDescriptionListPtrTy,
42449cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                      MethodDescriptionListPtrTy,
42459cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                      NULL);
42469cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner
424710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_protocol_list *
424896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
42496efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
425096e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
425127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
425227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // Class description structures
425327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
425410a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_ivar {
425510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   char *ivar_name;
425610a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   char *ivar_type;
425710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   int  ivar_offset;
425810a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // }
4259c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner  IvarTy = llvm::StructType::create("struct._objc_ivar",
4260c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                    Int8PtrTy, Int8PtrTy, IntTy, NULL);
426127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
426210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_ivar_list *
42639cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  IvarListTy =
4264c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create(VMContext, "struct._objc_ivar_list");
426596e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
426627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
426710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_method_list *
42689cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  MethodListTy =
4269c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create(VMContext, "struct._objc_method_list");
427096e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
427127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
427210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_class_extension *
42736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  ClassExtensionTy =
4274c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._objc_class_extension",
4275c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             IntTy, Int8PtrTy, PropertyListPtrTy, NULL);
427696e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
427727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
4278c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner  ClassTy = llvm::StructType::create(VMContext, "struct._objc_class");
427927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
428010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_class {
428110a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   Class isa;
428210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   Class super_class;
428310a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   char *name;
428410a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   long version;
428510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   long info;
428610a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   long instance_size;
428710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_ivar_list *ivars;
428810a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_method_list *methods;
428910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_cache *cache;
429010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_protocol_list *protocols;
429110a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   char *ivar_layout;
429210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_class_ext *ext;
429310a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // };
42949cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy),
42959cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   llvm::PointerType::getUnqual(ClassTy),
42969cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   Int8PtrTy,
42979cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   LongTy,
42989cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   LongTy,
42999cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   LongTy,
43009cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   IvarListPtrTy,
43019cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   MethodListPtrTy,
43029cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   CachePtrTy,
43039cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   ProtocolListPtrTy,
43049cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   Int8PtrTy,
43059cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   ClassExtensionPtrTy,
43069cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   NULL);
43079cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner
430896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
430927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
431010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_category {
431110a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   char *category_name;
431210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   char *class_name;
431310a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_method_list *instance_method;
431410a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_method_list *class_method;
431510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   uint32_t size;  // sizeof(struct _objc_category)
431610a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_property_list *instance_properties;// category's @property
431710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // }
43189cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  CategoryTy =
4319c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._objc_category",
4320c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             Int8PtrTy, Int8PtrTy, MethodListPtrTy,
4321c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             MethodListPtrTy, ProtocolListPtrTy,
4322c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             IntTy, PropertyListPtrTy, NULL);
432386e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar
432427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // Global metadata structures
432527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
432610a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_symtab {
432710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   long sel_ref_cnt;
432810a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   SEL *refs;
432910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   short cls_def_cnt;
433010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   short cat_def_cnt;
433110a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   char *defs[cls_def_cnt + cat_def_cnt];
433210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // }
43339cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  SymtabTy =
4334c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._objc_symtab",
4335c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             LongTy, SelectorPtrTy, ShortTy, ShortTy,
4336c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             llvm::ArrayType::get(Int8PtrTy, 0), NULL);
433796e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
433827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
4339db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian  // struct _objc_module {
4340db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian  //   long version;
4341db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian  //   long size;   // sizeof(struct _objc_module)
4342db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian  //   char *name;
4343db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian  //   struct _objc_symtab* symtab;
4344db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian  //  }
43456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  ModuleTy =
4346c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._objc_module",
4347c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             LongTy, LongTy, Int8PtrTy, SymtabPtrTy, NULL);
434814c80b7ed64e0eddfbe81adf5113d5be5f9964bfDaniel Dunbar
43496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4350f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // FIXME: This is the size of the setjmp buffer and should be target
4351f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // specific. 18 is what's used on 32-bit X86.
4352124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson  uint64_t SetJmpBufferSize = 18;
43536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4354124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson  // Exceptions
43559cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *StackPtrTy = llvm::ArrayType::get(
43563c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer    llvm::Type::getInt8PtrTy(VMContext), 4);
43576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
43586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  ExceptionDataTy =
4359c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._objc_exception_data",
43609cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                         llvm::ArrayType::get(llvm::Type::getInt32Ty(VMContext),
43619cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                                              SetJmpBufferSize),
43629cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                         StackPtrTy, NULL);
4363124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson
4364bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar}
4365bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar
43666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm)
43671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : ObjCCommonTypesHelper(cgm) {
436830bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // struct _method_list_t {
436930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   uint32_t entsize;  // sizeof(struct _objc_method)
437030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   uint32_t method_count;
437130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   struct _objc_method method_list[method_count];
437230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // }
43739cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  MethodListnfABITy =
4374c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct.__method_list_t", IntTy, IntTy,
4375c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             llvm::ArrayType::get(MethodTy, 0), NULL);
4376d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // struct method_list_t *
437796e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy);
43786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
437930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // struct _protocol_t {
438030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   id isa;  // NULL
438130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const char * const protocol_name;
4382d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   const struct _protocol_list_t * protocol_list; // super protocols
438330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const struct method_list_t * const instance_methods;
438430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const struct method_list_t * const class_methods;
438530bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const struct method_list_t *optionalInstanceMethods;
438630bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const struct method_list_t *optionalClassMethods;
4387d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   const struct _prop_list_t * properties;
438830bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const uint32_t size;  // sizeof(struct _protocol_t)
438930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const uint32_t flags;  // = 0
439030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // }
43916bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4392d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // Holder for struct _protocol_list_t *
43939cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  ProtocolListnfABITy =
4394c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create(VMContext, "struct._objc_protocol_list");
43959cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner
43969cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  ProtocolnfABITy =
4397c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._protocol_t", ObjectPtrTy, Int8PtrTy,
4398c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             llvm::PointerType::getUnqual(ProtocolListnfABITy),
4399c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             MethodListnfABIPtrTy, MethodListnfABIPtrTy,
4400c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             MethodListnfABIPtrTy, MethodListnfABIPtrTy,
4401c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             PropertyListPtrTy, IntTy, IntTy, NULL);
4402948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar
4403948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar  // struct _protocol_t*
440496e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy);
44056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4406da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  // struct _protocol_list_t {
4407d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   long protocol_count;   // Note, this is 32/64 bit
4408948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar  //   struct _protocol_t *[protocol_count];
440930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // }
44109cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  ProtocolListnfABITy->setBody(LongTy,
44119cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                               llvm::ArrayType::get(ProtocolnfABIPtrTy, 0),
44129cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                               NULL);
44136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4414d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // struct _objc_protocol_list*
441596e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy);
44166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
441730bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // struct _ivar_t {
441830bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   unsigned long int *offset;  // pointer to ivar offset location
441930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   char *name;
442030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   char *type;
442130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   uint32_t alignment;
442230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   uint32_t size;
442330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // }
44249cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  IvarnfABITy =
4425c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._ivar_t",
4426c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             llvm::PointerType::getUnqual(LongTy),
4427c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             Int8PtrTy, Int8PtrTy, IntTy, IntTy, NULL);
44286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
442930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // struct _ivar_list_t {
443030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   uint32 entsize;  // sizeof(struct _ivar_t)
443130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   uint32 count;
443230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   struct _iver_t list[count];
443330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // }
44349cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  IvarListnfABITy =
4435c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._ivar_list_t", IntTy, IntTy,
4436c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             llvm::ArrayType::get(IvarnfABITy, 0), NULL);
44376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
443896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy);
44396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4440d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // struct _class_ro_t {
444130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   uint32_t const flags;
444230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   uint32_t const instanceStart;
444330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   uint32_t const instanceSize;
444430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   uint32_t const reserved;  // only when building for 64bit targets
444530bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const uint8_t * const ivarLayout;
444630bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const char *const name;
444730bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const struct _method_list_t * const baseMethods;
444830bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const struct _objc_protocol_list *const baseProtocols;
444930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const struct _ivar_list_t *const ivars;
445030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const uint8_t * const weakIvarLayout;
445130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const struct _prop_list_t * const properties;
445230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // }
44536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4454d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // FIXME. Add 'reserved' field in 64bit abi mode!
4455c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner  ClassRonfABITy = llvm::StructType::create("struct._class_ro_t",
4456c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                            IntTy, IntTy, IntTy, Int8PtrTy,
4457c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                            Int8PtrTy, MethodListnfABIPtrTy,
4458c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                            ProtocolListnfABIPtrTy,
4459c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                            IvarListnfABIPtrTy,
4460c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                            Int8PtrTy, PropertyListPtrTy, NULL);
44616bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4462d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
44639cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
44640774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false)
44650774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                 ->getPointerTo();
44666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4467d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // struct _class_t {
4468d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   struct _class_t *isa;
4469d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   struct _class_t * const superclass;
4470d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   void *cache;
4471d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   IMP *vtable;
4472d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   struct class_ro_t *ro;
4473d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // }
44746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4475c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner  ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t");
44769cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy),
44779cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                        llvm::PointerType::getUnqual(ClassnfABITy),
44789cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                        CachePtrTy,
44799cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                        llvm::PointerType::getUnqual(ImpnfABITy),
44809cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                        llvm::PointerType::getUnqual(ClassRonfABITy),
44819cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                        NULL);
44826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4483aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  // LLVM for struct _class_t *
448496e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy);
44856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4486d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // struct _category_t {
4487d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   const char * const name;
4488d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   struct _class_t *const cls;
4489d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   const struct _method_list_t * const instance_methods;
4490d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   const struct _method_list_t * const class_methods;
4491d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   const struct _protocol_list_t * const protocols;
4492d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   const struct _prop_list_t * const properties;
449345c2ba0c13f353a8bab6cc01b30b3a13f3404c1eFariborz Jahanian  // }
4494c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner  CategorynfABITy = llvm::StructType::create("struct._category_t",
4495c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                             Int8PtrTy, ClassnfABIPtrTy,
4496c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                             MethodListnfABIPtrTy,
4497c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                             MethodListnfABIPtrTy,
4498c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                             ProtocolListnfABIPtrTy,
4499c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                             PropertyListPtrTy,
4500c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                             NULL);
45016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
45022e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // New types for nonfragile abi messaging.
450383a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  CodeGen::CodeGenTypes &Types = CGM.getTypes();
450483a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  ASTContext &Ctx = CGM.getContext();
45056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
45062e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // MessageRefTy - LLVM for:
45072e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // struct _message_ref_t {
45082e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  //   IMP messenger;
45092e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  //   SEL name;
45102e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // };
45116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
451283a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  // First the clang type for struct _message_ref_t
4513465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara  RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
4514daa3ac503e93315ed3546463c13de4856bb80ef7Daniel Dunbar                                      Ctx.getTranslationUnitDecl(),
4515ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                      SourceLocation(), SourceLocation(),
451683a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian                                      &Ctx.Idents.get("_message_ref_t"));
4517ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
45187a614d8380297fcd2bc23986241905d97222948cRichard Smith                                Ctx.VoidPtrTy, 0, 0, false, false));
4519ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
45207a614d8380297fcd2bc23986241905d97222948cRichard Smith                                Ctx.getObjCSelType(), 0, 0, false, false));
4521838db383b69b9fb55f55c8e9546477df198a4faaDouglas Gregor  RD->completeDefinition();
45226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
452383a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  MessageRefCTy = Ctx.getTagDeclType(RD);
452483a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
452583a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
45266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
45272e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // MessageRefPtrTy - LLVM for struct _message_ref_t*
452896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy);
45296bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
45302e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // SuperMessageRefTy - LLVM for:
45312e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // struct _super_message_ref_t {
45322e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  //   SUPER_IMP messenger;
45332e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  //   SEL name;
45342e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // };
45359cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  SuperMessageRefTy =
4536c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._super_message_ref_t",
4537c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             ImpnfABITy, SelectorPtrTy, NULL);
45386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
45392e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
45406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);
45419d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian
4542e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar
4543e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  // struct objc_typeinfo {
4544e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  //   const void** vtable; // objc_ehtype_vtable + 2
4545e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  //   const char*  name;    // c++ typeinfo string
4546e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  //   Class        cls;
4547e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  // };
45489cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  EHTypeTy =
4549c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._objc_typeinfo",
4550c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             llvm::PointerType::getUnqual(Int8PtrTy),
4551c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             Int8PtrTy, ClassnfABIPtrTy, NULL);
455296e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy);
4553bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar}
4554bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar
45556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
4556aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  FinishNonFragileABIModule();
45576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4558aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  return NULL;
4559aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian}
4560aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian
45616bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarvoid CGObjCNonFragileABIMac::AddModuleClassList(const
45626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                std::vector<llvm::GlobalValue*>
45636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                &Container,
4564463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar                                                const char *SymbolName,
4565463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar                                                const char *SectionName) {
4566463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar  unsigned NumClasses = Container.size();
45676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4568463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar  if (!NumClasses)
4569463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar    return;
45706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4571463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar  std::vector<llvm::Constant*> Symbols(NumClasses);
4572463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar  for (unsigned i=0; i<NumClasses; i++)
45733c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson    Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i],
4574463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar                                                ObjCTypes.Int8PtrTy);
45756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Constant* Init =
457696e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
4577463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar                                                  NumClasses),
4578463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar                             Symbols);
45796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4580463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar  llvm::GlobalVariable *GV =
45811c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson    new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
4582463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar                             llvm::GlobalValue::InternalLinkage,
4583463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar                             Init,
45841c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                             SymbolName);
45854b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar  GV->setAlignment(CGM.getTargetData().getABITypeAlignment(Init->getType()));
4586463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar  GV->setSection(SectionName);
4587ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  CGM.AddUsedGlobal(GV);
4588463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar}
45896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4590aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanianvoid CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
4591aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  // nonfragile abi has no module definition.
45926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4593463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar  // Build list of all implemented class addresses in array
4594f87a0ccb05eb2aa095ea835fdcdf4a0363637b28Fariborz Jahanian  // L_OBJC_LABEL_CLASS_$.
45956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  AddModuleClassList(DefinedClasses,
4596463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar                     "\01L_OBJC_LABEL_CLASS_$",
4597463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar                     "__DATA, __objc_classlist, regular, no_dead_strip");
4598a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian
4599a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian  for (unsigned i = 0; i < DefinedClasses.size(); i++) {
4600a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian    llvm::GlobalValue *IMPLGV = DefinedClasses[i];
4601a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian    if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage)
4602a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian      continue;
4603a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian    IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage);
4604a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian  }
4605a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian
46060e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian  for (unsigned i = 0; i < DefinedMetaClasses.size(); i++) {
46070e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian    llvm::GlobalValue *IMPLGV = DefinedMetaClasses[i];
46080e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian    if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage)
46090e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian      continue;
46100e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian    IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage);
46110e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian  }
4612a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian
46136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  AddModuleClassList(DefinedNonLazyClasses,
461474d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar                     "\01L_OBJC_LABEL_NONLAZY_CLASS_$",
461574d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar                     "__DATA, __objc_nlclslist, regular, no_dead_strip");
46166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4617f87a0ccb05eb2aa095ea835fdcdf4a0363637b28Fariborz Jahanian  // Build list of all implemented category addresses in array
4618f87a0ccb05eb2aa095ea835fdcdf4a0363637b28Fariborz Jahanian  // L_OBJC_LABEL_CATEGORY_$.
46196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  AddModuleClassList(DefinedCategories,
4620463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar                     "\01L_OBJC_LABEL_CATEGORY_$",
4621463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar                     "__DATA, __objc_catlist, regular, no_dead_strip");
46226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  AddModuleClassList(DefinedNonLazyCategories,
462374d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar                     "\01L_OBJC_LABEL_NONLAZY_CATEGORY_$",
462474d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar                     "__DATA, __objc_nlcatlist, regular, no_dead_strip");
46256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4626fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar  EmitImageInfo();
4627aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian}
4628aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian
4629944c84313da15477eb18d90babb0890d10d98082John McCall/// isVTableDispatchedSelector - Returns true if SEL is not in the list of
4630944c84313da15477eb18d90babb0890d10d98082John McCall/// VTableDispatchMethods; false otherwise. What this means is that
46316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar/// except for the 19 selectors in the list, we generate 32bit-style
4632d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian/// message dispatch call for all the rest.
4633944c84313da15477eb18d90babb0890d10d98082John McCallbool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
4634944c84313da15477eb18d90babb0890d10d98082John McCall  // At various points we've experimented with using vtable-based
4635944c84313da15477eb18d90babb0890d10d98082John McCall  // dispatch for all methods.
4636f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar  switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
4637f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar  default:
4638944c84313da15477eb18d90babb0890d10d98082John McCall    llvm_unreachable("Invalid dispatch method!");
4639f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar  case CodeGenOptions::Legacy:
4640776dbf9704353515b422ee13e481194c937ba01dFariborz Jahanian    return false;
4641944c84313da15477eb18d90babb0890d10d98082John McCall  case CodeGenOptions::NonLegacy:
4642944c84313da15477eb18d90babb0890d10d98082John McCall    return true;
4643f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar  case CodeGenOptions::Mixed:
4644f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar    break;
4645f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar  }
4646f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar
4647f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar  // If so, see whether this selector is in the white-list of things which must
4648f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar  // use the new dispatch convention. We lazily build a dense set for this.
4649944c84313da15477eb18d90babb0890d10d98082John McCall  if (VTableDispatchMethods.empty()) {
4650944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetNullarySelector("alloc"));
4651944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetNullarySelector("class"));
4652944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetNullarySelector("self"));
4653944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetNullarySelector("isFlipped"));
4654944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetNullarySelector("length"));
4655944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetNullarySelector("count"));
4656944c84313da15477eb18d90babb0890d10d98082John McCall
4657944c84313da15477eb18d90babb0890d10d98082John McCall    // These are vtable-based if GC is disabled.
4658944c84313da15477eb18d90babb0890d10d98082John McCall    // Optimistically use vtable dispatch for hybrid compiles.
4659e289d81369914678db386f6aa86faf8f178e245dDouglas Gregor    if (CGM.getLangOptions().getGC() != LangOptions::GCOnly) {
4660944c84313da15477eb18d90babb0890d10d98082John McCall      VTableDispatchMethods.insert(GetNullarySelector("retain"));
4661944c84313da15477eb18d90babb0890d10d98082John McCall      VTableDispatchMethods.insert(GetNullarySelector("release"));
4662944c84313da15477eb18d90babb0890d10d98082John McCall      VTableDispatchMethods.insert(GetNullarySelector("autorelease"));
4663944c84313da15477eb18d90babb0890d10d98082John McCall    }
4664944c84313da15477eb18d90babb0890d10d98082John McCall
4665944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetUnarySelector("allocWithZone"));
4666944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass"));
4667944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector"));
4668944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetUnarySelector("objectForKey"));
4669944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex"));
4670944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetUnarySelector("isEqualToString"));
4671944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetUnarySelector("isEqual"));
4672944c84313da15477eb18d90babb0890d10d98082John McCall
4673944c84313da15477eb18d90babb0890d10d98082John McCall    // These are vtable-based if GC is enabled.
4674944c84313da15477eb18d90babb0890d10d98082John McCall    // Optimistically use vtable dispatch for hybrid compiles.
4675e289d81369914678db386f6aa86faf8f178e245dDouglas Gregor    if (CGM.getLangOptions().getGC() != LangOptions::NonGC) {
4676944c84313da15477eb18d90babb0890d10d98082John McCall      VTableDispatchMethods.insert(GetNullarySelector("hash"));
4677944c84313da15477eb18d90babb0890d10d98082John McCall      VTableDispatchMethods.insert(GetUnarySelector("addObject"));
4678944c84313da15477eb18d90babb0890d10d98082John McCall
4679944c84313da15477eb18d90babb0890d10d98082John McCall      // "countByEnumeratingWithState:objects:count"
4680944c84313da15477eb18d90babb0890d10d98082John McCall      IdentifierInfo *KeyIdents[] = {
4681944c84313da15477eb18d90babb0890d10d98082John McCall        &CGM.getContext().Idents.get("countByEnumeratingWithState"),
4682944c84313da15477eb18d90babb0890d10d98082John McCall        &CGM.getContext().Idents.get("objects"),
4683944c84313da15477eb18d90babb0890d10d98082John McCall        &CGM.getContext().Idents.get("count")
4684944c84313da15477eb18d90babb0890d10d98082John McCall      };
4685944c84313da15477eb18d90babb0890d10d98082John McCall      VTableDispatchMethods.insert(
4686944c84313da15477eb18d90babb0890d10d98082John McCall        CGM.getContext().Selectors.getSelector(3, KeyIdents));
4687944c84313da15477eb18d90babb0890d10d98082John McCall    }
4688d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  }
4689f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar
4690944c84313da15477eb18d90babb0890d10d98082John McCall  return VTableDispatchMethods.count(Sel);
4691d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian}
4692d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian
4693058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian// Metadata flags
4694058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanianenum MetaDataDlags {
4695058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  CLS = 0x0,
4696058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  CLS_META = 0x1,
4697058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  CLS_ROOT = 0x2,
4698493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  OBJC2_CLS_HIDDEN = 0x10,
4699f85e193739c953358c865005855253af4f68a497John McCall  CLS_EXCEPTION = 0x20,
4700f85e193739c953358c865005855253af4f68a497John McCall
4701f85e193739c953358c865005855253af4f68a497John McCall  /// (Obsolete) ARC-specific: this class has a .release_ivars method
4702f85e193739c953358c865005855253af4f68a497John McCall  CLS_HAS_IVAR_RELEASER = 0x40,
4703f85e193739c953358c865005855253af4f68a497John McCall  /// class was compiled with -fobjc-arr
4704f85e193739c953358c865005855253af4f68a497John McCall  CLS_COMPILED_BY_ARC = 0x80  // (1<<7)
4705058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian};
4706058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// BuildClassRoTInitializer - generate meta-data for:
4707058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// struct _class_ro_t {
4708058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   uint32_t const flags;
4709058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   uint32_t const instanceStart;
4710058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   uint32_t const instanceSize;
4711058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   uint32_t const reserved;  // only when building for 64bit targets
4712058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   const uint8_t * const ivarLayout;
4713058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   const char *const name;
4714058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   const struct _method_list_t * const baseMethods;
4715da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   const struct _protocol_list_t *const baseProtocols;
4716058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   const struct _ivar_list_t *const ivars;
4717058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   const uint8_t * const weakIvarLayout;
4718058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   const struct _prop_list_t * const properties;
4719058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// }
4720058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///
4721058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanianllvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
47226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  unsigned flags,
47236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  unsigned InstanceStart,
47246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  unsigned InstanceSize,
47256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const ObjCImplementationDecl *ID) {
4726058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  std::string ClassName = ID->getNameAsString();
47271d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  llvm::Constant *Values[10]; // 11 for 64bit targets!
4728f85e193739c953358c865005855253af4f68a497John McCall
4729f85e193739c953358c865005855253af4f68a497John McCall  if (CGM.getLangOptions().ObjCAutoRefCount)
4730f85e193739c953358c865005855253af4f68a497John McCall    flags |= CLS_COMPILED_BY_ARC;
4731f85e193739c953358c865005855253af4f68a497John McCall
47324a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags);
47334a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart);
47344a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize);
4735058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  // FIXME. For 64bit targets add 0 here.
47366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[ 3] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes)
47376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    : BuildIvarLayout(ID, true);
4738058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  Values[ 4] = GetClassName(ID->getIdentifier());
4739493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  // const struct _method_list_t * const baseMethods;
4740493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  std::vector<llvm::Constant*> Methods;
4741493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  std::string MethodListName("\01l_OBJC_$_");
4742493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  if (flags & CLS_META) {
4743493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian    MethodListName += "CLASS_METHODS_" + ID->getNameAsString();
47446bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    for (ObjCImplementationDecl::classmeth_iterator
474517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis           i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
4746493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian      // Class methods should always be defined.
4747493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian      Methods.push_back(GetMethodConstant(*i));
4748493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian    }
4749493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  } else {
4750493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian    MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString();
47516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    for (ObjCImplementationDecl::instmeth_iterator
475217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis           i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
4753493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian      // Instance methods should always be defined.
4754493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian      Methods.push_back(GetMethodConstant(*i));
4755493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian    }
47566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    for (ObjCImplementationDecl::propimpl_iterator
475717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis           i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
4758939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian      ObjCPropertyImplDecl *PID = *i;
47596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4760939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian      if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
4761939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian        ObjCPropertyDecl *PD = PID->getPropertyDecl();
47626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4763939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian        if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
4764939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian          if (llvm::Constant *C = GetMethodConstant(MD))
4765939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian            Methods.push_back(C);
4766939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian        if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
4767939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian          if (llvm::Constant *C = GetMethodConstant(MD))
4768939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian            Methods.push_back(C);
4769939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian      }
4770939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian    }
4771493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  }
47726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[ 5] = EmitMethodList(MethodListName,
47736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                              "__DATA, __objc_const", Methods);
47746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4775da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  const ObjCInterfaceDecl *OID = ID->getClassInterface();
4776da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");
47776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_"
47789c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                + OID->getName(),
477953b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek                                OID->all_referenced_protocol_begin(),
478053b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek                                OID->all_referenced_protocol_end());
47816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
478298abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  if (flags & CLS_META)
4783c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
478498abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  else
478598abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian    Values[ 7] = EmitIvarList(ID);
47866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[ 8] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes)
47876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    : BuildIvarLayout(ID, false);
47885de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian  if (flags & CLS_META)
4789c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
47905de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian  else
47919c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
47929c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                  ID, ID->getClassInterface(), ObjCTypes);
479308e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy,
4794058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian                                                   Values);
4795058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  llvm::GlobalVariable *CLASS_RO_GV =
47966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassRonfABITy, false,
47976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             llvm::GlobalValue::InternalLinkage,
47986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             Init,
47996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             (flags & CLS_META) ?
48006bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName :
48016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             std::string("\01l_OBJC_CLASS_RO_$_")+ClassName);
480209796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian  CLASS_RO_GV->setAlignment(
48034b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar    CGM.getTargetData().getABITypeAlignment(ObjCTypes.ClassRonfABITy));
48041bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian  CLASS_RO_GV->setSection("__DATA, __objc_const");
4805058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  return CLASS_RO_GV;
4806f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian
4807058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian}
4808058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian
4809058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// BuildClassMetaData - This routine defines that to-level meta-data
4810058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// for the given ClassName for:
4811058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// struct _class_t {
4812058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   struct _class_t *isa;
4813058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   struct _class_t * const superclass;
4814058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   void *cache;
4815058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   IMP *vtable;
4816058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   struct class_ro_t *ro;
4817058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// }
4818058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///
481984394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanianllvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData(
48206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  std::string &ClassName,
48216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Constant *IsAGV,
48226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Constant *SuperClassGV,
48236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Constant *ClassRoGV,
48246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  bool HiddenVisibility) {
48251d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  llvm::Constant *Values[] = {
48261d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    IsAGV,
48271d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    SuperClassGV,
48281d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    ObjCEmptyCacheVar,  // &ObjCEmptyCacheVar
48291d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    ObjCEmptyVtableVar, // &ObjCEmptyVtableVar
48301d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    ClassRoGV           // &CLASS_RO_GV
48311d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  };
48326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  if (!Values[1])
48336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Values[1] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy);
48346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy,
4835058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian                                                   Values);
48365a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar  llvm::GlobalVariable *GV = GetClassGlobal(ClassName);
48375a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar  GV->setInitializer(Init);
4838dd0db2a60b65e7eaa852b77c8b9f607640eb50b9Fariborz Jahanian  GV->setSection("__DATA, __objc_data");
483909796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian  GV->setAlignment(
48404b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar    CGM.getTargetData().getABITypeAlignment(ObjCTypes.ClassnfABITy));
4841cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian  if (HiddenVisibility)
4842cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian    GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
484384394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian  return GV;
4844058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian}
4845058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian
48466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarbool
4847ecfbdcbaf71609ab99cdebbf2d704173070dbaf3Fariborz JahanianCGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
484817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  return OD->getClassMethod(GetNullarySelector("load")) != 0;
484974d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar}
485074d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar
48519f89f2bc111339ee7fa0df3c2f18e39493b460c4Daniel Dunbarvoid CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
4852b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar                                              uint32_t &InstanceStart,
4853b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar                                              uint32_t &InstanceSize) {
48546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const ASTRecordLayout &RL =
4855b4c79e027fdcc752b5a377611fd4cfbb21611a05Daniel Dunbar    CGM.getContext().getASTObjCImplementationLayout(OID);
48566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
48576e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar  // InstanceSize is really instance end.
4858ec2990351335f163601b98e39b52425e2e9f931eKen Dyck  InstanceSize = RL.getDataSize().getQuantity();
48596e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar
48606e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar  // If there are no fields, the start is the same as the end.
48616e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar  if (!RL.getFieldCount())
48626e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar    InstanceStart = InstanceSize;
48636e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar  else
4864fb67ccd9da412d652d62e2ac9675b0f1b14fdc73Ken Dyck    InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
4865b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar}
4866b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar
4867aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanianvoid CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
4868aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  std::string ClassName = ID->getNameAsString();
4869aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  if (!ObjCEmptyCacheVar) {
4870aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian    ObjCEmptyCacheVar = new llvm::GlobalVariable(
48716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      CGM.getModule(),
48726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      ObjCTypes.CacheTy,
48736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      false,
48746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      llvm::GlobalValue::ExternalLinkage,
48756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      0,
48766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      "_objc_empty_cache");
48776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4878aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian    ObjCEmptyVtableVar = new llvm::GlobalVariable(
48796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      CGM.getModule(),
48806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      ObjCTypes.ImpnfABITy,
48816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      false,
48826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      llvm::GlobalValue::ExternalLinkage,
48836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      0,
48846bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      "_objc_empty_vtable");
48856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  }
48866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  assert(ID->getClassInterface() &&
4887493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian         "CGObjCNonFragileABIMac::GenerateClass - class is 0");
48886c1aac8883ef2732a2d8543d7ac2a5ca9a199f86Daniel Dunbar  // FIXME: Is this correct (that meta class size is never computed)?
48896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  uint32_t InstanceStart =
48909408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassnfABITy);
4891058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  uint32_t InstanceSize = InstanceStart;
4892058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  uint32_t flags = CLS_META;
48936ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar  std::string ObjCMetaClassName(getMetaclassSymbolPrefix());
48946ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar  std::string ObjCClassName(getClassSymbolPrefix());
48956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4896058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  llvm::GlobalVariable *SuperClassGV, *IsAGV;
48976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
48986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  bool classIsHidden =
48991fb0caaa7bef765b85972274e3b434af2572c141John McCall    ID->getClassInterface()->getVisibility() == HiddenVisibility;
4900cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian  if (classIsHidden)
4901493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian    flags |= OBJC2_CLS_HIDDEN;
4902f85e193739c953358c865005855253af4f68a497John McCall  if (ID->hasCXXStructors())
4903109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    flags |= eClassFlags_ABI2_HasCXXStructors;
4904493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  if (!ID->getClassInterface()->getSuperClass()) {
4905058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian    // class is root
4906058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian    flags |= CLS_ROOT;
49075a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar    SuperClassGV = GetClassGlobal(ObjCClassName + ClassName);
49080f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz Jahanian    IsAGV = GetClassGlobal(ObjCMetaClassName + ClassName);
4909058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  } else {
491084394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian    // Has a root. Current class is not a root.
4911fab98c4e24a55960322c0f5e349df22c48597a73Fariborz Jahanian    const ObjCInterfaceDecl *Root = ID->getClassInterface();
4912fab98c4e24a55960322c0f5e349df22c48597a73Fariborz Jahanian    while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
4913fab98c4e24a55960322c0f5e349df22c48597a73Fariborz Jahanian      Root = Super;
49140f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz Jahanian    IsAGV = GetClassGlobal(ObjCMetaClassName + Root->getNameAsString());
49150a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (Root->isWeakImported())
49160e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian      IsAGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
4917fab98c4e24a55960322c0f5e349df22c48597a73Fariborz Jahanian    // work on super class metadata symbol.
49186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    std::string SuperClassName =
49190e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian      ObjCMetaClassName +
49200e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian        ID->getClassInterface()->getSuperClass()->getNameAsString();
49210f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz Jahanian    SuperClassGV = GetClassGlobal(SuperClassName);
49220a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (ID->getClassInterface()->getSuperClass()->isWeakImported())
4923a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian      SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
4924058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  }
4925058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags,
4926058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian                                                               InstanceStart,
4927058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian                                                               InstanceSize,ID);
492884394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian  std::string TClassName = ObjCMetaClassName + ClassName;
49296bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::GlobalVariable *MetaTClass =
4930cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian    BuildClassMetaData(TClassName, IsAGV, SuperClassGV, CLASS_RO_GV,
4931cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian                       classIsHidden);
4932a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian  DefinedMetaClasses.push_back(MetaTClass);
49336ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar
493484394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian  // Metadata for the class
493584394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian  flags = CLS;
4936cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian  if (classIsHidden)
4937493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian    flags |= OBJC2_CLS_HIDDEN;
4938f85e193739c953358c865005855253af4f68a497John McCall  if (ID->hasCXXStructors())
4939109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    flags |= eClassFlags_ABI2_HasCXXStructors;
49408158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar
494168584ed35ad819a1668e3f527ba7f5dd4ae6a333Douglas Gregor  if (hasObjCExceptionAttribute(CGM.getContext(), ID->getClassInterface()))
49428158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar    flags |= CLS_EXCEPTION;
49438158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar
4944493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  if (!ID->getClassInterface()->getSuperClass()) {
494584394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian    flags |= CLS_ROOT;
494684394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian    SuperClassGV = 0;
4947b7b58b1fcd3007730fd46471583543c9b57c7693Chris Lattner  } else {
494884394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian    // Has a root. Current class is not a root.
4949fab98c4e24a55960322c0f5e349df22c48597a73Fariborz Jahanian    std::string RootClassName =
495084394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian      ID->getClassInterface()->getSuperClass()->getNameAsString();
49515a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar    SuperClassGV = GetClassGlobal(ObjCClassName + RootClassName);
49520a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (ID->getClassInterface()->getSuperClass()->isWeakImported())
4953a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian      SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
495484394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian  }
49559f89f2bc111339ee7fa0df3c2f18e39493b460c4Daniel Dunbar  GetClassSizeInfo(ID, InstanceStart, InstanceSize);
495684394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian  CLASS_RO_GV = BuildClassRoTInitializer(flags,
4957f6a077edbbfc88d63b43d43f22db93017685c130Fariborz Jahanian                                         InstanceStart,
49586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                         InstanceSize,
4959f6a077edbbfc88d63b43d43f22db93017685c130Fariborz Jahanian                                         ID);
49606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
496184394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian  TClassName = ObjCClassName + ClassName;
49626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::GlobalVariable *ClassMD =
4963cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian    BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV,
4964cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian                       classIsHidden);
4965f87a0ccb05eb2aa095ea835fdcdf4a0363637b28Fariborz Jahanian  DefinedClasses.push_back(ClassMD);
49668158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar
496774d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar  // Determine if this class is also "non-lazy".
496874d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar  if (ImplementationIsNonLazy(ID))
496974d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar    DefinedNonLazyClasses.push_back(ClassMD);
497074d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar
49718158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  // Force the definition of the EHType if necessary.
49728158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  if (flags & CLS_EXCEPTION)
49738158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar    GetInterfaceEHType(ID->getClassInterface(), true);
497464089cece350472c04b420c497ae391443353325Fariborz Jahanian  // Make sure method definition entries are all clear for next implementation.
497564089cece350472c04b420c497ae391443353325Fariborz Jahanian  MethodDefinitions.clear();
4976aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian}
4977aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian
49788cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// GenerateProtocolRef - This routine is called to generate code for
49798cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// a protocol reference expression; as in:
49808cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// @code
49818cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian///   @protocol(Proto1);
49828cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// @endcode
49838cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1
49848cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// which will hold address of the protocol meta-data.
49858cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian///
49868cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanianllvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CGBuilderTy &Builder,
49876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                         const ObjCProtocolDecl *PD) {
49886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4989960cd06eab1325071d331b462553c9e4135c926eFariborz Jahanian  // This routine is called for @protocol only. So, we must build definition
4990960cd06eab1325071d331b462553c9e4135c926eFariborz Jahanian  // of protocol's meta-data (not a reference to it!)
4991960cd06eab1325071d331b462553c9e4135c926eFariborz Jahanian  //
49926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Constant *Init =
49936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD),
49946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                   ObjCTypes.ExternalProtocolPtrTy);
49956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
49968cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian  std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_");
49974087f27e5416c799bcb6be072f905be752acb61cDaniel Dunbar  ProtocolName += PD->getName();
49986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
49998cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian  llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
50008cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian  if (PTGV)
5001578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer    return Builder.CreateLoad(PTGV);
50028cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian  PTGV = new llvm::GlobalVariable(
50036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    CGM.getModule(),
50046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Init->getType(), false,
50056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    llvm::GlobalValue::WeakAnyLinkage,
50066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Init,
50076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    ProtocolName);
50088cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian  PTGV->setSection("__DATA, __objc_protorefs, coalesced, no_dead_strip");
50098cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian  PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5010ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  CGM.AddUsedGlobal(PTGV);
5011578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer  return Builder.CreateLoad(PTGV);
50128cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian}
50138cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian
5014eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// GenerateCategory - Build metadata for a category implementation.
5015eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// struct _category_t {
5016eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian///   const char * const name;
5017eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian///   struct _class_t *const cls;
5018eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian///   const struct _method_list_t * const instance_methods;
5019eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian///   const struct _method_list_t * const class_methods;
5020eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian///   const struct _protocol_list_t * const protocols;
5021eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian///   const struct _prop_list_t * const properties;
5022eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// }
5023eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian///
502474d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbarvoid CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
5025eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian  const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
5026f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian  const char *Prefix = "\01l_OBJC_$_CATEGORY_";
50276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  std::string ExtCatName(Prefix + Interface->getNameAsString()+
50286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                         "_$_" + OCD->getNameAsString());
50296bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  std::string ExtClassName(getClassSymbolPrefix() +
50306ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar                           Interface->getNameAsString());
50316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
50321d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  llvm::Constant *Values[6];
5033eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian  Values[0] = GetClassName(OCD->getIdentifier());
5034eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian  // meta-class entry symbol
50355a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar  llvm::GlobalVariable *ClassGV = GetClassGlobal(ExtClassName);
50360a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Interface->isWeakImported())
50372cdcc4c4314b9db36028b10da8805fe02b1c85ebFariborz Jahanian    ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
50382cdcc4c4314b9db36028b10da8805fe02b1c85ebFariborz Jahanian
5039eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian  Values[1] = ClassGV;
5040f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian  std::vector<llvm::Constant*> Methods;
5041f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian  std::string MethodListName(Prefix);
50426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  MethodListName += "INSTANCE_METHODS_" + Interface->getNameAsString() +
5043f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian    "_$_" + OCD->getNameAsString();
50446bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
50456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCCategoryImplDecl::instmeth_iterator
504617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
5047f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian    // Instance methods should always be defined.
5048f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian    Methods.push_back(GetMethodConstant(*i));
5049f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian  }
50506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
50516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[2] = EmitMethodList(MethodListName,
50526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             "__DATA, __objc_const",
5053f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian                             Methods);
5054f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian
5055f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian  MethodListName = Prefix;
5056f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian  MethodListName += "CLASS_METHODS_" + Interface->getNameAsString() + "_$_" +
5057f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian    OCD->getNameAsString();
5058f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian  Methods.clear();
50596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCCategoryImplDecl::classmeth_iterator
506017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
5061f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian    // Class methods should always be defined.
5062f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian    Methods.push_back(GetMethodConstant(*i));
5063f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian  }
50646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
50656bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[3] = EmitMethodList(MethodListName,
50666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             "__DATA, __objc_const",
5067f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian                             Methods);
50686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const ObjCCategoryDecl *Category =
50695de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian    Interface->FindCategoryDeclaration(OCD->getIdentifier());
5070943ed6ff5fafabc5ee1ea6a015908562688fbd47Fariborz Jahanian  if (Category) {
50719c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    llvm::SmallString<256> ExtName;
50729c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    llvm::raw_svector_ostream(ExtName) << Interface->getName() << "_$_"
50739c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                       << OCD->getName();
5074943ed6ff5fafabc5ee1ea6a015908562688fbd47Fariborz Jahanian    Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_"
50759c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                 + Interface->getName() + "_$_"
50769c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                 + Category->getName(),
5077943ed6ff5fafabc5ee1ea6a015908562688fbd47Fariborz Jahanian                                 Category->protocol_begin(),
5078943ed6ff5fafabc5ee1ea6a015908562688fbd47Fariborz Jahanian                                 Category->protocol_end());
50799c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    Values[5] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
50809c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                 OCD, Category, ObjCTypes);
5081b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump  } else {
5082c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
5083c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
5084943ed6ff5fafabc5ee1ea6a015908562688fbd47Fariborz Jahanian  }
50856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
50866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Constant *Init =
50876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy,
5088eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian                              Values);
5089eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian  llvm::GlobalVariable *GCATV
50906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CategorynfABITy,
5091eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian                               false,
5092eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian                               llvm::GlobalValue::InternalLinkage,
5093eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian                               Init,
50941c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                               ExtCatName);
509509796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian  GCATV->setAlignment(
50964b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar    CGM.getTargetData().getABITypeAlignment(ObjCTypes.CategorynfABITy));
50971bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian  GCATV->setSection("__DATA, __objc_const");
5098ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  CGM.AddUsedGlobal(GCATV);
5099eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian  DefinedCategories.push_back(GCATV);
510074d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar
510174d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar  // Determine if this category is also "non-lazy".
510274d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar  if (ImplementationIsNonLazy(OCD))
510374d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar    DefinedNonLazyCategories.push_back(GCATV);
510464089cece350472c04b420c497ae391443353325Fariborz Jahanian  // method definition entries must be clear for next implementation.
510564089cece350472c04b420c497ae391443353325Fariborz Jahanian  MethodDefinitions.clear();
5106eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian}
5107493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian
5108493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// GetMethodConstant - Return a struct objc_method constant for the
5109493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// given method if it has been defined. The result is null if the
5110493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// method has not been defined. The return value has type MethodPtrTy.
5111493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanianllvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant(
51126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const ObjCMethodDecl *MD) {
51139d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis  llvm::Function *Fn = GetMethodDefinition(MD);
5114493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  if (!Fn)
5115493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian    return 0;
51166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
51171d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  llvm::Constant *Method[] = {
51183c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson    llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
51191d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer                                   ObjCTypes.SelectorPtrTy),
51201d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    GetMethodVarType(MD),
51211d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy)
51221d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  };
512308e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson  return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
5124493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian}
5125493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian
5126493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// EmitMethodList - Build meta-data for method declarations
5127493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// struct _method_list_t {
5128493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian///   uint32_t entsize;  // sizeof(struct _objc_method)
5129493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian///   uint32_t method_count;
5130493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian///   struct _objc_method method_list[method_count];
5131493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// }
5132493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian///
51335f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerllvm::Constant *CGObjCNonFragileABIMac::EmitMethodList(Twine Name,
51349c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                                       const char *Section,
51359c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                                const ConstantVector &Methods) {
5136493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  // Return null for empty list.
5137493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  if (Methods.empty())
5138c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
51396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5140c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[3];
5141493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  // sizeof(struct _objc_method)
51429408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands  unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.MethodTy);
51434a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
5144493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  // method_count
51454a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
514696e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
5147493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian                                             Methods.size());
51487db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson  Values[2] = llvm::ConstantArray::get(AT, Methods);
5149c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
51506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5151493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  llvm::GlobalVariable *GV =
51521c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson    new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5153c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner                             llvm::GlobalValue::InternalLinkage, Init, Name);
5154c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  GV->setAlignment(CGM.getTargetData().getABITypeAlignment(Init->getType()));
5155493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  GV->setSection(Section);
5156ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  CGM.AddUsedGlobal(GV);
5157c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy);
5158493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian}
515998abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian
5160ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian/// ObjCIvarOffsetVariable - Returns the ivar offset variable for
5161ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian/// the given ivar.
5162e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbarllvm::GlobalVariable *
5163e83be1228028f44de76cbad9d908e2dc9e261171Daniel DunbarCGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
5164e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbar                                               const ObjCIvarDecl *Ivar) {
5165e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbar  const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
5166a81419d0b53a40399a589a2fcc13f1ed2ec28f75Daniel Dunbar  std::string Name = "OBJC_IVAR_$_" + Container->getNameAsString() +
51676ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor    '.' + Ivar->getNameAsString();
51686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::GlobalVariable *IvarOffsetGV =
5169ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian    CGM.getModule().getGlobalVariable(Name);
5170ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian  if (!IvarOffsetGV)
51716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    IvarOffsetGV =
51721c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.LongTy,
5173ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian                               false,
5174ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian                               llvm::GlobalValue::ExternalLinkage,
5175ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian                               0,
51761c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                               Name);
5177ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian  return IvarOffsetGV;
5178ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian}
5179ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian
5180e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbarllvm::Constant *
5181e83be1228028f44de76cbad9d908e2dc9e261171Daniel DunbarCGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
5182e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbar                                          const ObjCIvarDecl *Ivar,
5183e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbar                                          unsigned long int Offset) {
5184737c502a3f259fc3790542366597c7e3fccad6fdDaniel Dunbar  llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
51856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  IvarOffsetGV->setInitializer(llvm::ConstantInt::get(ObjCTypes.LongTy,
5186737c502a3f259fc3790542366597c7e3fccad6fdDaniel Dunbar                                                      Offset));
518709796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian  IvarOffsetGV->setAlignment(
51884b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar    CGM.getTargetData().getABITypeAlignment(ObjCTypes.LongTy));
5189737c502a3f259fc3790542366597c7e3fccad6fdDaniel Dunbar
5190f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // FIXME: This matches gcc, but shouldn't the visibility be set on the use as
5191f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // well (i.e., in ObjCIvarOffsetVariable).
5192737c502a3f259fc3790542366597c7e3fccad6fdDaniel Dunbar  if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
5193737c502a3f259fc3790542366597c7e3fccad6fdDaniel Dunbar      Ivar->getAccessControl() == ObjCIvarDecl::Package ||
51941fb0caaa7bef765b85972274e3b434af2572c141John McCall      ID->getVisibility() == HiddenVisibility)
51952fa5a27f38b2c4abc26e86895fdcef3ec84af39dFariborz Jahanian    IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
519604d4078425614bf9fd58d606335c1f5f74ee7fa4Daniel Dunbar  else
519777c9fd2eee4cdac3c5a38a353788f308990598afFariborz Jahanian    IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
51981f382510495b581e3028d670a23c7dcf5440be62Bill Wendling  IvarOffsetGV->setSection("__DATA, __objc_ivar");
519945012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian  return IvarOffsetGV;
52001bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian}
52011bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian
520298abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// EmitIvarList - Emit the ivar list for the given
52031139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar/// implementation. The return value has type
520498abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// IvarListnfABIPtrTy.
520598abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian///  struct _ivar_t {
520698abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian///   unsigned long int *offset;  // pointer to ivar offset location
520798abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian///   char *name;
520898abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian///   char *type;
520998abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian///   uint32_t alignment;
521098abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian///   uint32_t size;
521198abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// }
521298abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// struct _ivar_list_t {
521398abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian///   uint32 entsize;  // sizeof(struct _ivar_t)
521498abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian///   uint32 count;
521598abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian///   struct _iver_t list[count];
521698abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// }
521798abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian///
52183e5f0d88d7eda79b7a679188d1e6da54cec72f5dDaniel Dunbar
521998abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanianllvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
52206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const ObjCImplementationDecl *ID) {
52216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
52221d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  std::vector<llvm::Constant*> Ivars;
52236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5224db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  const ObjCInterfaceDecl *OID = ID->getClassInterface();
522598abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface");
52266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
52271bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian  // FIXME. Consolidate this with similar code in GenerateClass.
52286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5229db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
5230bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian       IVD; IVD = IVD->getNextIvar()) {
52318e6ac1d80055fa37b9b84029c7e751624ba7f84cFariborz Jahanian    // Ignore unnamed bit-fields.
52328e6ac1d80055fa37b9b84029c7e751624ba7f84cFariborz Jahanian    if (!IVD->getDeclName())
52338e6ac1d80055fa37b9b84029c7e751624ba7f84cFariborz Jahanian      continue;
52341d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    llvm::Constant *Ivar[5];
52356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Ivar[0] = EmitIvarOffsetVar(ID->getClassInterface(), IVD,
52369f89f2bc111339ee7fa0df3c2f18e39493b460c4Daniel Dunbar                                ComputeIvarBaseOffset(CGM, ID, IVD));
52373fea0c01e178e46eb20e81de4907a3d144c21fd6Daniel Dunbar    Ivar[1] = GetMethodVarName(IVD->getIdentifier());
52383fea0c01e178e46eb20e81de4907a3d144c21fd6Daniel Dunbar    Ivar[2] = GetMethodVarType(IVD);
52392acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::Type *FieldTy =
52403fea0c01e178e46eb20e81de4907a3d144c21fd6Daniel Dunbar      CGM.getTypes().ConvertTypeForMem(IVD->getType());
52419408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    unsigned Size = CGM.getTargetData().getTypeAllocSize(FieldTy);
524298abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian    unsigned Align = CGM.getContext().getPreferredTypeAlign(
52436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      IVD->getType().getTypePtr()) >> 3;
524498abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian    Align = llvm::Log2_32(Align);
52454a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson    Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align);
524691636d6c4c07fd2edf19a510b02c6e793a28741fDaniel Dunbar    // NOTE. Size of a bitfield does not match gcc's, because of the
524791636d6c4c07fd2edf19a510b02c6e793a28741fDaniel Dunbar    // way bitfields are treated special in each. But I am told that
524891636d6c4c07fd2edf19a510b02c6e793a28741fDaniel Dunbar    // 'size' for bitfield ivars is ignored by the runtime so it does
524991636d6c4c07fd2edf19a510b02c6e793a28741fDaniel Dunbar    // not matter.  If it matters, there is enough info to get the
525091636d6c4c07fd2edf19a510b02c6e793a28741fDaniel Dunbar    // bitfield right!
52514a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson    Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
525208e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson    Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar));
525398abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  }
525498abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  // Return null for empty list.
525598abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  if (Ivars.empty())
5256c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
5257c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner
5258c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[3];
52599408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands  unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.IvarnfABITy);
52604a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
52614a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
526296e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy,
526398abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian                                             Ivars.size());
52647db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson  Values[2] = llvm::ConstantArray::get(AT, Ivars);
5265c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
526698abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_";
526798abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  llvm::GlobalVariable *GV =
52681c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson    new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
526998abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian                             llvm::GlobalValue::InternalLinkage,
527098abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian                             Init,
52719c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                             Prefix + OID->getName());
527209796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian  GV->setAlignment(
52734b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar    CGM.getTargetData().getABITypeAlignment(Init->getType()));
52741bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian  GV->setSection("__DATA, __objc_const");
52756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5276ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  CGM.AddUsedGlobal(GV);
52773c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
5278da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian}
5279da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian
5280da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanianllvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
52816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const ObjCProtocolDecl *PD) {
5282da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
52836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5284da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  if (!Entry) {
5285da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    // We use the initializer as a marker of whether this is a forward
5286da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    // reference or not. At module finalization we add the empty
5287da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    // contents for protocols which were referenced but never defined.
52886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry =
52896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, false,
52906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                               llvm::GlobalValue::ExternalLinkage,
52916bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                               0,
52929c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                               "\01l_OBJC_PROTOCOL_$_" + PD->getName());
5293da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    Entry->setSection("__DATA,__datacoal_nt,coalesced");
5294da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  }
52956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5296da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  return Entry;
5297da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian}
5298da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian
5299da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// GetOrEmitProtocol - Generate the protocol meta-data:
5300da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// @code
5301da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// struct _protocol_t {
5302da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   id isa;  // NULL
5303da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   const char * const protocol_name;
5304da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   const struct _protocol_list_t * protocol_list; // super protocols
5305da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   const struct method_list_t * const instance_methods;
5306da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   const struct method_list_t * const class_methods;
5307da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   const struct method_list_t *optionalInstanceMethods;
5308da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   const struct method_list_t *optionalClassMethods;
5309da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   const struct _prop_list_t * properties;
5310da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   const uint32_t size;  // sizeof(struct _protocol_t)
5311da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   const uint32_t flags;  // = 0
5312da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// }
5313da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// @endcode
5314da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///
5315da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian
5316da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanianllvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
53176bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const ObjCProtocolDecl *PD) {
5318da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
53196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5320da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  // Early exit if a defining object has already been generated.
5321da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  if (Entry && Entry->hasInitializer())
5322da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    return Entry;
5323da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian
5324da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  // Construct method lists.
5325da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
5326da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
53276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCProtocolDecl::instmeth_iterator
532817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
5329da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    ObjCMethodDecl *MD = *i;
53303819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian    llvm::Constant *C = GetMethodDescriptionConstant(MD);
5331f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor    if (!C)
5332f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor      return GetOrEmitProtocolRef(PD);
5333f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor
5334da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
5335da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian      OptInstanceMethods.push_back(C);
5336da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    } else {
5337da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian      InstanceMethods.push_back(C);
53386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    }
5339da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  }
53406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
53416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCProtocolDecl::classmeth_iterator
534217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
5343da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    ObjCMethodDecl *MD = *i;
53443819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian    llvm::Constant *C = GetMethodDescriptionConstant(MD);
5345f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor    if (!C)
5346f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor      return GetOrEmitProtocolRef(PD);
5347f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor
5348da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
5349da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian      OptClassMethods.push_back(C);
5350da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    } else {
5351da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian      ClassMethods.push_back(C);
53526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    }
5353da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  }
53546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
53551d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  llvm::Constant *Values[10];
5356da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  // isa is NULL
5357c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy);
5358da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  Values[1] = GetClassName(PD->getIdentifier());
53599c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar  Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getName(),
53609c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                               PD->protocol_begin(),
53619c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                               PD->protocol_end());
53626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
53633819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian  Values[3] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_"
53649c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                             + PD->getName(),
5365da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                             "__DATA, __objc_const",
5366da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                             InstanceMethods);
53676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[4] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_"
53689c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                             + PD->getName(),
5369da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                             "__DATA, __objc_const",
5370da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                             ClassMethods);
53713819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian  Values[5] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_"
53729c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                             + PD->getName(),
5373da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                             "__DATA, __objc_const",
5374da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                             OptInstanceMethods);
53756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[6] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_"
53769c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                             + PD->getName(),
5377da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                             "__DATA, __objc_const",
5378da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                             OptClassMethods);
53799c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar  Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getName(),
5380da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                               0, PD, ObjCTypes);
53816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  uint32_t Size =
53829408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
53834a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
5384c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy);
538508e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy,
5386da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                                                   Values);
53876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5388da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  if (Entry) {
5389da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    // Already created, fix the linkage and update the initializer.
5390286acbdbe0c82e9a6bcad5fca3c4fa582f3f1a2cMike Stump    Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
5391da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    Entry->setInitializer(Init);
5392da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  } else {
53936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry =
53949c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
53959c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                               false, llvm::GlobalValue::WeakAnyLinkage, Init,
53969c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                               "\01l_OBJC_PROTOCOL_$_" + PD->getName());
539709796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian    Entry->setAlignment(
53984b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar      CGM.getTargetData().getABITypeAlignment(ObjCTypes.ProtocolnfABITy));
5399da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    Entry->setSection("__DATA,__datacoal_nt,coalesced");
5400da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  }
54018448c2cdab6e3d4b15725921735243c77b06623dFariborz Jahanian  Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
5402ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  CGM.AddUsedGlobal(Entry);
5403ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner
54048448c2cdab6e3d4b15725921735243c77b06623dFariborz Jahanian  // Use this protocol meta-data to build protocol list table in section
54058448c2cdab6e3d4b15725921735243c77b06623dFariborz Jahanian  // __DATA, __objc_protolist
54069c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar  llvm::GlobalVariable *PTGV =
54079c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy,
54089c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                             false, llvm::GlobalValue::WeakAnyLinkage, Entry,
54099c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                             "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getName());
541009796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian  PTGV->setAlignment(
54114b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar    CGM.getTargetData().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
54120bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar  PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip");
54138448c2cdab6e3d4b15725921735243c77b06623dFariborz Jahanian  PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5414ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  CGM.AddUsedGlobal(PTGV);
5415da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  return Entry;
5416da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian}
5417da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian
5418da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// EmitProtocolList - Generate protocol list meta-data:
5419da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// @code
5420da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// struct _protocol_list_t {
5421da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   long protocol_count;   // Note, this is 32/64 bit
5422da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   struct _protocol_t[protocol_count];
5423da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// }
5424da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// @endcode
5425da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///
5426da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanianllvm::Constant *
54275f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerCGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
54289c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                      ObjCProtocolDecl::protocol_iterator begin,
54299c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                      ObjCProtocolDecl::protocol_iterator end) {
5430da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  std::vector<llvm::Constant*> ProtocolRefs;
54316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5432da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  // Just return null for empty protocol lists
54336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  if (begin == end)
5434c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
54356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5436948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar  // FIXME: We shouldn't need to do this lookup here, should we?
54379c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar  llvm::SmallString<256> TmpName;
54389c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar  Name.toVector(TmpName);
54399c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar  llvm::GlobalVariable *GV =
54409c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    CGM.getModule().getGlobalVariable(TmpName.str(), true);
5441da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  if (GV)
54429c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
54436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5444948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar  for (; begin != end; ++begin)
5445948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar    ProtocolRefs.push_back(GetProtocolRef(*begin));  // Implemented???
5446948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar
5447da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  // This list is null terminated.
5448c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  ProtocolRefs.push_back(llvm::Constant::getNullValue(
54496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                           ObjCTypes.ProtocolnfABIPtrTy));
54506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5451c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[2];
5452a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson  Values[0] =
54534a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson    llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
54546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[1] =
54557db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson    llvm::ConstantArray::get(
545696e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson      llvm::ArrayType::get(ObjCTypes.ProtocolnfABIPtrTy,
54576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                           ProtocolRefs.size()),
54586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      ProtocolRefs);
54596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5460c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
54611c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson  GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5462da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                                llvm::GlobalValue::InternalLinkage,
5463c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner                                Init, Name);
5464da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  GV->setSection("__DATA, __objc_const");
546509796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian  GV->setAlignment(
54664b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar    CGM.getTargetData().getABITypeAlignment(Init->getType()));
5467ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  CGM.AddUsedGlobal(GV);
54686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  return llvm::ConstantExpr::getBitCast(GV,
5469948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar                                        ObjCTypes.ProtocolListnfABIPtrTy);
5470da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian}
5471da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian
54723819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian/// GetMethodDescriptionConstant - This routine build following meta-data:
54733819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian/// struct _objc_method {
54743819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian///   SEL _cmd;
54753819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian///   char *method_type;
54763819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian///   char *_imp;
54773819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian/// }
54783819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian
54793819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanianllvm::Constant *
54803819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz JahanianCGObjCNonFragileABIMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
54811d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  llvm::Constant *Desc[3];
5482a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson  Desc[0] =
54836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
54846bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                   ObjCTypes.SelectorPtrTy);
54853819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian  Desc[1] = GetMethodVarType(MD);
5486f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor  if (!Desc[1])
5487f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor    return 0;
5488f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor
54898cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian  // Protocol methods have no implementation. So, this entry is always NULL.
5490c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
549108e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson  return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc);
54923819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian}
549345012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian
549445012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian/// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference.
549545012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian/// This code gen. amounts to generating code for:
549645012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian/// @code
549745012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian/// (type *)((char *)base + _OBJC_IVAR_$_.ivar;
549845012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian/// @encode
54996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar///
5500598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz JahanianLValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
5501506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall                                               CodeGen::CodeGenFunction &CGF,
5502506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall                                               QualType ObjectTy,
5503506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall                                               llvm::Value *BaseValue,
5504506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall                                               const ObjCIvarDecl *Ivar,
5505506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall                                               unsigned CVRQualifiers) {
5506506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCObjectType>()->getInterface();
55079777687562c338601c2f17906e65e1c1a0aad96fDaniel Dunbar  return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
55089777687562c338601c2f17906e65e1c1a0aad96fDaniel Dunbar                                  EmitIvarOffset(CGF, ID, Ivar));
550945012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian}
551045012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian
5511f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanianllvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(
55126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  CodeGen::CodeGenFunction &CGF,
55136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const ObjCInterfaceDecl *Interface,
55146bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const ObjCIvarDecl *Ivar) {
55152da84ff228a231adbd3f6f236b857f752d02959aDaniel Dunbar  return CGF.Builder.CreateLoad(ObjCIvarOffsetVariable(Interface, Ivar),"ivar");
5516f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian}
5517f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian
5518b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCallstatic void appendSelectorForMessageRefTable(std::string &buffer,
5519b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall                                             Selector selector) {
5520b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  if (selector.isUnarySelector()) {
5521b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    buffer += selector.getNameForSlot(0);
5522b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    return;
5523b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  }
55246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5525b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) {
5526b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    buffer += selector.getNameForSlot(i);
5527b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    buffer += '_';
5528b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  }
5529b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall}
5530b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall
5531944c84313da15477eb18d90babb0890d10d98082John McCall/// Emit a "v-table" message send.  We emit a weak hidden-visibility
5532944c84313da15477eb18d90babb0890d10d98082John McCall/// struct, initially containing the selector pointer and a pointer to
5533944c84313da15477eb18d90babb0890d10d98082John McCall/// a "fixup" variant of the appropriate objc_msgSend.  To call, we
5534944c84313da15477eb18d90babb0890d10d98082John McCall/// load and call the function pointer, passing the address of the
5535944c84313da15477eb18d90babb0890d10d98082John McCall/// struct as the second parameter.  The runtime determines whether
5536944c84313da15477eb18d90babb0890d10d98082John McCall/// the selector is currently emitted using vtable dispatch; if so, it
5537944c84313da15477eb18d90babb0890d10d98082John McCall/// substitutes a stub function which simply tail-calls through the
5538944c84313da15477eb18d90babb0890d10d98082John McCall/// appropriate vtable slot, and if not, it substitues a stub function
5539944c84313da15477eb18d90babb0890d10d98082John McCall/// which tail-calls objc_msgSend.  Both stubs adjust the selector
5540944c84313da15477eb18d90babb0890d10d98082John McCall/// argument to correctly point to the selector.
5541944c84313da15477eb18d90babb0890d10d98082John McCallRValue
5542944c84313da15477eb18d90babb0890d10d98082John McCallCGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF,
5543944c84313da15477eb18d90babb0890d10d98082John McCall                                              ReturnValueSlot returnSlot,
5544944c84313da15477eb18d90babb0890d10d98082John McCall                                              QualType resultType,
5545944c84313da15477eb18d90babb0890d10d98082John McCall                                              Selector selector,
5546944c84313da15477eb18d90babb0890d10d98082John McCall                                              llvm::Value *arg0,
5547944c84313da15477eb18d90babb0890d10d98082John McCall                                              QualType arg0Type,
5548944c84313da15477eb18d90babb0890d10d98082John McCall                                              bool isSuper,
5549944c84313da15477eb18d90babb0890d10d98082John McCall                                              const CallArgList &formalArgs,
5550944c84313da15477eb18d90babb0890d10d98082John McCall                                              const ObjCMethodDecl *method) {
5551b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  // Compute the actual arguments.
5552b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  CallArgList args;
5553b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall
5554944c84313da15477eb18d90babb0890d10d98082John McCall  // First argument: the receiver / super-call structure.
5555b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  if (!isSuper)
5556944c84313da15477eb18d90babb0890d10d98082John McCall    arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy);
5557944c84313da15477eb18d90babb0890d10d98082John McCall  args.add(RValue::get(arg0), arg0Type);
5558b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall
5559944c84313da15477eb18d90babb0890d10d98082John McCall  // Second argument: a pointer to the message ref structure.  Leave
5560944c84313da15477eb18d90babb0890d10d98082John McCall  // the actual argument value blank for now.
5561b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  args.add(RValue::get(0), ObjCTypes.MessageRefCPtrTy);
5562b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall
5563b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  args.insert(args.end(), formalArgs.begin(), formalArgs.end());
5564b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall
5565b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  const CGFunctionInfo &fnInfo =
5566b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    CGM.getTypes().getFunctionInfo(resultType, args,
5567b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall                                   FunctionType::ExtInfo());
5568b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall
5569cba681af356e24ec4335bcf2b6bb6515072ace99John McCall  NullReturnState nullReturn;
5570cba681af356e24ec4335bcf2b6bb6515072ace99John McCall
5571944c84313da15477eb18d90babb0890d10d98082John McCall  // Find the function to call and the mangled name for the message
5572944c84313da15477eb18d90babb0890d10d98082John McCall  // ref structure.  Using a different mangled name wouldn't actually
5573944c84313da15477eb18d90babb0890d10d98082John McCall  // be a problem; it would just be a waste.
5574944c84313da15477eb18d90babb0890d10d98082John McCall  //
5575944c84313da15477eb18d90babb0890d10d98082John McCall  // The runtime currently never uses vtable dispatch for anything
5576944c84313da15477eb18d90babb0890d10d98082John McCall  // except normal, non-super message-sends.
5577944c84313da15477eb18d90babb0890d10d98082John McCall  // FIXME: don't use this for that.
5578b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  llvm::Constant *fn = 0;
5579b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  std::string messageRefName("\01l_");
5580b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  if (CGM.ReturnTypeUsesSRet(fnInfo)) {
5581b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    if (isSuper) {
5582b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall      fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
5583b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall      messageRefName += "objc_msgSendSuper2_stret_fixup";
55849b7d6701dabc24387cc152e4d13bf9aec6aa461aChris Lattner    } else {
5585cba681af356e24ec4335bcf2b6bb6515072ace99John McCall      nullReturn.init(CGF, arg0);
5586b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall      fn = ObjCTypes.getMessageSendStretFixupFn();
5587b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall      messageRefName += "objc_msgSend_stret_fixup";
55889b7d6701dabc24387cc152e4d13bf9aec6aa461aChris Lattner    }
5589b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) {
5590b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    fn = ObjCTypes.getMessageSendFpretFixupFn();
5591b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    messageRefName += "objc_msgSend_fpret_fixup";
5592b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump  } else {
5593b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    if (isSuper) {
5594b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall      fn = ObjCTypes.getMessageSendSuper2FixupFn();
5595b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall      messageRefName += "objc_msgSendSuper2_fixup";
55969b7d6701dabc24387cc152e4d13bf9aec6aa461aChris Lattner    } else {
5597b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall      fn = ObjCTypes.getMessageSendFixupFn();
5598b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall      messageRefName += "objc_msgSend_fixup";
55999b7d6701dabc24387cc152e4d13bf9aec6aa461aChris Lattner    }
560083a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  }
5601b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend");
5602b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  messageRefName += '_';
5603b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall
5604b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  // Append the selector name, except use underscores anywhere we
5605b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  // would have used colons.
5606b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  appendSelectorForMessageRefTable(messageRefName, selector);
5607b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall
5608b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  llvm::GlobalVariable *messageRef
5609b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    = CGM.getModule().getGlobalVariable(messageRefName);
5610b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  if (!messageRef) {
5611944c84313da15477eb18d90babb0890d10d98082John McCall    // Build the message ref structure.
5612b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    llvm::Constant *values[] = { fn, GetMethodVarName(selector) };
5613c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner    llvm::Constant *init = llvm::ConstantStruct::getAnon(values);
5614b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    messageRef = new llvm::GlobalVariable(CGM.getModule(),
5615b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall                                          init->getType(),
5616b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall                                          /*constant*/ false,
5617b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall                                          llvm::GlobalValue::WeakAnyLinkage,
5618b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall                                          init,
5619b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall                                          messageRefName);
5620b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
5621b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    messageRef->setAlignment(16);
5622b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    messageRef->setSection("__DATA, __objc_msgrefs, coalesced");
562383a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  }
5624b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  llvm::Value *mref =
5625b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy);
56266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5627944c84313da15477eb18d90babb0890d10d98082John McCall  // Update the message ref argument.
5628b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  args[1].RV = RValue::get(mref);
5629b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall
5630b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  // Load the function to call from the message ref table.
5631b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  llvm::Value *callee = CGF.Builder.CreateStructGEP(mref, 0);
5632b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  callee = CGF.Builder.CreateLoad(callee, "msgSend_fn");
5633b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall
5634b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  bool variadic = method ? method->isVariadic() : false;
56352acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::FunctionType *fnType =
5636b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    CGF.getTypes().GetFunctionType(fnInfo, variadic);
5637b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  callee = CGF.Builder.CreateBitCast(callee,
5638b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall                                     llvm::PointerType::getUnqual(fnType));
5639b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall
5640cba681af356e24ec4335bcf2b6bb6515072ace99John McCall  RValue result = CGF.EmitCall(fnInfo, callee, returnSlot, args);
5641cba681af356e24ec4335bcf2b6bb6515072ace99John McCall  return nullReturn.complete(CGF, result, resultType);
56424655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian}
56434655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian
56444655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian/// Generate code for a message send expression in the nonfragile abi.
5645d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel DunbarCodeGen::RValue
5646d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel DunbarCGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
5647ef072fd2f3347cfd857d6eb787b245b950771430John McCall                                            ReturnValueSlot Return,
5648d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                                            QualType ResultType,
5649d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                                            Selector Sel,
5650d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                                            llvm::Value *Receiver,
5651d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                                            const CallArgList &CallArgs,
5652c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall                                            const ObjCInterfaceDecl *Class,
5653d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                                            const ObjCMethodDecl *Method) {
5654944c84313da15477eb18d90babb0890d10d98082John McCall  return isVTableDispatchedSelector(Sel)
5655944c84313da15477eb18d90babb0890d10d98082John McCall    ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
56566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                            Receiver, CGF.getContext().getObjCIdType(),
5657944c84313da15477eb18d90babb0890d10d98082John McCall                            false, CallArgs, Method)
5658944c84313da15477eb18d90babb0890d10d98082John McCall    : EmitMessageSend(CGF, Return, ResultType,
5659944c84313da15477eb18d90babb0890d10d98082John McCall                      EmitSelector(CGF.Builder, Sel),
56606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                      Receiver, CGF.getContext().getObjCIdType(),
5661944c84313da15477eb18d90babb0890d10d98082John McCall                      false, CallArgs, Method, ObjCTypes);
56624655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian}
56634655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian
56645a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbarllvm::GlobalVariable *
56650f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz JahanianCGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name) {
56665a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
56675a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar
5668dfff23060b4a3add79a3bb68ccec606ade4f39bfDaniel Dunbar  if (!GV) {
56696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABITy,
56701c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                                  false, llvm::GlobalValue::ExternalLinkage,
56711c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                                  0, Name);
56725a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar  }
56735a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar
56745a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar  return GV;
56755a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar}
56765a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar
5677f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CGBuilderTy &Builder,
5678f85e193739c953358c865005855253af4f68a497John McCall                                                        IdentifierInfo *II) {
5679f85e193739c953358c865005855253af4f68a497John McCall  llvm::GlobalVariable *&Entry = ClassReferences[II];
5680f85e193739c953358c865005855253af4f68a497John McCall
56810e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian  if (!Entry) {
5682f85e193739c953358c865005855253af4f68a497John McCall    std::string ClassName(getClassSymbolPrefix() + II->getName().str());
56835a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
56846bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry =
5685f85e193739c953358c865005855253af4f68a497John McCall    new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
5686f85e193739c953358c865005855253af4f68a497John McCall                             false, llvm::GlobalValue::InternalLinkage,
5687f85e193739c953358c865005855253af4f68a497John McCall                             ClassGV,
5688f85e193739c953358c865005855253af4f68a497John McCall                             "\01L_OBJC_CLASSLIST_REFERENCES_$_");
56890e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian    Entry->setAlignment(
5690f85e193739c953358c865005855253af4f68a497John McCall                        CGM.getTargetData().getABITypeAlignment(
5691f85e193739c953358c865005855253af4f68a497John McCall                                                                ObjCTypes.ClassnfABIPtrTy));
56921139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar    Entry->setSection("__DATA, __objc_classrefs, regular, no_dead_strip");
5693ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner    CGM.AddUsedGlobal(Entry);
56941139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar  }
5695f85e193739c953358c865005855253af4f68a497John McCall
5696578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer  return Builder.CreateLoad(Entry);
56971139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar}
56980e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian
5699f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CGBuilderTy &Builder,
5700f85e193739c953358c865005855253af4f68a497John McCall                                                  const ObjCInterfaceDecl *ID) {
5701f85e193739c953358c865005855253af4f68a497John McCall  return EmitClassRefFromId(Builder, ID->getIdentifier());
5702f85e193739c953358c865005855253af4f68a497John McCall}
5703f85e193739c953358c865005855253af4f68a497John McCall
5704f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
5705f85e193739c953358c865005855253af4f68a497John McCall                                                    CGBuilderTy &Builder) {
5706f85e193739c953358c865005855253af4f68a497John McCall  IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
5707f85e193739c953358c865005855253af4f68a497John McCall  return EmitClassRefFromId(Builder, II);
5708f85e193739c953358c865005855253af4f68a497John McCall}
5709f85e193739c953358c865005855253af4f68a497John McCall
57101139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbarllvm::Value *
57116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarCGObjCNonFragileABIMac::EmitSuperClassRef(CGBuilderTy &Builder,
57121139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar                                          const ObjCInterfaceDecl *ID) {
57131139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar  llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
57146bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
57151139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar  if (!Entry) {
57161139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar    std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
57171139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
57186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry =
57196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
57201c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                               false, llvm::GlobalValue::InternalLinkage,
57216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                               ClassGV,
57221c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                               "\01L_OBJC_CLASSLIST_SUP_REFS_$_");
57231139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar    Entry->setAlignment(
57244b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar      CGM.getTargetData().getABITypeAlignment(
57256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar        ObjCTypes.ClassnfABIPtrTy));
57261139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar    Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
5727ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner    CGM.AddUsedGlobal(Entry);
57280e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian  }
57296bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5730578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer  return Builder.CreateLoad(Entry);
57310e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian}
57320e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian
57337a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian/// EmitMetaClassRef - Return a Value * of the address of _class_t
57347a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian/// meta-data
57357a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian///
57366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CGBuilderTy &Builder,
57376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                      const ObjCInterfaceDecl *ID) {
57387a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];
57397a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  if (Entry)
5740578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer    return Builder.CreateLoad(Entry);
57416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
57426ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar  std::string MetaClassName(getMetaclassSymbolPrefix() + ID->getNameAsString());
57430f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz Jahanian  llvm::GlobalVariable *MetaClassGV = GetClassGlobal(MetaClassName);
57446bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Entry =
57451c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson    new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, false,
57467a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian                             llvm::GlobalValue::InternalLinkage,
57476bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             MetaClassGV,
57481c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                             "\01L_OBJC_CLASSLIST_SUP_REFS_$_");
57497a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  Entry->setAlignment(
57504b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar    CGM.getTargetData().getABITypeAlignment(
57516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      ObjCTypes.ClassnfABIPtrTy));
57526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
575333af70f0f003d9765b92621f4fdd801e2b6c0ae7Daniel Dunbar  Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
5754ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  CGM.AddUsedGlobal(Entry);
57556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5756578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer  return Builder.CreateLoad(Entry);
57577a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian}
57587a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian
57590e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian/// GetClass - Return a reference to the class for the given interface
57600e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian/// decl.
57610e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanianllvm::Value *CGObjCNonFragileABIMac::GetClass(CGBuilderTy &Builder,
57620e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian                                              const ObjCInterfaceDecl *ID) {
57630a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (ID->isWeakImported()) {
5764269f8bc10a33e29e2951df7720cad0abb45c74cbFariborz Jahanian    std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
5765269f8bc10a33e29e2951df7720cad0abb45c74cbFariborz Jahanian    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
5766269f8bc10a33e29e2951df7720cad0abb45c74cbFariborz Jahanian    ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
5767269f8bc10a33e29e2951df7720cad0abb45c74cbFariborz Jahanian  }
5768269f8bc10a33e29e2951df7720cad0abb45c74cbFariborz Jahanian
57690e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian  return EmitClassRef(Builder, ID);
57700e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian}
57710e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian
57727a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian/// Generates a message send where the super is the receiver.  This is
57737a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian/// a message send to self with special delivery semantics indicating
57747a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian/// which class's method should be called.
57757a06aae468c94a21c267106ec16bd2c79dab2857Fariborz JahanianCodeGen::RValue
57767a06aae468c94a21c267106ec16bd2c79dab2857Fariborz JahanianCGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
5777ef072fd2f3347cfd857d6eb787b245b950771430John McCall                                                 ReturnValueSlot Return,
57786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                 QualType ResultType,
57796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                 Selector Sel,
57806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                 const ObjCInterfaceDecl *Class,
57816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                 bool isCategoryImpl,
57826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                 llvm::Value *Receiver,
57836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                 bool IsClassMessage,
5784d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                                                 const CodeGen::CallArgList &CallArgs,
5785d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                                                 const ObjCMethodDecl *Method) {
57867a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  // ...
57877a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  // Create and init a super structure; this is a (receiver, class)
57887a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  // pair we will pass to objc_msgSendSuper.
57897a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  llvm::Value *ObjCSuper =
5790604da292483bc94a6a3e4700cd426d4fa7f1a4a8John McCall    CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super");
57916bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
57927a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  llvm::Value *ReceiverAsObject =
57937a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian    CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
57947a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  CGF.Builder.CreateStore(ReceiverAsObject,
57957a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian                          CGF.Builder.CreateStructGEP(ObjCSuper, 0));
57966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
57977a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  // If this is a class message the metaclass is passed as the target.
57987ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian  llvm::Value *Target;
57997ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian  if (IsClassMessage) {
58007ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian    if (isCategoryImpl) {
58017ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      // Message sent to "super' in a class method defined in
58027ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      // a category implementation.
58031139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar      Target = EmitClassRef(CGF.Builder, Class);
58047ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      Target = CGF.Builder.CreateStructGEP(Target, 0);
58057ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      Target = CGF.Builder.CreateLoad(Target);
5806b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump    } else
58077ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      Target = EmitMetaClassRef(CGF.Builder, Class);
5808b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump  } else
58091139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar    Target = EmitSuperClassRef(CGF.Builder, Class);
58106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5811f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
5812f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // ObjCTypes types.
58132acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *ClassTy =
58147a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian    CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
58157a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  Target = CGF.Builder.CreateBitCast(Target, ClassTy);
58167a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  CGF.Builder.CreateStore(Target,
58177a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian                          CGF.Builder.CreateStructGEP(ObjCSuper, 1));
58186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5819944c84313da15477eb18d90babb0890d10d98082John McCall  return (isVTableDispatchedSelector(Sel))
5820944c84313da15477eb18d90babb0890d10d98082John McCall    ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
58216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                            ObjCSuper, ObjCTypes.SuperPtrCTy,
5822944c84313da15477eb18d90babb0890d10d98082John McCall                            true, CallArgs, Method)
5823944c84313da15477eb18d90babb0890d10d98082John McCall    : EmitMessageSend(CGF, Return, ResultType,
5824944c84313da15477eb18d90babb0890d10d98082John McCall                      EmitSelector(CGF.Builder, Sel),
58256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                      ObjCSuper, ObjCTypes.SuperPtrCTy,
5826944c84313da15477eb18d90babb0890d10d98082John McCall                      true, CallArgs, Method, ObjCTypes);
58277a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian}
582826cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian
58296bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Value *CGObjCNonFragileABIMac::EmitSelector(CGBuilderTy &Builder,
583003b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian                                                  Selector Sel, bool lval) {
583126cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian  llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
58326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
583326cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian  if (!Entry) {
58346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    llvm::Constant *Casted =
58356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
58366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                     ObjCTypes.SelectorPtrTy);
58376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry =
58386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.SelectorPtrTy, false,
58396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                               llvm::GlobalValue::InternalLinkage,
58406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                               Casted, "\01L_OBJC_SELECTOR_REFERENCES_");
5841d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    Entry->setSection("__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
5842ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner    CGM.AddUsedGlobal(Entry);
584326cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian  }
58446bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
584503b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian  if (lval)
584603b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian    return Entry;
5847578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer  return Builder.CreateLoad(Entry);
584826cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian}
58496948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
58506c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian/// objc_assign_ivar (id src, id *dst, ptrdiff_t)
58516948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian///
58526948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanianvoid CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
58531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                                llvm::Value *src,
58546c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian                                                llvm::Value *dst,
58556c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian                                                llvm::Value *ivarOffset) {
58562acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type * SrcTy = src->getType();
58570a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian  if (!isa<llvm::PointerType>(SrcTy)) {
58589408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
58590a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    assert(Size <= 8 && "does not support size > 8");
58600a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
58610a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian           : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
58623b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
58633b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian  }
58646948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
58656948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
58666c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian  CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(),
58676c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian                          src, dst, ivarOffset);
58686948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  return;
58696948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian}
58706948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian
58716948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
58726948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// objc_assign_strongCast (id src, id *dst)
58736948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian///
58746948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanianvoid CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
58756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  CodeGen::CodeGenFunction &CGF,
58761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *src, llvm::Value *dst) {
58772acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type * SrcTy = src->getType();
58780a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian  if (!isa<llvm::PointerType>(SrcTy)) {
58799408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
58800a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    assert(Size <= 8 && "does not support size > 8");
58810a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
58826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar           : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
58833b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
58843b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian  }
58856948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
58866948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
5887bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(),
58886948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian                          src, dst, "weakassign");
58896948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  return;
58906948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian}
58916948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian
5892082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanianvoid CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
58936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  CodeGen::CodeGenFunction &CGF,
58946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Value *DestPtr,
58956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Value *SrcPtr,
589655bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian  llvm::Value *Size) {
5897082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
5898082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
5899082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(),
590055bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian                          DestPtr, SrcPtr, Size);
5901082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  return;
5902082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian}
5903082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian
59046948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// EmitObjCWeakRead - Code gen for loading value of a __weak
59056948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// object: objc_read_weak (id *src)
59066948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian///
59076948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanianllvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
59086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  CodeGen::CodeGenFunction &CGF,
59091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *AddrWeakObj) {
59102acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type* DestTy =
59116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
59126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
591372db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(),
59146948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian                                                  AddrWeakObj, "weakread");
59158339b35ca05dd040a9a0ecfc92e7b49d80c5a96bEli Friedman  read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
59166948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  return read_weak;
59176948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian}
59186948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian
59196948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
59206948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// objc_assign_weak (id src, id *dst)
59216948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian///
59226948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanianvoid CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
59231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                                llvm::Value *src, llvm::Value *dst) {
59242acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type * SrcTy = src->getType();
59250a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian  if (!isa<llvm::PointerType>(SrcTy)) {
59269408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
59270a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    assert(Size <= 8 && "does not support size > 8");
59280a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
59290a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian           : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
59303b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
59313b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian  }
59326948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
59336948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
593496508e1fea58347b6401ca9a4728c0b268174603Chris Lattner  CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(),
59356948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian                          src, dst, "weakassign");
59366948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  return;
59376948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian}
59386948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian
59396948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
59406948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// objc_assign_global (id src, id *dst)
59416948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian///
59426948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanianvoid CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
5943021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                                          llvm::Value *src, llvm::Value *dst,
5944021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                                          bool threadlocal) {
59452acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type * SrcTy = src->getType();
59460a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian  if (!isa<llvm::PointerType>(SrcTy)) {
59479408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
59480a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    assert(Size <= 8 && "does not support size > 8");
59490a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
59500a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian           : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
59513b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
59523b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian  }
59536948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
59546948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
5955021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian  if (!threadlocal)
5956021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian    CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(),
5957021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                            src, dst, "globalassign");
5958021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian  else
5959021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian    CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(),
5960021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                            src, dst, "threadlocalassign");
59616948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  return;
59626948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian}
596326cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian
59646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarvoid
5965f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallCGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
5966f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                                             const ObjCAtSynchronizedStmt &S) {
596705dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall  EmitAtSynchronizedStmt(CGF, S,
596805dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall      cast<llvm::Function>(ObjCTypes.getSyncEnterFn()),
596905dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall      cast<llvm::Function>(ObjCTypes.getSyncExitFn()));
5970f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
59714ff36847f44b35c2677330c39e87dff1d745944aDaniel Dunbar
59725a180397870944548aaadeaebf58e415885b9489John McCallllvm::Constant *
5973cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz JahanianCGObjCNonFragileABIMac::GetEHType(QualType T) {
59745a180397870944548aaadeaebf58e415885b9489John McCall  // There's a particular fixed type info for 'id'.
59755a180397870944548aaadeaebf58e415885b9489John McCall  if (T->isObjCIdType() ||
59765a180397870944548aaadeaebf58e415885b9489John McCall      T->isObjCQualifiedIdType()) {
59775a180397870944548aaadeaebf58e415885b9489John McCall    llvm::Constant *IDEHType =
59785a180397870944548aaadeaebf58e415885b9489John McCall      CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id");
59795a180397870944548aaadeaebf58e415885b9489John McCall    if (!IDEHType)
59805a180397870944548aaadeaebf58e415885b9489John McCall      IDEHType =
59815a180397870944548aaadeaebf58e415885b9489John McCall        new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy,
59825a180397870944548aaadeaebf58e415885b9489John McCall                                 false,
59835a180397870944548aaadeaebf58e415885b9489John McCall                                 llvm::GlobalValue::ExternalLinkage,
59845a180397870944548aaadeaebf58e415885b9489John McCall                                 0, "OBJC_EHTYPE_id");
59855a180397870944548aaadeaebf58e415885b9489John McCall    return IDEHType;
59865a180397870944548aaadeaebf58e415885b9489John McCall  }
59875a180397870944548aaadeaebf58e415885b9489John McCall
59885a180397870944548aaadeaebf58e415885b9489John McCall  // All other types should be Objective-C interface pointer types.
59895a180397870944548aaadeaebf58e415885b9489John McCall  const ObjCObjectPointerType *PT =
59905a180397870944548aaadeaebf58e415885b9489John McCall    T->getAs<ObjCObjectPointerType>();
59915a180397870944548aaadeaebf58e415885b9489John McCall  assert(PT && "Invalid @catch type.");
59925a180397870944548aaadeaebf58e415885b9489John McCall  const ObjCInterfaceType *IT = PT->getInterfaceType();
59935a180397870944548aaadeaebf58e415885b9489John McCall  assert(IT && "Invalid @catch type.");
59945a180397870944548aaadeaebf58e415885b9489John McCall  return GetInterfaceEHType(IT->getDecl(), false);
59955a180397870944548aaadeaebf58e415885b9489John McCall}
59965a180397870944548aaadeaebf58e415885b9489John McCall
5997f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
5998f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                                         const ObjCAtTryStmt &S) {
599905dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall  EmitTryCatchStmt(CGF, S,
600005dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall      cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()),
600105dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall      cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()),
600205dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall      cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn()));
60038ecbaf25c1373be6fb5a9d332b08b6be16d9fd4eDaniel Dunbar}
60048ecbaf25c1373be6fb5a9d332b08b6be16d9fd4eDaniel Dunbar
6005f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson/// EmitThrowStmt - Generate code for a throw statement.
6006f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlssonvoid CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
6007f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson                                           const ObjCAtThrowStmt &S) {
6008f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson  if (const Expr *ThrowExpr = S.getThrowExpr()) {
60092b014d6c0c6b8ac94b416ac37dfc7931f20777a7John McCall    llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
6010578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer    Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
60114c7d9f1507d0f102bd4133bba63348636facd469Jay Foad    CGF.EmitCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception)
60127ec404c40e42ce274d956a289ffa91e8f4befc43John McCall      .setDoesNotReturn();
6013f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  } else {
60144c7d9f1507d0f102bd4133bba63348636facd469Jay Foad    CGF.EmitCallOrInvoke(ObjCTypes.getExceptionRethrowFn())
60157ec404c40e42ce274d956a289ffa91e8f4befc43John McCall      .setDoesNotReturn();
6016f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
60174ff36847f44b35c2677330c39e87dff1d745944aDaniel Dunbar
60187ec404c40e42ce274d956a289ffa91e8f4befc43John McCall  CGF.Builder.CreateUnreachable();
6019f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson  CGF.Builder.ClearInsertionPoint();
6020f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson}
6021e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar
60225a180397870944548aaadeaebf58e415885b9489John McCallllvm::Constant *
60236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarCGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
60248158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar                                           bool ForDefinition) {
6025e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
60267e075cb62c06e0b0023fd12875c95da9c5ddefb7Daniel Dunbar
60278158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  // If we don't need a definition, return the entry if found or check
60288158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  // if we use an external reference.
60298158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  if (!ForDefinition) {
60308158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar    if (Entry)
60318158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar      return Entry;
60328158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar
60338158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar    // If this type (or a super class) has the __objc_exception__
60348158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar    // attribute, emit an external reference.
603568584ed35ad819a1668e3f527ba7f5dd4ae6a333Douglas Gregor    if (hasObjCExceptionAttribute(CGM.getContext(), ID))
60366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      return Entry =
60371c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson        new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
60388158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar                                 llvm::GlobalValue::ExternalLinkage,
60396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                 0,
60409c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                 ("OBJC_EHTYPE_$_" +
604101eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar                                  ID->getIdentifier()->getName()));
60428158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  }
60436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
60448158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  // Otherwise we need to either make a new entry or fill in the
60458158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  // initializer.
60468158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition");
60476ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar  std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
6048e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  std::string VTableName = "objc_ehtype_vtable";
60496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::GlobalVariable *VTableGV =
6050e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar    CGM.getModule().getGlobalVariable(VTableName);
6051e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  if (!VTableGV)
60526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    VTableGV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy,
60536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                        false,
6054e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar                                        llvm::GlobalValue::ExternalLinkage,
60551c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                                        0, VTableName);
6056e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar
605777b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner  llvm::Value *VTableIdx =
605877b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner    llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 2);
6059e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar
60601d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  llvm::Constant *Values[] = {
60611d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    llvm::ConstantExpr::getGetElementPtr(VTableGV, VTableIdx),
60621d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    GetClassName(ID->getIdentifier()),
60631d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    GetClassGlobal(ClassName)
60641d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  };
6065a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson  llvm::Constant *Init =
606608e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson    llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values);
6067e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar
60688158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  if (Entry) {
60698158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar    Entry->setInitializer(Init);
60708158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  } else {
60711c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson    Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
60728158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar                                     llvm::GlobalValue::WeakAnyLinkage,
60736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                     Init,
60749c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                     ("OBJC_EHTYPE_$_" +
607501eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar                                      ID->getIdentifier()->getName()));
60768158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  }
60778158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar
60781fb0caaa7bef765b85972274e3b434af2572c141John McCall  if (CGM.getLangOptions().getVisibilityMode() == HiddenVisibility)
60796ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar    Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
60804b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar  Entry->setAlignment(CGM.getTargetData().getABITypeAlignment(
60814b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar      ObjCTypes.EHTypeTy));
60828158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar
60838158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  if (ForDefinition) {
60848158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar    Entry->setSection("__DATA,__objc_const");
60858158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar    Entry->setLinkage(llvm::GlobalValue::ExternalLinkage);
60868158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  } else {
60878158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar    Entry->setSection("__DATA,__datacoal_nt,coalesced");
60888158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  }
6089e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar
6090e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  return Entry;
6091e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar}
60926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
6093bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar/* *** */
6094bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar
60956efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel DunbarCodeGen::CGObjCRuntime *
60966efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel DunbarCodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
609760be607e5d71627bf3dab8f51c3fdca74267c692David Chisnall  if (CGM.getLangOptions().ObjCNonFragileABI)
609860be607e5d71627bf3dab8f51c3fdca74267c692David Chisnall    return new CGObjCNonFragileABIMac(CGM);
6099c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar  return new CGObjCMac(CGM);
6100c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
6101